// eval part var evaluate = function(x, env) { if (Array.isArray(x)) { if (x[0] === 'def') { // 変数定義 return env[x[1]] = evaluate(x[2], env); } else if (x[0] === 'set!') { // 代入 return env[x[1]] = evaluate(x[2], env); } else if (x[0] === 'if') { // 条件分岐 return String(evaluate(x[1], env)) !== 'false' ? evaluate(x[2], env) : evaluate(x[3], env); } else { // 関数の実行 var exps = x.map(function(exp) {return evaluate(exp, env);}); var proc = exps.shift(); return proc.apply(null, exps); } } else { var y = env[x]; return y !== undefined ? y : x; } }; // library var globalEnv = { '+': function(a, b) {return a + b;}, '-': function(a, b) {return a - b;}, '*': function(a, b) {return a * b;}, '/': function(a, b) {return a / b;}, 'mod': function(a, b) {return a % b;}, 'not': function(x) {return !x;}, '=': function(a, b) {return a === b;}, '>': function(a, b) {return a > b;}, '<': function(a, b) {return a < b;}, '<=': function(a, b) {return a <= b;}, '>=': function(a, b) {return a >= b;}, 'alert': function(a) {alert(a);}, 'console.log': function() {console.log(arguments);}, 'do': function() {return arguments[arguments.length - 1];} }; // usage (output to JavaScript console) evaluate(['console.log', ['do', ['def', 'a', 2], ['def', 'b', 3], ['def', 'a', 1], ['+', 'a', 'b']]], globalEnv);