diff --git a/parse.js b/parse.js index bb6bfba..81ad5fe 100644 --- a/parse.js +++ b/parse.js @@ -71,7 +71,7 @@ } // all reserved keywords -const Keywords = Object.freeze([ "if", "else", "on", "wait", "for", "map", "in", ]); +const Keywords = Object.freeze([ "if", "else", "on", "wait", "for", "map", "in", "while", ]); // the types of AST nodes const ASTNode = Object.freeze({ @@ -89,10 +89,12 @@ For:12, // a for statement with loop variable, range, and loop body Map:13, // like a for statement, but is actually an expression where you can 'return' in the body and generate an array On:14, // handle a named event on a given target with given params, returning given values + While:15, // while loop with condition + Wait:16, // statement that pauses exeuction until the async call is done }); const StatementsWithSemicolon = Object.freeze([ - ASTNode.ExprStatement, + ASTNode.ExprStatement, ASTNode.Wait, ]); // all reserved words that represent literals @@ -191,6 +193,38 @@ return { ast:expr }; } + whileStmt() + { + let error; + + error = this.tokenStream.consume(lex.TokenType.Word, "while").error; + if (error) return this.getError(error); + + let condition; + ({ ast:condition, error } = this.exprInBrackets()); + if (error) return this.getError(error, true); + + let loop; + ({ ast:loop, error } = this.withBacktrack(this.block)); + if (error) return this.getError(error, true); + + return { ast: { node: ASTNode.While, condition: condition, loop: loop } }; + } + + whileStmt() + { + let error; + + error = this.tokenStream.consume(lex.TokenType.Word, "wait").error; + if (error) return this.getError(error); + + let expr; + ({ ast:expr, error } = this.expression()); + if (error) return this.getError(error, true); + + return { ast: { node: ASTNode.Wait, expr: expr } }; + } + onStmt() { let error; @@ -232,7 +266,7 @@ ({ ast:body, error } = this.withBacktrack(this.block)); if (error) return this.getError(error, true); - return { ast: { node: ASTNode.On, target: target, eventName: eventName, eventParams: eventParams, eventValues: eventValues } }; + return { ast: { node: ASTNode.On, target: target, eventName: eventName, eventParams: eventParams, eventValues: eventValues, body: body } }; } forStmt() @@ -311,6 +345,8 @@ { parse: this.ifStmt, handle: ast => ast }, { parse: this.forStmt, handle: ast => ast }, { parse: this.onStmt, handle: ast => ast }, + { parse: this.whileStmt, handle: ast => ast }, + { parse: this.waitStmt, handle: ast => ast }, ], "Expecting statement"); let error, bestError, numMatched, bestNumMatched = 0;