summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2023-02-16 19:24:20 -0800
committerKai Stevenson <kai@kaistevenson.com>2023-02-16 19:24:20 -0800
commitdeeb6aa4aa60e22190087a9615447e742c84a19c (patch)
tree11d8ae0e6c684ed5a14657a0fb048a28d45be945 /src/eval.c
parent7410d984ae270528ea4f3f16d3473acf807ef92c (diff)
added scoping and a lot of memory leaks
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c66
1 files changed, 35 insertions, 31 deletions
diff --git a/src/eval.c b/src/eval.c
index b1d4e0a..dffd289 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -5,70 +5,74 @@
#include "hashtable.h"
#include "parse.h"
-hashtable_t* ht;
-const int hashtableSize = 1000;
const int trueVal = 1;
sym_t trueSym = {LITERAL, INT, (void*)&trueVal, NULL, 0};
const int falseVal = 0;
sym_t falseSym = {LITERAL, INT, (void*)&falseVal, NULL, 0};
-void init_eval() {
- ht = init_hashtable(hashtableSize);
-}
/* TODO: read base hashtable from file to allow modularity
pair value value? */
-void exec_all(sym_t** symbols, int count) {
- for (int i = 0; i < count; i++) {
- /* dispose of result */
- eval(symbols[i]);
- }
-}
-sym_t* eval(sym_t* symbol) {
+sym_t* eval(sym_t* symbol, hashtable_t* parentScope) {
if (symbol->province == LITERAL) {
return(symbol);
}
else if (symbol->province == KEY_REF) {
- sym_t* ir = try_eval_internal(symbol);
+ sym_t* returnV = NULL;
+ /* entering new scope, so create a new table */
+ hashtable_t* newScope = init_hashtable(500, parentScope);
+ sym_t* ir = try_eval_internal(symbol, newScope);
if (ir != NULL) {
- return ir;
+ returnV = ir;
}
else {
/* not an internal function, search hashtable for
next symbol */
/* TODO: scope */
- pair_t* p = hashtable_get_pair(ht, (char*)symbol->name);
- if (p != NULL) {
- return eval((sym_t*)p->value);
+ pair_t p = hashtable_get_pair_recurse(parentScope, (char*)symbol->name);
+ if (p.key != NULL) {
+ returnV = eval((sym_t*)p.value, newScope);
}
else {
printf("no matching pair in hashtable\n");
- return NULL;
}
}
+ /* clear new scope, then return */
+ destroy_hashtable(newScope);
+ return returnV;
}
else {
printf("no symbol province\n");
return NULL;
}
}
+void exec_all(sym_t** symbols, int count, hashtable_t* symbolScope) {
+ for (int i = 0; i < count; i++) {
+ eval(symbols[i], symbolScope);
+ destroy_sym(symbols[i]);
+ }
+}
/* internal functions?
this function has side-effects */
-sym_t* try_eval_internal(sym_t* symbol) {
+sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) {
unsigned int hash = get_hash((char*)symbol->name);
- /* TODO: return last arg. that's the function return line */
if (hash == get_hash("root")) {
- /* execute all args as roots */
- exec_all(symbol->args, symbol->argCount);
- return &trueSym;
+ /* execute all args as roots except for the last */
+ /* return last arg, that's the function return line */
+ exec_all(symbol->args, symbol->argCount - 1, symbolScope);
+ return eval(symbol->args[symbol->argCount - 1], symbolScope);
+ }
+ else if (hash == get_hash("arg")) {
+ /* get positional arg in current scope */
+ return NULL;
}
else if (hash == get_hash("store")) {
/* TODO: scope */
/* first arg is value, remaining args are names */
/* TODO: recursion for multiple pairs */
- char* k = symtos(eval(symbol->args[1]));
+ char* k = symtos(eval(symbol->args[1], symbolScope));
sym_t* v = symbol->args[0];
- pair_t* p = init_pair(k, (void*)v);
- hashtable_add_pair(ht, p);
+ pair_t p = init_pair(k, (void*)v);
+ hashtable_add_pair(symbolScope->parent, p);
return &trueSym;
}
/* TODO: release()/free() method? */
@@ -76,7 +80,7 @@ sym_t* try_eval_internal(sym_t* symbol) {
litType_t type = NO_TYPE;
void* lastVal = NULL;
for (int i = 0; i < symbol->argCount; i++) {
- sym_t* v = eval(symbol->args[i]);
+ sym_t* v = eval(symbol->args[i], symbolScope);
/* initialize */
if (type == NO_TYPE) {
type = v->litType;
@@ -100,20 +104,20 @@ sym_t* try_eval_internal(sym_t* symbol) {
return &trueSym;
}
else if (hash == get_hash("if")) {
- sym_t* v = eval(symbol->args[0]);
+ sym_t* v = eval(symbol->args[0], symbolScope);
if (symtoi(v) != 0) {
- exec_all(symbol->args + 1, symbol->argCount - 1);
+ exec_all(symbol->args + 1, symbol->argCount - 1, symbolScope);
return &trueSym;
}
return &falseSym;
}
else if (hash == get_hash("not")) {
- sym_t* v = eval(symbol->args[0]);
+ sym_t* v = eval(symbol->args[0], symbolScope);
int b = symtoi(v);
return b ? &falseSym : &trueSym;
}
else if (hash == get_hash("print")) {
- sym_t* v = eval(symbol->args[0]);
+ sym_t* v = eval(symbol->args[0], symbolScope);
switch (v->litType) {
case NO_TYPE:
break;