--- /dev/null
+*~
\ No newline at end of file
+
+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
+
+okay! I think I might be able to wing it where you pass a pointer to an object that stores your env, and what it gets passed to is a function that
+
+
+
+major problem now is that I haven't figured out how I want to store the environment? I think that I might have to make a special sort of 'engine' type datastructure, which loads its own 'def' procedure
+
+Oh okay a bonus of that is that I can leave a 'page' of opcodes for doing things with the environment or whatever. I can perhaps open i/o ports that way, or spawn multiple processes, or run gc, or god knows what else
+
+do I even need gc yet? I might just be able to track what I use in time, maybe i'll end up with something more akin to arc?
+potential for avoiding auto-deletion of saved things: clone everything as it's used lol
+
+
OPCODES: each 'page' has 256 diff opts, splits prior to that for maintainability or whatever
OKAY MAIN PROBLEM NOW:
#include "types.h"
#include "sexpr.h"
+#include "dict.h"
// this is where you include whatever extra sets of instructions
#include "builtins/core.h"
+#include <inttypes.h>
+#include <stdio.h>
-Sexpr* apply(Sexpr* b, Sexpr* env) {
+
+Sexpr* dispatch(Sexpr* b, Sexpr* env) {
uint64_t prefix = (b->value.b.opcode) >> 8;
switch(prefix) {
case CORE_PREFIX:
}
}
-Sexpr* append_arg(Sexpr* b, Sexpr* arg) {
- // where b better be a builtin
- Sexpr* ret = malloc(sizeof(Sexpr));
- ret->type = BUILTIN;
- ret->value.b.opcode = b->value.b.opcode;
- ret->value.b.args = cons(arg, b->value.b.args);
- return ret;
+uint64_t u64_get_num_args(Sexpr* b) {
+ uint64_t curr_num = 0;
+ Sexpr* args = b->value.b.args;
+ while(args->type != NIL) {
+ curr_num++;
+ args = cdr(args);
+ }
+ return curr_num;
+}
+
+
+Sexpr* load_into_env(Sexpr* env) {
+ Sexpr* newenv = load_core_env(env);
+ return newenv;
}
#define _HIIIII
-Sexpr* apply(Sexpr* b, Sexpr* env);
-Sexpr* append_arg(Sexpr* b, Sexpr* arg);
+Sexpr* dispatch(Sexpr* b, Sexpr* env);
+uint64_t u64_get_num_args(Sexpr* b);
#endif
#include "../types.h"
+#include "../builtins.h"
#include "../sexpr.h"
#include "../eval.h"
+#include "../dict.h"
+#include "core.h"
-Sexpr* c_quote(Sexpr* args) {
- return car(args);
+#include <inttypes.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);
}
-Sexpr* c_cons(Sexpr* args) {
+
+// redo the rest of these...
+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));
return cons(_car, _cdr);
}
-Sexpr* c_car(Sexpr* args) {
+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));
}
-Sexpr* c_cdr(Sexpr* args) {
+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));
}
-Sexpr* c_if(Sexpr* args) {
+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* truthy = car(cdr(args));
Sexpr* falsy = car(cdr(cdr(args)));
-
+ if(eval(cond, env)->type != NIL)
+ return truthy;
+ else
+ return falsy;
+ // uhhh am I sure about this one?
+ // the lack of evals is perhaps a little suspect...
+}
+Sexpr* c_eq(Sexpr* b, Sexpr* env) {
+ if(CORE_EQ_ARGS != u64_get_num_args(b))
+ return b;
+ 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();
+}
+Sexpr* c_not(Sexpr* b, Sexpr* env) {
+ if(CORE_NOT_ARGS != u64_get_num_args(b))
+ return b;
+ 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();
}
+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)
+ return from_t();
+ return from_nil();
+}
+
-//Sexpr* c_quote(Sexpr* args);
-//Sexpr* c_cons(Sexpr* args);
+Sexpr* x_core_dispatch(Sexpr* b, Sexpr* env) {
+ uint64_t code = b->value.b.opcode & 0xff;
-Sexpr* x_core_dispatch(Sexpr* s, Sexpr* env) {
- uint64_t code = s->value.b.opcode & 0xff;
- Sexpr* args = s->value.b.args;
switch(code) {
- case 0: // quote
- return c_quote(args);
- case 1: // cons
- return c_cons(args);
+ case CORE_QUOTE:
+ return c_quote(b, env);
+ case CORE_CONS:
+ return c_cons(b, env);
+ case CORE_CAR:
+ return c_car(b, env);
+ case CORE_CDR:
+ return c_cdr(b, env);
+ case CORE_IF:
+ return c_if(b, env);
+ case CORE_EQ:
+ return c_eq(b, env);
+ case CORE_NOT:
+ return c_not(b, env);
+ case CORE_ATOM:
+ return c_atom(b, env);
default:
return from_nil();
}
return from_nil();
}
+
+
+Sexpr* load_core_env(Sexpr* env) {
+ Sexpr* c_quote = from_opcode(CORE_QUOTE);
+ append_to_dict(env, from_sym("quote"), c_quote);
+ Sexpr* c_cons = from_opcode(CORE_CONS);
+ append_to_dict(env, from_sym("cons"), c_cons);
+ Sexpr* c_car = from_opcode(CORE_CAR);
+ append_to_dict(env, from_sym("car"), c_car);
+ Sexpr* c_cdr = from_opcode(CORE_CDR);
+ append_to_dict(env, from_sym("cdr"), c_cdr);
+ Sexpr* c_if = from_opcode(CORE_IF);
+ append_to_dict(env, from_sym("if"), c_if);
+ Sexpr* c_eq = from_opcode(CORE_EQ);
+ append_to_dict(env, from_sym("eq"), c_eq);
+ Sexpr* c_not = from_opcode(CORE_NOT);
+ append_to_dict(env, from_sym("not"), c_not);
+ Sexpr* c_atom = from_opcode(CORE_ATOM);
+ append_to_dict(env, from_sym("atom"), c_atom);
+ return env;
+}
+#ifndef _B_CORE_H
+#define _B_CORE_H
#include "../types.h"
#define CORE_PREFIX 0x00
+#define CORE_QUOTE 0x00
+#define CORE_QUOTE_ARGS 1
+#define CORE_CONS 0x01
+#define CORE_CONS_ARGS 2
+#define CORE_CAR 0x02
+#define CORE_CAR_ARGS 1
+#define CORE_CDR 0x03
+#define CORE_CDR_ARGS 1
+#define CORE_IF 0x04
+#define CORE_IF_ARGS 3
+#define CORE_EQ 0x05
+#define CORE_EQ_ARGS 2
+#define CORE_NOT 0x06
+#define CORE_NOT_ARGS 1
+#define CORE_ATOM 0x07
+#define CORE_ATOM_ARGS 1
+
Sexpr* x_core_dispatch(Sexpr* s, Sexpr* env);
+Sexpr* load_core_env(Sexpr* env);
+#endif
// now i need to apply actually
Sexpr* arg = car(cdr(curr));
Sexpr* func = car(curr);
- Sexpr* newcar = apply_builtin(func, arg);
+ 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)
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
+ ret->type = BUILTIN;
+ ret->value.b.opcode = func->value.b.opcode;
+ ret->value.b.args = cons(arg, func->value.b.args);
+
return dispatch(ret, env);
+ // applies if correct no of args, just returns self otherwise
}
--- /dev/null
+#ifndef _EVAL_H
+#define _EVAL_H
+
+#include "types.h"
+#include <inttypes.h>
+#include <string.h>
+
+// everything needed for the dictionary
+
+// 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);
+
+
+
+#endif
--- /dev/null
+
+
+#include <stdio.h>
+
+#include "types.h"
+#include "eval.h"
+#include "dict.h"
+
+
+
+Sexpr* stepl(char* str, Sexpr* env) {
+ Sexpr* toeval = parse(str);
+
+}
+
+int main(int argc, char** argv) {
+ printf("makefile functional\n");
+
+ return 0;
+}
return ret;
}
+Sexpr* from_opcode(uint64_t u) {
+ Sexpr* ret = malloc(sizeof(Sexpr));
+ ret->type = BUILTIN;
+ ret->value.b.opcode = u;
+ ret->value.b.args = from_nil();
+ return ret;
+}
+
Sexpr* cons(Sexpr* car, Sexpr* cdr) {
Cons_t* c = malloc(sizeof(Cons_t));
Sexpr* s = malloc(sizeof(Sexpr));
Sexpr* from_sym(char* s);
Sexpr* from_uint(uint64_t u);
+
+Sexpr* from_opcode(uint64_t u);
Sexpr* cons(Sexpr* car, Sexpr* cdr);
typedef struct Builtin {
struct Sexpr* args;
- uint64_t num_args_needed;
uint64_t opcode;
} Builtin_t;