diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2023-02-18 22:29:14 -0800 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2023-02-18 22:29:14 -0800 |
| commit | 7701a8981c253cd76188999eed920d0e6101cdff (patch) | |
| tree | 4127060488f9d590237249b435d9ec08d99a01ac /src/eval.c | |
| parent | 552cb9bf439b9094c0ecc6b2ade0b70a926be7bb (diff) | |
added ref() and eval()
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 61 |
1 files changed, 42 insertions, 19 deletions
@@ -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); |
