removed extra lines from trailing `then` compilations

This commit is contained in:
satyr 2010-10-25 01:54:36 +09:00
parent 26a115adcf
commit d60aa9a80c
3 changed files with 68 additions and 54 deletions

View File

@ -187,8 +187,8 @@
Expressions.prototype.unwrap = function() { Expressions.prototype.unwrap = function() {
return this.expressions.length === 1 ? this.expressions[0] : this; return this.expressions.length === 1 ? this.expressions[0] : this;
}; };
Expressions.prototype.empty = function() { Expressions.prototype.isEmpty = function() {
return this.expressions.length === 0; return !this.expressions.length;
}; };
Expressions.prototype.makeReturn = function() { Expressions.prototype.makeReturn = function() {
var _ref2, end, idx; var _ref2, end, idx;
@ -845,7 +845,7 @@
constScope || (constScope = new Scope(o.scope, constructor.body, constructor)); constScope || (constScope = new Scope(o.scope, constructor.body, constructor));
me || (me = constScope.freeVariable('this')); me || (me = constScope.freeVariable('this'));
pname = pvar.compile(o); pname = pvar.compile(o);
if (constructor.body.empty()) { if (constructor.body.isEmpty()) {
constructor.body.push(new Return(new Literal('this'))); constructor.body.push(new Return(new Literal('this')));
} }
constructor.body.unshift(new Literal("this." + pname + " = function(){ return " + className + ".prototype." + pname + ".apply(" + me + ", arguments); }")); constructor.body.unshift(new Literal("this." + pname + " = function(){ return " + className + ".prototype." + pname + ".apply(" + me + ", arguments); }"));
@ -867,7 +867,7 @@
if (extension) { if (extension) {
construct += '\n' + this.tab + extension.compile(o) + ';'; construct += '\n' + this.tab + extension.compile(o) + ';';
} }
if (!props.empty()) { if (!props.isEmpty()) {
construct += '\n' + props.compile(o); construct += '\n' + props.compile(o);
} }
if (this.returns) { if (this.returns) {
@ -1235,17 +1235,22 @@
o.indent = this.idt(1); o.indent = this.idt(1);
set = ''; set = '';
body = this.body; body = this.body;
if (o.level > LEVEL_TOP || this.returns) { if (body.isEmpty()) {
rvar = o.scope.freeVariable('result'); body = '';
set = "" + this.tab + rvar + " = [];\n"; } else {
if (body) { if (o.level > LEVEL_TOP || this.returns) {
body = Push.wrap(rvar, body); rvar = o.scope.freeVariable('result');
set = "" + this.tab + rvar + " = [];\n";
if (body) {
body = Push.wrap(rvar, body);
}
} }
if (this.guard) {
body = Expressions.wrap([new If(this.guard, body)]);
}
body = "\n" + (body.compile(o, LEVEL_TOP)) + "\n" + this.tab;
} }
if (this.guard) { code = set + this.tab + ("while (" + (this.condition.compile(o, LEVEL_PAREN)) + ") {" + body + "}");
body = Expressions.wrap([new If(this.guard, body)]);
}
code = set + this.tab + ("while (" + (this.condition.compile(o, LEVEL_PAREN)) + ") {\n" + (body.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}");
if (this.returns) { if (this.returns) {
o.indent = this.tab; o.indent = this.tab;
code += '\n' + new Return(new Literal(rvar)).compile(o); code += '\n' + new Return(new Literal(rvar)).compile(o);
@ -1545,7 +1550,7 @@
return ''; return '';
}; };
For.prototype.compileNode = function(o) { For.prototype.compileNode = function(o) {
var _ref2, _ref3, _ref4, _ref5, _ref6, body, cond, defPart, forPart, guardPart, idt, index, ivar, lvar, name, namePart, pvar, retPart, rvar, scope, sourcePart, step, svar, tail, tvar, varPart, vars; var _ref2, _ref3, _ref4, _ref5, _ref6, body, code, cond, defPart, forPart, guardPart, idt, index, ivar, lvar, name, namePart, pvar, retPart, rvar, scope, sourcePart, step, svar, tail, tvar, varPart, vars;
scope = o.scope; scope = o.scope;
name = !this.pattern && ((_ref2 = this.name) != null ? _ref2.compile(o) : undefined); name = !this.pattern && ((_ref2 = this.name) != null ? _ref2.compile(o) : undefined);
index = (_ref3 = this.index) != null ? _ref3.compile(o) : undefined; index = (_ref3 = this.index) != null ? _ref3.compile(o) : undefined;
@ -1612,20 +1617,27 @@
} }
})(); })();
} }
if (o.level > LEVEL_TOP || this.returns) {
rvar = scope.freeVariable('result');
defPart += this.tab + rvar + ' = [];\n';
retPart = this.compileReturnValue(rvar, o);
body = Push.wrap(rvar, body);
}
if (this.guard) {
body = Expressions.wrap([new If(this.guard, body)]);
}
if (namePart) { if (namePart) {
varPart = idt + namePart + ';\n'; varPart = idt + namePart + ';\n';
} }
o.indent = idt; code = guardPart + varPart;
return defPart + ("" + this.tab + "for (" + forPart + ") {\n" + (guardPart || '') + varPart + (body.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}") + retPart; if (!body.isEmpty()) {
if (o.level > LEVEL_TOP || this.returns) {
rvar = scope.freeVariable('result');
defPart += this.tab + rvar + ' = [];\n';
retPart = this.compileReturnValue(rvar, o);
body = Push.wrap(rvar, body);
}
if (this.guard) {
body = Expressions.wrap([new If(this.guard, body)]);
}
o.indent = idt;
code += body.compile(o, LEVEL_TOP);
}
if (code) {
code = '\n' + code + '\n' + this.tab;
}
return defPart + this.tab + ("for (" + forPart + ") {" + code + "}") + retPart;
}; };
return For; return For;
})(); })();
@ -1782,7 +1794,7 @@
}).call(this); }).call(this);
Push = { Push = {
wrap: function(name, expressions) { wrap: function(name, expressions) {
if (expressions.empty() || last(expressions.expressions).containsPureStatement()) { if (expressions.isEmpty() || last(expressions.expressions).containsPureStatement()) {
return expressions; return expressions;
} }
return expressions.push(new Call(new Value(new Literal(name), [new Accessor(new Literal('push'))]), [expressions.pop()])); return expressions.push(new Call(new Value(new Literal(name), [new Accessor(new Literal('push'))]), [expressions.pop()]));

View File

@ -185,8 +185,7 @@ exports.Expressions = class Expressions extends Base
if @expressions.length is 1 then @expressions[0] else this if @expressions.length is 1 then @expressions[0] else this
# Is this an empty block of code? # Is this an empty block of code?
empty: -> isEmpty: -> not @expressions.length
@expressions.length is 0
# An Expressions node does not return its entire body, rather it # An Expressions node does not return its entire body, rather it
# ensures that the final expression is returned. # ensures that the final expression is returned.
@ -720,7 +719,7 @@ exports.Class = class Class extends Base
constScope or= new Scope o.scope, constructor.body, constructor constScope or= new Scope o.scope, constructor.body, constructor
me or= constScope.freeVariable 'this' me or= constScope.freeVariable 'this'
pname = pvar.compile o pname = pvar.compile o
constructor.body.push new Return new Literal 'this' if constructor.body.empty() constructor.body.push new Return new Literal 'this' if constructor.body.isEmpty()
constructor.body.unshift new Literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#{me}, arguments); }" constructor.body.unshift new Literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#{me}, arguments); }"
if pvar if pvar
access = if prop.context is 'this' then pvar.base.properties[0] else new Accessor(pvar, 'prototype') access = if prop.context is 'this' then pvar.base.properties[0] else new Accessor(pvar, 'prototype')
@ -733,7 +732,7 @@ exports.Class = class Class extends Base
o.sharedScope = constScope o.sharedScope = constScope
construct = @tab + new Assign(variable, constructor).compile(o) + ';' construct = @tab + new Assign(variable, constructor).compile(o) + ';'
construct += '\n' + @tab + extension.compile(o) + ';' if extension construct += '\n' + @tab + extension.compile(o) + ';' if extension
construct += '\n' + props.compile o if !props.empty() construct += '\n' + props.compile o if !props.isEmpty()
construct += '\n' + new Return(variable).compile o if @returns construct += '\n' + new Return(variable).compile o if @returns
construct construct
@ -1049,16 +1048,16 @@ exports.While = class While extends Base
o.indent = @idt 1 o.indent = @idt 1
set = '' set = ''
{body} = this {body} = this
if o.level > LEVEL_TOP or @returns if body.isEmpty()
rvar = o.scope.freeVariable 'result' body = ''
set = "#{@tab}#{rvar} = [];\n" else
body = Push.wrap rvar, body if body if o.level > LEVEL_TOP or @returns
body = Expressions.wrap [new If @guard, body] if @guard rvar = o.scope.freeVariable 'result'
code = set + @tab + """ set = "#{@tab}#{rvar} = [];\n"
while (#{ @condition.compile o, LEVEL_PAREN }) { body = Push.wrap rvar, body if body
#{ body.compile o, LEVEL_TOP } body = Expressions.wrap [new If @guard, body] if @guard
#{@tab}} body = "\n#{ body.compile o, LEVEL_TOP }\n#{@tab}"
""" code = set + @tab + "while (#{ @condition.compile o, LEVEL_PAREN }) {#{body}}"
if @returns if @returns
o.indent = @tab o.indent = @tab
code += '\n' + new Return(new Literal rvar).compile o code += '\n' + new Return(new Literal rvar).compile o
@ -1363,19 +1362,19 @@ exports.For = class For extends Base
when 1 then '++' when 1 then '++'
when -1 then '--' when -1 then '--'
else (if pvar < 0 then ' -= ' + pvar.slice 1 else ' += ' + pvar) else (if pvar < 0 then ' -= ' + pvar.slice 1 else ' += ' + pvar)
if o.level > LEVEL_TOP or @returns varPart = idt + namePart + ';\n' if namePart
rvar = scope.freeVariable 'result' code = guardPart + varPart
defPart += @tab + rvar + ' = [];\n' unless body.isEmpty()
retPart = @compileReturnValue rvar, o if o.level > LEVEL_TOP or @returns
body = Push.wrap rvar, body rvar = scope.freeVariable 'result'
body = Expressions.wrap [new If @guard, body] if @guard defPart += @tab + rvar + ' = [];\n'
varPart = idt + namePart + ';\n' if namePart retPart = @compileReturnValue rvar, o
o.indent = idt body = Push.wrap rvar, body
defPart + """ body = Expressions.wrap [new If @guard, body] if @guard
#{@tab}for (#{forPart}) { o.indent = idt
#{ guardPart or '' }#{varPart}#{ body.compile o, LEVEL_TOP } code += body.compile o, LEVEL_TOP
#{@tab}} code = '\n' + code + '\n' + @tab if code
""" + retPart defPart + @tab + "for (#{forPart}) {#{code}}" + retPart
#### Switch #### Switch
@ -1500,7 +1499,7 @@ exports.If = class If extends Base
# which is helpful for recording the result arrays from comprehensions. # which is helpful for recording the result arrays from comprehensions.
Push = Push =
wrap: (name, expressions) -> wrap: (name, expressions) ->
return expressions if expressions.empty() or return expressions if expressions.isEmpty() or
last(expressions.expressions).containsPureStatement() last(expressions.expressions).containsPureStatement()
expressions.push new Call(new Value new Literal(name), [new Accessor new Literal 'push'] expressions.push new Call(new Value new Literal(name), [new Accessor new Literal 'push']
[expressions.pop()]) [expressions.pop()])

View File

@ -9,3 +9,6 @@ ok 'passed' is CoffeeScript.eval '"passed"', bare: on, fileName: 'test'
#750 #750
try ok not CoffeeScript.nodes 'f(->' try ok not CoffeeScript.nodes 'f(->'
catch e then eq e.message, 'unclosed CALL_START on line 1' catch e then eq e.message, 'unclosed CALL_START on line 1'
eq CoffeeScript.compile('for all k of o then', bare: on, globals: on),
'for (k in o) {}'