+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
// this is where you include whatever extra sets of instructions
#include "builtins/core.h"
+#include "builtins/arithmetic.h"
#include <inttypes.h>
#include <stdio.h>
switch(prefix) {
case CORE_PREFIX:
return x_core_dispatch(b, env);
+ case ARITH_PREFIX:
+ return x_arith_dispatch(b, env);
default:
return from_nil();
}
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;
}
--- /dev/null
+
+#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;
+}
--- /dev/null
+#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
#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...
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
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) {
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();
}
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;
}
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)
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);
}
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;
int main(int argc, char** argv) {
- printf("makefile functional lol\n");
Sexpr* env = init_dict();
load_env(env);
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);
}
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));
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();
}
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;
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);
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() {
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 {
Cons_t* c;
Nil_t n;
Truth_t t;
+ struct Sexpr* q;
} value;
} Sexpr;