プログラミング言語JSOP
簡単な、JSONを使ったプログラミング言語JSOPを作ってみました。
数値演算しかできません。
ハッシュと配列で何とかすることを考えたら、関数型言語風になりました。
var program = { body:{ body:["+", "x", ["/", "y", 2]], x:["add", 1, "y"], y:["mul", 4, 5], add:{ args:["x","y"], body:["+", "x", "y"] } }, mul:{ args:["x","y"], body:["*", "x", "y"] } }; alert(eval(program, program));
以上のプログラムで、
mul = function (x, y) { return x * y; } function body(){ add = function (x, y) { return x + y; } y = mul(4,5); x = add(1,y); return x + (y/2); } alert(body());
と同様の結果が得られます。
全て関数的に動くので、
処理順序を気にせずに書くことが出来るのがメリットかもしれません。
最適化は何もされてないので、動作は遅いです。
処理系は以下のような感じです。
function eval(p, env) { if (!isNaN(p))return p; if (p instanceof Array) {// 関数適用 switch(p[0]) { case "+": return eval(p[1], env)+eval(p[2], env); case "-": return eval(p[1], env)-eval(p[2], env); case "*": return eval(p[1], env)*eval(p[2], env); case "/": return eval(p[1], env)/eval(p[2], env); } var envs = getEnv(p[0], env); for(var i = 0; i < envs[0]["args"].length; i++) { envs[0][ envs[0]["args"][i] ] = eval(p[i + 1], env); } envs[0]["parent"] = envs[1]; return eval(envs[0], envs[1]); } if (p instanceof Object) { p["parent"] = env; return eval(p["body"], p); } var envs = getEnv(p, env); return eval(envs[0], envs[1]); } function getEnv(p, env) { while (env != null) { if (env[p] != null) return [env[p], env]; env = env["parent"]; } }
非常に簡単です。
数値ならその値を、
Arrayなら、関数として計算、
Objectならbodyを計算、
それ以外は変数の値として環境から取得する。
と、やっていることはそれだけです。