]> git.eli173.com Git - klapaucius/commitdiff
it works? need to fix some things for sure tho, especially parser
authorElijah Cohen <eli@eli173.com>
Thu, 8 Aug 2024 20:06:27 +0000 (15:06 -0500)
committerElijah Cohen <eli@eli173.com>
Thu, 8 Aug 2024 20:06:27 +0000 (15:06 -0500)
ideas.org
src/builtins.c
src/builtins/arithmetic.c [new file with mode: 0644]
src/builtins/arithmetic.h [new file with mode: 0644]
src/builtins/core.c
src/eval.c
src/repl.c
src/sexpr.c
src/sexpr.h
src/test.c
src/types.h

index 00ca6f737f450ac3650d86fb5cf9040a85da3212..09d6a8739d28ea7ee7dff071c90c912a2520539c 100644 (file)
--- a/ideas.org
+++ b/ideas.org
@@ -1,5 +1,13 @@
 
 
+okay current problem is figuring out the right way to do 'quote'... I think I just need a special thing in my sexpr typedef for a quoted form.. should be easy enough
+
+ALL THE PLACES WHERE I NEED TO GO THROUGH ALL THE TYPES:
+sprint_sexpr
+eval
+
+is that it?
+
 
 shit do i make the env just a consed version of itself then update the car whenever i want a state update? That seems like an iffy but promising idea
 
index 088012cee470f0b89fa0f9096656d3d9db4b9289..f7a576145fc93fc0dd3a0e1dce78de84a32c52d7 100644 (file)
@@ -8,6 +8,7 @@
 // this is where you include whatever extra sets of instructions
 
 #include "builtins/core.h"
+#include "builtins/arithmetic.h"
 
 #include <inttypes.h>
 #include <stdio.h>
@@ -18,6 +19,8 @@ Sexpr* dispatch(Sexpr* b, Sexpr* env) {
        switch(prefix) {
        case CORE_PREFIX:
                return x_core_dispatch(b, env);
+       case ARITH_PREFIX:
+               return x_arith_dispatch(b, env);
        default:
                return from_nil();
        }
@@ -35,6 +38,10 @@ uint64_t u64_get_num_args(Sexpr* b) {
 
 
 Sexpr* load_env(Sexpr* env) {
+       append_to_dict(env, from_sym("nil"), from_nil());
+       append_to_dict(env, from_sym("t"), from_t());
        Sexpr* newenv = load_core_env(env);
+       newenv = load_arith_env(newenv);
+       append_to_dict(env, from_sym("asdf"), from_uint(5455));
        return newenv;
 }
diff --git a/src/builtins/arithmetic.c b/src/builtins/arithmetic.c
new file mode 100644 (file)
index 0000000..c612272
--- /dev/null
@@ -0,0 +1,40 @@
+
+#include "../types.h"
+#include "../builtins.h"
+#include "../sexpr.h"
+#include "../eval.h"
+#include "../dict.h"
+#include "arithmetic.h"
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+
+Sexpr* a_plus(Sexpr* b, Sexpr* env) {
+       if(ARITH_PLUS_ARGS != u64_get_num_args(b)) {
+               return b;
+       }
+       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);
+}
+
+Sexpr* x_arith_dispatch(Sexpr* b, Sexpr* env) {
+       uint64_t code = b->value.b.opcode & 0xff;
+
+       switch(code) {
+       case ARITH_PLUS:
+               return a_plus(b, env);
+       default:
+               return from_nil();
+       }
+       return from_nil();
+}
+
+Sexpr* load_arith_env(Sexpr* env) {
+       Sexpr* a_plus = from_opcode((ARITH_PREFIX << 8) | ARITH_PLUS);
+       append_to_dict(env, from_sym("+"), a_plus);
+
+       return env;
+}
diff --git a/src/builtins/arithmetic.h b/src/builtins/arithmetic.h
new file mode 100644 (file)
index 0000000..6c3fa8f
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _B_ARITH_H
+#define _B_ARITH_H
+
+#include "../types.h"
+
+#define ARITH_PREFIX 0x01
+
+
+#define ARITH_PLUS 0x00
+#define ARITH_PLUS_ARGS 2
+
+Sexpr* x_arith_dispatch(Sexpr* s, Sexpr* env);
+Sexpr* load_arith_env(Sexpr* env);
+
+#endif
index 01b5cc3cc5313782579b8b34c775a3ba9d0290cf..9c4ebf8f76228b4c23904496e087d2a7fe0a37c9 100644 (file)
 #include <inttypes.h>
 #include <stdlib.h>
 
+#include <stdio.h>
+
 Sexpr* c_quote(Sexpr* b, Sexpr* env) {
        if(CORE_QUOTE_ARGS != u64_get_num_args(b))
                return b;
-       return car(b->value.b.args);
+       //return car(b->value.b.args);
+       return from_quote(car(b->value.b.args));
 }
 
 // redo the rest of these...
@@ -21,30 +24,30 @@ Sexpr* c_cons(Sexpr* b, Sexpr* env) {
        if(CORE_CONS_ARGS != u64_get_num_args(b))
                return b;
        Sexpr* args = b->value.b.args;
-       Sexpr* _car = car(args);
-       Sexpr* _cdr = car(cdr(args));
+       Sexpr* _cdr = car(args);
+       Sexpr* _car = car(cdr(args));
        return cons(_car, _cdr);
 }
 Sexpr* c_car(Sexpr* b, Sexpr* env) {
        if(CORE_CAR_ARGS != u64_get_num_args(b))
                return b;
        Sexpr* args = b->value.b.args;
-       return car(car(args));
+       return car(eval(car(args), env));
 }
 Sexpr* c_cdr(Sexpr* b, Sexpr* env) {
        if(CORE_CDR_ARGS != u64_get_num_args(b))
                return b;
        Sexpr* args = b->value.b.args;
-       return cdr(car(args));
+       return cdr(eval(car(args), env));
 }
 Sexpr* c_if(Sexpr* b, Sexpr* env) {
        if(CORE_IF_ARGS != u64_get_num_args(b))
                return b;
        Sexpr* args = b->value.b.args;
        
-       Sexpr* cond = car(args);
+       Sexpr* falsy = car(args);
        Sexpr* truthy = car(cdr(args));
-       Sexpr* falsy = car(cdr(cdr(args)));
+       Sexpr* cond = car(cdr(cdr(args)));
        if(eval(cond, env)->type != NIL)
                return truthy;
        else
@@ -76,19 +79,26 @@ Sexpr* c_atom(Sexpr* b, Sexpr* env) {
        if(CORE_ATOM_ARGS != u64_get_num_args(b))
                return b;
        Sexpr* args = b->value.b.args;
-       // need eval here for same reasons as not
-       if(eval(car(args), env)->type != CONS)
+       Sexpr* argeval = eval(car(args), env);
+       while(argeval->type == QUOTE) {
+               argeval = argeval->value.q;
+       }
+       if(argeval->type != CONS) {
                return from_t();
+       }
        return from_nil();
 }
 
 
 Sexpr* c_def(Sexpr* b, Sexpr* env) {
-       if(CORE_ATOM_ARGS != u64_get_num_args(b))
+       if(CORE_DEF_ARGS != u64_get_num_args(b))
                return b;
        Sexpr* args = b->value.b.args;
-       Sexpr* val = eval(car(cdr(args)), env);
-       append_to_dict(env, car(args), cdr(args));
+       Sexpr* val = eval(car(args), env);
+       Sexpr* key = car(cdr(args));
+       printf("val: %s\n", sprint_sexpr(val));
+       printf("key: %s\n", sprint_sexpr(key));
+       append_to_dict(env, key, val);
        return val;
 }
 Sexpr* c_exit(Sexpr* b, Sexpr* env) {
@@ -122,6 +132,8 @@ Sexpr* x_core_dispatch(Sexpr* b, Sexpr* env) {
                return c_atom(b, env);
        case CORE_DEF:
                return c_def(b, env);
+       case CORE_EXIT:
+               return c_exit(b, env);
        default:
                return from_nil();
        }
@@ -148,5 +160,7 @@ Sexpr* load_core_env(Sexpr* env) {
        append_to_dict(env, from_sym("atom"), c_atom);
        Sexpr* c_def = from_opcode(CORE_DEF);
        append_to_dict(env, from_sym("def"), c_def);
+       Sexpr* c_exit = from_opcode(CORE_EXIT);
+       append_to_dict(env, from_sym("exit"), c_exit);
        return env;
 }
index 534f3e6dd481bc935fc11428c9f69e60334b037e..b4a16183be0b18bdd2639a296f50bbfd58048461 100644 (file)
 Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* env);
 
 Sexpr* eval(Sexpr* s, Sexpr* dict) {
+       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?
        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 car(lookup(dict, s));
+               Sexpr* lookedup = lookup(dict, s);
+               if(lookedup->type == NIL) {
+                       printf("%s not defined\n", s->value.s);
+                       return lookedup;
+               }
+               return car(lookedup);
        }
        if(s->type != CONS) {
                return s;
        } // from now on: type is cons
+       //printf("idk\n");
        Sexpr* curr = s;
        while(curr->type == CONS) {
                if(cdr(curr)->type == NIL)
@@ -28,10 +35,11 @@ Sexpr* eval(Sexpr* s, Sexpr* dict) {
                        return car(curr);
                if(cdr(curr)->type != CONS)
                        // need to redo, how do i eval "(f . x)" ?
-                       return car(curr);
+                       // ^ easy, just return (f . x)
+                       return curr;
                // now i need to apply actually
                Sexpr* arg = car(cdr(curr));
-               Sexpr* func = car(curr);
+               Sexpr* func = eval(car(curr), dict);
                Sexpr* newcar = apply_builtin(func, arg, dict);
                Sexpr* newcdr = cdr(cdr(curr));
                curr = cons(newcar, newcdr);
@@ -40,9 +48,10 @@ Sexpr* eval(Sexpr* s, Sexpr* dict) {
 }
 
 Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* env) {
-       if(func->type != BUILTIN)
+       if(func->type != BUILTIN) {
+               printf("uh oh\n");
                return from_nil(); // uhh this /should/ actually be impossible...
-
+       }
        Sexpr* ret = malloc(sizeof(Sexpr));
        ret->type = BUILTIN;
        ret->value.b.opcode = func->value.b.opcode;
index 94ebb17b9a651fdfb36ea69f3335237434386ba4..5329ccd41c94af52ac5723de6f7f5d87b285f0d8 100644 (file)
@@ -15,7 +15,6 @@
 
 
 int main(int argc, char** argv) {
-       printf("makefile functional lol\n");
 
        Sexpr* env = init_dict();
        load_env(env);
@@ -26,8 +25,14 @@ int main(int argc, char** argv) {
                if(input == NULL)
                        return 0;
                linenoiseHistoryAdd(input);
+               printf("asdf1\n");
                Sexpr* in = parse(input);
-               Sexpr* out = eval(in, env);
+               printf("asdf2\n");
+               if(in == NULL) {
+                       printf("bad input\n");
+               }
+               printf("- -%s\n", sprint_sexpr(in));
+               Sexpr* out = eval(car(in), env);
                printf(" - %s\n", sprint_sexpr(out));
                linenoiseFree(input);
        }
index 14e7fdb4ef596ae9179caf602bd982a2c12466f8..e2d4652825751f729d298f6a0f0c29bfccbd04f3 100644 (file)
@@ -45,6 +45,13 @@ Sexpr* from_opcode(uint64_t u) {
        return ret;
 }
 
+Sexpr* from_quote(Sexpr* s) {
+       Sexpr* ret = malloc(sizeof(Sexpr));
+       ret->type = QUOTE;
+       ret->value.q = s;
+       return ret;
+}
+
 Sexpr* cons(Sexpr* car, Sexpr* cdr) {
        Cons_t* c = malloc(sizeof(Cons_t));
        Sexpr* s = malloc(sizeof(Sexpr));
@@ -71,9 +78,18 @@ Sexpr* equal(Sexpr* a, Sexpr* b) {
                return from_t();
        if(t == T)
                return from_t();
-       if(t == SYM) {
+       if(t == SYM)
                return strcmp(a->value.s, b->value.s) == 0 ? from_t() : from_nil();
-       }
+       if(t == UINT)
+               return (a->value.u == b->value.u) ? from_t() : from_nil();
+       if(t == BUILTIN)
+               if(a->value.b.opcode == b->value.b.opcode)
+                       return equal(a->value.b.args, b->value.b.args);
+       if(t == QUOTE)
+               return equal(a->value.q, b->value.q);
+       if(t == CONS)
+               if(equal(car(a), car(b))->type == T)
+                       return equal(cdr(a), cdr(b));
        // leaving everything else off for... reasons
        return from_nil();
 }
@@ -135,8 +151,11 @@ char* sprint_sexpr(Sexpr* s) {
                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;
+               snprintf(out + 1, nbytes, "%" PRIu64 "", s->value.u);
+               return out;             
+       }
+       else if(s->type == QUOTE) {
+               return sprint_sexpr(s->value.q);
        }
        else if(s->type == CONS) {
                Sexpr* curr_cell = s;
index 89460910eaef3195752e47c7c19fc09048f23966..274dd3e9a261d511335b8ef5b76dbd84b7409b47 100644 (file)
@@ -8,6 +8,7 @@ Sexpr* from_t();
 Sexpr* from_sym(char* s);
 Sexpr* from_uint(uint64_t u);
 Sexpr* from_opcode(uint64_t u);
+Sexpr* from_quote(Sexpr* s);
        
 Sexpr* cons(Sexpr* car, Sexpr* cdr);
 Sexpr* car(Sexpr* s);
index 3fc6d14fa71253efb5d4cf09b9574560b80db81a..f11ee3727eca2ca54d74518f59000503e5ef2552 100644 (file)
@@ -65,6 +65,7 @@ void test_parser() {
        printf("_: %s\n", sprint_sexpr(parse("457")));
        printf("_: %s\n", sprint_sexpr(parse("a b c d e")));
        printf("_: %s\n", sprint_sexpr(parse("(a b (3 2 (5) c) d (e f) g)")));
+       //printf("_: %s\n", sprint_sexpr(parse("(457")));
 }
 
 void test_eq() {
index d1e30c44281a028e53612cd0e64a4e9dd1c1a8ca..4d2e6c184fe78b79ae894be80388bacbf66543a6 100644 (file)
@@ -12,7 +12,7 @@ typedef void* Nil_t;
 typedef void* Truth_t;
 
 typedef enum Sexpr_Type {
-       UINT, SYM, BUILTIN, NIL, T, CONS
+       UINT, SYM, BUILTIN, NIL, T, CONS, QUOTE
 } Sexpr_Type; 
 
 typedef struct Cons {
@@ -35,6 +35,7 @@ typedef struct Sexpr {
                Cons_t* c;
                Nil_t n;
                Truth_t t;
+               struct Sexpr* q;
        } value;
 } Sexpr;