removing the (now-unused) inherits helper, and adding a helper for creating LiteralNodes
This commit is contained in:
parent
56eb474bf3
commit
fec2eaef7e
44
lib/nodes.js
44
lib/nodes.js
|
@ -1,5 +1,5 @@
|
||||||
(function(){
|
(function(){
|
||||||
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IfNode, IndexNode, LiteralNode, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, ValueNode, WhileNode, compact, del, flatten, inherit, merge, statement;
|
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IfNode, IndexNode, LiteralNode, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, ValueNode, WhileNode, compact, del, flatten, literal, merge, statement;
|
||||||
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
|
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
|
||||||
var ctor = function(){ };
|
var ctor = function(){ };
|
||||||
ctor.prototype = parent.prototype;
|
ctor.prototype = parent.prototype;
|
||||||
|
@ -62,17 +62,9 @@
|
||||||
delete obj[key];
|
delete obj[key];
|
||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
// Quickie inheritance convenience wrapper to reduce typing.
|
// Quickie helper for a generated LiteralNode.
|
||||||
inherit = function inherit(parent, props) {
|
literal = function literal(name) {
|
||||||
var _a, klass, name, prop;
|
return new LiteralNode(name);
|
||||||
klass = del(props, 'constructor');
|
|
||||||
__extends(klass, parent);
|
|
||||||
_a = props;
|
|
||||||
for (name in _a) { if (__hasProp.call(_a, name)) {
|
|
||||||
prop = _a[name];
|
|
||||||
((klass.prototype[name] = prop));
|
|
||||||
}}
|
|
||||||
return klass;
|
|
||||||
};
|
};
|
||||||
// Mark a node as a statement, or a statement only.
|
// Mark a node as a statement, or a statement only.
|
||||||
statement = function statement(klass, only) {
|
statement = function statement(klass, only) {
|
||||||
|
@ -122,7 +114,7 @@
|
||||||
// in multiple places, ensure that the expression is only ever evaluated once.
|
// in multiple places, ensure that the expression is only ever evaluated once.
|
||||||
BaseNode.prototype.compile_reference = function compile_reference(o) {
|
BaseNode.prototype.compile_reference = function compile_reference(o) {
|
||||||
var compiled, reference;
|
var compiled, reference;
|
||||||
reference = new LiteralNode(o.scope.free_variable());
|
reference = literal(o.scope.free_variable());
|
||||||
compiled = new AssignNode(reference, this);
|
compiled = new AssignNode(reference, this);
|
||||||
return [compiled, reference];
|
return [compiled, reference];
|
||||||
};
|
};
|
||||||
|
@ -527,7 +519,7 @@
|
||||||
ExtendsNode.prototype.compile_node = function compile_node(o) {
|
ExtendsNode.prototype.compile_node = function compile_node(o) {
|
||||||
var call, ref;
|
var call, ref;
|
||||||
o.scope.assign('__extends', this.code, true);
|
o.scope.assign('__extends', this.code, true);
|
||||||
ref = new ValueNode(new LiteralNode('__extends'));
|
ref = new ValueNode(literal('__extends'));
|
||||||
call = new CallNode(ref, [this.child, this.parent]);
|
call = new CallNode(ref, [this.child, this.parent]);
|
||||||
return call.compile(o);
|
return call.compile(o);
|
||||||
};
|
};
|
||||||
|
@ -601,10 +593,10 @@
|
||||||
RangeNode.prototype.compile_array = function compile_array(o) {
|
RangeNode.prototype.compile_array = function compile_array(o) {
|
||||||
var arr, body, name;
|
var arr, body, name;
|
||||||
name = o.scope.free_variable();
|
name = o.scope.free_variable();
|
||||||
body = Expressions.wrap([new LiteralNode(name)]);
|
body = Expressions.wrap([literal(name)]);
|
||||||
arr = Expressions.wrap([new ForNode(body, {
|
arr = Expressions.wrap([new ForNode(body, {
|
||||||
source: (new ValueNode(this))
|
source: (new ValueNode(this))
|
||||||
}, new LiteralNode(name))
|
}, literal(name))
|
||||||
]);
|
]);
|
||||||
return (new ParentheticalNode(new CallNode(new CodeNode([], arr)))).compile(o);
|
return (new ParentheticalNode(new CallNode(new CodeNode([], arr)))).compile(o);
|
||||||
};
|
};
|
||||||
|
@ -699,7 +691,7 @@
|
||||||
prop = _a[_b];
|
prop = _a[_b];
|
||||||
if (prop.variable && prop.variable.base.value === 'constructor') {
|
if (prop.variable && prop.variable.base.value === 'constructor') {
|
||||||
func = prop.value;
|
func = prop.value;
|
||||||
func.body.push(new ReturnNode(new LiteralNode('this')));
|
func.body.push(new ReturnNode(literal('this')));
|
||||||
constructor = new AssignNode(this.variable, func);
|
constructor = new AssignNode(this.variable, func);
|
||||||
} else {
|
} else {
|
||||||
if (prop.variable) {
|
if (prop.variable) {
|
||||||
|
@ -711,8 +703,8 @@
|
||||||
}
|
}
|
||||||
if (!constructor) {
|
if (!constructor) {
|
||||||
if (this.parent) {
|
if (this.parent) {
|
||||||
applied = new ValueNode(this.parent, [new AccessorNode(new LiteralNode('apply'))]);
|
applied = new ValueNode(this.parent, [new AccessorNode(literal('apply'))]);
|
||||||
constructor = new AssignNode(this.variable, new CodeNode([], new Expressions([new CallNode(applied, [new LiteralNode('this'), new LiteralNode('arguments')])])));
|
constructor = new AssignNode(this.variable, new CodeNode([], new Expressions([new CallNode(applied, [literal('this'), literal('arguments')])])));
|
||||||
} else {
|
} else {
|
||||||
constructor = new AssignNode(this.variable, new CodeNode());
|
constructor = new AssignNode(this.variable, new CodeNode());
|
||||||
}
|
}
|
||||||
|
@ -771,7 +763,7 @@
|
||||||
})) {
|
})) {
|
||||||
return expressions;
|
return expressions;
|
||||||
}
|
}
|
||||||
return Expressions.wrap([new CallNode(new ValueNode(new LiteralNode(array), [new AccessorNode(new LiteralNode('push'))]), [expr])]);
|
return Expressions.wrap([new CallNode(new ValueNode(literal(array), [new AccessorNode(literal('push'))]), [expr])]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// A faux-node used to wrap an expressions body in a closure.
|
// A faux-node used to wrap an expressions body in a closure.
|
||||||
|
@ -779,7 +771,7 @@
|
||||||
wrap: function wrap(expressions, statement) {
|
wrap: function wrap(expressions, statement) {
|
||||||
var call, func;
|
var call, func;
|
||||||
func = new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])));
|
func = new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])));
|
||||||
call = new CallNode(new ValueNode(func, [new AccessorNode(new LiteralNode('call'))]), [new LiteralNode('this')]);
|
call = new CallNode(new ValueNode(func, [new AccessorNode(literal('call'))]), [literal('this')]);
|
||||||
return statement ? Expressions.wrap([call]) : call;
|
return statement ? Expressions.wrap([call]) : call;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -864,12 +856,12 @@
|
||||||
}
|
}
|
||||||
access_class = this.variable.is_array() ? IndexNode : AccessorNode;
|
access_class = this.variable.is_array() ? IndexNode : AccessorNode;
|
||||||
if (obj instanceof SplatNode) {
|
if (obj instanceof SplatNode) {
|
||||||
val = new LiteralNode(obj.compile_value(o, val_var, this.variable.base.objects.indexOf(obj)));
|
val = literal(obj.compile_value(o, val_var, this.variable.base.objects.indexOf(obj)));
|
||||||
} else {
|
} else {
|
||||||
if (!(typeof idx === 'object')) {
|
if (!(typeof idx === 'object')) {
|
||||||
idx = new LiteralNode(idx);
|
idx = literal(idx);
|
||||||
}
|
}
|
||||||
val = new ValueNode(new LiteralNode(val_var), [new access_class(idx)]);
|
val = new ValueNode(literal(val_var), [new access_class(idx)]);
|
||||||
}
|
}
|
||||||
assigns.push(new AssignNode(obj, val).compile(o));
|
assigns.push(new AssignNode(obj, val).compile(o));
|
||||||
}
|
}
|
||||||
|
@ -979,7 +971,7 @@
|
||||||
exports.SplatNode = (function() {
|
exports.SplatNode = (function() {
|
||||||
SplatNode = function SplatNode(name) {
|
SplatNode = function SplatNode(name) {
|
||||||
if (!(name.compile)) {
|
if (!(name.compile)) {
|
||||||
name = new LiteralNode(name);
|
name = literal(name);
|
||||||
}
|
}
|
||||||
this.children = [(this.name = name)];
|
this.children = [(this.name = name)];
|
||||||
return this;
|
return this;
|
||||||
|
@ -1367,7 +1359,7 @@
|
||||||
var _a, _b, _c, assigner, cond, i, variable;
|
var _a, _b, _c, assigner, cond, i, variable;
|
||||||
assigner = this.switcher;
|
assigner = this.switcher;
|
||||||
if (!(this.switcher.unwrap() instanceof LiteralNode)) {
|
if (!(this.switcher.unwrap() instanceof LiteralNode)) {
|
||||||
variable = new LiteralNode(o.scope.free_variable());
|
variable = literal(o.scope.free_variable());
|
||||||
assigner = new AssignNode(variable, this.switcher);
|
assigner = new AssignNode(variable, this.switcher);
|
||||||
this.switcher = variable;
|
this.switcher = variable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,9 @@ del: (obj, key) ->
|
||||||
delete obj[key]
|
delete obj[key]
|
||||||
val
|
val
|
||||||
|
|
||||||
# Quickie inheritance convenience wrapper to reduce typing.
|
# Quickie helper for a generated LiteralNode.
|
||||||
inherit: (parent, props) ->
|
literal: (name) ->
|
||||||
klass: del(props, 'constructor')
|
new LiteralNode(name)
|
||||||
klass extends parent
|
|
||||||
(klass.prototype[name]: prop) for name, prop of props
|
|
||||||
klass
|
|
||||||
|
|
||||||
# Mark a node as a statement, or a statement only.
|
# Mark a node as a statement, or a statement only.
|
||||||
statement: (klass, only) ->
|
statement: (klass, only) ->
|
||||||
|
@ -82,7 +79,7 @@ exports.BaseNode: class BaseNode
|
||||||
# If the code generation wishes to use the result of a complex expression
|
# If the code generation wishes to use the result of a complex expression
|
||||||
# in multiple places, ensure that the expression is only ever evaluated once.
|
# in multiple places, ensure that the expression is only ever evaluated once.
|
||||||
compile_reference: (o) ->
|
compile_reference: (o) ->
|
||||||
reference: new LiteralNode(o.scope.free_variable())
|
reference: literal(o.scope.free_variable())
|
||||||
compiled: new AssignNode(reference, this)
|
compiled: new AssignNode(reference, this)
|
||||||
[compiled, reference]
|
[compiled, reference]
|
||||||
|
|
||||||
|
@ -387,7 +384,7 @@ exports.ExtendsNode: class ExtendsNode extends BaseNode
|
||||||
# Hooking one constructor into another's prototype chain.
|
# Hooking one constructor into another's prototype chain.
|
||||||
compile_node: (o) ->
|
compile_node: (o) ->
|
||||||
o.scope.assign('__extends', @code, true)
|
o.scope.assign('__extends', @code, true)
|
||||||
ref: new ValueNode new LiteralNode '__extends'
|
ref: new ValueNode literal('__extends')
|
||||||
call: new CallNode ref, [@child, @parent]
|
call: new CallNode ref, [@child, @parent]
|
||||||
call.compile(o)
|
call.compile(o)
|
||||||
|
|
||||||
|
@ -451,8 +448,8 @@ exports.RangeNode: class RangeNode extends BaseNode
|
||||||
# TODO: This generates pretty ugly code ... shrink it.
|
# TODO: This generates pretty ugly code ... shrink it.
|
||||||
compile_array: (o) ->
|
compile_array: (o) ->
|
||||||
name: o.scope.free_variable()
|
name: o.scope.free_variable()
|
||||||
body: Expressions.wrap([new LiteralNode(name)])
|
body: Expressions.wrap([literal(name)])
|
||||||
arr: Expressions.wrap([new ForNode(body, {source: (new ValueNode(this))}, new LiteralNode(name))])
|
arr: Expressions.wrap([new ForNode(body, {source: (new ValueNode(this))}, literal(name))])
|
||||||
(new ParentheticalNode(new CallNode(new CodeNode([], arr)))).compile(o)
|
(new ParentheticalNode(new CallNode(new CodeNode([], arr)))).compile(o)
|
||||||
|
|
||||||
|
|
||||||
|
@ -515,7 +512,7 @@ exports.ClassNode: class ClassNode extends BaseNode
|
||||||
for prop in @properties
|
for prop in @properties
|
||||||
if prop.variable and prop.variable.base.value is 'constructor'
|
if prop.variable and prop.variable.base.value is 'constructor'
|
||||||
func: prop.value
|
func: prop.value
|
||||||
func.body.push(new ReturnNode(new LiteralNode('this')))
|
func.body.push(new ReturnNode(literal('this')))
|
||||||
constructor: new AssignNode(@variable, func)
|
constructor: new AssignNode(@variable, func)
|
||||||
else
|
else
|
||||||
if prop.variable
|
if prop.variable
|
||||||
|
@ -525,9 +522,9 @@ exports.ClassNode: class ClassNode extends BaseNode
|
||||||
|
|
||||||
if not constructor
|
if not constructor
|
||||||
if @parent
|
if @parent
|
||||||
applied: new ValueNode(@parent, [new AccessorNode(new LiteralNode('apply'))])
|
applied: new ValueNode(@parent, [new AccessorNode(literal('apply'))])
|
||||||
constructor: new AssignNode(@variable, new CodeNode([], new Expressions([
|
constructor: new AssignNode(@variable, new CodeNode([], new Expressions([
|
||||||
new CallNode(applied, [new LiteralNode('this'), new LiteralNode('arguments')])
|
new CallNode(applied, [literal('this'), literal('arguments')])
|
||||||
])))
|
])))
|
||||||
else
|
else
|
||||||
constructor: new AssignNode(@variable, new CodeNode())
|
constructor: new AssignNode(@variable, new CodeNode())
|
||||||
|
@ -571,7 +568,7 @@ PushNode: exports.PushNode: {
|
||||||
expr: expressions.unwrap()
|
expr: expressions.unwrap()
|
||||||
return expressions if expr.is_statement_only() or expr.contains (n) -> n.is_statement_only()
|
return expressions if expr.is_statement_only() or expr.contains (n) -> n.is_statement_only()
|
||||||
Expressions.wrap([new CallNode(
|
Expressions.wrap([new CallNode(
|
||||||
new ValueNode(new LiteralNode(array), [new AccessorNode(new LiteralNode('push'))]), [expr]
|
new ValueNode(literal(array), [new AccessorNode(literal('push'))]), [expr]
|
||||||
)])
|
)])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -582,7 +579,7 @@ ClosureNode: exports.ClosureNode: {
|
||||||
|
|
||||||
wrap: (expressions, statement) ->
|
wrap: (expressions, statement) ->
|
||||||
func: new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])))
|
func: new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])))
|
||||||
call: new CallNode(new ValueNode(func, [new AccessorNode(new LiteralNode('call'))]), [new LiteralNode('this')])
|
call: new CallNode(new ValueNode(func, [new AccessorNode(literal('call'))]), [literal('this')])
|
||||||
if statement then Expressions.wrap([call]) else call
|
if statement then Expressions.wrap([call]) else call
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -642,10 +639,10 @@ exports.AssignNode: class AssignNode extends BaseNode
|
||||||
[obj, idx]: [obj.value, obj.variable.base] if @variable.is_object()
|
[obj, idx]: [obj.value, obj.variable.base] if @variable.is_object()
|
||||||
access_class: if @variable.is_array() then IndexNode else AccessorNode
|
access_class: if @variable.is_array() then IndexNode else AccessorNode
|
||||||
if obj instanceof SplatNode
|
if obj instanceof SplatNode
|
||||||
val: new LiteralNode(obj.compile_value(o, val_var, @variable.base.objects.indexOf(obj)))
|
val: literal(obj.compile_value(o, val_var, @variable.base.objects.indexOf(obj)))
|
||||||
else
|
else
|
||||||
idx: new LiteralNode(idx) unless typeof idx is 'object'
|
idx: literal(idx) unless typeof idx is 'object'
|
||||||
val: new ValueNode(new LiteralNode(val_var), [new access_class(idx)])
|
val: new ValueNode(literal(val_var), [new access_class(idx)])
|
||||||
assigns.push(new AssignNode(obj, val).compile(o))
|
assigns.push(new AssignNode(obj, val).compile(o))
|
||||||
code: assigns.join("\n")
|
code: assigns.join("\n")
|
||||||
code += '\n' + @idt() + 'return ' + @variable.compile(o) + ';' if o.returns
|
code += '\n' + @idt() + 'return ' + @variable.compile(o) + ';' if o.returns
|
||||||
|
@ -715,7 +712,7 @@ exports.SplatNode: class SplatNode extends BaseNode
|
||||||
type: 'Splat'
|
type: 'Splat'
|
||||||
|
|
||||||
constructor: (name) ->
|
constructor: (name) ->
|
||||||
name: new LiteralNode(name) unless name.compile
|
name: literal(name) unless name.compile
|
||||||
@children: [@name: name]
|
@children: [@name: name]
|
||||||
|
|
||||||
compile_node: (o) ->
|
compile_node: (o) ->
|
||||||
|
@ -1001,7 +998,7 @@ exports.IfNode: class IfNode extends BaseNode
|
||||||
rewrite_switch: (o) ->
|
rewrite_switch: (o) ->
|
||||||
assigner: @switcher
|
assigner: @switcher
|
||||||
if not (@switcher.unwrap() instanceof LiteralNode)
|
if not (@switcher.unwrap() instanceof LiteralNode)
|
||||||
variable: new LiteralNode(o.scope.free_variable())
|
variable: literal(o.scope.free_variable())
|
||||||
assigner: new AssignNode(variable, @switcher)
|
assigner: new AssignNode(variable, @switcher)
|
||||||
@switcher: variable
|
@switcher: variable
|
||||||
@condition: if @multiple
|
@condition: if @multiple
|
||||||
|
|
Loading…
Reference in New Issue