Expressions -> Block
This commit is contained in:
parent
f4a7cca075
commit
566087b518
|
@ -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
|
||||
});
|
||||
|
|
76
lib/nodes.js
76
lib/nodes.js
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
});
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) ->
|
||||
|
|
Loading…
Reference in New Issue