■
書きかけ
書いてたらだんだん眠くなってやめた。
環境とか、lambdaとクロージャとそのへん、こんがらがり中。
適当になってるのがよくないかんじ。
MiniDってののソースが気になる今日この頃ですけど、時間ね。
単なるゴミなかんじ。
<script> Array.prototype.toString = function(){ return "["+this.join(",")+"]"} Object.prototype.toString = function(){ var a = []; for(var i in this) a.push(i+":"+this[i]); return "{"+a.join(",")+"}"} function eval(s,env){ function getEnv(env, a) { if (env[a] != null) return env[a]; if (env.parent == null) throw "error not found val "+a; 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": env = {parent:env}; case "#begin2": var a = s.reverse();a.pop(); var rc = eval(a.pop(),env); if (a.length == 0) return rc; a.push("#begin2"); return eval(a.reverse(),env); case "lambda": return ["#closure",s,{parent:env}]; } var data = null; if(s[0] instanceof Array && s[0][0] == "lambda") data = eval(s[0],env); else if(s[0] instanceof Array && s[0][0] == "#closure") data = s[0]; else data = getEnv(env, s[0]); if (data == null) throw "error"; if (data instanceof Array) { if (data[0] == "#closure") { var lambda = data[1]; var argv = lambda[1]; var newenv = {parent:data[2]}; for (var i = 0; i < argv.length; i++) newenv[argv[i]] = eval(s[i+1], env); return eval(lambda[2],newenv); } throw "error"; } } if (typeof(s) == "string") return getEnv(env, s); return s; } var env = {}; try{ //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","data",1],["define","c",["lambda",["a","b"],["add",["add","a","b"],"data"]]],["begin",["define","data",2],["c",2,"data"]]])); alert(eval([["lambda",["a","b"],["add","a","b"]],1,2])); }catch(e){alert(e)} </script>