From 12134d2043df8d9e2243a7dc64aa71c91216bf5a Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Sat, 20 Nov 2010 18:14:05 -0500 Subject: [PATCH] Using pluckDirectCalls again --- lib/command.js | 14 +++++++++----- lib/lexer.js | 1 - lib/nodes.js | 47 ++++++++++++++++++++++++++--------------------- src/nodes.coffee | 37 +++++++++++++++++++------------------ 4 files changed, 54 insertions(+), 45 deletions(-) diff --git a/lib/command.js b/lib/command.js index 0fe74016..f39e568c 100644 --- a/lib/command.js +++ b/lib/command.js @@ -49,11 +49,10 @@ return compileScripts(); }; compileScripts = function() { - var base, compile, source, _i, _len, _ref, _results; + var _fn, _i, _len, _ref, _results; _ref = sources; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - source = _ref[_i]; + _fn = function(source) { + var base, compile; base = path.join(source); compile = function(source, topLevel) { return path.exists(source, function(exists) { @@ -82,7 +81,12 @@ }); }); }; - _results.push(compile(source, true)); + return _results.push(compile(source, true)); + }; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + source = _ref[_i]; + _fn(source); } return _results; }; diff --git a/lib/lexer.js b/lib/lexer.js index 308b3eec..a4e2ce02 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -471,7 +471,6 @@ } } } - i--; throw new Error("unterminated " + (stack.pop()[0]) + " on line " + (this.line + 1)); }; Lexer.prototype.interpolateString = function(str, options) { diff --git a/lib/nodes.js b/lib/nodes.js index 4b12e8fb..550793ba 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1756,20 +1756,25 @@ }; For.prototype.containsPureStatement = While.prototype.containsPureStatement; For.prototype.compileNode = function(o) { - var body, forPart, guardPart, idt1, index, ivar, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, sourcePart, stepPart, svar, unstepPart, varPart, vars; + var body, defPart, forPart, guardPart, hasCode, idt1, index, ivar, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, svar, varPart; + hasCode = this.body.contains(function(node) { + return node instanceof Code; + }); source = this.range ? this.source.base : this.source; scope = o.scope; name = this.name && this.name.compile(o, LEVEL_LIST); index = this.index && this.index.compile(o, LEVEL_LIST); - if (name && !this.pattern) { - scope.find(name, { - immediate: true - }); - } - if (index) { - scope.find(index, { - immediate: true - }); + if (!hasCode) { + if (name && !this.pattern) { + scope.find(name, { + immediate: true + }); + } + if (index) { + scope.find(index, { + immediate: true + }); + } } if (this.returns) { rvar = scope.freeVariable('results'); @@ -1777,7 +1782,7 @@ ivar = (this.range ? name : index) || scope.freeVariable('i'); varPart = ''; guardPart = ''; - unstepPart = ''; + defPart = ''; body = Expressions.wrap([this.body]); idt1 = this.tab + TAB; if (this.range) { @@ -1790,7 +1795,7 @@ if ((name || !this.raw) && !(IDENTIFIER.test(svar) && scope.check(svar, { immediate: true }))) { - sourcePart = "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n"; + defPart = "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n"; svar = ref; } namePart = this.pattern ? new Assign(this.name, new Literal("" + svar + "[" + ivar + "]")).compile(o, LEVEL_TOP) : name ? "" + name + " = " + svar + "[" + ivar + "]" : void 0; @@ -1810,25 +1815,25 @@ if (this.guard) { body = Expressions.wrap([new If(this.guard, body)]); } + if (hasCode) { + body = Closure.wrap(body, true); + } if (namePart) { varPart = "" + idt1 + namePart + ";\n"; } - if (forPart && name === ivar) { - unstepPart = this.step ? "" + name + " -= " + (this.step.compile(o)) + ";" : "" + name + "--;"; - unstepPart = ("\n" + this.tab) + unstepPart; - } if (this.object) { forPart = "" + ivar + " in " + svar; if (!this.raw) { guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + ivar + ")) continue;"; } } + if (!this.pattern) { + defPart += this.pluckDirectCall(o, body, name, index); + } body = body.compile(merge(o, { - indent: idt1, - top: true - })); - vars = this.range ? name : "" + name + ", " + ivar; - return "" + (sourcePart || '') + (resultPart || '') + this.tab + "for (" + forPart + ") {" + guardPart + "\n" + varPart + body + "\n" + this.tab + "}" + unstepPart + (returnResult || ''); + indent: idt1 + }), LEVEL_TOP); + return "" + defPart + (resultPart || '') + this.tab + "for (" + forPart + ") {" + guardPart + "\n" + varPart + body + "\n" + this.tab + "}" + (returnResult || ''); }; For.prototype.pluckDirectCall = function(o, body, name, index) { var arg, args, base, defs, expr, fn, i, idx, ref, val, _len, _len2, _ref, _ref2, _ref3, _ref4, _ref5, _ref6; diff --git a/src/nodes.coffee b/src/nodes.coffee index 829f0184..c7a109fd 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1423,17 +1423,19 @@ exports.For = class For extends Base # comprehensions. Some of the generated code can be shared in common, and # some cannot. compileNode: (o) -> + hasCode = @body.contains (node) -> node instanceof Code source = if @range then @source.base else @source scope = o.scope name = @name and @name.compile o, LEVEL_LIST index = @index and @index.compile o, LEVEL_LIST - scope.find(name, immediate: yes) if name and not @pattern - scope.find(index, immediate: yes) if index + unless hasCode + scope.find(name, immediate: yes) if name and not @pattern + scope.find(index, immediate: yes) if index rvar = scope.freeVariable 'results' if @returns ivar = (if @range then name else index) or scope.freeVariable 'i' varPart = '' guardPart = '' - unstepPart = '' + defPart = '' body = Expressions.wrap [@body] idt1 = @tab + TAB if @range @@ -1442,35 +1444,34 @@ exports.For = class For extends Base svar = @source.compile o, LEVEL_TOP if (name or not @raw) and not (IDENTIFIER.test(svar) and scope.check svar, immediate: on) - sourcePart = "#{@tab}#{ref = scope.freeVariable 'ref'} = #{svar};\n" + defPart = "#{@tab}#{ref = scope.freeVariable 'ref'} = #{svar};\n" svar = ref namePart = if @pattern new Assign(@name, new Literal "#{svar}[#{ivar}]").compile o, LEVEL_TOP else if name "#{name} = #{svar}[#{ivar}]" unless @object - lvar = scope.freeVariable 'len' - stepPart = if @step then "#{ivar} += #{ @step.compile(o, LEVEL_OP) }" else "#{ivar}++" - forPart = "#{ivar} = 0, #{lvar} = #{svar}.length; #{ivar} < #{lvar}; #{stepPart}" + lvar = scope.freeVariable 'len' + stepPart = if @step then "#{ivar} += #{ @step.compile(o, LEVEL_OP) }" else "#{ivar}++" + forPart = "#{ivar} = 0, #{lvar} = #{svar}.length; #{ivar} < #{lvar}; #{stepPart}" if @returns resultPart = "#{@tab}#{rvar} = [];\n" returnResult = '\n' + (new Return(new Literal(rvar)).compile o, LEVEL_PAREN) body = Push.wrap rvar, body if @returns if @guard - body = Expressions.wrap [new If @guard, body] - varPart = "#{idt1}#{namePart};\n" if namePart - if forPart and name is ivar - unstepPart = if @step then "#{name} -= #{ @step.compile(o) };" else "#{name}--;" - unstepPart = "\n#{@tab}" + unstepPart + body = Expressions.wrap [new If @guard, body] + if hasCode + body = Closure.wrap(body, yes) + varPart = "#{idt1}#{namePart};\n" if namePart if @object - forPart = "#{ivar} in #{svar}" - guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw - body = body.compile merge o, indent: idt1, top: true - vars = if @range then name else "#{name}, #{ivar}" + forPart = "#{ivar} in #{svar}" + guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw + defPart += @pluckDirectCall o, body, name, index unless @pattern + body = body.compile merge(o, indent: idt1), LEVEL_TOP """ - #{sourcePart or ''}#{resultPart or ''}#{@tab}for (#{forPart}) {#{guardPart} + #{defPart}#{resultPart or ''}#{@tab}for (#{forPart}) {#{guardPart} #{varPart}#{body} - #{@tab}}#{unstepPart}#{returnResult or ''} + #{@tab}}#{returnResult or ''} """ pluckDirectCall: (o, body, name, index) ->