From d789cf9a2fc418cb0eac71ed2eec147b1c1b17a5 Mon Sep 17 00:00:00 2001 From: Elijah Cohen Date: Fri, 27 Sep 2024 17:29:08 -0500 Subject: [PATCH] added print function, added command line file loading, added a file I forgot to add last time lol --- src/builtins.c | 4 ++++ src/builtins/io.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/builtins/io.h | 16 ++++++++++++++++ src/config.h | 21 +++++++++++++++++++++ src/repl.c | 9 +++++++++ src/util.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/util.h | 11 +++++++++++ 7 files changed, 145 insertions(+) create mode 100644 src/builtins/io.c create mode 100644 src/builtins/io.h create mode 100644 src/config.h create mode 100644 src/util.c create mode 100644 src/util.h diff --git a/src/builtins.c b/src/builtins.c index 6edb70c..b775e85 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -9,6 +9,7 @@ #include "builtins/core.h" #include "builtins/arithmetic.h" #include "builtins/combinators.h" +#include "builtins/io.h" #include @@ -22,6 +23,8 @@ Sexpr* dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) { return x_arith_dispatch(b, rest, env); case COMB_PREFIX: return x_comb_dispatch(b, rest, env); + case IO_PREFIX: + return x_io_dispatch(b, rest, env); default: return from_nil(); } @@ -100,6 +103,7 @@ Sexpr* load_env(Sexpr* env) { newenv = load_core_env(env); newenv = load_arith_env(newenv); newenv = load_comb_env(newenv); + newenv = load_io_env(newenv); return newenv; } diff --git a/src/builtins/io.c b/src/builtins/io.c new file mode 100644 index 0000000..fd9ff06 --- /dev/null +++ b/src/builtins/io.c @@ -0,0 +1,42 @@ + + +#include "../types.h" +#include "../builtins.h" +#include "../sexpr.h" +#include "../config.h" +#include "io.h" + +#include +#include + +Sexpr* io_print(Sexpr* b, Sexpr* rest, Sexpr* env) { + if(IO_PRINT_ARGS != u64_get_num_args(b)) { + return cons(b, rest); + } + Sexpr* arg = clone(car(b->value.b.args)); + sexpr_free(b); + char* out = sprint_sexpr(arg); + sexpr_free(arg); + PRINT(out); + free(out); + return cons(from_t(), rest); +} + + +Sexpr* x_io_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) { + uint64_t code = b->value.b.opcode & 0xff; + + switch(code) { + case IO_PRINT: + return io_print(b, rest, env); + default: + return from_nil(); + } + return from_nil(); +} + +Sexpr* load_io_env(Sexpr* env) { + load_builtin("print", (IO_PREFIX << 8) | IO_PRINT, env); + + return env; +} diff --git a/src/builtins/io.h b/src/builtins/io.h new file mode 100644 index 0000000..2cb627e --- /dev/null +++ b/src/builtins/io.h @@ -0,0 +1,16 @@ +#ifndef _B_IO_H +#define _B_IO_H + +#include "../types.h" + +#define IO_PREFIX 0x03 + +#define IO_PRINT 0x00 +#define IO_PRINT_ARGS 1 + +Sexpr* x_io_dispatch(Sexpr* s, Sexpr* rest, Sexpr* env); +Sexpr* load_io_env(Sexpr* env); + + + +#endif diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..cc19f22 --- /dev/null +++ b/src/config.h @@ -0,0 +1,21 @@ +#ifndef _CONFIG_H +#define _CONFIG_H + + +// configuration file for various compile-time things +// i.e. uint size, so on + + + +#include + +#define K_UINT_TYPE uint64_t +#define K_UINT_PRINT PRIu64 +#define K_UINT_SCAN SCNu64 + +#define WARN(m, v) printf("WARN: %s%s\n", m, v) +#define ERR(m, v) printf("ERROR: %s%s\n", m, v) +#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 db3e492..c5d9e93 100644 --- a/src/repl.c +++ b/src/repl.c @@ -2,6 +2,7 @@ #include #include +//#include #include @@ -11,6 +12,7 @@ #include "parser.h" #include "builtins.h" #include "sexpr.h" +#include "util.h" int main(int argc, char** argv) { @@ -18,6 +20,13 @@ int main(int argc, char** argv) { Sexpr* env = init_dict(); 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--; + } + char* input = NULL; while(1) { input = readline("> "); diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..5f2b842 --- /dev/null +++ b/src/util.c @@ -0,0 +1,42 @@ + +// this file exists becaause I didn't know where else to put the load_file function... + +#include +#include + +#include "types.h" +#include "sexpr.h" +#include "eval.h" +#include "builtins.h" +#include "parser.h" + +Sexpr* load_file(Sexpr* env, char* path) { + char* buf; + size_t len; + FILE* f = fopen(path, "r"); + if(f) { + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + buf = malloc(len+1); + if(buf) { + fread(buf, 1, len, f); + buf[len] = '\n'; // deals with no newline at end shenanigans + } + fclose(f); + if(buf) { + // file loaded into buf + // wait i forget how my dealloc works with this stuff, gonna have to play with it + Sexpr* in = parse(buf); + free(buf); + if(in==NULL) return env; + Sexpr* curr = in; + // okay, the file is likely a bunch of (def ...)s, so i need to eval this expression by expression + while(curr->type != NIL) { + eval(clone(car(curr)), env); + curr = cdr(curr); + } + } + } + return env; +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..ff7b284 --- /dev/null +++ b/src/util.h @@ -0,0 +1,11 @@ +#ifndef _UTIL_H +#define _UTIL_H + +#include "types.h" + +Sexpr* load_file(Sexpr* env, char* path); + + + + +#endif -- 2.39.2