Files
fz-lang/src/compiler/fzl_parser.c
T

242 lines
5.7 KiB
C

#include <compiler/fzl_parser.h>
#include <compiler/fzl_token.h>
#include <compiler/internals/parser.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char plast_err[256];
fzl_token_t *last_known_tok = NULL;
fzl_token_t null_tok = {
.type = FZL_TOKTYPE_TYPE,
.filename = "",
.ln = 0,
.cn = 0,
.store_value = false,
.value = "null",
.value_sz = 4,
};
fzl_token_t this_tok = {.type = FZL_TOKTYPE_NAME,
.filename = "",
.ln = 0,
.cn = 0,
.store_value = false,
.value = "this",
.value_sz = 4};
fzl_parser_t *fzl_mkparser(fzl_reader_ll_t *first)
{
if (!first)
return NULL;
fzl_parser_t *parser = malloc(sizeof(fzl_parser_t));
if (!parser)
return NULL;
parser->root = NULL;
parser->cursor = first->next;
if (!parser->cursor)
return NULL;
return parser;
}
// Make a new node
fzl_node_t *fzl_mknode(fzl_nodetype_t type, fzl_token_t *token)
{
fzl_node_t *node = malloc(sizeof(fzl_node_t));
memset(node, 0, sizeof(fzl_node_t));
if (!node)
return NULL;
node->type = type;
node->token = token;
node->parent = NULL;
node->next = NULL;
return node;
}
// Parse tokens and build AST
int fzl_parse(fzl_parser_t *parser)
{
last_known_tok = NULL;
fzl_node_t *ast = pa_program(parser);
if (!ast)
return -1;
parser->root = ast;
return 0;
}
// --- Parse zone end ---
char *fzl_parser_geterror() { return plast_err; }
void fzl_freenode(fzl_node_t *node)
{
if (!node)
return;
free(node);
}
void fzl_freeast(fzl_node_t *root)
{
if (!root)
return;
while (root)
{
switch (root->type)
{
case FZL_NODETYPE_REFERENCE:
case FZL_NODETYPE_ALIAS:
case FZL_NODETYPE_HANDLE:
case FZL_NODETYPE_BREAK:
case FZL_NODETYPE_IDENTIFIER:
case FZL_NODETYPE_LITERAL:
break;
case FZL_NODETYPE_EXTERN:
for (size_t i = 0; i < root->ext.typedefs_count; i++)
fzl_freeast(root->ext.typedefs[i]);
free(root->ext.typedefs);
for (size_t i = 0; i < root->ext.fns_count; i++)
fzl_freeast(root->ext.fns[i]);
free(root->ext.fns);
break;
case FZL_NODETYPE_EXTERN_FN:
for (size_t i = 0; i < root->ext_fn.args_count; i++)
fzl_freeast(root->ext_fn.args[i]);
free(root->ext_fn.args);
break;
case FZL_NODETYPE_STRUCT:
for (size_t i = 0; i < root->structure.entries_count; i++)
fzl_freeast(root->structure.entries[i]);
free(root->structure.entries);
break;
case FZL_NODETYPE_TYPEDEF:
fzl_freeast(root->typedefinition.type);
break;
case FZL_NODETYPE_FMT_STRING:
case FZL_NODETYPE_BLOCK:
if (root->list.entries)
{
for (size_t i = 0; i < root->list.entry_count; i++)
fzl_freeast(root->list.entries[i]);
free(root->list.entries);
}
break;
case FZL_NODETYPE_CALL:
fzl_freeast(root->call.callee);
if (root->call.args_count)
{
for (size_t i = 0; i < root->call.args_count; i++)
fzl_freeast(root->call.args[i]);
}
if (root->call.args)
free(root->call.args);
break;
case FZL_NODETYPE_CONDITIONAL:
fzl_freeast(root->cond.condition);
fzl_freeast(root->cond.true_block);
fzl_freeast(root->cond.else_block);
break;
case FZL_NODETYPE_LOOP:
fzl_freeast(root->loop.init);
fzl_freeast(root->loop.cond);
fzl_freeast(root->loop.step);
fzl_freeast(root->loop.body);
break;
case FZL_NODETYPE_ADD:
case FZL_NODETYPE_SUB:
case FZL_NODETYPE_MUL:
case FZL_NODETYPE_DIV:
case FZL_NODETYPE_POW:
case FZL_NODETYPE_MOD:
case FZL_NODETYPE_OR:
case FZL_NODETYPE_AND:
case FZL_NODETYPE_EQUAL:
case FZL_NODETYPE_NEQUAL:
case FZL_NODETYPE_LESS:
case FZL_NODETYPE_LESS_EQUAL:
case FZL_NODETYPE_GREATER:
case FZL_NODETYPE_GREATER_EQUAL:
case FZL_NODETYPE_ASSIGN:
fzl_freeast(root->binary_op.left);
fzl_freeast(root->binary_op.right);
break;
case FZL_NODETYPE_UNARY_PLUS:
case FZL_NODETYPE_UNARY_MINUS:
case FZL_NODETYPE_NOT:
fzl_freeast(root->unary_op.operand);
break;
case FZL_NODETYPE_FUNCTION:
if (root->fn.args_count)
for (size_t i = 0; i < root->fn.args_count; i++)
fzl_freeast(root->fn.args[i]);
free(root->fn.args);
fzl_freeast(root->fn.body);
break;
case FZL_NODETYPE_RETURN:
fzl_freeast(root->ret.value);
break;
case FZL_NODETYPE_CLASS:
if (root->class.fields_count)
for (size_t i = 0; i < root->class.fields_count; i++)
fzl_freeast(root->class.fields[i]);
free(root->class.fields);
if (root->class.methods_count)
for (size_t i = 0; i < root->class.methods_count; i++)
fzl_freeast(root->class.methods[i]);
free(root->class.methods);
break;
case FZL_NODETYPE_CONSTRUCT:
fzl_freeast(root->construct.name);
break;
case FZL_NODETYPE_FIELD:
fzl_freeast(root->memb.field);
fzl_freeast(root->memb.parent);
break;
case FZL_NODETYPE_DECLARATION:
fzl_freeast(root->var.identifier);
break;
}
fzl_node_t *next = root->next;
fzl_freenode(root);
root = next;
}
}
void fzl_freeparser(fzl_parser_t *parser)
{
if (!parser)
return;
free(parser);
}