mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Pulling in variable declarations closer to inner scope (after Coco).
This commit is contained in:
parent
b5bd58b2b6
commit
466cd43277
8 changed files with 56 additions and 47 deletions
|
@ -211,8 +211,9 @@
|
||||||
return jsl.stdin.end();
|
return jsl.stdin.end();
|
||||||
};
|
};
|
||||||
printTokens = function(tokens) {
|
printTokens = function(tokens) {
|
||||||
var strings, tag, token, value, _i, _len, _ref, _results;
|
var strings, tag, token, value;
|
||||||
strings = function() {
|
strings = function() {
|
||||||
|
var _i, _len, _ref, _results;
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = tokens.length; _i < _len; _i++) {
|
for (_i = 0, _len = tokens.length; _i < _len; _i++) {
|
||||||
token = tokens[_i];
|
token = tokens[_i];
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(function() {
|
(function() {
|
||||||
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap, _i, _j, _len, _len2, _ref, _results;
|
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
|
||||||
Parser = require('jison').Parser;
|
Parser = require('jison').Parser;
|
||||||
unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
|
unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
|
||||||
o = function(patternString, action, options) {
|
o = function(patternString, action, options) {
|
||||||
|
@ -561,6 +561,7 @@
|
||||||
for (name in grammar) {
|
for (name in grammar) {
|
||||||
alternatives = grammar[name];
|
alternatives = grammar[name];
|
||||||
grammar[name] = function() {
|
grammar[name] = function() {
|
||||||
|
var _i, _j, _len, _len2, _ref, _results;
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = alternatives.length; _i < _len; _i++) {
|
for (_i = 0, _len = alternatives.length; _i < _len; _i++) {
|
||||||
alt = alternatives[_i];
|
alt = alternatives[_i];
|
||||||
|
|
68
lib/nodes.js
68
lib/nodes.js
|
@ -44,7 +44,7 @@
|
||||||
if (this.containsPureStatement()) {
|
if (this.containsPureStatement()) {
|
||||||
throw SyntaxError('cannot include a pure statement in an expression.');
|
throw SyntaxError('cannot include a pure statement in an expression.');
|
||||||
}
|
}
|
||||||
o.sharedScope = o.scope;
|
o.sharedScope = true;
|
||||||
return Closure.wrap(this).compileNode(o);
|
return Closure.wrap(this).compileNode(o);
|
||||||
};
|
};
|
||||||
Base.prototype.cache = function(o, level, reused) {
|
Base.prototype.cache = function(o, level, reused) {
|
||||||
|
@ -597,7 +597,7 @@
|
||||||
return ifn;
|
return ifn;
|
||||||
};
|
};
|
||||||
Call.prototype.compileNode = function(o) {
|
Call.prototype.compileNode = function(o) {
|
||||||
var arg, args, code, _i, _len, _ref, _ref2, _results;
|
var arg, args, code, _ref;
|
||||||
if ((_ref = this.variable) != null) {
|
if ((_ref = this.variable) != null) {
|
||||||
_ref.front = this.front;
|
_ref.front = this.front;
|
||||||
}
|
}
|
||||||
|
@ -605,10 +605,11 @@
|
||||||
return this.compileSplat(o, code);
|
return this.compileSplat(o, code);
|
||||||
}
|
}
|
||||||
args = (function() {
|
args = (function() {
|
||||||
_ref2 = this.args;
|
var _i, _len, _ref, _results;
|
||||||
|
_ref = this.args;
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
arg = _ref2[_i];
|
arg = _ref[_i];
|
||||||
_results.push(arg.compile(o, LEVEL_LIST));
|
_results.push(arg.compile(o, LEVEL_LIST));
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
|
@ -803,7 +804,7 @@
|
||||||
}
|
}
|
||||||
Obj.prototype.children = ['properties'];
|
Obj.prototype.children = ['properties'];
|
||||||
Obj.prototype.compileNode = function(o) {
|
Obj.prototype.compileNode = function(o) {
|
||||||
var i, idt, indent, join, lastNoncom, nonComments, obj, prop, props, _i, _len, _len2, _ref, _results, _results2;
|
var i, idt, indent, join, lastNoncom, nonComments, obj, prop, props;
|
||||||
props = this.properties;
|
props = this.properties;
|
||||||
if (!props.length) {
|
if (!props.length) {
|
||||||
if (this.front) {
|
if (this.front) {
|
||||||
|
@ -814,6 +815,7 @@
|
||||||
}
|
}
|
||||||
idt = o.indent += TAB;
|
idt = o.indent += TAB;
|
||||||
nonComments = (function() {
|
nonComments = (function() {
|
||||||
|
var _i, _len, _ref, _results;
|
||||||
_ref = this.properties;
|
_ref = this.properties;
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
@ -826,8 +828,9 @@
|
||||||
}.call(this));
|
}.call(this));
|
||||||
lastNoncom = last(nonComments);
|
lastNoncom = last(nonComments);
|
||||||
props = function() {
|
props = function() {
|
||||||
_results2 = [];
|
var _len, _results;
|
||||||
for (i = 0, _len2 = props.length; i < _len2; i++) {
|
_results = [];
|
||||||
|
for (i = 0, _len = props.length; i < _len; i++) {
|
||||||
prop = props[i];
|
prop = props[i];
|
||||||
join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
|
join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
|
||||||
indent = prop instanceof Comment ? '' : idt;
|
indent = prop instanceof Comment ? '' : idt;
|
||||||
|
@ -836,9 +839,9 @@
|
||||||
} else if (!(prop instanceof Assign) && !(prop instanceof Comment)) {
|
} else if (!(prop instanceof Assign) && !(prop instanceof Comment)) {
|
||||||
prop = new Assign(prop, prop, 'object');
|
prop = new Assign(prop, prop, 'object');
|
||||||
}
|
}
|
||||||
_results2.push(indent + prop.compile(o, LEVEL_TOP) + join);
|
_results.push(indent + prop.compile(o, LEVEL_TOP) + join);
|
||||||
}
|
}
|
||||||
return _results2;
|
return _results;
|
||||||
}();
|
}();
|
||||||
props = props.join('');
|
props = props.join('');
|
||||||
obj = "{" + (props && '\n' + props + '\n' + this.tab) + "}";
|
obj = "{" + (props && '\n' + props + '\n' + this.tab) + "}";
|
||||||
|
@ -868,7 +871,7 @@
|
||||||
}
|
}
|
||||||
Arr.prototype.children = ['objects'];
|
Arr.prototype.children = ['objects'];
|
||||||
Arr.prototype.compileNode = function(o) {
|
Arr.prototype.compileNode = function(o) {
|
||||||
var code, obj, _i, _len, _ref, _results;
|
var code, obj;
|
||||||
if (!this.objects.length) {
|
if (!this.objects.length) {
|
||||||
return '[]';
|
return '[]';
|
||||||
}
|
}
|
||||||
|
@ -877,6 +880,7 @@
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
code = (function() {
|
code = (function() {
|
||||||
|
var _i, _len, _ref, _results;
|
||||||
_ref = this.objects;
|
_ref = this.objects;
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
@ -1218,12 +1222,9 @@
|
||||||
return !!this.ctor;
|
return !!this.ctor;
|
||||||
};
|
};
|
||||||
Code.prototype.compileNode = function(o) {
|
Code.prototype.compileNode = function(o) {
|
||||||
var code, exprs, i, idt, lit, p, param, ref, sharedScope, splats, v, val, vars, wasEmpty, _i, _j, _k, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _results;
|
var code, exprs, i, idt, lit, p, param, ref, splats, v, val, vars, wasEmpty, _i, _j, _len, _len2, _len3, _ref, _ref2, _ref3;
|
||||||
sharedScope = del(o, 'sharedScope');
|
o.scope = new Scope(o.scope, this.body, this);
|
||||||
o.scope = sharedScope || new Scope(o.scope, this.body, this);
|
o.scope.shared = del(o, 'sharedScope');
|
||||||
if (sharedScope) {
|
|
||||||
o.scope.shared = true;
|
|
||||||
}
|
|
||||||
o.indent += TAB;
|
o.indent += TAB;
|
||||||
delete o.bare;
|
delete o.bare;
|
||||||
delete o.globals;
|
delete o.globals;
|
||||||
|
@ -1234,10 +1235,11 @@
|
||||||
param = _ref[_i];
|
param = _ref[_i];
|
||||||
if (param.splat) {
|
if (param.splat) {
|
||||||
splats = new Assign(new Value(new Arr(function() {
|
splats = new Assign(new Value(new Arr(function() {
|
||||||
_ref2 = this.params;
|
var _i, _len, _ref, _results;
|
||||||
|
_ref = this.params;
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
p = _ref2[_j];
|
p = _ref[_i];
|
||||||
_results.push(p.asReference(o));
|
_results.push(p.asReference(o));
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
|
@ -1245,9 +1247,9 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ref3 = this.params;
|
_ref2 = this.params;
|
||||||
for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) {
|
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
|
||||||
param = _ref3[_k];
|
param = _ref2[_j];
|
||||||
if (param.isComplex()) {
|
if (param.isComplex()) {
|
||||||
val = ref = param.asReference(o);
|
val = ref = param.asReference(o);
|
||||||
if (param.value) {
|
if (param.value) {
|
||||||
|
@ -1273,10 +1275,10 @@
|
||||||
exprs.unshift(splats);
|
exprs.unshift(splats);
|
||||||
}
|
}
|
||||||
if (exprs.length) {
|
if (exprs.length) {
|
||||||
(_ref4 = this.body.expressions).unshift.apply(_ref4, exprs);
|
(_ref3 = this.body.expressions).unshift.apply(_ref3, exprs);
|
||||||
}
|
}
|
||||||
if (!splats) {
|
if (!splats) {
|
||||||
for (i = 0, _len4 = vars.length; i < _len4; i++) {
|
for (i = 0, _len3 = vars.length; i < _len3; i++) {
|
||||||
v = vars[i];
|
v = vars[i];
|
||||||
o.scope.parameter(vars[i] = v.compile(o));
|
o.scope.parameter(vars[i] = v.compile(o));
|
||||||
}
|
}
|
||||||
|
@ -1367,7 +1369,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Splat.compileSplattedArray = function(o, list, apply) {
|
Splat.compileSplattedArray = function(o, list, apply) {
|
||||||
var args, base, code, i, index, node, _i, _len, _len2, _ref, _results;
|
var args, base, code, i, index, node, _len;
|
||||||
index = -1;
|
index = -1;
|
||||||
while ((node = list[++index]) && !(node instanceof Splat)) {
|
while ((node = list[++index]) && !(node instanceof Splat)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1392,9 +1394,10 @@
|
||||||
return args[0] + (".concat(" + (args.slice(1).join(', ')) + ")");
|
return args[0] + (".concat(" + (args.slice(1).join(', ')) + ")");
|
||||||
}
|
}
|
||||||
base = (function() {
|
base = (function() {
|
||||||
|
var _i, _len, _ref, _results;
|
||||||
_ref = list.slice(0, index);
|
_ref = list.slice(0, index);
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len2 = _ref.length; _i < _len2; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
node = _ref[_i];
|
node = _ref[_i];
|
||||||
_results.push(node.compile(o, LEVEL_LIST));
|
_results.push(node.compile(o, LEVEL_LIST));
|
||||||
}
|
}
|
||||||
|
@ -1611,14 +1614,15 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
In.prototype.compileOrTest = function(o) {
|
In.prototype.compileOrTest = function(o) {
|
||||||
var cmp, cnj, i, item, ref, sub, tests, _len, _ref, _ref2, _ref3, _results;
|
var cmp, cnj, i, item, ref, sub, tests, _ref, _ref2;
|
||||||
_ref = this.object.cache(o, LEVEL_OP), sub = _ref[0], ref = _ref[1];
|
_ref = this.object.cache(o, LEVEL_OP), sub = _ref[0], ref = _ref[1];
|
||||||
_ref2 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref2[0], cnj = _ref2[1];
|
_ref2 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref2[0], cnj = _ref2[1];
|
||||||
tests = function() {
|
tests = function() {
|
||||||
_ref3 = this.array.base.objects;
|
var _len, _ref, _results;
|
||||||
|
_ref = this.array.base.objects;
|
||||||
_results = [];
|
_results = [];
|
||||||
for (i = 0, _len = _ref3.length; i < _len; i++) {
|
for (i = 0, _len = _ref.length; i < _len; i++) {
|
||||||
item = _ref3[i];
|
item = _ref[i];
|
||||||
_results.push((i ? ref : sub) + cmp + item.compile(o, LEVEL_OP));
|
_results.push((i ? ref : sub) + cmp + item.compile(o, LEVEL_OP));
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
|
@ -1882,7 +1886,7 @@
|
||||||
args.unshift(new Literal('this'));
|
args.unshift(new Literal('this'));
|
||||||
}
|
}
|
||||||
body.expressions[idx] = new Call(base, args);
|
body.expressions[idx] = new Call(base, args);
|
||||||
o.sharedScope = o.scope;
|
o.sharedScope = true;
|
||||||
defs += this.tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n';
|
defs += this.tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n';
|
||||||
}
|
}
|
||||||
return defs;
|
return defs;
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
Scope.root = this;
|
Scope.root = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Scope.prototype.add = function(name, type) {
|
Scope.prototype.add = function(name, type, immediate) {
|
||||||
var pos;
|
var pos;
|
||||||
|
if (this.shared && !immediate) {
|
||||||
|
return this.parent.add(name, type, immediate);
|
||||||
|
}
|
||||||
if (typeof (pos = this.positions[name]) === 'number') {
|
if (typeof (pos = this.positions[name]) === 'number') {
|
||||||
return this.variables[pos].type = type;
|
return this.variables[pos].type = type;
|
||||||
} else {
|
} else {
|
||||||
|
@ -37,7 +40,7 @@
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
Scope.prototype.parameter = function(name) {
|
Scope.prototype.parameter = function(name) {
|
||||||
if (this.shared && this.check(name, true)) {
|
if (this.shared && this.parent.check(name, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return this.add(name, 'param');
|
return this.add(name, 'param');
|
||||||
|
@ -74,7 +77,7 @@
|
||||||
while (this.check((temp = this.temporary(type, index)), true)) {
|
while (this.check((temp = this.temporary(type, index)), true)) {
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
this.add(temp, 'var');
|
this.add(temp, 'var', true);
|
||||||
return temp;
|
return temp;
|
||||||
};
|
};
|
||||||
Scope.prototype.assign = function(name, value) {
|
Scope.prototype.assign = function(name, value) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ exports.Base = class Base
|
||||||
compileClosure: (o) ->
|
compileClosure: (o) ->
|
||||||
if @containsPureStatement()
|
if @containsPureStatement()
|
||||||
throw SyntaxError 'cannot include a pure statement in an expression.'
|
throw SyntaxError 'cannot include a pure statement in an expression.'
|
||||||
o.sharedScope = o.scope
|
o.sharedScope = yes
|
||||||
Closure.wrap(this).compileNode o
|
Closure.wrap(this).compileNode o
|
||||||
|
|
||||||
# If the code generation wishes to use the result of a complex expression
|
# If the code generation wishes to use the result of a complex expression
|
||||||
|
@ -988,9 +988,8 @@ exports.Code = class Code extends Base
|
||||||
# arrow, generates a wrapper that saves the current value of `this` through
|
# arrow, generates a wrapper that saves the current value of `this` through
|
||||||
# a closure.
|
# a closure.
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
sharedScope = del o, 'sharedScope'
|
o.scope = new Scope o.scope, @body, this
|
||||||
o.scope = sharedScope or new Scope o.scope, @body, this
|
o.scope.shared = del o, 'sharedScope'
|
||||||
o.scope.shared = yes if sharedScope
|
|
||||||
o.indent += TAB
|
o.indent += TAB
|
||||||
delete o.bare
|
delete o.bare
|
||||||
delete o.globals
|
delete o.globals
|
||||||
|
@ -1495,7 +1494,7 @@ exports.For = class For extends Base
|
||||||
[val.base, base] = [base, val]
|
[val.base, base] = [base, val]
|
||||||
args.unshift new Literal 'this'
|
args.unshift new Literal 'this'
|
||||||
body.expressions[idx] = new Call base, args
|
body.expressions[idx] = new Call base, args
|
||||||
o.sharedScope = o.scope
|
o.sharedScope = yes
|
||||||
defs += @tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n'
|
defs += @tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n'
|
||||||
defs
|
defs
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ exports.Scope = class Scope
|
||||||
Scope.root = this unless @parent
|
Scope.root = this unless @parent
|
||||||
|
|
||||||
# Adds a new variable or overrides an existing one.
|
# Adds a new variable or overrides an existing one.
|
||||||
add: (name, type) ->
|
add: (name, type, immediate) ->
|
||||||
|
return @parent.add name, type, immediate if @shared and not immediate
|
||||||
if typeof (pos = @positions[name]) is 'number'
|
if typeof (pos = @positions[name]) is 'number'
|
||||||
@variables[pos].type = type
|
@variables[pos].type = type
|
||||||
else
|
else
|
||||||
|
@ -39,7 +40,7 @@ exports.Scope = class Scope
|
||||||
# Reserve a variable name as originating from a function parameter for this
|
# Reserve a variable name as originating from a function parameter for this
|
||||||
# scope. No `var` required for internal references.
|
# scope. No `var` required for internal references.
|
||||||
parameter: (name) ->
|
parameter: (name) ->
|
||||||
return if @shared and @check name, yes
|
return if @shared and @parent.check name, yes
|
||||||
@add name, 'param'
|
@add name, 'param'
|
||||||
|
|
||||||
# Just check to see if a variable has already been declared, without reserving,
|
# Just check to see if a variable has already been declared, without reserving,
|
||||||
|
@ -66,7 +67,7 @@ exports.Scope = class Scope
|
||||||
freeVariable: (type) ->
|
freeVariable: (type) ->
|
||||||
index = 0
|
index = 0
|
||||||
index++ while @check((temp = @temporary type, index), true)
|
index++ while @check((temp = @temporary type, index), true)
|
||||||
@add temp, 'var'
|
@add temp, 'var', yes
|
||||||
temp
|
temp
|
||||||
|
|
||||||
# Ensure that an assignment is made at the top of this scope
|
# Ensure that an assignment is made at the top of this scope
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Importing
|
# Importing
|
||||||
# ---------
|
# ---------
|
||||||
|
|
||||||
unless window? or testingBrowser
|
unless window? or testingBrowser?
|
||||||
test "coffeescript modules can be imported and executed", ->
|
test "coffeescript modules can be imported and executed", ->
|
||||||
|
|
||||||
magicKey = __filename
|
magicKey = __filename
|
||||||
|
|
|
@ -236,7 +236,7 @@ list = ['one', 'two']
|
||||||
|
|
||||||
(->
|
(->
|
||||||
for entity in list
|
for entity in list
|
||||||
facets[entity] = -> entity
|
facets[entity] = -> entity
|
||||||
)()
|
)()
|
||||||
|
|
||||||
eq typeof entity, 'undefined'
|
eq typeof entity, 'undefined'
|
||||||
|
|
Loading…
Add table
Reference in a new issue