diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval.c | 89 | ||||
| -rw-r--r-- | src/hashtable.c | 21 | ||||
| -rw-r--r-- | src/hashtable.h | 1 | ||||
| -rw-r--r-- | src/parse.c | 21 | ||||
| -rw-r--r-- | src/parse.h | 3 | ||||
| -rw-r--r-- | src/precedent.c | 3 |
6 files changed, 97 insertions, 41 deletions
@@ -5,16 +5,21 @@ #include "hashtable.h" #include "parse.h" -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}; - -/* TODO: read base hashtable from file to allow modularity -pair value value? */ sym_t* eval(sym_t* symbol, hashtable_t* parentScope) { if (symbol->province == LITERAL) { - return(symbol); + if (symbol->litType == INT) { + return init_sym_int(*((int*)symbol->name)); + } + else if (symbol->litType == FLOAT) { + /* TODO: float */ + return NULL; + } + else if (symbol->litType == STRING) { + return init_sym_str((char*)symbol->name); + } + else { + return NULL; + } } else if (symbol->province == KEY_REF) { sym_t* returnV = NULL; @@ -48,7 +53,7 @@ sym_t* eval(sym_t* symbol, hashtable_t* parentScope) { } } /* clear new scope, then return */ - /* destroy_hashtable(newScope); */ + destroy_hashtable(newScope); return returnV; } else { @@ -58,8 +63,8 @@ sym_t* eval(sym_t* symbol, hashtable_t* parentScope) { } 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]); */ + sym_t* sym = eval(symbols[i], symbolScope); + destroy_sym(sym); } } /* internal functions? @@ -71,6 +76,7 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) { /* 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); + return init_sym_int(0); } /* TODO: rename storel */ else if (hash == get_hash("store")) { @@ -80,56 +86,80 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) { sym_t* v = symbol->args[0]; pair_t p = init_pair(k, (void*)v); hashtable_add_pair(symbolScope->parent, p); - return &trueSym; + return init_sym_int(1); } /* TODO: release()/free() method? */ else if (hash == get_hash("eq")) { litType_t type = NO_TYPE; - void* lastVal = NULL; + int firstInt = 0; + float firstFloat = 0; + char* firstString; for (int i = 0; i < symbol->argCount; i++) { sym_t* v = eval(symbol->args[i], symbolScope); /* initialize */ if (type == NO_TYPE) { type = v->litType; - lastVal = v->name; + if (type == INT) { + firstInt = symtoi(v); + destroy_sym(v); + } + else if (type == FLOAT) { + } + else if (type == STRING) { + firstString = symtos(v); + free(v); + } } else { /* interpret type */ if (type == INT) { - if (symtoi(v) != *((int*)lastVal)) { - return &falseSym; + int si = symtoi(v); + destroy_sym(v); + if (si != firstInt) { + return init_sym_int(0); } } - if (type == STRING) { - if (strcmp(symtos(v), (char*)lastVal) != 0) { - return &falseSym; + /* TODO: float */ + else if (type == FLOAT) { + + } + else if (type == STRING) { + char* ss = symtos(v); + if (strcmp(ss, firstString) != 0) { + destroy_sym(v); + return init_sym_int(0); } + destroy_sym(v); } - /* TODO: float */ } } - return &trueSym; + return init_sym_int(1); } else if (hash == get_hash("if")) { sym_t* v = eval(symbol->args[0], symbolScope); - if (symtoi(v) != 0) { + int si = symtoi(v); + destroy_sym(v); + if (si != 0) { exec_all(symbol->args + 1, symbol->argCount - 1, symbolScope); - return &trueSym; + return init_sym_int(1); } - return &falseSym; + /* TODO: free other args if condition fails */ + return init_sym_int(0); } else if (hash == get_hash("not")) { sym_t* v = eval(symbol->args[0], symbolScope); int b = symtoi(v); - return b ? &falseSym : &trueSym; + destroy_sym(v); + return init_sym_int(!b); } else if (hash == get_hash("sum")) { - int* sum = calloc(1, sizeof(int)); + int sum = 0; for (int i = 0; i < symbol->argCount; i++) { sym_t* v = eval(symbol->args[i], symbolScope); - *sum += symtoi(v); + sum += symtoi(v); + destroy_sym(v); } - return init_sym(LITERAL, INT, sum); + return init_sym_int(sum); } else if (hash == get_hash("print")) { sym_t* v = eval(symbol->args[0], symbolScope); @@ -145,7 +175,8 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) { printf("%s\n", symtos(v)); break; } - return &trueSym; + destroy_sym(v); + return init_sym_int(1); } else { return NULL; diff --git a/src/hashtable.c b/src/hashtable.c index 2506c5b..9a8484d 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -32,15 +32,28 @@ unsigned int get_hash(char* str) { } return hash; } -/* TODO: handle collision -TODO: return 0 if something goes wrong */ unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair) { unsigned int hash = get_hash(pair.key); - hashtable->pairs[hash % hashtable->capacity] = pair; - return hash; + for (int i = 0; i < hashtable->capacity; i++) { + pair_t p = hashtable->pairs[hash % hashtable->capacity]; + if (p.key == NULL || p.key == pair.key) { + hashtable->pairs[hash % hashtable->capacity] = pair; + return hash; + } + } + 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) { + return p; + } + else if (p.key == NULL) { + return init_pair(NULL, NULL); + } + } return hashtable->pairs[(hash) % hashtable->capacity]; } pair_t hashtable_get_pair_recurse(hashtable_t* origin, char* key) { diff --git a/src/hashtable.h b/src/hashtable.h index 3e4d9d9..34751fa 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -14,7 +14,6 @@ typedef struct HashTable { } hashtable_t; hashtable_t* init_hashtable(unsigned int capacity, hashtable_t* parent); void destroy_hashtable(hashtable_t* hashtable); -hashtable_t* clone_hashtable(hashtable_t* hashtable); unsigned int get_hash(char* str); unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair); pair_t hashtable_get_pair(hashtable_t* hashtable, char* key); diff --git a/src/parse.c b/src/parse.c index c7f5e5b..b84a3f6 100644 --- a/src/parse.c +++ b/src/parse.c @@ -13,9 +13,19 @@ sym_t* init_sym(prov_t province, litType_t litType, void* name) { symbol->argCount = 0; return symbol; } +sym_t* init_sym_int(int value) { + int* vp = malloc(sizeof(int)); + *vp = value; + return init_sym(LITERAL, INT, vp); +} +sym_t* init_sym_str(char* value) { + return init_sym(LITERAL, STRING, value); +} void destroy_sym(sym_t* symbol) { free(symbol->name); - free(symbol->args); + if (symbol->argCount > 0) { + free(symbol->args); + } free(symbol); } int symtoi(sym_t* symbol) { @@ -73,17 +83,16 @@ symset_t* parse_symbols(char** str) { sym_t* symbol; /* TODO: float */ /* string */ + /* TODO: more frees in here */ if (isalpha(symbolName[0])) { - //symbolName = realloc(symbolName, i * sizeof(char)); - symbol = init_sym(LITERAL, STRING, symbolName); + //TODO: realloc this + symbol = init_sym_str(symbolName); } /* int */ else { int v = atoi(symbolName); - int* vp = malloc(sizeof(int)); - *vp = v; + symbol = init_sym_int(v); free(symbolName); - symbol = init_sym(LITERAL, INT, vp); } symset_add_symbol(symbolSet, symbol); break; diff --git a/src/parse.h b/src/parse.h index 218f9a1..2a5b68a 100644 --- a/src/parse.h +++ b/src/parse.h @@ -30,6 +30,9 @@ typedef struct SymbolSet { } symset_t; sym_t* init_sym(prov_t province, litType_t litType, void* name); +sym_t* init_sym_int(int value); +sym_t* init_sym_float(float value); +sym_t* init_sym_str(char* value); void destroy_sym(sym_t* symbol); int symtoi(sym_t* symbol); float symtof(sym_t* symbol); diff --git a/src/precedent.c b/src/precedent.c index 7460a0a..c8f4dea 100644 --- a/src/precedent.c +++ b/src/precedent.c @@ -50,7 +50,8 @@ int main(int argc, char** argv) { printf("--END VISUALIZATION--\n"); } hashtable_t* rootTable = init_hashtable(500, NULL); - eval(finalSymbol, rootTable); + sym_t* sym = eval(finalSymbol, rootTable); + destroy_sym(sym); return 0; } char* read_file(char* path) { |
