■
<script> Array.prototype.toString = function(){ return "["+this.join(",")+"]"} function eval(s,env){ function getEnv(env,a) { if (env[a] != null) return env[a]; if (env.parent == null) throw "error"; return getEnv(env.parent, a); } function setEnv(env, a, v) { if (env[a] != null) return env[a] = v; if (env.parent == null) throw "error"; return setEnv(env.parent, a, v); } if (env == null) env = {}; if (s instanceof Array) { switch(s[0]){ case "add": return eval(s[1],env) + eval(s[2],env); case "mul": return eval(s[1],env) * eval(s[2],env); case "define": return env[s[1]] = eval(s[2],env); case "set": return setEnv(env, s[1], eval(s[2],env)); case "begin": var a = s.reverse();a.pop(); var rc = eval(a.pop(),env); if (a.length == 0) return rc; a.push("begin"); return eval(a.reverse(),env); case "lambda": return s; } var data = null; if(s[0] instanceof Array && s[0][0] == "lambda") data = s[0]; else data = getEnv(env, s[0]); if (data == null) return "error"; if (data instanceof Array) { if (data[0] == "lambda") { var argv = data[1];// 引数リスト var newenv = {parent:env}; for (var i = 0; i < argv.length; i++) newenv[argv[i]] = eval(s[i+1],env); return eval(data[2],newenv); } else return "error"; } } if (typeof(s) == "string") return getEnv(env,s); return s; } var env = {}; //alert(eval(["define","a",["add",["mul",2,3],2]],env)); //alert(eval("a",env)); //alert(eval(["begin",["define","a",["add",1,2]],["define","b",["add",1,2]],["add","a","b"]])); alert(eval(["begin",["define","c",["lambda",["a","b"],["add","a","b"]]],["c",1,2]])); alert(eval([["lambda",["a","b"],["add","a","b"]],1,2])); </script>
書きかけ