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>
<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>
<string>keyword.control.coffee</string>
</dict>

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
func: =>
a: 3
b: []
while a >= 0
b.push('o')
a--
@ -20,7 +21,7 @@ func: =>
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]

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]
result: nums.concat(negs).join(', ')