diff options
| author | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-27 01:22:42 +0000 |
|---|---|---|
| committer | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-27 01:22:42 +0000 |
| commit | 938773d9cc062fd028f6560b1127a2ecd23f61c3 (patch) | |
| tree | 403aacd629975440ba23a645975c34a141d634ee /src/codegen | |
| parent | 2f47bdf7f49f05bd421e4182635f489c8cae01b3 (diff) | |
Fixed constant hex/oct bug + Fixed some of the examples (work in progress) + added bootloader example (I will add some docs)
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/codegen.h | 22 | ||||
| -rw-r--r-- | src/codegen/codegen_decl.c | 88 | ||||
| -rw-r--r-- | src/codegen/codegen_stmt.c | 35 | ||||
| -rw-r--r-- | src/codegen/codegen_utils.c | 9 | ||||
| -rw-r--r-- | src/codegen/compat.h | 8 |
5 files changed, 101 insertions, 61 deletions
diff --git a/src/codegen/codegen.h b/src/codegen/codegen.h index 9d32110..b3e971d 100644 --- a/src/codegen/codegen.h +++ b/src/codegen/codegen.h @@ -11,7 +11,7 @@ /** * @brief Generates code for a given AST node. - * + * * @param ctx Parser context. * @param node The AST node to generate code for. * @param out Output file stream. @@ -76,19 +76,19 @@ int emit_tests_and_runner(ParserContext *ctx, ASTNode *node, FILE *out); void print_type_defs(ParserContext *ctx, FILE *out, ASTNode *nodes); // Global state (shared across modules). -extern ASTNode *global_user_structs; ///< List of user defined structs. -extern char *g_current_impl_type; ///< Type currently being implemented (in impl block). -extern int tmp_counter; ///< Counter for temporary variables. -extern int defer_count; ///< Counter for defer statements in current scope. -extern ASTNode *defer_stack[]; ///< Stack of deferred nodes. -extern ASTNode *g_current_lambda; ///< Current lambda being generated. -extern char *g_current_func_ret_type; ///< Return type of current function. +extern ASTNode *global_user_structs; ///< List of user defined structs. +extern char *g_current_impl_type; ///< Type currently being implemented (in impl block). +extern int tmp_counter; ///< Counter for temporary variables. +extern int defer_count; ///< Counter for defer statements in current scope. +extern ASTNode *defer_stack[]; ///< Stack of deferred nodes. +extern ASTNode *g_current_lambda; ///< Current lambda being generated. +extern char *g_current_func_ret_type; ///< Return type of current function. // Defer boundary tracking for proper defer execution on break/continue/return #define MAX_DEFER 1024 #define MAX_LOOP_DEPTH 64 -extern int loop_defer_boundary[]; ///< Defer stack index at start of each loop. -extern int loop_depth; ///< Current loop nesting depth. -extern int func_defer_boundary; ///< Defer stack index at function entry. +extern int loop_defer_boundary[]; ///< Defer stack index at start of each loop. +extern int loop_depth; ///< Current loop nesting depth. +extern int func_defer_boundary; ///< Defer stack index at function entry. #endif diff --git a/src/codegen/codegen_decl.c b/src/codegen/codegen_decl.c index d59511d..10294e4 100644 --- a/src/codegen/codegen_decl.c +++ b/src/codegen/codegen_decl.c @@ -34,13 +34,9 @@ static void emit_freestanding_preamble(FILE *out) fputs("#define _z_arg(x) _Generic((x), _Bool: _z_bool_str(x), default: (x))\n", out); fputs("typedef struct { void *func; void *ctx; } z_closure_T;\n", out); - fputs("__attribute__((weak)) void* z_malloc(usize sz) { return NULL; }\n", out); - fputs("__attribute__((weak)) void* z_realloc(void* ptr, usize sz) { return " - "NULL; }\n", - out); - fputs("__attribute__((weak)) void z_free(void* ptr) { }\n", out); - fputs("__attribute__((weak)) void z_print(const char* fmt, ...) { }\n", out); - fputs("__attribute__((weak)) void z_panic(const char* msg) { while(1); }\n", out); + // In true freestanding, explicit definitions of z_malloc/etc are removed. + // The user must implement them if they use features requiring them. + // Most primitives (integers, pointers) work without them. } void emit_preamble(ParserContext *ctx, FILE *out) @@ -48,6 +44,7 @@ void emit_preamble(ParserContext *ctx, FILE *out) if (g_config.is_freestanding) { emit_freestanding_preamble(out); + return; } else { @@ -1034,53 +1031,52 @@ void print_type_defs(ParserContext *ctx, FILE *out, ASTNode *nodes) if (!g_config.is_freestanding) { fprintf(out, "typedef char* string;\n"); - } + - fprintf(out, "typedef struct { void **data; int len; int cap; } Vec;\n"); - fprintf(out, "#define Vec_new() (Vec){.data=0, .len=0, .cap=0}\n"); + fprintf(out, "typedef struct { void **data; int len; int cap; } Vec;\n"); + fprintf(out, "#define Vec_new() (Vec){.data=0, .len=0, .cap=0}\n"); - if (g_config.use_cpp) - { - fprintf(out, "void _z_vec_push(Vec *v, void *item) { if(v->len >= v->cap) { " - "v->cap = v->cap?v->cap*2:8; " - "v->data = static_cast<void**>(realloc(v->data, v->cap * sizeof(void*))); } " - "v->data[v->len++] = item; }\n"); - fprintf(out, "static inline Vec _z_make_vec(int count, ...) { Vec v = {0}; v.cap = " - "count > 8 ? " - "count : 8; v.data = static_cast<void**>(malloc(v.cap * sizeof(void*))); " - "v.len = 0; va_list " - "args; " - "va_start(args, count); for(int i=0; i<count; i++) { v.data[v.len++] = " - "va_arg(args, void*); } va_end(args); return v; }\n"); - } - else - { - fprintf(out, "void _z_vec_push(Vec *v, void *item) { if(v->len >= v->cap) { " - "v->cap = v->cap?v->cap*2:8; " - "v->data = z_realloc(v->data, v->cap * sizeof(void*)); } " - "v->data[v->len++] = item; }\n"); - fprintf(out, "static inline Vec _z_make_vec(int count, ...) { Vec v = {0}; v.cap = " - "count > 8 ? " - "count : 8; v.data = z_malloc(v.cap * sizeof(void*)); v.len = 0; va_list " - "args; " - "va_start(args, count); for(int i=0; i<count; i++) { v.data[v.len++] = " - "va_arg(args, void*); } va_end(args); return v; }\n"); - } - fprintf(out, "#define Vec_push(v, i) _z_vec_push(&(v), (void*)(long)(i))\n"); + if (g_config.use_cpp) + { + fprintf(out, "void _z_vec_push(Vec *v, void *item) { if(v->len >= v->cap) { " + "v->cap = v->cap?v->cap*2:8; " + "v->data = static_cast<void**>(realloc(v->data, v->cap * sizeof(void*))); } " + "v->data[v->len++] = item; }\n"); + fprintf(out, "static inline Vec _z_make_vec(int count, ...) { Vec v = {0}; v.cap = " + "count > 8 ? " + "count : 8; v.data = static_cast<void**>(malloc(v.cap * sizeof(void*))); " + "v.len = 0; va_list " + "args; " + "va_start(args, count); for(int i=0; i<count; i++) { v.data[v.len++] = " + "va_arg(args, void*); } va_end(args); return v; }\n"); + } + else + { + fprintf(out, "void _z_vec_push(Vec *v, void *item) { if(v->len >= v->cap) { " + "v->cap = v->cap?v->cap*2:8; " + "v->data = z_realloc(v->data, v->cap * sizeof(void*)); } " + "v->data[v->len++] = item; }\n"); + fprintf(out, "static inline Vec _z_make_vec(int count, ...) { Vec v = {0}; v.cap = " + "count > 8 ? " + "count : 8; v.data = z_malloc(v.cap * sizeof(void*)); v.len = 0; va_list " + "args; " + "va_start(args, count); for(int i=0; i<count; i++) { v.data[v.len++] = " + "va_arg(args, void*); } va_end(args); return v; }\n"); + } + fprintf(out, "#define Vec_push(v, i) _z_vec_push(&(v), (void*)(long)(i))\n"); - if (g_config.is_freestanding) - { fprintf(out, "#define _z_check_bounds(index, limit) ({ ZC_AUTO _i = " - "(index); if(_i < 0 " - "|| _i >= (limit)) { z_panic(\"index out of bounds\"); } _i; })\n"); + "(index); if(_i < 0 " + "|| _i >= (limit)) { fprintf(stderr, \"Index out of bounds: " + "%%ld (limit " + "%%d)\\n\", (long)_i, (int)(limit)); exit(1); } _i; })\n"); } else { - fprintf(out, "#define _z_check_bounds(index, limit) ({ ZC_AUTO _i = " + // We might need to change this later. So TODO. + fprintf(out, "#define _z_check_bounds(index, limit) ({ ZC_AUTO _i = " "(index); if(_i < 0 " - "|| _i >= (limit)) { fprintf(stderr, \"Index out of bounds: " - "%%ld (limit " - "%%d)\\n\", (long)_i, (int)(limit)); exit(1); } _i; })\n"); + "|| _i >= (limit)) { z_panic(\"index out of bounds\"); } _i; })\n"); } SliceType *c = ctx->used_slices; diff --git a/src/codegen/codegen_stmt.c b/src/codegen/codegen_stmt.c index 43e5bb5..6e41109 100644 --- a/src/codegen/codegen_stmt.c +++ b/src/codegen/codegen_stmt.c @@ -697,6 +697,41 @@ void codegen_node_single(ParserContext *ctx, ASTNode *node, FILE *out) fprintf(out, "{\n"); char *prev_ret = g_current_func_ret_type; g_current_func_ret_type = node->func.ret_type; + + // Initialize drop flags for arguments that implement Drop + for (int i = 0; i < node->func.arg_count; i++) + { + Type *arg_type = node->func.arg_types[i]; + char *arg_name = node->func.param_names[i]; + if (arg_type && arg_name) + { + // Check if type implements Drop + int has_drop = 0; + if (arg_type->kind == TYPE_STRUCT && arg_type->name) + { + ASTNode *def = find_struct_def(ctx, arg_type->name); + if (def && def->type == NODE_STRUCT && def->type_info && + def->type_info->traits.has_drop) + { + has_drop = 1; + } + else if (def) + { + // No drop needed + } + else + { + // No struct def found + } + } + + if (has_drop) + { + fprintf(out, " int __z_drop_flag_%s = 1;\n", arg_name); + } + } + } + codegen_walker(ctx, node->func.body, out); for (int i = defer_count - 1; i >= 0; i--) { diff --git a/src/codegen/codegen_utils.c b/src/codegen/codegen_utils.c index c48f4eb..8de3cf6 100644 --- a/src/codegen/codegen_utils.c +++ b/src/codegen/codegen_utils.c @@ -474,6 +474,15 @@ char *infer_type(ParserContext *ctx, ASTNode *node) return node->struct_init.struct_name; } + if (node->type == NODE_EXPR_ARRAY_LITERAL) + { + if (node->type_info) + { + return type_to_string(node->type_info); + } + return NULL; + } + if (node->type == NODE_EXPR_LITERAL) { if (node->literal.type_kind == LITERAL_STRING) diff --git a/src/codegen/compat.h b/src/codegen/compat.h index f34d612..f2d221a 100644 --- a/src/codegen/compat.h +++ b/src/codegen/compat.h @@ -14,10 +14,10 @@ #define ZC_EXTERN_C_END } #else /* C mode */ -#define ZC_AUTO __auto_type ///< Auto type inference. -#define ZC_CAST(T, x) ((T)(x)) ///< Explicit cast. -#define ZC_REINTERPRET(T, x) ((T)(x)) ///< Reinterpret cast. -#define ZC_EXTERN_C ///< Extern "C" (no-op in C). +#define ZC_AUTO __auto_type ///< Auto type inference. +#define ZC_CAST(T, x) ((T)(x)) ///< Explicit cast. +#define ZC_REINTERPRET(T, x) ((T)(x)) ///< Reinterpret cast. +#define ZC_EXTERN_C ///< Extern "C" (no-op in C). #define ZC_EXTERN_C_BEGIN #define ZC_EXTERN_C_END #endif |
