Skip to content

Commit

Permalink
fixed #110 (labelled break and continue)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjouhier committed Sep 21, 2012
1 parent e984a11 commit 7186c5c
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 7 deletions.
67 changes: 62 additions & 5 deletions lib/callbacks/transform.js
Expand Up @@ -995,12 +995,22 @@ if (typeof exports !== 'undefined') {
" $statement;" + //
"})(function $name(){ $tail; });"),

LABEL: new Template("cb", "" + //
"$statement;" + //
"$tail;"),

BREAK: new Template("cb", "return __break();"),

LABELLED_BREAK: new Template("cb", "return $break();"),

CONTINUE: new Template("cb", "" + //
"while (__more) { __loop(); } __more = true;" + //
"return;"),

LABELLED_CONTINUE: new Template("cb", "" + //
"while ($more.get()) { $loop(); } $more.set(true);" + //
"return;"),

LOOP1: new Template("cb", "" + //
"if ($v) {" + //
" $body;" + //
Expand All @@ -1025,6 +1035,17 @@ if (typeof exports !== 'undefined') {
" do { __loop(); } while (__more); __more = true;" + //
"})(function $name(){ $tail;});"),

LABELLED_FOR: new Template("cb", "" + //
"return (function ___(__break){" + //
" var __more, $more = { get: function() { return __more; }, set: function(v) { __more = v; }};" + //
" var __loop = __cb(_, __frame, 0, 0, function $name(){" + //
" var $break = __break, $loop = __loop;" + //
" __more = false;" + //
" $loop2" + //
" });" + //
" do { __loop(); } while (__more); __more = true;" + //
"})(function $name(){ $tail;});"),

FOR_UPDATE: new Template("cb", "" + //
"var $beenHere = false;" + //
"return (function ___(__break){" + //
Expand All @@ -1036,6 +1057,18 @@ if (typeof exports !== 'undefined') {
" do { __loop(); } while (__more); __more = true;" + //
"})(function $name(){ $tail; });"),

LABELLED_FOR_UPDATE: new Template("cb", "" + //
"var $beenHere = false;" + //
"return (function ___(__break){" + //
" var __more, $more = { get: function() { return __more; }, set: function(v) { __more = v; }};" + //
" var __loop = __cb(_, __frame, 0, 0, function $name(){" + //
" var $break = __break, $loop = __loop;" + //
" __more = false;" + //
" $loop2" + //
" });" + //
" do { __loop(); } while (__more); __more = true;" + //
"})(function $name(){ $tail; });"),

CATCH: new Template("cb", "" + //
"return (function ___(__then){" + //
" (function ___(_){" + //
Expand Down Expand Up @@ -1079,6 +1112,7 @@ if (typeof exports !== 'undefined') {
};

function _callbackify(node, options) {
var label;
function _scanIt(node, parent) {
//console.log("CBIT: " + _tag(node) + " " + pp(node))
node = _flatten(node);
Expand Down Expand Up @@ -1148,19 +1182,26 @@ if (typeof exports !== 'undefined') {
}
_extractTail(parent, i);
if (node.label) {
throw new Error(node.filename + ": labelled break not supported yet");
node = _cbTemplates.LABELLED_BREAK.generate(node, {
$break: _safeName(options.precious, '__break__' + node.label)
});
} else {
node = _cbTemplates.BREAK.generate(node, {});
}
node = _cbTemplates.BREAK.generate(node, {});
break;
case CONTINUE:
if (node.target && !node.target._async) {
break;
}
_extractTail(parent, i);
if (node.label) {
throw new Error(node.filename + ": labelled continue not supported yet");
node = _cbTemplates.LABELLED_CONTINUE.generate(node, {
$loop: _safeName(options.precious, '__loop__' + node.label),
$more: _safeName(options.precious, '__more__' + node.label),
});
} else {
node = _cbTemplates.CONTINUE.generate(node, {});
}
node = _cbTemplates.CONTINUE.generate(node, {});
break;
case TRY:
var tail = _extractTail(parent, i);
Expand Down Expand Up @@ -1202,6 +1243,17 @@ if (typeof exports !== 'undefined') {
$tail: tail
});
break;
case LABEL:
var l = label;
label = node.label;
node = _cbTemplates.LABEL.generate(node, {
$name: "__$" + node._scope.name,
$statement: node.statement,
$tail: tail
});
node = _scanIt(node, parent);
label = l;
return node;
case FOR:
var v = _identifier(_genId(node));
var loop1 = _cbTemplates.LOOP1.generate(node, {
Expand All @@ -1217,8 +1269,13 @@ if (typeof exports !== 'undefined') {
$update: _statementify(update),
$loop1: loop1
});
node = (update ? _cbTemplates.FOR_UPDATE : _cbTemplates.FOR).generate(node, {
node = (update
? (label ? _cbTemplates.LABELLED_FOR_UPDATE : _cbTemplates.FOR_UPDATE)
: (label ? _cbTemplates.LABELLED_FOR : _cbTemplates.FOR)).generate(node, {
$name: "__$" + node._scope.name,
$loop: _identifier(_safeName(options.precious, '__loop__' + label)),
$break: _identifier(_safeName(options.precious, '__break__' + label)),
$more: _identifier(_safeName(options.precious, '__more__' + label)),
$beenHere: beenHere,
$loop2: loop2,
$tail: tail
Expand Down
23 changes: 22 additions & 1 deletion test/common/callbacks/eval-test.js
Expand Up @@ -654,4 +654,25 @@ asyncTest("sync try/catch inside conditional", 1, function __50(_) { var __frame
if (true) { return (function ___(__then) { (function ___(_) { __tryCatch(_, __then); })(function ___(ex, __result) { __tryCatch(_, function __$f() { if (ex) { __then(); } else { _(null, __result); } ; }); }); })(function ___() { __tryCatch(_, __then); }); } else { __then(); } ; })(_); });


}, undefined); _(); });});
}, undefined); _(); });});


asyncTest("labelled break", 1, function __51(_) { var __frame = { name: "__51", line: 660 }; return __func(_, this, arguments, __51, 0, __frame, function __$__51() {
evalTest(function f(_) { var result, i, j; var __frame = { name: "f", line: 661 }; return __func(_, this, arguments, f, 0, __frame, function __$f() {
result = "";

i = 1; var __7 = false; return (function ___(__break) { var __more, __more__outer = { get: function() { return __more; }, set: function(v) { __more = v; } }; var __loop = __cb(_, __frame, 0, 0, function __$f() { var __break__outer = __break, __loop__outer = __loop; __more = false; if (__7) { i++; } else { __7 = true; } ; var __6 = (i < 10); if (__6) {

j = 5; var __9 = false; return (function ___(__break) { var __more, __more__inner = { get: function() { return __more; }, set: function(v) { __more = v; } }; var __loop = __cb(_, __frame, 0, 0, function __$f() { var __break__inner = __break, __loop__inner = __loop; __more = false; if (__9) { j++; } else { __9 = true; } ; var __8 = (j < 10); if (__8) {
return delay(__cb(_, __frame, 6, 13, function ___(__0, __1) { result = (__1 + "!");
if (((i == 1) && (j == 7))) { return __break(); } ;
if (((i == 2) && (j == 7))) { return __break__inner(); } ;
if (((i == 3) && (j == 7))) { while (__more__inner.get()) { __loop__inner(); }; __more__inner.set(true); return; } ;
if (((i == 4) && (j == 7))) { while (__more__outer.get()) { __loop__outer(); }; __more__outer.set(true); return; } ;
if (((i == 5) && (j == 7))) { return __break__outer(); } ;
return delay(__cb(_, __frame, 12, 13, function ___(__0, __2) { return delay(__cb(_, __frame, 12, 32, function ___(__0, __3) { return delay(__cb(_, __frame, 12, 46, function ___(__0, __4) { result = (((__2 + __3) + __4) + "-"); while (__more) { __loop(); }; __more = true; }, true), j); }, true), i); }, true), result); }, true), result); } else { __break(); } ; }); do { __loop(); } while (__more); __more = true; })(function __$f() {

return delay(__cb(_, __frame, 14, 13, function ___(__0, __5) { result += __5; while (__more) { __loop(); }; __more = true; }, true), "/"); }); } else { __break(); } ; }); do { __loop(); } while (__more); __more = true; })(function __$f() {

return _(null, result); }); });
}, "!15-!16-!/!25-!26-!/!35-!36-!!38-!39-/!45-!46-!!55-!56-!"); _(); });});
23 changes: 22 additions & 1 deletion test/common/eval-test._js
Expand Up @@ -655,4 +655,25 @@ asyncTest("sync try/catch inside conditional", 1, function(_) {
try {} catch (ex) {}
}
}, undefined);
})
})

asyncTest("labelled break", 1, function(_) {
evalTest(function f(_) {
var result = '';
outer:
for (var i = 1; i < 10; i++) {
inner:
for (var j = 5; j < 10; j++) {
result = delay(_, result) + '!'
if (i == 1 && j == 7) break;
if (i == 2 && j == 7) break inner;
if (i == 3 && j == 7) continue inner;
if (i == 4 && j == 7) continue outer;
if (i == 5 && j == 7) break outer;
result = delay(_, result) + delay(_, i) + delay(_, j) + '-';
}
result += delay(_, '/')
}
return result;
}, '!15-!16-!/!25-!26-!/!35-!36-!!38-!39-/!45-!46-!!55-!56-!');
})
22 changes: 22 additions & 0 deletions test/common/generators/eval-test.js
Expand Up @@ -656,6 +656,28 @@ asyncTest("sync try/catch inside conditional", 1, fstreamline__.create(function(
}
;yield;}, 0), undefined);
;yield;}, 0));

asyncTest("labelled break", 1, fstreamline__.create(function(_) {
evalTest(fstreamline__.create(function f(_) {
var result = '';
outer:
for (var i = 1; i < 10; i++) {
inner:
for (var j = 5; j < 10; j++) {
result = (yield delay(_, result)) + '!';
if (i == 1 && j == 7) break;
if (i == 2 && j == 7) break inner;
if (i == 3 && j == 7) continue inner;
if (i == 4 && j == 7) continue outer;
if (i == 5 && j == 7) break outer;
result = (yield delay(_, result)) + (yield delay(_, i)) + (yield delay(_, j)) + '-';
}
result += (yield delay(_, '/'));
}
yield ( result);
}, 0), '!15-!16-!/!25-!26-!/!35-!36-!!38-!39-/!45-!46-!!55-!56-!');
;yield;}, 0));

;yield;}, 0).call(this, function(err) {
if (err) throw err;
}));

0 comments on commit 7186c5c

Please sign in to comment.