class PowNode < ContainerNode include BinaryNode def initialize(lhs, rhs) @lhs, @rhs = lhs, rhs raise TypeError unless NumberNode === @rhs end def to_s lhs = @lhs.to_s case lhs when /\d$/, /[\d\.]/ lhs = "(#{lhs})" end rhs = @rhs.to_s if rhs == '1' lhs else rhs = "^(#{rhs})" if (/\./ =~ rhs) lhs + rhs end end attr_reader :lhs, :rhs alias :power :rhs def pow_eval(other) case other when NumberNode PowNode.new(@lhs, @rhs.mul_eval(other)) else super(other) end end def flatten2 x = @lhs.flatten2 case x when NumberNode a = @lhs.pow_eval(@rhs) when TerminalNode a = self when PowNode a = PowNode.new(x.lhs, x.rhs.mul_eval(@rhs)) when MulNode, MultiNode a = MultiNode.new() for gc in x a.append(gc.pow_eval(@rhs)) end else raise "internal error" end return a end def name case @lhs when NumberNode, NameNode @lhs.name else raise "internal error" end end def value case @lhs when NumberNode Units::pow_f(@lhs.value, @rhs.value) else raise(format('%s#value: internal error', self.class.to_s)) end end def mul_eval(another) raise "internal error (#{name}, #{another.name})" if name != another.name case @lhs when NumberNode NumberNode.new(Units::pow_f(@lhs.value, @rhs.value) * another.value) else self.class.new(@lhs, @rhs.add_eval(another.power)) end end def sort case @lhs when NumberNode NumberNode.new(Units::pow_f(@lhs.value, @rhs.value)) else self end end def factor Units::pow_f(@lhs.factor, @rhs.value) end end