Expressions -> Block

This commit is contained in:
Jeremy Ashkenas 2011-01-15 14:19:35 -05:00
parent f4a7cca075
commit 566087b518
6 changed files with 94 additions and 94 deletions

View File

@ -10,18 +10,18 @@
}
action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
action = action.replace(/\bnew /g, '$&yy.');
action = action.replace(/\b(?:Expressions\.wrap|extend)\b/g, 'yy.$&');
action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&');
return [patternString, "$$ = " + action + ";", options];
};
grammar = {
Root: [
o('', function() {
return new Expressions;
return new Block;
}), o('Body'), o('Block TERMINATOR')
],
Body: [
o('Line', function() {
return Expressions.wrap([$1]);
return Block.wrap([$1]);
}), o('Body TERMINATOR Line', function() {
return $1.push($3);
}), o('Body TERMINATOR')
@ -35,7 +35,7 @@
Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class')],
Block: [
o('INDENT OUTDENT', function() {
return new Expressions;
return new Block;
}), o('INDENT Body OUTDENT', function() {
return $2;
})
@ -357,9 +357,9 @@
o('WhileSource Block', function() {
return $1.addBody($2);
}), o('Statement WhileSource', function() {
return $2.addBody(Expressions.wrap([$1]));
return $2.addBody(Block.wrap([$1]));
}), o('Expression WhileSource', function() {
return $2.addBody(Expressions.wrap([$1]));
return $2.addBody(Block.wrap([$1]));
}), o('Loop', function() {
return $1;
})
@ -368,7 +368,7 @@
o('LOOP Block', function() {
return new While(new Literal('true')).addBody($2);
}), o('LOOP Expression', function() {
return new While(new Literal('true')).addBody(Expressions.wrap([$2]));
return new While(new Literal('true')).addBody(Block.wrap([$2]));
})
],
For: [
@ -492,12 +492,12 @@
o('IfBlock'), o('IfBlock ELSE Block', function() {
return $1.addElse($3);
}), o('Statement POST_IF Expression', function() {
return new If($3, Expressions.wrap([$1]), {
return new If($3, Block.wrap([$1]), {
type: $2,
statement: true
});
}), o('Expression POST_IF Expression', function() {
return new If($3, Expressions.wrap([$1]), {
return new If($3, Block.wrap([$1]), {
type: $2,
statement: true
});

View File

@ -1,5 +1,5 @@
(function() {
var Access, Arr, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, NEGATE, NO, Obj, Op, Param, Parens, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref;
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, NEGATE, NO, Obj, Op, Param, Parens, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
@ -166,34 +166,34 @@
Base.prototype.assigns = NO;
return Base;
})();
exports.Expressions = Expressions = (function() {
__extends(Expressions, Base);
function Expressions(nodes) {
exports.Block = Block = (function() {
__extends(Block, Base);
function Block(nodes) {
this.expressions = compact(flatten(nodes || []));
}
Expressions.prototype.children = ['expressions'];
Expressions.prototype.push = function(node) {
Block.prototype.children = ['expressions'];
Block.prototype.push = function(node) {
this.expressions.push(node);
return this;
};
Expressions.prototype.pop = function() {
Block.prototype.pop = function() {
return this.expressions.pop();
};
Expressions.prototype.unshift = function(node) {
Block.prototype.unshift = function(node) {
this.expressions.unshift(node);
return this;
};
Expressions.prototype.unwrap = function() {
Block.prototype.unwrap = function() {
if (this.expressions.length === 1) {
return this.expressions[0];
} else {
return this;
}
};
Expressions.prototype.isEmpty = function() {
Block.prototype.isEmpty = function() {
return !this.expressions.length;
};
Expressions.prototype.isStatement = function(o) {
Block.prototype.isStatement = function(o) {
var exp, _i, _len, _ref;
_ref = this.expressions;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -204,7 +204,7 @@
}
return false;
};
Expressions.prototype.jumps = function(o) {
Block.prototype.jumps = function(o) {
var exp, _i, _len, _ref;
_ref = this.expressions;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -214,7 +214,7 @@
}
}
};
Expressions.prototype.makeReturn = function() {
Block.prototype.makeReturn = function() {
var expr, len;
len = this.expressions.length;
while (len--) {
@ -229,17 +229,17 @@
}
return this;
};
Expressions.prototype.compile = function(o, level) {
Block.prototype.compile = function(o, level) {
if (o == null) {
o = {};
}
if (o.scope) {
return Expressions.__super__.compile.call(this, o, level);
return Block.__super__.compile.call(this, o, level);
} else {
return this.compileRoot(o);
}
};
Expressions.prototype.compileNode = function(o) {
Block.prototype.compileNode = function(o) {
var code, codes, node, top, _i, _len, _ref;
this.tab = o.indent;
top = o.level === LEVEL_TOP;
@ -267,7 +267,7 @@
return code;
}
};
Expressions.prototype.compileRoot = function(o) {
Block.prototype.compileRoot = function(o) {
var code;
o.indent = this.tab = o.bare ? '' : TAB;
o.scope = new Scope(null, this, null);
@ -280,7 +280,7 @@
return "(function() {\n" + code + "\n}).call(this);\n";
}
};
Expressions.prototype.compileWithDeclarations = function(o) {
Block.prototype.compileWithDeclarations = function(o) {
var code, exp, i, post, rest, scope, _len, _ref;
code = post = '';
_ref = this.expressions;
@ -311,13 +311,13 @@
}
return code + post;
};
Expressions.wrap = function(nodes) {
if (nodes.length === 1 && nodes[0] instanceof Expressions) {
Block.wrap = function(nodes) {
if (nodes.length === 1 && nodes[0] instanceof Block) {
return nodes[0];
}
return new Expressions(nodes);
return new Block(nodes);
};
return Expressions;
return Block;
})();
exports.Literal = Literal = (function() {
__extends(Literal, Base);
@ -944,7 +944,7 @@
function Class(variable, parent, body) {
this.variable = variable;
this.parent = parent;
this.body = body != null ? body : new Expressions;
this.body = body != null ? body : new Block;
this.boundFuncs = [];
this.body.classBody = true;
}
@ -1026,7 +1026,7 @@
if (child instanceof Class) {
return false;
}
if (child instanceof Expressions) {
if (child instanceof Block) {
_ref = exps = child.expressions;
for (i = 0, _len = _ref.length; i < _len; i++) {
node = _ref[i];
@ -1254,7 +1254,7 @@
__extends(Code, Base);
function Code(params, body, tag) {
this.params = params || [];
this.body = body || new Expressions;
this.body = body || new Block;
this.bound = tag === 'boundfunc';
if (this.bound) {
this.context = 'this';
@ -1499,7 +1499,7 @@
}
}
if (this.guard) {
body = Expressions.wrap([new If(this.guard, body)]);
body = Block.wrap([new If(this.guard, body)]);
}
body = "\n" + (body.compile(o, LEVEL_TOP)) + "\n" + this.tab;
}
@ -1801,7 +1801,7 @@
function For(body, source) {
var _ref;
this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
this.body = Expressions.wrap([body]);
this.body = Block.wrap([body]);
this.own = !!source.own;
this.object = !!source.object;
if (this.object) {
@ -1829,7 +1829,7 @@
};
For.prototype.compileNode = function(o) {
var body, defPart, forPart, guardPart, idt1, index, ivar, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, svar, varPart, _ref;
body = Expressions.wrap([this.body]);
body = Block.wrap([this.body]);
lastJumps = (_ref = last(body.expressions)) != null ? _ref.jumps() : void 0;
if (lastJumps && lastJumps instanceof Return) {
this.returns = false;
@ -1885,7 +1885,7 @@
body = Push.wrap(rvar, body);
}
if (this.guard) {
body = Expressions.wrap([new If(this.guard, body)]);
body = Block.wrap([new If(this.guard, body)]);
}
if (this.pattern) {
body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + ivar + "]")));
@ -2034,7 +2034,7 @@
this.elseBodyNode().addElse(elseBody);
} else {
this.isChain = elseBody instanceof If;
this.elseBody = this.ensureExpressions(elseBody);
this.elseBody = this.ensureBlock(elseBody);
}
return this;
};
@ -2054,15 +2054,15 @@
}
};
If.prototype.makeReturn = function() {
this.body && (this.body = new Expressions([this.body.makeReturn()]));
this.elseBody && (this.elseBody = new Expressions([this.elseBody.makeReturn()]));
this.body && (this.body = new Block([this.body.makeReturn()]));
this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn()]));
return this;
};
If.prototype.ensureExpressions = function(node) {
if (node instanceof Expressions) {
If.prototype.ensureBlock = function(node) {
if (node instanceof Block) {
return node;
} else {
return new Expressions([node]);
return new Block([node]);
}
};
If.prototype.compileStatement = function(o) {
@ -2070,7 +2070,7 @@
child = del(o, 'chainChild');
cond = this.condition.compile(o, LEVEL_PAREN);
o.indent += TAB;
body = this.ensureExpressions(this.body).compile(o);
body = this.ensureBlock(this.body).compile(o);
if (body) {
body = "\n" + body + "\n" + this.tab;
}
@ -2114,7 +2114,7 @@
if (expressions.jumps()) {
return expressions;
}
func = new Code([], Expressions.wrap([expressions]));
func = new Code([], Block.wrap([expressions]));
args = [];
if ((mentionsArgs = expressions.contains(this.literalArgs)) || (expressions.contains(this.literalThis))) {
meth = new Literal(mentionsArgs ? 'apply' : 'call');
@ -2127,7 +2127,7 @@
func.noReturn = noReturn;
call = new Call(func, args);
if (statement) {
return Expressions.wrap([call]);
return Block.wrap([call]);
} else {
return call;
}

View File

@ -9,13 +9,13 @@ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$) {
var $0 = $$.length - 1;
switch (yystate) {
case 1:return this.$ = new yy.Expressions;
case 1:return this.$ = new yy.Block;
break;
case 2:return this.$ = $$[$0];
break;
case 3:return this.$ = $$[$0-1];
break;
case 4:this.$ = yy.Expressions.wrap([$$[$0]]);
case 4:this.$ = yy.Block.wrap([$$[$0]]);
break;
case 5:this.$ = $$[$0-2].push($$[$0]);
break;
@ -55,7 +55,7 @@ case 22:this.$ = $$[$0];
break;
case 23:this.$ = $$[$0];
break;
case 24:this.$ = new yy.Expressions;
case 24:this.$ = new yy.Block;
break;
case 25:this.$ = $$[$0-1];
break;
@ -301,15 +301,15 @@ case 136:this.$ = new yy.While($$[$0-2], {
break;
case 137:this.$ = $$[$0-1].addBody($$[$0]);
break;
case 138:this.$ = $$[$0].addBody(yy.Expressions.wrap([$$[$0-1]]));
case 138:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]]));
break;
case 139:this.$ = $$[$0].addBody(yy.Expressions.wrap([$$[$0-1]]));
case 139:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]]));
break;
case 140:this.$ = $$[$0];
break;
case 141:this.$ = new yy.While(new yy.Literal('true')).addBody($$[$0]);
break;
case 142:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Expressions.wrap([$$[$0]]));
case 142:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Block.wrap([$$[$0]]));
break;
case 143:this.$ = new yy.For($$[$0-1], $$[$0]);
break;
@ -410,12 +410,12 @@ case 172:this.$ = $$[$0];
break;
case 173:this.$ = $$[$0-2].addElse($$[$0]);
break;
case 174:this.$ = new yy.If($$[$0], yy.Expressions.wrap([$$[$0-2]]), {
case 174:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), {
type: $$[$0-1],
statement: true
});
break;
case 175:this.$ = new yy.If($$[$0], yy.Expressions.wrap([$$[$0-2]]), {
case 175:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), {
type: $$[$0-1],
statement: true
});

View File

@ -35,7 +35,7 @@ o = (patternString, action, options) ->
return [patternString, '$$ = $1;', options] unless action
action = if match = unwrap.exec action then match[1] else "(#{action}())"
action = action.replace /\bnew /g, '$&yy.'
action = action.replace /\b(?:Expressions\.wrap|extend)\b/g, 'yy.$&'
action = action.replace /\b(?:Block\.wrap|extend)\b/g, 'yy.$&'
[patternString, "$$ = #{action};", options]
# Grammatical Rules
@ -56,19 +56,19 @@ grammar =
# The **Root** is the top-level node in the syntax tree. Since we parse bottom-up,
# all parsing must end here.
Root: [
o '', -> new Expressions
o '', -> new Block
o 'Body'
o 'Block TERMINATOR'
]
# Any list of statements and expressions, separated by line breaks or semicolons.
Body: [
o 'Line', -> Expressions.wrap [$1]
o 'Line', -> Block.wrap [$1]
o 'Body TERMINATOR Line', -> $1.push $3
o 'Body TERMINATOR'
]
# Expressions and statements, which make up a line in a body.
# Block and statements, which make up a line in a body.
Line: [
o 'Expression'
o 'Statement'
@ -84,7 +84,7 @@ grammar =
# All the different types of expressions in our language. The basic unit of
# CoffeeScript is the **Expression** -- everything that can be an expression
# is one. Expressions serve as the building blocks of many other rules, making
# is one. Block serve as the building blocks of many other rules, making
# them somewhat circular.
Expression: [
o 'Value'
@ -104,7 +104,7 @@ grammar =
# will convert some postfix forms into blocks for us, by adjusting the
# token stream.
Block: [
o 'INDENT OUTDENT', -> new Expressions
o 'INDENT OUTDENT', -> new Block
o 'INDENT Body OUTDENT', -> $2
]
@ -166,7 +166,7 @@ grammar =
]
# The **Code** node is the function literal. It's defined by an indented block
# of **Expressions** preceded by a function arrow, with an optional parameter
# of **Block** preceded by a function arrow, with an optional parameter
# list.
Code: [
o 'PARAM_START ParamList PARAM_END FuncGlyph Block', -> new Code $2, $5, $4
@ -350,7 +350,7 @@ grammar =
o 'ArgList OptComma INDENT ArgList OptComma OUTDENT', -> $1.concat $4
]
# Valid arguments are Expressions or Splats.
# Valid arguments are Block or Splats.
Arg: [
o 'Expression'
o 'Splat'
@ -403,14 +403,14 @@ grammar =
# or postfix, with a single expression. There is no do..while.
While: [
o 'WhileSource Block', -> $1.addBody $2
o 'Statement WhileSource', -> $2.addBody Expressions.wrap [$1]
o 'Expression WhileSource', -> $2.addBody Expressions.wrap [$1]
o 'Statement WhileSource', -> $2.addBody Block.wrap [$1]
o 'Expression WhileSource', -> $2.addBody Block.wrap [$1]
o 'Loop', -> $1
]
Loop: [
o 'LOOP Block', -> new While(new Literal 'true').addBody $2
o 'LOOP Expression', -> new While(new Literal 'true').addBody Expressions.wrap [$2]
o 'LOOP Expression', -> new While(new Literal 'true').addBody Block.wrap [$2]
]
# Array, object, and range comprehensions, at the most generic level.
@ -492,8 +492,8 @@ grammar =
If: [
o 'IfBlock'
o 'IfBlock ELSE Block', -> $1.addElse $3
o 'Statement POST_IF Expression', -> new If $3, Expressions.wrap([$1]), type: $2, statement: true
o 'Expression POST_IF Expression', -> new If $3, Expressions.wrap([$1]), type: $2, statement: true
o 'Statement POST_IF Expression', -> new If $3, Block.wrap([$1]), type: $2, statement: true
o 'Expression POST_IF Expression', -> new If $3, Block.wrap([$1]), type: $2, statement: true
]
# Arithmetic and logical operators, working on one or more operands.

View File

@ -145,12 +145,12 @@ exports.Base = class Base
# Is this node used to assign a certain variable?
assigns: NO
#### Expressions
#### Block
# The expressions body is the list of expressions that forms the body of an
# indented block of code -- the implementation of a function, a clause in an
# `if`, `switch`, or `try`, and so on...
exports.Expressions = class Expressions extends Base
exports.Block = class Block extends Base
constructor: (nodes) ->
@expressions = compact flatten nodes or []
@ -170,7 +170,7 @@ exports.Expressions = class Expressions extends Base
@expressions.unshift node
this
# If this Expressions consists of just a single node, unwrap it by pulling
# If this Block consists of just a single node, unwrap it by pulling
# it back out.
unwrap: ->
if @expressions.length is 1 then @expressions[0] else this
@ -188,7 +188,7 @@ exports.Expressions = class Expressions extends Base
for exp in @expressions
return exp if exp.jumps o
# An Expressions node does not return its entire body, rather it
# An Block node does not return its entire body, rather it
# ensures that the final expression is returned.
makeReturn: ->
len = @expressions.length
@ -200,11 +200,11 @@ exports.Expressions = class Expressions extends Base
break
this
# An **Expressions** is the only node that can serve as the root.
# An **Block** is the only node that can serve as the root.
compile: (o = {}, level) ->
if o.scope then super o, level else @compileRoot o
# Compile all expressions within the **Expressions** body. If we need to
# Compile all expressions within the **Block** body. If we need to
# return the result, and it's an expression, simply return it. If it's a
# statement, ask the statement to do so.
compileNode: (o) ->
@ -224,7 +224,7 @@ exports.Expressions = class Expressions extends Base
code = codes.join(', ') or 'void 0'
if codes.length > 1 and o.level >= LEVEL_LIST then "(#{code})" else code
# If we happen to be the top-level **Expressions**, wrap everything in
# If we happen to be the top-level **Block**, wrap everything in
# a safety closure, unless requested not to.
# It would be better not to generate them in the first place, but for now,
# clean up obvious double-parentheses.
@ -257,11 +257,11 @@ exports.Expressions = class Expressions extends Base
code += "#{@tab}var #{ multident scope.assignedVariables().join(', '), @tab };\n"
code + post
# Wrap up the given nodes as an **Expressions**, unless it already happens
# Wrap up the given nodes as an **Block**, unless it already happens
# to be one.
@wrap: (nodes) ->
return nodes[0] if nodes.length is 1 and nodes[0] instanceof Expressions
new Expressions nodes
return nodes[0] if nodes.length is 1 and nodes[0] instanceof Block
new Block nodes
#### Literal
@ -755,7 +755,7 @@ exports.Arr = class Arr extends Base
# Initialize a **Class** with its name, an optional superclass, and a
# list of prototype property assignments.
exports.Class = class Class extends Base
constructor: (@variable, @parent, @body = new Expressions) ->
constructor: (@variable, @parent, @body = new Block) ->
@boundFuncs = []
@body.classBody = yes
@ -819,7 +819,7 @@ exports.Class = class Class extends Base
walkBody: (name) ->
@traverseChildren false, (child) =>
return false if child instanceof Class
if child instanceof Expressions
if child instanceof Block
for node, i in exps = child.expressions
if node instanceof Value and node.isObject(true)
exps[i] = @addProperties node, name
@ -1005,7 +1005,7 @@ exports.Assign = class Assign extends Base
exports.Code = class Code extends Base
constructor: (params, body, tag) ->
@params = params or []
@body = body or new Expressions
@body = body or new Block
@bound = tag is 'boundfunc'
@context = 'this' if @bound
@ -1173,7 +1173,7 @@ exports.While = class While extends Base
rvar = o.scope.freeVariable 'results'
set = "#{@tab}#{rvar} = [];\n"
body = Push.wrap rvar, body if body
body = Expressions.wrap [new If @guard, body] if @guard
body = Block.wrap [new If @guard, body] if @guard
body = "\n#{ body.compile o, LEVEL_TOP }\n#{@tab}"
code = set + @tab + "while (#{ @condition.compile o, LEVEL_PAREN }) {#{body}}"
if @returns
@ -1435,7 +1435,7 @@ exports.Parens = class Parens extends Base
exports.For = class For extends Base
constructor: (body, source) ->
{@source, @guard, @step, @name, @index} = source
@body = Expressions.wrap [body]
@body = Block.wrap [body]
@own = !!source.own
@object = !!source.object
[@name, @index] = [@index, @name] if @object
@ -1461,7 +1461,7 @@ exports.For = class For extends Base
# comprehensions. Some of the generated code can be shared in common, and
# some cannot.
compileNode: (o) ->
body = Expressions.wrap [@body]
body = Block.wrap [@body]
lastJumps = last(body.expressions)?.jumps()
@returns = no if lastJumps and lastJumps instanceof Return
source = if @range then @source.base else @source
@ -1495,7 +1495,7 @@ exports.For = class For extends Base
returnResult = "\n#{@tab}return #{rvar};"
body = Push.wrap rvar, body
if @guard
body = Expressions.wrap [new If @guard, body]
body = Block.wrap [new If @guard, body]
if @pattern
body.expressions.unshift new Assign @name, new Literal "#{svar}[#{ivar}]"
defPart += @pluckDirectCall o, body
@ -1592,7 +1592,7 @@ exports.If = class If extends Base
@elseBodyNode().addElse elseBody
else
@isChain = elseBody instanceof If
@elseBody = @ensureExpressions elseBody
@elseBody = @ensureBlock elseBody
this
# The **If** only compiles into a statement if either of its bodies needs
@ -1607,12 +1607,12 @@ exports.If = class If extends Base
if @isStatement o then @compileStatement o else @compileExpression o
makeReturn: ->
@body and= new Expressions [@body.makeReturn()]
@elseBody and= new Expressions [@elseBody.makeReturn()]
@body and= new Block [@body.makeReturn()]
@elseBody and= new Block [@elseBody.makeReturn()]
this
ensureExpressions: (node) ->
if node instanceof Expressions then node else new Expressions [node]
ensureBlock: (node) ->
if node instanceof Block then node else new Block [node]
# Compile the **If** as a regular *if-else* statement. Flattened chains
# force inner *else* bodies into statement form.
@ -1620,7 +1620,7 @@ exports.If = class If extends Base
child = del o, 'chainChild'
cond = @condition.compile o, LEVEL_PAREN
o.indent += TAB
body = @ensureExpressions(@body).compile o
body = @ensureBlock(@body).compile o
body = "\n#{body}\n#{@tab}" if body
ifPart = "if (#{cond}) {#{body}}"
ifPart = @tab + ifPart unless child
@ -1667,7 +1667,7 @@ Closure =
# then make sure that the closure wrapper preserves the original values.
wrap: (expressions, statement, noReturn) ->
return expressions if expressions.jumps()
func = new Code [], Expressions.wrap [expressions]
func = new Code [], Block.wrap [expressions]
args = []
if (mentionsArgs = expressions.contains @literalArgs) or
( expressions.contains @literalThis)
@ -1677,7 +1677,7 @@ Closure =
func = new Value func, [new Access meth]
func.noReturn = noReturn
call = new Call func, args
if statement then Expressions.wrap [call] else call
if statement then Block.wrap [call] else call
literalArgs: (node) ->
node instanceof Literal and node.value is 'arguments' and not node.asKey

View File

@ -14,7 +14,7 @@ exports.Scope = class Scope
@root: null
# Initialize a scope with its parent, for lookups up the chain,
# as well as a reference to the **Expressions** node is belongs to, which is
# as well as a reference to the **Block** node is belongs to, which is
# where it should declare its variables, and a reference to the function that
# it wraps.
constructor:(@parent, @expressions, @method) ->