Skip to content

Commit

Permalink
Fixed mechanics for string escaped characters on runtime.
Browse files Browse the repository at this point in the history
  • Loading branch information
nthnn committed Jun 27, 2024
1 parent 38700eb commit aa72abb
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/main/java/xyz/uartix/ast/expr/LiteralExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import xyz.uartix.ast.Expression;
import xyz.uartix.core.SymbolTable;
import xyz.uartix.parser.Token;
import xyz.uartix.util.MiscUtil;

public class LiteralExpression implements Expression {
private final Token address;
Expand All @@ -35,6 +36,9 @@ public Token getAddress() {
}

public Object visit(SymbolTable symtab) {
if(this.value instanceof String)
return MiscUtil.unescapeCharacters(this.value.toString());

return this.value;
}
}
66 changes: 62 additions & 4 deletions src/main/java/xyz/uartix/parser/Tokenizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,69 @@ else if(currentChar == '"') {
int currentColumn = column;

while(!this.isAtEnd() && this.source.charAt(index) != '"') {
if(this.source.charAt(index) == '\n')
throw new LexicalAnalysisException("Found new line inside string literal.");
char curr = this.source.charAt(index);

string.append(this.source.charAt(index++));
column++;
if(curr == '\n')
throw new LexicalAnalysisException("Found new line inside string literal." +
"(line " + line + ", column " + column + ")");
else if(curr == '\\') {
string.append(curr);
index++;
column++;

if(this.isAtEnd())
throw new LexicalAnalysisException("Expecting escape character, encountered end-of-file "+
"(line " + line + ", column " + column + ")");

curr = this.source.charAt(index);
switch(curr) {
case 'r':
case 'n':
case 't':
case 'b':
case 'f':
case '"':
case '\\':
string.append(curr);

index++;
column++;

break;

case 'u':
string.append(curr);

index++;
column++;

for(int count = 0; count < 4; count++) {
if(this.isAtEnd())
throw new LexicalAnalysisException("Expecting hexadecimal value, encountered end-of-file." +
"(line " + line + ", column " + column + ")");

char hex = this.source.charAt(index);
if(!Tokenizer.isHexadecimalDigit(hex))
throw new LexicalAnalysisException("Invalid hexadecimal character: " + hex + "." +
"(line " + line + ", column " + column + ")");

string.append(hex);
index++;
column++;
}

break;

default:
throw new LexicalAnalysisException("Unknown string escape character. " +
"(line " + line + ", column " + column + ")");
}
}
else {
string.append(curr);
index++;
column++;
}

if(this.isAtEnd())
throw new LexicalAnalysisException("Unterminated string literal on line " + line + ".");
Expand Down
63 changes: 63 additions & 0 deletions src/main/java/xyz/uartix/util/MiscUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,67 @@ public final class MiscUtil {
public static String multiply(String string, int count) {
return String.valueOf(string).repeat(Math.max(0, count));
}

public static String unescapeCharacters(String string) {
StringBuilder sb = new StringBuilder();

for(int i = 0; i < string.length(); i++) {
char ch = string.charAt(i);

if(ch == '\\' && i + 1 < string.length()) {
char nextChar = string.charAt(i + 1);
switch (nextChar) {
case 'r':
sb.append('\r');
i++;
break;

case 'n':
sb.append('\n');
i++;
break;

case 't':
sb.append('\t');
i++;
break;

case 'b':
sb.append('\b');
i++;
break;

case 'f':
sb.append('\f');
i++;
break;

case '"':
sb.append('"');
i++;
break;

case '\\':
sb.append('\\');
i++;
break;

case 'u':
if(i + 5 < string.length()) {
String unicode = string.substring(i + 2, i + 6);
sb.append((char) Integer.parseInt(unicode, 16));
i += 5;
}
break;

default:
sb.append(ch);
break;
}
}
else sb.append(ch);
}

return sb.toString();
}
}

0 comments on commit aa72abb

Please sign in to comment.