diff options
author | Camil Staps | 2016-08-25 13:20:22 +0200 |
---|---|---|
committer | Camil Staps | 2016-08-25 13:20:22 +0200 |
commit | 9846c6831cf2bd3de8a1285ffda9a14f2e13fe02 (patch) | |
tree | 38a9c3ab215ba15a203b9a7d633230c51dc9ae45 | |
parent | eval_rnf, lazy matching (diff) |
Fix memory leaks
-rw-r--r-- | compiler/eval.c | 14 | ||||
-rw-r--r-- | compiler/fuspelc.c | 12 | ||||
-rw-r--r-- | compiler/lex.c | 4 | ||||
-rw-r--r-- | compiler/parse.c | 7 | ||||
-rw-r--r-- | compiler/syntax.c | 19 | ||||
-rw-r--r-- | compiler/syntax.h | 1 |
6 files changed, 46 insertions, 11 deletions
diff --git a/compiler/eval.c b/compiler/eval.c index 297a4d7..df39212 100644 --- a/compiler/eval.c +++ b/compiler/eval.c @@ -9,7 +9,9 @@ void free_rules_until(fuspel* new, fuspel* old) { while (new != old) { free_rewrite_rule(&new->rule); - new = new->rest; + fuspel* _new = new->rest; + free(new); + new = _new; } } @@ -88,12 +90,14 @@ fuspel* match_rule(fuspel* rules, rewrite_rule* rule, expression* expr) { if (!empty_args_list(args) && !_expr) { free_rules_until(_rules, rules); + free(expr_args); return NULL; } } free(expr_args); return _rules; } + free(expr_args); default: return NULL; } @@ -134,8 +138,9 @@ expression* eval_rnf(fuspel* rules, expression* expr) { new_rules = match_rule(rules, &_rules->rule, expr); if (new_rules) { rules = new_rules; + free(result); result = eval_rnf(rules, &_rules->rule.rhs); - free_rules_until(new_rules, _rules); + free_rules_until(new_rules, rules); return result; } _rules = _rules->rest; @@ -154,7 +159,6 @@ expression* eval(fuspel* rules, expression* expr) { expression *e1, *e2; fuspel* _rules = rules; - fuspel* new_rules; switch (expr->kind) { case EXPR_INT: @@ -164,9 +168,9 @@ expression* eval(fuspel* rules, expression* expr) { case EXPR_NAME: case EXPR_APP: while (_rules) { - new_rules = match_rule(rules, &_rules->rule, expr); + fuspel* new_rules = match_rule(rules, &_rules->rule, expr); if (new_rules) { - rules = new_rules; + free(result); result = eval(new_rules, &_rules->rule.rhs); free_rules_until(new_rules, rules); return result; diff --git a/compiler/fuspelc.c b/compiler/fuspelc.c index 38e4a99..9964349 100644 --- a/compiler/fuspelc.c +++ b/compiler/fuspelc.c @@ -8,6 +8,14 @@ #include "eval.h" #include "print.h" +//static char* program = +// "take_one [x:_] = [x:[]];" +// "inflist = [1:inflist];" +// "main = take_one inflist;"; +//static char* program = +// "append [] ys = ys;" +// "append [x:xs] ys = [x:append xs ys];" +// "main = append [1:[2:[3:[]]]] [5:[6:[]]];"; static char* program = "singleton x = [x:[]];" "push x y = [x:y];" @@ -52,6 +60,7 @@ int main(void) { strcpy(to_eval.var1, "main"); evaled = eval(pgm, &to_eval); + free_expression(&to_eval); if (evaled) { print_expression(evaled); printf("\n"); @@ -60,5 +69,8 @@ int main(void) { free(evaled); } + free_fuspel(pgm); + free(pgm); + return 0; } diff --git a/compiler/lex.c b/compiler/lex.c index 5f42e37..57a39e5 100644 --- a/compiler/lex.c +++ b/compiler/lex.c @@ -63,7 +63,7 @@ token_list* lex(char* input) { if (is_int_char(*input)) { list->elem.kind = TOKEN_INT; unsigned char len = lex_int_length(input); - char* s = malloc(len); + char* s = calloc(1, len + 1); list->elem.var = calloc(1, sizeof(int)); if (!s || !list->elem.var) error_no_mem(); @@ -91,7 +91,7 @@ token_list* lex(char* input) { input++; if (*input && proceed_to_next_token) { - list->rest = malloc(sizeof(token_list)); + list->rest = calloc(1, sizeof(token_list)); if (!list->rest) error_no_mem(); list = list->rest; diff --git a/compiler/parse.c b/compiler/parse.c index a8c4b37..8507098 100644 --- a/compiler/parse.c +++ b/compiler/parse.c @@ -47,6 +47,7 @@ token_list* parse_simple_expression(expression* expr, token_list* list) { if (!_expr) error_no_mem(); cpy_expression(_expr, expr); + free_expression(expr); expr->kind = EXPR_TUPLE; expr->var1 = _expr; expr->var2 = calloc(1, sizeof(expression)); @@ -138,6 +139,7 @@ token_list* parse_expression_no_app(expression* expr, token_list* list) { error_no_mem(); cpy_expression(_expr, expr); + free_expression(expr); expr->kind = EXPR_TUPLE; expr->var1 = _expr; @@ -166,11 +168,15 @@ token_list* parse_expression_no_app(expression* expr, token_list* list) { token_list* _list = parse_expression(expr1, list->rest); if (!_list || _list->elem.kind != TOKEN_COLON) { + free_expression(expr1); free(expr1); + free(expr2); } else { _list = parse_expression(expr2, _list->rest); if (!_list || _list->elem.kind != TOKEN_CLOSE_SQ) { free_expression(expr1); + free_expression(expr2); + free(expr1); free(expr2); } else { expr->var1 = expr1; @@ -203,6 +209,7 @@ token_list* parse_expression(expression* expr, token_list* list) { error_no_mem(); cpy_expression(_expr, expr); + free_expression(expr); expr->kind = EXPR_APP; expr->var1 = _expr; diff --git a/compiler/syntax.c b/compiler/syntax.c index c19bf3b..cbb2fc7 100644 --- a/compiler/syntax.c +++ b/compiler/syntax.c @@ -10,10 +10,10 @@ void free_token(token* tk) { } void free_token_list(token_list* list) { - if (list->rest) { - free_token_list(list->rest); - } free_token(&list->elem); + if (list->rest) + free_token_list(list->rest); + free(list->rest); } unsigned empty_args_list(arg_list* list) { @@ -135,19 +135,30 @@ void free_expression(expression* expr) { case EXPR_APP: free_expression(expr->var1); free_expression(expr->var2); + free(expr->var1); + free(expr->var2); break; } } void free_arg_list(arg_list* list) { + free_expression(&list->elem); if (list->rest) free_arg_list(list->rest); - free_expression(&list->elem); + free(list->rest); } void free_rewrite_rule(rewrite_rule* rule) { free(rule->name); if (rule->args) free_arg_list(rule->args); + free(rule->args); free_expression(&rule->rhs); } + +void free_fuspel(fuspel* rules) { + free_rewrite_rule(&rules->rule); + if (rules->rest) + free_fuspel(rules->rest); + free(rules->rest); +} diff --git a/compiler/syntax.h b/compiler/syntax.h index 66223a9..f71786c 100644 --- a/compiler/syntax.h +++ b/compiler/syntax.h @@ -75,5 +75,6 @@ fuspel* popn_fuspel(fuspel*, unsigned char); void free_expression(expression*); void free_arg_list(arg_list*); void free_rewrite_rule(rewrite_rule*); +void free_fuspel(fuspel*); #endif |