diff --git a/lex.js b/lex.js index 8dbe134..1d1d076 100644 --- a/lex.js +++ b/lex.js @@ -30,9 +30,9 @@ return this.index < 0 || this.index >= this.tokens.length; } - peek(type = undefined, value = undefined) + peek(type = undefined, tokenValue = undefined) { - if (this.index < 0 || this.index >= this.tokens.length) return { error: { msg: "Unexpected EOF", ...this.stringIndexToLinePos(this.inputLength - 1) } }; + if (this.index < 0 || this.index >= this.tokens.length) return { error: { msg: "Unexpected EOF", ...this.stringPosToLinePos(this.inputLength - 1) } }; const token = this.tokens[this.index]; @@ -40,14 +40,14 @@ { if (token.type !== type) { - return { error: { msg: "Expecting " . TokenType.keyName(type) + ", not " + TokenType.keyName(token.type) + " '" + token.value + "'", ...this.tokenToLinePos(token) } }; + return { error: { msg: "Expecting " . TokenType.keyName(type) + ", not " + TokenType.keyName(token.type) + " '" + token.token + "'", ...this.tokenToLinePos(token) } }; } - if (value !== undefined) + if (tokenValue !== undefined) { - if (token.value !== value) + if (token.token !== tokenValue) { - return { error: { msg: "Expecting " + TokenType.keyName(type) + " '" + value + "', not '" + token.value + "'", ...this.tokenToLinePos(token) } }; + return { error: { msg: "Expecting " + TokenType.keyName(type) + " '" + tokenValue + "', not '" + token.token + "'", ...this.tokenToLinePos(token) } }; } } } @@ -55,10 +55,10 @@ return token; } - consume(type = undefined, value = undefined) + consume(type = undefined, tokenValue = undefined) { - const token = this.peek(type, value); - if (token.error) return token.error; + const token = this.peek(type, tokenValue); + if (token.error) return token; this.index++; return token; @@ -101,7 +101,7 @@ tokenIndexToLinePos(index) { - if (index < 0 || index >= this.tokens.length) return this.stringIndexToLinePos(this.inputLength - 1); + if (index < 0 || index >= this.tokens.length) return this.stringPosToLinePos(this.inputLength - 1); return this.tokenToLinePos(this.tokens[index]); } diff --git a/lex.js b/lex.js index 8dbe134..1d1d076 100644 --- a/lex.js +++ b/lex.js @@ -30,9 +30,9 @@ return this.index < 0 || this.index >= this.tokens.length; } - peek(type = undefined, value = undefined) + peek(type = undefined, tokenValue = undefined) { - if (this.index < 0 || this.index >= this.tokens.length) return { error: { msg: "Unexpected EOF", ...this.stringIndexToLinePos(this.inputLength - 1) } }; + if (this.index < 0 || this.index >= this.tokens.length) return { error: { msg: "Unexpected EOF", ...this.stringPosToLinePos(this.inputLength - 1) } }; const token = this.tokens[this.index]; @@ -40,14 +40,14 @@ { if (token.type !== type) { - return { error: { msg: "Expecting " . TokenType.keyName(type) + ", not " + TokenType.keyName(token.type) + " '" + token.value + "'", ...this.tokenToLinePos(token) } }; + return { error: { msg: "Expecting " . TokenType.keyName(type) + ", not " + TokenType.keyName(token.type) + " '" + token.token + "'", ...this.tokenToLinePos(token) } }; } - if (value !== undefined) + if (tokenValue !== undefined) { - if (token.value !== value) + if (token.token !== tokenValue) { - return { error: { msg: "Expecting " + TokenType.keyName(type) + " '" + value + "', not '" + token.value + "'", ...this.tokenToLinePos(token) } }; + return { error: { msg: "Expecting " + TokenType.keyName(type) + " '" + tokenValue + "', not '" + token.token + "'", ...this.tokenToLinePos(token) } }; } } } @@ -55,10 +55,10 @@ return token; } - consume(type = undefined, value = undefined) + consume(type = undefined, tokenValue = undefined) { - const token = this.peek(type, value); - if (token.error) return token.error; + const token = this.peek(type, tokenValue); + if (token.error) return token; this.index++; return token; @@ -101,7 +101,7 @@ tokenIndexToLinePos(index) { - if (index < 0 || index >= this.tokens.length) return this.stringIndexToLinePos(this.inputLength - 1); + if (index < 0 || index >= this.tokens.length) return this.stringPosToLinePos(this.inputLength - 1); return this.tokenToLinePos(this.tokens[index]); } diff --git a/parse.js b/parse.js index 2883b7e..50958ed 100644 --- a/parse.js +++ b/parse.js @@ -105,13 +105,13 @@ if (token == "(") { // parse a subexpression - let { expr, error } = this.attemptSubtree(this.expression); + let { ast:expr, error } = this.attemptSubtree(this.expression); if (error) return this.getError(error); lhs = expr; // ensure the next token after the sub expression is a closing paren, and consume it - if (error = tokens.consume(lex.TokenType.Op, ")").error) + if (error = this.tokenStream.consume(lex.TokenType.Op, ")").error) { return this.getError(error); } @@ -120,7 +120,7 @@ { // this is a prefix operator of the given power // get the expression it applies to... - let { rhs, error } = this.attemptSubtree(expressionInternal, power); + let { ast:rhs, error } = this.attemptSubtree(this.expressionInternal, power); if (error) return this.getError(error); // ... and generate an AST node for it @@ -193,7 +193,7 @@ * We need to parse the index expression. Note we reset the binding power, * this is because we will always end with ], so we don't need to worry about our current precedence */ - let { index, error } = this.attemptSubtree(this.expression); + let { ast:index, error } = this.attemptSubtree(this.expression); if (error) return this.getError(error); // parse the closing ] @@ -235,7 +235,7 @@ { // avoid re-declaring error... annoying - let { arg, error } = this.attemptSubtree(this.expression); + let { ast:arg, error } = this.attemptSubtree(this.expression); if (error) return this.getError(error); // our new node is the old lhs as a function, called with the index expression @@ -261,11 +261,11 @@ break; } - [leftBinding, rightBinding] = InfixBindingPower[opToken]; + let [ leftBindingPower, rightBindingPower ] = InfixBindingPower[opToken]; // if the binding power is too low, we are done parsing the current subexpression, leave // the current operator for our caller... - if (leftBinding < minBindingPower) break; + if (leftBindingPower < minBindingPower) break; //... otherwise, this operator is for us, so consume it this.tokenStream.consume(); @@ -273,7 +273,7 @@ { // the next expression is the right side of our current operator, but only as much as the // right-side binding power of our operator can grab - let { rhs, error } = this.attemptSubtree(this.expressionInternal, rightBinding); + let { ast:rhs, error } = this.attemptSubtree(this.expressionInternal, rightBindingPower); if (error) return this.getError(error); // our new lhs becomes our applied operator, @@ -288,7 +288,7 @@ attemptSubtree(parseFunction, ...args) { this.tokenStream.startMatch(); - const subtree = parseFunction.apply(this, [ this.tokenStream, ...args ]); + const subtree = parseFunction.apply(this, args); if (subtree.error) { @@ -306,7 +306,11 @@ { return { ast: null, error: error }; } - } -module.exports = { Parser: Parser }; +function getPrettyAST(ast) +{ + return ast.mapKey("node", v => ASTNode.keyName(v)); +} + +module.exports = { Parser: Parser, getPrettyAST: getPrettyAST };