diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval.c | 24 | ||||
| -rw-r--r-- | src/hashtable.c | 14 | ||||
| -rw-r--r-- | src/hashtable.h | 1 | ||||
| -rw-r--r-- | src/parse.c | 8 |
4 files changed, 43 insertions, 4 deletions
@@ -86,7 +86,6 @@ 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); } - /* TODO: rename storel */ else if (hash == get_hash("store")) { /* first arg is value, remaining args are names */ /* TODO: recursion for multiple pairs */ @@ -99,6 +98,18 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) { hashtable_add_pair(symbolScope->parent, p); return init_sym_int(1); } + else if (hash == get_hash("update")) { + /* 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]; + pair_t p = init_pair(k, (void*)value); + free(k); + hashtable_update_pair_recurse(symbolScope->parent, p); + return init_sym_int(1); + } /* TODO: release()/free() method? */ else if (hash == get_hash("eq")) { litType_t type = NO_TYPE; @@ -175,6 +186,17 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) { } return init_sym_int(sum); } + else if (hash == get_hash("sub")) { + sym_t* v1 = eval(symbol->args[0], symbolScope); + int sum = symtoi(v1); + destroy_sym(v1); + for (int i = 1; i < symbol->argCount; i++) { + sym_t* v = eval(symbol->args[i], symbolScope); + sum -= symtoi(v); + destroy_sym(v); + } + return init_sym_int(sum); + } else if (hash == get_hash("print")) { sym_t* v = eval(symbol->args[0], symbolScope); if (v->litType == INT) { diff --git a/src/hashtable.c b/src/hashtable.c index 3a83861..2ec766d 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -49,18 +49,28 @@ unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair) { unsigned int hash = get_hash(pair.key); for (int i = 0; i < hashtable->capacity; i++) { pair_t p = hashtable->pairs[hash % hashtable->capacity]; - if (p.key == NULL || p.key == pair.key) { + if (p.key == NULL || strcmp(p.key, pair.key) == 0) { hashtable->pairs[hash % hashtable->capacity] = pair; return hash; } } return 0; } +unsigned int hashtable_update_pair_recurse(hashtable_t* origin, pair_t pair) { + pair_t p = hashtable_get_pair(origin, pair.key); + if (p.key != NULL) { + return hashtable_add_pair(origin, pair); + } + if (origin->parent != NULL) { + return hashtable_update_pair_recurse(origin->parent, pair); + } + return 0; +} pair_t hashtable_get_pair(hashtable_t* hashtable, char* key) { unsigned int hash = get_hash(key); for (int i = 0; i < hashtable->capacity; i++) { pair_t p = hashtable->pairs[hash % hashtable->capacity]; - if (p.key == key) { + if (p.key != NULL && strcmp(p.key, key) == 0) { return p; } else if (p.key == NULL) { diff --git a/src/hashtable.h b/src/hashtable.h index 34751fa..6f0dc51 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -16,6 +16,7 @@ hashtable_t* init_hashtable(unsigned int capacity, hashtable_t* parent); void destroy_hashtable(hashtable_t* hashtable); unsigned int get_hash(char* str); unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair); +unsigned int hashtable_update_pair_recurse(hashtable_t* origin, pair_t pair); pair_t hashtable_get_pair(hashtable_t* hashtable, char* key); pair_t hashtable_get_pair_recurse(hashtable_t* origin, char* key); diff --git a/src/parse.c b/src/parse.c index 0144f44..79c1dc4 100644 --- a/src/parse.c +++ b/src/parse.c @@ -104,7 +104,13 @@ symset_t* parse_symbols(char** str) { } /* int */ else { - int v = atoi(symbolName); + int v; + if (symbolName[0] == '-') { + v = atoi(symbolName + 1) * -1; + } + else { + v = atoi(symbolName); + } symbol = init_sym_int(v); } symset_add_symbol(symbolSet, symbol); |
