feat: add prepared error/null ok returns from gen_* functions

This commit is contained in:
samsonium
2026-11-04 22:52:40 +03:00
parent aae183c0c0
commit 181458ecda
18 changed files with 232 additions and 66 deletions
+3 -2
View File
@@ -20,6 +20,8 @@ typedef struct
char *classname;
} gen_res_t;
extern gen_res_t gen_error;
extern gen_res_t gen_ok_null;
extern char *null_name;
extern fzl_extern_type_t type_buf;
@@ -51,10 +53,9 @@ gen_res_t gen_construct(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_field(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_fn(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_return(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_not(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_unary_logical(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_compare(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_logical(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_unary_logical(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_condition(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_unary_math(fzl_gen_t *gen, fzl_node_t *node);
gen_res_t gen_declaration(fzl_gen_t *gen, fzl_node_t *node);
+3 -3
View File
@@ -8,7 +8,7 @@
gen_res_t gen_alias(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
fzl_type_t type;
char typecn[256];
@@ -16,7 +16,7 @@ gen_res_t gen_alias(fzl_gen_t *gen, fzl_node_t *node)
bool resolved = gen_resolve_type(gen, node->token, &type, typecn);
if (!resolved)
return (gen_res_t){.error = true};
return gen_error;
ssize_t slot = gen_resolve_extern_type(gen, typecn);
if (slot == -1)
@@ -26,5 +26,5 @@ gen_res_t gen_alias(fzl_gen_t *gen, fzl_node_t *node)
type_buf.alias_target =
(fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot};
return (gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
return gen_ok_null;
}
+3 -3
View File
@@ -8,7 +8,7 @@
gen_res_t gen_break(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
fzl_gen_ctx_t *ctx = gen->ctx;
while (ctx != NULL)
@@ -20,7 +20,7 @@ gen_res_t gen_break(fzl_gen_t *gen, fzl_node_t *node)
}
if (!ctx || ctx->type != FZL_GEN_CTX_TYPE_LOOP)
return (gen_res_t){.error = true};
return gen_error;
for (size_t i = gen->syms_top - 1; i > ctx->level + 1; i--)
gen_op(gen, FZL_OPCODE_RM_ENVTABLE);
@@ -29,5 +29,5 @@ gen_res_t gen_break(fzl_gen_t *gen, fzl_node_t *node)
ctx->loop.breaks[ctx->loop.breaks_count++] = gen->ops_count;
gen_word(gen, 0);
return (gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
return gen_ok_null;
}
+6 -6
View File
@@ -9,11 +9,11 @@
gen_res_t gen_class(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
fzl_gen_ctx_t *ctx = gen_ctx(gen, FZL_GEN_CTX_TYPE_CLASS, node);
if (!ctx)
return (gen_res_t){.error = true};
return gen_error;
gen->classes[gen->classes_count] = fzl_mkctable(node->class.name->value);
fzl_ctable_t *class = gen->classes[gen->classes_count++];
@@ -37,7 +37,7 @@ gen_res_t gen_class(fzl_gen_t *gen, fzl_node_t *node)
if (!resolved)
{
free(class->fields);
return (gen_res_t){.error = true};
return gen_error;
}
class->fields[class->fields_count] = (fzl_ctable_field_t){
@@ -66,7 +66,7 @@ gen_res_t gen_class(fzl_gen_t *gen, fzl_node_t *node)
if (gen_common(gen, fn).error)
{
free(class->fields);
return (gen_res_t){.error = true};
return gen_error;
}
}
@@ -74,8 +74,8 @@ gen_res_t gen_class(fzl_gen_t *gen, fzl_node_t *node)
if (!ctx)
{
free(class->fields);
return (gen_res_t){.error = true};
return gen_error;
}
return (gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
return gen_ok_null;
}
+7 -2
View File
@@ -1,3 +1,4 @@
#include <common/fzl_types.h>
#include <compiler/fzl_gen.h>
#include <compiler/fzl_parser.h>
#include <compiler/internals/gen.h>
@@ -6,11 +7,15 @@
typedef gen_res_t (*gen_handle_fn)(fzl_gen_t *, fzl_node_t *);
gen_res_t gen_error = (gen_res_t){.error = true};
gen_res_t gen_ok_null =
(gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
// Common generator entry point
gen_res_t gen_common(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
gen_handle_fn res = NULL;
switch (node->type)
@@ -137,7 +142,7 @@ gen_res_t gen_common(fzl_gen_t *gen, fzl_node_t *node)
}
if (!res)
return (gen_res_t){.error = true};
return gen_error;
return res(gen, node);
}
+2 -2
View File
@@ -7,7 +7,7 @@
gen_res_t gen_construct(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
fzl_node_t *classname = node->construct.name;
fzl_ctable_t *ct = NULL;
@@ -20,7 +20,7 @@ gen_res_t gen_construct(fzl_gen_t *gen, fzl_node_t *node)
}
}
if (!ct)
return (gen_res_t){.error = true};
return gen_error;
gen_op(gen, FZL_OPCODE_ALLOC_OBJECT);
gen_word(gen, ct->fields_count);
+4 -4
View File
@@ -9,18 +9,18 @@
gen_res_t gen_extern(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
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]).error)
return (gen_res_t){.error = true};
return gen_error;
for (size_t i = 0; i < node->ext.fns_count; i++)
if (gen_common(gen, node->ext.fns[i]).error)
return (gen_res_t){.error = true};
return gen_error;
return (gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
return gen_ok_null;
}
+20 -13
View File
@@ -14,23 +14,23 @@
gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
fzl_gen_ctx_t *ctx = gen_ctx(gen, FZL_GEN_CTX_TYPE_FUNCTION, node);
if (!ctx)
return (gen_res_t){.error = true};
return gen_error;
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 (gen_res_t){.error = true};
return gen_error;
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 (gen_res_t){.error = true};
return gen_error;
if (args_count >= args_remainder)
{
@@ -40,7 +40,7 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
if (!newargs)
{
free(args);
return (gen_res_t){.error = true};
return gen_error;
}
args = newargs;
@@ -49,7 +49,7 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
if (argnode->type != FZL_NODETYPE_DECLARATION)
{
free(args);
return (gen_res_t){.error = true};
return gen_error;
}
fzl_extern_arg_t *arg = &args[args_count++];
@@ -62,7 +62,7 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
if (!resolved)
{
free(args);
return (gen_res_t){.error = true};
return gen_error;
}
ssize_t slot = gen_resolve_extern_type(gen, argcn);
@@ -81,7 +81,7 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
if (!ctx)
{
free(args);
return (gen_res_t){.error = true};
return gen_error;
}
fzl_type_t ret;
@@ -92,15 +92,22 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
if (!resolved)
{
free(args);
return (gen_res_t){.error = true};
return gen_error;
}
fzl_symtable_res_t res = fzl_symt_put(gen->syms[0], node, node->ext_fn.name,
FZL_TYPE_EXTERN_FN, 0);
fzl_symtable_res_t res =
fzl_symt_put(gen->syms[0], node, node->ext_fn.name, ret, 0);
if (res != FZL_SYMTABLE_RESULT_OK)
{
free(args);
return (gen_res_t){.error = true};
return gen_error;
}
res = fzl_symt_setobjclass(gen->syms[0], node->ext_fn.name, retname);
if (res != FZL_SYMTABLE_RESULT_OK)
{
free(args);
return gen_error;
}
fzl_extern_fn_t *result = &gen->extern_fns[gen->extern_fns_count++];
@@ -120,5 +127,5 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
result->used_name = node->ext_fn.name;
result->symbol_name = node->ext_fn.original_name;
return (gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
return gen_ok_null;
}
+4 -4
View File
@@ -6,11 +6,11 @@
gen_res_t gen_field(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
gen_res_t parent_res = gen_common(gen, node->memb.parent);
if (parent_res.error)
return (gen_res_t){.error = true};
return gen_error;
fzl_ctable_t *ct = NULL;
for (size_t i = 0; i < gen->classes_count; i++)
@@ -23,7 +23,7 @@ gen_res_t gen_field(fzl_gen_t *gen, fzl_node_t *node)
}
if (!ct)
return (gen_res_t){.error = true};
return gen_error;
fzl_token_t *ftok = node->memb.field->token;
fzl_ctable_field_t ctf;
@@ -39,7 +39,7 @@ gen_res_t gen_field(fzl_gen_t *gen, fzl_node_t *node)
}
if (!field_exists)
return (gen_res_t){.error = true};
return gen_error;
gen_op(gen, FZL_OPCODE_GET_FIELD);
gen_word(gen, ctf.slot_index);
+2 -2
View File
@@ -7,11 +7,11 @@
gen_res_t gen_fmtstr(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
for (size_t i = 0; i < node->list.entry_count; i++)
if (gen_common(gen, node->list.entries[i]).error)
return (gen_res_t){.error = true};
return gen_error;
gen_op(gen, FZL_OPCODE_BUILD_STR);
gen_word(gen, node->list.entry_count);
+66
View File
@@ -0,0 +1,66 @@
#include <compiler/fzl_gen.h>
#include <compiler/internals/gen.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
// Function definition
gen_res_t gen_fn(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return gen_error;
gen_op(gen, FZL_OPCODE_JMP);
size_t skip_ip = gen->ops_count;
gen_word(gen, (uint64_t)0);
fzl_type_t fntype;
char fntypcn[256];
memset(fntypcn, 0, sizeof(fntypcn));
bool resolved = gen_resolve_type(gen, node->fn.type, &fntype, fntypcn);
if (!resolved)
return gen_error;
fzl_symtable_res_t putres =
fzl_symt_put(gen->syms[gen->syms_top - 1], node, node->fn.name->value,
fntype, gen->ops_count);
if (putres != FZL_SYMTABLE_RESULT_OK)
return gen_error;
if (fntype == FZL_TYPE_OBJECT)
{
fzl_symtable_res_t updres = fzl_symt_setobjclass(
gen->syms[gen->syms_top - 1], node->fn.name->value, fntypcn);
if (updres != FZL_SYMTABLE_RESULT_OK)
return gen_error;
}
fzl_gen_ctx_t *ctx = gen_ctx(gen, FZL_GEN_CTX_TYPE_FUNCTION, node);
if (!ctx)
return gen_error;
gen_op(gen, FZL_OPCODE_MK_ENVTABLE);
for (ssize_t i = node->fn.args_count - 1; i >= 0; i--)
{
if (gen_common(gen, node->fn.args[i]).error)
return gen_error;
gen_op(gen, FZL_OPCODE_WRITE);
}
if (gen_common(gen, node->fn.body).error)
return gen_error;
gen_op(gen, FZL_OPCODE_RM_ENVTABLE);
gen_op(gen, FZL_OPCODE_RET);
gen->ops[skip_ip] = gen->ops_count;
ctx = gen_fin_ctx(gen);
if (!ctx)
return gen_error;
return (gen_res_t){.error = false, .type = fntype, .classname = fntypcn};
}
+2 -2
View File
@@ -6,8 +6,8 @@
gen_res_t gen_handle(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
type_buf.kind = FZL_EXTERN_KIND_HANDLE;
return (gen_res_t){.error = false};
return gen_ok_null;
}
+8 -8
View File
@@ -8,23 +8,23 @@
gen_res_t gen_loop(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
fzl_gen_ctx_t *ctx = gen_ctx(gen, FZL_GEN_CTX_TYPE_LOOP, node);
if (!ctx)
return (gen_res_t){.error = true};
return gen_error;
gen_op(gen, FZL_OPCODE_MK_ENVTABLE);
if (node->loop.init)
if (gen_common(gen, node->loop.init).error)
return (gen_res_t){.error = true};
return gen_error;
size_t start_ip = gen->ops_count;
if (node->loop.cond)
{
if (gen_common(gen, node->loop.cond).error)
return (gen_res_t){.error = true};
return gen_error;
}
else
{
@@ -37,11 +37,11 @@ gen_res_t gen_loop(fzl_gen_t *gen, fzl_node_t *node)
gen_word(gen, 0);
if (gen_common(gen, node->loop.body).error)
return (gen_res_t){.error = true};
return gen_error;
if (node->loop.step)
if (gen_common(gen, node->loop.step).error)
return (gen_res_t){.error = true};
return gen_error;
gen_op(gen, FZL_OPCODE_JMP);
gen_word(gen, start_ip);
@@ -57,7 +57,7 @@ gen_res_t gen_loop(fzl_gen_t *gen, fzl_node_t *node)
ctx = gen_fin_ctx(gen);
if (!ctx)
return (gen_res_t){.error = true};
return gen_error;
return (gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
return gen_ok_null;
}
+3 -3
View File
@@ -9,16 +9,16 @@
gen_res_t gen_reference(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
char *refname = (char *)node->token->value;
ssize_t slot = gen_resolve_extern_type(gen, refname);
if (slot == -1)
return (gen_res_t){.error = true};
return gen_error;
type_buf.kind = FZL_EXTERN_KIND_REF;
type_buf.ref_target =
(fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot};
return (gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
return gen_ok_null;
}
+64
View File
@@ -0,0 +1,64 @@
#include <common/fzl_types.h>
#include <compiler/fzl_gen.h>
#include <compiler/internals/gen.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
// Return keyword
gen_res_t gen_return(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return gen_error;
fzl_gen_ctx_t *ctx = gen->ctx;
while (ctx != NULL)
{
if (ctx && ctx->type == FZL_GEN_CTX_TYPE_FUNCTION)
break;
ctx = ctx->parent;
}
if (!ctx || ctx->type != FZL_GEN_CTX_TYPE_FUNCTION)
return gen_error;
gen_res_t result;
bool returning_object = false;
if (node->ret.value)
{
gen_res_t retres = gen_common(gen, node->ret.value);
if (retres.error)
return gen_error;
fzl_node_t *fn_node = gen->ctx->function;
fzl_type_t fntype;
char fntypecn[256];
memset(fntypecn, 0, sizeof(fntypecn));
bool resolved = gen_resolve_type(gen, fn_node->fn.type, &fntype, fntypecn);
if (!resolved)
return gen_error;
if (!gen_is_types_compatible(retres.type, fntype, retres.classname,
fntypecn))
return gen_error;
if (retres.type == FZL_TYPE_OBJECT)
returning_object = true;
result = retres;
}
else
result = gen_ok_null;
for (size_t i = 0; i < (gen->syms_top - gen->ctx->level); i++)
{
if (returning_object)
gen_op(gen, FZL_OPCODE_ESCAPE_OBJECT);
gen_op(gen, FZL_OPCODE_RM_ENVTABLE);
}
gen_op(gen, FZL_OPCODE_RET);
return result;
}
+9 -9
View File
@@ -13,19 +13,19 @@
gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
type_buf.kind = FZL_EXTERN_KIND_STRUCT;
fzl_gen_ctx_t *ctx = gen_ctx(gen, FZL_GEN_CTX_TYPE_UNECCESSARY, node);
if (!ctx)
return (gen_res_t){.error = true};
return gen_error;
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 (gen_res_t){.error = true};
return gen_error;
for (size_t i = 0; i < node->structure.entries_count; i++)
{
@@ -33,7 +33,7 @@ gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
if (!gen_common(gen, fnode))
{
free(fields);
return (gen_res_t){.error = true};
return gen_error;
}
if (count >= remainder)
@@ -44,7 +44,7 @@ gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
if (!newfields)
{
free(fields);
return (gen_res_t){.error = true};
return gen_error;
}
fields = newfields;
}
@@ -63,7 +63,7 @@ gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
if (!resolved)
{
free(fields);
return (gen_res_t){.error = true};
return gen_error;
}
ssize_t slot = gen_resolve_extern_type(gen, typecn);
@@ -82,7 +82,7 @@ gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
if (slot == -1)
{
free(fields);
return (gen_res_t){.error = true};
return gen_error;
}
else
field->type =
@@ -91,12 +91,12 @@ gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
else
{
free(fields);
return (gen_res_t){.error = true};
return gen_error;
}
}
type_buf.structure.fields = fields;
type_buf.structure.fields_count = count;
return (gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
return gen_ok_null;
}
+3 -3
View File
@@ -11,11 +11,11 @@ fzl_extern_type_t type_buf;
gen_res_t gen_typedef(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return (gen_res_t){.error = true};
return gen_error;
memset(&type_buf, 0, sizeof(type_buf));
if (gen_common(gen, node->typedefinition.type).error)
return (gen_res_t){.error = true};
return gen_error;
fzl_extern_type_t *newtype = &gen->extern_types[gen->extern_types_count++];
newtype->lib_slot = gen->extern_libs_count - 1;
@@ -42,5 +42,5 @@ gen_res_t gen_typedef(fzl_gen_t *gen, fzl_node_t *node)
break;
}
return (gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
return gen_ok_null;
}
@@ -0,0 +1,23 @@
#include <common/fzl_opcodes.h>
#include <common/fzl_types.h>
#include <compiler/fzl_parser.h>
#include <compiler/internals/gen.h>
#include <stdio.h>
// Currently, only NOT operator
gen_res_t gen_unary_logical(fzl_gen_t *gen, fzl_node_t *node)
{
if (!gen || !node)
return gen_error;
gen_res_t operand_res = gen_common(gen, node->unary_op.operand);
if (operand_res.error)
return gen_error;
if (node->type == FZL_NODETYPE_NOT)
gen_op(gen, FZL_OPCODE_NOT);
else
return gen_error;
return (gen_res_t){.error = false, .type = FZL_TYPE_BOOL, .classname = NULL};
}