Created
July 12, 2017 16:28
-
-
Save kmizu/d4d1a4e8d6c71d7fd65a99961eb76806 to your computer and use it in GitHub Desktop.
インタプリタの挙動を示すための例
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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