Self-compiler can compile splats.

This commit is contained in:
Jeremy Ashkenas
2010-02-09 21:44:34 -05:00
parent ae4f6309e8
commit fd80d784f4
4 changed files with 41 additions and 4 deletions

View File

@@ -1,5 +1,5 @@
(function(){ (function(){
var AccessorNode, ArrayNode, AssignNode, CallNode, ClosureNode, CodeNode, CommentNode, Expressions, ExtendsNode, IndexNode, LiteralNode, Node, ObjectNode, PushNode, RangeNode, ReturnNode, SliceNode, TAB, TRAILING_WHITESPACE, ThisNode, ValueNode, any, compact, del, dup, flatten, inherit, merge, statement; var AccessorNode, ArrayNode, AssignNode, CallNode, ClosureNode, CodeNode, CommentNode, Expressions, ExtendsNode, IndexNode, LiteralNode, Node, ObjectNode, PushNode, RangeNode, ReturnNode, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThisNode, ValueNode, any, compact, del, dup, flatten, inherit, merge, statement;
var __hasProp = Object.prototype.hasOwnProperty; var __hasProp = Object.prototype.hasOwnProperty;
process.mixin(require('./scope')); process.mixin(require('./scope'));
// The abstract base class for all CoffeeScript nodes. // The abstract base class for all CoffeeScript nodes.
@@ -980,4 +980,22 @@
return true; return true;
} }
})); }));
// A splat, either as a parameter to a function, an argument to a call,
// or in a destructuring assignment.
SplatNode = (exports.SplatNode = inherit(Node, {
constructor: function constructor(name) {
this.children = [(this.name = name)];
return this;
},
compile_node: function compile_node(o) {
return this.index ? this.compile_param(o) : this.name.compile(o);
},
compile_param: function compile_param(o) {
o.scope.find(this.name);
return this.name + ' = Array.prototype.slice.call(arguments, ' + this.index + ')';
},
compile_value: function compile_value(o, name, index) {
return "Array.prototype.slice.call(" + this.name + ', ' + this.index + ')';
}
}));
})(); })();

View File

@@ -196,8 +196,8 @@
// A Parameter (or ParamSplat) in a function definition. // A Parameter (or ParamSplat) in a function definition.
Param: [o("PARAM", function() { Param: [o("PARAM", function() {
return yytext; return yytext;
}), o("PARAM . . .", function() { }), o("Param . . .", function() {
return new SplatNode(yytext); return new SplatNode($1);
}) })
], ],
// A regular splat. // A regular splat.

View File

@@ -691,6 +691,25 @@ CodeNode: exports.CodeNode: inherit Node, {
} }
# A splat, either as a parameter to a function, an argument to a call,
# or in a destructuring assignment.
SplatNode: exports.SplatNode: inherit Node, {
constructor: (name) ->
@children: [@name: name]
this
compile_node: (o) ->
if @index then @compile_param(o) else @name.compile(o)
compile_param: (o) ->
o.scope.find @name
@name + ' = Array.prototype.slice.call(arguments, ' + @index + ')'
compile_value: (o, name, index) ->
"Array.prototype.slice.call(" + @name + ', ' + @index + ')'
}

View File

@@ -221,7 +221,7 @@ grammar: {
# A Parameter (or ParamSplat) in a function definition. # A Parameter (or ParamSplat) in a function definition.
Param: [ Param: [
o "PARAM", -> yytext o "PARAM", -> yytext
o "PARAM . . .", -> new SplatNode(yytext) o "Param . . .", -> new SplatNode($1)
] ]
# A regular splat. # A regular splat.