summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eval.c89
-rw-r--r--src/hashtable.c21
-rw-r--r--src/hashtable.h1
-rw-r--r--src/parse.c21
-rw-r--r--src/parse.h3
-rw-r--r--src/precedent.c3
6 files changed, 97 insertions, 41 deletions
diff --git a/src/eval.c b/src/eval.c
index 45cdde4..45e727a 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -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) {