Add support for Hex, Binary, and Octal literals

This commit is contained in:
Garrett Dickinson 2022-07-14 18:09:58 -05:00 committed by GitHub
parent c8b7214e6f
commit a5ee63fffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 1 deletions

View File

@ -100,6 +100,8 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
checkNumberOperand(expr.operator, right); checkNumberOperand(expr.operator, right);
return (double) left - (double) right; return (double) left - (double) right;
case PLUS: case PLUS:
System.out.println("Left: " + left.getClass());
System.out.println("Right: " + right.getClass());
if (left instanceof Double && right instanceof Double) { if (left instanceof Double && right instanceof Double) {
return (double) left + (double) right; return (double) left + (double) right;
} else if (left instanceof String && right instanceof String) { } else if (left instanceof String && right instanceof String) {

View File

@ -115,7 +115,24 @@ class Scanner {
default: default:
if (isDigit(c)) { if (isDigit(c)) {
// Check to see if our incoming value is part of a number // Check to see if our incoming value is part of a number
// Switch on base prefix (hex, binary, base10...)
switch (peek()) {
case 'x':
advance(); // Advance to disregard the '0x' prefix
hex();
break;
case 'b':
advance(); // Advance to disregard the '0b' prefix
binary();
break;
case 'o':
advance(); // Advance to disregard the '0o' prefix
octal();
break;
default:
number(); number();
break;
}
} else if (isAlpha(c)) { } else if (isAlpha(c)) {
// Check to see if our incoming value is part of // Check to see if our incoming value is part of
// a reserved word or identifier // a reserved word or identifier
@ -127,12 +144,32 @@ class Scanner {
} }
} }
// Determine if the char is a base 10 digit // Determine if the char is a base 10 digit
private boolean isDigit(char c) { private boolean isDigit(char c) {
return c >= '0' && c <= '9'; return c >= '0' && c <= '9';
} }
// Determine if the character is a valid base 16 digit
private boolean isHex(char c) {
return (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
}
// Determine if the character is a valid base 16 digit
private boolean isBinary(char c) {
return (c >= '0' && c <= '1');
}
// Determine if the character is a valid base 8 digit
private boolean isOctal(char c) {
return (c >= '0' && c <= '7');
}
// Parse and tokenize the value as a base 10 number
private void number() { private void number() {
while (isDigit(peek())) advance(); while (isDigit(peek())) advance();
@ -148,6 +185,30 @@ class Scanner {
} }
// Parse and tokenize the value as a hexadecimal number, store in base 10
private void hex() {
while (isDigit(peek()) || isHex(peek())) advance();
addToken(NUMBER, Long.parseLong(source.substring(start + 2, current), 16));
}
// Parse and tokenize the value as a binary number, store in base 10
private void binary() {
while (isBinary(peek())) advance();
addToken(NUMBER, Long.parseLong(source.substring(start + 2, current), 2));
}
// Parse and tokenize the value as an octal number, store in base 10
private void octal() {
while (isOctal(peek())) advance();
addToken(NUMBER, Long.parseLong(source.substring(start + 2, current), 8));
}
// TODO: Lox spec supports multiline strings, we'll need to // TODO: Lox spec supports multiline strings, we'll need to
// probably remove that support since I don't intend Cobalt's // probably remove that support since I don't intend Cobalt's
// grammar to support that (maybe) :/ // grammar to support that (maybe) :/