Permalink
Browse files

more cleanup and tests.

  • Loading branch information...
1 parent eb2636f commit b6d5285e66d5ba7ce47a4a8449b623d2f25b47f4 @maxtaco committed Dec 14, 2011
Showing with 70 additions and 69 deletions.
  1. +4 −5 lib/coffee-script/cake.js
  2. +12 −17 lib/coffee-script/nodes.js
  3. +7 −13 lib/coffee-script/tamelib.js
  4. +21 −17 src/nodes.coffee
  5. +26 −17 test/tame.coffee
View
9 lib/coffee-script/cake.js
@@ -75,12 +75,12 @@
return switches.push([letter, flag, description]);
},
invoke: function(name, cb) {
- var t;
+ var t, __tame_deferrals,
+ _this = this;
if (!(t = tasks[name])) missingTask(name);
(function(__tame_k) {
if (t.async) {
(function(__tame_k) {
- var __tame_deferrals;
__tame_deferrals = new tame.Deferrals(__tame_k);
t.action(options, __tame_deferrals.defer({}));
__tame_deferrals._fulfill();
@@ -98,7 +98,8 @@
});
exports.run = function(cb) {
- var arg, args, _i, _len, _ref, _results, _while;
+ var arg, args, __tame_deferrals, _break, _continue, _i, _len, _ref, _results, _while,
+ _this = this;
global.__originalDirname = fs.realpathSync('.');
process.chdir(cakefileDirectory(__originalDirname));
args = process.argv.slice(2);
@@ -116,7 +117,6 @@
_len = _ref.length;
_i = 0;
_while = function(__tame_k) {
- var _break, _continue;
_break = __tame_k;
_continue = function() {
++_i;
@@ -125,7 +125,6 @@
if (_i < _len) {
arg = _ref[_i];
(function(__tame_k) {
- var __tame_deferrals;
__tame_deferrals = new tame.Deferrals(__tame_k);
invoke(arg, __tame_deferrals.defer({}));
__tame_deferrals._fulfill();
View
29 lib/coffee-script/nodes.js
@@ -659,7 +659,7 @@
Literal.prototype.compileNode = function(o) {
var code, _ref2, _ref3;
- code = this.isUndefined ? o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0' : this.value === 'this' ? ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0) ? o.scope.method.context : o.tamed_scope ? (o.tamed_scope.assign('_this', 'this'), '_this') : this.value : this.value.reserved && ((_ref3 = "" + this.value) !== 'eval' && _ref3 !== 'arguments') ? "\"" + this.value + "\"" : this.tameLoopFlag && this.tameIsJump() ? this.compileTame(o) : this.value;
+ code = this.isUndefined ? o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0' : this.value === 'this' ? ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved && ((_ref3 = "" + this.value) !== 'eval' && _ref3 !== 'arguments') ? "\"" + this.value + "\"" : this.tameLoopFlag && this.tameIsJump() ? this.compileTame(o) : this.value;
if (this.isStatement()) {
return "" + this.tab + code + ";";
} else {
@@ -1701,9 +1701,9 @@
function Code(params, body, tag) {
this.params = params || [];
this.body = body || new Block;
- this.bound = tag === 'boundfunc';
this.tamegen = tag === 'tamegen';
- if (this.bound) this.context = '_this';
+ this.bound = tag === 'boundfunc' || this.tamegen;
+ if (this.bound || this.tamegen) this.context = '_this';
}
Code.prototype.children = ['params', 'body'];
@@ -1729,9 +1729,9 @@
};
Code.prototype.compileNode = function(o) {
- var code, exprs, i, idt, k_id, lit, p, param, ref, rhs, splats, stored_tamed_scope, v, val, vars, wasEmpty, _i, _j, _k, _len, _len2, _len3, _len4, _ref2, _ref3, _ref4, _ref5, _ref6;
+ var code, exprs, i, idt, k_id, lit, p, param, ref, rhs, splats, v, val, vars, wasEmpty, _i, _j, _k, _len, _len2, _len3, _len4, _ref2, _ref3, _ref4, _ref5, _ref6;
o.scope = new Scope(o.scope, this.body, this);
- o.scope.shared = del(o, 'sharedScope');
+ o.scope.shared = del(o, 'sharedScope') || this.tamegen;
o.indent += TAB;
delete o.bare;
vars = [];
@@ -1799,22 +1799,17 @@
code = 'function';
if (this.ctor) code += ' ' + this.name;
code += '(' + vars.join(', ') + ') {';
- if (!this.tamegen) {
- stored_tamed_scope = o.tamed_scope;
- o.tamed_scope = this.tameNodeFlag ? o.scope : null;
- if (this.tameNodeFlag && this.tameHasAutocbFlag) {
- rhs = new Value(new Literal(tame["const"].autocb));
- k_id = new Value(new Literal(tame["const"].k));
- this.body.unshift(new Assign(k_id, rhs, null, {
- param: true
- }));
- }
+ if (!this.tamegen && this.tameNodeFlag && this.tameHasAutocbFlag) {
+ rhs = new Value(new Literal(tame["const"].autocb));
+ k_id = new Value(new Literal(tame["const"].k));
+ this.body.unshift(new Assign(k_id, rhs, null, {
+ param: true
+ }));
}
if (!this.body.isEmpty()) {
code += "\n" + (this.body.compileWithDeclarations(o)) + "\n" + this.tab;
}
code += '}';
- o.tamed_scope = stored_tamed_scope;
if (this.ctor) return this.tab + code;
if (this.front || (o.level >= LEVEL_ACCESS)) {
return "(" + code + ")";
@@ -2411,7 +2406,7 @@
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
v = _ref2[_i];
name = v.compile(o, LEVEL_LIST);
- scope = o.tamed_scope || o.scope;
+ scope = o.scope;
scope.add(name, 'var');
}
return call.compile(o);
View
20 lib/coffee-script/tamelib.js
@@ -10,7 +10,8 @@
tame = tame_internals.runtime;
_timeout = function(cb, t, res, tmp) {
- var arr, rv, which;
+ var arr, rv, which, __tame_deferrals,
+ _this = this;
rv = new tame.Rendezvous;
tmp[0] = rv.id(true).__tame_deferrals.defer({
assign_fn: (function() {
@@ -21,7 +22,6 @@
});
setTimeout(rv.id(false).__tame_deferrals.defer({}), t);
(function(__tame_k) {
- var __tame_deferrals;
__tame_deferrals = new tame.Deferrals(__tame_k);
rv.wait(__tame_deferrals.defer({
assign_fn: (function() {
@@ -57,18 +57,16 @@
}
Pipeliner.prototype.waitInQueue = function(cb) {
- var _this = this;
+ var __tame_deferrals, _break, _continue, _while,
+ _this = this;
(function(__tame_k) {
- var _while;
_while = function(__tame_k) {
- var _break, _continue;
_break = __tame_k;
_continue = function() {
return _while(__tame_k);
};
if (_this.n_out > _this.window) {
(function(__tame_k) {
- var __tame_deferrals;
__tame_deferrals = new tame.Deferrals(__tame_k);
_this.cb = __tame_deferrals.defer({});
__tame_deferrals._fulfill();
@@ -85,7 +83,6 @@
(function(__tame_k) {
if (_this.delay) {
(function(__tame_k) {
- var __tame_deferrals;
__tame_deferrals = new tame.Deferrals(__tame_k);
setTimeout(__tame_deferrals.defer({}), _this.delay);
__tame_deferrals._fulfill();
@@ -102,9 +99,9 @@
};
Pipeliner.prototype.__defer = function(out, deferArgs) {
- var _this = this;
+ var tmp, voidCb, __tame_deferrals,
+ _this = this;
(function(__tame_k) {
- var voidCb, __tame_deferrals;
__tame_deferrals = new tame.Deferrals(__tame_k);
voidCb = __tame_deferrals.defer({});
out[0] = function() {
@@ -115,7 +112,6 @@
};
__tame_deferrals._fulfill();
})(function() {
- var tmp;
_this.n_out--;
if (_this.cb) {
tmp = _this.cb;
@@ -133,18 +129,16 @@
};
Pipeliner.prototype.flush = function(autocb) {
- var __tame_k, _while,
+ var __tame_deferrals, _break, _continue, _while,
_this = this;
__tame_k = autocb;
_while = function(__tame_k) {
- var _break, _continue;
_break = __tame_k;
_continue = function() {
return _while(__tame_k);
};
if (_this.n_out) {
(function(__tame_k) {
- var __tame_deferrals;
__tame_deferrals = new tame.Deferrals(__tame_k);
_this.cb = __tame_deferrals.defer({});
__tame_deferrals._fulfill();
View
38 src/nodes.coffee
@@ -183,12 +183,14 @@ exports.Base = class Base
for child in @flattenChildren()
return true if child.tameNeedsRuntime()
return false
-
+
tameFindRequire : ->
for child in @flattenChildren()
return r if (r = child.tameFindRequire())
return null
-
+
+ # Mark all of the autocbs, and all of their descendants in the AST.
+ # The smart sub-class behavior here is in Code.
tameMarkAutocbs : (found) ->
@tameHasAutocbFlag = found
for child in @flattenChildren()
@@ -553,9 +555,6 @@ exports.Literal = class Literal extends Base
else if @value is 'this'
if o.scope.method?.bound
o.scope.method.context
- else if o.tamed_scope
- o.tamed_scope.assign '_this', 'this'
- '_this'
else
@value
else if @value.reserved
@@ -1399,9 +1398,9 @@ exports.Code = class Code extends Base
constructor: (params, body, tag) ->
@params = params or []
@body = body or new Block
- @bound = tag is 'boundfunc'
@tamegen = tag is 'tamegen'
- @context = '_this' if @bound
+ @bound = tag is 'boundfunc' or @tamegen
+ @context = '_this' if @bound or @tamegen
children: ['params', 'body']
@@ -1424,7 +1423,7 @@ exports.Code = class Code extends Base
# a closure.
compileNode: (o) ->
o.scope = new Scope o.scope, @body, this
- o.scope.shared = del(o, 'sharedScope')
+ o.scope.shared = del(o, 'sharedScope') or @tamegen
o.indent += TAB
delete o.bare
params = []
@@ -1472,18 +1471,23 @@ exports.Code = class Code extends Base
=======
code += '(' + vars.join(', ') + ') {'
- unless @tamegen
- stored_tamed_scope = o.tamed_scope
- o.tamed_scope = if @tameNodeFlag then o.scope else null
- if @tameNodeFlag and @tameHasAutocbFlag
- rhs = new Value new Literal tame.const.autocb
- k_id = new Value new Literal tame.const.k
- @body.unshift(new Assign k_id, rhs, null, { param : yes })
+ # There are two important cases to consider in terms of autocb;
+ # In the case of an explicit call to return, we handle it in
+ # 'new Return' constructor. The subtler case is when control
+ # falls off the end of a function. But that's just the top-level
+ # continuation within the function. So we assign it to the autocb
+ # here. There's a slight scoping hack, to supply { param : yes },
+ # which forces __tame_k to be locally scoped. Note that there's a
+ # global __tame_k that's just the no-op, and we definitely don't
+ # want to molest that!
+ if not @tamegen and @tameNodeFlag and @tameHasAutocbFlag
+ rhs = new Value new Literal tame.const.autocb
+ k_id = new Value new Literal tame.const.k
+ @body.unshift(new Assign k_id, rhs, null, { param : yes })
>>>>>>> betteR! gotta run, but close!
code += "\n#{ @body.compileWithDeclarations o }\n#{@tab}" unless @body.isEmpty()
code += '}'
- o.tamed_scope = stored_tamed_scope
return @tab + code if @ctor
if @front or (o.level >= LEVEL_ACCESS) then "(#{code})" else code
@@ -2018,7 +2022,7 @@ exports.Defer = class Defer extends Base
call = @transform()
for v in @vars
name = v.compile o, LEVEL_LIST
- scope = o.tamed_scope || o.scope
+ scope = o.scope
scope.add name, 'var'
call.compile o
View
43 test/tame.coffee
@@ -21,15 +21,15 @@ atest "basic tame waiting", (cb) ->
atest "basic tame trigger values", (cb) ->
i = 10
- await foo(i, defer (j))
+ await foo(i, defer j)
cb(i == j, {})
atest "basic tame set structs", (cb) ->
field = "yo"
i = 10
obj = { cat : { dog : 0 } }
await
- foo(i, defer(obj.cat[field]))
+ foo(i, defer obj.cat[field])
field = "bar" # change the field to make sure that we captured "yo"
cb(obj.cat.yo == i, {})
@@ -186,21 +186,6 @@ atest "test nested serial/parallel", (cb) ->
for i in [0..10]
ok = false unless slots[i]
cb(ok, {})
-
-atest "AT variable works in an await (2)", (cb) ->
- class MyClass
- constructor : -> @val = 0
- inc : -> @val++
- chill : (autocb) -> await delay defer()
- run : (autocb) ->
- await @chill defer()
- for i in [0..10]
- await @chill defer()
- @inc()
- getVal : -> @val
- o = new MyClass
- await o.run defer()
- cb(o.getVal() == 10, {})
atest "loops respect autocbs", (cb) ->
ok = false
@@ -242,3 +227,27 @@ atest "test scoping", (cb) ->
o = new MyClass
await o.run defer(v)
cb(v == 5, {})
+
+atest "AT variable works in an await (2)", (cb) ->
+ class MyClass
+ constructor : -> @val = 0
+ inc : -> @val++
+ chill : (autocb) -> await delay defer()
+ run : (autocb) ->
+ await @chill defer()
+ for i in [0..10]
+ await @chill defer()
+ @inc()
+ getVal : -> @val
+ o = new MyClass
+ await o.run defer()
+ cb(o.getVal() == 10, {})
+
+atest "another autocb gotcha", (cb) ->
+ bar = (autocb) ->
+ await delay defer() if yes
+ ok = false
+ await bar defer()
+ ok = true
+ cb(ok, {})
+

0 comments on commit b6d5285

Please sign in to comment.