lib/minjs/ecma262/exp.rb in minjs-0.1.2 vs lib/minjs/ecma262/exp.rb in minjs-0.1.3

- old
+ new

@@ -1,23 +1,22 @@ module Minjs module ECMA262 class Exp < Base - def replace(from, to) - puts "warning: #{self.class}: not implement" - end - def traverse yield(self) - p "??#{self.class}" end def to_js(options = {}) - "??#{@val.to_js(options)}(#{_args})" + raise "internal error" end def reduce(parent) end + + def priority(exp) + 9999 + end end class ExpArg1 < Exp def initialize(val) @val = val @@ -75,14 +74,20 @@ end end # ( exp ) class ExpParen < Exp + attr_reader :val + def initialize(val) @val = val end + def priority(exp) + 0 + end + def replace(from, to) if @val == from @val = to end end @@ -100,75 +105,115 @@ # val = val2 class ExpAssign < ExpArg2 def sym "=" end + def priority(exp) + 130 + end end class ExpDivAssign < ExpAssign def sym "/=" end + def priority(exp) + 130 + end end class ExpMulAssign < ExpAssign def sym "*=" end + def priority(exp) + 130 + end end class ExpModAssign < ExpAssign def sym - "/=" + "%=" end + def priority(exp) + 130 + end end class ExpAddAssign < ExpAssign def sym "+=" end + def priority(exp) + 130 + end end class ExpSubAssign < ExpAssign def sym "-=" end + def priority(exp) + 130 + end end class ExpLShiftAssign < ExpAssign def sym "<<=" end + def priority(exp) + 130 + end end class ExpRShiftAssign < ExpAssign def sym ">>=" end + def priority(exp) + 130 + end end class ExpURShiftAssign < ExpAssign def sym ">>>=" end + def priority(exp) + 130 + end end class ExpAndAssign < ExpAssign def sym "&=" end + def priority(exp) + 130 + end end class ExpOrAssign < ExpAssign def sym "|=" end + def priority(exp) + 130 + end end class ExpXorAssign < ExpAssign def sym "^=" end + def priority(exp) + 130 + end end # a ? b : c class ExpCond < Exp def initialize(val, val2, val3) @val = val @val2 = val2 @val3 = val3 end + def priority(exp) + 120 + end + def replace(from, to) if from == @val @val = to elsif from == @val2 @val2 = to @@ -192,95 +237,137 @@ # || class ExpLogicalOr < ExpArg2 def sym "||" end + def priority(exp) + 118 + end end # && class ExpLogicalAnd < ExpArg2 def sym "&&" end + def priority(exp) + 116 + end end # | class ExpOr < ExpArg2 def sym "|" end + def priority(exp) + 108 + end end # ^ class ExpXor < ExpArg2 def sym "^" end + def priority(exp) + 106 + end end # & class ExpAnd < ExpArg2 def sym "&" end + def priority(exp) + 104 + end end # 11.9 # == class ExpEq < ExpArg2 def sym "==" end + def priority(exp) + 90 + end end # != class ExpNotEq < ExpArg2 def sym "!=" end + def priority(exp) + 90 + end end # === class ExpStrictEq < ExpArg2 def sym "===" end + def priority(exp) + 90 + end end # !== class ExpStrictNotEq < ExpArg2 def sym "!==" end + def priority(exp) + 90 + end end class ExpLt < ExpArg2 def sym "<" end + def priority(exp) + 80 + end end class ExpGt < ExpArg2 def sym ">" end + def priority(exp) + 80 + end end class ExpLtEq < ExpArg2 def sym "<=" end + def priority(exp) + 80 + end end class ExpGtEq < ExpArg2 def sym ">=" end + def priority(exp) + 80 + end end #+ class ExpAdd < ExpArg2 def sym "+" end + def priority(exp) + 60 + end def reduce(parent) # a + 0 => a if @val.kind_of? ECMA262Numeric and @val2.kind_of? ECMA262Numeric and @val.to_num == 0 parent.replace(self, @val2) @@ -289,29 +376,29 @@ if @val.kind_of? ECMA262Numeric and @val2.kind_of? ECMA262Numeric and @val2.to_num == 0 parent.replace(self, @val) end # N + M => (N + M) if @val.kind_of? ECMA262Numeric and @val2.kind_of? ECMA262Numeric and @val.integer? and @val2.integer? - parent.replace(self, ECMA262Numeric.new(nil, @val.to_num + @val2.to_num)) + parent.replace(self, ECMA262Numeric.new(@val.to_num + @val2.to_num)) end if @val2.kind_of? ECMA262Numeric and @val2.integer? # ((a + N) + M) or ((N + a) + M) if @val.kind_of? ExpAdd if @val.val2.kind_of? ECMA262Numeric and @val.val2.integer? - @val2 = ECMA262Numeric.new(nil, @val.val2.to_num + @val2.to_num) + @val2 = ECMA262Numeric.new(@val.val2.to_num + @val2.to_num) @val = @val.val elsif @val.val.kind_of? ECMA262Numeric and @val.val.integer? - @val2 = ECMA262Numeric.new(nil, @val.val.to_num + @val2.to_num) + @val2 = ECMA262Numeric.new(@val.val.to_num + @val2.to_num) @val = @val.val2 end # ((a - N) + M) or ((N - a) + M) elsif @val.kind_of? ExpSub if @val.val2.kind_of? ECMA262Numeric and @val.val2.integer? - @val2 = ECMA262Numeric.new(nil, -(@val.val2.to_num - @val2.to_num)) + @val2 = ECMA262Numeric.new(-(@val.val2.to_num - @val2.to_num)) @val = @val.val elsif @val.val.kind_of? ECMA262Numeric and @val.val.integer? - @val2 = ECMA262Numeric.new(nil, -(@val.val.to_num - @val2.to_num)) + @val2 = ECMA262Numeric.new(-(@val.val.to_num - @val2.to_num)) @val = @val.val2 end end end end @@ -320,10 +407,13 @@ class ExpSub < ExpArg2 def sym "-" end + def priority(exp) + 60 + end def reduce(parent) # a - 0 => a if @val.kind_of? ECMA262Numeric and @val2.kind_of? ECMA262Numeric and @val.to_num == 0 parent.replace(self, @val2) @@ -332,29 +422,29 @@ if @val2.kind_of? ECMA262Numeric and @val.kind_of? ECMA262Numeric and @val2.to_num == 0 parent.replace(self, @val) end # N - M => (N - M) if @val.kind_of? ECMA262Numeric and @val2.kind_of? ECMA262Numeric and @val.integer? and @val2.integer? - parent.replace(self, ECMA262Numeric.new(nil, @val.to_num - @val2.to_num)) + parent.replace(self, ECMA262Numeric.new(@val.to_num - @val2.to_num)) end if @val2.kind_of? ECMA262Numeric and @val2.integer? # ((a - N) - M) or ((N - a) - M) if @val.kind_of? ExpSub if @val.val2.kind_of? ECMA262Numeric and @val.val2.integer? - @val2 = ECMA262Numeric.new(nil, @val.val2.to_num + @val2.to_num) + @val2 = ECMA262Numeric.new(@val.val2.to_num + @val2.to_num) @val = @val.val elsif @val.val.kind_of? ECMA262Numeric and @val.val.integer? - @val2 = ECMA262Numeric.new(nil, @val.val.to_num + @val2.to_num) + @val2 = ECMA262Numeric.new(@val.val.to_num + @val2.to_num) @val = @val.val2 end # ((a + N) - M) or ((N + a) - M) elsif @val.kind_of? ExpAdd if @val.val2.kind_of? ECMA262Numeric and @val.val2.integer? - @val2 = ECMA262Numeric.new(nil, -(@val.val2.to_num - @val2.to_num)) + @val2 = ECMA262Numeric.new(-(@val.val2.to_num - @val2.to_num)) @val = @val.val elsif @val.val.kind_of? ECMA262Numeric and @val.val.integer? - @val2 = ECMA262Numeric.new(nil, -(@val.val.to_num - @val2.to_num)) + @val2 = ECMA262Numeric.new(-(@val.val.to_num - @val2.to_num)) @val = @val.val2 end end end end @@ -363,38 +453,56 @@ class ExpInstanceOf < ExpArg2 def sym "instanceof" end + def priority(exp) + 80 + end end class ExpIn < ExpArg2 def sym "in" end + def priority(exp) + 80 + end end class ExpLShift < ExpArg2 def sym "<<" end + def priority(exp) + 70 + end end class ExpRShift < ExpArg2 def sym ">>" end + def priority(exp) + 70 + end end class ExpURShift < ExpArg2 def sym ">>>" end + def priority(exp) + 70 + end end class ExpMul < ExpArg2 def sym "*" end + def priority(exp) + 50 + end def reduce(parent) # a * 1 => a if @val.kind_of? ECMA262Numeric and @val2.kind_of? ECMA262Numeric and @val.to_num == 1 parent.replace(self, @val2) @@ -403,83 +511,113 @@ if @val.kind_of? ECMA262Numeric and @val2.kind_of? ECMA262Numeric and @val2.to_num == 1 parent.replace(self, @val) end # N * M => (N * M) if @val.kind_of? ECMA262Numeric and @val2.kind_of? ECMA262Numeric and @val.integer? and @val2.integer? - parent.replace(self, ECMA262Numeric.new(nil, @val.to_num * @val2.to_num)) + parent.replace(self, ECMA262Numeric.new(@val.to_num * @val2.to_num)) end # ((a * N) * M) or ((N * a) * M) if @val2.kind_of? ECMA262Numeric and @val2.integer? and @val.kind_of? ExpMul if @val.val2.kind_of? ECMA262Numeric and @val.val2.integer? - @val2 = ECMA262Numeric.new(nil, @val.val2.to_num * @val2.to_num) + @val2 = ECMA262Numeric.new(@val.val2.to_num * @val2.to_num) @val = @val.val elsif @val.val.kind_of? ECMA262Numeric and @val.val.integer? - @val2 = ECMA262Numeric.new(nil, @val.val.to_num * @val2.to_num) + @val2 = ECMA262Numeric.new(@val.val.to_num * @val2.to_num) @val = @val.val2 end end end end class ExpDiv < ExpArg2 def sym "/" end + def priority(exp) + 50 + end end class ExpMod < ExpArg2 def sym "%" end + def priority(exp) + 50 + end end # # 11.4 # unary expression # class ExpDelete < ExpArg1 def sym "delete" end + def priority(exp) + 40 + end end class ExpVoid < ExpArg1 def sym "void" end + def priority(exp) + 40 + end end class ExpTypeof < ExpArg1 def sym "typeof" end + def priority(exp) + 40 + end end class ExpPostInc < ExpArg1 def sym "++" end + def priority(exp) + 30 + end def to_js(options = {}) concat options, @val, sym end end class ExpPostDec < ExpArg1 def sym "--" end + def priority(exp) + 30 + end def to_js(options = {}) concat options, @val, sym end end class ExpPreInc < ExpArg1 def sym "++" end + def priority(exp) + 40 + end end class ExpPreDec < ExpArg1 def sym "--" end + def priority(exp) + 40 + end end class ExpPositive < ExpArg1 def sym "+" end + def priority(exp) + 40 + end def reduce(parent) if @val.kind_of? ECMA262Numeric parent.replace(self, @val) end @@ -488,40 +626,53 @@ class ExpNegative < ExpArg1 def sym "-" end + def priority(exp) + 40 + end def reduce(parent) if @val.kind_of? ECMA262Numeric if @val.integer.match(/^\-/) integer = $' else integer = "-#{@val.integer}" end - val = ECMA262Numeric.new(integer, integer, @val.decimal, @val.exp) + val = ECMA262Numeric.new(integer, @val.decimal, @val.exp) parent.replace(self, val) end end end class ExpBitwiseNot < ExpArg1 def sym "~" end + def priority(exp) + 40 + end end class ExpLogicalNot < ExpArg1 def sym "!" end + def priority(exp) + 40 + end end class ExpNew < Exp def initialize(name, args) @name = name @args = args end + def priority(exp) + 20 + end + def replace(from, to) if @name == from @name = from elsif @args and (idx = @args.index(from)) @args[idx] = to @@ -557,10 +708,18 @@ def initialize(name, args) @name = name @args = args end + def priority(exp) + if @args.index(exp) + 999 + else + 20 + end + end + def replace(from, to) @args.each_index do |i| arg = @args[i] if arg == from @args[i] = to @@ -583,19 +742,24 @@ end end # # => val.val2 # - class ExpProp < Exp + class ExpProp < ExpArg2 def initialize(val, val2) @val = val if val2.kind_of? IdentifierName @val2 = ECMA262::ECMA262String.new(val2.val) else - raise "val2 must be kind_of ItentiferName" + raise "internal error: val2 must be kind_of ItentiferName" end end + + def priority(exp) + 20 + end + def traverse(parent, &block) @val.traverse(self, &block) @val2.traverse(self, &block) yield self, parent end @@ -604,15 +768,15 @@ end end # # => val[val2] # - class ExpPropBrac < Exp - def initialize(val, val2) - @val = val - @val2 = val2 + class ExpPropBrac < ExpArg2 + def priority(exp) + 20 end + def traverse(parent, &block) @val.traverse(self, &block) @val2.traverse(self, &block) yield self, parent end @@ -622,9 +786,12 @@ end class ExpComma < ExpArg2 def sym "," + end + def priority(exp) + 140 end end end end