diff --git a/lib/nodes.js b/lib/nodes.js index 65cc16fd..f3399974 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -597,7 +597,7 @@ return "" + vars + "; " + (idx) + " " + op + " " + (this.toVar.compile(o)) + "; " + idx + " += " + step; }; RangeNode.prototype.compileArray = function(o) { - var body, clause, equals, from, idt, post, pre, to, vars; + var body, clause, equals, from, i, idt, post, pre, result, to, vars; idt = this.idt(1); vars = this.compileVariables(merge(o, { indent: idt @@ -605,11 +605,13 @@ equals = this.exclusive ? '' : '='; from = this.fromVar.compile(o); to = this.toVar.compile(o); + result = o.scope.freeVariable(); + i = o.scope.freeVariable(); clause = ("" + from + " <= " + to + " ?"); - pre = ("\n" + (idt) + "a = [];" + (vars)); - body = ("var i = " + from + "; (" + clause + " i <" + equals + " " + to + " : i >" + equals + " " + to + "); (" + clause + " i += 1 : i -= 1)"); - post = ("a.push(i);\n" + (idt) + "return a;\n" + o.indent); - return "(function(){" + (pre) + "for (" + body + ") " + post + "}).call(this)"; + pre = ("\n" + (idt) + (result) + " = [];" + (vars)); + body = ("var " + i + " = " + from + "; " + clause + " " + i + " <" + equals + " " + to + " : " + i + " >" + equals + " " + to + "; " + clause + " " + i + " += 1 : " + i + " -= 1"); + post = ("{ " + (result) + ".push(" + i + ") };\n" + (idt) + "return " + result + ";\n" + o.indent); + return "(function(){" + (pre) + ";\n" + (idt) + "for (" + body + ")" + post + "}).call(this)"; }; return RangeNode; })(); diff --git a/src/nodes.coffee b/src/nodes.coffee index a6a8f1ff..045a1daa 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -525,11 +525,13 @@ exports.RangeNode: class RangeNode extends BaseNode equals: if @exclusive then '' else '=' from: @fromVar.compile o to: @toVar.compile o + result: o.scope.freeVariable() + i: o.scope.freeVariable() clause: "$from <= $to ?" - pre: "\n${idt}a = [];${vars}" - body: "var i = $from; ($clause i <$equals $to : i >$equals $to); ($clause i += 1 : i -= 1)" - post: "a.push(i);\n${idt}return a;\n$o.indent" - "(function(){${pre}for ($body) $post}).call(this)" + pre: "\n${idt}${result} = [];${vars}" + body: "var $i = $from; $clause $i <$equals $to : $i >$equals $to; $clause $i += 1 : $i -= 1" + post: "{ ${result}.push($i) };\n${idt}return $result;\n$o.indent" + "(function(){${pre};\n${idt}for ($body)$post}).call(this)" #### SliceNode diff --git a/test/test_ranges_slices_and_splices.coffee b/test/test_ranges_slices_and_splices.coffee index 71d19cde..7b74c1c7 100644 --- a/test/test_ranges_slices_and_splices.coffee +++ b/test/test_ranges_slices_and_splices.coffee @@ -12,10 +12,19 @@ a: [0, 1, 2, 3, 4, 5, 6, 7] deepEqual a[2...6], [2, 3, 4, 5] -# Range. +# Ranges. countdown: [10..1].join(' ') ok countdown is "10 9 8 7 6 5 4 3 2 1" +a: 1 +b: 5 +nums: [a...b] +ok nums.join(' ') is '1 2 3 4' + +b: -5 +nums: [a..b] +ok nums.join(' ') is '1 0 -1 -2 -3 -4 -5' + # Expression-based range. array: [(1+5)..1+9]