orelangをPythonで実装してみた
http://qiita.com/shuetsu@github/items/ac21e597265d6bb906dc
いろんな人がいろんな言語で実装してた。 Python版が載ってなかったので参戦。
一応、引き算にも対応した。
class Engine: def __init__(self): self.operators = {} self.variables = {} self.operators["+"] = AddOperator() self.operators["-"] = SubOperator() self.operators["*"] = MultiplyOperator() self.operators["="] = EqualOperator() self.operators["set"] = SetOperator() self.operators["get"] = GetOperator() self.operators["until"] = UntilOperator() self.operators["step"] = StepOperator() def eval(self, script): return self._get_expression(script).eval(self) def _get_expression(self, script): if isinstance(script, list): script_list = script return CallOperator(self.operators[script_list[0]], script_list[1:]) else: return ImmediateValue(script) class CallOperator: def __init__(self, operator, args): self.operator = operator self.args = args def eval(self, engine): return self.operator.call(engine, self.args) class ImmediateValue: def __init__(self, value): self.value = value def eval(self, engine): return self.value class SubOperator: def call(self, engine, args): retval = engine.eval(args[0]) for arg in args[1:]: v = engine.eval(arg) retval -= v return retval class AddOperator: def call(self, engine, args): retval = 0 for arg in args: v = engine.eval(arg) retval += v return retval class MultiplyOperator: def call(self, engine, args): retval = 1 for arg in args: v = engine.eval(arg) retval *= v return retval class EqualOperator: def call(self, engine, args): return engine.eval(args[0]) == engine.eval(args[1]) class SetOperator: def call(self, engine, args): value = engine.eval(args[1]) engine.variables[str(engine.eval(args[0]))] = value return value class GetOperator: def call(self, engine, args): return engine.variables[engine.eval(args[0])] class UntilOperator: def call(self, engine, args): retval = None while not engine.eval(args[0]): retval = engine.eval(args[1]) return retval class StepOperator: def call(self, engine, args): retval = None for arg in args: retval = engine.eval(arg) return retval
言語を作るのは、どうやるのか想像がしにくかったので面白かった