From 9d7d365c2bfbd1e75197607d3a5ee97cc7fa6c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Santos?= Date: Mon, 13 Apr 2015 01:25:46 +0100 Subject: [PATCH] for...of --- lib/ast.js | 4 ++++ lib/output.js | 6 +++++- lib/parse.js | 24 +++++++++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/ast.js b/lib/ast.js index 16cfc387..7caccfd3 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -262,6 +262,10 @@ var AST_ForIn = DEFNODE("ForIn", "init name object", { } }, AST_IterationStatement); +var AST_ForOf = DEFNODE("ForOf", null, { + $documentation: "A `for ... of` statement", +}, AST_ForIn); + var AST_With = DEFNODE("With", "expression", { $documentation: "A `with` statement", $propdoc: { diff --git a/lib/output.js b/lib/output.js index fcaa364b..28c1facd 100644 --- a/lib/output.js +++ b/lib/output.js @@ -719,7 +719,11 @@ function OutputStream(options) { output.with_parens(function(){ self.init.print(output); output.space(); - output.print("in"); + if (self instanceof AST_ForOf) { + output.print("of"); + } else { + output.print("in"); + } output.space(); self.object.print(output); }); diff --git a/lib/parse.js b/lib/parse.js index 4e16171a..7b175a7e 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -44,7 +44,7 @@ "use strict"; -var KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with'; +var KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in of instanceof new return switch throw try typeof var void while with'; var KEYWORDS_ATOM = 'false null true'; var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield' + " " + KEYWORDS_ATOM + " " + KEYWORDS; @@ -921,11 +921,17 @@ function parse($TEXT, options) { init = is("keyword", "var") ? (next(), var_(true)) : expression(true, true); - if (is("operator", "in")) { + var is_in = is("operator", "in"); + var is_of = is("keyword", "of"); + if (is_in || is_of) { if (init instanceof AST_Var && init.definitions.length > 1) croak("Only one variable declaration allowed in for..in loop"); next(); - return for_in(init); + if (is_in) { + return for_in(init); + } else { + return for_of(init); + } } } return regular_for(init); @@ -945,6 +951,18 @@ function parse($TEXT, options) { }); }; + function for_of(init) { + var lhs = init instanceof AST_Var ? init.definitions[0].name : null; + var obj = expression(true); + expect(")"); + return new AST_ForOf({ + init : init, + name : lhs, + object : obj, + body : in_loop(statement) + }); + }; + function for_in(init) { var lhs = init instanceof AST_Var ? init.definitions[0].name : null; var obj = expression(true);