return ret;
 }
 
+Sexpr* c_phi(Sexpr* b, Sexpr* rest, Sexpr* env) {
+       if(COMB_PHI_ARGS != u64_get_num_args(b)) {
+               return cons(b, rest);
+       }
+       Sexpr* args = b->value.b.args;
+       Sexpr* d = clone(car(args));
+       Sexpr* c = clone(car(cdr(args)));
+       Sexpr* bee = clone(car(cdr(cdr(args))));
+       Sexpr* a = clone(car(cdr(cdr(cdr(args)))));
+       Sexpr* d2 = clone(d);
+       Sexpr* bd = cons(bee, cons(d, from_nil()));
+       Sexpr* cd = cons(c, cons(d2, from_nil()));
+       Sexpr* ret = cons(a, cons(bd, cons(cd, from_nil())));
+       sexpr_free(b);
+       return ret;
+}
+
+Sexpr* c_psi(Sexpr* b, Sexpr* rest, Sexpr* env) {
+       if(COMB_PHI_ARGS != u64_get_num_args(b)) {
+               return cons(b, rest);
+       }
+       Sexpr* args = b->value.b.args;
+       Sexpr* d = clone(car(args));
+       Sexpr* c = clone(car(cdr(args)));
+       Sexpr* bee = clone(car(cdr(cdr(args))));
+       Sexpr* a = clone(car(cdr(cdr(cdr(args)))));
+       Sexpr* bee2 = clone(bee);
+       Sexpr* bd = cons(bee, cons(d, from_nil()));
+       Sexpr* bc = cons(bee2, cons(c, from_nil()));
+       Sexpr* ret = cons(a, cons(bc, cons(bd, from_nil())));
+       sexpr_free(b);
+       return ret;
+}
+
+
 
 Sexpr* x_comb_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) {
        uint64_t code = b->value.b.opcode & 0xff;
                return c_c(b, rest, env);
        case COMB_W:
                return c_w(b, rest, env);
+       case COMB_PHI:
+               return c_phi(b, rest, env);
+       case COMB_PSI:
+               return c_psi(b, rest, env);
        default:
                return from_nil();
        }
        load_builtin("B", (COMB_PREFIX << 8) | COMB_B, env);
        load_builtin("C", (COMB_PREFIX << 8) | COMB_C, env);
        load_builtin("W", (COMB_PREFIX << 8) | COMB_W, env);
+       load_builtin("Phi", (COMB_PREFIX << 8) | COMB_PHI, env);
+       load_builtin("Psi", (COMB_PREFIX << 8) | COMB_PSI, env);
        
        return env;
 }
 
        return ret;
 }
 
+Sexpr* from_pointer(void* p) {
+       Sexpr* ret = malloc(sizeof(Sexpr));
+       ret->type = PTR;
+       ret->value.p = p;
+       return ret;
+}
+
 Sexpr* cons(Sexpr* car, Sexpr* cdr) {
        Cons_t* c = malloc(sizeof(Cons_t));
        Sexpr* s = malloc(sizeof(Sexpr));
                return from_t();
        if(t == SYM)
                return strcmp(a->value.s, b->value.s) == 0 ? from_t() : from_nil();
+       if(t == PTR)
+               return (a->value.p == b->value.p) ? from_t() : from_nil();
        if(t == UINT)
                return (a->value.u == b->value.u) ? from_t() : from_nil();
        if(t == BUILTIN)
        case SYM:
                ret = from_sym(s->value.s);
                break;
+       case PTR:
+               ret = from_pointer(s->value.p);
+               break;
        case BUILTIN:
                ret = from_opcode(s->value.b.opcode);
                sexpr_free(ret->value.b.args);
                strcpy(out, s->value.s);
                return out;
        }
+       else if(s->type == PTR) {
+               out = strdup("<*>");
+               return out;
+       }
        else if(s->type == UINT) {
                nbytes = snprintf(NULL, 0, "%" PRIu64 "", s->value.u) + 1;
                out = malloc(nbytes*sizeof(char));