got negative ranges working with (much, much) uglier compiled code

This commit is contained in:
Jeremy Ashkenas 2009-12-26 20:35:43 -08:00
parent 694833dbd0
commit eeef8d3612
3 changed files with 20 additions and 15 deletions

View File

@ -19,7 +19,7 @@ module CoffeeScript
# Token matching regexes.
IDENTIFIER = /\A([a-zA-Z$_]\w*)/
NUMBER = /\A\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?))\b/i
NUMBER = /\A((\b|-)((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i
STRING = /\A(""|''|"(.*?)[^\\]"|'(.*?)[^\\]')/m
JS = /\A(``|`(.*?)[^\\]`)/m
OPERATOR = /\A([+\*&|\/\-%=<>:!]+)/

View File

@ -307,8 +307,6 @@ module CoffeeScript
# A range literal. Ranges can be used to extract portions (slices) of arrays,
# or to specify a range for array comprehensions.
# RangeNodes get expanded into the equivalent array, if not used to index
# a slice or define an array comprehension.
class RangeNode
attr_reader :from, :to
@ -320,15 +318,20 @@ module CoffeeScript
@exclusive
end
# TODO -- figure out if we can detect if a range runs negative.
def downward?
def less_operator
@exclusive ? '<' : '<='
end
# TODO -- figure out if we can expand ranges into the corresponding array,
# as an expression, reliably.
def compile(o={})
write()
def greater_operator
@exclusive ? '>' : '>='
end
def compile(o, fv, tv)
fvv, tvv = @from.compile(o), @to.compile(o)
vars = "#{fv}=#{fvv}, #{tv}=#{tvv}"
compare = "(#{fvv} <= #{tvv} ? #{fv} #{less_operator} #{tv} : #{fv} #{greater_operator} #{tv})"
incr = "(#{fvv} <= #{tvv} ? #{fv} += 1 : #{fv} -= 1)"
"#{vars}; #{compare}; #{incr}"
end
end
@ -548,11 +551,10 @@ module CoffeeScript
index_name = @index ? @index : nil
if range
source_part = ''
operator = @source.exclusive? ? '<' : '<='
index_var = scope.free_variable
for_part = "#{index_var}=0, #{ivar}=#{@source.from.compile(o)}, #{lvar}=#{@source.to.compile(o)}; #{ivar}#{operator}#{lvar}; #{ivar}++, #{index_var}++"
var_part = ''
index_part = ''
index_var = scope.free_variable
for_part = "#{index_var}=0, #{@source.compile(o, ivar, lvar)}, #{index_var}++"
else
index_var = nil
source_part = "#{svar} = #{@source.compile(o)};\n#{o[:indent]}"

View File

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