]> git.eli173.com Git - klapaucius/commitdiff
made dubious changes to eval structure
authorElijah Cohen <eli@eli173.com>
Mon, 12 Aug 2024 05:52:02 +0000 (00:52 -0500)
committerElijah Cohen <eli@eli173.com>
Mon, 12 Aug 2024 05:52:02 +0000 (00:52 -0500)
ideas.org
src/builtins.c
src/builtins.h
src/builtins/arithmetic.c
src/builtins/arithmetic.h
src/builtins/core.c
src/builtins/core.h
src/dict.c
src/eval.c
src/eval.h

index c8b9514738129bbcde038072f4c4d39c9a4f235a..9690f46af620b9139787bdf9dd37efb19f114a32 100644 (file)
--- a/ideas.org
+++ b/ideas.org
@@ -1,3 +1,9 @@
+
+so i'm redoing the basic eval to not pass an arg, but pass the rest of the list... yeah?
+then the builtins just harvest the rest one at a time to get all their args,
+and when executed can modify the rest? cool sounds good and worthwhile
+
+
 GARBAGE COLLECTION
 my grand design is that I will allocate and deallocate all the time, that is, if I 'def' something I keep it, but dereferencing something clones the thing, and then any call using it frees it again.
 is that too slow? yeah probably
index f7a576145fc93fc0dd3a0e1dce78de84a32c52d7..90cf1c157a2cb4b35512869f109393b8ca17b4be 100644 (file)
 #include <stdio.h>
 
 
-Sexpr* dispatch(Sexpr* b, Sexpr* env) {
+Sexpr* dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) {
        uint64_t prefix = (b->value.b.opcode) >> 8;
        switch(prefix) {
        case CORE_PREFIX:
-               return x_core_dispatch(b, env);
+               return x_core_dispatch(b, rest, env);
        case ARITH_PREFIX:
-               return x_arith_dispatch(b, env);
+               return x_arith_dispatch(b, rest, env);
        default:
                return from_nil();
        }
index 51b1aabe4ef05e59355acd3ca0f69346f703f9f5..c20e829f00c300d3e12304ecf2bf07da34f6ddbb 100644 (file)
@@ -5,7 +5,7 @@
 
 #include "builtins/core.h"
 
-Sexpr* dispatch(Sexpr* b, Sexpr* env);
+Sexpr* dispatch(Sexpr* b, Sexpr* rest, Sexpr* env);
 uint64_t u64_get_num_args(Sexpr* b);
 Sexpr* load_env(Sexpr* env);
 
index c612272b545754d63629d0e1343f6caed78b9c4c..8a04be59c4c2a280d6a9f06e8235f402631001f0 100644 (file)
 #include <stdlib.h>
 
 
-Sexpr* a_plus(Sexpr* b, Sexpr* env) {
+Sexpr* a_plus(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(ARITH_PLUS_ARGS != u64_get_num_args(b)) {
-               return b;
+               return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
        uint64_t m = eval(car(args), env)->value.u;
        uint64_t n = eval(car(cdr(args)), env)->value.u;
-       return from_uint(m + n);
+       return cons(from_uint(m + n), rest);
 }
 
-Sexpr* x_arith_dispatch(Sexpr* b, Sexpr* env) {
+Sexpr* x_arith_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) {
        uint64_t code = b->value.b.opcode & 0xff;
 
        switch(code) {
        case ARITH_PLUS:
-               return a_plus(b, env);
+               return a_plus(b, rest, env);
        default:
                return from_nil();
        }
index 6c3fa8f7e9b234c2ebce07418e67446f465b4e31..bbfa4f015f69600b3141408a38f951f0906b5a79 100644 (file)
@@ -9,7 +9,7 @@
 #define ARITH_PLUS 0x00
 #define ARITH_PLUS_ARGS 2
 
-Sexpr* x_arith_dispatch(Sexpr* s, Sexpr* env);
+Sexpr* x_arith_dispatch(Sexpr* s, Sexpr* rest, Sexpr* env);
 Sexpr* load_arith_env(Sexpr* env);
 
 #endif
index 244ba494804e2005c0e3bf284bfb9a7a6165b42e..99eb17c7ab8e14fd240155e3923a18ad302ecfb2 100644 (file)
 
 #include <stdio.h>
 
-Sexpr* c_quote(Sexpr* b, Sexpr* env) {
+Sexpr* c_quote(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_QUOTE_ARGS != u64_get_num_args(b))
-               return b;
+               return cons(b, rest);
        //return car(b->value.b.args);
-       return from_quote(car(b->value.b.args));
+       return cons(from_quote(car(b->value.b.args)), rest);
 }
 
 // redo the rest of these...
-Sexpr* c_cons(Sexpr* b, Sexpr* env) {
+Sexpr* c_cons(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_CONS_ARGS != u64_get_num_args(b))
-               return b;
+               return cons(b, rest);
        Sexpr* args = b->value.b.args;
        Sexpr* _cdr = eval(car(args), env);
        Sexpr* _car = eval(car(cdr(args)), env);
-       return cons(_car, _cdr);
+       return cons(cons(_car, _cdr), rest);
 }
-Sexpr* c_car(Sexpr* b, Sexpr* env) {
+Sexpr* c_car(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_CAR_ARGS != u64_get_num_args(b))
-               return b;
+               return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       return car(eval(car(args), env));
+       // huh okay, can i ditch the eval now that i'm doing the 'rest' thing?
+       return cons(car(eval(car(args), env)), rest);
 }
-Sexpr* c_cdr(Sexpr* b, Sexpr* env) {
+Sexpr* c_cdr(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_CDR_ARGS != u64_get_num_args(b))
-               return b;
+               return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       return cdr(eval(car(args), env));
+       // see above
+       return cons(cdr(eval(car(args), env)), rest);
 }
-Sexpr* c_if(Sexpr* b, Sexpr* env) {
+Sexpr* c_if(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_IF_ARGS != u64_get_num_args(b))
-               return b;
+               return cons(b, rest);
        Sexpr* args = b->value.b.args;
        
        Sexpr* falsy = car(args);
        Sexpr* truthy = car(cdr(args));
        Sexpr* cond = car(cdr(cdr(args)));
        if(eval(cond, env)->type != NIL)
-               return truthy;
+               return cons(truthy, rest);
        else
-               return falsy;
-       // uhhh am I sure about this one?
-       // the lack of evals is perhaps a little suspect...
+               return cons(falsy, rest);
 }
-Sexpr* c_eq(Sexpr* b, Sexpr* env) {
+Sexpr* c_eq(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_EQ_ARGS != u64_get_num_args(b))
-               return b;
+               return cons(b, rest);
        Sexpr* args = b->value.b.args;
        // yeah eval is kinda necessary for this one I'd say
        Sexpr* lh = eval(car(args), env);
        Sexpr* rh = eval(car(cdr(args)), env);
        if(equal(lh, rh)->type == T)
-               return from_t();
-       return from_nil();
+               return cons(from_t(), rest);
+       return cons(from_nil(), rest);
 }
-Sexpr* c_not(Sexpr* b, Sexpr* env) {
-               if(CORE_NOT_ARGS != u64_get_num_args(b))
-               return b;
+Sexpr* c_not(Sexpr* b, Sexpr* rest, Sexpr* env) {
+       if(CORE_NOT_ARGS != u64_get_num_args(b))
+               return cons(b, rest);
        Sexpr* args = b->value.b.args;
        // I guess I would need the eval to check if eventually is nil
        if(eval(car(args), env)->type == NIL)
-               return from_t();
-       return from_nil();
+               return cons(from_t(), rest);
+       return cons(from_nil(), rest);
 }
-Sexpr* c_atom(Sexpr* b, Sexpr* env) {
+Sexpr* c_atom(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_ATOM_ARGS != u64_get_num_args(b))
-               return b;
+               return cons(b, rest);
        Sexpr* args = b->value.b.args;
        Sexpr* argeval = eval(car(args), env);
        while(argeval->type == QUOTE) {
                argeval = argeval->value.q;
        }
        if(argeval->type != CONS) {
-               return from_t();
+               return cons(from_t(), rest);
        }
-       return from_nil();
+       return cons(from_nil(), rest);
 }
 
 
-Sexpr* c_def(Sexpr* b, Sexpr* env) {
+Sexpr* c_def(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_DEF_ARGS != u64_get_num_args(b))
-               return b;
+               return cons(b, rest);
        Sexpr* args = b->value.b.args;
        Sexpr* val = eval(car(args), env);
        Sexpr* key = car(cdr(args));
        append_to_dict(env, key, val);
-       return val;
+       return cons(val, rest);
 }
-Sexpr* c_exit(Sexpr* b, Sexpr* env) {
+Sexpr* c_exit(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_EXIT_ARGS != u64_get_num_args(b))
-               return b;
+               return cons(b, rest);
        Sexpr* args = b->value.b.args;
        uint64_t value = car(args)->value.u;
        exit(value);
        return NULL;
 }
 
-Sexpr* x_core_dispatch(Sexpr* b, 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, env);
+               return c_quote(b, rest, env);
        case CORE_CONS:
-               return c_cons(b, env);
+               return c_cons(b, rest, env);
        case CORE_CAR:
-               return c_car(b, env);
+               return c_car(b, rest, env);
        case CORE_CDR:
-               return c_cdr(b, env);
+               return c_cdr(b, rest, env);
        case CORE_IF:
-               return c_if(b, env);
+               return c_if(b, rest, env);
        case CORE_EQ:
-               return c_eq(b, env);
+               return c_eq(b, rest, env);
        case CORE_NOT:
-               return c_not(b, env);
+               return c_not(b, rest, env);
        case CORE_ATOM:
-               return c_atom(b, env);
+               return c_atom(b, rest, env);
        case CORE_DEF:
-               return c_def(b, env);
+               return c_def(b, rest, env);
        case CORE_EXIT:
-               return c_exit(b, env);
+               return c_exit(b, rest, env);
        default:
                return from_nil();
        }
index c85342e074d46674ec12552bbb8da5ab3785426a..72cb4210605057766d13891ca54c22f7e1218ffb 100644 (file)
@@ -30,7 +30,7 @@
 #define CORE_EXIT 0xff
 #define CORE_EXIT_ARGS 1
 
-Sexpr* x_core_dispatch(Sexpr* s, Sexpr* env);
+Sexpr* x_core_dispatch(Sexpr* s, Sexpr* rest, Sexpr* env);
 Sexpr* load_core_env(Sexpr* env);
 
 #endif
index 92c088de14caac2b9c2e4bc8e9cadf6abfec42cc..c28498e84c863973ad5a96af8a697c9f78254c7e 100644 (file)
@@ -23,7 +23,8 @@ Sexpr* init_dict() {
 Sexpr* append_to_dict(Sexpr* dict, Sexpr* key, Sexpr* value) {
        // assumes dict well-formed, returns new dict
        // puts new things on the front of the dict, makes it so looking up gets the newest stuff first
-       Sexpr* new = cons(key, value);
+       Sexpr* new = cons(key, clone(value));
+       // not yet sure if the above 'clone' is needed, or where the call should take place
        Sexpr* head = cons(new, car(dict));
        dict->value.c->car = head;
        //return cons(new, dict);
@@ -36,7 +37,8 @@ Sexpr* lookup(Sexpr* dict, Sexpr* key) {
        Sexpr* node = car(dict);
                while(node->type != NIL) {
                        if(equal(key, car(car(node)))->type == T) {
-                               return cons(cdr(car(node)), from_nil());
+                               Sexpr* value = clone(cdr(car(node)));
+                               return cons(value, from_nil());
                        }
                        node = cdr(node);
        }
index 031fb2522140aa140f67e9bd56190aa636f8d130..cb99014e490d10bfdb1396b14e61e47eb64b44f3 100644 (file)
@@ -10,7 +10,7 @@
 Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* env);
 
 Sexpr* eval(Sexpr* s, Sexpr* dict) {
-       //printf("s: %s\n", sprint_sexpr(s));
+       printf("s: %s\n", sprint_sexpr(s));
        // 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?
@@ -29,23 +29,25 @@ Sexpr* eval(Sexpr* s, Sexpr* dict) {
        } // from now on: type is cons
        Sexpr* curr = s;
        while(curr->type == CONS) {
-               if(cdr(curr)->type == NIL)
+               if(cdr(curr)->type == NIL) // this is okay to keep, yeah
                        return eval(car(curr), dict);
                if(cdr(curr)->type != CONS)
                        // need to redo, how do i eval "(f . x)" ?
                        // ^ easy, just return (f . x)
                        return curr;
                // now i need to apply actually
-               Sexpr* arg = car(cdr(curr));
+               //Sexpr* arg = car(cdr(curr));
+               Sexpr* rest = cdr(curr);
                Sexpr* func = eval(car(curr), dict);
-               Sexpr* newcar = apply_builtin(func, arg, dict);
-               Sexpr* newcdr = cdr(cdr(curr));
-               curr = cons(newcar, newcdr);
+               //Sexpr* newcar = apply_builtin(func, arg, dict);
+               //Sexpr* newcdr = cdr(cdr(curr));
+               curr = apply_builtin(func, rest, dict); // is this ok?
+               //curr = cons(newcar, newcdr);
        }
        return curr;
 }
 
-Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* 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...
@@ -53,8 +55,8 @@ Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* env) {
        Sexpr* ret = malloc(sizeof(Sexpr));
        ret->type = BUILTIN;
        ret->value.b.opcode = func->value.b.opcode;
-       ret->value.b.args = cons(arg, func->value.b.args);
+       ret->value.b.args = cons(car(rest), func->value.b.args);
        
-       return dispatch(ret, env);
+       return dispatch(ret, cdr(rest), env);
        // applies if correct no of args, just returns self otherwise
 }
index db625cc23242626c608e331e8de41abeb434d2a2..358df0832ad56cae9a3d37e818ebb56780f3758b 100644 (file)
@@ -10,7 +10,7 @@
 // key type is string, value type is sexpr, hash range is uint64_t
 
 Sexpr* eval(Sexpr* s, Sexpr* env);
-Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* env);
+Sexpr* apply_builtin(Sexpr* func, Sexpr* rest, Sexpr* env);