- Feat: add new generator scope to replace walker - Feat: add generators' context functions - Feat: add generators' ops array functions - Feat: add generators' utility functions
138 lines
3.1 KiB
C
138 lines
3.1 KiB
C
#include <common/fzl_types.h>
|
|
#include <compiler/fzl_parser.h>
|
|
#include <compiler/fzl_token.h>
|
|
#include <compiler/internals/gen.h>
|
|
#include <compiler/utils/fzl_const_pool.h>
|
|
#include <compiler/utils/fzl_symtable.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
// Resolve name in symbol tables
|
|
bool gen_resolve_name(fzl_gen_t *gen, char *name, fzl_sym_t *sym)
|
|
{
|
|
if (!gen || !name || !sym)
|
|
return NULL;
|
|
|
|
bool found = false;
|
|
for (ssize_t i = gen->syms_top - 1; i >= 0; i--)
|
|
{
|
|
if ((found = fzl_symt_get(gen->syms[i], name, sym)))
|
|
break;
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
// Resolve type and return if was resolved or not
|
|
bool gen_resolve_type(fzl_gen_t *gen, fzl_token_t *tok, fzl_type_t *t, char *c)
|
|
{
|
|
if (!gen || !tok || !t)
|
|
return false;
|
|
|
|
if (tok->type == FZL_TOKTYPE_NAME)
|
|
{
|
|
char *name = (char *)tok->value;
|
|
if (!name)
|
|
return false;
|
|
|
|
fzl_sym_t sym;
|
|
if (!gen_resolve_name(gen, name, &sym))
|
|
return false;
|
|
|
|
if (sym.node && sym.node->type == FZL_NODETYPE_CLASS)
|
|
{
|
|
*t = FZL_TYPE_OBJECT;
|
|
if (c)
|
|
c = sym.classname;
|
|
}
|
|
else if (sym.node && sym.node->type == FZL_NODETYPE_TYPEDEF)
|
|
{
|
|
*t = sym.type;
|
|
if (c)
|
|
c = sym.classname;
|
|
}
|
|
else
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
if (strcmp(tok->value, "null") == 0)
|
|
*t = FZL_TYPE_NULL;
|
|
else if (strcmp(tok->value, "str") == 0)
|
|
*t = FZL_TYPE_STRING;
|
|
else if (strcmp(tok->value, "bool") == 0)
|
|
*t = FZL_TYPE_BOOL;
|
|
else if (strcmp(tok->value, "char") == 0)
|
|
*t = FZL_TYPE_CHAR;
|
|
|
|
else if (strcmp(tok->value, "uint") == 0)
|
|
*t = FZL_TYPE_UINT;
|
|
else if (strcmp(tok->value, "u8") == 0)
|
|
*t = FZL_TYPE_UINT8;
|
|
else if (strcmp(tok->value, "u16") == 0)
|
|
*t = FZL_TYPE_UINT16;
|
|
else if (strcmp(tok->value, "u32") == 0)
|
|
*t = FZL_TYPE_UINT32;
|
|
else if (strcmp(tok->value, "u64") == 0)
|
|
*t = FZL_TYPE_UINT64;
|
|
|
|
else if (strcmp(tok->value, "int") == 0)
|
|
*t = FZL_TYPE_INT;
|
|
else if (strcmp(tok->value, "i8") == 0)
|
|
*t = FZL_TYPE_INT8;
|
|
else if (strcmp(tok->value, "i16") == 0)
|
|
*t = FZL_TYPE_INT16;
|
|
else if (strcmp(tok->value, "i32") == 0)
|
|
*t = FZL_TYPE_INT32;
|
|
else if (strcmp(tok->value, "i64") == 0)
|
|
*t = FZL_TYPE_INT64;
|
|
else
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Check if left and right types are compatible
|
|
bool gen_is_types_compatible(fzl_type_t t1, fzl_type_t t2, char *c1, char *c2)
|
|
{
|
|
if (t1 == FZL_TYPE_OBJECT && t2 == FZL_TYPE_OBJECT)
|
|
{
|
|
if (!c1 || !c2)
|
|
return false;
|
|
|
|
if (strcmp(c1, null_name) == 0 || strcmp(c2, null_name) == 0)
|
|
return true;
|
|
|
|
return strcmp(c1, c2) == 0;
|
|
}
|
|
|
|
if ((t1 == FZL_TYPE_HANDLE && t2 == FZL_TYPE_HANDLE) ||
|
|
(t1 == FZL_TYPE_STRUCT && t2 == FZL_TYPE_STRUCT))
|
|
{
|
|
if (!c1 || !c2)
|
|
return false;
|
|
|
|
return strcmp(c1, c2) == 0;
|
|
}
|
|
|
|
if (t1 == t2)
|
|
return true;
|
|
|
|
if (t1 >= FZL_TYPE_INT8 && t2 >= FZL_TYPE_INT8)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
// Add new constant to constants table
|
|
size_t gen_add_const(fzl_gen_t *gen, fzl_const_t c)
|
|
{
|
|
if (!gen)
|
|
return 0;
|
|
|
|
return fzl_consts_pool_add(gen->consts, c);
|
|
}
|