From d38365f10c12c41b3eeca66ce46217348dc95838 Mon Sep 17 00:00:00 2001 From: samsonium Date: Fri, 6 Nov 2026 14:06:01 +0300 Subject: [PATCH] feat: add extern functions call support --- src/compiler/analyzer/an_call.c | 40 ++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/compiler/analyzer/an_call.c b/src/compiler/analyzer/an_call.c index e347dff..b87aea4 100644 --- a/src/compiler/analyzer/an_call.c +++ b/src/compiler/analyzer/an_call.c @@ -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}; } - 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", callee_name); @@ -146,22 +147,24 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node) return (fzl_an_res_t){.error = true}; } - size_t offset = is_method ? 1 : 0; - if ((sym.node->fn.args_count - offset) != call_node->call.args_count) + size_t offset = is_method ? 1 : 0; + 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) { snprintf(an_problem, sizeof(an_problem), "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); } else { snprintf(an_problem, sizeof(an_problem), "function '%s' is expecting %zu argument(s), got %zu", - callee_name, sym.node->fn.args_count, - call_node->call.args_count - offset); + callee_name, args_count, call_node->call.args_count - offset); } 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}; } + 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++) { - fzl_node_t *arg = sym.node->fn.args[i]; + fzl_node_t *arg = args[i]; bool found = false; fzl_type_t req_type = an_toktotype(analyzer, arg->var.type, &found); 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; - 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; if (!type_found) { snprintf(an_problem, sizeof(an_problem), "symbol '%s' not found", - (char *)sym.node->fn.type->value); - an_push_error(analyzer, sym.node->fn.type, an_problem); + (char *)ret_name); + an_push_error(analyzer, ret_tok, an_problem); return (fzl_an_res_t){.error = true}; }