- Feat: add analyzers for: - external functions - reference - structures - type definitions - Feat: add new nodes to debug print (ast)
258 lines
7.5 KiB
C
258 lines
7.5 KiB
C
#include "compiler/fzl_parser.h"
|
|
#include <compiler/fzl_debug.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
size_t print_level(char *buf, int level)
|
|
{
|
|
int lvl = 0;
|
|
while (lvl < level)
|
|
{
|
|
buf[lvl] = '-';
|
|
lvl++;
|
|
}
|
|
|
|
buf[lvl] = '>';
|
|
return strlen(buf);
|
|
}
|
|
|
|
void print_node(fzl_node_t *node, int level)
|
|
{
|
|
char levelbuf[32];
|
|
char printbuf[256];
|
|
memset(levelbuf, 0, sizeof(levelbuf));
|
|
memset(printbuf, 0, sizeof(printbuf));
|
|
|
|
if (!node)
|
|
return;
|
|
|
|
print_level(levelbuf, level);
|
|
strcpy(printbuf, levelbuf);
|
|
|
|
switch (node->type)
|
|
{
|
|
case FZL_NODETYPE_EXTERN:
|
|
printf("%s Extern bindings to library '%s':\n", levelbuf,
|
|
node->ext.libname);
|
|
printf("-%s Types:\n", levelbuf);
|
|
for (size_t i = 0; i < node->ext.typedefs_count; i++)
|
|
print_node(node->ext.typedefs[i], level + 2);
|
|
printf("-%s Functions:\n", levelbuf);
|
|
for (size_t i = 0; i < node->ext.fns_count; i++)
|
|
print_node(node->ext.fns[i], level + 2);
|
|
break;
|
|
|
|
case FZL_NODETYPE_EXTERN_FN:
|
|
printf("%s External function '%s' (original name %s), rettype '%s':\n",
|
|
levelbuf, node->ext_fn.name, node->ext_fn.original_name,
|
|
(char *)node->ext_fn.type->value);
|
|
printf("-%s Arguments:\n", levelbuf);
|
|
for (size_t i = 0; i < node->ext_fn.args_count; i++)
|
|
print_node(node->ext_fn.args[i], level + 2);
|
|
break;
|
|
|
|
case FZL_NODETYPE_REFERENCE:
|
|
printf("%s Reference (pointer type) to '%s'\n", levelbuf,
|
|
(char *)node->token->value);
|
|
break;
|
|
|
|
case FZL_NODETYPE_STRUCT:
|
|
printf("%s Structure '%s' (original name %s):\n", levelbuf,
|
|
(char *)node->token->value, node->structure.original_name);
|
|
for (size_t i = 0; i < node->structure.entries_count; i++)
|
|
print_node(node->structure.entries[i], level + 1);
|
|
break;
|
|
|
|
case FZL_NODETYPE_ALIAS:
|
|
printf("%s Type alias to '%s'\n", levelbuf, (char *)node->token->value);
|
|
break;
|
|
|
|
case FZL_NODETYPE_HANDLE:
|
|
printf("%s Opaque pointer (handle)\n", levelbuf);
|
|
break;
|
|
|
|
case FZL_NODETYPE_TYPEDEF:
|
|
printf("%s Type definition '%s':\n", levelbuf,
|
|
node->typedefinition.typename);
|
|
print_node(node->typedefinition.type, level + 1);
|
|
break;
|
|
|
|
case FZL_NODETYPE_UNARY_MINUS:
|
|
printf("%s Unary '-':\n", levelbuf);
|
|
print_node(node->unary_op.operand, level + 1);
|
|
break;
|
|
|
|
case FZL_NODETYPE_UNARY_PLUS:
|
|
printf("%s Unary '+':\n", levelbuf);
|
|
print_node(node->unary_op.operand, level + 1);
|
|
break;
|
|
|
|
case FZL_NODETYPE_BREAK:
|
|
printf("%s Break\n", levelbuf);
|
|
break;
|
|
|
|
case FZL_NODETYPE_FMT_STRING:
|
|
printf("%s Format string:\n", levelbuf);
|
|
for (size_t i = 0; i < node->list.entry_count; i++)
|
|
print_node(node->list.entries[i], level + 1);
|
|
break;
|
|
|
|
case FZL_NODETYPE_LOOP:
|
|
printf("%s Loop:\n", levelbuf);
|
|
printf("-%s Init:\n", levelbuf);
|
|
if (node->loop.init)
|
|
print_node(node->loop.init, level + 2);
|
|
printf("-%s Condition:\n", levelbuf);
|
|
if (node->loop.cond)
|
|
print_node(node->loop.cond, level + 2);
|
|
printf("-%s Step:\n", levelbuf);
|
|
if (node->loop.step)
|
|
print_node(node->loop.step, level + 2);
|
|
printf("-%s Body:\n", levelbuf);
|
|
if (node->loop.body)
|
|
print_node(node->loop.body, level + 2);
|
|
break;
|
|
|
|
case FZL_NODETYPE_CONSTRUCT:
|
|
printf("%s Construct class '%s':\n", levelbuf,
|
|
(char *)node->construct.name->token->value);
|
|
break;
|
|
|
|
case FZL_NODETYPE_CLASS:
|
|
printf("%s Class '%s':\n", levelbuf, (char *)node->token->value);
|
|
printf("-%s Fields:\n", levelbuf);
|
|
for (size_t i = 0; i < node->class.fields_count; i++)
|
|
print_node(node->class.fields[i], level + 2);
|
|
printf("-%s Methods:\n", levelbuf);
|
|
for (size_t i = 0; i < node->class.methods_count; i++)
|
|
print_node(node->class.methods[i], level + 2);
|
|
break;
|
|
|
|
case FZL_NODETYPE_FIELD:
|
|
printf("%s Field '%s' access:\n", levelbuf,
|
|
(char *)node->memb.field->token->value);
|
|
print_node(node->memb.parent, level + 1);
|
|
break;
|
|
|
|
case FZL_NODETYPE_DECLARATION:
|
|
printf("%s Declare variable with type %d:\n", levelbuf,
|
|
node->var.type->type);
|
|
print_node(node->var.identifier, level + 1);
|
|
break;
|
|
|
|
case FZL_NODETYPE_ASSIGN:
|
|
printf("%s Assign:\n", levelbuf);
|
|
printf("-%s Target:\n", levelbuf);
|
|
print_node(node->binary_op.left, level + 2);
|
|
printf("-%s Source:\n", levelbuf);
|
|
print_node(node->binary_op.right, level + 2);
|
|
break;
|
|
|
|
case FZL_NODETYPE_CALL:
|
|
if (node->call.args_count > 0)
|
|
{
|
|
printf("%s Call fn '%s' with args:\n", levelbuf,
|
|
(char *)node->token->value);
|
|
for (size_t i = 0; i < node->call.args_count; i++)
|
|
print_node(node->call.args[i], level + 1);
|
|
}
|
|
else
|
|
printf("%s Call fn '%s' w/o args\n", levelbuf,
|
|
(char *)node->token->value);
|
|
break;
|
|
|
|
case FZL_NODETYPE_LITERAL:
|
|
printf("%s Literal '%s'\n", levelbuf, (char *)node->token->value);
|
|
break;
|
|
|
|
case FZL_NODETYPE_CONDITIONAL:
|
|
printf("%s Conditional block:\n", levelbuf);
|
|
printf("-%s Condition:\n", levelbuf);
|
|
print_node(node->cond.condition, level + 2);
|
|
printf("-%s True block:\n", levelbuf);
|
|
print_node(node->cond.true_block, level + 2);
|
|
if (node->cond.else_block)
|
|
{
|
|
printf("-%s Else block:\n", levelbuf);
|
|
print_node(node->cond.else_block, level + 2);
|
|
}
|
|
break;
|
|
|
|
case FZL_NODETYPE_BLOCK:
|
|
printf("%s Block: ", levelbuf);
|
|
|
|
if (node->list.entry_count < 1)
|
|
{
|
|
printf("<empty>\n");
|
|
break;
|
|
}
|
|
|
|
printf("\n");
|
|
for (size_t i = 0; i < node->list.entry_count; i++)
|
|
print_node(node->list.entries[i], level + 1);
|
|
|
|
break;
|
|
|
|
case FZL_NODETYPE_NOT:
|
|
printf("%s Inverse:\n", levelbuf);
|
|
print_node(node->unary_op.operand, level + 1);
|
|
break;
|
|
|
|
case FZL_NODETYPE_FUNCTION:
|
|
printf("%s Function named '%s' with ret type '%s':\n", levelbuf,
|
|
(char *)node->fn.name->value, (char *)node->fn.type->value);
|
|
printf("-%s Args:\n", levelbuf);
|
|
for (size_t i = 0; i < node->fn.args_count; i++)
|
|
print_node(node->fn.args[i], level + 2);
|
|
printf("-%s Body:\n", levelbuf);
|
|
print_node(node->fn.body, level + 2);
|
|
break;
|
|
|
|
case FZL_NODETYPE_RETURN:
|
|
printf("%s Return:\n", levelbuf);
|
|
if (node->ret.value)
|
|
print_node(node->ret.value, level + 1);
|
|
break;
|
|
|
|
case FZL_NODETYPE_AND:
|
|
case FZL_NODETYPE_OR:
|
|
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_ADD:
|
|
case FZL_NODETYPE_SUB:
|
|
case FZL_NODETYPE_MUL:
|
|
case FZL_NODETYPE_DIV:
|
|
case FZL_NODETYPE_POW:
|
|
case FZL_NODETYPE_MOD:
|
|
printf("%s Binary op (%d)\n", levelbuf, node->type);
|
|
printf("-%s LEFT:\n", levelbuf);
|
|
print_node(node->binary_op.left, level + 2);
|
|
printf("-%s RIGHT:\n", levelbuf);
|
|
print_node(node->binary_op.right, level + 2);
|
|
break;
|
|
|
|
case FZL_NODETYPE_IDENTIFIER:
|
|
printf("%s Identifier ('%s')\n", levelbuf, (char *)node->token->value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void fzl_debug_print_ast(fzl_node_t *root)
|
|
{
|
|
printf("> AST tree:\n");
|
|
|
|
fzl_node_t *curr = root;
|
|
while (curr != NULL)
|
|
{
|
|
print_node(curr, 2);
|
|
curr = curr->next;
|
|
}
|
|
|
|
printf("-> FINISH\n");
|
|
}
|