hash-map equality: bash, c, coffee, cs, es6, ...
[jackhill/mal.git] / js / step2_eval.js
1 if (typeof module !== 'undefined') {
2 var types = require('./types');
3 var readline = require('./node_readline');
4 var reader = require('./reader');
5 var printer = require('./printer');
6 }
7
8 // read
9 function READ(str) {
10 return reader.read_str(str);
11 }
12
13 // eval
14 function eval_ast(ast, env) {
15 if (types._symbol_Q(ast)) {
16 return env[ast];
17 } else if (types._list_Q(ast)) {
18 return ast.map(function(a) { return EVAL(a, env); });
19 } else if (types._vector_Q(ast)) {
20 var v = ast.map(function(a) { return EVAL(a, env); });
21 v.__isvector__ = true;
22 return v;
23 } else if (types._hash_map_Q(ast)) {
24 var new_hm = {};
25 for (k in ast) {
26 new_hm[EVAL(k, env)] = EVAL(ast[k], env);
27 }
28 return new_hm;
29 } else {
30 return ast;
31 }
32 }
33
34 function _EVAL(ast, env) {
35 //printer.println("EVAL:", printer._pr_str(ast, true));
36 if (!types._list_Q(ast)) {
37 return eval_ast(ast, env);
38 }
39
40 // apply list
41 var el = eval_ast(ast, env), f = el[0];
42 return f.apply(f, el.slice(1));
43 }
44
45 function EVAL(ast, env) {
46 var result = _EVAL(ast, env);
47 return (typeof result !== "undefined") ? result : null;
48 }
49
50 // print
51 function PRINT(exp) {
52 return printer._pr_str(exp, true);
53 }
54
55 // repl
56 repl_env = {};
57 var rep = function(str) { return PRINT(EVAL(READ(str), repl_env)); };
58
59 repl_env['+'] = function(a,b){return a+b;};
60 repl_env['-'] = function(a,b){return a-b;};
61 repl_env['*'] = function(a,b){return a*b;};
62 repl_env['/'] = function(a,b){return a/b;};
63
64 // repl loop
65 if (typeof require !== 'undefined' && require.main === module) {
66 // Synchronous node.js commandline mode
67 while (true) {
68 var line = readline.readline("user> ");
69 if (line === null) { break; }
70 try {
71 if (line) { printer.println(rep(line)); }
72 } catch (exc) {
73 if (exc instanceof reader.BlankException) { continue; }
74 if (exc.stack) { printer.println(exc.stack); }
75 else { printer.println(exc); }
76 }
77 }
78 }