1 import rdstdin, tables, sequtils, types, reader, printer
3 proc read(str: string): MalType = str.read_str
5 proc eval(ast: MalType, env: Table[string, MalType]): MalType
7 proc eval_ast(ast: MalType, env: Table[string, MalType]): MalType =
10 if not env.hasKey(ast.str):
11 raise newException(ValueError, "'" & ast.str & "' not found")
14 result = list ast.list.mapIt(MalType, it.eval(env))
16 result = vector ast.list.mapIt(MalType, it.eval(env))
19 for k, v in ast.hash_map.pairs:
20 result.hash_map[k] = v.eval(env)
24 proc eval(ast: MalType, env: Table[string, MalType]): MalType =
27 let el = ast.eval_ast(env)
28 el.list[0].fun(el.list[1 .. ^1])
32 proc print(exp: MalType): string = exp.pr_str
34 template wrapNumberFun(op: expr): expr =
35 fun proc(xs: varargs[MalType]): MalType = number op(xs[0].number, xs[1].number)
37 let repl_env = toTable({
38 "+": wrapNumberFun `+`,
39 "-": wrapNumberFun `-`,
40 "*": wrapNumberFun `*`,
41 "/": wrapNumberFun `div`,
44 proc rep(str: string): string =
45 str.read.eval(repl_env).print
49 let line = readLineFromStdin("user> ")
52 echo getCurrentExceptionMsg()