From 13f7b119bb7e2184dcd623e167f507b31e73725a Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Fri, 17 Aug 2012 15:59:42 +0300 Subject: [PATCH] code generator finally seems to work properly --- lib/ast.js | 27 ++- lib/node.js | 8 +- lib/output.js | 445 ++++++++++++++++++++++++++++++++++++++------------ lib/parse.js | 34 ++-- 4 files changed, 373 insertions(+), 141 deletions(-) diff --git a/lib/ast.js b/lib/ast.js index f66853eb..8ee58686 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -9,7 +9,7 @@ function DEFNODE(type, props, methods, base) { code += "this." + props[i] + " = props." + props[i] + ";"; } if (methods && methods.initialize) - code += "this.initialize();" + code += "this.initialize();"; code += " } }"; var ctor = new Function(code)(); if (base) { @@ -36,7 +36,7 @@ var AST_Token = DEFNODE("Token", "type value line col pos endpos nlb comments_be var AST_Node = DEFNODE("Node", "start end", { clone: function() { return new this.CTOR(this); - }, + } }, null); var AST_Directive = DEFNODE("Directive", "value", { @@ -47,16 +47,6 @@ var AST_Debugger = DEFNODE("Debugger", null, { }); -var AST_Parenthesized = DEFNODE("Parenthesized", "expression", { - $documentation: "Represents an expression which is always parenthesized. Used for the \ -conditions in IF/WHILE/DO and expression in SWITCH/WITH.", -}); - -var AST_Bracketed = DEFNODE("Bracketed", "body", { - $documentation: "Represents a block of statements that are always included in brackets. \ -Used for bodies of FUNCTION/TRY/CATCH/THROW/SWITCH.", -}); - /* -----[ loops ]----- */ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label statement", { @@ -78,11 +68,14 @@ var AST_EmptyStatement = DEFNODE("EmptyStatement", null, { }, AST_Statement); -var AST_Do = DEFNODE("Do", "condition", { +var AST_DWLoop = DEFNODE("DWLoop", "condition", { }, AST_Statement); -var AST_While = DEFNODE("While", "condition", { -}, AST_Statement); +var AST_Do = DEFNODE("Do", null, { +}, AST_DWLoop); + +var AST_While = DEFNODE("While", null, { +}, AST_DWLoop); var AST_For = DEFNODE("For", "init condition step", { }, AST_Statement); @@ -152,7 +145,7 @@ var AST_Switch = DEFNODE("Switch", "expression", { }, AST_Statement); var AST_SwitchBlock = DEFNODE("SwitchBlock", null, { -}, AST_Bracketed); +}, AST_BlockStatement); var AST_SwitchBranch = DEFNODE("SwitchBranch", "body", { }); @@ -177,7 +170,7 @@ var AST_Finally = DEFNODE("Finally", "body", { /* -----[ VAR/CONST ]----- */ -var AST_Definitions = DEFNODE("Definitions", "definitions inline", { +var AST_Definitions = DEFNODE("Definitions", "definitions", { }); var AST_Var = DEFNODE("Var", null, { diff --git a/lib/node.js b/lib/node.js index 69867497..ae2ec845 100755 --- a/lib/node.js +++ b/lib/node.js @@ -19,13 +19,15 @@ /// var filename = process.argv[2]; - console.time("parse"); + //console.time("parse"); var ast = parse(fs.readFileSync(filename, "utf8")); - console.timeEnd("parse"); + //console.timeEnd("parse"); + //console.time("generate"); var stream = OutputStream({ beautify: true }); ast.print(stream); - console.log(stream.get()); + //console.timeEnd("generate"); + sys.puts(stream.get()); // console.time("walk"); // var w = new TreeWalker(function(node){ diff --git a/lib/output.js b/lib/output.js index c581fa87..85003290 100644 --- a/lib/output.js +++ b/lib/output.js @@ -8,7 +8,8 @@ function OutputStream(options) { ascii_only : false, inline_script : false, width : 80, - beautify : true + beautify : true, + scope_style : "negate" }); function noop() {}; @@ -63,11 +64,8 @@ function OutputStream(options) { return name; }; - function make_indent(line) { - if (line == null) - line = ""; - line = repeat_string(" ", options.indent_start + indentation) + line; - return line; + function make_indent(back) { + return repeat_string(" ", options.indent_start + indentation - back * options.indent_level); }; function last_char() { @@ -77,11 +75,14 @@ function OutputStream(options) { /* -----[ beautification/minification ]----- */ var might_need_space = false; + var might_need_semicolon = false; + var last = null; function print(str) { + last = str; str = String(str); + var ch = str.charAt(0); if (might_need_space) { - var ch = str.charAt(0); if ((is_identifier_char(last_char()) && (is_identifier_char(ch) || ch == "\\")) || @@ -91,8 +92,16 @@ function OutputStream(options) { current_col++; current_pos++; } + might_need_space = false; + } + if (might_need_semicolon) { + if (";{}".indexOf(ch) < 0 && !/[;]$/.test(OUTPUT)) { + OUTPUT += ";"; + current_col++; + current_pos++; + } + might_need_semicolon = false; } - might_need_space = false; var a = str.split(/\r?\n/), n = a.length; current_line += n; if (n == 1) { @@ -110,9 +119,9 @@ function OutputStream(options) { might_need_space = true; }; - var indent = options.beautify ? function() { + var indent = options.beautify ? function(half) { if (options.beautify) { - print(make_indent()); + print(make_indent(half ? 0.5 : 0)); } } : noop; @@ -129,6 +138,12 @@ function OutputStream(options) { print("\n"); } : noop; + var semicolon = options.beautify ? function() { + print(";"); + } : function() { + might_need_semicolon = true; + }; + function next_indent() { return indentation + options.indent_level; }; @@ -156,15 +171,12 @@ function OutputStream(options) { function with_square(cont) { print("["); - var ret = with_indent(current_col, cont); + //var ret = with_indent(current_col, cont); + var ret = cont(); print("]"); return ret; }; - function semicolon() { - print(";"); - }; - function comma() { print(","); space(); @@ -184,6 +196,7 @@ function OutputStream(options) { space : space, comma : comma, colon : colon, + last : function() { return last }, semicolon : semicolon, print_name : function(name) { print(make_name(name)) }, print_string : function(str) { print(encode_string(str)) }, @@ -191,57 +204,170 @@ function OutputStream(options) { with_block : with_block, with_parens : with_parens, with_square : with_square, - options : function() { return options }, + options : function(opt) { return options[opt] }, line : function() { return current_line }, col : function() { return current_col }, pos : function() { return current_pos }, push_node : function(node) { stack.push(node) }, pop_node : function() { return stack.pop() }, stack : function() { return stack }, - parent : function() { return stack[stack.length - 2] } + parent : function(n) { + return stack[stack.length - 2 - (n || 0)]; + } }; }; /* -----[ code generators ]----- */ -(function(DEFPRINT){ +(function(){ + + /* -----[ utils ]----- */ + + function DEFPRINT(nodetype, generator) { + nodetype.DEFMETHOD("print", function(stream){ + var self = this; + stream.push_node(self); + if (self.needs_parens(stream)) { + stream.with_parens(function(){ + generator(self, stream); + }); + } else { + generator(self, stream); + } + stream.pop_node(); + }); + }; + + function PARENS(nodetype, func) { + nodetype.DEFMETHOD("needs_parens", func); + }; + + /* -----[ PARENTHESES ]----- */ + + PARENS(AST_Node, function(){ + return false; + }); + + // a function expression needs parens around it when it's provably + // the first token to appear in a statement. + PARENS(AST_Lambda, function(output){ + return first_in_statement(output); + }); + + // same goes for an object literal, because otherwise it would be + // interpreted as a block of code. + PARENS(AST_Object, function(output){ + return first_in_statement(output); + }); + + // Defun inherits from Lambda, but we don't want parens here. + PARENS(AST_Defun, function(){ + return false; + }); + + PARENS(AST_Seq, function(output){ + var p = output.parent(); + return p instanceof AST_Call + || p instanceof AST_Binary + || p instanceof AST_VarDef + || p instanceof AST_Dot + || p instanceof AST_Array + || p instanceof AST_ObjectProperty + || p instanceof AST_Conditional; + }); + + PARENS(AST_Binary, function(output){ + var p = output.parent(); + if (p instanceof AST_Call && p.expression === this) + return true; + if (p instanceof AST_Unary) + return true; + if (p instanceof AST_PropAccess && p.expression === this) + return true; + if (p instanceof AST_Binary) { + var po = p.operator, pp = PRECEDENCE[po]; + var so = this.operator, sp = PRECEDENCE[so]; + if (pp > sp + || (pp == sp + && this === p.right + && !(so == po && + (so == "*" || + so == "&&" || + so == "||")))) { + return true; + } + } + if (this.operator == "in") { + // the “NoIn” stuff :-\ + // UglifyJS 1.3.3 misses this one. + if ((p instanceof AST_For || p instanceof AST_ForIn) && p.init === this) + return true; + if (p instanceof AST_VarDef) { + var v = output.parent(1), p2 = output.parent(2); + if ((p2 instanceof AST_For || p2 instanceof AST_ForIn) && p2.init === v) + return true; + } + } + }); + + PARENS(AST_New, function(output){ + var p = output.parent(); + if (p instanceof AST_Dot && no_constructor_parens(this, output)) + return true; + }); + + function assign_and_conditional_paren_rules(output) { + var p = output.parent(); + if (p instanceof AST_Unary) + return true; + if (p instanceof AST_Binary && !(p instanceof AST_Assign)) + return true; + if (p instanceof AST_Call && p.expression === this) + return true; + if (p instanceof AST_Conditional && p.condition === this) + return true; + if (p instanceof AST_PropAccess && p.expression === this) + return true; + }; + + PARENS(AST_Conditional, assign_and_conditional_paren_rules); + PARENS(AST_Assign, assign_and_conditional_paren_rules); + + /* -----[ PRINTERS ]----- */ + DEFPRINT(AST_Directive, function(self, output){ output.print_string(self.value); }); DEFPRINT(AST_Debugger, function(self, output){ - output.print_string("debugger"); - }); - DEFPRINT(AST_Parenthesized, function(self, output){ - output.with_parens(function(){ - self.expression.print(output); - }); + output.print("debugger"); + output.semicolon(); }); - DEFPRINT(AST_Bracketed, function(self, output){ - if (self.body.length > 0) output.with_block(function(){ - self.body.forEach(function(stmt){ + + /* -----[ statements ]----- */ + + function display_body(body, is_toplevel, output) { + body.forEach(function(stmt){ + if (!(stmt instanceof AST_EmptyStatement)) { output.indent(); stmt.print(output); output.newline(); - }); + if (is_toplevel) output.newline(); + } }); - else output.print("{}"); - }); - /* -----[ statements ]----- */ + }; + DEFPRINT(AST_Statement, function(self, output){ if (self.body instanceof AST_Node) { self.body.print(output); output.semicolon(); } else { - self.body.forEach(function(stmt){ - stmt.print(output); - output.newline(); - }); + display_body(self.body, self instanceof AST_Toplevel, output); } }); DEFPRINT(AST_LabeledStatement, function(self, output){ - output.print(self.label + ":"); - output.space(); + self.label.print(output); + output.colon(); self.statement.print(output); }); DEFPRINT(AST_SimpleStatement, function(self, output){ @@ -249,7 +375,10 @@ function OutputStream(options) { output.semicolon(); }); DEFPRINT(AST_BlockStatement, function(self, output){ - AST_Bracketed.prototype.print.call(self, output); + if (self.body.length > 0) output.with_block(function(){ + display_body(self.body, false, output); + }); + else output.print("{}"); }); DEFPRINT(AST_EmptyStatement, function(self, output){ output.semicolon(); @@ -260,8 +389,20 @@ function OutputStream(options) { self.body.print(output); output.space(); output.print("while"); - self.condition.print(output); - self.semicolon(); + output.space(); + output.with_parens(function(){ + self.condition.print(output); + }); + output.semicolon(); + }); + DEFPRINT(AST_While, function(self, output){ + output.print("while"); + output.space(); + output.with_parens(function(){ + self.condition.print(output); + }); + output.space(); + self.body.print(output); }); DEFPRINT(AST_For, function(self, output){ output.print("for"); @@ -269,17 +410,17 @@ function OutputStream(options) { output.with_parens(function(){ if (self.init) { self.init.print(output); - output.semicolon(); + output.print(";"); output.space(); } else { - output.semicolon(); + output.print(";"); } if (self.condition) { self.condition.print(output); - output.semicolon(); + output.print(";"); output.space(); } else { - output.semicolon(); + output.print(";"); } if (self.step) { self.step.print(output); @@ -312,11 +453,15 @@ function OutputStream(options) { output.space(); self.body.print(output); }); + /* -----[ functions ]----- */ - DEFPRINT(AST_Lambda, function(self, output){ - output.print("function"); - output.space(); + AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){ + var self = this; + if (!nokeyword) { + output.print("function"); + } if (self.name) { + output.space(); self.name.print(output); } output.with_parens(function(){ @@ -328,11 +473,17 @@ function OutputStream(options) { output.space(); self.body.print(output); }); + DEFPRINT(AST_Lambda, function(self, output){ + self._do_print(output); + }); + /* -----[ exits ]----- */ AST_Exit.DEFMETHOD("_do_print", function(output, kind){ output.print(kind); - output.space(); - this.value.print(output); + if (this.value) { + output.space(); + this.value.print(output); + } output.semicolon(); }); DEFPRINT(AST_Return, function(self, output){ @@ -341,6 +492,7 @@ function OutputStream(options) { DEFPRINT(AST_Throw, function(self, output){ self._do_print(output, "throw"); }); + /* -----[ loop control ]----- */ AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){ output.print(kind); @@ -356,6 +508,7 @@ function OutputStream(options) { DEFPRINT(AST_Continue, function(self, output){ self._do_print(output, "continue"); }); + /* -----[ if ]----- */ DEFPRINT(AST_If, function(self, output){ output.print("if"); @@ -366,10 +519,13 @@ function OutputStream(options) { output.space(); self.consequent.print(output); if (self.alternative) { + output.space(); + output.print("else"); output.space(); self.alternative.print(output); } }); + /* -----[ switch ]----- */ DEFPRINT(AST_Switch, function(self, output){ output.print("switch"); @@ -380,16 +536,28 @@ function OutputStream(options) { output.space(); self.body.print(output); }); + DEFPRINT(AST_SwitchBlock, function(self, output){ + if (self.body.length > 0) output.with_block(function(){ + self.body.forEach(function(stmt, i){ + if (i) output.newline(); + output.indent(true); + stmt.print(output); + }); + }); + else output.print("{}"); + }); AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){ - this.body.forEach(function(stmt){ - output.indent(); - stmt.print(output); + if (this.body.length > 0) { output.newline(); - }); + this.body.forEach(function(stmt){ + output.indent(); + stmt.print(output); + output.newline(); + }); + } }); DEFPRINT(AST_Default, function(self, output){ output.print("default:"); - output.newline(); self._do_print_body(output); }); DEFPRINT(AST_Case, function(self, output){ @@ -397,9 +565,9 @@ function OutputStream(options) { output.space(); self.expression.print(output); output.print(":"); - output.newline(); self._do_print_body(output); }); + /* -----[ exceptions ]----- */ DEFPRINT(AST_Try, function(self, output){ output.print("try"); @@ -417,6 +585,10 @@ function OutputStream(options) { DEFPRINT(AST_Catch, function(self, output){ output.print("catch"); output.space(); + output.with_parens(function(){ + self.argname.print(output); + }); + output.space(); self.body.print(output); }); DEFPRINT(AST_Finally, function(self, output){ @@ -424,6 +596,7 @@ function OutputStream(options) { output.space(); self.body.print(output); }); + /* -----[ var/const ]----- */ AST_Definitions.DEFMETHOD("_do_print", function(output, kind){ output.print(kind); @@ -432,7 +605,11 @@ function OutputStream(options) { if (i) output.comma(); def.print(output); }); - if (!this.inline) output.semicolon(); + var p = output.parent(); + var in_for = p instanceof AST_For || p instanceof AST_ForIn; + var avoid_semicolon = in_for && p.init === this; + if (!avoid_semicolon) + output.semicolon(); }); DEFPRINT(AST_Var, function(self, output){ self._do_print(output, "var"); @@ -449,16 +626,24 @@ function OutputStream(options) { self.value.print(output); } }); + /* -----[ other expressions ]----- */ DEFPRINT(AST_Call, function(self, output){ self.expression.print(output); + if (self instanceof AST_New && no_constructor_parens(self, output)) + return; output.with_parens(function(){ - self.args.forEach(function(arg, i){ + self.args.forEach(function(expr, i){ if (i) output.comma(); - arg.print(output); + expr.print(output); }); }); }); + function no_constructor_parens(self, output) { + return (self.args.length == 0 + // && !output.options("beautify") + ); + }; DEFPRINT(AST_New, function(self, output){ output.print("new"); output.space(); @@ -470,7 +655,12 @@ function OutputStream(options) { self.second.print(output); }); DEFPRINT(AST_Dot, function(self, output){ - self.expression.print(output); + var expr = self.expression; + expr.print(output); + if (expr instanceof AST_Number) { + if (!/[xa-f.]/i.test(output.last())) + output.print("."); + } output.print("."); output.print_name(self.property); }); @@ -488,43 +678,12 @@ function OutputStream(options) { self.expression.print(output); output.print(self.operator); }); - AST_Binary.DEFMETHOD("_do_print", function(output){ - this.left.print(output); + DEFPRINT(AST_Binary, function(self, output){ + self.left.print(output); output.space(); - output.print(this.operator); + output.print(self.operator); output.space(); - this.right.print(output); - }); - DEFPRINT(AST_Binary, function(self, output){ - var p = output.parent(); - if (p instanceof AST_Binary) { - var po = p.operator, pp = PRECEDENCE[po]; - var so = self.operator, sp = PRECEDENCE[so]; - if (pp > sp - || (pp == sp - && self === p.right - && !(so == po && - (so == "*" || - so == "&&" || - so == "||")))) { - output.with_parens(function(){ - self._do_print(output); - }); - return; - } - } - self._do_print(output); - }); - // XXX: this is quite similar as for AST_Binary, except for the parens. - DEFPRINT(AST_Assign, function(self, output){ - var p = output.parent(); - if (p instanceof AST_Binary) { - output.with_parens(function(){ - self._do_print(output); - }); - return; - } - self._do_print(output); + self.right.print(output); }); DEFPRINT(AST_Conditional, function(self, output){ self.condition.print(output); @@ -532,9 +691,11 @@ function OutputStream(options) { output.print("?"); output.space(); self.consequent.print(output); + output.space(); output.colon(); self.alternative.print(output); }); + /* -----[ literals ]----- */ DEFPRINT(AST_Array, function(self, output){ output.with_square(function(){ @@ -547,24 +708,43 @@ function OutputStream(options) { DEFPRINT(AST_Object, function(self, output){ if (self.properties.length > 0) output.with_block(function(){ self.properties.forEach(function(prop, i){ - if (i) output.comma(); + if (i) { + output.comma(); + output.newline(); + } output.indent(); prop.print(output); - output.newline(); }); + output.newline(); }); else output.print("{}"); }); DEFPRINT(AST_ObjectKeyVal, function(self, output){ - output.print_name(self.key); + var key = self.key; + if (output.options("quote_keys")) { + output.print_string(key); + } else if ((typeof key == "number" + || !output.options("beautify") + && +key + "" == key) + && parseFloat(key) >= 0) { + output.print(make_num(key)); + } else if (!is_identifier(key)) { + output.print_string(key); + } else { + output.print_name(key); + } output.colon(); self.value.print(output); }); DEFPRINT(AST_ObjectSetter, function(self, output){ - throw "not yet done"; + output.print("set"); + output.space(); + self.func._do_print(output, true); }); DEFPRINT(AST_ObjectGetter, function(self, output){ - throw "not yet done"; + output.print("get"); + output.space(); + self.func._do_print(output, true); }); DEFPRINT(AST_Symbol, function(self, output){ output.print_name(self.name); @@ -581,16 +761,69 @@ function OutputStream(options) { DEFPRINT(AST_String, function(self, output){ output.print_string(self.getValue()); }); + DEFPRINT(AST_Number, function(self, output){ + output.print(make_num(self.getValue())); + }); DEFPRINT(AST_RegExp, function(self, output){ output.print("/"); output.print(self.pattern); output.print("/"); if (self.mods) output.print(self.mods); }); -})(function DEF(nodetype, generator) { - nodetype.DEFMETHOD("print", function(stream){ - stream.push_node(this); - generator(this, stream); - stream.pop_node(); - }); -}); + + // return true if the node at the top of the stack (that means the + // innermost node in the current output) is lexically the first in + // a statement. + function first_in_statement(output) { + var a = output.stack(), i = a.length, node = a[--i], p = a[--i]; + while (i > 0) { + if (p instanceof AST_Statement) return true; + if ((p instanceof AST_Seq && p.first === node) || + (p instanceof AST_Call && p.expression === node) || + (p instanceof AST_Dot && p.expression === node) || + (p instanceof AST_Sub && p.expression === node) || + (p instanceof AST_Conditional && p.condition === node) || + (p instanceof AST_Binary && p.first === node) || + (p instanceof AST_Assign && p.first === node) || + (p instanceof AST_UnaryPostfix && p.expression === node)) + { + node = p; + p = a[--i]; + } else { + return false; + } + } + }; + + function best_of(a) { + var best = a[0], len = best.length; + for (var i = 1; i < a.length; ++i) { + if (a[i].length < len) { + best = a[i]; + len = best.length; + } + } + return best; + }; + + function make_num(num) { + var str = num.toString(10), a = [ str.replace(/^0\./, ".").replace('e+', 'e') ], m; + if (Math.floor(num) === num) { + if (num >= 0) { + a.push("0x" + num.toString(16).toLowerCase(), // probably pointless + "0" + num.toString(8)); // same. + } else { + a.push("-0x" + (-num).toString(16).toLowerCase(), // probably pointless + "-0" + (-num).toString(8)); // same. + } + if ((m = /^(.*?)(0+)$/.exec(num))) { + a.push(m[1] + "e" + m[2].length); + } + } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) { + a.push(m[2] + "e-" + (m[1].length + m[2].length), + str.substr(str.indexOf("."))); + } + return best_of(a); + }; + +})(); diff --git a/lib/parse.js b/lib/parse.js index 260c4117..f5796b0f 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -166,6 +166,14 @@ function is_unicode_connector_punctuation(ch) { return UNICODE.connector_punctuation.test(ch); }; +function is_identifier(name) { + return /^[a-z_$][a-z0-9_$]*$/i.test(name) + && name != "this" + && !HOP(KEYWORDS_ATOM, name) + && !HOP(RESERVED_WORDS, name) + && !HOP(KEYWORDS, name); +}; + function is_identifier_start(ch) { return ch == "$" || ch == "_" || is_letter(ch); }; @@ -695,11 +703,10 @@ function parse($TEXT, exigent_mode) { }; function parenthesised() { - return new AST_Parenthesized({ - start : expect("("), - expression : expression(), - end : expect(")") - }); + expect("("); + var exp = expression(); + expect(")"); + return exp; }; function embed_tokens(parser) { @@ -834,7 +841,7 @@ function parse($TEXT, exigent_mode) { S.labels.push(label); var start = S.token, stat = statement(); S.labels.pop(); - return new AST_LabeledStatement({ statement: stat }); + return new AST_LabeledStatement({ statement: stat, label: label }); }; function simple_statement() { @@ -866,9 +873,6 @@ function parse($TEXT, exigent_mode) { init = is("keyword", "var") ? (next(), var_(true)) : expression(true, true); - if (init instanceof AST_Var) { - init.inline = true; - } if (is("operator", "in")) { if (init instanceof AST_Var && init.definitions.length > 1) croak("Only one variable declaration allowed in for..in loop"); @@ -932,7 +936,7 @@ function parse($TEXT, exigent_mode) { --S.in_function; S.in_loop = loop; S.labels = labels; - return new AST_Bracketed({ body: a }); + return new AST_BlockStatement({ body: a }); })() }); }; @@ -997,7 +1001,7 @@ function parse($TEXT, exigent_mode) { })); function try_() { - var body = new AST_Bracketed({ + var body = new AST_BlockStatement({ start : S.token, body : block_(), end : prev() @@ -1011,7 +1015,7 @@ function parse($TEXT, exigent_mode) { bcatch = new AST_Catch({ start : start, argname : name, - body : new AST_Bracketed({ + body : new AST_BlockStatement({ start : S.token, body : block_(), end : prev() @@ -1024,7 +1028,7 @@ function parse($TEXT, exigent_mode) { next(); bfinally = new AST_Finally({ start : start, - body : new AST_Bracketed({ + body : new AST_BlockStatement({ start : S.token, body : block_(), end : prev() @@ -1191,7 +1195,7 @@ function parse($TEXT, exigent_mode) { var type = start.type; var name = as_property_name(); if (type == "name" && !is("punc", ":")) { - if (name.name == "get") { + if (name == "get") { a.push(new AST_ObjectGetter({ start : start, name : name, @@ -1200,7 +1204,7 @@ function parse($TEXT, exigent_mode) { })); continue; } - if (name.name == "set") { + if (name == "set") { a.push(new AST_ObjectSetter({ start : start, name : name, -- 2.34.1