Comparing version
@@ -58,38 +58,2 @@ import { errorOnToken } from "./main.js"; | ||
const expression = () => equality(); | ||
const equality = () => { | ||
let expr = comparison(); | ||
while (match("!=", "==")) { | ||
const operator = previous(); | ||
const right = comparison(); | ||
expr = { kind: "binary", left: expr, operator, right }; | ||
} | ||
return expr; | ||
}; | ||
const comparison = () => { | ||
let expr = term(); | ||
while (match(">", ">=", "<", "<=")) { | ||
const operator = previous(); | ||
const right = term(); | ||
expr = { kind: "binary", left: expr, operator, right }; | ||
} | ||
return expr; | ||
}; | ||
const term = () => { | ||
let expr = factor(); | ||
while (match("-", "+")) { | ||
const operator = previous(); | ||
const right = factor(); | ||
expr = { kind: "binary", left: expr, operator, right }; | ||
} | ||
return expr; | ||
}; | ||
const factor = () => { | ||
let expr = unary(); | ||
while (match("/", "*")) { | ||
const operator = previous(); | ||
const right = unary(); | ||
expr = { kind: "binary", left: expr, operator, right }; | ||
} | ||
return expr; | ||
}; | ||
const unary = () => { | ||
@@ -119,2 +83,17 @@ if (match("!", "-")) { | ||
}; | ||
const parseBinaryOp = (ops, next) => { | ||
return () => { | ||
let expr = next(); | ||
while (match(...ops)) { | ||
const operator = previous(); | ||
const right = next(); | ||
expr = { kind: "binary", left: expr, operator, right }; | ||
} | ||
return expr; | ||
}; | ||
}; | ||
const factor = parseBinaryOp(["/", "*"], unary); | ||
const term = parseBinaryOp(["-", "+"], factor); | ||
const comparison = parseBinaryOp([">", ">=", "<", "<="], term); | ||
const equality = parseBinaryOp(["!=", "=="], comparison); | ||
try { | ||
@@ -121,0 +100,0 @@ return expression(); |
@@ -26,5 +26,11 @@ import { error } from "./main.js"; | ||
} | ||
#addToken(type, literal) { | ||
const text = this.source.slice(this.start, this.current); | ||
this.tokens.push({ lexeme: text, line: this.line, literal, type }); | ||
#addToken(type, literal, isCurrency) { | ||
const lexeme = this.source.slice(this.start, this.current); | ||
this.tokens.push({ | ||
lexeme, | ||
line: this.line, | ||
literal, | ||
type, | ||
...isCurrency && { isCurrency } | ||
}); | ||
} | ||
@@ -58,3 +64,4 @@ #advance() { | ||
#number() { | ||
while (isDigit(this.#peek())) { | ||
const isCurrency = this.source[this.start] === "$"; | ||
while (isDigit(this.#peek()) || this.#peek() === ",") { | ||
this.#advance(); | ||
@@ -68,6 +75,4 @@ } | ||
} | ||
this.#addToken( | ||
"number", | ||
Number(this.source.slice(this.start, this.current)) | ||
); | ||
const numText = this.source.slice(this.start, this.current).replace(/[$,]/g, ""); | ||
this.#addToken("number", Number(numText), isCurrency); | ||
} | ||
@@ -127,3 +132,3 @@ #peek() { | ||
default: | ||
if (isDigit(c)) { | ||
if (isDigit(c) || c === "$") { | ||
this.#number(); | ||
@@ -130,0 +135,0 @@ } else if (isAlpha(c)) { |
import { TokenType } from './token-type.js'; | ||
interface Token { | ||
isCurrency?: boolean; | ||
lexeme: string; | ||
@@ -5,0 +6,0 @@ line: number; |
function tokenToString(token) { | ||
return `'${token.lexeme}': ${token.type}` + (token.literal !== null ? `: ${token.literal}` : ""); | ||
return `'${token.lexeme}': ${token.type}` + (token.literal !== null ? `: ${token.isCurrency ? "$" : ""}${token.literal}` : ""); | ||
} | ||
@@ -4,0 +4,0 @@ export { |
{ | ||
"name": "gravlax", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "A Lox interpreter with tasty TypeScript seasoning", | ||
@@ -5,0 +5,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
40860
-1.49%477
-3.05%