Skip to content

Instantly share code, notes, and snippets.

@kmizu
Created July 12, 2017 16:28
Show Gist options
  • Save kmizu/d4d1a4e8d6c71d7fd65a99961eb76806 to your computer and use it in GitHub Desktop.
Save kmizu/d4d1a4e8d6c71d7fd65a99961eb76806 to your computer and use it in GitHub Desktop.
インタプリタの挙動を示すための例
class Expression:
def __add__(self, that):
return BinaryOp('+', self, that)
def __sub__(self, that):
return BinaryOp('-', self, that)
def __mul__(self, that):
return BinaryOp('*', self, that)
def __div__(self, that):
self.__truediv__(that)
def __truediv__(self, that):
return BinaryOp('/', self, that)
class BinaryOp(Expression):
def __init__(self, op, lhs, rhs):
self.op = op
self.lhs = lhs
self.rhs = rhs
class Value(Expression):
def __init__(self, value):
self.value = value
class Ref(Expression):
def __init__(self, var):
self.var = var
class Set(Expression):
def __init__(self, var, value):
self.var = var
self.value = value
class Block(Expression):
def __init__(self, args):
self.args = args
def v(value):
return Value(value)
def set(var, value):
return Set(var, value)
def ref(var):
return Ref(var)
def block(args):
return Block(args)
def eval(e):
environment = {}
def evalMain(e):
if isinstance(e, Value):
return e.value
elif isinstance(e, Ref):
return environment[e.var]
elif isinstance(e, Set):
environment[e.var] = evalMain(e.value)
return environment[e.var]
elif isinstance(e, BinaryOp):
if e.op == '+':
return evalMain(e.lhs) + evalMain(e.rhs)
elif e.op == '-':
return evalMain(e.lhs) - evalMain(e.rhs)
elif e.op == '*':
return evalMain(e.lhs) * evalMain(e.rhs)
else:
return evalMain(e.lhs) // evalMain(e.rhs)
else:
last = None
for arg in e.args:
last = evalMain(arg)
return last
return evalMain(e)
program = block([
set('a', (v(1) + v(2)) * v(3) / v(4)), # a = (1 + 2) * 3 / 4
set('b', ref('a') * ref('a'))
])
print(eval(program))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment