From 6a4b05a4dcef9da60a47af0054bdf745c0588802 Mon Sep 17 00:00:00 2001 From: Elijah Cohen Date: Fri, 25 Oct 2024 15:43:00 -0500 Subject: [PATCH] added histfile support, added 'rest' builtin, couple of examples --- demos.kl | 17 +++++++++++++++-- src/builtins/core.c | 21 +++++++++++++++++++++ src/builtins/core.h | 5 ++++- src/config.h | 1 + src/repl.c | 30 ++++++++++++++++++++++++++++-- 5 files changed, 69 insertions(+), 5 deletions(-) diff --git a/demos.kl b/demos.kl index 2f1e5ec..f26bb66 100644 --- a/demos.kl +++ b/demos.kl @@ -1,8 +1,7 @@ (def D (B B)) -(def fachelp (D S (C (eq 0) 1) (D S * (C B (C - 1))))) -(def fac (Z fachelp)) +(def fac (Z (D S (C (eq 0) 1) (D S * (C B (C - 1)))))) (def rh (B B S (S (B (eq 0) car) cdr) (C B (Phi cons (B (C - 1) car) (Phi cons car cdr))))) @@ -10,3 +9,17 @@ (def fph (B (S (Phi (eq nil) cdr car)) (C B (Phi cons (Phi + car (B car cdr)) (B cdr cdr))))) +(def reverse (B (Z (B (S (S (B (eq nil) cdr) car)) (C B (Phi cons (Phi cons (B car cdr) car) (B cdr cdr))))) (cons nil))) + +(def maphelp (B (S (S (B (eq nil) (B cdr cdr)) (B car cdr)) (C B (S (B cons car) (S (cons (Phi cons (S car (B car (B cdr cdr))) (B car cdr))) (B cdr (B cdr cdr)))))))) + +(def nth-bad (B B B (Z (B (S (S (B (eq 1) car) (B car cdr))) (C B (Phi cons (C (B - car) 1) (B cdr cdr))))) cons)) + +(def nth (B (B car) (B (C I cdr) (C - 1)))) + +(def list (rest I)) + +(def maphelp (B (S (S (B (eq nil) (3 cdr)) (B car cdr))) (C B (Phi cons car (Phi cons (Phi cons (S car (B car (3 cdr))) (B car cdr)) (4 cdr)))))) + + +(def CC (B (C B (C B cdr)) (B (Phi cons) (C B car)))) diff --git a/src/builtins/core.c b/src/builtins/core.c index b365e6b..8d2aefc 100644 --- a/src/builtins/core.c +++ b/src/builtins/core.c @@ -144,6 +144,24 @@ Sexpr* c_atom(Sexpr* b, Sexpr* rest, Sexpr* env) { return cons(from_nil(), rest); } +Sexpr* c_rest(Sexpr* b, Sexpr* rest, Sexpr* env) { + // what kind of name is rest? need to reconsider + // but am making this a bit broader than it might need to be + // but this is the variadic thing, takes the first argument, + // and applies it to the rest + // e.g. (rest (nth 5) 1 2 3 4 5 6) -> 5 + // !! also! this is weird and takes two args so as to not trigger when trying to define things(?) + // i.e. (def list (rest I)) works this way rather than the more straightforward implementation + if(CORE_REST_ARGS != u64_get_num_args(b)) + return cons(b, rest); + Sexpr* args = b->value.b.args; + Sexpr* first_arg = eval(clone(car(cdr(args))), env); + Sexpr* second_arg = clone(car(args)); // uhh no eval? nah don't think so + Sexpr* newrest = cons(second_arg, rest); + sexpr_free(b); + return cons(first_arg, cons(from_quote(newrest), from_nil())); +} + Sexpr* c_applyn(Sexpr* b, Sexpr* rest, Sexpr* env) { // possible commentary for the future: @@ -214,6 +232,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_REST: + return c_rest(b, rest, env); case CORE_APPLYN: return c_applyn(b, rest, env); case CORE_DEF: @@ -236,6 +256,7 @@ Sexpr* load_core_env(Sexpr* env) { load_builtin(CORE_EQ_STR, (CORE_PREFIX << 8) | CORE_EQ, env); load_builtin(CORE_NOT_STR, (CORE_PREFIX << 8) | CORE_NOT, env); load_builtin(CORE_ATOM_STR, (CORE_PREFIX << 8) | CORE_ATOM, env); + load_builtin(CORE_REST_STR, (CORE_PREFIX << 8) | CORE_REST, env); load_builtin(CORE_DEF_STR, (CORE_PREFIX << 8) | CORE_DEF, env); load_builtin(CORE_EXIT_STR, (CORE_PREFIX << 8) | CORE_EXIT, env); diff --git a/src/builtins/core.h b/src/builtins/core.h index 0d6e8cc..401aa6f 100644 --- a/src/builtins/core.h +++ b/src/builtins/core.h @@ -32,8 +32,11 @@ #define CORE_ATOM 0x07 #define CORE_ATOM_ARGS 1 #define CORE_ATOM_STR "atom" +#define CORE_REST 0x08 +#define CORE_REST_ARGS 2 +#define CORE_REST_STR "rest" -#define CORE_APPLYN 0x08 +#define CORE_APPLYN 0x0f #define CORE_APPLYN_ARGS 3 #define CORE_APPLYN_STR "applyn" diff --git a/src/config.h b/src/config.h index 7e78c16..ed60a69 100644 --- a/src/config.h +++ b/src/config.h @@ -18,4 +18,5 @@ #define PRINTMV(m, v) printf("%s%s\n", m, v) #define PRINT(s) printf("%s\n", s) + #endif diff --git a/src/repl.c b/src/repl.c index c5d9e93..0654c30 100644 --- a/src/repl.c +++ b/src/repl.c @@ -2,6 +2,7 @@ #include #include +#include //#include #include @@ -13,7 +14,7 @@ #include "builtins.h" #include "sexpr.h" #include "util.h" - +#include "config.h" int main(int argc, char** argv) { @@ -21,11 +22,28 @@ int main(int argc, char** argv) { load_env(env); while(argc > 1) { - printf("ac/av: %d, %s\n", argc, argv[argc-1]); // lol am i loading files back to front? env = load_file(env, argv[argc-1]); argc--; } + + // now i load the history? + char* histfile = getenv("HOME"); + strcat(histfile, "/.config/klhist"); + FILE* f = fopen(histfile, "r"); + if(f) { + size_t s; + char* line = NULL; + while (getline(&line, &s, f) != -1) { + add_history(line); + free(line); + line = NULL; + } + fclose(f); + } + else { + printf("no histfile!?!?!?\n"); + } char* input = NULL; while(1) { @@ -33,6 +51,13 @@ int main(int argc, char** argv) { if(input == NULL) return 0; add_history(input); + // add to histfile here + f = fopen(histfile, "a"); + if(f) { + fprintf(f, "%s", input); + fclose(f); + } + // Sexpr* in = parse(input); if(in == NULL) { ERR("bad input\n", ""); @@ -49,5 +74,6 @@ int main(int argc, char** argv) { } free(input); } + free(histfile); return 0; } -- 2.39.2