fibだとphpやrubyより速いバイナリツリー処理系

MegLevとかで使われてるバイナリツリーのベンチマークJavaがかなり速かったりします。
ってことで、Javaでバイナリツリー言語を作れば速いんじゃなかろうか?
ってことで、作ってみました。
フィボナッチ関数の計算では、phpruby1.8.7より速い処理系が出来ました。
パーサはついてませんけど。

import java.util.*;

class BinTree {
	int item;
	Object left;
	Object right;
	BinTree(int item, Object left, Object right) {
		this.left = left;
		this.right = right;
		this.item = item;
	}
	public String toString() {
		switch(item) {
		case INT: return ""+left;
		case SYMBOL: return ""+left;
		case STRING: return "\""+escape(""+left)+"\"";
		case NIL: return "nil";
		default: return i2sym.get(new Integer(item)) + "{"+left+","+ right+"}";
		}
	}

	static final Env sym2i = new Env();
	static final Env i2sym = new Env();
	static final void set(String s, int i) {
		Integer in = new Integer(i);
		sym2i.put(s, in);
		i2sym.put(in, s);
	}
	static final int INT = 0;
	static final int OPADD = 1;
	static final int OPSUB = 2;
	static final int OPMUL = 3;
	static final int OPDIV = 4;
	static final int OPPER = 5;
	static final int OPEQ = 6;
	static final int OPLT = 7;
	static final int OPGT = 8;
	static final int OPLTEQ = 9;
	static final int OPGTEQ = 10;
	static final int OPEQEQ = 11;
	static final int OPNOTEQ = 12;
	static final int OPCRN = 13;
	static final int OPCMM = 14;
	static final int SYMBOL = 15;
	static final int OPSIFP = 16;
	static final int OPMB = 17;
	static final int OPSFUNCTIONP = 18;
	static final int OPMP = 19;
	static final int NIL = 20;
	static final int OPELSE = 21;
	static final int STRING = 22;
	static final int DEFFUN = 23;
	static int symmax;
	public static final BinTree Nil = new BinTree(NIL, null, null);
	static {
		set("INT", INT);
		set("opAdd", OPADD);
		set("opSub", OPSUB);
		set("opMul", OPMUL);
		set("opDiv", OPDIV);
		set("opPer", OPPER);
		set("opEq", OPEQ);
		set("opLt", OPLT);
		set("opGt", OPGT);
		set("opLtEq", OPLTEQ);
		set("opGtEq", OPGTEQ);
		set("opEqEq", OPEQEQ);
		set("opNotEq", OPNOTEQ);
		set("opCrn", OPCRN);
		set("opCmm", OPCMM);
		set("SYMBOL", SYMBOL);
		set("opSifP", OPSIFP);
		set("opMB",OPMB);
		set("opSfunctionP", OPSFUNCTIONP);
		set("opMP",OPMP);
		set("Nil",NIL);
		set("opelse", OPELSE);
		set("STRING", STRING);
		set("DEFFUN", DEFFUN);
		symmax = DEFFUN;
		Nil.left = Nil;
		Nil.right = Nil;
	}
	static final int sym(String s) {
		if (sym2i.containsKey(s)) return ((Integer)sym2i.get(s)).intValue();
		set(s, ++symmax);
		return symmax;
	}

	final int i() {
		if(left instanceof Integer) return ((Integer)left).intValue();
		return 0;
	}
	final boolean b() {
		if(left instanceof Integer) return ((Integer)left).intValue() != 0;
		return false;
	}

	final BinTree l() { return (BinTree)left; }
	final BinTree r() { return (BinTree)right; }


	static final String escape(String s) {
		String rc = "";
		for(int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			switch (c) {
			case '\\': rc += "\\\\"; break;
			case '\n': rc += "\\n"; break;
			case '\r': rc += "\\r"; break;
			case '\t': rc += "\\t"; break;
			default: rc += c; break;
			}
		}
		return rc;
	}
	static final BinTree b(int i, Object l, Object r) {
		return new BinTree(i,l,r);
	}

	static final BinTree b(String i, Object l, Object r) {
		return new BinTree(sym(i),l,r);
	}

	static final BinTree i(int i) {
		return new BinTree(INT, new Integer(i), null);
	}
	static final BinTree b(boolean b) {
		return new BinTree(INT, new Integer(b ? -1 : 0), null);
	}
	static final BinTree s(String s) {
		return new BinTree(STRING, s, null);
	}
	static final BinTree id(String s) {
		return new BinTree(SYMBOL, s, null);
	}

	static final boolean isSym(Object o, String s) {
		if(!( o instanceof BinTree)) return false;
		BinTree l = (BinTree)o;
		return (l.item == SYMBOL && l.left.equals(s));
	}

	static final BinTree eval(BinTree t) {
		int item = t.item;
		switch (item) {
		case INT:     return t;
		case OPADD:   return i(eval(t.l()).i() + eval(t.r()).i());
		case OPSUB:   return i(eval(t.l()).i() - eval(t.r()).i());
		case OPMUL:   return i(eval(t.l()).i() * eval(t.r()).i());
		case OPDIV:   return i(eval(t.l()).i() / eval(t.r()).i());
		case OPPER:   return i(eval(t.l()).i() % eval(t.r()).i());
		case OPEQ:    return setEnv(t.l(), eval(t.r()));
		case OPLT:    return b(eval(t.l()).i() > eval(t.r()).i());
		case OPGT:    return b(eval(t.l()).i() < eval(t.r()).i());
		case OPLTEQ:  return b(eval(t.l()).i() >= eval(t.r()).i());
		case OPGTEQ:  return b(eval(t.l()).i() <= eval(t.r()).i());
		case OPEQEQ:  return b(eval(t.l()).i() == eval(t.r()).i());
		case OPNOTEQ: return b(eval(t.l()).i() != eval(t.r()).i());
		case OPCRN:   return defEnv(t.l(), eval(t.r()));
		case OPCMM:   return b("opCmm", eval(t.l()), eval(t.r()));
		case SYMBOL:  return getEnv(t);
		case OPSIFP:
			if(eval(t.l()).b()) {
				if (t.r().item == OPELSE) return eval(t.r().l());
				else return eval(t.r());
			} else {
				if(t.r().item == OPELSE) return eval(t.r().r());
				else return Nil;
			}
		case OPMB: if (isSym(t.left, "q")) return t.r(); else return t;
		case OPSFUNCTIONP: return defFun(t); // 関数定義
		case OPMP: return callFun(t); // 関数適用
		default: return t;
		}
	}
	static Env env = new Env();
	static Env pEnv = new Env();
	static final BinTree defEnv(BinTree o, BinTree b) {
		if (o.item == SYMBOL) env.put(o.left, b);
		return b;
	}

	static final BinTree setEnv(BinTree o, BinTree b) {
		if (o.item == SYMBOL) {
			Env env = BinTree.env;
			Env pEnv = BinTree.pEnv;
			Env oEnv = BinTree.env;
			while (env != null) {
				if (env.containsKey(o.left)) {
					env.put(o.left, b);
					return b;
				}
				oEnv = env;
				env = pEnv;
				if(env == null) break;
				pEnv = (Env)env.get("parent");
			}
			oEnv.put(o.left, b);
		}
		return b;
	}

	static final BinTree getEnv(BinTree o) {
		Env env = BinTree.env;
		Env pEnv = BinTree.pEnv;
		Env oEnv = BinTree.env;
		while (env != null) {
			if(env.containsKey(o.left)) {
				return (BinTree)env.get(o.left);
			}
			oEnv = env;
			env = pEnv;
			if(env == null) break;
			pEnv = (Env)env.get("parent");
		}
		return Nil;
	}

	static final BinTree defFun(BinTree o) {// 関数定義
		return b(DEFFUN, o, env);
	}

	static final BinTree callFun(BinTree o) {// 関数定義
		BinTree f = eval(o.l());// 関数
		if(f.item != DEFFUN)
			throw new Error("関数ではないものを関数として呼び出そうとしました。");
		BinTree fn = f.l();
		BinTree arg = eval(o.r());// 引数リストを評価する。,の連続はタプルとして返す。

		Env oldenv = env;
		Env oldpenv = pEnv;
		env = new Env();
		pEnv = (Env)f.right;// 親の環境を設定

		BinTree prm = fn.l();// パラメータリスト
		
		while (prm.item == OPCMM) {
			defEnv(prm.l(), arg.l());
			prm = prm.r();
			arg = arg.r();
		}
		defEnv(prm, arg);
		BinTree rc = eval(fn.r());
		env = oldenv;
		pEnv = oldpenv;
		return rc;
	}

	public static void main(String[] a) {
		System.out.println(eval(b("opAdd", i(1), i(2))));
		System.out.println(eval(b("opAdd", i(1), b("opMul", i(2), i(3)))));
		System.out.println(eval(b("opCrn", id("a"), b("opAdd", i(1), i(2)))));
		System.out.println(eval(s("a")));
		System.out.println(eval(id("a")));
		System.out.println(eval(b("opMB", id("q"),b("opAdd", i(1), i(2)))));
		System.out.println(eval(s("hoge\n")));
		System.out.println(eval(b("opSfunctionP",id("a"), b("opAdd", id("a"), i(1)))));
		System.out.println(eval(b("opMP", b("opSfunctionP",id("a"), b("opAdd", id("a"), i(1))),i(2))));
		System.out.println(eval(b("opMP",
			b("opSfunctionP",
				b("opCmm", id("a"), id("b")), 
				b("opAdd", id("a"), id("b"))
			),
			b("opCmm", i(2),i(3))
		)));

		System.out.println(eval(b("opCrn",
			id("add"),
			b("opSfunctionP",
				b("opCmm", id("a"), id("b")), 
				b("opAdd", id("a"), id("b"))
			)
		)));
		System.out.println(eval(b(OPCRN,
			id("fib"),
			b(OPSFUNCTIONP,
				id("a"),
				b(OPSIFP,
					b(OPEQEQ, id("a"), i(0)),
					b(OPELSE,
						i(0),
						b(OPSIFP,
							b(OPGTEQ, id("a"), i(2)),
							b(OPELSE,
								i(1),
								b(OPADD,
									b(OPMP, id("fib"),
										b("opSub", id("a"), i(1))),
									b(OPMP, id("fib"),
										b(OPSUB, id("a"), i(2))))))))))));
		long start = System.currentTimeMillis();
		System.out.println(eval(b(OPMP, id("fib"), i(30))));
		System.out.println( System.currentTimeMillis() - start + "ms");
	}
}

class Env extends HashMap {
	public String toString() { return "[Env]";}
}