Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fixed a deep bug, in which we weren't recursing properly on the the r…

…otations. added a little optimization. started on While
  • Loading branch information...
commit 30445b70814326bee4b0c173fd7f9433236b3423 1 parent e31e9bf
Maxwell Krohn authored
26 lib/coffee-script/nodes.js
View
@@ -64,9 +64,7 @@
var node, ret;
this.gotCpsSplit = true;
node = CpsCascade.wrap(this, this.tameContinuationBlock);
- console.log("yo INDENT" + o.indent + "TNEDNI");
ret = node.compile(o);
- console.log("yo TAB" + node.tab + "BAT");
return ret;
};
@@ -347,6 +345,15 @@
return this;
};
+ Block.prototype.compileCps = function(o) {
+ this.gotCpsSplit = true;
+ if (this.expressions.length > 1) {
+ return Block.__super__.compileCps.call(this, o);
+ } else {
+ return this.compileNode(o);
+ }
+ };
+
Block.prototype.compile = function(o, level) {
if (o == null) o = {};
if (o.scope) {
@@ -436,8 +443,9 @@
};
Block.prototype.cpsRotate = function() {
- var child, e, i, pivot, rest, _i, _len, _ref2;
+ var child, e, i, pivot, rest, _i, _j, _len, _len2, _ref2;
pivot = null;
+ child = null;
if (this.hasTaming) {
i = 0;
_ref2 = this.expressions;
@@ -451,12 +459,18 @@
}
}
if (pivot) {
+ console.log("found pvito");
pivot.floodCpsTranslation();
rest = this.expressions.slice(i + 1);
this.expressions = this.expressions.slice(0, i + 1);
if (rest.length) {
child = new Block(rest);
pivot.tameNestContinuationBlock(child);
+ for (_j = 0, _len2 = rest.length; _j < _len2; _j++) {
+ e = rest[_j];
+ if (e.hasTaming) child.hasTaming = true;
+ }
+ child.cpsRotate();
}
pivot.callContinuation();
}
@@ -1820,6 +1834,12 @@
return false;
};
+ While.prototype.callContinuation = function() {
+ var k;
+ k = new Call(new Literal(tame["const"].k_while, []));
+ return this.body.push(k);
+ };
+
While.prototype.compileNode = function(o) {
var body, code, rvar, set;
o.indent += TAB;
3  lib/coffee-script/tame.js
View
@@ -22,7 +22,8 @@
ns: "tame",
Deferrals: "Deferrals",
deferrals: "__tame_deferrals",
- fulfill: "_fulfill"
+ fulfill: "_fulfill",
+ k_while: "_kw"
};
}).call(this);
34 src/nodes.coffee
View
@@ -129,7 +129,7 @@ exports.Base = class Base
extras += "C"
if extras.length
extras = " (" + extras + ")"
- tree = '\n' + idt + name
+ tree = '\n' + idt + name
tree += '?' if @soak
tree += extras
@eachChild (node) -> tree += node.toString idt + TAB
@@ -173,7 +173,7 @@ exports.Base = class Base
# when considering the children
walkTaming : ->
@hasTaming = false
- for child in @flattenChildren()
+ for child in @flattenChildren()
@hasTaming = true if child.walkTaming()
return @hasTaming
@@ -276,6 +276,16 @@ exports.Block = class Block extends Base
break
this
+ # Optimization!
+ # Blocks typically don't need their own cpsCascading. This saves
+ # wasted code.
+ compileCps : (o) ->
+ @gotCpsSplit = true
+ if @expressions.length > 1
+ super o
+ else
+ @compileNode o
+
# A **Block** is the only node that can serve as the root.
compile: (o = {}, level) ->
if o.scope then super o, level else @compileRoot o
@@ -365,6 +375,7 @@ exports.Block = class Block extends Base
cpsRotate : ->
pivot = null
+ child = null
# If this Block has taming, then we go ahead and look for a pivot
if @hasTaming
@@ -378,6 +389,7 @@ exports.Block = class Block extends Base
# We find a pivot if this node hasTaming, and it's not an Await
# itself
if pivot
+ console.log("found pvito")
# flood that all children of the pivot need to be CPS-Translated
pivot.floodCpsTranslation()
# include the pivot in this slice!
@@ -386,14 +398,22 @@ exports.Block = class Block extends Base
if rest.length
child = new Block rest
pivot.tameNestContinuationBlock child
+ # we have to set the taming bit on the new Block
+ for e in rest
+ child.hasTaming = true if e.hasTaming
+ # now recursive apply the transformation to the new child,
+ # this being especially import in blocks that have multiple
+ # awaits on the same level
+ child.cpsRotate()
pivot.callContinuation()
-
+
# After we have pivoted this guy, we still need to walk all of the
# expressions, because maybe the expressions that we left still have
# embedded functions that need the rotation run on them. Thus,
# hasTaming will be false, but children might have blocks that still
# need to be tamed
super()
+
# return this for chaining
this
@@ -1482,6 +1502,10 @@ exports.While = class While extends Base
return node if node.jumps loop: yes
no
+ callContinuation : ->
+ k = new Call(new Literal tame.const.k_while, [])
+ @body.push k
+
# The main difference from a JavaScript *while* is that the CoffeeScript
# *while* can be used as a part of a larger expression -- while loops may
# return an array containing the computed result of each iteration.
@@ -1707,7 +1731,7 @@ exports.Await = class Await extends Base
isStatement: YES
makeReturn: THIS
-
+
compileNode: (o) ->
o.indent += TAB
@body.compile o
@@ -1995,7 +2019,7 @@ exports.If = class If extends Base
this
# propogate the closing continuation call down both branches of the if.
- # note this prevents if ...else if... inline chaining, and makes it
+ # note this prevents if ...else if... inline chaining, and makes it
# fully nested if { .. } else { if { } ..} ..'s
callContinuation : ->
code = CALL_CONTINUATION()
3  src/tame.coffee
View
@@ -2,7 +2,7 @@
exports.AstTamer = class AstTamer
constructor: (rest...) ->
-
+
transform: (x) ->
x.tameTransform()
@@ -12,3 +12,4 @@ exports.const =
Deferrals : "Deferrals"
deferrals : "__tame_deferrals"
fulfill : "_fulfill"
+ k_while : "_kw"
Please sign in to comment.
Something went wrong with that request. Please try again.