Fixing inconsistencies for index variables

See the tests added to test_comprehensions.coffee. Previously, after
`for i in [1..3]`, i was 4. Also, index variables were never set to
any value in comprehensions containing both a closure and a break or
return.
This commit is contained in:
Trevor Burnham
2010-10-19 14:09:16 -04:00
parent 0e395569ee
commit 5005cb606f
13 changed files with 148 additions and 7 deletions

View File

@@ -36,6 +36,8 @@
})(); })();
script = _j; script = _j;
} }
return null; return null;
}; };
if (window.addEventListener) { if (window.addEventListener) {

View File

@@ -51,6 +51,8 @@
arg = _ref[_i]; arg = _ref[_i];
_result.push(invoke(arg)); _result.push(invoke(arg));
} }
return _result; return _result;
}); });
}; };
@@ -64,6 +66,8 @@
desc = task.description ? ("# " + (task.description)) : ''; desc = task.description ? ("# " + (task.description)) : '';
puts("cake " + name + spaces + " " + desc); puts("cake " + name + spaces + " " + desc);
} }
return switches.length ? puts(oparse.help()) : undefined; return switches.length ? puts(oparse.help()) : undefined;
}; };
missingTask = function(task) { missingTask = function(task) {

View File

@@ -70,6 +70,8 @@
file = files[_k]; file = files[_k];
_result2.push(compile(path.join(source, file))); _result2.push(compile(path.join(source, file)));
} }
return _result2; return _result2;
}); });
} else if (topLevel || path.extname(source) === '.coffee') { } else if (topLevel || path.extname(source) === '.coffee') {
@@ -86,6 +88,8 @@
})(); })();
source = _j; source = _j;
} }
return _result; return _result;
}; };
compileScript = function(file, input, base) { compileScript = function(file, input, base) {
@@ -97,6 +101,8 @@
req = _ref2[_i]; req = _ref2[_i];
require(helpers.starts(req, '.') ? fs.realpathSync(req) : req); require(helpers.starts(req, '.') ? fs.realpathSync(req) : req);
} }
} }
try { try {
t = (task = { t = (task = {
@@ -197,6 +203,8 @@
return "[" + tag + " " + value + "]"; return "[" + tag + " " + value + "]";
})()); })());
} }
return _result; return _result;
})(); })();
return puts(strings.join(' ')); return puts(strings.join(' '));

View File

@@ -604,15 +604,21 @@
tokens.push(token); tokens.push(token);
} }
} }
if (name === 'Root') { if (name === 'Root') {
alt[1] = ("return " + (alt[1])); alt[1] = ("return " + (alt[1]));
} }
return alt; return alt;
})()); })());
} }
return _result; return _result;
})(); })();
} }
exports.parser = new Parser({ exports.parser = new Parser({
tokens: tokens.join(' '), tokens: tokens.join(' '),
bnf: grammar, bnf: grammar,

View File

@@ -10,6 +10,8 @@
return index; return index;
} }
} }
return -1; return -1;
})); }));
exports.include = function(list, value) { exports.include = function(list, value) {
@@ -32,6 +34,8 @@
_result.push(item); _result.push(item);
} }
} }
return _result; return _result;
}; };
exports.count = function(string, letter) { exports.count = function(string, letter) {
@@ -51,6 +55,8 @@
val = properties[key]; val = properties[key];
object[key] = val; object[key] = val;
} }
return object; return object;
}); });
exports.flatten = (flatten = function(array) { exports.flatten = (flatten = function(array) {
@@ -64,6 +70,8 @@
flattened.push(element); flattened.push(element);
} }
} }
return flattened; return flattened;
}); });
exports.del = function(obj, key) { exports.del = function(obj, key) {

View File

@@ -6,4 +6,6 @@
val = _ref[key]; val = _ref[key];
(exports[key] = val); (exports[key] = val);
} }
}).call(this); }).call(this);

View File

@@ -226,6 +226,8 @@
} }
tokens.push(['+', '+']); tokens.push(['+', '+']);
} }
tokens.pop(); tokens.pop();
if ((((_ref4 = tokens[0]) != null) ? _ref4[0] : undefined) !== 'STRING') { if ((((_ref4 = tokens[0]) != null) ? _ref4[0] : undefined) !== 'STRING') {
this.tokens.push(['STRING', '""'], ['+', '+']); this.tokens.push(['STRING', '""'], ['+', '+']);
@@ -480,6 +482,8 @@
break; break;
} }
} }
} }
if (!levels.length) { if (!levels.length) {
break; break;
@@ -550,6 +554,8 @@
this.token('STRING', this.makeString(value, '"', heredoc)); this.token('STRING', this.makeString(value, '"', heredoc));
} }
} }
if (interpolated) { if (interpolated) {
this.token(')', ')'); this.token(')', ')');
} }
@@ -600,6 +606,8 @@
})) { })) {
COFFEE_KEYWORDS.push(op); COFFEE_KEYWORDS.push(op);
} }
RESERVED = ['case', 'default', 'do', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice']; RESERVED = ['case', 'default', 'do', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice'];
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED); JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED);
IDENTIFIER = /^([$A-Za-z_][$\w]*)([^\n\S]*:(?!:))?/; IDENTIFIER = /^([$A-Za-z_][$\w]*)([^\n\S]*:(?!:))?/;

View File

@@ -58,6 +58,8 @@
node = pair[i]; node = pair[i];
(pair[i] = node.compile(o)); (pair[i] = node.compile(o));
} }
} }
return pair; return pair;
}; };
@@ -106,6 +108,8 @@
child = _ref2[_i]; child = _ref2[_i];
_result.push(child.toString(idt + TAB)); _result.push(child.toString(idt + TAB));
} }
return _result; return _result;
}).call(this).join(''); }).call(this).join('');
klass = override || this.constructor.name + (this.soakNode ? '?' : ''); klass = override || this.constructor.name + (this.soakNode ? '?' : '');
@@ -126,8 +130,12 @@
return; return;
} }
} }
} }
} }
return _result; return _result;
}; };
Base.prototype.collectChildren = function() { Base.prototype.collectChildren = function() {
@@ -208,6 +216,8 @@
node = _ref2[_i]; node = _ref2[_i];
_result.push(this.compileExpression(node, merge(o))); _result.push(this.compileExpression(node, merge(o)));
} }
return _result; return _result;
}).call(this).join('\n'); }).call(this).join('\n');
}; };
@@ -411,6 +421,8 @@
prop = props[_i]; prop = props[_i];
(code += prop.compile(o)); (code += prop.compile(o));
} }
return code; return code;
}; };
Value.prototype.unfoldSoak = function(o) { Value.prototype.unfoldSoak = function(o) {
@@ -436,6 +448,8 @@
return ifn; return ifn;
} }
} }
return null; return null;
}; };
return Value; return Value;
@@ -542,6 +556,8 @@
} }
ifn = If.unfoldSoak(o, call, 'variable'); ifn = If.unfoldSoak(o, call, 'variable');
} }
return ifn; return ifn;
}; };
Call.prototype.compileNode = function(o) { Call.prototype.compileNode = function(o) {
@@ -556,12 +572,16 @@
return this.compileSplat(o); return this.compileSplat(o);
} }
} }
args = (function() { args = (function() {
_result = []; _result = [];
for (_j = 0, _len2 = (_ref4 = this.args).length; _j < _len2; _j++) { for (_j = 0, _len2 = (_ref4 = this.args).length; _j < _len2; _j++) {
arg = _ref4[_j]; arg = _ref4[_j];
_result.push((arg.parenthetical = true) && arg.compile(o)); _result.push((arg.parenthetical = true) && arg.compile(o));
} }
return _result; return _result;
}).call(this).join(', '); }).call(this).join(', ');
return this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + args + ")"); return this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + args + ")");
@@ -792,6 +812,8 @@
_result.push(prop); _result.push(prop);
} }
} }
return _result; return _result;
}).call(this); }).call(this);
lastNoncom = last(nonComments); lastNoncom = last(nonComments);
@@ -810,6 +832,8 @@
return indent + prop.compile(o) + join; return indent + prop.compile(o) + join;
}).call(this)); }).call(this));
} }
return _result; return _result;
}).call(this); }).call(this);
props = props.join(''); props = props.join('');
@@ -824,6 +848,8 @@
return true; return true;
} }
} }
return false; return false;
}; };
return ObjectLiteral; return ObjectLiteral;
@@ -852,12 +878,16 @@
return this.compileSplatLiteral(o); return this.compileSplatLiteral(o);
} }
} }
objects = []; objects = [];
for (i = 0, _len2 = (_ref3 = this.objects).length; i < _len2; i++) { for (i = 0, _len2 = (_ref3 = this.objects).length; i < _len2; i++) {
obj = _ref3[i]; obj = _ref3[i];
code = obj.compile(o); code = obj.compile(o);
objects.push(obj instanceof Comment ? ("\n" + code + "\n" + (o.indent)) : (i === this.objects.length - 1 ? code : code + ', ')); objects.push(obj instanceof Comment ? ("\n" + code + "\n" + (o.indent)) : (i === this.objects.length - 1 ? code : code + ', '));
} }
objects = objects.join(''); objects = objects.join('');
return 0 < objects.indexOf('\n') ? ("[\n" + (o.indent) + objects + "\n" + (this.tab) + "]") : ("[" + objects + "]"); return 0 < objects.indexOf('\n') ? ("[\n" + (o.indent) + objects + "\n" + (this.tab) + "]") : ("[" + objects + "]");
}; };
@@ -869,6 +899,8 @@
return true; return true;
} }
} }
return false; return false;
}; };
return ArrayLiteral; return ArrayLiteral;
@@ -957,6 +989,8 @@
} }
props.push(prop); props.push(prop);
} }
constructor.className = className.match(/[\w\d\$_]+$/); constructor.className = className.match(/[\w\d\$_]+$/);
if (me) { if (me) {
constructor.body.unshift(new Literal("" + me + " = this")); constructor.body.unshift(new Literal("" + me + " = this"));
@@ -1082,6 +1116,8 @@
} }
assigns.push(new Assign(obj, val).compile(otop)); assigns.push(new Assign(obj, val).compile(otop));
} }
if (!top) { if (!top) {
assigns.push(valVar); assigns.push(valVar);
} }
@@ -1159,6 +1195,8 @@
} }
} }
} }
o.scope.startLevel(); o.scope.startLevel();
params = (function() { params = (function() {
_result = []; _result = [];
@@ -1166,6 +1204,8 @@
param = params[_i]; param = params[_i];
_result.push(param.compile(o)); _result.push(param.compile(o));
} }
return _result; return _result;
})(); })();
if (!(empty || this.noReturn)) { if (!(empty || this.noReturn)) {
@@ -1175,6 +1215,8 @@
param = params[_i]; param = params[_i];
(o.scope.parameter(param)); (o.scope.parameter(param));
} }
comm = this.comment ? this.comment.compile(o) + '\n' : ''; comm = this.comment ? this.comment.compile(o) + '\n' : '';
if (this.className) { if (this.className) {
o.indent = this.idt(2); o.indent = this.idt(2);
@@ -1262,6 +1304,8 @@
pos = this.trailings.length - idx; pos = this.trailings.length - idx;
o.scope.assign(trailing.compile(o), "arguments[" + variadic + " ? " + len + " - " + pos + " : " + (this.index + idx) + "]"); o.scope.assign(trailing.compile(o), "arguments[" + variadic + " ? " + len + " - " + pos + " : " + (this.index + idx) + "]");
} }
} }
return "" + name + " = " + (utility('slice')) + ".call(arguments, " + (this.index) + end + ")"; return "" + name + " = " + (utility('slice')) + ".call(arguments, " + (this.index) + end + ")";
}; };
@@ -1291,6 +1335,8 @@
} }
args[++end] = i === 0 ? code : (".concat(" + code + ")"); args[++end] = i === 0 ? code : (".concat(" + code + ")");
} }
return args.join(''); return args.join('');
}; };
return Splat; return Splat;
@@ -1492,6 +1538,8 @@
item = _ref2[i]; item = _ref2[i];
_result.push("" + (i ? this.obj2 : this.obj1) + " === " + (item.compile(o))); _result.push("" + (i ? this.obj2 : this.obj1) + " === " + (item.compile(o)));
} }
return _result; return _result;
}).call(this); }).call(this);
return "(" + (tests.join(' || ')) + ")"; return "(" + (tests.join(' || ')) + ")";
@@ -1657,7 +1705,7 @@
return ''; return '';
}; };
For.prototype.compileNode = function(o) { For.prototype.compileNode = function(o) {
var body, codeInBody, forPart, guardPart, idt1, index, ivar, lastLine, lvar, name, namePart, nvar, range, ref, resultPart, returnResult, rvar, scope, source, sourcePart, stepPart, svar, topLevel, varPart, vars; var body, codeInBody, forPart, guardPart, idt1, index, ivar, lastLine, lvar, name, namePart, nvar, range, ref, resultPart, returnResult, rvar, scope, source, sourcePart, stepPart, svar, topLevel, unstepPart, varPart, vars;
topLevel = del(o, 'top') && !this.returns; topLevel = del(o, 'top') && !this.returns;
range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length; range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length;
source = range ? this.source.base : this.source; source = range ? this.source.base : this.source;
@@ -1689,6 +1737,7 @@
} }
varPart = ''; varPart = '';
guardPart = ''; guardPart = '';
unstepPart = '';
body = Expressions.wrap([this.body]); body = Expressions.wrap([this.body]);
idt1 = this.idt(1); idt1 = this.idt(1);
if (range) { if (range) {
@@ -1724,10 +1773,12 @@
if (this.guard) { if (this.guard) {
body = Expressions.wrap([new If(this.guard, body)]); body = Expressions.wrap([new If(this.guard, body)]);
} }
if (codeInBody && !body.containsPureStatement()) { if (codeInBody) {
if (range) { if (range) {
body.unshift(new Literal("var " + name + " = " + ivar)); body.unshift(new Literal("var " + name + " = " + ivar));
} }
}
if (codeInBody && !body.containsPureStatement()) {
if (namePart) { if (namePart) {
body.unshift(new Literal("var " + namePart)); body.unshift(new Literal("var " + namePart));
} }
@@ -1754,6 +1805,9 @@
if (namePart) { if (namePart) {
varPart = ("" + idt1 + namePart + ";\n"); varPart = ("" + idt1 + namePart + ";\n");
} }
if (forPart && name === ivar) {
unstepPart = this.step ? ("\n" + name + " -= " + (this.step.compile(o)) + ";") : ("\n" + name + "--;");
}
} }
if (this.object) { if (this.object) {
forPart = ("" + ivar + " in " + sourcePart); forPart = ("" + ivar + " in " + sourcePart);
@@ -1766,7 +1820,7 @@
top: true top: true
})); }));
vars = range ? name : ("" + name + ", " + ivar); vars = range ? name : ("" + name + ", " + ivar);
return "" + resultPart + (this.tab) + "for (" + forPart + ") {" + guardPart + "\n" + varPart + body + "\n" + (this.tab) + "}" + returnResult; return "" + resultPart + (this.tab) + "for (" + forPart + ") {" + guardPart + "\n" + varPart + body + "\n" + (this.tab) + "}\n" + unstepPart + "\n" + returnResult;
}; };
return For; return For;
})(); })();
@@ -1792,6 +1846,8 @@
pair = _ref2[_i]; pair = _ref2[_i];
pair[1].makeReturn(); pair[1].makeReturn();
} }
if (this.otherwise) { if (this.otherwise) {
this.otherwise.makeReturn(); this.otherwise.makeReturn();
} }
@@ -1813,11 +1869,15 @@
} }
code += ("\n" + (this.idt(1)) + "case " + (condition.compile(o)) + ":"); code += ("\n" + (this.idt(1)) + "case " + (condition.compile(o)) + ":");
} }
code += ("\n" + (block.compile(o))); code += ("\n" + (block.compile(o)));
if (!(last(exprs) instanceof Return)) { if (!(last(exprs) instanceof Return)) {
code += ("\n" + idt + "break;"); code += ("\n" + idt + "break;");
} }
} }
if (this.otherwise) { if (this.otherwise) {
code += ("\n" + (this.idt(1)) + "default:\n" + (this.otherwise.compile(o))); code += ("\n" + (this.idt(1)) + "default:\n" + (this.otherwise.compile(o)));
} }

View File

@@ -28,6 +28,8 @@
break; break;
} }
} }
if (isOption && !matchedRule) { if (isOption && !matchedRule) {
throw new Error("unrecognized option: " + arg); throw new Error("unrecognized option: " + arg);
} }
@@ -36,6 +38,8 @@
break; break;
} }
} }
return options; return options;
}; };
OptionParser.prototype.help = function() { OptionParser.prototype.help = function() {
@@ -51,6 +55,8 @@
letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' '; letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
lines.push(' ' + letPart + rule.longFlag + spaces + rule.description); lines.push(' ' + letPart + rule.longFlag + spaces + rule.description);
} }
return "\n" + (lines.join('\n')) + "\n"; return "\n" + (lines.join('\n')) + "\n";
}; };
return OptionParser; return OptionParser;
@@ -71,6 +77,8 @@
return buildRule.apply(buildRule, tuple); return buildRule.apply(buildRule, tuple);
})()); })());
} }
return _result; return _result;
}; };
buildRule = function(shortFlag, longFlag, description, options) { buildRule = function(shortFlag, longFlag, description, options) {
@@ -98,10 +106,14 @@
l = _ref[_j]; l = _ref[_j];
result.push('-' + l); result.push('-' + l);
} }
} else { } else {
result.push(arg); result.push(arg);
} }
} }
return result; return result;
}; };
}).call(this); }).call(this);

View File

@@ -90,6 +90,8 @@
break; break;
} }
} }
return i ? this.tokens.splice(0, i) : undefined; return i ? this.tokens.splice(0, i) : undefined;
}; };
exports.Rewriter.prototype.removeMidExpressionNewlines = function() { exports.Rewriter.prototype.removeMidExpressionNewlines = function() {
@@ -296,6 +298,8 @@
throw Error("too many " + (token[1]) + " on line " + (token[2] + 1)); throw Error("too many " + (token[1]) + " on line " + (token[2] + 1));
} }
} }
return 1; return 1;
}); });
unclosed = (function() { unclosed = (function() {
@@ -306,6 +310,8 @@
_result.push(key); _result.push(key);
} }
} }
return _result; return _result;
})(); })();
if (unclosed.length) { if (unclosed.length) {
@@ -319,6 +325,8 @@
for (key in INVERSES) { for (key in INVERSES) {
(debt[key] = 0); (debt[key] = 0);
} }
return this.scanTokens(function(token, i, tokens) { return this.scanTokens(function(token, i, tokens) {
var inv, match, mtag, oppos, tag, val; var inv, match, mtag, oppos, tag, val;
if (include(EXPRESSION_START, tag = token[0])) { if (include(EXPRESSION_START, tag = token[0])) {
@@ -366,6 +374,8 @@
EXPRESSION_START.push(INVERSES[rite] = left); EXPRESSION_START.push(INVERSES[rite] = left);
EXPRESSION_END.push(INVERSES[left] = rite); EXPRESSION_END.push(INVERSES[left] = rite);
} }
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END); EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', '@', '->', '=>', '[', '(', '{', '--', '++']; IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', '@', '->', '=>', '[', '(', '{', '--', '++'];

View File

@@ -35,6 +35,8 @@
_result.push(vars[name] = 'reuse'); _result.push(vars[name] = 'reuse');
} }
} }
return _result; return _result;
}; };
Scope.prototype.find = function(name, options) { Scope.prototype.find = function(name, options) {
@@ -53,6 +55,8 @@
return true; return true;
} }
} }
return false; return false;
}; };
Scope.prototype.parameter = function(name) { Scope.prototype.parameter = function(name) {
@@ -108,6 +112,8 @@
_result.push(key); _result.push(key);
} }
} }
return _result; return _result;
}).call(this).sort(); }).call(this).sort();
}; };
@@ -121,6 +127,8 @@
_result.push("" + key + " = " + (val.value)); _result.push("" + key + " = " + (val.value));
} }
} }
return _result; return _result;
}; };
Scope.prototype.compiledDeclarations = function() { Scope.prototype.compiledDeclarations = function() {

View File

@@ -1428,6 +1428,7 @@ exports.For = class For extends Base
nvar = scope.freeVariable 'i' if name and not range and codeInBody nvar = scope.freeVariable 'i' if name and not range and codeInBody
varPart = '' varPart = ''
guardPart = '' guardPart = ''
unstepPart = ''
body = Expressions.wrap([@body]) body = Expressions.wrap([@body])
idt1 = @idt 1 idt1 = @idt 1
if range if range
@@ -1452,8 +1453,9 @@ exports.For = class For extends Base
body = Push.wrap(rvar, body) unless topLevel body = Push.wrap(rvar, body) unless topLevel
if @guard if @guard
body = Expressions.wrap([new If(@guard, body)]) body = Expressions.wrap([new If(@guard, body)])
if codeInBody and not body.containsPureStatement() if codeInBody
body.unshift new Literal "var #{name} = #{ivar}" if range body.unshift new Literal "var #{name} = #{ivar}" if range
if codeInBody and not body.containsPureStatement()
body.unshift new Literal "var #{namePart}" if namePart body.unshift new Literal "var #{namePart}" if namePart
body.unshift new Literal "var #{index} = #{ivar}" if index body.unshift new Literal "var #{index} = #{ivar}" if index
lastLine = body.expressions.pop() lastLine = body.expressions.pop()
@@ -1466,6 +1468,8 @@ exports.For = class For extends Base
body.push new Assign new Literal(name), new Literal nvar or ivar if name body.push new Assign new Literal(name), new Literal nvar or ivar if name
else else
varPart = "#{idt1}#{namePart};\n" if namePart varPart = "#{idt1}#{namePart};\n" if namePart
if forPart and name is ivar
unstepPart = if @step then "\n#{name} -= #{ @step.compile(o) };" else "\n#{name}--;"
if @object if @object
forPart = "#{ivar} in #{sourcePart}" forPart = "#{ivar} in #{sourcePart}"
guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw
@@ -1474,7 +1478,9 @@ exports.For = class For extends Base
""" """
#{resultPart}#{@tab}for (#{forPart}) {#{guardPart} #{resultPart}#{@tab}for (#{forPart}) {#{guardPart}
#{varPart}#{body} #{varPart}#{body}
#{@tab}}#{returnResult} #{@tab}}
#{unstepPart}
#{returnResult}
""" """
#### Switch #### Switch

View File

@@ -23,6 +23,8 @@ negs = negs[0..2]
result = nums.concat(negs).join(', ') result = nums.concat(negs).join(', ')
ok result is '3, 6, 9, -20, -19, -18' ok result is '3, 6, 9, -20, -19, -18'
ok i is 3
ok x is -10
# With range comprehensions, you can loop in steps. # With range comprehensions, you can loop in steps.
@@ -70,17 +72,22 @@ ok obj.one() is "I'm one"
ok obj.two() is "I'm two" ok obj.two() is "I'm two"
ok obj.three() is "I'm three" ok obj.three() is "I'm three"
i = 0
for i in [1..3]
-> 'func'
break if false
ok i is 3
# Ensure that local variables are closed over for range comprehensions. # Ensure that local variables are closed over for range comprehensions.
funcs = for i in [1..3] funcs = for i in [1..3]
-> -i -> -i
ok (func() for func in funcs).join(' ') is '-1 -2 -3' ok (func() for func in funcs).join(' ') is '-1 -2 -3'
ok i is 3
# Ensure that closing over local variables doesn't break scoping laws. # Ensure that closing over local variables doesn't break scoping laws.
ok i is 3
for i in [0] for i in [0]
count = 0 count = 0
i = 50 i = 50