LDFLAGS:= -g -Wall `pkg-config $(LIBRARIES) --libs`
-#$(BUILD)/lex.yy.o: lisp.l
-#lex -o $(BUILD)/lex.yy.c lisp.l
-
-#$(BUILD)/y.tab.o: lisp.y
-# yacc -defines lisp.y
-
-#y.tab.h: lisp.y
-# yacc -d lisp.y
-
-
$(BUILD)/$(BIN): $(OBJS)
$(CC) $(BIN_OBJS) $(LDFLAGS) -o $(BUILD)/$(BIN)
$(OBJS): $(BUILD)/%.o:%.c Makefile
+ mkdir -p $(BUILD)/builtins
$(CC) -c $< -MMD -o $@ $(CFLAGS)
#include "sexpr.h"
#include "dict.h"
-
// this is where you include whatever extra sets of instructions
#include "builtins/core.h"
#include "builtins/combinators.h"
#include <inttypes.h>
-#include <stdio.h>
Sexpr* dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) {
}
}
-
Sexpr* dispatch_others(Sexpr* b, Sexpr* rest, Sexpr* env) {
// this is for applying other types,
// i.e. doing
return b;
}
else if(b->type == UINT) {
- // the hard one
uint64_t anx = (CORE_PREFIX << 8) | CORE_APPLYN;
Sexpr* idk = from_opcode(anx);
Sexpr* ret = cons(idk, cons(clone(b), rest));
return from_nil();
}
-
uint64_t u64_get_num_args(Sexpr* b) {
uint64_t curr_num = 0;
Sexpr* args = b->value.b.args;
newenv = load_core_env(env);
newenv = load_arith_env(newenv);
newenv = load_comb_env(newenv);
- //append_to_dict(env, from_sym("asdf"), from_uint(5455));
+
return newenv;
}
#include "../types.h"
-#define ARITH_PREFIX 0x01
+#define ARITH_PREFIX 0x02
#define ARITH_ADD 0x00
}
Sexpr* args = b->value.b.args;
Sexpr* x = clone(car(cdr(args)));
- //Sexpr* y = clone(car(args)); // not needed
sexpr_free(b);
return cons(x, rest);
}
#include "../types.h"
-#define COMB_PREFIX 0x02
+#define COMB_PREFIX 0x01
#define COMB_I 0x00
#define COMB_I_ARGS 1
if(_car->type == QUOTE)
_car = _car->value.q;
Sexpr* ret = cons(from_quote(cons(clone(_car),clone(_cdr))), rest);
- //return cons(from_quote(cons(_car, _cdr)), rest);
sexpr_free(raw_car);
sexpr_free(raw_cdr);
sexpr_free(b);
Sexpr* args = b->value.b.args;
Sexpr* unqargev = eval(clone(car(args)), env);
Sexpr* ret = cons(from_quote(clone(cdr(unquote(unqargev)))), rest);
- //Sexpr* arg = unquote(eval(car(args), env));
- //return cons(from_quote(cdr(arg)), rest);
sexpr_free(unqargev);
sexpr_free(b);
return ret;
return cons(b, rest);
Sexpr* args = b->value.b.args;
- //Sexpr* falsy = car(args);
- //Sexpr* truthy = car(cdr(args));
Sexpr* cond = eval(clone(car(cdr(cdr(args)))), env);
if(unquote(cond)->type != NIL) {
Sexpr* truthy = clone(car(cdr(args)));
// possible commentary for the future:
// i may wish to rewrite to eval (f x)
// then return something like ((n-1) f x)
+ // OOPS I NEED to actually eval
+ // and not just macroexpand, for memory reasons
if(CORE_APPLYN_ARGS != u64_get_num_args(b))
return cons(b, rest);
Sexpr* args = b->value.b.args;
Sexpr* ret = cons(arg, from_nil());
while(num > 0) {
ret = cons(clone(fun), cons(ret, from_nil()));
+ ret = eval(ret, env);
num--;
}
sexpr_free(b);
#include "sexpr.h"
#include "dict.h"
-#include <stdio.h>
-
-
// IMMENSE WARNING: as of now this is the only place where any sort of variable is modified in place.. that may come to pass more later, but beware
// okay, doing an incredibly /incredibly/ naive dict implementation for now,
// proper hash tables come later
-// wait, this naive method can totally just be done in sexprs that I already have
-
-
// great redo: have it in a cons cell, so I can modify it without having to return anything
Sexpr* init_dict() {
// 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(clone(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);
return dict;
}
// everything needed for the dictionary
-// key type is string, value type is sexpr, hash range is uint64_t
-
Sexpr* init_dict();
Sexpr* append_to_dict(Sexpr* dict, Sexpr* key, Sexpr* value);
Sexpr* lookup(Sexpr* dict, Sexpr* key);
// 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
Sexpr* lookedup = lookup(dict, s);
if(lookedup->type == NIL) {
printf("%s not defined\n", s->value.s);
// now i need to apply actually
//Sexpr* arg = car(cdr(curr));
Sexpr* rest = clone(cdr(curr));
- // wait, where does rest get freed?
Sexpr* func = eval(clone(car(curr)), dict);
sexpr_free(curr);
curr = apply_builtin(func, rest, dict); // is this ok?
- //sexpr_free(rest);
sexpr_free(func);
}
return curr;
}
-
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...
return dispatch_others(func, rest, env);
}
Sexpr* ret = malloc(sizeof(Sexpr));
#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* rest, Sexpr* env);
-
-
#endif
Sexpr* vals_parse(Sexpr* tokens) {
- // should only accept a singly-linked list of symbols
+ // should only accept a non-nested list of symbols
// note: may also reverse
Sexpr* out = from_nil();
Sexpr* next = NULL;
}
curr = cdr(curr);
}
- //printf("b: %d\n", balance);
return balance == 0;
}
Sexpr* cons_parse(Sexpr* tokens) {
Sexpr* reversedptr = reverse(tokens);
Sexpr* reversed = reversedptr;
- // takes results from previous parsing ops, aka the forward-facing?
Sexpr* heads_stack = from_nil();
Sexpr* curr_head = from_nil();
Sexpr* curr_car;
Sexpr* parse(char* s) {
- //printf("s: %s\n", s);
Sexpr* tokens = tokenize(s);
- //printf("t: %s\n", sprint_sexpr(tokens));
Sexpr* vals = vals_parse(tokens);
sexpr_free(tokens);
- //printf("v: %s\n", sprint_sexpr(vals));
if(!balance_checker(vals)) {
printf("unbalanced parenthesis\n");
sexpr_free(vals);
return NULL;
}
- //printf("v1: %s\n", sprint_sexpr(vals));
Sexpr* done = cons_parse(vals);
- //printf("v2: %s\n", sprint_sexpr(vals));
sexpr_free(vals);
- //printf("c: %s\n", sprint_sexpr(*done));
return done;
}
#include <stdio.h>
#include <stdlib.h>
-//#include <histedit.h>
#include <editline/readline.h>
#include "builtins.h"
#include "sexpr.h"
-// huh?
-
int main(int argc, char** argv) {
Sexpr* env = init_dict();
load_env(env);
- // now do the loop, right?
+
char* input = NULL;
while(1) {
input = readline("> ");
return s;
}
-
-// wait uh oh, do I do the quote-unquote thing here or in builtins/core?
Sexpr* car(Sexpr* s) {
if(s->type == QUOTE)
return from_quote(s->value.q->value.c->car);
}
Sexpr* equal(Sexpr* a, Sexpr* b) {
- // need to change later with proper builtins and so forth
if(a->type != b->type)
return from_nil();
Sexpr_Type t = a->type;
return equal(cdr(a), cdr(b));
}
}
- // leaving everything else off for... reasons
return from_nil();
}
strcpy(out, s->value.s);
return out;
}
- /*
- else if(s->type == FUN) {
- out = malloc(6*sizeof(char));
- strcpy(out, "<fun>");
- return out;
- }
- else if(s->type == FEXP) {
- out = malloc(7*sizeof(char));
- strcpy(out, "<fexp>");
- return out;
- }
- */
else if(s->type == UINT) {
nbytes = snprintf(NULL, 0, "%" PRIu64 "", s->value.u) + 1;
out = malloc(nbytes*sizeof(char));