M CHANGES.md +2 -0
@@ 7,6 7,8 @@ Glass 0.6 — ????-??-??
* The `$` prefix can now be used for hexadecimal numbers.
* Symbols can no longer start with the `$` character (bc).
* The `>>>` unsigned shift right operator is now supported.
+ * The `'` character can now be written as `''` in character literals.
+ * The `"` character can now be written as `""` in string literals.
Glass 0.5 — 2017-01-18
----------------------
M README.md +3 -0
@@ 303,6 303,9 @@ Literals
* Character: `'c'`
* String: `"abc"`
+Character literals can contain the `'` character by repeating it as `''`, and
+string literals can contain the `"` character by repeating it as `""`.
+
Character and string literals support the following escape sequences:
* `\0` (NUL)
M src/main/java/nl/grauw/glass/Parser.java +31 -5
@@ 253,9 253,7 @@ public class Parser {
private class ArgumentStringState extends State {
public State parse(char character) {
if (character == '"') {
- expressionBuilder.addValueToken(new StringLiteral(accumulator.toString()));
- accumulator.setLength(0);
- return argumentOperatorState;
+ return argumentStringDoubleQuoteState;
} else if (character == '\\') {
return argumentStringEscapeState;
} else if (character == '\n' || character == '\0') {
@@ 267,6 265,20 @@ public class Parser {
}
}
+ private ArgumentStringDoubleQuoteState argumentStringDoubleQuoteState = new ArgumentStringDoubleQuoteState();
+ private class ArgumentStringDoubleQuoteState extends State {
+ public State parse(char character) {
+ if (character == '"') {
+ accumulator.append(character);
+ return argumentStringState;
+ } else {
+ expressionBuilder.addValueToken(new StringLiteral(accumulator.toString()));
+ accumulator.setLength(0);
+ return argumentOperatorState.parse(character);
+ }
+ }
+ }
+
private ArgumentStringEscapeState argumentStringEscapeState = new ArgumentStringEscapeState();
private class ArgumentStringEscapeState extends State {
public State parse(char character) {
@@ 311,9 323,11 @@ public class Parser {
private ArgumentCharacterState argumentCharacterState = new ArgumentCharacterState();
private class ArgumentCharacterState extends State {
public State parse(char character) {
- if (character == '\\') {
+ if (character == '\'') {
+ return argumentCharacterDoubleQuoteState;
+ } else if (character == '\\') {
return argumentCharacterEscapeState;
- } else if (character == '\'' || character == '\n' || character == '\0') {
+ } else if (character == '\n' || character == '\0') {
throw new SyntaxError();
} else {
accumulator.append(character);
@@ 322,6 336,18 @@ public class Parser {
}
}
+ private ArgumentCharacterDoubleQuoteState argumentCharacterDoubleQuoteState = new ArgumentCharacterDoubleQuoteState();
+ private class ArgumentCharacterDoubleQuoteState extends State {
+ public State parse(char character) {
+ if (character == '\'') {
+ accumulator.append(character);
+ return argumentCharacterEndState;
+ } else {
+ throw new SyntaxError();
+ }
+ }
+ }
+
private ArgumentCharacterEscapeState argumentCharacterEscapeState = new ArgumentCharacterEscapeState();
private class ArgumentCharacterEscapeState extends State {
public State parse(char character) {
M src/test/java/nl/grauw/glass/ParserTest.java +11 -1
@@ 116,6 116,11 @@ public class ParserTest extends TestBase
}
@Test
+ public void testCharacterLiteralDoubleQuote() {
+ assertEquals('\'', ((CharacterLiteral)parseExpression("''''")).getCharacter());
+ }
+
+ @Test
public void testCharacterLiteralEscape() {
assertEquals('\0', ((CharacterLiteral)parseExpression("'\\0'")).getCharacter());
assertEquals('\7', ((CharacterLiteral)parseExpression("'\\a'")).getCharacter());
@@ 138,7 143,7 @@ public class ParserTest extends TestBase
@Test
public void testCharacterLiteralTooShort() {
- assertSyntaxError(0, 1, 1, () -> {
+ assertSyntaxError(0, 1, 2, () -> {
parseExpression("''");
});
}
@@ 163,6 168,11 @@ public class ParserTest extends TestBase
}
@Test
+ public void testStringLiteralDoubleQuote() {
+ assertEquals("x\"z", ((StringLiteral)parseExpression("\"x\"\"z\"")).getString());
+ }
+
+ @Test
public void testStringLiteralEscape() {
assertEquals("x\0z", ((StringLiteral)parseExpression("\"x\\0z\"")).getString());
assertEquals("x\7z", ((StringLiteral)parseExpression("\"x\\az\"")).getString());