reorganizing test fixtures and adding range literals for array slices

This commit is contained in:
Jeremy Ashkenas
2009-12-25 16:20:28 -08:00
parent 62485c2b8c
commit 1ba7c77136
21 changed files with 46 additions and 22 deletions

View File

@@ -64,8 +64,7 @@ rule
# The parts that are natural JavaScript expressions.
PureExpression:
Literal
| Value
Value
| Call
| Code
| Operation
@@ -213,6 +212,7 @@ rule
# Expressions that can be treated as values.
Value:
IDENTIFIER { result = ValueNode.new(val[0]) }
| Literal { result = ValueNode.new(val[0]) }
| Array { result = ValueNode.new(val[0]) }
| Object { result = ValueNode.new(val[0]) }
| Parenthetical { result = ValueNode.new(val[0]) }
@@ -234,7 +234,7 @@ rule
# Array slice literal.
Slice:
"[" Expression "," Expression "]" { result = SliceNode.new(val[1], val[3]) }
"[" Range "]" { result = SliceNode.new(val[1]) }
;
# An object literal.
@@ -273,6 +273,12 @@ rule
SUPER "(" ArgList ")" { result = CallNode.new(:super, val[2]) }
;
# The range literal.
Range:
Value "." "." Value { result = RangeNode.new(val[0], val[3]) }
| Value "." "." "." Value { result = RangeNode.new(val[0], val[4], true) }
;
# The array literal.
Array:
"[" ArgList "]" { result = ArrayNode.new(val[1]) }

View File

@@ -75,7 +75,7 @@ module CoffeeScript
# Keywords are special identifiers tagged with their own name, 'if' will result
# in an [:IF, "if"] token
tag = KEYWORDS.include?(identifier) ? identifier.upcase.to_sym : :IDENTIFIER
@tokens[-1][0] = :PROPERTY_ACCESS if tag == :IDENTIFIER && last_value == '.'
@tokens[-1][0] = :PROPERTY_ACCESS if tag == :IDENTIFIER && last_value == '.' && !(@tokens[-2][1] == '.')
token(tag, identifier)
@i += identifier.length
end

View File

@@ -300,19 +300,37 @@ module CoffeeScript
end
end
# A range literal. Ranges can be used to extract portions (slices) of arrays,
# or to specify a range for array comprehensions.
class RangeNode
attr_reader :from, :to
def initialize(from, to, exclusive=false)
@from, @to, @exclusive = from, to, exclusive
end
def exclusive?
@exclusive
end
end
# An array slice literal. Unlike JavaScript's Array#slice, the second parameter
# specifies the index of the end of the slice (just like the first parameter)
# is the index of the beginning.
class SliceNode < Node
attr_reader :from, :to
attr_reader :range
def initialize(from, to)
@from, @to = from, to
def initialize(range)
@range = range
end
def compile(o={})
o = super(o)
write(".slice(#{@from.compile(o)}, #{@to.compile(o)} + 1)")
o = super(o)
from = @range.from.compile(o)
to = @range.to.compile(o)
plus_part = @range.exclusive? ? '' : ' + 1'
write(".slice(#{from}, #{to}#{plus_part})")
end
end