プログラミング言語JSOP(2)

factの計算が出来るようにしてみました。ifと=を追加して前回の関数呼び出し部分のバグを取ってあります。

<html>
<script language="javascript">
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); break;
		case "-": return eval(p[1], env) -  eval(p[2], env); break;
		case "*": return eval(p[1], env) *  eval(p[2], env); break;
		case "/": return eval(p[1], env) /  eval(p[2], env); break;
		case "=": return eval(p[1], env) == eval(p[2], env); break;
		case "if": return eval(p[1], env) ? eval(p[2], env) : eval(p[3], env); break;
		}
		var envs = getEnv(p[0], env);
		var e = {body:envs[0]["body"], parent:envs[1]};
		for(var i = 0; i < envs[0]["args"].length; i++)
			e[ envs[0]["args"][i] ] = eval(p[i + 1], env);
		return eval(e, 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"];
	}
}
var program = {
	body : ["fact", 10],
	fact : {
		args : ["n"],
		body : ["if",
			["=", "n", 1],
			1,
			["*",
				["fact",
					["-", "n", 1]],
				"n"]
		]
	}
};

alert(eval(program, program));
</script>
</html>