First draft at loop block scoping again ... works for functions that mention 'this'

This commit is contained in:
Jeremy Ashkenas
2010-11-03 22:05:24 -04:00
parent 58cac0ca39
commit 9fc3f8593e
2 changed files with 27 additions and 16 deletions

View File

@@ -1534,19 +1534,24 @@
return '';
};
For.prototype.compileNode = function(o) {
var body, code, cond, defPart, forPart, guardPart, idt, index, ivar, lvar, name, namePart, pvar, retPart, rvar, scope, sourcePart, step, svar, tail, tvar, varPart, vars, _ref, _ref2, _ref3, _ref4, _ref5;
var body, code, cond, defPart, forPart, guardPart, hasCode, idt, index, ivar, lvar, name, namePart, pvar, retPart, rvar, scope, sourcePart, step, svar, tail, tvar, varPart, vars, _ref, _ref2, _ref3, _ref4, _ref5;
scope = o.scope;
body = this.body;
hasCode = this.body.contains(function(node) {
return node instanceof Code;
});
name = !this.pattern && ((_ref = this.name) != null ? _ref.compile(o) : void 0);
index = (_ref2 = this.index) != null ? _ref2.compile(o) : void 0;
ivar = !index ? scope.freeVariable('i') : index;
ivar = !index || hasCode ? scope.freeVariable('i') : index;
varPart = guardPart = defPart = retPart = '';
idt = this.idt(1);
if (name) {
scope.find(name, true);
}
if (index) {
scope.find(index, true);
if (!hasCode) {
if (name) {
scope.find(name, true);
}
if (index) {
scope.find(index, true);
}
}
if (this.step) {
_ref3 = this.step.compileLoopReference(o, 'step'), step = _ref3[0], pvar = _ref3[1];
@@ -1597,6 +1602,9 @@
}
})();
}
if (hasCode) {
body = Closure.wrap(body, true);
}
if (namePart) {
varPart = idt + namePart + ';\n';
}
@@ -1633,10 +1641,10 @@
continue;
}
val = expr.variable.unwrapAll();
if (!(val instanceof Code && !expr.args.length || val instanceof Value && val.base instanceof Code && val.properties.length === 1 && ((_ref2 = val.properties[0].name) != null ? _ref2.value : void 0) === 'call')) {
if (!((val instanceof Code && !expr.args.length) || (val instanceof Value && val.base.unwrapAll() instanceof Code && val.properties.length === 1 && ((_ref2 = val.properties[0].name) != null ? _ref2.value : void 0) === 'call'))) {
continue;
}
fn = val.base || val;
fn = val.base.unwrapAll() || val;
ref = new Literal(o.scope.freeVariable('fn'));
base = new Value(ref);
args = compact([name, index]);

View File

@@ -1290,13 +1290,15 @@ exports.For = class For extends Base
compileNode: (o) ->
{scope} = o
{body} = this
hasCode = @body.contains (node) -> node instanceof Code
name = not @pattern and @name?.compile o
index = @index?.compile o
ivar = if not index then scope.freeVariable 'i' else index
ivar = if not index or hasCode then scope.freeVariable 'i' else index
varPart = guardPart = defPart = retPart = ''
idt = @idt 1
scope.find(name, yes) if name
scope.find(index, yes) if index
unless hasCode
scope.find(name, yes) if name
scope.find(index, yes) if index
[step, pvar] = @step.compileLoopReference o, 'step' if @step
if @from
[tail, tvar] = @to.compileLoopReference o, 'to'
@@ -1334,6 +1336,7 @@ exports.For = class For extends Base
when 1 then '++'
when -1 then '--'
else (if pvar < 0 then ' -= ' + pvar.slice 1 else ' += ' + pvar)
body = Closure.wrap(body, yes) if hasCode
varPart = idt + namePart + ';\n' if namePart
defPart += @pluckDirectCall o, body, name, index unless @pattern
code = guardPart + varPart
@@ -1355,11 +1358,11 @@ exports.For = class For extends Base
expr = expr.unwrapAll()
continue unless expr instanceof Call
val = expr.variable.unwrapAll()
continue unless val instanceof Code and not expr.args.length or
val instanceof Value and val.base instanceof Code and
continue unless (val instanceof Code and not expr.args.length) or
(val instanceof Value and val.base.unwrapAll() instanceof Code and
val.properties.length is 1 and
val.properties[0].name?.value is 'call'
fn = val.base or val
val.properties[0].name?.value is 'call')
fn = val.base.unwrapAll() or val
ref = new Literal o.scope.freeVariable 'fn'
base = new Value ref
args = compact [name, index]