using 'where' for array comprehension filtering, after kamatsu's suggestion -- execution tests pass now with significant whitespace

This commit is contained in:
Jeremy Ashkenas
2009-12-29 08:52:26 -05:00
parent cea417de02
commit 3fbb870d01
6 changed files with 26 additions and 21 deletions

View File

@@ -204,7 +204,7 @@
</dict> </dict>
<dict> <dict>
<key>match</key> <key>match</key>
<string>\b(break|when|catch|continue|else|finally|for|if|return|switch|then|throw|try|unless|while)\b</string> <string>\b(break|when|catch|continue|else|finally|for|if|return|switch|then|throw|try|unless|where|while)\b</string>
<key>name</key> <key>name</key>
<string>keyword.control.coffee</string> <string>keyword.control.coffee</string>
</dict> </dict>

View File

@@ -8,7 +8,7 @@ token IDENTIFIER PROPERTY_ACCESS
token CODE PARAM NEW RETURN token CODE PARAM NEW RETURN
token TRY CATCH FINALLY THROW token TRY CATCH FINALLY THROW
token BREAK CONTINUE token BREAK CONTINUE
token FOR IN WHILE token FOR IN WHERE WHILE
token SWITCH WHEN token SWITCH WHEN
token DELETE INSTANCEOF TYPEOF token DELETE INSTANCEOF TYPEOF
token SUPER EXTENDS token SUPER EXTENDS
@@ -32,7 +32,7 @@ prechigh
left '.' left '.'
right INDENT right INDENT
left OUTDENT left OUTDENT
right THROW FOR IN WHILE NEW SUPER right THROW FOR IN WHERE WHILE NEW SUPER
left UNLESS IF ELSE EXTENDS left UNLESS IF ELSE EXTENDS
left ASSIGN '||=' '&&=' left ASSIGN '||=' '&&='
right RETURN right RETURN
@@ -178,7 +178,7 @@ rule
| ParamList "=>" Expression { result = CodeNode.new(val[0], Expressions.new([val[2]])) } | ParamList "=>" Expression { result = CodeNode.new(val[0], Expressions.new([val[2]])) }
| "=>" Block { result = CodeNode.new([], val[1]) } | "=>" Block { result = CodeNode.new([], val[1]) }
| "=>" Expression { result = CodeNode.new([], Expressions.new([val[1]])) } | "=>" Expression { result = CodeNode.new([], Expressions.new([val[1]])) }
| "=>" { result = CodeNode.new([], nil) } | "=>" { result = CodeNode.new([], Expressions.new([])) }
; ;
# The parameters to a function definition. # The parameters to a function definition.
@@ -290,14 +290,14 @@ rule
# The while loop. (there is no do..while). # The while loop. (there is no do..while).
While: While:
WHILE PureExpression Block { result = WhileNode.new(val[1], val[3]) } WHILE PureExpression Block { result = WhileNode.new(val[1], val[2]) }
; ;
# Array comprehensions, including guard and current index. # Array comprehensions, including guard and current index.
# Looks a little confusing, check nodes.rb for the arguments to ForNode. # Looks a little confusing, check nodes.rb for the arguments to ForNode.
For: For:
Expression FOR Expression FOR
ForVariables ForSource "." { result = ForNode.new(val[0], val[3][0], val[2][0], val[3][1], val[2][1]) } ForVariables ForSource { result = ForNode.new(val[0], val[3][0], val[2][0], val[3][1], val[2][1]) }
| FOR ForVariables ForSource Block { result = ForNode.new(val[3], val[2][0], val[1][0], val[2][1], val[1][1]) } | FOR ForVariables ForSource Block { result = ForNode.new(val[3], val[2][0], val[1][0], val[2][1], val[1][1]) }
; ;
@@ -311,7 +311,7 @@ rule
ForSource: ForSource:
IN PureExpression { result = [val[1]] } IN PureExpression { result = [val[1]] }
| IN PureExpression | IN PureExpression
IF Expression { result = [val[1], val[3]] } WHERE Expression { result = [val[1], val[3]] }
; ;
# Switch/When blocks. # Switch/When blocks.
@@ -376,8 +376,8 @@ rule
# The full complement of if blocks, including postfix one-liner ifs and unlesses. # The full complement of if blocks, including postfix one-liner ifs and unlesses.
If: If:
IfBlock IfEnd { result = val[0].add_else(val[1]) } IfBlock IfEnd { result = val[0].add_else(val[1]) }
| Block IfClause { result = IfNode.new(val[1], Expressions.new([val[0]]), nil, {:statement => true}) } | Expression IfClause { result = IfNode.new(val[1], Expressions.new([val[0]]), nil, {:statement => true}) }
| Block UNLESS PureExpression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true, :invert => true}) } | Expression UNLESS PureExpression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true, :invert => true}) }
; ;
end end

View File

@@ -12,7 +12,7 @@ module CoffeeScript
"new", "return", "new", "return",
"try", "catch", "finally", "throw", "try", "catch", "finally", "throw",
"break", "continue", "break", "continue",
"for", "in", "while", "for", "in", "where", "while",
"switch", "when", "switch", "when",
"super", "extends", "super", "extends",
"delete", "instanceof", "typeof"] "delete", "instanceof", "typeof"]
@@ -24,11 +24,11 @@ module CoffeeScript
JS = /\A(``|`(.*?)[^\\]`)/m JS = /\A(``|`(.*?)[^\\]`)/m
OPERATOR = /\A([+\*&|\/\-%=<>:!]+)/ OPERATOR = /\A([+\*&|\/\-%=<>:!]+)/
WHITESPACE = /\A([ \t\r]+)/ WHITESPACE = /\A([ \t\r]+)/
NEWLINE = /\A(\n+)(?![ \t\r]+)/
COMMENT = /\A((#[^\n]*\s*)+)/m COMMENT = /\A((#[^\n]*\s*)+)/m
CODE = /\A(=>)/ CODE = /\A(=>)/
REGEX = /\A(\/(.*?)[^\\]\/[imgy]{0,4})/ REGEX = /\A(\/(.*?)[^\\]\/[imgy]{0,4})/
INDENT = /\A\n([ \t\r]*)/ INDENT = /\A\n([ \t\r]*)/
NEWLINE = /\A(\n+)([ \t\r]*)/
# Token cleaning regexes. # Token cleaning regexes.
JS_CLEANER = /(\A`|`\Z)/ JS_CLEANER = /(\A`|`\Z)/
@@ -245,11 +245,15 @@ module CoffeeScript
# To that end, remove redundant outdent/indents from the token stream. # To that end, remove redundant outdent/indents from the token stream.
def remove_empty_outdents def remove_empty_outdents
scan_tokens do |prev, token, post, i| scan_tokens do |prev, token, post, i|
match = (prev[0] == :OUTDENT && token[1] == "\n" && post[0] == :INDENT) if prev[0] == :OUTDENT && token[1] == "\n" && post[0] == :INDENT && prev[1] == post[1]
match = match && prev[1] == post[1] @tokens.delete_at(i + 1)
next unless match @tokens.delete_at(i - 1)
@tokens.delete_at(i + 1) end
@tokens.delete_at(i - 1) if prev[0] == :OUTDENT && token[0] == :INDENT && prev[1] == token[1]
@tokens.delete_at(i)
@tokens.delete_at(i - 1)
@tokens.insert(i - 1, ["\n", Value.new("\n", prev[1].line)])
end
end end
end end

View File

@@ -1,5 +1,5 @@
nums: n * n for n in [1, 2, 3] if n % 2 isnt 0. nums: n * n for n in [1, 2, 3] where n % 2 isnt 0
results: n * 2 for n in nums. results: n * 2 for n in nums
# next: for n in [1, 2, 3] if n % 2 isnt 0 # next: for n in [1, 2, 3] if n % 2 isnt 0
# print('hi') if false # print('hi') if false

View File

@@ -1,6 +1,7 @@
func: => func: =>
a: 3 a: 3
b: [] b: []
while a >= 0 while a >= 0
b.push('o') b.push('o')
a-- a--
@@ -20,7 +21,7 @@ func: =>
text = c.text text = c.text
} }
c.list: l for l in d.text.split('') if l is '-' c.list: l for l in d.text.split('') where l is '-'
c.single: c.list[1..1][0] c.single: c.list[1..1][0]

View File

@@ -1,6 +1,6 @@
nums: i * 3 for i in [1..3]. nums: i * 3 for i in [1..3]
negs: x for x in [-20..-10]. negs: x for x in [-20..-10]
negs: negs[0..2] negs: negs[0..2]
result: nums.concat(negs).join(', ') result: nums.concat(negs).join(', ')