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
syntax highlighted by Code2HTML, v. 0.9.1