diff --git a/lib/coffee_script/grammar.y b/lib/coffee_script/grammar.y index d9ea226c..6261125f 100644 --- a/lib/coffee_script/grammar.y +++ b/lib/coffee_script/grammar.y @@ -18,7 +18,7 @@ token JS # Declare order of operations. prechigh - nonassoc UMINUS NOT '!' '!!' '~' + nonassoc UMINUS NOT '!' '!!' '~' '++' '--' left '*' '/' '%' left '+' '-' left '<<' '>>' '>>>' @@ -142,6 +142,10 @@ rule | '-' Expression = UMINUS { result = OpNode.new(val[0], val[1]) } | NOT Expression { result = OpNode.new(val[0], val[1]) } | '~' Expression { result = OpNode.new(val[0], val[1]) } + | '--' Expression { result = OpNode.new(val[0], val[1]) } + | '++' Expression { result = OpNode.new(val[0], val[1]) } + | Expression '--' { result = OpNode.new(val[1], val[0], nil, true) } + | Expression '++' { result = OpNode.new(val[1], val[0], nil, true) } | Expression '*' Expression { result = OpNode.new(val[1], val[0], val[2]) } | Expression '/' Expression { result = OpNode.new(val[1], val[0], val[2]) } diff --git a/lib/coffee_script/nodes.rb b/lib/coffee_script/nodes.rb index 07603d38..38d3e57e 100644 --- a/lib/coffee_script/nodes.rb +++ b/lib/coffee_script/nodes.rb @@ -318,11 +318,11 @@ module CoffeeScript name = @variable.respond_to?(:compile) ? @variable.compile(o) : @variable last = @variable.respond_to?(:last) ? @variable.last.to_s : name.to_s o = o.merge(:assign => name, :last_assign => last) + postfix = o[:return] ? ";\n#{o[:indent]}return #{name}" : '' return write("#{@variable}: #{@value.compile(o)}") if @context == :object - return write("#{name} = #{@value.compile(o)}") if @variable.properties? + return write("#{name} = #{@value.compile(o)}#{postfix}") if @variable.properties? && !@value.custom_assign? defined = o[:scope].find(name) - postfix = !defined && o[:return] ? ";\n#{o[:indent]}return #{name}" : '' - def_part = defined ? "" : "var #{name};\n#{o[:indent]}" + def_part = defined || @variable.properties? ? "" : "var #{name};\n#{o[:indent]}" return write(def_part + @value.compile(o)) if @value.custom_assign? def_part = defined ? name : "var #{name}" val_part = @value.compile(o).sub(LEADING_VAR, '') @@ -346,8 +346,8 @@ module CoffeeScript attr_reader :operator, :first, :second - def initialize(operator, first, second=nil) - @first, @second = first, second + def initialize(operator, first, second=nil, flip=false) + @first, @second, @flip = first, second, flip @operator = CONVERSIONS[operator] || operator end @@ -369,8 +369,10 @@ module CoffeeScript end def compile_unary(o) - space = @operator == 'delete' ? ' ' : '' - "#{@operator}#{space}#{@first.compile(o)}" + space = @operator.to_s == 'delete' ? ' ' : '' + parts = [@operator.to_s, space, @first.compile(o)] + parts.reverse! if @flip + parts.join('') end end diff --git a/test/fixtures/execution/test_everything.cs b/test/fixtures/execution/test_everything.cs new file mode 100644 index 00000000..62a43a85 --- /dev/null +++ b/test/fixtures/execution/test_everything.cs @@ -0,0 +1,23 @@ +func: => + a: 3 + b: [] + while a >= 0 + b.push('o') + a--. + + c: { + text: b + } + + c: 'error' unless 42 > 41 + + c.text: if false + 'error' + else + c.text + '---'. + + c.list: let for let in c.text.split('') if let is '-'. + + c.single: c.list[1, 1][0]. + +print(func() == '-') diff --git a/test/fixtures/execution/test_everything.js b/test/fixtures/execution/test_everything.js new file mode 100644 index 00000000..59cee64e --- /dev/null +++ b/test/fixtures/execution/test_everything.js @@ -0,0 +1,29 @@ +(function(){ + var func = function() { + var a = 3; + var b = []; + while (a >= 0) { + b.push('o'); + a--; + } + var c = { + text: b + }; + if (!(42 > 41)) { + c = 'error'; + } + c.text = false ? 'error' : c.text + '---'; + var d = c.text.split(''); + var g = []; + for (var e=0, f=d.length; e