diff --git a/include/compiler/internals/gen.h b/include/compiler/internals/gen.h index 369db48..59a117a 100644 --- a/include/compiler/internals/gen.h +++ b/include/compiler/internals/gen.h @@ -14,6 +14,7 @@ #include extern char *null_name; +extern fzl_extern_type_t type_buf; 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); diff --git a/src/compiler/fzl_walker.c b/src/compiler/fzl_walker.c index 88b51fc..a998272 100644 --- a/src/compiler/fzl_walker.c +++ b/src/compiler/fzl_walker.c @@ -15,9 +15,6 @@ #include #include -extern bool is_infinite_loop(fzl_walker_t *walker, fzl_node_t *node, size_t ls, - size_t le); - char *null_name = ""; char wlast_err[256]; @@ -234,7 +231,20 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node) .error = false, .type = FZL_TYPE_NULL, .classname = NULL}; break; - case FZL_NODETYPE_EXTERN_FN: // TODO: write to meta + case FZL_NODETYPE_EXTERN_FN: + { + fzl_extern_fn_t *fn = &walker->extern_fns[walker->extern_fns_count++]; + fn->has_return = tok_to_type(node->ext_fn.type) != FZL_TYPE_NULL; + + for (size_t i = 0; i < node->ext_fn.args_count; i++) + { + // + } + + fn->args_count = node->ext_fn.args_count; + break; + } + case FZL_NODETYPE_REFERENCE: // TODO: write to meta case FZL_NODETYPE_STRUCT: // TODO: write to meta case FZL_NODETYPE_ALIAS: // TODO: write to meta diff --git a/src/compiler/generator/gen_alias.c b/src/compiler/generator/gen_alias.c new file mode 100644 index 0000000..d2a2c1d --- /dev/null +++ b/src/compiler/generator/gen_alias.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include + +// Type aliasing +bool gen_alias(fzl_gen_t *gen, fzl_node_t *node) +{ + if (!gen || !node) + return false; + + fzl_type_t type; + char typecn[256]; + memset(typecn, 0, sizeof(typecn)); + + bool resolved = gen_resolve_type(gen, node->token, &type, typecn); + if (!resolved) + return false; + + ssize_t slot = gen_resolve_extern_type(gen, typecn); + if (slot == -1) + type_buf.alias_target = + (fzl_extern_type_ref_t){.is_primitive = true, .primitive = type}; + else + type_buf.alias_target = + (fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot}; + + return true; +} diff --git a/src/compiler/generator/gen_handle.c b/src/compiler/generator/gen_handle.c new file mode 100644 index 0000000..c28b3e0 --- /dev/null +++ b/src/compiler/generator/gen_handle.c @@ -0,0 +1,13 @@ +#include +#include +#include + +// Opaque pointer +bool gen_handle(fzl_gen_t *gen, fzl_node_t *node) +{ + if (!gen || !node) + return false; + + type_buf.kind = FZL_EXTERN_KIND_HANDLE; + return true; +} diff --git a/src/compiler/generator/gen_reference.c b/src/compiler/generator/gen_reference.c new file mode 100644 index 0000000..8bf56be --- /dev/null +++ b/src/compiler/generator/gen_reference.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include + +// Type reference (convert T => T*) +bool gen_reference(fzl_gen_t *gen, fzl_node_t *node) +{ + if (!gen || !node) + return false; + + char *refname = (char *)node->token->value; + ssize_t slot = gen_resolve_extern_type(gen, refname); + if (slot == -1) + return false; + + type_buf.kind = FZL_EXTERN_KIND_REF; + type_buf.ref_target = + (fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot}; + + return true; +} diff --git a/src/compiler/generator/gen_struct.c b/src/compiler/generator/gen_struct.c new file mode 100644 index 0000000..45bcc98 --- /dev/null +++ b/src/compiler/generator/gen_struct.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Structure +bool gen_struct(fzl_gen_t *gen, fzl_node_t *node) +{ + if (!gen || !node) + return false; + + type_buf.kind = FZL_EXTERN_KIND_STRUCT; + fzl_gen_ctx_t *ctx = gen_ctx(gen, FZL_GEN_CTX_TYPE_UNECCESSARY, node); + if (!ctx) + return false; + + size_t remainder = 2; + size_t count = 0; + fzl_extern_struct_field_t *fields = + malloc(remainder * sizeof(fzl_extern_struct_field_t)); + if (!fields) + return false; + + for (size_t i = 0; i < node->structure.entries_count; i++) + { + fzl_node_t *fnode = node->structure.entries[i]; + if (!gen_common(gen, fnode)) + { + free(fields); + return false; + } + + if (count >= remainder) + { + remainder *= 2; + fzl_extern_struct_field_t *newfields = + realloc(fields, remainder * sizeof(fzl_extern_struct_field_t)); + if (!newfields) + { + free(fields); + return false; + } + fields = newfields; + } + + fzl_type_t type; + char typecn[256]; + memset(typecn, 0, sizeof(typecn)); + + fzl_extern_struct_field_t *field = &fields[count++]; + + if (node->type == FZL_NODETYPE_DECLARATION) + { + field->name = (char *)fnode->var.identifier->token->value; + + bool resolved = gen_resolve_type(gen, fnode->var.type, &type, typecn); + if (!resolved) + { + free(fields); + return false; + } + + ssize_t slot = gen_resolve_extern_type(gen, typecn); + if (slot == -1) + field->type = + (fzl_extern_type_ref_t){.is_primitive = true, .primitive = type}; + else + field->type = + (fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot}; + } + else if (node->type == FZL_NODETYPE_IDENTIFIER) + { + field->name = (char *)fnode->token->value; + + ssize_t slot = gen_resolve_extern_type(gen, typecn); + if (slot == -1) + { + free(fields); + return false; + } + else + field->type = + (fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot}; + } + else + { + free(fields); + return false; + } + } + + type_buf.structure.fields = fields; + type_buf.structure.fields_count = count; + + return true; +} diff --git a/src/compiler/generator/gen_typedef.c b/src/compiler/generator/gen_typedef.c new file mode 100644 index 0000000..bfe8eb9 --- /dev/null +++ b/src/compiler/generator/gen_typedef.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include + +fzl_extern_type_t type_buf; + +// Type definition +bool gen_typedef(fzl_gen_t *gen, fzl_node_t *node) +{ + if (!gen || !node) + return false; + + memset(&type_buf, 0, sizeof(type_buf)); + if (!gen_common(gen, node->typedefinition.type)) + return false; + + fzl_extern_type_t *newtype = &gen->extern_types[gen->extern_types_count++]; + newtype->lib_slot = gen->extern_libs_count - 1; + newtype->name = node->typedefinition.typename; + + switch (type_buf.kind) + { + case FZL_EXTERN_KIND_REF: + newtype->kind = FZL_EXTERN_KIND_REF; + newtype->ref_target = type_buf.ref_target; + break; + + case FZL_EXTERN_KIND_HANDLE: + newtype->kind = FZL_EXTERN_KIND_HANDLE; + break; + + case FZL_EXTERN_KIND_ALIAS: + newtype->alias_target = type_buf.alias_target; + break; + + case FZL_EXTERN_KIND_STRUCT: + newtype->structure.fields = type_buf.structure.fields; + newtype->structure.fields_count = type_buf.structure.fields_count; + break; + } + + return true; +}