From 731b662cfcdb2cb4f5e9c8131fe4dbadae970df7 Mon Sep 17 00:00:00 2001 From: samsonium Date: Wed, 4 Nov 2026 18:30:02 +0300 Subject: [PATCH] wip: working on generator - Feat: add extern type resolving to type slot - Feat: add extern block handling - Feat: add extern function handling --- include/compiler/internals/gen.h | 3 + src/compiler/generator/gen_extern.c | 24 +++++ src/compiler/generator/gen_externfn.c | 124 ++++++++++++++++++++++++++ src/compiler/generator/utility.c | 15 ++++ 4 files changed, 166 insertions(+) create mode 100644 src/compiler/generator/gen_extern.c create mode 100644 src/compiler/generator/gen_externfn.c diff --git a/include/compiler/internals/gen.h b/include/compiler/internals/gen.h index 76d92f0..369db48 100644 --- a/include/compiler/internals/gen.h +++ b/include/compiler/internals/gen.h @@ -1,6 +1,7 @@ #ifndef INTERNALS_GEN_H #define INTERNALS_GEN_H +#include #include #include #include @@ -10,11 +11,13 @@ #include #include #include +#include extern char *null_name; bool gen_resolve_name(fzl_gen_t *gen, char *name, fzl_sym_t *sym); bool gen_resolve_type(fzl_gen_t *gen, fzl_token_t *tok, fzl_type_t *t, char *c); +ssize_t gen_resolve_extern_type(fzl_gen_t *gen, char *name); bool gen_is_types_compatible(fzl_type_t t1, fzl_type_t t2, char *c1, char *c2); size_t gen_add_const(fzl_gen_t *gen, fzl_const_t c); void gen_op(fzl_gen_t *gen, fzl_opcode_t opcode); diff --git a/src/compiler/generator/gen_extern.c b/src/compiler/generator/gen_extern.c new file mode 100644 index 0000000..96f3974 --- /dev/null +++ b/src/compiler/generator/gen_extern.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +// Extern block +bool gen_extern(fzl_gen_t *gen, fzl_node_t *node) +{ + if (!gen || !node) + return false; + + gen->extern_libs[gen->extern_libs_count++] = + (fzl_extern_lib_t){.name = (char *)node->ext.libname}; + + for (size_t i = 0; i < node->ext.typedefs_count; i++) + if (!gen_common(gen, node->ext.typedefs[i])) + return false; + + for (size_t i = 0; i < node->ext.fns_count; i++) + if (!gen_common(gen, node->ext.fns[i])) + return false; + + return true; +} diff --git a/src/compiler/generator/gen_externfn.c b/src/compiler/generator/gen_externfn.c new file mode 100644 index 0000000..779af05 --- /dev/null +++ b/src/compiler/generator/gen_externfn.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// External function definition +bool gen_externfn(fzl_gen_t *gen, fzl_node_t *node) +{ + if (!gen || !node) + return false; + + fzl_gen_ctx_t *ctx = gen_ctx(gen, FZL_GEN_CTX_TYPE_FUNCTION, node); + if (!ctx) + return false; + + size_t args_remainder = 2; + size_t args_count = 0; + fzl_extern_arg_t *args = malloc(args_remainder * sizeof(fzl_extern_arg_t)); + if (!args) + return false; + + for (size_t i = 0; i < node->ext_fn.args_count; i++) + { + fzl_node_t *argnode = node->ext_fn.args[i]; + if (!gen_common(gen, argnode)) + return false; + + if (args_count >= args_remainder) + { + args_remainder *= 2; + fzl_extern_arg_t *newargs = + realloc(args, args_remainder * sizeof(fzl_extern_arg_t)); + if (!newargs) + { + free(args); + return false; + } + + args = newargs; + } + + if (argnode->type != FZL_NODETYPE_DECLARATION) + { + free(args); + return false; + } + + fzl_extern_arg_t *arg = &args[args_count++]; + + fzl_type_t argtype; + char argcn[256]; + memset(argcn, 0, sizeof(argcn)); + + bool resolved = gen_resolve_type(gen, argnode->var.type, &argtype, argcn); + if (!resolved) + { + free(args); + return false; + } + + ssize_t slot = gen_resolve_extern_type(gen, argcn); + if (slot == -1) + arg->type = + (fzl_extern_type_ref_t){.is_primitive = true, .primitive = argtype}; + else + arg->type = + (fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot}; + + arg->name = (char *)argnode->var.identifier->token->value; + arg->is_out = argnode->var.is_out; + } + + ctx = gen_fin_ctx(gen); + if (!ctx) + { + free(args); + return false; + } + + fzl_type_t ret; + char retname[256]; + memset(retname, 0, sizeof(retname)); + + bool resolved = gen_resolve_type(gen, node->ext_fn.type, &ret, retname); + if (!resolved) + { + free(args); + return false; + } + + fzl_symtable_res_t res = fzl_symt_put(gen->syms[0], node, node->ext_fn.name, + FZL_TYPE_EXTERN_FN, 0); + if (res != FZL_SYMTABLE_RESULT_OK) + { + free(args); + return false; + } + + fzl_extern_fn_t *result = &gen->extern_fns[gen->extern_fns_count++]; + + ssize_t slot = gen_resolve_extern_type(gen, retname); + if (slot == -1) + result->ret_type = + (fzl_extern_type_ref_t){.is_primitive = true, .primitive = ret}; + else + result->ret_type = + (fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot}; + + result->lib_slot = gen->extern_libs_count - 1; + result->args = args; + result->args_count = args_count; + result->has_return = ret != FZL_TYPE_NULL; + result->used_name = node->ext_fn.name; + result->symbol_name = node->ext_fn.original_name; + + return true; +} diff --git a/src/compiler/generator/utility.c b/src/compiler/generator/utility.c index 3a9cc5f..5bbdc3d 100644 --- a/src/compiler/generator/utility.c +++ b/src/compiler/generator/utility.c @@ -95,6 +95,21 @@ bool gen_resolve_type(fzl_gen_t *gen, fzl_token_t *tok, fzl_type_t *t, char *c) return true; } +// Resolve external type +ssize_t gen_resolve_extern_type(fzl_gen_t *gen, char *name) +{ + if (!gen || !name) + return -1; + + for (size_t i = 0; i < gen->extern_types_count; i++) + { + if (strcmp(name, gen->extern_types[i].name) == 0) + return i; + } + + return -1; +} + // Check if left and right types are compatible bool gen_is_types_compatible(fzl_type_t t1, fzl_type_t t2, char *c1, char *c2) {