Files
fz-lang/src/compiler/analyzer/utility.c
T
samsonium 4d9c4ddd21 wip: working on walker (externs)
Begin working on extern walking (libs metadata collet + opcode gen)
2026-10-31 18:45:33 +03:00

161 lines
3.5 KiB
C

#include <common/fzl_types.h>
#include <compiler/fzl_analyzer.h>
#include <compiler/fzl_parser.h>
#include <compiler/fzl_token.h>
#include <compiler/internals/analyzer.h>
#include <compiler/utils/fzl_symtable.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
// Check compatibility between A and B types (and classnames)
bool an_is_compatible(fzl_type_t a, fzl_type_t b, char *ac, char *bc)
{
if (a == b)
return true;
if (a == FZL_TYPE_OBJECT && b == FZL_TYPE_OBJECT)
{
if (strcmp(ac, "null") == 0 || strcmp(bc, "null") == 0)
return true;
return strcmp(ac, bc) == 0;
}
if (a >= FZL_TYPE_INT8 && b >= FZL_TYPE_INT8)
return true;
return false;
}
// Convert type to string
char *an_typetostr(fzl_type_t type, char *classname)
{
if (classname)
return classname;
switch (type)
{
case FZL_TYPE_NULL:
return "null";
case FZL_TYPE_BOOL:
return "boolean";
case FZL_TYPE_STRING:
return "string";
case FZL_TYPE_CHAR:
return "char";
case FZL_TYPE_INT8:
return "i8";
case FZL_TYPE_INT16:
return "i16";
case FZL_TYPE_INT32:
return "i32";
case FZL_TYPE_INT64:
return "i64";
case FZL_TYPE_UINT8:
return "u8";
case FZL_TYPE_UINT16:
return "u16";
case FZL_TYPE_UINT32:
return "u32";
case FZL_TYPE_UINT64:
return "u64";
case FZL_TYPE_INT:
return "int";
case FZL_TYPE_UINT:
return "uint";
default:
return "<unknown>";
}
}
// Convert type token to type
fzl_type_t an_toktotype(fzl_analyzer_t *analyzer, fzl_token_t *tok,
bool *sym_found)
{
if (!tok)
return FZL_TYPE_NULL;
if (tok->type == FZL_TOKTYPE_NAME)
{
fzl_sym_t sym;
bool found = false;
for (ssize_t i = analyzer->symbols_top - 1; i >= 0; i--)
{
if ((found = fzl_symt_get(analyzer->symbols[i], tok->value, &sym)))
break;
}
if (sym_found)
*sym_found = found;
if (found && sym.node->type == FZL_NODETYPE_CLASS)
return FZL_TYPE_OBJECT;
if (found && sym.node->type != FZL_NODETYPE_CLASS &&
sym.node->type != FZL_NODETYPE_TYPEDEF)
{
snprintf(an_problem, sizeof(an_problem), "cannot use '%s' as type",
sym.name);
an_push_error(analyzer, sym.node->token, an_problem);
return FZL_TYPE_NULL;
}
return (found || (tok->value && strcmp(tok->value, "null") == 0))
? sym.type
: FZL_TYPE_NULL;
}
if (sym_found)
*sym_found = true;
if (strcmp(tok->value, "null") == 0)
return FZL_TYPE_NULL;
if (strcmp((char *)tok->value, "i8") == 0)
return FZL_TYPE_INT8;
if (strcmp((char *)tok->value, "i16") == 0)
return FZL_TYPE_INT16;
if (strcmp((char *)tok->value, "i32") == 0)
return FZL_TYPE_INT32;
if (strcmp((char *)tok->value, "i64") == 0)
return FZL_TYPE_INT64;
if (strcmp((char *)tok->value, "u8") == 0)
return FZL_TYPE_UINT8;
if (strcmp((char *)tok->value, "u16") == 0)
return FZL_TYPE_UINT16;
if (strcmp((char *)tok->value, "u32") == 0)
return FZL_TYPE_UINT32;
if (strcmp((char *)tok->value, "u64") == 0)
return FZL_TYPE_UINT64;
if (strcmp((char *)tok->value, "int") == 0)
return FZL_TYPE_INT;
if (strcmp((char *)tok->value, "uint") == 0)
return FZL_TYPE_UINT;
if (strcmp((char *)tok->value, "bool") == 0)
return FZL_TYPE_BOOL;
if (strcmp((char *)tok->value, "str") == 0)
return FZL_TYPE_STRING;
if (strcmp((char *)tok->value, "char") == 0)
return FZL_TYPE_CHAR;
return FZL_TYPE_NULL;
}