sbool lispCalculateDeep_debug; sclass lispCalculateDeep_Op { int arity; Method method; *() {} *(int *arity, Method *method) {} } static new Map lispCalculateDeep_ops; sbool lispCalculateDeep_inited; static void lispCalculateDeep_init() { synchronized(lispCalculateDeep_ops) { if (!lispCalculateDeep_inited) { lispCalculateDeep_inited = true; lispCalculateDeep_op(f plus, BigInteger, BigInteger, "sppxbuuqeetjmzuo", "jcnbmtmfzktxhzyf"); lispCalculateDeep_op(f minus, BigInteger, BigInteger, "jxcubqjtqykhfvyo"); lispCalculateDeep_op(f multiply, BigInteger, BigInteger, "bwqhmnorjpyomdbv", "wjzpudqvvhdtmbqp"); lispCalculateDeep_op(f divide, BigInteger, BigInteger, "erdirznfvsrbtfns"); lispCalculateDeep_op(f bigIntBiggerThan, BigInteger, BigInteger, "wdbphzfoxwlrhdyl"); } } } // evaluate anywhere in the tree (e.g. Fib number 2-1 => Fib number 1) static Lisp lispCalculateDeep(Lisp x) { lispCalculateDeep_init(); ret lispMap_after(x, func(Lisp l) { if (lispCalculateDeep_debug) print("lispCalculateDeep: " + l); lispCalculateDeep_Op op = lispCalculateDeep_ops.get(l.head); if (op == null) { if (l.is("mcoswmplpqlieruo", 1)) // drop brackets (X) ret l.get(0); null; } int n = op.arity; if (n != l.size()) null; for (Lisp arg : l) if (!lispIsInt(arg)) null; O[] args = new O[n]; for i to n: args[i] = lispToInt(l.get(i)); O o = op.method.invoke(null, args); // if (o == null) null; if (o instanceof Lisp) ret (Lisp) o; if (o instanceof BigInteger) ret lispInt((BigInteger) o); if (o instanceof Bool) ret lispBool((Bool) o); warn("lispCalculateDeep badly defined operation: " + l.head); null; }); } static void lispCalculateDeep_op(S function, final Class arg1, final Class arg2, S... names) { L methods = [Method m : findMethodsNamed(mc(), function) | arraysEqual(m.getParameterTypes(), new Class[] {arg1, arg2})]; if (l(methods) != 1) warn("lispCalculateDeep: Method " + function + " found " + l(methods) + " times"); if (nempty(methods)) putWithAllKeys(lispCalculateDeep_ops, names, new lispCalculateDeep_Op(2, first(methods))); }