summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hashtable.c15
-rw-r--r--src/parse.c49
-rw-r--r--src/parse.h3
-rw-r--r--src/precedent.c2
4 files changed, 57 insertions, 12 deletions
diff --git a/src/hashtable.c b/src/hashtable.c
index 9a8484d..3a83861 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -8,7 +8,14 @@ const unsigned int fnvOffset = 2166136261U;
pair_t init_pair(char* key, void* value) {
pair_t p;
- p.key = key;
+ if (key != NULL) {
+ char* kp = malloc((strlen(key) + 1) * sizeof(char));
+ strcpy(kp, key);
+ p.key = kp;
+ }
+ else {
+ p.key = NULL;
+ }
p.value = value;
return p;
}
@@ -20,6 +27,12 @@ hashtable_t* init_hashtable(unsigned int capacity, hashtable_t* parent) {
return ht;
}
void destroy_hashtable(hashtable_t* hashtable) {
+ /* TODO: optimize this */
+ for (int i = 0; i < hashtable->capacity; i++) {
+ if (hashtable->pairs[i].key != NULL) {
+ free(hashtable->pairs[i].key);
+ }
+ }
free(hashtable->pairs);
free(hashtable);
}
diff --git a/src/parse.c b/src/parse.c
index b84a3f6..4aafc32 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -13,13 +13,20 @@ sym_t* init_sym(prov_t province, litType_t litType, void* name) {
symbol->argCount = 0;
return symbol;
}
+sym_t* init_sym_key(char* value) {
+ char* vp = malloc((strlen(value) + 1) * sizeof(char));
+ strcpy(vp, value);
+ return init_sym(KEY_REF, NO_TYPE, vp);
+}
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);
+ char* vp = malloc((strlen(value) + 1) * sizeof(char));
+ strcpy(vp, value);
+ return init_sym(LITERAL, STRING, vp);
}
void destroy_sym(sym_t* symbol) {
free(symbol->name);
@@ -28,6 +35,20 @@ void destroy_sym(sym_t* symbol) {
}
free(symbol);
}
+void destroy_sym_tree(sym_t* origin) {
+ if (origin->province == KEY_REF) {
+ /* doesn't follow user-defined refs */
+ if (is_internal((char*)origin->name)) {
+ for (int i = 0; i < origin->argCount; i++) {
+ destroy_sym_tree(origin->args[i]);
+ }
+ destroy_sym(origin);
+ }
+ }
+ else if (origin->province == LITERAL) {
+ destroy_sym(origin);
+ }
+}
int symtoi(sym_t* symbol) {
return *((int*)symbol->name);
}
@@ -37,7 +58,6 @@ float symtof(sym_t* symbol) {
char* symtos(sym_t* symbol) {
return (char*)symbol->name;
}
-
void symbol_add_arg(sym_t* symbol, sym_t* arg) {
symbol->argCount += 1;
if (symbol->argCount == 1) {
@@ -92,7 +112,6 @@ symset_t* parse_symbols(char** str) {
else {
int v = atoi(symbolName);
symbol = init_sym_int(v);
- free(symbolName);
}
symset_add_symbol(symbolSet, symbol);
break;
@@ -102,13 +121,10 @@ symset_t* parse_symbols(char** str) {
symbolName[i] = '\0';
sym_t* symbol;
if (i > 1) {
- symbol = init_sym(KEY_REF, NO_TYPE, symbolName);
+ symbol = init_sym_key(symbolName);
}
else {
- free(symbolName);
- char* memName = malloc(5 * sizeof(char));
- strcpy(memName, "root");
- symbol = init_sym(KEY_REF, NO_TYPE, memName);
+ symbol = init_sym_key("root");
}
symset_t* symbols = parse_symbols(str);
for (int s = 0; s < symbols->count; s++) {
@@ -120,20 +136,31 @@ symset_t* parse_symbols(char** str) {
i++;
(*str)++;
}
+ free(symbolName);
}
}
sym_t* parse_symbol_final(char* str) {
char** strp = malloc(sizeof(char**));
*strp = str;
symset_t* finalSymset = parse_symbols(strp);
- char* memName = malloc(5 * sizeof(char));
- strcpy(memName, "root");
- sym_t* root = init_sym(KEY_REF, NO_TYPE, memName);
+ free(strp);
+ sym_t* root = init_sym_key("root");
for (int s = 0; s < finalSymset->count; s++) {
symbol_add_arg(root, finalSymset->symbols[s]);
}
return root;
}
+/* TODO: improve this system */
+int is_internal(char* name) {
+ unsigned int hash = get_hash(name);
+ if (hash == get_hash("root") || hash == get_hash("store")
+ || hash == get_hash("eq") || hash == get_hash("if")
+ || hash == get_hash("not") || hash == get_hash("sum")
+ || hash == get_hash("print")) {
+ return 1;
+ }
+ return 0;
+}
void write_symbol_visual(sym_t* symbol, int offset) {
for (int o = 0; o < offset; o++) {
printf(" ");
diff --git a/src/parse.h b/src/parse.h
index 2a5b68a..b25e719 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -30,10 +30,12 @@ typedef struct SymbolSet {
} symset_t;
sym_t* init_sym(prov_t province, litType_t litType, void* name);
+sym_t* init_sym_key(char* value);
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);
+void destroy_sym_tree(sym_t* origin);
int symtoi(sym_t* symbol);
float symtof(sym_t* symbol);
char* symtos(sym_t* symbol);
@@ -41,6 +43,7 @@ void symbol_add_arg(sym_t* symbol, sym_t* arg);
void symset_add_symbol(symset_t* symbolSet, sym_t* symbol);
symset_t* parse_symbols(char** str);
sym_t* parse_symbol_final(char* str);
+int is_internal(char* name);
void write_symbol_visual(sym_t* symbol, int offset);
#endif
diff --git a/src/precedent.c b/src/precedent.c
index c8f4dea..1874c51 100644
--- a/src/precedent.c
+++ b/src/precedent.c
@@ -52,6 +52,8 @@ int main(int argc, char** argv) {
hashtable_t* rootTable = init_hashtable(500, NULL);
sym_t* sym = eval(finalSymbol, rootTable);
destroy_sym(sym);
+ destroy_sym_tree(finalSymbol);
+ destroy_hashtable(rootTable);
return 0;
}
char* read_file(char* path) {