From fa5ebaa20327d0569cd5337a6b5fd22792b00ed1 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sun, 20 Oct 2024 23:15:21 +0300 Subject: fix memory leaks + lol --- include/lyn/ast.h | 2 +- src/lexer.l | 4 ++-- src/lyn.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/include/lyn/ast.h b/include/lyn/ast.h index ba9a0d5..4910aa8 100644 --- a/include/lyn/ast.h +++ b/include/lyn/ast.h @@ -14,7 +14,7 @@ struct lyn_value { union { long long i; double d; - const char *s; + char *s; struct vec args; }; }; diff --git a/src/lexer.l b/src/lexer.l index 4756cf0..7b30454 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -56,7 +56,7 @@ FLOAT {HEXF}|{DECF} {STRING} { /* seems risky, I know, but letting the parser choose when to allocate a * new string seems to help with syntax error cleanup */ - yylval->str = strdup(yytext); + yylval->str = yytext; return STRING; } @@ -71,7 +71,7 @@ FLOAT {HEXF}|{DECF} } {ID} { - yylval->str = strdup(yytext); + yylval->str = yytext; return ID; } diff --git a/src/lyn.c b/src/lyn.c index fd2b802..b74e19f 100644 --- a/src/lyn.c +++ b/src/lyn.c @@ -11,7 +11,7 @@ #include #include -int eval_group(struct lyn *lyn, struct lyn_value value) +static int eval_group(struct lyn *lyn, struct lyn_value value) { fprintf(lyn->output, "(begin"); @@ -30,7 +30,7 @@ int eval_group(struct lyn *lyn, struct lyn_value value) return 0; } -int eval_apply(struct lyn *lyn, struct lyn_value value) +static int eval_apply(struct lyn *lyn, struct lyn_value value) { fprintf(lyn->output, "("); foreach_vec(ai, value.args) { @@ -43,7 +43,7 @@ int eval_apply(struct lyn *lyn, struct lyn_value value) return 0; } -int eval_cmd(struct lyn *lyn, struct lyn_value value) +static int eval_cmd(struct lyn *lyn, struct lyn_value value) { foreach_vec(ci, value.args) { struct lyn_value arg = lyn_at(value.args, ci); @@ -57,25 +57,25 @@ int eval_cmd(struct lyn *lyn, struct lyn_value value) return 0; } -int eval_str(struct lyn *lyn, struct lyn_value value) +static int eval_str(struct lyn *lyn, struct lyn_value value) { fprintf(lyn->output, "%s", value.s); return 0; } -int eval_int(struct lyn *lyn, struct lyn_value value) +static int eval_int(struct lyn *lyn, struct lyn_value value) { fprintf(lyn->output, "%lld", value.i); return 0; } -int eval_float(struct lyn *lyn, struct lyn_value value) +static int eval_float(struct lyn *lyn, struct lyn_value value) { fprintf(lyn->output, "%f", value.d); return 0; } -int eval_id(struct lyn *lyn, struct lyn_value value) +static int eval_id(struct lyn *lyn, struct lyn_value value) { fprintf(lyn->output, "%s", value.s); return 0; @@ -86,6 +86,7 @@ int lyn_eval(struct lyn *lyn, struct lyn_value value) switch (value.kind) { case LYN_GROUP: return eval_group(lyn, value); case LYN_APPLY: return eval_apply(lyn, value); + case LYN_FLOAT: return eval_float(lyn, value); case LYN_STR: return eval_str(lyn, value); case LYN_CMD: return eval_cmd(lyn, value); case LYN_INT: return eval_int(lyn, value); @@ -96,6 +97,61 @@ int lyn_eval(struct lyn *lyn, struct lyn_value value) return -1; } +static void destroy_val(struct lyn_value value); + +static void destroy_group(struct lyn_value value) +{ + foreach_vec(gi, value.args) { + struct lyn_value arg = lyn_at(value.args, gi); + destroy_val(arg); + } + + vec_destroy(&value.args); +} + +static void destroy_apply(struct lyn_value value) +{ + foreach_vec(ai, value.args) { + struct lyn_value arg = lyn_at(value.args, ai); + destroy_val(arg); + } + + vec_destroy(&value.args); +} + +static void destroy_cmd(struct lyn_value value) +{ + foreach_vec(ci, value.args) { + struct lyn_value arg = lyn_at(value.args, ci); + destroy_val(arg); + } + + vec_destroy(&value.args); +} + +static void destroy_str(struct lyn_value value) +{ + free(value.s); +} + +static void destroy_id(struct lyn_value value) +{ + free(value.s); +} + +static void destroy_val(struct lyn_value value) +{ + switch (value.kind) { + case LYN_GROUP: return destroy_group(value); + case LYN_APPLY: return destroy_apply(value); + case LYN_STR: return destroy_str(value); + case LYN_CMD: return destroy_cmd(value); + case LYN_ID: return destroy_id(value); + case LYN_INT: return; /* nothing to do */ + default: error("unhandled case during 'destroy'"); break; + } +} + int lyn_eval_str(struct lyn *lyn, const char *name, const char *str) { struct parser *p = create_parser(); @@ -131,6 +187,7 @@ int lyn_eval_str(struct lyn *lyn, const char *name, const char *str) fprintf(lyn->output, ")\n"); } fclose(lyn->output); + destroy_val(ast); if (ret) return ret; @@ -197,4 +254,5 @@ struct lyn lyn_create() void lyn_destroy(struct lyn *lyn) { + (void)lyn; } -- cgit v1.2.3