From 7701a8981c253cd76188999eed920d0e6101cdff Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Sat, 18 Feb 2023 22:29:14 -0800 Subject: added ref() and eval() --- src/eval.c | 61 ++++++++++++++++++++++++++++++++++++++++++------------------- src/eval.h | 1 + 2 files changed, 43 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/eval.c b/src/eval.c index 63305b4..8319676 100644 --- a/src/eval.c +++ b/src/eval.c @@ -36,26 +36,12 @@ sym_t* eval(sym_t* symbol, hashtable_t* parentScope) { pair_t p = hashtable_get_pair_recurse(parentScope, (char*)symbol->name); if (p.key != NULL) { sym_t* nextSym = (sym_t*)p.value; - /* add params */ - sym_t** addedArgs = malloc(100 * sizeof(sym_t*)); - for (int i = 0; i < symbol->argCount && i < 100; i++) { - char* keyName = malloc(6 * sizeof(char)); - strcpy(keyName, "arg"); - char index[3]; - snprintf(index, 3, "%d", i); - strcat(keyName, index); - sym_t* argV = eval(symbol->args[i], parentScope); - addedArgs[i] = argV; - pair_t argPair = init_pair(keyName, argV); - free(keyName); - hashtable_add_pair(newScope, argPair); + if (symbol->argCount > 0) { + returnV = eval_with_args(nextSym, symbol->args, symbol->argCount, newScope); } - returnV = eval(nextSym, newScope); - /* clean up args */ - for (int i = 0; i < symbol->argCount && i < 100; i++) { - destroy_sym(addedArgs[i]); + else { + returnV = eval(nextSym, newScope); } - free(addedArgs); } else { printf("no matching pair in hashtable\n"); @@ -76,6 +62,28 @@ void exec_all(sym_t** symbols, int count, hashtable_t* symbolScope) { destroy_sym(sym); } } +sym_t* eval_with_args(sym_t* symbol, sym_t** args, int argCount, hashtable_t* symbolScope) { + sym_t** addedArgs = malloc(100 * sizeof(sym_t*)); + for (int i = 0; i < argCount && i < 100; i++) { + char* keyName = malloc(6 * sizeof(char)); + strcpy(keyName, "arg"); + char index[3]; + snprintf(index, 3, "%d", i); + strcat(keyName, index); + sym_t* argV = eval(args[i], symbolScope->parent); + addedArgs[i] = argV; + pair_t argPair = init_pair(keyName, argV); + free(keyName); + hashtable_add_pair(symbolScope, argPair); + } + sym_t* v = eval(symbol, symbolScope); + /* clean up args */ + for (int i = 0; i < argCount && i < 100; i++) { + destroy_sym(addedArgs[i]); + } + free(addedArgs); + return v; +} /* internal functions? this function has side-effects */ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) { @@ -86,13 +94,28 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) { exec_all(symbol->args, symbol->argCount - 1, symbolScope); return eval(symbol->args[symbol->argCount - 1], symbolScope); } + else if (hash == get_hash("ref")) { + return symbol->args[0]; + } + else if (hash == get_hash("eval")) { + hashtable_t* newScope = init_hashtable(50, symbolScope); + sym_t* v; + if (symbol->argCount > 1) { + v = eval_with_args(eval(symbol->args[0], symbolScope), symbol->args + 1, symbol->argCount - 1, newScope); + } + else { + v = eval(eval(symbol->args[0], symbolScope), newScope); + } + destroy_hashtable(newScope); + return v; + } else if (hash == get_hash("store")) { /* first arg is value, remaining args are names */ /* TODO: recursion for multiple pairs */ sym_t* v = eval(symbol->args[1], symbolScope); char* k = symtos(v); destroy_sym(v); - sym_t* value = symbol->args[0]; + sym_t* value = eval(symbol->args[0], symbolScope); pair_t p = init_pair(k, (void*)value); free(k); hashtable_add_pair(symbolScope->parent, p); diff --git a/src/eval.h b/src/eval.h index fe1450b..8e551f7 100644 --- a/src/eval.h +++ b/src/eval.h @@ -3,6 +3,7 @@ #define EVAL void throw_e(char* error, int symbolLocale); sym_t* eval(sym_t* symbol, hashtable_t* parentScope); +sym_t* eval_with_args(sym_t* symbol, sym_t** args, int argCount, hashtable_t* symbolScope); void exec_all(sym_t** symbols, int count, hashtable_t* symbolScope); sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope); #endif -- cgit v1.3.1