Evaluate an expression in an environment.
(x, env=global_env)
| 179 | ################ eval (tail recursive) |
| 180 | |
| 181 | def eval(x, env=global_env): |
| 182 | "Evaluate an expression in an environment." |
| 183 | while True: |
| 184 | if isa(x, Symbol): # variable reference |
| 185 | return env.find(x)[x] |
| 186 | elif not isa(x, list): # constant literal |
| 187 | return x |
| 188 | elif x[0] is _quote: # (quote exp) |
| 189 | (_, exp) = x |
| 190 | return exp |
| 191 | elif x[0] is _if: # (if test conseq alt) |
| 192 | (_, test, conseq, alt) = x |
| 193 | x = (conseq if eval(test, env) else alt) |
| 194 | elif x[0] is _set: # (set! var exp) |
| 195 | (_, var, exp) = x |
| 196 | env.find(var)[var] = eval(exp, env) |
| 197 | return None |
| 198 | elif x[0] is _define: # (define var exp) |
| 199 | (_, var, exp) = x |
| 200 | env[var] = eval(exp, env) |
| 201 | return None |
| 202 | elif x[0] is _lambda: # (lambda (var*) exp) |
| 203 | (_, vars, exp) = x |
| 204 | return Procedure(vars, exp, env) |
| 205 | elif x[0] is _begin: # (begin exp+) |
| 206 | for exp in x[1:-1]: |
| 207 | eval(exp, env) |
| 208 | x = x[-1] |
| 209 | else: # (proc exp*) |
| 210 | exps = [eval(exp, env) for exp in x] |
| 211 | proc = exps.pop(0) |
| 212 | if isa(proc, Procedure): |
| 213 | x = proc.exp |
| 214 | env = Env(proc.parms, exps, proc.env) |
| 215 | else: |
| 216 | return proc(*exps) |
| 217 | |
| 218 | ################ expand |
| 219 |