Interpreter

デザインパターン入門を読んだ後、思いだしながら
実装してみました。何か違うな。

class Itpr
  def self.eval str
    p = Program.new(Lexer.new(str), CommandExecuter.new)
    p.parse
  end
end

class Parser
  def initialize lexer, exec
    @lexer = lexer
    @executer = exec
  end
end

class Program < Parser
  def parse
    if @lexer.current == "p"
      @lexer.shift
      @cmdlist = CommandList.new(@lexer, @executer)
      @cmdlist.parse
    end
  end
end

class CommandList < Parser
  def parse
    while true
      break if @lexer.current == "e"
      cmd = Command.new(@lexer, @executer)
      cmd.parse
      @cmds ||= []
      @cmds << cmd
      @lexer.shift
    end
  end
end

class Command < Parser
  def parse
    @name = @lexer.current
    @executer.execute(@name)
  end
end

class Lexer
  def initialize text
    @cmd_text = text.split(" ")
  end

  def current
    @cmd_text[0]
  end

  def shift
    @cmd_text.shift
  end
end

class CommandExecuter
  def execute(cmd)
    __send__(cmd)
  end

  def go
    puts "Go!"
  end

  def left
    puts "Left!"
  end

  def right
    puts "Right!"
  end
end

if __FILE__ == $0
Itpr.eval("p go left go e")
end
=>
Go!
Left!
Go!

現在Racc本を読んでます。文字列をごにょごにょするのは
楽しいもんですね。