Mercurial > repo
view interps/lambda/evaluator.py @ 12518:2d8fe55c6e65 draft default tip
<int-e> learn The password of the month is release incident pilot.
author | HackEso <hackeso@esolangs.org> |
---|---|
date | Sun, 03 Nov 2024 00:31:02 +0000 |
parents | 859f9b4339e6 |
children |
line wrap: on
line source
from parser import * class EvaluatorException(Exception): pass def eval(exp, env): # symbols are names to be left unevaluated. if isinstance(exp, NameExp): raise EvaluatorException("unbound variable: " + exp.body) if isinstance(exp, LambdaExp): # no change return exp if isinstance(exp, ApplyExp): # We're lazy, so we apply before evaluating the argument. # We do of course need to evaluate the function. rator = eval(exp.rator, env) rand = exp.rand return apply(rator, rand, env) if isinstance(exp, StringExp): import sys sys.stdout.write(exp.line) return LambdaExp('x', NameExp('x')) # i.e. the identity function if isinstance(exp, SpecialExp): if exp.body == '#list': # list all definitions in the environment import sys defs = env.keys() defs.sort() sys.stdout.write('[' + ' '.join(defs) + ']') return exp raise EvaluatorException("Unknown expression type for evaluation") def substitute(exp, name, value): if isinstance(exp, StringExp): return exp if isinstance(exp, NameExp): if exp.body == name: return value return exp if isinstance(exp, ApplyExp): return ApplyExp(substitute(exp.rator, name, value), substitute(exp.rand, name, value)) if isinstance(exp, SpecialExp): return exp if isinstance(exp, LambdaExp): # lambda can shadow the name if name == exp.arg: return exp return LambdaExp(exp.arg, substitute(exp.body, name, value)) print exp raise EvaluatorException("Unknown expression type for substitution") def apply(rator, rand, env): # since we're lazy, rand is unevaluated, so it might be anything # Rator, on the other hand ought to be a lambda or a special word if isinstance(rator, LambdaExp): # okay, now we actually have to do stuff # first we substitute all instances of the first named parameter # of the lambda with the rand. body = substitute(rator.body, rator.arg, rand) return eval(body, env) if isinstance(rator, SpecialExp): if rator.body == '#show': # first evaluates the operand, then shows it, returns the result of the evaluation import sys rand = eval(rand, env) sys.stdout.write(str(rand)) return rand else: raise EvaluatorException("Unknown special word: " + rator.body) raise EvaluatorException("Trying to apply something that isn't a lambda")