feat: implement AST walker

This commit is contained in:
samsonium
2026-10-10 02:40:53 +03:00
parent 2fabd0ec2d
commit e979a22739
9 changed files with 469 additions and 17 deletions
+16 -17
View File
@@ -2,13 +2,13 @@
#include <stdio.h>
#include <stdlib.h>
char last_err[256];
char plast_err[256];
fzl_parser_t *fzl_mkparser(fzl_reader_ll_t *first)
{
if (!first)
{
snprintf(last_err, sizeof(last_err), "token is null");
snprintf(plast_err, sizeof(plast_err), "token is null");
return NULL;
}
@@ -81,7 +81,7 @@ fzl_node_t *parse_primary(fzl_parser_t *parser)
return fzl_mknode(FZL_NODETYPE_LITERAL, tok);
}
snprintf(last_err, sizeof(last_err), "failed to parse primary at %d",
snprintf(plast_err, sizeof(plast_err), "failed to parse primary at %d",
peek(parser)->i0);
return NULL;
}
@@ -126,7 +126,7 @@ fzl_node_t *parse_call(fzl_parser_t *parser)
consume(parser);
else if (peek(parser) && peek(parser)->type != FZL_TOKTYPE_RPAIR)
{
snprintf(last_err, sizeof(last_err),
snprintf(plast_err, sizeof(plast_err),
"expected ',' or ')' after arg list");
return NULL;
}
@@ -147,7 +147,7 @@ fzl_node_t *parse_expression(fzl_parser_t *parser, int precedence)
else if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_STR_LITERAL)
return parse_primary(parser);
snprintf(last_err, sizeof(last_err), "failed to parse expression at %d",
snprintf(plast_err, sizeof(plast_err), "failed to parse expression at %d",
peek(parser)->i0);
return NULL;
}
@@ -184,7 +184,7 @@ fzl_node_t *parse_program(fzl_parser_t *parser)
if (!first)
{
snprintf(last_err, sizeof(last_err), "empty ;(");
snprintf(plast_err, sizeof(plast_err), "empty ;(");
return NULL;
}
@@ -204,7 +204,7 @@ int fzl_parse(fzl_parser_t *parser)
// --- Parse zone end ---
char *fzl_parser_geterror() { return last_err; }
char *fzl_parser_geterror() { return plast_err; }
void fzl_freenode(fzl_node_t *node)
{
@@ -220,17 +220,16 @@ void fzl_freeast(fzl_node_t *root)
while (root)
{
if (root->type == FZL_NODETYPE_BLOCK)
if (root->type == FZL_NODETYPE_BLOCK || root->type == FZL_NODETYPE_CALL)
{
for (size_t i = 0; i < root->list.entry_count; i++)
if (root->list.entries[i])
fzl_freeast(root->list.entries[i]);
}
else if (root->type == FZL_NODETYPE_CALL)
{
for (size_t i = 0; i < root->list.entry_count; i++)
if (root->list.entries[i])
fzl_freeast(root->list.entries[i]);
if (root->list.entries)
{
for (size_t i = 0; i < root->list.entry_count; i++)
if (root->list.entries[i])
fzl_freeast(root->list.entries[i]);
free(root->list.entries);
}
}
fzl_freenode(root);