}
}
+
+Sexpr* dispatch_others(Sexpr* b, Sexpr* rest, Sexpr* env) {
+ // this is for applying other types,
+ // i.e. doing
+ // (t x y) -> y
+ // (2 f x) -> (f (f x))
+ // etc...
+ if(b->type == T) {
+ uint64_t k = (COMB_PREFIX << 8) | COMB_K;
+ return cons(from_opcode(k), rest);
+ }
+ else if(b->type == NIL) {
+ uint64_t k = (COMB_PREFIX << 8) | COMB_K;
+ uint64_t i = (COMB_PREFIX << 8) | COMB_I;
+ return cons(from_opcode(k), cons(from_opcode(i), rest));
+ }
+ else if(b->type == SYM) {
+ // what even is this?
+ return b;
+ }
+ else if(b->type == QUOTE) {
+ // what even is this?
+ return b;
+ }
+ else if(b->type == UINT) {
+ // the hard one
+ uint64_t anx = (CORE_PREFIX << 8) | CORE_APPLYN;
+ Sexpr* idk = from_opcode(anx);
+ Sexpr* ret = cons(idk, cons(clone(b), rest));
+ return ret;
+ }
+ return from_nil();
+}
+
+
uint64_t u64_get_num_args(Sexpr* b) {
uint64_t curr_num = 0;
Sexpr* args = b->value.b.args;
#include "builtins/core.h"
Sexpr* dispatch(Sexpr* b, Sexpr* rest, Sexpr* env);
+Sexpr* dispatch_others(Sexpr* b, Sexpr* rest, Sexpr* env);
uint64_t u64_get_num_args(Sexpr* b);
void load_builtin(char* ks, uint64_t op, Sexpr* env);
Sexpr* load_env(Sexpr* env);
}
+Sexpr* c_applyn(Sexpr* b, Sexpr* rest, Sexpr* env) {
+ // possible commentary for the future:
+ // i may wish to rewrite to eval (f x)
+ // then return something like ((n-1) f x)
+ if(CORE_APPLYN_ARGS != u64_get_num_args(b))
+ return cons(b, rest);
+ Sexpr* args = b->value.b.args;
+ Sexpr* arg = clone(car(args));
+ Sexpr* fun = car(cdr(args));
+ Sexpr* snum = eval(clone(car(cdr(cdr(args)))), env);
+ // uh yeah i'm not typechecking lol
+ uint64_t num = snum->value.u;
+ sexpr_free(snum);
+ // fun not cloned due since i'll be cloning it in the loop
+ Sexpr* ret = cons(arg, from_nil());
+ while(num > 0) {
+ ret = cons(clone(fun), cons(ret, from_nil()));
+ num--;
+ }
+ sexpr_free(b);
+ return cons(ret, rest);
+}
+
Sexpr* c_def(Sexpr* b, Sexpr* rest, Sexpr* env) {
if(CORE_DEF_ARGS != u64_get_num_args(b))
return cons(b, rest);
Sexpr* x_core_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) {
uint64_t code = b->value.b.opcode & 0xff;
-
switch(code) {
case CORE_QUOTE:
return c_quote(b, rest, env);
return c_not(b, rest, env);
case CORE_ATOM:
return c_atom(b, rest, env);
+ case CORE_APPLYN:
+ return c_applyn(b, rest, env);
case CORE_DEF:
return c_def(b, rest, env);
case CORE_EXIT:
#define CORE_ATOM 0x07
#define CORE_ATOM_ARGS 1
+#define CORE_APPLYN 0x08
+#define CORE_APPLYN_ARGS 3
+
#define CORE_DEF 0xfe // huh do i want this so close to exit?
#define CORE_DEF_ARGS 2
#define CORE_EXIT 0xff
Sexpr* eval(Sexpr* s, Sexpr* dict) {
/* char* out = sprint_sexpr(s);
printf("s: %s\n", out);
- free(out); /**/
+ free(out); */
// okay.. important to note,
// this needs to free s
// (I think)
return curr;
}
-Sexpr* eval2(Sexpr* s, Sexpr* env) {
- if(s == NULL) return NULL;
- if(s->type == SYM) {
- Sexpr* lookedup = lookup(env, s);
- if(lookedup->type == NIL) {
- printf("%s not defined", s->value.s);
- sexpr_free(s);
- return lookedup;
- }
- sexpr_free(s);
- Sexpr* lookedupval = clone(car(lookedup));
- sexpr_free(lookedup);
- return lookedupval;
- }
- if(s->type != CONS) {
- return s;
- } // s must be a cons cell now
- Sexpr* curr = s;
- while(curr->type == CONS) {
- if(cdr(curr)->type == NIL)
- return eval(car(curr), env);
- }
-
-
-}
Sexpr* apply_builtin(Sexpr* func, Sexpr* rest, Sexpr* env) {
if(func->type != BUILTIN) {
- printf("uh oh\n");
- return from_nil(); // uhh this /should/ actually be impossible...
+ //printf("uh oh\n");
+ //return from_nil(); // uhh this /should/ actually be impossible...
+ return dispatch_others(func, rest, env);
}
Sexpr* ret = malloc(sizeof(Sexpr));
ret->type = BUILTIN;
run_eval_test("(B car cdr (quote (1 2 3)))");
run_eval_test("(C - 3 10)");
run_eval_test("(W * 5)");
+
+ run_eval_test("(t 4 5)");
+ run_eval_test("(nil 4 5)");
+ run_eval_test("(5 (+ 3) 4)");
}