+
+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.
--- /dev/null
+
+
+#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();
+ }
+}
--- /dev/null
+#ifndef _BUILTINS_H
+#define _BUILTINS_H
+
+#include "types.h"
+
+#include "builtins/core.h"
+
+#define _HIIIII
+
+Sexpr* dispatch(Sexpr* b);
+
+
+
+#endif
--- /dev/null
+
+
+#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();
+}
--- /dev/null
+
+
+#include "../types.h"
+
+// need to define
+
+#define CORE_PREFIX 0x00
+
+
+Sexpr* x_core_dispatch(Sexpr* s);
+
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);
}
#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);
}
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();
}
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;
#include "sexpr.h"
#include "parser.h"
#include "dict.h"
-
+#include "eval.h"
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
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;
Fexpr_t x;
Fun_t f;
uint64_t u;
+ Builtin_t b;
Symbol_t s;
Cons_t* c;
Nil_t n;