aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-10-20 23:15:21 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-10-23 18:25:23 +0300
commitfa5ebaa20327d0569cd5337a6b5fd22792b00ed1 (patch)
treefb2aa4946594e0c875427bfaab38c003a04056c7
parenteaa9f2c6dd47c7267c4e7f25565f8cf7f390e114 (diff)
downloadlyn-fa5ebaa20327d0569cd5337a6b5fd22792b00ed1.tar.gz
lyn-fa5ebaa20327d0569cd5337a6b5fd22792b00ed1.zip
fix memory leaks
+ lol
-rw-r--r--include/lyn/ast.h2
-rw-r--r--src/lexer.l4
-rw-r--r--src/lyn.c72
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 <lyn/parser.h>
#include <lyn/debug.h>
-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;
}