adding steps to range comprehensions
This commit is contained in:
parent
e30a267c9d
commit
0f81dbe913
|
@ -204,7 +204,7 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(break|catch|continue|else|finally|for|if|return|switch|then|throw|try|unless|when|while)\b</string>
|
||||
<string>\b(break|by|catch|continue|else|finally|for|if|return|switch|then|throw|try|unless|when|while)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.control.coffee</string>
|
||||
</dict>
|
||||
|
|
|
@ -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 BY WHILE
|
||||
token SWITCH WHEN
|
||||
token DELETE INSTANCEOF TYPEOF
|
||||
token SUPER EXTENDS
|
||||
|
@ -32,7 +32,7 @@ prechigh
|
|||
left '.'
|
||||
right INDENT
|
||||
left OUTDENT
|
||||
right WHEN IN
|
||||
right WHEN IN BY
|
||||
right THROW FOR WHILE NEW SUPER ELSE
|
||||
left UNLESS EXTENDS IF
|
||||
left ASSIGN '||=' '&&='
|
||||
|
@ -321,8 +321,8 @@ rule
|
|||
# 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]) }
|
||||
| FOR ForVariables ForSource Block { result = ForNode.new(val[3], val[2][0], val[1][0], val[2][1], val[1][1]) }
|
||||
ForVariables ForSource { result = ForNode.new(val[0], val[3], val[2][0], val[2][1]) }
|
||||
| FOR ForVariables ForSource Block { result = ForNode.new(val[3], val[2], val[1][0], val[1][1]) }
|
||||
;
|
||||
|
||||
# An array comprehension has variables for the current element and index.
|
||||
|
@ -333,9 +333,11 @@ rule
|
|||
|
||||
# The source of the array comprehension can optionally be filtered.
|
||||
ForSource:
|
||||
IN Expression { result = [val[1]] }
|
||||
| IN Expression
|
||||
WHEN Expression { result = [val[1], val[3]] }
|
||||
IN Expression { result = {:source => val[1]} }
|
||||
| ForSource
|
||||
WHEN Expression { result = val[0].merge(:filter => val[2]) }
|
||||
| ForSource
|
||||
BY Expression { result = val[0].merge(:step => val[2]) }
|
||||
;
|
||||
|
||||
# Switch/When blocks.
|
||||
|
|
|
@ -12,7 +12,7 @@ module CoffeeScript
|
|||
"new", "return",
|
||||
"try", "catch", "finally", "throw",
|
||||
"break", "continue",
|
||||
"for", "in", "where", "while",
|
||||
"for", "in", "by", "where", "while",
|
||||
"switch", "when",
|
||||
"super", "extends",
|
||||
"delete", "instanceof", "typeof"]
|
||||
|
|
|
@ -360,11 +360,12 @@ module CoffeeScript
|
|||
write("#{idt}#{@from_var} = #{from_val};\n#{idt}#{@to_var} = #{to_val};\n#{idt}")
|
||||
end
|
||||
|
||||
def compile(o, idx=nil)
|
||||
def compile(o, idx=nil, step=nil)
|
||||
raise SyntaxError, "unexpected range literal" unless idx
|
||||
vars = "#{idx}=#{@from_var}"
|
||||
step = step ? step.compile(o) : '1'
|
||||
compare = "(#{@from_var} <= #{@to_var} ? #{idx} #{less_operator} #{@to_var} : #{idx} #{greater_operator} #{@to_var})"
|
||||
incr = "(#{@from_var} <= #{@to_var} ? #{idx} += 1 : #{idx} -= 1)"
|
||||
incr = "(#{@from_var} <= #{@to_var} ? #{idx} += #{step} : #{idx} -= #{step})"
|
||||
write("#{vars}; #{compare}; #{incr}")
|
||||
end
|
||||
|
||||
|
@ -609,10 +610,13 @@ module CoffeeScript
|
|||
custom_return
|
||||
custom_assign
|
||||
|
||||
attr_reader :body, :source, :name, :filter, :index
|
||||
attr_reader :body, :source, :name, :index, :filter, :step
|
||||
|
||||
def initialize(body, source, name, filter, index=nil)
|
||||
@body, @source, @name, @filter, @index = body, source, name, filter, index
|
||||
def initialize(body, source, name, index=nil)
|
||||
@body, @name, @index = body, name, index
|
||||
@source = source[:source]
|
||||
@filter = source[:filter]
|
||||
@step = source[:step]
|
||||
end
|
||||
|
||||
def line_ending
|
||||
|
@ -634,7 +638,7 @@ module CoffeeScript
|
|||
var_part, pre_cond, post_cond = '', '', ''
|
||||
index_var = scope.free_variable
|
||||
source_part = @source.compile_variables(o)
|
||||
for_part = "#{index_var}=0, #{@source.compile(o, ivar)}, #{index_var}++"
|
||||
for_part = "#{index_var}=0, #{@source.compile(o, ivar, @step)}, #{index_var}++"
|
||||
else
|
||||
index_var = nil
|
||||
body_dent = o[:indent] + TAB + TAB
|
||||
|
|
|
@ -12,4 +12,9 @@ j = 5
|
|||
result: for j in [j..(j+3)]
|
||||
j
|
||||
|
||||
print(result.join(' ') is '5 6 7 8')
|
||||
print(result.join(' ') is '5 6 7 8')
|
||||
|
||||
# With range comprehensions, you can loop in steps.
|
||||
results: x for x in [0..25] by 5
|
||||
|
||||
print(results.join(' ') is '0 5 10 15 20 25')
|
Loading…
Reference in New Issue