aboutsummaryrefslogtreecommitdiff
path: root/lib/ast.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ast.js')
-rw-r--r--lib/ast.js137
1 files changed, 66 insertions, 71 deletions
diff --git a/lib/ast.js b/lib/ast.js
index 1a77a59d..c37ba598 100644
--- a/lib/ast.js
+++ b/lib/ast.js
@@ -44,21 +44,21 @@
"use strict";
function DEFNODE(type, props, methods, base) {
- if (arguments.length < 4) base = AST_Node;
- if (!props) props = [];
- else props = props.split(/\s+/);
+ if (typeof base === "undefined") base = AST_Node;
+ props = props ? props.split(/\s+/) : [];
var self_props = props;
- if (base && base.PROPS)
- props = props.concat(base.PROPS);
- var code = "return function AST_" + type + "(props){ if (props) { ";
- for (var i = props.length; --i >= 0;) {
- code += "this." + props[i] + " = props." + props[i] + ";";
- }
+ if (base && base.PROPS) props = props.concat(base.PROPS);
+ var code = [
+ "return function AST_", type, "(props){",
+ "if(props){",
+ ];
+ props.forEach(function(prop) {
+ code.push("this.", prop, "=props.", prop, ";");
+ });
var proto = base && new base;
- if (proto && proto.initialize || (methods && methods.initialize))
- code += "this.initialize();";
- code += "}}";
- var ctor = new Function(code)();
+ if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();");
+ code.push("}}");
+ var ctor = new Function(code.join(""))();
if (proto) {
ctor.prototype = proto;
ctor.BASE = base;
@@ -71,11 +71,11 @@ function DEFNODE(type, props, methods, base) {
if (type) {
ctor.prototype.TYPE = ctor.TYPE = type;
}
- if (methods) for (i in methods) if (HOP(methods, i)) {
- if (/^\$/.test(i)) {
- ctor[i.substr(1)] = methods[i];
+ if (methods) for (var name in methods) if (HOP(methods, name)) {
+ if (/^\$/.test(name)) {
+ ctor[name.substr(1)] = methods[name];
} else {
- ctor.prototype[i] = methods[i];
+ ctor.prototype[name] = methods[name];
}
}
ctor.DEFMETHOD = function(name, method) {
@@ -85,7 +85,7 @@ function DEFNODE(type, props, methods, base) {
exports["AST_" + type] = ctor;
}
return ctor;
-};
+}
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before comments_after file raw", {
}, null);
@@ -148,7 +148,7 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.body._walk(visitor);
});
}
@@ -158,11 +158,10 @@ function walk_body(node, visitor) {
var body = node.body;
if (body instanceof AST_Statement) {
body._walk(visitor);
- }
- else for (var i = 0, len = body.length; i < len; i++) {
- body[i]._walk(visitor);
- }
-};
+ } else body.forEach(function(node) {
+ node._walk(visitor);
+ });
+}
var AST_Block = DEFNODE("Block", "body", {
$documentation: "A body of statements (usually braced)",
@@ -170,7 +169,7 @@ var AST_Block = DEFNODE("Block", "body", {
body: "[AST_Statement*] an array of statements"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
walk_body(this, visitor);
});
}
@@ -197,7 +196,7 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
label: "[AST_Label] a label definition"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.label._walk(visitor);
this.body._walk(visitor);
});
@@ -233,7 +232,7 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
var AST_Do = DEFNODE("Do", null, {
$documentation: "A `do` statement",
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.body._walk(visitor);
this.condition._walk(visitor);
});
@@ -243,7 +242,7 @@ var AST_Do = DEFNODE("Do", null, {
var AST_While = DEFNODE("While", null, {
$documentation: "A `while` statement",
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.condition._walk(visitor);
this.body._walk(visitor);
});
@@ -258,7 +257,7 @@ var AST_For = DEFNODE("For", "init condition step", {
step: "[AST_Node?] the `for` update clause, or null if empty"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
if (this.init) this.init._walk(visitor);
if (this.condition) this.condition._walk(visitor);
if (this.step) this.step._walk(visitor);
@@ -274,7 +273,7 @@ var AST_ForIn = DEFNODE("ForIn", "init object", {
object: "[AST_Node] the object that we're looping through"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.init._walk(visitor);
this.object._walk(visitor);
this.body._walk(visitor);
@@ -288,7 +287,7 @@ var AST_With = DEFNODE("With", "expression", {
expression: "[AST_Node] the `with` expression"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.expression._walk(visitor);
this.body._walk(visitor);
});
@@ -329,7 +328,7 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
var body = this.body;
var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
wrapped_tl = parse(wrapped_tl);
- wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
+ wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node) {
if (node instanceof AST_Directive && node.value == "$ORIG") {
return MAP.splice(body);
}
@@ -363,12 +362,11 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
if (this.name) this.name._walk(visitor);
- var argnames = this.argnames;
- for (var i = 0, len = argnames.length; i < len; i++) {
- argnames[i]._walk(visitor);
- }
+ this.argnames.forEach(function(argname) {
+ argname._walk(visitor);
+ });
walk_body(this, visitor);
});
}
@@ -398,7 +396,7 @@ var AST_Exit = DEFNODE("Exit", "value", {
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
},
_walk: function(visitor) {
- return visitor._visit(this, this.value && function(){
+ return visitor._visit(this, this.value && function() {
this.value._walk(visitor);
});
}
@@ -418,7 +416,7 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
label: "[AST_LabelRef?] the label, or null if none",
},
_walk: function(visitor) {
- return visitor._visit(this, this.label && function(){
+ return visitor._visit(this, this.label && function() {
this.label._walk(visitor);
});
}
@@ -441,7 +439,7 @@ var AST_If = DEFNODE("If", "condition alternative", {
alternative: "[AST_Statement?] the `else` part, or null if not present"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.condition._walk(visitor);
this.body._walk(visitor);
if (this.alternative) this.alternative._walk(visitor);
@@ -457,7 +455,7 @@ var AST_Switch = DEFNODE("Switch", "expression", {
expression: "[AST_Node] the `switch` “discriminant”"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.expression._walk(visitor);
walk_body(this, visitor);
});
@@ -478,7 +476,7 @@ var AST_Case = DEFNODE("Case", "expression", {
expression: "[AST_Node] the `case` expression"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.expression._walk(visitor);
walk_body(this, visitor);
});
@@ -494,7 +492,7 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
bfinally: "[AST_Finally?] the finally block, or null if not present"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
walk_body(this, visitor);
if (this.bcatch) this.bcatch._walk(visitor);
if (this.bfinally) this.bfinally._walk(visitor);
@@ -508,7 +506,7 @@ var AST_Catch = DEFNODE("Catch", "argname", {
argname: "[AST_SymbolCatch] symbol for the exception"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.argname._walk(visitor);
walk_body(this, visitor);
});
@@ -527,11 +525,10 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
definitions: "[AST_VarDef*] array of variable definitions"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
- var definitions = this.definitions;
- for (var i = 0, len = definitions.length; i < len; i++) {
- definitions[i]._walk(visitor);
- }
+ return visitor._visit(this, function() {
+ this.definitions.forEach(function(defn) {
+ defn._walk(visitor);
+ });
});
}
}, AST_Statement);
@@ -547,7 +544,7 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
value: "[AST_Node?] initializer, or null of there's no initializer"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.name._walk(visitor);
if (this.value) this.value._walk(visitor);
});
@@ -582,7 +579,7 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
expressions: "[AST_Node*] array of expressions (at least two)"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.expressions.forEach(function(node) {
node._walk(visitor);
});
@@ -601,7 +598,7 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
var AST_Dot = DEFNODE("Dot", null, {
$documentation: "A dotted property access expression",
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.expression._walk(visitor);
});
}
@@ -610,7 +607,7 @@ var AST_Dot = DEFNODE("Dot", null, {
var AST_Sub = DEFNODE("Sub", null, {
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.expression._walk(visitor);
this.property._walk(visitor);
});
@@ -624,7 +621,7 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
expression: "[AST_Node] expression that this unary operator applies to"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.expression._walk(visitor);
});
}
@@ -646,7 +643,7 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
right: "[AST_Node] right-hand side expression"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.left._walk(visitor);
this.right._walk(visitor);
});
@@ -661,7 +658,7 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
alternative: "[AST_Node]"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.condition._walk(visitor);
this.consequent._walk(visitor);
this.alternative._walk(visitor);
@@ -681,11 +678,10 @@ var AST_Array = DEFNODE("Array", "elements", {
elements: "[AST_Node*] array of elements"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
- var elements = this.elements;
- for (var i = 0, len = elements.length; i < len; i++) {
- elements[i]._walk(visitor);
- }
+ return visitor._visit(this, function() {
+ this.elements.forEach(function(element) {
+ element._walk(visitor);
+ });
});
}
});
@@ -696,11 +692,10 @@ var AST_Object = DEFNODE("Object", "properties", {
properties: "[AST_ObjectProperty*] array of properties"
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
- var properties = this.properties;
- for (var i = 0, len = properties.length; i < len; i++) {
- properties[i]._walk(visitor);
- }
+ return visitor._visit(this, function() {
+ this.properties.forEach(function(prop) {
+ prop._walk(visitor);
+ });
});
}
});
@@ -712,7 +707,7 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor."
},
_walk: function(visitor) {
- return visitor._visit(this, function(){
+ return visitor._visit(this, function() {
this.value._walk(visitor);
});
}
@@ -839,12 +834,12 @@ var AST_NaN = DEFNODE("NaN", null, {
var AST_Undefined = DEFNODE("Undefined", null, {
$documentation: "The `undefined` value",
- value: (function(){}())
+ value: function(){}()
}, AST_Atom);
var AST_Hole = DEFNODE("Hole", null, {
$documentation: "A hole in an array",
- value: (function(){}())
+ value: function(){}()
}, AST_Atom);
var AST_Infinity = DEFNODE("Infinity", null, {
@@ -872,11 +867,11 @@ function TreeWalker(callback) {
this.visit = callback;
this.stack = [];
this.directives = Object.create(null);
-};
+}
TreeWalker.prototype = {
_visit: function(node, descend) {
this.push(node);
- var ret = this.visit(node, descend ? function(){
+ var ret = this.visit(node, descend ? function() {
descend.call(node);
} : noop);
if (!ret && descend) {