diff --git a/examples/code.cs b/examples/code.cs index 4504aba9..a06dbb7e 100644 --- a/examples/code.cs +++ b/examples/code.cs @@ -109,9 +109,9 @@ change_a_and_set_b: => b: 20 # Array comprehensions. -supper: [food.capitalize() for food in ['toast', 'cheese', 'wine']] +supper: food.capitalize() for food in ['toast', 'cheese', 'wine']. -[drink(bottle) for bottle, i in ['soda', 'wine', 'lemonade'] if even(i)] +drink(bottle) for bottle, i in ['soda', 'wine', 'lemonade'] if even(i). # Switch statements ("else" serves as a default). switch day diff --git a/lib/coffee_script/grammar.y b/lib/coffee_script/grammar.y index d2999541..b7cdfc21 100644 --- a/lib/coffee_script/grammar.y +++ b/lib/coffee_script/grammar.y @@ -23,12 +23,13 @@ prechigh left '<=' '<' '>' '>=' right '==' '!=' IS AINT left '&&' '||' AND OR - left ':' right '-=' '+=' '/=' '*=' '||=' '&&=' right DELETE - right RETURN THROW FOR IN WHILE + left "." + right THROW FOR IN WHILE left UNLESS IF ELSE - nonassoc "." + left ":" + right RETURN preclow # We expect 4 shift/reduce errors for optional syntax. @@ -340,8 +341,8 @@ rule If: IF Expression Then Expressions IfEnd { result = IfNode.new(val[1], val[3], val[4]) } - | Expression IF Expression { result = IfNode.new(val[2], Expressions.new([val[0]])) } - | Expression UNLESS Expression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, :invert) } + | Expression IF Expression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true}) } + | Expression UNLESS Expression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true, :invert => true}) } ; end diff --git a/lib/coffee_script/nodes.rb b/lib/coffee_script/nodes.rb index 66c8f1d3..026d810f 100644 --- a/lib/coffee_script/nodes.rb +++ b/lib/coffee_script/nodes.rb @@ -112,6 +112,10 @@ module CoffeeScript @expression = expression end + def line_ending + @expression.custom_return? ? '' : ';' + end + def compile(indent, scope, opts={}) return @expression.compile(indent, scope, opts.merge(:return => true)) if @expression.custom_return? compiled = @expression.compile(indent, scope) @@ -407,12 +411,12 @@ module CoffeeScript set_result = "var #{rvar} = [];\n#{indent}" save_result += "#{rvar}[#{ivar}] = " return_result = rvar - return_result = "#{opts[:assign]} = #{return_result}" if opts[:assign] - return_result = "return #{return_result}" if opts[:return] + return_result = "#{opts[:assign]} = #{return_result};" if opts[:assign] + return_result = "return #{return_result};" if opts[:return] return_result = "\n#{indent}#{return_result}" if @filter body = CallNode.new(ValueNode.new(LiteralNode.new(rvar), [AccessorNode.new('push')]), [@body]) - body = @filter ? IfNode.new(@filter, body, nil, :statement) : body + body = IfNode.new(@filter, body, nil, :statement) save_result = '' suffix = '' end @@ -495,12 +499,12 @@ module CoffeeScript class IfNode < Node attr_reader :condition, :body, :else_body - def initialize(condition, body, else_body=nil, tag=nil) + def initialize(condition, body, else_body=nil, tags={}) @condition = condition @body = body && body.unwrap @else_body = else_body && else_body.unwrap - @tag = tag - @condition = OpNode.new("!", @condition) if @tag == :invert + @tags = tags + @condition = OpNode.new("!", @condition) if @tags[:invert] end def <<(else_body) @@ -530,7 +534,7 @@ module CoffeeScript # The IfNode only compiles into a statement if either of the bodies needs # to be a statement. def statement? - @is_statement ||= ((@tag == :statement) || @body.statement? || (@else_body && @else_body.statement?)) + @is_statement ||= !!(@tags[:statement] || @body.statement? || (@else_body && @else_body.statement?)) end def custom_return?