Some env.c refactoring and clean-up

This commit is contained in:
= 2020-08-04 20:26:47 +01:00
parent b92768c5ec
commit d87322b6a5
1 changed files with 24 additions and 37 deletions

View File

@ -24,6 +24,7 @@ Object fetchFromEnvironment(const char *name, struct Environment *env)
printd("Try %d (NULL)\n", i); printd("Try %d (NULL)\n", i);
break; break;
} }
printd("Try %d (%s)\n", i, env->strings[i]); printd("Try %d (%s)\n", i, env->strings[i]);
debugObj(&env->objects[i]); debugObj(&env->objects[i]);
if(strcmp(name, env->strings[i]) == 0) { if(strcmp(name, env->strings[i]) == 0) {
@ -34,7 +35,6 @@ Object fetchFromEnvironment(const char *name, struct Environment *env)
printd("Trying outer %p\n", env->outer); printd("Trying outer %p\n", env->outer);
if(env->outer) { if(env->outer) {
// printEnv(env->outer);
return fetchFromEnvironment(name, env->outer); return fetchFromEnvironment(name, env->outer);
} }
@ -71,12 +71,11 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms,
return env; return env;
} }
// todo could include and return a starting index for faster multi-adds // TODO Maybe extend environment using a new outer, instead of realloc
// Maybe extend existing environment using a malloc'd outer, instead of realloc
void addToEnv(struct Environment *env, const char *name, const Object obj) void addToEnv(struct Environment *env, const char *name, const Object obj)
{ {
int i; int i;
for(i = 0; i < env->size ; i++) { for(i = 0; i < env->size; i++) {
if(env->strings[i] == NULL) { if(env->strings[i] == NULL) {
env->strings[i] = calloc(sizeof(char), strlen(name) + 1); env->strings[i] = calloc(sizeof(char), strlen(name) + 1);
strncpy(env->strings[i], name, strlen(name)); strncpy(env->strings[i], name, strlen(name));
@ -163,53 +162,41 @@ const char *codes[] = {
// Return the smaller of the two // Return the smaller of the two
"(def min (fn (a b) (if (< a b) a b)))", "(def min (fn (a b) (if (< a b) a b)))",
// Arbitrary recursion tester
"(def ad (fn (a) (if (> a 10) a (ad (* 10 a) ))))",
// A demo tip calculator // A demo tip calculator
"(def spent (fn (a) \ "(def spent (fn (a) \
(cat \"Tip: $\" (/ a 5) \".\" \ (cat \"Tip: $\" (/ a 5) \".\" \
(/ (* 100 (% a 5)) 5) \ (/ (* 100 (% a 5)) 5) \
) \ ) \
))", ))",
};
"(def r (fn (L) \ struct symFunc {
(if (= L () \ const char *sym;
", Object (*func)(Object, Object, struct Environment*);
NULL
}; };
struct Environment defaultEnv() struct Environment defaultEnv()
{ {
struct Environment e; struct Environment e = {
e.outer = NULL; .outer = NULL,
e.strings = calloc(sizeof(char*), MAX_ENV_ELM); .strings = calloc(sizeof(char*), MAX_ENV_ELM),
e.objects = malloc(sizeof(Object) * MAX_ENV_ELM); .objects = malloc(sizeof(Object) * MAX_ENV_ELM),
e.size = MAX_ENV_ELM; .size = MAX_ENV_ELM
};
#define af(S, F) addFunc(S, F, &e) struct symFunc symFuncs[] = {
af("+", &add); af("-", &sub); {"+", &add}, {"-", &sub}, {"*", &mul}, {"/", &dvi}, {"%", &mod},
af("*", &mul); af("/", &dvi); {"=", &equ}, {">", &gth}, {"<", &lth},
af("%", &mod); {"cat", &catObjects}, {"fil", &filter}, {"len", &len}, {"ap", &append},
{"at", &at}, {"rest", &rest}, {"rev", &reverse},
};
af("=", &equ); for(int i = 0; i < sizeof(symFuncs)/sizeof(symFuncs[0]); i++) {
af(">", &gth); addFunc(symFuncs[i].sym, symFuncs[i].func, &e);
af("<", &lth); }
af("cat", &catObjects); for(int i = 0; i < sizeof(codes)/sizeof(codes[0]); i++) {
af("fil", &filter); parseEval(codes[i], &e);
af("len", &len);
af("ap", &append);
af("at", &at);
af("rest", &rest);
af("rev", &reverse);
#undef af
int i = 0;
while(codes[i]) {
parseEval(codes[i++], &e);
} }
return e; return e;