feat: add extern functions call support

This commit is contained in:
samsonium
2026-11-06 14:06:01 +03:00
parent 317b846108
commit d38365f10c
+29 -9
View File
@@ -131,7 +131,8 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
return (fzl_an_res_t){.error = true}; return (fzl_an_res_t){.error = true};
} }
if (sym.node->type != FZL_NODETYPE_FUNCTION) if (sym.node->type != FZL_NODETYPE_FUNCTION &&
sym.node->type != FZL_NODETYPE_EXTERN_FN)
{ {
snprintf(an_problem, sizeof(an_problem), "'%s' is not callable", snprintf(an_problem, sizeof(an_problem), "'%s' is not callable",
callee_name); callee_name);
@@ -147,21 +148,23 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
} }
size_t offset = is_method ? 1 : 0; size_t offset = is_method ? 1 : 0;
if ((sym.node->fn.args_count - offset) != call_node->call.args_count) size_t args_count = sym.node->type == FZL_NODETYPE_EXTERN_FN
? sym.node->ext_fn.args_count
: sym.node->fn.args_count;
if ((args_count - offset) != call_node->call.args_count)
{ {
if (is_method) if (is_method)
{ {
snprintf(an_problem, sizeof(an_problem), snprintf(an_problem, sizeof(an_problem),
"method '%s.%s' is expecting %zu argument(s), got %zu", "method '%s.%s' is expecting %zu argument(s), got %zu",
tmp_classname, tmp_fnname, sym.node->fn.args_count, tmp_classname, tmp_fnname, args_count,
call_node->call.args_count - offset); call_node->call.args_count - offset);
} }
else else
{ {
snprintf(an_problem, sizeof(an_problem), snprintf(an_problem, sizeof(an_problem),
"function '%s' is expecting %zu argument(s), got %zu", "function '%s' is expecting %zu argument(s), got %zu",
callee_name, sym.node->fn.args_count, callee_name, args_count, call_node->call.args_count - offset);
call_node->call.args_count - offset);
} }
an_push_error(analyzer, call_node->token, an_problem); an_push_error(analyzer, call_node->token, an_problem);
@@ -174,9 +177,12 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
return (fzl_an_res_t){.error = true}; return (fzl_an_res_t){.error = true};
} }
fzl_node_t **args = sym.node->type == FZL_NODETYPE_EXTERN_FN
? sym.node->ext_fn.args
: sym.node->fn.args;
for (size_t i = offset; i < sym.node->fn.args_count; i++) for (size_t i = offset; i < sym.node->fn.args_count; i++)
{ {
fzl_node_t *arg = sym.node->fn.args[i]; fzl_node_t *arg = args[i];
bool found = false; bool found = false;
fzl_type_t req_type = an_toktotype(analyzer, arg->var.type, &found); fzl_type_t req_type = an_toktotype(analyzer, arg->var.type, &found);
char *req_classname = NULL; char *req_classname = NULL;
@@ -237,14 +243,28 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
} }
bool type_found = false; bool type_found = false;
fzl_type_t type = an_toktotype(analyzer, sym.node->fn.type, &type_found); fzl_token_t *ret_tok = NULL;
void *ret_name = NULL;
if (sym.node->type == FZL_NODETYPE_EXTERN_FN)
{
ret_tok = sym.node->ext_fn.type;
ret_name = sym.node->ext_fn.name;
}
else
{
ret_tok = sym.node->fn.type;
ret_name = sym.node->fn.name;
}
fzl_type_t type = an_toktotype(analyzer, ret_tok, &type_found);
char *classname = sym.classname; char *classname = sym.classname;
if (!type_found) if (!type_found)
{ {
snprintf(an_problem, sizeof(an_problem), "symbol '%s' not found", snprintf(an_problem, sizeof(an_problem), "symbol '%s' not found",
(char *)sym.node->fn.type->value); (char *)ret_name);
an_push_error(analyzer, sym.node->fn.type, an_problem); an_push_error(analyzer, ret_tok, an_problem);
return (fzl_an_res_t){.error = true}; return (fzl_an_res_t){.error = true};
} }