242 lines
5.7 KiB
C
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);
|
|
}
|