From 224012b708fa8ee6f0617c0ef95f2b5c20cad14e Mon Sep 17 00:00:00 2001 From: Miha Korenjak Date: Thu, 10 Nov 2022 20:33:38 +0000 Subject: [PATCH] add escape sequences in character strings (#38) * add escape sequences in character strings Standard escape sequences (those used in java) and ability to write bytes directly (\xbb). * remove unneeded line in escape sequence parsing * fix handling of unterminated byte strings * add double quoted strings To avoid breaking backwards compatibility, escaped strings need to be enclosed in double quotes. Moved code for lexing to Lexer. --- src/sic/asm/parsing/Lexer.java | 48 ++++++++++++++++++++++++++++++++++ src/sic/ast/data/DataChr.java | 13 +++++++-- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/sic/asm/parsing/Lexer.java b/src/sic/asm/parsing/Lexer.java index 747f439..9604e62 100644 --- a/src/sic/asm/parsing/Lexer.java +++ b/src/sic/asm/parsing/Lexer.java @@ -218,4 +218,52 @@ public double readFloat() throws AsmError { return num; } + public String readEscapedString(char terminator) throws AsmError { + StringBuilder buf = new StringBuilder(); + for (char c = advance(); c != terminator; c = advance()) { + if (!ready() || c == '\n') { + throw new AsmError(loc(), "Unterminated byte string"); + } + if (c == '\\') { + c = advance(); + switch (c) { + case '\"', '\\': + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case '0': + c = '\0'; + break; + case 'x': + int mark = pos(); + advance(2); + String str = extract(mark); + try { + c = (char) Integer.parseInt(str, 16); + } catch (NumberFormatException e) { + throw new AsmError(loc(), "Hexadecimal byte expected"); + } + break; + default: + throw new AsmError(loc(), "Unknown escape sequence '\\%c'", c); + } + } + buf.append(c); + } + return buf.toString(); + } + } diff --git a/src/sic/ast/data/DataChr.java b/src/sic/ast/data/DataChr.java index eba4439..f3cf2fb 100644 --- a/src/sic/ast/data/DataChr.java +++ b/src/sic/ast/data/DataChr.java @@ -26,8 +26,17 @@ public String toString() { @Override public void parse(Parser parser, boolean allowList) throws AsmError { parser.advance('C'); - parser.advance('\''); - data = parser.readUntil('\'').getBytes(); + char quote = parser.advance(); + switch (quote) { + case '\'': + data = parser.readUntil('\'').getBytes(); + break; + case '"': + data = parser.readEscapedString('"').getBytes(); + break; + default: + throw new AsmError(parser.loc(), "Expected quote"); + } if (allowList) super.parse(parser, true); }