]> git.eli173.com Git - klapaucius/commitdiff
some infra for builtins, mostly commit before makefile changes
authorElijah Cohen <eli@eli173.com>
Wed, 24 Jul 2024 00:26:30 +0000 (19:26 -0500)
committerElijah Cohen <eli@eli173.com>
Wed, 24 Jul 2024 00:26:30 +0000 (19:26 -0500)
ideas.org
src/builtins.c [new file with mode: 0644]
src/builtins.h [new file with mode: 0644]
src/builtins/core.c [new file with mode: 0644]
src/builtins/core.h [new file with mode: 0644]
src/dict.c
src/eval.c
src/sexpr.c
src/test.c
src/types.h

index 3b6a1e7634388bf47ff3da0d54dea8026a1ffd11..f2dc0997b0a4452da3901e9c75c4d335e8f0c3ae 100644 (file)
--- a/ideas.org
+++ b/ideas.org
@@ -1,4 +1,20 @@
 
+
+OPCODES: each 'page' has 256 diff opts, splits prior to that for maintainability or whatever
+
+OKAY MAIN PROBLEM NOW:
+for the builtins, I need to literally clone them all the time whenever I need a new one, or else the args pointer stays the same and it effects other calls of the function
+solution! I just initialize to null, and make a clone when I need to I guess
+
+
+NOTE ON HOW I ACTUALLY INTEND TO DO THIS
+THIS REFERRING TO HANDLING EVALUATIONS OF BUILTINS
+I think maybe a struct storing the opcode and a pointer to a sexpr representing a list of args might be the way to do it, plus a uint for num of args?
+
+also I want each individual opcode to decide whether or not and how to evaluate its own arguments
+
+
+
 So this is a poorly-named directory, since what I'm making will end up being a lisp-1...
 
 thinking about taking ideas from concatenative languages, tacit programming, and the such.
diff --git a/src/builtins.c b/src/builtins.c
new file mode 100644 (file)
index 0000000..74ddec4
--- /dev/null
@@ -0,0 +1,20 @@
+
+
+#include "types.h"
+#include "sexpr.h"
+
+
+// this is where you include whatever extra sets of instructions
+
+#include "builtins/core.h"
+
+
+Sexpr* dispatch(Sexpr* b) {
+       uint64_t prefix = (b->value.b.opcode) >> 8;
+       switch(prefix) {
+       case CORE_PREFIX:
+               return x_core_dispatch(b);
+       default:
+               return from_nil();
+       }
+}
diff --git a/src/builtins.h b/src/builtins.h
new file mode 100644 (file)
index 0000000..cc110c3
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _BUILTINS_H
+#define _BUILTINS_H
+
+#include "types.h"
+
+#include "builtins/core.h"
+
+#define _HIIIII
+
+Sexpr* dispatch(Sexpr* b);
+
+
+
+#endif
diff --git a/src/builtins/core.c b/src/builtins/core.c
new file mode 100644 (file)
index 0000000..8e08682
--- /dev/null
@@ -0,0 +1,18 @@
+
+
+#include "../types.h"
+#include "../sexpr.h"
+#include "../eval.h"
+
+
+
+Sexpr* x_core_dispatch(Sexpr* s) {
+       uint64_t code = s->value.b.opcode & 0xff;
+       switch(code) {
+       case 0: // quote
+               
+       default:
+               return from_nil();
+       }
+       return from_nil();
+}
diff --git a/src/builtins/core.h b/src/builtins/core.h
new file mode 100644 (file)
index 0000000..7f941e0
--- /dev/null
@@ -0,0 +1,11 @@
+
+
+#include "../types.h"
+
+// need to define
+
+#define CORE_PREFIX 0x00
+
+
+Sexpr* x_core_dispatch(Sexpr* s);
+
index fc2053e3c445af288d5fadce8122106379da1e29..dd5aa4fb8efa2fa1c221cbbdcb73f6865c91d45d 100644 (file)
@@ -23,10 +23,11 @@ Sexpr* append_to_dict(Sexpr* dict, Sexpr* key, Sexpr* value) {
 
 Sexpr* lookup(Sexpr* dict, Sexpr* key) {
        // assumes dict well-formed
+       // returns nil if not found, returns (result) if it is
        Sexpr* node = dict;
                while(node->type != NIL) {
                        if(equal(key, car(car(node)))->type == T) {
-                               return cdr(car(node));
+                               return cons(cdr(car(node)), from_nil());
                        }
                        node = cdr(node);
        }
index 9d68efe174f8ee8c91199dc09f288e13440d1468..a28fd07881edfb5d046c8e006de89b0bd217a03e 100644 (file)
@@ -4,23 +4,60 @@
 
 #include "types.h"
 #include "sexpr.h"
+#include "dict.h"
+#include "builtins.h"
 
+Sexpr* apply_builtin(Sexpr* func, Sexpr* arg);
 
-Sexpr* eval(Sexpr* s) {
+Sexpr* eval(Sexpr* s, Sexpr* dict) {
        // non-null s
        // generally assumes that a sexpr passed to this is well-formed (ie no inapt NULLS)
        // question: does a completed builtin get evaluated here?
        if(s == NULL) return NULL; // not needed if assumptions accurate, but yknow
        if(s->type == SYM) {
                // look up the value in the lookup table
-               return s;
+               return car(lookup(dict, s));
        }
        if(s->type != CONS) {
                return s;
        } // from now on: type is cons
-       if(cdr(s) == NULL) {
-               return car(s);
-       } // from now on: a function of some sort is being called
+       Sexpr* curr = s;
+       while(curr->type == CONS) {
+               if(cdr(curr)->type == NIL)
+                       //return eval(car(curr), dict);
+                       return car(curr);
+               if(cdr(curr)->type != CONS)
+                       // need to redo, how do i eval "(f . x)" ?
+                       return car(curr);
+               // now i need to apply actually
+               Sexpr* arg = car(cdr(curr));
+               Sexpr* func = car(curr);
+               Sexpr* newcar = apply_builtin(func, arg);
+               Sexpr* newcdr = cdr(cdr(curr));
+               curr = cons(newcar, newcdr);
+       }
+       return curr;
+}
 
-       return NULL;
+Sexpr* apply_builtin(Sexpr* func, Sexpr* arg) {
+       if(func->type != BUILTIN)
+               return from_nil(); // uhh this /should/ actually be impossible...
+       uint8_t num_args = 0;
+       Sexpr* curr = func->value.b.args;
+       while(curr->type != NIL) {
+               curr = cdr(curr);
+               num_args++;
+       }
+       Sexpr* ret = malloc(sizeof(Sexpr));
+       if(num_args < func->value.b.num_args_needed) {
+               ret->type = BUILTIN;
+               ret->value.b.opcode = func->value.b.opcode;
+               ret->value.b.num_args_needed = func->value.b.num_args_needed;
+               ret->value.b.args = cons(arg, func->value.b.args);
+       }
+       if(num_args+1 < func->value.b.num_args_needed)
+               return ret;
+       // what's left now: all the args needed are there,
+       // just gotta dispatch to whatever handles the opcode evals
+       return dispatch(ret);
 }
index 126b1248c370372de425f9f881e6cf5e7a720df9..fbe49940fd4427948205c745e3075d31dd3b8fe5 100644 (file)
@@ -63,7 +63,6 @@ Sexpr* equal(Sexpr* a, Sexpr* b) {
                return from_t();
        if(t == T)
                return from_t();
-
        if(t == SYM) {
                return strcmp(a->value.s, b->value.s) == 0 ? from_t() : from_nil();
        }
@@ -122,6 +121,13 @@ char* sprint_sexpr(Sexpr* s) {
                snprintf(out, nbytes, "%" PRIu64 "", s->value.u);
                return out;
        }
+       else if(s->type == BUILTIN) {
+               nbytes = snprintf(NULL, 0, "%" PRIu64 "", s->value.u) + 2;
+               out = malloc(nbytes*sizeof(char));
+               out[0] = '_';
+               snprintf(out, nbytes+1, "%" PRIu64 "", s->value.u);
+               return out;
+       }
        else if(s->type == CONS) {
                Sexpr* curr_cell = s;
                size_t currsize = 2;
index 550e6fb9fb9ae8d9bb4dd20302fe5a503f34542e..8cd28c8691bab2fcdbdd989001e0aa4833e6760d 100644 (file)
@@ -6,7 +6,7 @@
 #include "sexpr.h"
 #include "parser.h"
 #include "dict.h"
-
+#include "eval.h"
 
 
 
index b5a881a1cecf55f581338f8e94b7010c420b6cce..caf34848f00014050ae06d441afbfd52651af0ce 100644 (file)
@@ -11,6 +11,7 @@
 typedef char* Symbol_t;
 typedef void* Nil_t;
 typedef void* Truth_t;
+//typedef uint64_t Builtin_t;
 
 typedef enum Sexpr_Type {
        UINT, SYM, BUILTIN, NIL, T, CONS, FEXP, FUN
@@ -21,6 +22,12 @@ typedef struct Cons {
        struct Sexpr* cdr;
 } Cons_t;
 
+typedef struct Builtin {
+       struct Sexpr* args;
+       uint64_t num_args_needed;
+       uint64_t opcode;
+} Builtin_t;
+
 typedef struct Closure {
        uint64_t opcode;
        uint64_t num_args;
@@ -36,6 +43,7 @@ typedef struct Sexpr {
                Fexpr_t x;
                Fun_t f;
                uint64_t u;
+               Builtin_t b;
                Symbol_t s;
                Cons_t* c;
                Nil_t n;