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()