diff options
Diffstat (limited to 'js/step2_eval.js')
| -rw-r--r-- | js/step2_eval.js | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/js/step2_eval.js b/js/step2_eval.js new file mode 100644 index 0000000..f2cb8b1 --- /dev/null +++ b/js/step2_eval.js @@ -0,0 +1,83 @@ +var types = require('./types'); +var reader = require('./reader'); +if (typeof module !== 'undefined') { + var readline = require('./node_readline'); +} + +// read +function READ(str) { + return reader.read_str(str); +} + +// eval +function eval_ast(ast, env) { + if (types.symbol_Q(ast)) { + return env[ast]; + } else if (types.list_Q(ast)) { + return ast.map(function(a) { return EVAL(a, env); }); + } else if (types.vector_Q(ast)) { + var v = ast.map(function(a) { return EVAL(a, env); }); + v.__isvector__ = true; + return v; + } else if (types.hash_map_Q(ast)) { + var new_hm = {}; + for (k in ast) { + new_hm[EVAL(k, env)] = EVAL(ast[k], env); + } + return new_hm; + } else { + return ast; + } +} + +function _EVAL(ast, env) { + if (!types.list_Q(ast)) { + return eval_ast(ast, env); + } + + // apply list + var el = eval_ast(ast, env), f = el[0]; + return f.apply(f, el.slice(1)); +} + +function EVAL(ast, env) { + var result = _EVAL(ast, env); + return (typeof result !== "undefined") ? result : null; +} + +// print +function PRINT(exp) { + return types._pr_str(exp, true); +} + +// repl +repl_env = {}; +var rep = function(str) { return PRINT(EVAL(READ(str), repl_env)); }; + +repl_env['+'] = function(a,b){return a+b;}; +repl_env['-'] = function(a,b){return a-b;}; +repl_env['*'] = function(a,b){return a*b;}; +repl_env['/'] = function(a,b){return a/b;}; + +if (typeof require === 'undefined') { + // Asynchronous browser mode + readline.rlwrap(function(line) { return rep(line); }, + function(exc) { + if (exc instanceof reader.BlankException) { return; } + if (exc.stack) { console.log(exc.stack); } else { console.log(exc); } + }); +} else if (require.main === module) { + // Synchronous node.js commandline mode + while (true) { + var line = readline.readline("user> "); + if (line === null) { break; } + try { + if (line) { console.log(rep(line)); } + } catch (exc) { + if (exc instanceof reader.BlankException) { continue; } + if (exc.stack) { console.log(exc.stack); } else { console.log(exc); } + } + } +} else { + exports.rep = rep; +} |
