#include #include #include #include #include #include #include #include #include // Analyze external function definition fzl_an_res_t analyze_externfn(fzl_analyzer_t *analyzer, fzl_node_t *externfn) { if (!analyzer) return (fzl_an_res_t){.error = true}; if (!externfn || externfn->type != FZL_NODETYPE_EXTERN_FN) { an_push_error(analyzer, NULL, "node is not an external function"); return (fzl_an_res_t){.error = true}; } an_nest_ctx(analyzer, FZL_AN_CTX_TYPE_UNNECESSARY); for (size_t i = 0; i < externfn->ext_fn.args_count; i++) { fzl_an_res_t res = analyze_common(analyzer, externfn->ext_fn.args[i]); if (res.error) return (fzl_an_res_t){.error = true}; } if (externfn->ext_fn.type->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], (char *)externfn->ext_fn.type->value, &sym))) break; } if (!found) { snprintf(an_problem, sizeof(an_problem), "cannot find '%s' used as return type", (char *)externfn->ext_fn.type->value); an_push_error(analyzer, externfn->ext_fn.type, an_problem); return (fzl_an_res_t){.error = true}; } } fzl_symtable_res_t wrres = fzl_symt_put(analyzer->symbols[0], externfn, (char *)externfn->ext_fn.name, FZL_TYPE_EXTERN_FN, 0); if (wrres != FZL_SYMTABLE_RESULT_OK) { if (wrres == FZL_SYMTABLE_RESULT_EXISTS) { snprintf(an_problem, sizeof(an_problem), "symbol '%s' already has been declared", externfn->ext_fn.name); an_push_error(analyzer, externfn->token, an_problem); return (fzl_an_res_t){.error = true}; } else { snprintf(an_problem, sizeof(an_problem), "cannot store symbol '%s'", externfn->ext_fn.name); } an_push_error(analyzer, externfn->token, an_problem); return (fzl_an_res_t){.error = true}; } an_fin_ctx(analyzer); return (fzl_an_res_t){ .error = false, .type = FZL_TYPE_EXTERN_FN, .classname = NULL}; }