comparison interps/lambda/evaluator.py @ 996:859f9b4339e6

<Gregor> tar xf egobot.tar.xz
author HackBot
date Sun, 09 Dec 2012 19:30:08 +0000
parents
children
comparison
equal deleted inserted replaced
995:6883f5911eb7 996:859f9b4339e6
1 from parser import *
2
3 class EvaluatorException(Exception):
4 pass
5
6 def eval(exp, env):
7 # symbols are names to be left unevaluated.
8 if isinstance(exp, NameExp):
9 raise EvaluatorException("unbound variable: " + exp.body)
10 if isinstance(exp, LambdaExp):
11 # no change
12 return exp
13 if isinstance(exp, ApplyExp):
14 # We're lazy, so we apply before evaluating the argument.
15 # We do of course need to evaluate the function.
16 rator = eval(exp.rator, env)
17 rand = exp.rand
18 return apply(rator, rand, env)
19 if isinstance(exp, StringExp):
20 import sys
21 sys.stdout.write(exp.line)
22 return LambdaExp('x', NameExp('x')) # i.e. the identity function
23 if isinstance(exp, SpecialExp):
24 if exp.body == '#list':
25 # list all definitions in the environment
26 import sys
27 defs = env.keys()
28 defs.sort()
29 sys.stdout.write('[' + ' '.join(defs) + ']')
30 return exp
31 raise EvaluatorException("Unknown expression type for evaluation")
32
33 def substitute(exp, name, value):
34 if isinstance(exp, StringExp):
35 return exp
36 if isinstance(exp, NameExp):
37 if exp.body == name:
38 return value
39 return exp
40 if isinstance(exp, ApplyExp):
41 return ApplyExp(substitute(exp.rator, name, value), substitute(exp.rand, name, value))
42 if isinstance(exp, SpecialExp):
43 return exp
44 if isinstance(exp, LambdaExp):
45 # lambda can shadow the name
46 if name == exp.arg:
47 return exp
48 return LambdaExp(exp.arg, substitute(exp.body, name, value))
49 print exp
50 raise EvaluatorException("Unknown expression type for substitution")
51
52 def apply(rator, rand, env):
53 # since we're lazy, rand is unevaluated, so it might be anything
54 # Rator, on the other hand ought to be a lambda or a special word
55 if isinstance(rator, LambdaExp):
56 # okay, now we actually have to do stuff
57 # first we substitute all instances of the first named parameter
58 # of the lambda with the rand.
59 body = substitute(rator.body, rator.arg, rand)
60 return eval(body, env)
61 if isinstance(rator, SpecialExp):
62 if rator.body == '#show':
63 # first evaluates the operand, then shows it, returns the result of the evaluation
64 import sys
65 rand = eval(rand, env)
66 sys.stdout.write(str(rand))
67 return rand
68 else:
69 raise EvaluatorException("Unknown special word: " + rator.body)
70 raise EvaluatorException("Trying to apply something that isn't a lambda")