# okay what the fuck am i doing with lex yacc generated stuff? just do it once? okay
 
-SRCS:= $(wildcard *.c)
+SRCS:= $(wildcard *.c */*.c)
 BUILD:= ../build
 BIN:=repl
 TEST_BIN:=test
 
 #include "builtins/core.h"
 
 
-Sexpr* dispatch(Sexpr* b) {
+Sexpr* apply(Sexpr* b, Sexpr* env) {
        uint64_t prefix = (b->value.b.opcode) >> 8;
        switch(prefix) {
        case CORE_PREFIX:
-               return x_core_dispatch(b);
+               return x_core_dispatch(b, env);
        default:
                return from_nil();
        }
 }
+
+Sexpr* append_arg(Sexpr* b, Sexpr* arg) {
+       // where b better be a builtin
+       Sexpr* ret = malloc(sizeof(Sexpr));
+       ret->type = BUILTIN;
+       ret->value.b.opcode = b->value.b.opcode;
+       ret->value.b.args = cons(arg, b->value.b.args);
+       return ret;
+}
 
 
 #define _HIIIII
 
-Sexpr* dispatch(Sexpr* b);
-
+Sexpr* apply(Sexpr* b, Sexpr* env);
+Sexpr* append_arg(Sexpr* b, Sexpr* arg);
 
 
 #endif
 
 #include "../sexpr.h"
 #include "../eval.h"
 
+Sexpr* c_quote(Sexpr* args) {
+       return car(args);
+}
+Sexpr* c_cons(Sexpr* args) {
+       Sexpr* _car = car(args);
+       Sexpr* _cdr = car(cdr(args));
+       return cons(_car, _cdr);
+}
+Sexpr* c_car(Sexpr* args) {
+       return car(car(args));
+}
+Sexpr* c_cdr(Sexpr* args) {
+       return cdr(car(args));
+}
+Sexpr* c_if(Sexpr* args) {
+       Sexpr* cond = car(args);
+       Sexpr* truthy = car(cdr(args));
+       Sexpr* falsy = car(cdr(cdr(args)));
+
+}
 
+//Sexpr* c_quote(Sexpr* args);
+//Sexpr* c_cons(Sexpr* args);
 
-Sexpr* x_core_dispatch(Sexpr* s) {
+Sexpr* x_core_dispatch(Sexpr* s, Sexpr* env) {
        uint64_t code = s->value.b.opcode & 0xff;
+       Sexpr* args = s->value.b.args;
        switch(code) {
        case 0: // quote
-               
+               return c_quote(args);
+       case 1: // cons
+               return c_cons(args);
        default:
                return from_nil();
        }
 
 #define CORE_PREFIX 0x00
 
 
-Sexpr* x_core_dispatch(Sexpr* s);
+Sexpr* x_core_dispatch(Sexpr* s, Sexpr* env);
 
 
 #include "dict.h"
 #include "builtins.h"
 
-Sexpr* apply_builtin(Sexpr* func, Sexpr* arg);
+Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* env);
 
 Sexpr* eval(Sexpr* s, Sexpr* dict) {
        // non-null s
        return curr;
 }
 
-Sexpr* apply_builtin(Sexpr* func, Sexpr* arg) {
+Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* env) {
        if(func->type != BUILTIN)
                return from_nil(); // uhh this /should/ actually be impossible...
        uint8_t num_args = 0;
                return ret;
        // what's left now: all the args needed are there,
        // just gotta dispatch to whatever handles the opcode evals
-       return dispatch(ret);
+       return dispatch(ret, env);
 }