From e20e2612339a70903fd2449454e2ed80b5fa514d Mon Sep 17 00:00:00 2001 From: Elijah Cohen Date: Sat, 17 Aug 2024 13:59:16 +0000 Subject: [PATCH] added eval rules for other types --- src/builtins.c | 35 +++++++++++++++++++++++++++++++++++ src/builtins.h | 1 + src/builtins/core.c | 26 +++++++++++++++++++++++++- src/builtins/core.h | 3 +++ src/eval.c | 32 ++++---------------------------- src/test.c | 4 ++++ 6 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index c336bfa..8168887 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -29,6 +29,41 @@ Sexpr* dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) { } } + +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; diff --git a/src/builtins.h b/src/builtins.h index a37b2c6..fe03089 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -6,6 +6,7 @@ #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); diff --git a/src/builtins/core.c b/src/builtins/core.c index a72b87f..23bee2c 100644 --- a/src/builtins/core.c +++ b/src/builtins/core.c @@ -134,6 +134,29 @@ Sexpr* c_atom(Sexpr* b, Sexpr* rest, 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); @@ -159,7 +182,6 @@ Sexpr* c_exit(Sexpr* b, Sexpr* rest, Sexpr* env) { 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); @@ -177,6 +199,8 @@ Sexpr* x_core_dispatch(Sexpr* b, Sexpr* rest, Sexpr* 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: diff --git a/src/builtins/core.h b/src/builtins/core.h index 72cb421..50606c7 100644 --- a/src/builtins/core.h +++ b/src/builtins/core.h @@ -25,6 +25,9 @@ #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 diff --git a/src/eval.c b/src/eval.c index 4f98b5b..f15251c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -12,7 +12,7 @@ Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* env); 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) @@ -64,36 +64,12 @@ Sexpr* eval(Sexpr* s, Sexpr* dict) { 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; diff --git a/src/test.c b/src/test.c index 3ed70c3..2cc3fd2 100644 --- a/src/test.c +++ b/src/test.c @@ -303,6 +303,10 @@ void eval_tests() { 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)"); } -- 2.39.2