diff --git a/lib/coffee_script/grammar.y b/lib/coffee_script/grammar.y index 766b90bd..d01c38d4 100644 --- a/lib/coffee_script/grammar.y +++ b/lib/coffee_script/grammar.y @@ -169,10 +169,10 @@ rule # Expressions that can be treated as values. Value: - IDENTIFIER { result = ValueNode.new(val) } - | Array { result = ValueNode.new(val) } - | Object { result = ValueNode.new(val) } - | Parenthetical { result = ValueNode.new(val) } + IDENTIFIER { result = ValueNode.new(val[0]) } + | Array { result = ValueNode.new(val[0]) } + | Object { result = ValueNode.new(val[0]) } + | Parenthetical { result = ValueNode.new(val[0]) } | Value Accessor { result = val[0] << val[1] } | Invocation Accessor { result = ValueNode.new(val[0], [val[1]]) } ; diff --git a/lib/coffee_script/lexer.rb b/lib/coffee_script/lexer.rb index f90d1bd5..7c351fbe 100644 --- a/lib/coffee_script/lexer.rb +++ b/lib/coffee_script/lexer.rb @@ -157,8 +157,9 @@ module CoffeeScript index = 0 loop do tok = @tokens[index -= 1] - return if !tok || tok[0] != :IDENTIFIER + return if !tok next if tok[0] == ',' + return if tok[0] != :IDENTIFIER tok[0] = :PARAM end end diff --git a/lib/coffee_script/nodes.rb b/lib/coffee_script/nodes.rb index af38b332..50df8f0c 100644 --- a/lib/coffee_script/nodes.rb +++ b/lib/coffee_script/nodes.rb @@ -148,7 +148,7 @@ module CoffeeScript # A value, indexed or dotted into or vanilla. class ValueNode < Node - attr_reader :last + attr_reader :name, :properties, :last def initialize(name, properties=[]) @name, @properties = name, properties @@ -212,6 +212,8 @@ module CoffeeScript statement custom_return + attr_reader :variable, :value, :context + def initialize(variable, value, context=nil) @variable, @value, @context = variable, value, context end diff --git a/test/fixtures/each.tokens b/test/fixtures/each.tokens index 079be192..bbaa3432 100644 --- a/test/fixtures/each.tokens +++ b/test/fixtures/each.tokens @@ -1 +1 @@ -[["\n", "\n"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "each"], [":", ":"], [:IDENTIFIER, "obj"], [",", ","], [:IDENTIFIER, "iterator"], [",", ","], [:PARAM, "context"], ["=>", "=>"], ["\n", "\n"], [:IDENTIFIER, "index"], [":", ":"], [:NUMBER, "0"], ["\n", "\n"], [:TRY, "try"], ["\n", "\n"], [:RETURN, "return"], [:IDENTIFIER, "obj"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "forEach"], ["(", "("], [:IDENTIFIER, "iterator"], [",", ","], [:IDENTIFIER, "context"], [")", ")"], [:IF, "if"], [:IDENTIFIER, "obj"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "forEach"], ["\n", "\n"], [:RETURN, "return"], [:IDENTIFIER, "iterator"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "call"], ["(", "("], [:IDENTIFIER, "context"], [",", ","], [:IDENTIFIER, "item"], [",", ","], [:IDENTIFIER, "i"], [",", ","], [:IDENTIFIER, "obj"], [")", ")"], [:FOR, "for"], [:IDENTIFIER, "item"], [",", ","], [:IDENTIFIER, "i"], [:IN, "in"], [:IDENTIFIER, "obj"], [".", "."], [:IF, "if"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "isArray"], ["(", "("], [:IDENTIFIER, "obj"], [")", ")"], [:OR, "or"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "isArguments"], ["(", "("], [:IDENTIFIER, "obj"], [")", ")"], ["\n", "\n"], [:IDENTIFIER, "iterator"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "call"], ["(", "("], [:IDENTIFIER, "context"], [",", ","], [:IDENTIFIER, "obj"], ["[", "["], [:IDENTIFIER, "key"], ["]", "]"], [",", ","], [:IDENTIFIER, "key"], [",", ","], [:IDENTIFIER, "obj"], [")", ")"], [:FOR, "for"], [:IDENTIFIER, "key"], [:IN, "in"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "keys"], ["(", "("], [:IDENTIFIER, "obj"], [")", ")"], [".", "."], ["\n", "\n"], [:CATCH, "catch"], [:IDENTIFIER, "e"], ["\n", "\n"], [:THROW, "throw"], [:IDENTIFIER, "e"], [:IF, "if"], [:IDENTIFIER, "e"], [:AINT, "aint"], [:IDENTIFIER, "breaker"], [".", "."], ["\n", "\n"], [:IDENTIFIER, "obj"], [".", "."]] \ No newline at end of file +[["\n", "\n"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "each"], [":", ":"], [:PARAM, "obj"], [",", ","], [:PARAM, "iterator"], [",", ","], [:PARAM, "context"], ["=>", "=>"], ["\n", "\n"], [:IDENTIFIER, "index"], [":", ":"], [:NUMBER, "0"], ["\n", "\n"], [:TRY, "try"], ["\n", "\n"], [:RETURN, "return"], [:IDENTIFIER, "obj"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "forEach"], ["(", "("], [:IDENTIFIER, "iterator"], [",", ","], [:IDENTIFIER, "context"], [")", ")"], [:IF, "if"], [:IDENTIFIER, "obj"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "forEach"], ["\n", "\n"], [:RETURN, "return"], [:IDENTIFIER, "iterator"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "call"], ["(", "("], [:IDENTIFIER, "context"], [",", ","], [:IDENTIFIER, "item"], [",", ","], [:IDENTIFIER, "i"], [",", ","], [:IDENTIFIER, "obj"], [")", ")"], [:FOR, "for"], [:IDENTIFIER, "item"], [",", ","], [:IDENTIFIER, "i"], [:IN, "in"], [:IDENTIFIER, "obj"], [".", "."], [:IF, "if"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "isArray"], ["(", "("], [:IDENTIFIER, "obj"], [")", ")"], [:OR, "or"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "isArguments"], ["(", "("], [:IDENTIFIER, "obj"], [")", ")"], ["\n", "\n"], [:IDENTIFIER, "iterator"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "call"], ["(", "("], [:IDENTIFIER, "context"], [",", ","], [:IDENTIFIER, "obj"], ["[", "["], [:IDENTIFIER, "key"], ["]", "]"], [",", ","], [:IDENTIFIER, "key"], [",", ","], [:IDENTIFIER, "obj"], [")", ")"], [:FOR, "for"], [:IDENTIFIER, "key"], [:IN, "in"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "keys"], ["(", "("], [:IDENTIFIER, "obj"], [")", ")"], [".", "."], ["\n", "\n"], [:CATCH, "catch"], [:IDENTIFIER, "e"], ["\n", "\n"], [:THROW, "throw"], [:IDENTIFIER, "e"], [:IF, "if"], [:IDENTIFIER, "e"], [:AINT, "aint"], [:IDENTIFIER, "breaker"], [".", "."], ["\n", "\n"], [:IDENTIFIER, "obj"], [".", "."]] \ No newline at end of file diff --git a/test/unit/test_lexer.rb b/test/unit/test_lexer.rb index d989a324..8c29b896 100644 --- a/test/unit/test_lexer.rb +++ b/test/unit/test_lexer.rb @@ -24,9 +24,9 @@ class LexerTest < Test::Unit::TestCase end def test_lexing_function_definition - code = "x => x * x." - assert @lex.tokenize(code) == [[:PARAM, "x"], ["=>", "=>"], - [:IDENTIFIER, "x"], ["*", "*"], [:IDENTIFIER, "x"], [".", "."]] + code = "x, y => x * y." + assert @lex.tokenize(code) == [[:PARAM, "x"], [",", ","], [:PARAM, "y"], + ["=>", "=>"], [:IDENTIFIER, "x"], ["*", "*"], [:IDENTIFIER, "y"], [".", "."]] end def test_lexing_if_statement diff --git a/test/unit/test_parser.rb b/test/unit/test_parser.rb index 2c9c8ba7..e74c6d56 100644 --- a/test/unit/test_parser.rb +++ b/test/unit/test_parser.rb @@ -7,15 +7,18 @@ class ParserTest < Test::Unit::TestCase end def test_parsing_an_empty_string - puts @par.parse("").inspect + nodes = @par.parse("") + assert nodes.is_a? Expressions + assert nodes.expressions.empty? end - # def test_lexing_basic_assignment - # code = "a: 'one'; b: [1, 2]" - # assert @lex.tokenize(code) == [[:IDENTIFIER, "a"], [":", ":"], - # [:STRING, "'one'"], [";", ";"], [:IDENTIFIER, "b"], [":", ":"], - # ["[", "["], [:NUMBER, "1"], [",", ","], [:NUMBER, "2"], ["]", "]"]] - # end + def test_parsing_a_basic_assignment + nodes = @par.parse("a: 'one'") + assert nodes.expressions.length == 1 + assign = nodes.expressions.first + assert assign.is_a? AssignNode + assert assign.variable.name == 'a' + end # # def test_lexing_object_literal # code = "{one : 1}"