Mikrointerpretaator
Allikas: Lambda
# a trivial treewalk interpreter in python by Tanel Tammet
def main():
example=["+",2,["*",4,5]]
print("evaluating ",str(example)," gives ")
print(evaluate({},example))
example=[["=","x",1],
["if",["==","x",["-",2,1]],
10,
20]]
print("evaluating ",str(example)," gives ")
print(evaluate({},example))
example=[["=","x",1],["print", ["+","x",2]]]
print("evaluating ",str(example)," gives ")
print(evaluate({},example))
example=[["=","x",0],
["=","y",1],
["while", ["not",["==","y",10]],
["=","x",["+","x","y"]],
["=","y",["+","y",1]] ],
["print", "x"] ]
print("evaluating ",str(example)," gives ")
print(evaluate({},example))
def evaluate(vars,term):
if type(term)==int or type(term)==float:
return term
elif type(term)==str:
if term in vars:
return vars[term]
else:
return 0
elif type(term)==list:
op=term[0]
# arithmetic
if op=="+":
return evaluate(vars,term[1])+evaluate(vars,term[2])
elif op=="*":
return evaluate(vars,term[1])*evaluate(vars,term[2])
elif op=="-":
return evaluate(vars,term[1])-evaluate(vars,term[2])
elif op=="/":
return evaluate(vars,term[1])/evaluate(vars,term[2])
# side effects: print and assignment
elif op=="print":
tmp=evaluate(vars,term[1])
print(tmp)
return tmp
elif op=="=":
tmp=evaluate(vars,term[2])
vars[term[1]]=tmp
return tmp
# control
elif op=="==":
if evaluate(vars,term[1])==evaluate(vars,term[2]):
return 1
else:
return 0
elif op=="not":
if evaluate(vars,term[1])==0:
return 1
else:
return 0
elif op=="if":
if evaluate(vars,term[1]):
return evaluate(vars,term[2])
else:
return evaluate(vars,term[3])
elif op=="while":
tmp=0
while evaluate(vars,term[1])!=0:
tmp=evaluate(vars,term[2:])
return tmp
# sequence of commands
elif type(op)==list:
l=len(term)
i=0
while i<l:
tmp=evaluate(vars,term[i])
if i==l-1:
return tmp
i=i+1
else:
print("error: unknown operator ",str(op))
return 0
else:
print("error: unknown argument type of ",str(term))
return 0
main()