From b249d796036d689803c7b3a91d3157491689b47b Mon Sep 17 00:00:00 2001 From: Marco Maccaferri Date: Sat, 12 Jan 2019 20:14:05 +0100 Subject: [PATCH] Implemented support for single-quote delimited string literals --- src-tests/nl/grauw/glass/ParserTest.java | 31 ++++++++++ src/nl/grauw/glass/Parser.java | 72 ++++++++++++++++++------ 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/src-tests/nl/grauw/glass/ParserTest.java b/src-tests/nl/grauw/glass/ParserTest.java index b9eacb2..4de7ee0 100644 --- a/src-tests/nl/grauw/glass/ParserTest.java +++ b/src-tests/nl/grauw/glass/ParserTest.java @@ -14,6 +14,7 @@ import nl.grauw.glass.expressions.Expression; import nl.grauw.glass.expressions.ExpressionBuilder.ExpressionError; import nl.grauw.glass.expressions.Flag; import nl.grauw.glass.expressions.IntegerLiteral; +import nl.grauw.glass.expressions.StringLiteral; public class ParserTest { @@ -169,6 +170,36 @@ public class ParserTest { assertEquals(Flag.P, parseExpression("!m").getFlag()); } + @Test + public void testCharacterStringLiteral() { + assertEquals("test", ((StringLiteral) parseExpression("'test'")).getString()); + } + + @Test + public void testStringLiteral() { + assertEquals("test", ((StringLiteral) parseExpression("\"test\"")).getString()); + } + + @Test + public void testStringLiteralEscape() { + assertEquals("\t", ((StringLiteral) parseExpression("\"\\t\"")).getString()); + } + + @Test(expected = SyntaxError.class) + public void testStringLiteralTooShort() { + parse("\"\""); + } + + @Test(expected = SyntaxError.class) + public void testStringLiteralUnclosed() { + parse("\""); + } + + @Test(expected = SyntaxError.class) + public void testStringLiteralUnclosedEscape() { + parse("\"\\"); + } + public Line parse(String text) { LineNumberReader reader = new LineNumberReader(new StringReader(text)); return new Parser().parse(reader, new Scope(), null); diff --git a/src/nl/grauw/glass/Parser.java b/src/nl/grauw/glass/Parser.java index 6b4e21f..ca686b3 100644 --- a/src/nl/grauw/glass/Parser.java +++ b/src/nl/grauw/glass/Parser.java @@ -362,15 +362,25 @@ public class Parser { private class ArgumentCharacterState extends State { @Override public State parse(char character) { - if (character == '\\') { + if (character == '\'') { + if (accumulator.length() == 1) { + expressionBuilder.addValueToken(new CharacterLiteral(accumulator.charAt(0))); + } + else { + expressionBuilder.addValueToken(new StringLiteral(accumulator.toString())); + } + accumulator.setLength(0); + return argumentOperatorState; + } + 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); - return argumentCharacterEndState; + return argumentCharacterState; } } } @@ -379,22 +389,48 @@ public class Parser { private class ArgumentCharacterEscapeState extends State { @Override public State parse(char character) { - State state = argumentStringEscapeState.parse(character); - if (state == argumentStringState) { - return argumentCharacterEndState; + if (character == '0') { + accumulator.append('\0'); + return argumentCharacterState; } - throw new AssemblyException("Unexpected state."); - } - } - - private ArgumentCharacterEndState argumentCharacterEndState = new ArgumentCharacterEndState(); - private class ArgumentCharacterEndState extends State { - @Override - public State parse(char character) { - if (character == '\'') { - expressionBuilder.addValueToken(new CharacterLiteral(accumulator.charAt(0))); - accumulator.setLength(0); - return argumentOperatorState; + else if (character == 'a') { + accumulator.append('\7'); + return argumentCharacterState; + } + else if (character == 't') { + accumulator.append('\t'); + return argumentCharacterState; + } + else if (character == 'n') { + accumulator.append('\n'); + return argumentCharacterState; + } + else if (character == 'f') { + accumulator.append('\f'); + return argumentCharacterState; + } + else if (character == 'r') { + accumulator.append('\r'); + return argumentCharacterState; + } + else if (character == 'e') { + accumulator.append('\33'); + return argumentCharacterState; + } + else if (character == '"') { + accumulator.append('"'); + return argumentCharacterState; + } + else if (character == '\'') { + accumulator.append('\''); + return argumentCharacterState; + } + else if (character == '\\') { + accumulator.append('\\'); + return argumentCharacterState; + } + else if (character == '\n' || character == '\0') { + throw new SyntaxError(); } else { throw new SyntaxError();