class NameNode < TerminalNode def initialize(string) @a = string end def to_s; @a; end alias :name :to_s def power; NumberNode::UNITY; end def mul_eval(another) raise "internal error (#{name}, #{another.name})" if name != another.name PowNode.new(self, self.power.add_eval(another.power)) end def expand(stopper) raise "circular dependency for #{@a}" if stopper[@a] return self if basic? return CACHE[@a] if CACHE.include?(@a) CACHE[@a] = expand2(stopper) end def expand2(stopper) newstopper = stopper.dup newstopper[@a] = true if UDEFS.include?(@a) then Units.new(UDEFS[@a]).ptree.expand(newstopper) else p, n = UALIASES[@a] u = Units.new(UDEFS[n] || n).ptree.expand(newstopper) MulNode.new(u, PowNode.new(NumberNode.new(10), NumberNode.new(p))) end end def unalias(stopper) raise "circular dependency for #{@a}" if stopper[@a] return self unless UALIASES.include?(@a) p, n = UALIASES[@a] u = NameNode.new(n) q = PowNode.new(NumberNode.new(10), NumberNode.new(p)) MulNode.new(u, q) end def foldnumber(stopper) return self unless UPLURALS.include?(@a) n = UPLURALS[@a] NameNode.new(n) end def basic? not (UDEFS.include?(@a) or UALIASES.include?(@a)) end CACHE = {} def factor 1 end end