Merge pull request #467 from MontakOleg/swift5
[jackhill/mal.git] / wren / step2_eval.wren
CommitLineData
5755c330
DM
1import "./readline" for Readline
2import "./reader" for MalReader
3import "./printer" for Printer
4import "./types" for MalSymbol, MalList, MalVector, MalMap
5
6class Mal {
7 static read(str) {
8 return MalReader.read_str(str)
9 }
10
11 static eval_ast(ast, env) {
12 if (ast is MalSymbol) {
13 if (!env.containsKey(ast.value)) Fiber.abort("'%(ast.value)' not found")
14 return env[ast.value]
15 } else if (ast is MalList) {
16 return MalList.new(ast.elements.map { |e| eval(e, env) }.toList)
17 } else if (ast is MalVector) {
18 return MalVector.new(ast.elements.map { |e| eval(e, env) }.toList)
19 } else if (ast is MalMap) {
20 var m = {}
21 for (e in ast.data) {
22 m[e.key] = eval(e.value, env)
23 }
24 return MalMap.new(m)
25 } else {
26 return ast
27 }
28 }
29
30 static eval(ast, env) {
31 if (!(ast is MalList)) return eval_ast(ast, env)
32 if (ast.isEmpty) return ast
33 var evaled_ast = eval_ast(ast, env)
34 var f = evaled_ast[0]
35 return f.call(evaled_ast[1..-1])
36 }
37
38 static print(ast) {
39 return Printer.pr_str(ast)
40 }
41
42 static rep(str) {
43 return print(eval(read(str), __repl_env))
44 }
45
46 static main() {
47 __repl_env = {
48 "+": Fn.new { |a| a[0] + a[1] },
49 "-": Fn.new { |a| a[0] - a[1] },
50 "*": Fn.new { |a| a[0] * a[1] },
51 "/": Fn.new { |a| a[0] / a[1] }
52 }
53 while (true) {
54 var line = Readline.readLine("user> ")
55 if (line == null) break
56 if (line != "") {
57 var fiber = Fiber.new { System.print(rep(line)) }
58 fiber.try()
59 if (fiber.error) System.print("Error: %(fiber.error)")
60 }
61 }
62 System.print()
63 }
64}
65
66Mal.main()