From dc2f77e019c5245d4e767c6257ded1cc82383df5 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Tue, 21 Dec 2010 19:14:53 -0500 Subject: [PATCH] Allowing the fat arrow to be used in scoped loops. --- lib/nodes.js | 5 ++++- lib/rewriter.js | 2 +- src/nodes.coffee | 4 +++- src/rewriter.coffee | 2 +- test/test_comprehensions.coffee | 4 ++-- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index 39f56825..e7e4a641 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -42,7 +42,7 @@ }; Base.prototype.compileClosure = function(o) { if (this.containsPureStatement()) { - throw SyntaxError('cannot include a pure statement in an expression.'); + throw SyntaxError('cannot use a pure statement in an expression.'); } o.sharedScope = true; return Closure.wrap(this).compileNode(o); @@ -1799,6 +1799,9 @@ guardPart = ''; defPart = ''; idt1 = this.tab + TAB; + if (this.scoped && this.containsPureStatement()) { + throw SyntaxError('cannot use a pure statement in a scoped loop.'); + } if (this.range) { forPart = source.compile(merge(o, { index: ivar, diff --git a/lib/rewriter.js b/lib/rewriter.js index f0bfd877..e7f063c8 100644 --- a/lib/rewriter.js +++ b/lib/rewriter.js @@ -176,7 +176,7 @@ if (prev && !prev.spaced && tag === '?') { token.call = true; } - if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref3 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref3) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0) && !(seenFor && tag === '->' && next && next[0] === 'INDENT'))) { + if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref3 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref3) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0) && !(seenFor && (tag === '->' || tag === '=>') && next && next[0] === 'INDENT'))) { return 1; } tokens.splice(i, 0, ['CALL_START', '(', token[2]]); diff --git a/src/nodes.coffee b/src/nodes.coffee index 22a15bf9..3d91f019 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -49,7 +49,7 @@ exports.Base = class Base # object with their parent closure, to preserve the expected lexical scope. compileClosure: (o) -> if @containsPureStatement() - throw SyntaxError 'cannot include a pure statement in an expression.' + throw SyntaxError 'cannot use a pure statement in an expression.' o.sharedScope = yes Closure.wrap(this).compileNode o @@ -1454,6 +1454,8 @@ exports.For = class For extends Base guardPart = '' defPart = '' idt1 = @tab + TAB + if @scoped and @containsPureStatement() + throw SyntaxError 'cannot use a pure statement in a scoped loop.' if @range forPart = source.compile merge(o, {index: ivar, @step}) else diff --git a/src/rewriter.coffee b/src/rewriter.coffee index 3e1e641e..74eb9f7a 100644 --- a/src/rewriter.coffee +++ b/src/rewriter.coffee @@ -148,7 +148,7 @@ class exports.Rewriter return 1 unless callObject or prev?.spaced and (prev.call or prev[0] in IMPLICIT_FUNC) and (tag in IMPLICIT_CALL or not (token.spaced or token.newLine) and tag in IMPLICIT_UNSPACED_CALL) and - not (seenFor and tag is '->' and next and next[0] is 'INDENT') + not (seenFor and tag in ['->', '=>'] and next and next[0] is 'INDENT') tokens.splice i, 0, ['CALL_START', '(', token[2]] @detectEnd i + 1, (token, i) -> return yes if not seenSingle and token.fromThen diff --git a/test/test_comprehensions.coffee b/test/test_comprehensions.coffee index ef38a69e..1d4c2808 100644 --- a/test/test_comprehensions.coffee +++ b/test/test_comprehensions.coffee @@ -139,8 +139,8 @@ ok(num % 2 is 0 for num in array by 2) # Nested shared scopes. foo = -> - for i in [0..7] -> - for j in [0..7] -> + for i in [0..7] => + for j in [0..7] => -> i + j eq foo()[3][4](), 7