Skip to content
Browse files

add a TameTailCall class so that tail calls aren't ad-hoc. Eventually…

… they'll return a value.
  • Loading branch information...
1 parent 3e1cca8 commit 8247386539eefc7bf5e0da7959ac0a16fb09f613 @maxtaco committed
Showing with 39 additions and 13 deletions.
  1. +23 −8 lib/coffee-script/nodes.js
  2. +16 −5 src/nodes.coffee
View
31 lib/coffee-script/nodes.js
@@ -1,5 +1,5 @@
(function() {
- var Access, Arr, Assign, Await, Base, Block, Call, Class, Closure, Code, Comment, CpsCascade, Defer, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, InlineDeferral, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, Scope, Slice, Slot, Splat, Switch, TAB, TAME_CALL_CONTINUATION, THIS, TameRequire, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, tame, unfoldSoak, utility, _ref,
+ var Access, Arr, Assign, Await, Base, Block, Call, Class, Closure, Code, Comment, CpsCascade, Defer, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, InlineDeferral, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, Scope, Slice, Slot, Splat, Switch, TAB, THIS, TameRequire, TameTailCall, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, tame, unfoldSoak, utility, _ref,
__hasProp = Object.prototype.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; },
__indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; };
@@ -31,10 +31,6 @@
return this;
};
- TAME_CALL_CONTINUATION = function() {
- return new Call(new Literal(tame["const"].k, []));
- };
-
exports.Base = Base = (function() {
function Base() {}
@@ -2119,7 +2115,7 @@
While.prototype.tameCallContinuation = function() {
var k;
- k = new Call(new Literal(tame["const"].c_while, []));
+ k = new TameTailCall(tame["const"].c_while);
return this.body.push(k);
};
@@ -3075,7 +3071,7 @@
Switch.prototype.tameCallContinuation = function() {
var block, code, condition, _i, _len, _ref2, _ref3, _ref4;
- code = TAME_CALL_CONTINUATION();
+ code = new TameTailCall;
_ref2 = this.cases;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
_ref3 = _ref2[_i], condition = _ref3[0], block = _ref3[1];
@@ -3153,7 +3149,7 @@
If.prototype.tameCallContinuation = function() {
var code;
- code = TAME_CALL_CONTINUATION();
+ code = new TameTailCall;
if (this.elseBody) {
this.elseBody.push(code);
this.isChain = false;
@@ -3281,6 +3277,25 @@
}
};
+ TameTailCall = (function(_super) {
+
+ __extends(TameTailCall, _super);
+
+ function TameTailCall(func) {
+ this.func = func;
+ if (!this.func) this.func = tame["const"].k;
+ }
+
+ TameTailCall.prototype.compileNode = function(o) {
+ var s;
+ s = new Call(new Literal(this.func, []));
+ return s.compileNode(o);
+ };
+
+ return TameTailCall;
+
+ })(Base);
+
InlineDeferral = {
generate: function() {
var a1, af, apply_call, assignments, body, call_meth, cn, cnt, cnt_member, constructor_assign, constructor_body, constructor_code, constructor_name, constructor_params, decr, defer_assign, defer_body, defer_code, defer_name, defer_params, dp, if_body, if_cond, if_expr, inc, inner_body, inner_code, inner_params, ip, k, k_member, klass, klass_assign, my_apply, my_if, my_null, ns, ns_obj, ns_val, obj, p1, _fulfill_assign, _fulfill_body, _fulfill_call, _fulfill_code, _fulfill_method, _fulfill_name;
View
21 src/nodes.coffee
@@ -19,8 +19,6 @@ NO = -> no
THIS = -> this
NEGATE = -> @negated = not @negated; this
-TAME_CALL_CONTINUATION = -> new Call(new Literal tame.const.k, [])
-
#### Base
# The **Base** is the abstract base class for all nodes in the syntax tree.
@@ -1737,7 +1735,7 @@ exports.While = class While extends Base
top_block = new Block top_statements
tameCallContinuation : ->
- k = new Call(new Literal tame.const.c_while, [])
+ k = new TameTailCall tame.const.c_while
@body.push k
compileTame: (o) ->
@@ -2529,7 +2527,7 @@ exports.Switch = class Switch extends Base
this
tameCallContinuation : ->
- code = TAME_CALL_CONTINUATION()
+ code = new TameTailCall
for [condition,block] in @cases
block.push code
@otherwise?.push code
@@ -2582,7 +2580,7 @@ exports.If = class If extends Base
# note this prevents if ...else if... inline chaining, and makes it
# fully nested if { .. } else { if { } ..} ..'s
tameCallContinuation : ->
- code = TAME_CALL_CONTINUATION()
+ code = new TameTailCall
if @elseBody
@elseBody.push code
@isChain = false
@@ -2698,6 +2696,19 @@ CpsCascade =
call = new Call func, [ cont ]
new Block [ call ]
+#### TailCall
+#
+# At the end of a tamed if, loop, or switch statement, we tail call off
+# to the next continuation
+
+class TameTailCall extends Base
+ constructor : (@func) ->
+ @func = tame.const.k unless @func
+
+ compileNode : (o) ->
+ s = new Call(new Literal @func, [])
+ s.compileNode o
+
#### Deferral class, the most basic one...
InlineDeferral =

0 comments on commit 8247386

Please sign in to comment.
Something went wrong with that request. Please try again.