From 19367a27472a06634424e56c1eb21e4f53da4e9e Mon Sep 17 00:00:00 2001 From: Preston Pan Date: Sun, 8 Jan 2023 15:39:19 -0800 Subject: fixed invalid read; some memory leakage fixed but not completely --- src/ast.c | 17 +++++++++++++++++ src/hash_table.c | 26 +++++++++++++++++++++++--- src/include/ast.h | 2 ++ src/include/hash_table.h | 3 +++ src/include/parser.h | 2 ++ src/include/stack.h | 2 ++ src/main.c | 12 ++++++++++-- src/parser.c | 20 ++++++++++++++++++++ src/stack.c | 7 +++++++ src/visitor.c | 13 +++++++++++-- 10 files changed, 97 insertions(+), 7 deletions(-) diff --git a/src/ast.c b/src/ast.c index eefbc45..ef2246e 100644 --- a/src/ast.c +++ b/src/ast.c @@ -94,3 +94,20 @@ bool is_proper_list(ast_t *e) { return true; return false; } + +void ast_free(ast_t *e) { + if (e->cdr != NULL) { + ast_free(e->cdr); + } + if (e->car != NULL) { + ast_free(e->car); + } + + if (e->type == AST_ROOT) { + for (int i = 0; i < e->root_size; i++) { + ast_free(e->subnodes[i]); + } + } + + free(e); +} diff --git a/src/hash_table.c b/src/hash_table.c index 29946b1..f8d97a2 100644 --- a/src/hash_table.c +++ b/src/hash_table.c @@ -24,6 +24,11 @@ sl_node_t *init_sl_node(char *key, ast_t *value) { return n; } +void sl_node_free(sl_node_t *n) { + ast_free(n->value->value); + free(n->value); + free(n); +} /*** SINGLY LINKED LIST FUNCTIONS ***/ sl_list_t *init_sl_list() { sl_list_t *l = (sl_list_t *)malloc(sizeof(sl_list_t)); @@ -108,14 +113,24 @@ bool sl_list_exists(sl_list_t *l, char *key) { void sl_list_free(sl_list_t *l) { sl_node_t *cur = l->head; sl_node_t *tmp; - for (int i = 0; i < l->size; i++) { + while (cur != NULL) { tmp = cur; - cur = cur->next; - free(tmp); + cur = tmp->next; + sl_node_free(tmp); } free(l); } +void sl_list_free_some(sl_list_t *l) { + sl_node_t *cur = l->head; + sl_node_t *tmp; + while (cur != NULL) { + tmp = cur; + cur = tmp->next; + free(tmp); + } + free(l); +} /*** HASH TABLE FUNCTIONS ***/ hash_table_t *init_hash_table(int size) { hash_table_t *h = (hash_table_t *)malloc(sizeof(hash_table_t)); @@ -153,6 +168,11 @@ void hash_table_free(hash_table_t *h) { free(h); } +void hash_table_free_some(hash_table_t *h) { + for (int i = 0; i < h->size; i++) + sl_list_free_some(h->buckets[i]); + free(h); +} /* DJB2 HASH FUNCTION */ unsigned long hash(char *key, int size) { unsigned long hash = 5381; diff --git a/src/include/ast.h b/src/include/ast.h index 8b60490..d330ee5 100644 --- a/src/include/ast.h +++ b/src/include/ast.h @@ -54,4 +54,6 @@ ast_t *init_ast_root(ast_t **subnodes, int size); void ast_type_print(ast_t *e); bool is_proper_list(ast_t *e); + +void ast_free(ast_t *e); #endif diff --git a/src/include/hash_table.h b/src/include/hash_table.h index 833daee..b70331e 100644 --- a/src/include/hash_table.h +++ b/src/include/hash_table.h @@ -36,6 +36,8 @@ bool sl_list_exists(sl_list_t *l, char *key); void sl_list_free(sl_list_t *l); +void sl_list_free_some(sl_list_t *l); + hash_table_t *init_hash_table(int size); void hash_table_add(hash_table_t *h, char *key, ast_t *value); @@ -48,4 +50,5 @@ unsigned long hash(char *key, int size); void hash_table_free(hash_table_t *h); +void hash_table_free_some(hash_table_t *h); #endif diff --git a/src/include/parser.h b/src/include/parser.h index 7b26696..d159646 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -45,4 +45,6 @@ void parse_bind(parser_t *parser); ast_t *parse_expr(parser_t *parser); ast_t *parse_all(parser_t *parser); + +void parser_free(parser_t *parser); #endif diff --git a/src/include/stack.h b/src/include/stack.h index 6b0ed9a..e5630fc 100644 --- a/src/include/stack.h +++ b/src/include/stack.h @@ -15,4 +15,6 @@ hash_table_t *stack_peek(stack_t *s); hash_table_t *stack_pop(stack_t *s); bool is_empty(stack_t *s); + +void stack_free(stack_t *s); #endif diff --git a/src/main.c b/src/main.c index ba710bf..1d68cdb 100644 --- a/src/main.c +++ b/src/main.c @@ -132,7 +132,9 @@ int main(int argc, char **argv) { printf("nxs, version 1.2 alpha\n"); exit(0); } else if (strcmp(argv[1], "-r") == 0 || strcmp(argv[1], "--repl") == 0) { - /* Start a REPL */ + printf("Welcome to the NoExcess REPL.\n"); + while (true) { + } } char *filename = argv[1]; @@ -162,8 +164,14 @@ int main(int argc, char **argv) { lexer_t *lexer = init_lexer(buffer); parser_t *parser = init_parser(lexer); visitor_t *visitor = init_visitor(parser); - eval(visitor); + ast_t *root = eval(visitor); /* print_root(root); */ + ast_free(root); + free(visitor); + hash_table_free(parser->symbol_table); + parser_free(parser); + free(lexer); + free(buffer); } return 0; diff --git a/src/parser.c b/src/parser.c index 0f1ba69..dc949fe 100644 --- a/src/parser.c +++ b/src/parser.c @@ -7,6 +7,14 @@ #include #include +void parser_reset(parser_t *parser, lexer_t *lexer) { + for (int i = 0; i < parser->size; i++) { + free(parser->tokens[i]); + } + parser->i = 0; + parser->finished = false; +} + parser_t *init_parser_copy_hash(lexer_t *lexer, hash_table_t *h) { parser_t *p = (parser_t *)malloc(sizeof(parser_t)); if (p == NULL) @@ -203,6 +211,10 @@ ast_t *parse_include(parser_t *parser) { if (parser->tokens[parser->i]->type != TOKEN_RPAREN) parser_error(parser); parser_move(parser); + + free(lexer); + free(buffer); + parser_free(p); return root; } else { parser_error(parser); @@ -317,3 +329,11 @@ void parser_error(parser_t *parser) { printf("PARSER ERROR: something went wrong.\n"); exit(1); } + +void parser_free(parser_t *parser) { + for (int i = 0; i < parser->size; i++) { + free(parser->tokens[i]); + } + free(parser->tokens); + free(parser); +} diff --git a/src/stack.c b/src/stack.c index ebfa640..ba43023 100644 --- a/src/stack.c +++ b/src/stack.c @@ -43,3 +43,10 @@ bool is_empty(stack_t *s) { return true; return false; } + +void stack_free(stack_t *s) { + if (s->stack != NULL) { + free(s->stack); + } + free(s); +} diff --git a/src/visitor.c b/src/visitor.c index 65af934..bcea8e4 100644 --- a/src/visitor.c +++ b/src/visitor.c @@ -8,6 +8,8 @@ #include #include +void visitor_reset() {} + visitor_t *init_visitor(parser_t *p) { visitor_t *v = (visitor_t *)malloc(sizeof(visitor_t)); if (v == NULL) @@ -535,8 +537,8 @@ ast_t *eval_list(visitor_t *v, ast_t *e) { } stack_push(v->stack_frame, stack_frame); ast_t *res = eval_expr(v, function->cdr); - stack_frame = stack_pop(v->stack_frame); - /* hash_table_free(stack_frame); */ + stack_pop(v->stack_frame); + hash_table_free_some(stack_frame); return res; } @@ -572,3 +574,10 @@ void eval_error(visitor_t *v, ast_t *e) { printf("ERROR: something went wrong with the visitor.\n"); exit(1); } + +void visitor_free(visitor_t *v) { + ast_free(v->root); + hash_table_free(v->eval_table); + stack_free(v->stack_frame); + free(v); +} -- cgit