161 lines
3.5 KiB
C
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;
|
|
}
|