DISABLE FDs (REMOVE ME).
[jackhill/mal.git] / python / step2_eval.py
CommitLineData
31690700
JM
1import sys, traceback
2import mal_readline
ea81a808
JM
3import mal_types as types
4import reader, printer
31690700
JM
5
6# read
7def READ(str):
ea81a808 8 return reader.read_str(str)
31690700
JM
9
10# eval
11def eval_ast(ast, env):
ea81a808 12 if types._symbol_Q(ast):
aef93ea3
JM
13 try:
14 return env[ast]
15 except:
16 raise Exception("'" + ast + "' not found")
ea81a808
JM
17 elif types._list_Q(ast):
18 return types._list(*map(lambda a: EVAL(a, env), ast))
19 elif types._vector_Q(ast):
20 return types._vector(*map(lambda a: EVAL(a, env), ast))
21 elif types._hash_map_Q(ast):
31690700
JM
22 keyvals = []
23 for k in ast.keys():
24 keyvals.append(EVAL(k, env))
25 keyvals.append(EVAL(ast[k], env))
ea81a808 26 return types._hash_map(*keyvals)
31690700
JM
27 else:
28 return ast # primitive value, return unchanged
29
30def EVAL(ast, env):
86b689f3 31 #print("EVAL %s" % printer._pr_str(ast))
ea81a808
JM
32 if not types._list_Q(ast):
33 return eval_ast(ast, env)
31690700 34
ea81a808 35 # apply list
efa2daef 36 if len(ast) == 0: return ast
ea81a808
JM
37 el = eval_ast(ast, env)
38 f = el[0]
39 return f(*el[1:])
31690700 40
4eb71990 41# print
31690700 42def PRINT(exp):
ea81a808 43 return printer._pr_str(exp)
31690700
JM
44
45# repl
46repl_env = {}
47def REP(str):
48 return PRINT(EVAL(READ(str), repl_env))
49
50repl_env['+'] = lambda a,b: a+b
51repl_env['-'] = lambda a,b: a-b
52repl_env['*'] = lambda a,b: a*b
a05f7822 53repl_env['/'] = lambda a,b: int(a/b)
31690700 54
86b689f3 55# repl loop
31690700
JM
56while True:
57 try:
58 line = mal_readline.readline("user> ")
59 if line == None: break
60 if line == "": continue
61 print(REP(line))
ea81a808 62 except reader.Blank: continue
31690700 63 except Exception as e:
a05f7822 64 print("".join(traceback.format_exception(*sys.exc_info())))