summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-27 01:22:42 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-27 01:22:42 +0000
commit938773d9cc062fd028f6560b1127a2ecd23f61c3 (patch)
tree403aacd629975440ba23a645975c34a141d634ee /src
parent2f47bdf7f49f05bd421e4182635f489c8cae01b3 (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')
-rw-r--r--src/analysis/typecheck.c8
-rw-r--r--src/analysis/typecheck.h6
-rw-r--r--src/ast/ast.h186
-rw-r--r--src/codegen/codegen.h22
-rw-r--r--src/codegen/codegen_decl.c88
-rw-r--r--src/codegen/codegen_stmt.c35
-rw-r--r--src/codegen/codegen_utils.c9
-rw-r--r--src/codegen/compat.h8
-rw-r--r--src/constants.h33
-rw-r--r--src/lsp/json_rpc.h8
-rw-r--r--src/lsp/lsp_index.h22
-rw-r--r--src/parser/parser.h188
-rw-r--r--src/parser/parser_decl.c5
-rw-r--r--src/parser/parser_expr.c56
-rw-r--r--src/parser/parser_utils.c4
-rw-r--r--src/plugins/plugin_manager.h2
-rw-r--r--src/repl/repl.h2
-rw-r--r--src/zen/zen_facts.h2
-rw-r--r--src/zprep.h172
19 files changed, 473 insertions, 383 deletions
diff --git a/src/analysis/typecheck.c b/src/analysis/typecheck.c
index e83bb4b..1faff2c 100644
--- a/src/analysis/typecheck.c
+++ b/src/analysis/typecheck.c
@@ -15,7 +15,10 @@ static void tc_error(TypeChecker *tc, Token t, const char *msg)
static void tc_enter_scope(TypeChecker *tc)
{
Scope *s = malloc(sizeof(Scope));
- if (!s) return;
+ if (!s)
+ {
+ return;
+ }
s->symbols = NULL;
s->parent = tc->current_scope;
tc->current_scope = s;
@@ -365,6 +368,9 @@ static void check_node(TypeChecker *tc, ASTNode *node)
case NODE_EXPR_CALL:
check_expr_call(tc, node);
break;
+ case NODE_EXPR_ARRAY_LITERAL:
+ check_node(tc, node->array_literal.elements);
+ break;
default:
// Generic recursion for lists and other nodes.
// Special case for Return to trigger move?
diff --git a/src/analysis/typecheck.h b/src/analysis/typecheck.h
index b690f1d..f141deb 100644
--- a/src/analysis/typecheck.h
+++ b/src/analysis/typecheck.h
@@ -9,7 +9,7 @@
// Unlike the parser, this focuses on semantic validity (types, definitions).
/**
* @brief Type Checker Context.
- *
+ *
* Holds the state during the semantic analysis pass.
* Unlike the parser, this focuses on semantic validity (types, definitions, correctness).
*/
@@ -24,9 +24,9 @@ typedef struct TypeChecker
/**
* @brief Main Type Checking Entry Point.
- *
+ *
* Performs semantic analysis on the entire AST.
- *
+ *
* @param ctx Global parser context.
* @param root Root AST node of the program.
* @return 0 on success (no errors), non-zero if errors occurred.
diff --git a/src/ast/ast.h b/src/ast/ast.h
index b95c80c..c971d54 100644
--- a/src/ast/ast.h
+++ b/src/ast/ast.h
@@ -28,37 +28,37 @@ typedef enum
*/
typedef enum
{
- TYPE_VOID, ///< `void` type.
- TYPE_BOOL, ///< `bool` type.
- TYPE_CHAR, ///< `char` type.
- TYPE_STRING, ///< `string` type.
- TYPE_U0, ///< `u0` type.
- TYPE_I8, ///< `i8` type.
- TYPE_U8, ///< `u8` type.
- TYPE_I16, ///< `i16` type.
- TYPE_U16, ///< `u16` type.
- TYPE_I32, ///< `i32` type.
- TYPE_U32, ///< `u32` type.
- TYPE_I64, ///< `i64` type.
- TYPE_U64, ///< `u64` type.
- TYPE_I128, ///< `i128` type.
- TYPE_U128, ///< `u128` type.
- TYPE_F32, ///< `f32` type.
- TYPE_F64, ///< `f64` type.
- TYPE_INT, ///< `int` (alias, usually i32).
- TYPE_FLOAT, ///< `float` (alias).
- TYPE_USIZE, ///< `usize` (pointer size unsigned).
- TYPE_ISIZE, ///< `isize` (pointer size signed).
- TYPE_BYTE, ///< `byte`.
- TYPE_RUNE, ///< `rune`.
- TYPE_UINT, ///< `uint` (alias).
- TYPE_STRUCT, ///< Struct type.
- TYPE_ENUM, ///< Enum type.
- TYPE_POINTER, ///< Pointer type (*).
- TYPE_ARRAY, ///< Fixed size array [N].
- TYPE_FUNCTION, ///< Function pointer or reference.
- TYPE_GENERIC, ///< Generic type parameter (T).
- TYPE_UNKNOWN ///< Unknown/unresolved type.
+ TYPE_VOID, ///< `void` type.
+ TYPE_BOOL, ///< `bool` type.
+ TYPE_CHAR, ///< `char` type.
+ TYPE_STRING, ///< `string` type.
+ TYPE_U0, ///< `u0` type.
+ TYPE_I8, ///< `i8` type.
+ TYPE_U8, ///< `u8` type.
+ TYPE_I16, ///< `i16` type.
+ TYPE_U16, ///< `u16` type.
+ TYPE_I32, ///< `i32` type.
+ TYPE_U32, ///< `u32` type.
+ TYPE_I64, ///< `i64` type.
+ TYPE_U64, ///< `u64` type.
+ TYPE_I128, ///< `i128` type.
+ TYPE_U128, ///< `u128` type.
+ TYPE_F32, ///< `f32` type.
+ TYPE_F64, ///< `f64` type.
+ TYPE_INT, ///< `int` (alias, usually i32).
+ TYPE_FLOAT, ///< `float` (alias).
+ TYPE_USIZE, ///< `usize` (pointer size unsigned).
+ TYPE_ISIZE, ///< `isize` (pointer size signed).
+ TYPE_BYTE, ///< `byte`.
+ TYPE_RUNE, ///< `rune`.
+ TYPE_UINT, ///< `uint` (alias).
+ TYPE_STRUCT, ///< Struct type.
+ TYPE_ENUM, ///< Enum type.
+ TYPE_POINTER, ///< Pointer type (*).
+ TYPE_ARRAY, ///< Fixed size array [N].
+ TYPE_FUNCTION, ///< Function pointer or reference.
+ TYPE_GENERIC, ///< Generic type parameter (T).
+ TYPE_UNKNOWN ///< Unknown/unresolved type.
} TypeKind;
/**
@@ -74,9 +74,9 @@ typedef struct Type
int is_const; ///< 1 if const-qualified.
int is_explicit_struct; ///< 1 if defined with "struct" keyword explicitly.
int is_raw; // Raw function pointer (fn*)
+ int array_size; ///< Size for fixed-size arrays.
union
{
- int array_size; ///< Size for fixed-size arrays.
int is_varargs; ///< 1 if function type is variadic.
int is_restrict; ///< 1 if pointer is restrict-qualified.
struct
@@ -93,67 +93,67 @@ typedef struct Type
*/
typedef enum
{
- NODE_ROOT, ///< Root of the AST.
- NODE_FUNCTION, ///< Function definition.
- NODE_BLOCK, ///< Code block { ... }.
- NODE_RETURN, ///< Return statement.
- NODE_VAR_DECL, ///< Variable declaration.
- NODE_CONST, ///< Constant definition.
- NODE_TYPE_ALIAS, ///< Type alias (typedef).
- NODE_IF, ///< If statement.
- NODE_WHILE, ///< While loop.
- NODE_FOR, ///< For loop.
- NODE_FOR_RANGE, ///< For-range loop (iterator).
- NODE_LOOP, ///< Infinite loop.
- NODE_REPEAT, ///< Repeat loop (n times).
- NODE_UNLESS, ///< Unless statement (if !cond).
- NODE_GUARD, ///< Guard clause (if !cond return).
- NODE_BREAK, ///< Break statement.
- NODE_CONTINUE, ///< Continue statement.
- NODE_MATCH, ///< Match statement.
- NODE_MATCH_CASE, ///< Case within match.
- NODE_EXPR_BINARY, ///< Binary expression (a + b).
- NODE_EXPR_UNARY, ///< Unary expression (!a).
- NODE_EXPR_LITERAL, ///< Literal value.
- NODE_EXPR_VAR, ///< Variable reference.
- NODE_EXPR_CALL, ///< Function call.
- NODE_EXPR_MEMBER, ///< Member access (a.b).
- NODE_EXPR_INDEX, ///< Array index (a[b]).
- NODE_EXPR_CAST, ///< Type cast.
- NODE_EXPR_SIZEOF, ///< Sizeof expression.
- NODE_EXPR_STRUCT_INIT, ///< Struct initializer.
- NODE_EXPR_ARRAY_LITERAL,///< Array literal.
- NODE_EXPR_SLICE, ///< Slice operation.
- NODE_STRUCT, ///< Struct definition.
- NODE_FIELD, ///< Struct field.
- NODE_ENUM, ///< Enum definition.
- NODE_ENUM_VARIANT, ///< Enum variant.
- NODE_TRAIT, ///< Trait definition.
- NODE_IMPL, ///< Impl block.
- NODE_IMPL_TRAIT, ///< Trait implementation.
- NODE_INCLUDE, ///< Include directive.
- NODE_RAW_STMT, ///< Raw statement (transpiler bypass).
- NODE_TEST, ///< Test block.
- NODE_ASSERT, ///< Assert statement.
- NODE_DEFER, ///< Defer statement.
- NODE_DESTRUCT_VAR, ///< Destructuring declaration.
- NODE_TERNARY, ///< Ternary expression (?:).
- NODE_ASM, ///< Assembly block.
- NODE_LAMBDA, ///< Lambda function.
- NODE_PLUGIN, ///< Plugin invocation.
- NODE_GOTO, ///< Goto statement.
- NODE_LABEL, ///< Label.
- NODE_DO_WHILE, ///< Do-while loop.
- NODE_TYPEOF, ///< Typeof operator.
- NODE_TRY, ///< Try statement (error handling).
- NODE_REFLECTION, ///< Reflection info.
- NODE_AWAIT, ///< Await expression.
- NODE_REPL_PRINT, ///< Implicit print (REPL).
- NODE_CUDA_LAUNCH, ///< CUDA kernel launch (<<<...>>>).
- NODE_VA_START, ///< va_start intrinsic.
- NODE_VA_END, ///< va_end intrinsic.
- NODE_VA_COPY, ///< va_copy intrinsic.
- NODE_VA_ARG ///< va_arg intrinsic.
+ NODE_ROOT, ///< Root of the AST.
+ NODE_FUNCTION, ///< Function definition.
+ NODE_BLOCK, ///< Code block { ... }.
+ NODE_RETURN, ///< Return statement.
+ NODE_VAR_DECL, ///< Variable declaration.
+ NODE_CONST, ///< Constant definition.
+ NODE_TYPE_ALIAS, ///< Type alias (typedef).
+ NODE_IF, ///< If statement.
+ NODE_WHILE, ///< While loop.
+ NODE_FOR, ///< For loop.
+ NODE_FOR_RANGE, ///< For-range loop (iterator).
+ NODE_LOOP, ///< Infinite loop.
+ NODE_REPEAT, ///< Repeat loop (n times).
+ NODE_UNLESS, ///< Unless statement (if !cond).
+ NODE_GUARD, ///< Guard clause (if !cond return).
+ NODE_BREAK, ///< Break statement.
+ NODE_CONTINUE, ///< Continue statement.
+ NODE_MATCH, ///< Match statement.
+ NODE_MATCH_CASE, ///< Case within match.
+ NODE_EXPR_BINARY, ///< Binary expression (a + b).
+ NODE_EXPR_UNARY, ///< Unary expression (!a).
+ NODE_EXPR_LITERAL, ///< Literal value.
+ NODE_EXPR_VAR, ///< Variable reference.
+ NODE_EXPR_CALL, ///< Function call.
+ NODE_EXPR_MEMBER, ///< Member access (a.b).
+ NODE_EXPR_INDEX, ///< Array index (a[b]).
+ NODE_EXPR_CAST, ///< Type cast.
+ NODE_EXPR_SIZEOF, ///< Sizeof expression.
+ NODE_EXPR_STRUCT_INIT, ///< Struct initializer.
+ NODE_EXPR_ARRAY_LITERAL, ///< Array literal.
+ NODE_EXPR_SLICE, ///< Slice operation.
+ NODE_STRUCT, ///< Struct definition.
+ NODE_FIELD, ///< Struct field.
+ NODE_ENUM, ///< Enum definition.
+ NODE_ENUM_VARIANT, ///< Enum variant.
+ NODE_TRAIT, ///< Trait definition.
+ NODE_IMPL, ///< Impl block.
+ NODE_IMPL_TRAIT, ///< Trait implementation.
+ NODE_INCLUDE, ///< Include directive.
+ NODE_RAW_STMT, ///< Raw statement (transpiler bypass).
+ NODE_TEST, ///< Test block.
+ NODE_ASSERT, ///< Assert statement.
+ NODE_DEFER, ///< Defer statement.
+ NODE_DESTRUCT_VAR, ///< Destructuring declaration.
+ NODE_TERNARY, ///< Ternary expression (?:).
+ NODE_ASM, ///< Assembly block.
+ NODE_LAMBDA, ///< Lambda function.
+ NODE_PLUGIN, ///< Plugin invocation.
+ NODE_GOTO, ///< Goto statement.
+ NODE_LABEL, ///< Label.
+ NODE_DO_WHILE, ///< Do-while loop.
+ NODE_TYPEOF, ///< Typeof operator.
+ NODE_TRY, ///< Try statement (error handling).
+ NODE_REFLECTION, ///< Reflection info.
+ NODE_AWAIT, ///< Await expression.
+ NODE_REPL_PRINT, ///< Implicit print (REPL).
+ NODE_CUDA_LAUNCH, ///< CUDA kernel launch (<<<...>>>).
+ NODE_VA_START, ///< va_start intrinsic.
+ NODE_VA_END, ///< va_end intrinsic.
+ NODE_VA_COPY, ///< va_copy intrinsic.
+ NODE_VA_ARG ///< va_arg intrinsic.
} NodeType;
// ** AST Node Structure **
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
diff --git a/src/constants.h b/src/constants.h
index a867bf3..5162f9f 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -3,21 +3,22 @@
#define ZEN_CONSTANTS_H
// Buffer sizes
-// Buffer sizes
-#define MAX_TYPE_NAME_LEN 256 ///< Max length for type name strings.
-#define MAX_FUNC_NAME_LEN 512 ///< Max length for function names.
-#define MAX_ERROR_MSG_LEN 1024 ///< Max length for error messages.
-#define MAX_MANGLED_NAME_LEN 512 ///< Max length for mangled names (generics).
-#define MAX_PATH_LEN 4096 ///< Max length for file paths.
+#define MAX_TYPE_NAME_LEN 256 ///< Max length for type name strings.
+#define MAX_FUNC_NAME_LEN 512 ///< Max length for function names.
+#define MAX_ERROR_MSG_LEN 1024 ///< Max length for error messages.
+#define MAX_MANGLED_NAME_LEN 512 ///< Max length for mangled names (generics).
+#define MAX_PATH_LEN 4096 ///< Max length for file paths.
// Type checking helpers
-#define IS_INT_TYPE(t) ((t) && strcmp((t), "int") == 0) ///< Checks if type is "int".
-#define IS_BOOL_TYPE(t) ((t) && strcmp((t), "bool") == 0) ///< Checks if type is "bool".
-#define IS_CHAR_TYPE(t) ((t) && strcmp((t), "char") == 0) ///< Checks if type is "char".
-#define IS_VOID_TYPE(t) ((t) && strcmp((t), "void") == 0) ///< Checks if type is "void".
-#define IS_FLOAT_TYPE(t) ((t) && strcmp((t), "float") == 0) ///< Checks if type is "float".
-#define IS_DOUBLE_TYPE(t) ((t) && strcmp((t), "double") == 0)///< Checks if type is "double".
-#define IS_USIZE_TYPE(t) ((t) && (strcmp((t), "usize") == 0 || strcmp((t), "size_t") == 0)) ///< Checks if type is "usize" or "size_t".
+#define IS_INT_TYPE(t) ((t) && strcmp((t), "int") == 0) ///< Checks if type is "int".
+#define IS_BOOL_TYPE(t) ((t) && strcmp((t), "bool") == 0) ///< Checks if type is "bool".
+#define IS_CHAR_TYPE(t) ((t) && strcmp((t), "char") == 0) ///< Checks if type is "char".
+#define IS_VOID_TYPE(t) ((t) && strcmp((t), "void") == 0) ///< Checks if type is "void".
+#define IS_FLOAT_TYPE(t) ((t) && strcmp((t), "float") == 0) ///< Checks if type is "float".
+#define IS_DOUBLE_TYPE(t) ((t) && strcmp((t), "double") == 0) ///< Checks if type is "double".
+#define IS_USIZE_TYPE(t) \
+ ((t) && (strcmp((t), "usize") == 0 || \
+ strcmp((t), "size_t") == 0)) ///< Checks if type is "usize" or "size_t".
/**
* @brief Checks if type is a string type ("string", "char*", "const char*").
*/
@@ -44,8 +45,10 @@
#define IS_PTR_TYPE(t) ((t) && strchr((t), '*') != NULL) ///< Checks if type string contains '*'.
// Struct prefix check
-#define IS_STRUCT_PREFIX(t) ((t) && strncmp((t), "struct ", 7) == 0) ///< Checks if type starts with "struct ".
-#define STRIP_STRUCT_PREFIX(t) (IS_STRUCT_PREFIX(t) ? ((t) + 7) : (t)) ///< Returns ptr to name after "struct " prefix.
+#define IS_STRUCT_PREFIX(t) \
+ ((t) && strncmp((t), "struct ", 7) == 0) ///< Checks if type starts with "struct ".
+#define STRIP_STRUCT_PREFIX(t) \
+ (IS_STRUCT_PREFIX(t) ? ((t) + 7) : (t)) ///< Returns ptr to name after "struct " prefix.
// Generic type checks
#define IS_OPTION_TYPE(t) ((t) && strncmp((t), "Option_", 7) == 0) ///< Checks if type is Option<T>.
diff --git a/src/lsp/json_rpc.h b/src/lsp/json_rpc.h
index 98d7ec1..0a5c282 100644
--- a/src/lsp/json_rpc.h
+++ b/src/lsp/json_rpc.h
@@ -4,10 +4,10 @@
/**
* @brief Handle a raw JSON-RPC request string.
- *
- * Parses the request, routes it to the appropriate handler (initialize, textDocument/didChange, etc.),
- * and sends back the response to stdout.
- *
+ *
+ * Parses the request, routes it to the appropriate handler (initialize, textDocument/didChange,
+ * etc.), and sends back the response to stdout.
+ *
* @param json_str Null-terminated JSON request string.
*/
void handle_request(const char *json_str);
diff --git a/src/lsp/lsp_index.h b/src/lsp/lsp_index.h
index 1b45c57..5702503 100644
--- a/src/lsp/lsp_index.h
+++ b/src/lsp/lsp_index.h
@@ -18,15 +18,15 @@ typedef enum
*/
typedef struct LSPRange
{
- int start_line; ///< Start line (1-based).
- int start_col; ///< Start column (1-based).
- int end_line; ///< End line.
- int end_col; ///< End column (approximated).
- RangeType type; ///< Type of range (def or ref).
- int def_line; ///< Line of definition (if reference).
- int def_col; ///< Column of definition (if reference).
- char *hover_text; ///< Tooltip text / signature.
- ASTNode *node; ///< Associated AST node.
+ int start_line; ///< Start line (1-based).
+ int start_col; ///< Start column (1-based).
+ int end_line; ///< End line.
+ int end_col; ///< End column (approximated).
+ RangeType type; ///< Type of range (def or ref).
+ int def_line; ///< Line of definition (if reference).
+ int def_col; ///< Column of definition (if reference).
+ char *hover_text; ///< Tooltip text / signature.
+ ASTNode *node; ///< Associated AST node.
struct LSPRange *next;
} LSPRange;
@@ -35,8 +35,8 @@ typedef struct LSPRange
*/
typedef struct LSPIndex
{
- LSPRange *head; ///< First range in the file.
- LSPRange *tail; ///< Last range in the file.
+ LSPRange *head; ///< First range in the file.
+ LSPRange *tail; ///< Last range in the file.
} LSPIndex;
// API.
diff --git a/src/parser/parser.h b/src/parser/parser.h
index 4dd5cf5..cf57971 100644
--- a/src/parser/parser.h
+++ b/src/parser/parser.h
@@ -12,18 +12,18 @@
*/
typedef enum
{
- PREC_NONE, ///< No precedence.
- PREC_ASSIGNMENT,///< Assignment operators.
- PREC_TERNARY, ///< Ternary operator.
- PREC_OR, ///< Logical OR.
- PREC_AND, ///< Logical AND.
- PREC_EQUALITY, ///< Equality operators.
- PREC_COMPARISON,///< Comparison operators.
- PREC_TERM, ///< Addition and subtraction.
- PREC_FACTOR, ///< Multiplication and division.
- PREC_UNARY, ///< Unary operators.
- PREC_CALL, ///< Function calls.
- PREC_PRIMARY ///< Primary expressions.
+ PREC_NONE, ///< No precedence.
+ PREC_ASSIGNMENT, ///< Assignment operators.
+ PREC_TERNARY, ///< Ternary operator.
+ PREC_OR, ///< Logical OR.
+ PREC_AND, ///< Logical AND.
+ PREC_EQUALITY, ///< Equality operators.
+ PREC_COMPARISON, ///< Comparison operators.
+ PREC_TERM, ///< Addition and subtraction.
+ PREC_FACTOR, ///< Multiplication and division.
+ PREC_UNARY, ///< Unary operators.
+ PREC_CALL, ///< Function calls.
+ PREC_PRIMARY ///< Primary expressions.
} Precedence;
// Main entry points
@@ -41,7 +41,7 @@ extern ParserContext *g_parser_ctx;
// Symbol table
/**
* @brief Represents a symbol in the symbol table.
- *
+ *
* Used for variables, functions, and other named entities.
*/
typedef struct ZenSymbol
@@ -61,32 +61,32 @@ typedef struct ZenSymbol
/**
* @brief Represents a lexical scope (block).
- *
+ *
* Scopes form a hierarchy (parent pointer) and contain a list of symbols defined in that scope.
*/
typedef struct Scope
{
- ZenSymbol *symbols; ///< Linked list of symbols in this scope.
- struct Scope *parent; ///< Pointer to the parent scope (NULL for global).
+ ZenSymbol *symbols; ///< Linked list of symbols in this scope.
+ struct Scope *parent; ///< Pointer to the parent scope (NULL for global).
} Scope;
/**
* @brief Registry entry for a function signature.
- *
+ *
* Stores metadata about declared functions for type checking and call validation.
*/
typedef struct FuncSig
{
- char *name; ///< Function name.
- Token decl_token; ///< declaration token.
- int total_args; ///< Total argument count.
- char **defaults; ///< Default values for arguments (or NULL).
- Type **arg_types; ///< Argument types.
- Type *ret_type; ///< Return type.
- int is_varargs; ///< 1 if variadic.
- int is_async; ///< 1 if async.
- int must_use; ///< 1 if return value must be used.
- struct FuncSig *next; ///< Next function in registry.
+ char *name; ///< Function name.
+ Token decl_token; ///< declaration token.
+ int total_args; ///< Total argument count.
+ char **defaults; ///< Default values for arguments (or NULL).
+ Type **arg_types; ///< Argument types.
+ Type *ret_type; ///< Return type.
+ int is_varargs; ///< 1 if variadic.
+ int is_async; ///< 1 if async.
+ int must_use; ///< 1 if return value must be used.
+ struct FuncSig *next; ///< Next function in registry.
} FuncSig;
/**
@@ -94,7 +94,7 @@ typedef struct FuncSig
*/
typedef struct LambdaRef
{
- ASTNode *node; ///< The AST node for the lambda.
+ ASTNode *node; ///< The AST node for the lambda.
struct LambdaRef *next;
} LambdaRef;
@@ -103,8 +103,8 @@ typedef struct LambdaRef
*/
typedef struct GenericTemplate
{
- char *name; ///< Template name.
- ASTNode *struct_node; ///< The struct AST node (containing generic params).
+ char *name; ///< Template name.
+ ASTNode *struct_node; ///< The struct AST node (containing generic params).
struct GenericTemplate *next;
} GenericTemplate;
@@ -113,9 +113,9 @@ typedef struct GenericTemplate
*/
typedef struct GenericFuncTemplate
{
- char *name; ///< Template name.
- char *generic_param; ///< Generic parameters string (legacy).
- ASTNode *func_node; ///< The function AST node.
+ char *name; ///< Template name.
+ char *generic_param; ///< Generic parameters string (legacy).
+ ASTNode *func_node; ///< The function AST node.
struct GenericFuncTemplate *next;
} GenericFuncTemplate;
@@ -124,9 +124,9 @@ typedef struct GenericFuncTemplate
*/
typedef struct GenericImplTemplate
{
- char *struct_name; ///< Target struct name.
- char *generic_param; ///< Generic parameters.
- ASTNode *impl_node; ///< The impl block AST node.
+ char *struct_name; ///< Target struct name.
+ char *generic_param; ///< Generic parameters.
+ ASTNode *impl_node; ///< The impl block AST node.
struct GenericImplTemplate *next;
} GenericImplTemplate;
@@ -135,7 +135,7 @@ typedef struct GenericImplTemplate
*/
typedef struct ImportedFile
{
- char *path; ///< Absolute file path.
+ char *path; ///< Absolute file path.
struct ImportedFile *next;
} ImportedFile;
@@ -144,11 +144,11 @@ typedef struct ImportedFile
*/
typedef struct Instantiation
{
- char *name; ///< Mangled name of the instantiation (e.g. "Vec_int").
- char *template_name; ///< Original template name (e.g. "Vec").
- char *concrete_arg; ///< Concrete type argument string.
- char *unmangled_arg; ///< Unmangled argument for substitution code.
- ASTNode *struct_node; ///< The AST node of the instantiated struct.
+ char *name; ///< Mangled name of the instantiation (e.g. "Vec_int").
+ char *template_name; ///< Original template name (e.g. "Vec").
+ char *concrete_arg; ///< Concrete type argument string.
+ char *unmangled_arg; ///< Unmangled argument for substitution code.
+ ASTNode *struct_node; ///< The AST node of the instantiated struct.
struct Instantiation *next;
} Instantiation;
@@ -194,9 +194,9 @@ typedef struct TupleType
*/
typedef struct EnumVariantReg
{
- char *enum_name; ///< Name of the enum.
- char *variant_name; ///< Name of the variant.
- int tag_id; ///< Integration tag value.
+ char *enum_name; ///< Name of the enum.
+ char *variant_name; ///< Name of the variant.
+ int tag_id; ///< Integration tag value.
struct EnumVariantReg *next;
} EnumVariantReg;
@@ -206,7 +206,7 @@ typedef struct EnumVariantReg
typedef struct DeprecatedFunc
{
char *name;
- char *reason; ///< Optional reason for deprecation.
+ char *reason; ///< Optional reason for deprecation.
struct DeprecatedFunc *next;
} DeprecatedFunc;
@@ -215,10 +215,10 @@ typedef struct DeprecatedFunc
*/
typedef struct Module
{
- char *alias; ///< Import alias (or default name).
- char *path; ///< File path.
- char *base_name; ///< Base name of the module.
- int is_c_header; ///< 1 if this is a C header import.
+ char *alias; ///< Import alias (or default name).
+ char *path; ///< File path.
+ char *base_name; ///< Base name of the module.
+ int is_c_header; ///< 1 if this is a C header import.
struct Module *next;
} Module;
@@ -227,9 +227,9 @@ typedef struct Module
*/
typedef struct SelectiveImport
{
- char *symbol; ///< Symbol name.
- char *alias; ///< Local alias.
- char *source_module; ///< Origin module.
+ char *symbol; ///< Symbol name.
+ char *alias; ///< Local alias.
+ char *source_module; ///< Origin module.
struct SelectiveImport *next;
} SelectiveImport;
@@ -238,8 +238,8 @@ typedef struct SelectiveImport
*/
typedef struct ImplReg
{
- char *trait; ///< Trait name.
- char *strct; ///< Implementing struct name.
+ char *trait; ///< Trait name.
+ char *strct; ///< Implementing struct name.
struct ImplReg *next;
} ImplReg;
@@ -248,8 +248,8 @@ typedef struct ImplReg
*/
typedef struct ImportedPlugin
{
- char *name; ///< Plugin name (e.g., "brainfuck").
- char *alias; ///< Optional usage alias.
+ char *name; ///< Plugin name (e.g., "brainfuck").
+ char *alias; ///< Optional usage alias.
struct ImportedPlugin *next;
} ImportedPlugin;
@@ -258,53 +258,54 @@ typedef struct ImportedPlugin
*/
typedef struct TypeAlias
{
- char *alias; ///< New type name.
- char *original_type; ///< Original type.
+ char *alias; ///< New type name.
+ char *original_type; ///< Original type.
struct TypeAlias *next;
} TypeAlias;
/**
* @brief Global compilation state and symbol table.
- *
+ *
* ParserContext maintains the state of the compiler during parsing and analysis.
* It holds symbol tables, type definitions, function registries, and configuration.
*/
struct ParserContext
{
- Scope *current_scope; ///< Current lexical scope for variable lookup.
- FuncSig *func_registry; ///< Registry of declared function signatures.
+ Scope *current_scope; ///< Current lexical scope for variable lookup.
+ FuncSig *func_registry; ///< Registry of declared function signatures.
// Lambdas
- LambdaRef *global_lambdas; ///< List of all lambdas generated during parsing.
- int lambda_counter; ///< Counter for generating unique lambda IDs.
+ LambdaRef *global_lambdas; ///< List of all lambdas generated during parsing.
+ int lambda_counter; ///< Counter for generating unique lambda IDs.
// Generics
#define MAX_KNOWN_GENERICS 1024
- char *known_generics[MAX_KNOWN_GENERICS]; ///< Stack of currently active generic type parameters.
- int known_generics_count; ///< Count of active generic parameters.
- GenericTemplate *templates; ///< Struct generic templates.
- GenericFuncTemplate *func_templates; ///< Function generic templates.
- GenericImplTemplate *impl_templates; ///< Implementation block templates.
+ char
+ *known_generics[MAX_KNOWN_GENERICS]; ///< Stack of currently active generic type parameters.
+ int known_generics_count; ///< Count of active generic parameters.
+ GenericTemplate *templates; ///< Struct generic templates.
+ GenericFuncTemplate *func_templates; ///< Function generic templates.
+ GenericImplTemplate *impl_templates; ///< Implementation block templates.
// Instantiations
- Instantiation *instantiations; ///< Cache of instantiated generic types.
- ASTNode *instantiated_structs; ///< List of AST nodes for instantiated structs.
- ASTNode *instantiated_funcs; ///< List of AST nodes for instantiated functions.
+ Instantiation *instantiations; ///< Cache of instantiated generic types.
+ ASTNode *instantiated_structs; ///< List of AST nodes for instantiated structs.
+ ASTNode *instantiated_funcs; ///< List of AST nodes for instantiated functions.
// Structs/Enums
- StructRef *parsed_structs_list; ///< List of all parsed struct nodes.
- StructRef *parsed_enums_list; ///< List of all parsed enum nodes.
- StructRef *parsed_funcs_list; ///< List of all parsed function nodes.
- StructRef *parsed_impls_list; ///< List of all parsed impl blocks.
- StructRef *parsed_globals_list; ///< List of all parsed global variables.
- StructDef *struct_defs; ///< Registry of struct definitions (map name -> node).
- EnumVariantReg *enum_variants; ///< Registry of enum variants for global lookup.
- ImplReg *registered_impls; ///< Cache of type/trait implementations.
+ StructRef *parsed_structs_list; ///< List of all parsed struct nodes.
+ StructRef *parsed_enums_list; ///< List of all parsed enum nodes.
+ StructRef *parsed_funcs_list; ///< List of all parsed function nodes.
+ StructRef *parsed_impls_list; ///< List of all parsed impl blocks.
+ StructRef *parsed_globals_list; ///< List of all parsed global variables.
+ StructDef *struct_defs; ///< Registry of struct definitions (map name -> node).
+ EnumVariantReg *enum_variants; ///< Registry of enum variants for global lookup.
+ ImplReg *registered_impls; ///< Cache of type/trait implementations.
// Types
- SliceType *used_slices; ///< Cache of generated slice types.
- TupleType *used_tuples; ///< Cache of generated tuple types.
- TypeAlias *type_aliases; ///< Defined type aliases.
+ SliceType *used_slices; ///< Cache of generated slice types.
+ TupleType *used_tuples; ///< Cache of generated tuple types.
+ TypeAlias *type_aliases; ///< Defined type aliases.
// Modules/Imports
Module *modules; ///< List of registered modules.
@@ -314,24 +315,24 @@ struct ParserContext
ImportedPlugin *imported_plugins; ///< List of active plugins.
// Config/State
- char *current_impl_struct; ///< Name of struct currently being implemented (in impl block).
- ASTNode *current_impl_methods; ///< Head of method list for current impl block.
+ char *current_impl_struct; ///< Name of struct currently being implemented (in impl block).
+ ASTNode *current_impl_methods; ///< Head of method list for current impl block.
// Internal tracking
- DeprecatedFunc *deprecated_funcs; ///< Registry of deprecated functions.
+ DeprecatedFunc *deprecated_funcs; ///< Registry of deprecated functions.
// LSP / Fault Tolerance
- int is_fault_tolerant; ///< 1 if parser should recover from errors (LSP mode).
- void *error_callback_data; ///< User data for error callback.
+ int is_fault_tolerant; ///< 1 if parser should recover from errors (LSP mode).
+ void *error_callback_data; ///< User data for error callback.
void (*on_error)(void *data, Token t, const char *msg); ///< Callback for reporting errors.
// LSP: Flat symbol list (persists after parsing for LSP queries)
- ZenSymbol *all_symbols; ///< comprehensive list of all symbols seen.
+ ZenSymbol *all_symbols; ///< comprehensive list of all symbols seen.
// External C interop: suppress undefined warnings for external symbols
- int has_external_includes; ///< Set when `#include <...>` is used.
- char **extern_symbols; ///< Explicitly declared extern symbols.
- int extern_symbol_count; ///< Count of external symbols.
+ int has_external_includes; ///< Set when `#include <...>` is used.
+ char **extern_symbols; ///< Explicitly declared extern symbols.
+ int extern_symbol_count; ///< Count of external symbols.
// Codegen state:
FILE *hoist_out; ///< File stream for hoisting code (e.g. from plugins).
@@ -450,8 +451,7 @@ ZenSymbol *find_symbol_entry(ParserContext *ctx, const char *n);
/**
* @brief Finds a symbol in all scopes.
*/
-ZenSymbol *find_symbol_in_all(ParserContext *ctx,
- const char *n);
+ZenSymbol *find_symbol_in_all(ParserContext *ctx, const char *n);
char *find_similar_symbol(ParserContext *ctx, const char *name);
// Function registry
diff --git a/src/parser/parser_decl.c b/src/parser/parser_decl.c
index ab1516e..98f46e1 100644
--- a/src/parser/parser_decl.c
+++ b/src/parser/parser_decl.c
@@ -586,6 +586,9 @@ ASTNode *parse_var_decl(ParserContext *ctx, Lexer *l)
type_obj->arg_count = init->type_info->arg_count;
type_obj->is_varargs = init->type_info->is_varargs;
}
+ type_obj->array_size = init->type_info->array_size;
+ type_obj->is_raw = init->type_info->is_raw;
+ type_obj->is_explicit_struct = init->type_info->is_explicit_struct;
type = type_to_string(type_obj);
}
else if (init->type == NODE_EXPR_SLICE)
@@ -775,7 +778,7 @@ ASTNode *parse_def(ParserContext *ctx, Lexer *l)
if (lexer_peek(l).type == TOK_INT)
{
Token val_tok = lexer_peek(l);
- int val = atoi(token_strdup(val_tok)); // quick check
+ int val = (int)strtol(token_strdup(val_tok), NULL, 0); // support hex/octal
ZenSymbol *s = find_symbol_entry(ctx, ns);
if (s)
diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c
index 8005e8e..3a205a8 100644
--- a/src/parser/parser_expr.c
+++ b/src/parser/parser_expr.c
@@ -65,6 +65,10 @@ static void validate_named_arguments(Token call_token, const char *func_name, ch
extern ASTNode *global_user_structs;
+// Forward declaration
+char *resolve_struct_name_from_type(ParserContext *ctx, Type *t, int *is_ptr_out,
+ char **allocated_out);
+
// Helper to check if a type is a struct type
int is_struct_type(ParserContext *ctx, const char *type_name)
{
@@ -3094,9 +3098,7 @@ ASTNode *parse_primary(ParserContext *ctx, Lexer *l)
int overloaded_get = 0;
if (node->type_info && node->type_info->kind != TYPE_ARRAY &&
- (node->type_info->kind == TYPE_STRUCT ||
- (node->type_info->kind == TYPE_POINTER && node->type_info->inner &&
- node->type_info->inner->kind == TYPE_STRUCT)))
+ node->type_info->kind == TYPE_STRUCT)
{
Type *st = node->type_info;
char *struct_name = (st->kind == TYPE_STRUCT) ? st->name : st->inner->name;
@@ -3200,12 +3202,11 @@ Type *get_field_type(ParserContext *ctx, Type *struct_type, const char *field_na
}
}
- char *sname = struct_type->name;
- // Handle Pointers (User* -> User)
- if (struct_type->kind == TYPE_POINTER && struct_type->inner)
- {
- sname = struct_type->inner->name;
- }
+ // Use resolve_struct_name_from_type to handle Generics and Pointers correctly
+ int is_ptr = 0;
+ char *alloc_name = NULL;
+ char *sname = resolve_struct_name_from_type(ctx, struct_type, &is_ptr, &alloc_name);
+
if (!sname)
{
return NULL;
@@ -3214,6 +3215,10 @@ Type *get_field_type(ParserContext *ctx, Type *struct_type, const char *field_na
ASTNode *def = find_struct_def(ctx, sname);
if (!def)
{
+ if (alloc_name)
+ {
+ free(alloc_name);
+ }
return NULL;
}
@@ -3222,10 +3227,18 @@ Type *get_field_type(ParserContext *ctx, Type *struct_type, const char *field_na
{
if (strcmp(f->field.name, field_name) == 0)
{
+ if (alloc_name)
+ {
+ free(alloc_name);
+ }
return f->type_info;
}
f = f->next;
}
+ if (alloc_name)
+ {
+ free(alloc_name);
+ }
return NULL;
}
@@ -4476,11 +4489,16 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
{
struct_name = t->name;
}
+ /*
else if (t->kind == TYPE_POINTER && t->inner && t->inner->kind == TYPE_STRUCT)
{
- struct_name = t->inner->name;
- is_ptr = 1;
+ // struct_name = t->inner->name;
+ // is_ptr = 1;
+ // DISABLE: Pointers should use array indexing by default, not operator
+ overload.
+ // If users want operator overload, they must dereference first (*ptr)[idx]
}
+ */
}
if (!struct_name && lhs->resolved_type)
{
@@ -4570,6 +4588,17 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
}
}
+ // Assign type_info for index access (Fix for nested generics)
+ if (lhs->type_info &&
+ (lhs->type_info->kind == TYPE_ARRAY || lhs->type_info->kind == TYPE_POINTER))
+ {
+ node->type_info = lhs->type_info->inner;
+ }
+ if (!node->type_info)
+ {
+ node->type_info = type_new(TYPE_INT);
+ }
+
lhs = node;
}
continue;
@@ -4589,6 +4618,9 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
node->member.field = token_strdup(field);
node->member.is_pointer_access = 0;
+ node->member.field = token_strdup(field);
+ node->member.is_pointer_access = 0;
+
if (lhs->type_info && lhs->type_info->kind == TYPE_POINTER)
{
node->member.is_pointer_access = 1;
@@ -5203,6 +5235,8 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
{
int is_rhs_ptr = 0;
char *r_alloc = NULL;
+
+ // This gives a warning as "unused" but it's needed for the rewrite.
char *r_name =
resolve_struct_name_from_type(ctx, rhs->type_info, &is_rhs_ptr, &r_alloc);
if (r_alloc)
diff --git a/src/parser/parser_utils.c b/src/parser/parser_utils.c
index f889561..4e85500 100644
--- a/src/parser/parser_utils.c
+++ b/src/parser/parser_utils.c
@@ -1002,6 +1002,9 @@ char *replace_in_string(const char *src, const char *old_w, const char *new_w)
char *replace_type_str(const char *src, const char *param, const char *concrete,
const char *old_struct, const char *new_struct)
{
+ if (src && param && concrete)
+ {
+ }
if (!src)
{
return NULL;
@@ -2563,6 +2566,7 @@ void instantiate_methods(ParserContext *ctx, GenericImplTemplate *it,
void instantiate_generic(ParserContext *ctx, const char *tpl, const char *arg,
const char *unmangled_arg, Token token)
{
+
// Ignore generic placeholders
if (strlen(arg) == 1 && isupper(arg[0]))
{
diff --git a/src/plugins/plugin_manager.h b/src/plugins/plugin_manager.h
index f5696e6..899ba71 100644
--- a/src/plugins/plugin_manager.h
+++ b/src/plugins/plugin_manager.h
@@ -17,7 +17,7 @@ void zptr_register_plugin(ZPlugin *plugin);
/**
* @brief Load a plugin from a shared object file (.so).
- *
+ *
* @param path Path to the shared object file.
* @return ZPlugin* Pointer to the loaded plugin on success, NULL on failure.
*/
diff --git a/src/repl/repl.h b/src/repl/repl.h
index 2a49288..3100bcd 100644
--- a/src/repl/repl.h
+++ b/src/repl/repl.h
@@ -4,7 +4,7 @@
/**
* @brief Starts the Read-Eval-Print Loop (REPL).
- *
+ *
* @param self_path Path to the executable/ZC compiler itself.
*/
void run_repl(const char *self_path);
diff --git a/src/zen/zen_facts.h b/src/zen/zen_facts.h
index 329c8fb..38aab86 100644
--- a/src/zen/zen_facts.h
+++ b/src/zen/zen_facts.h
@@ -6,7 +6,7 @@
/**
* @brief Triggers for Zen facts (easter egg system).
- *
+ *
* Each trigger corresponds to a specific coding pattern or event
* which may elicit a "Zen Fact" message to the user.
*/
diff --git a/src/zprep.h b/src/zprep.h
index 9f82706..e248871 100644
--- a/src/zprep.h
+++ b/src/zprep.h
@@ -34,19 +34,19 @@
#endif
// ** ANSI COLORS **
-#define COLOR_RESET "\033[0m" ///< Reset color.
-#define COLOR_RED "\033[1;31m" ///< Red color.
-#define COLOR_GREEN "\033[1;32m" ///< Green color.
+#define COLOR_RESET "\033[0m" ///< Reset color.
+#define COLOR_RED "\033[1;31m" ///< Red color.
+#define COLOR_GREEN "\033[1;32m" ///< Green color.
#define COLOR_YELLOW "\033[1;33m" ///< Yellow color.
-#define COLOR_BLUE "\033[1;34m" ///< Blue color.
-#define COLOR_CYAN "\033[1;36m" ///< Cyan color.
-#define COLOR_BOLD "\033[1m" ///< Bold text.
+#define COLOR_BLUE "\033[1;34m" ///< Blue color.
+#define COLOR_CYAN "\033[1;36m" ///< Cyan color.
+#define COLOR_BOLD "\033[1m" ///< Bold text.
// ** MEMORY OVERRIDES (Arena) **
-#define free(ptr) ((void)0) ///< Free memory.
-#define malloc(sz) xmalloc(sz) ///< Allocate memory.
+#define free(ptr) ((void)0) ///< Free memory.
+#define malloc(sz) xmalloc(sz) ///< Allocate memory.
#define realloc(p, s) xrealloc(p, s) ///< Reallocate memory.
-#define calloc(n, s) xcalloc(n, s) ///< Allocate and zero memory.
+#define calloc(n, s) xcalloc(n, s) ///< Allocate and zero memory.
// ** GLOBAL STATE **
extern char *g_current_filename; ///< Current filename.
@@ -56,59 +56,59 @@ extern char *g_current_filename; ///< Current filename.
*/
typedef enum
{
- TOK_EOF = 0, ///< End of File.
- TOK_IDENT, ///< Identifier (variable, function name).
- TOK_INT, ///< Integer literal.
- TOK_FLOAT, ///< Float literal.
- TOK_STRING, ///< String literal.
- TOK_FSTRING, ///< Formatted string literal (f"val is {x}").
- TOK_CHAR, ///< Character literal.
- TOK_LPAREN, ///< (
- TOK_RPAREN, ///< )
- TOK_LBRACE, ///< {
- TOK_RBRACE, ///< }
- TOK_LBRACKET, ///< [
- TOK_RBRACKET, ///< ]
- TOK_LANGLE, ///< <
- TOK_RANGLE, ///< >
- TOK_COMMA, ///< ,
- TOK_COLON, ///< :
- TOK_SEMICOLON, ///< ;
- TOK_OP, ///< General operator (e.g. +, *, /).
- TOK_AT, ///< @
- TOK_DOTDOT, ///< ..
- TOK_DOTDOT_EQ, ///< ..= (inclusive range).
- TOK_DOTDOT_LT, ///< ..< (exclusive range, explicit).
- TOK_ARROW, ///< -> or =>
- TOK_PIPE, ///< |> (pipe operator).
- TOK_TEST, ///< 'test' keyword.
- TOK_ASSERT, ///< 'assert' keyword.
- TOK_SIZEOF, ///< 'sizeof' keyword.
- TOK_DEF, ///< 'def' keyword.
- TOK_DEFER, ///< 'defer' keyword.
- TOK_AUTOFREE, ///< 'autofree' keyword.
- TOK_QUESTION, ///< ?
- TOK_USE, ///< 'use' keyword.
- TOK_QQ, ///< ?? (null coalescing).
- TOK_QQ_EQ, ///< ??=
- TOK_Q_DOT, ///< ?. (optional chaining).
- TOK_DCOLON, ///< ::
- TOK_TRAIT, ///< 'trait' keyword.
- TOK_IMPL, ///< 'impl' keyword.
- TOK_AND, ///< 'and' keyword.
- TOK_OR, ///< 'or' keyword.
- TOK_FOR, ///< 'for' keyword.
- TOK_COMPTIME, ///< 'comptime' keyword.
- TOK_ELLIPSIS, ///< ...
- TOK_UNION, ///< 'union' keyword.
- TOK_ASM, ///< 'asm' keyword.
- TOK_VOLATILE, ///< 'volatile' keyword.
- TOK_ASYNC, ///< 'async' keyword.
- TOK_AWAIT, ///< 'await' keyword.
- TOK_PREPROC, ///< Preprocessor directive (#...).
- TOK_ALIAS, ///< 'alias' keyword.
- TOK_COMMENT, ///< Comment (usually skipped).
- TOK_UNKNOWN ///< Unknown token.
+ TOK_EOF = 0, ///< End of File.
+ TOK_IDENT, ///< Identifier (variable, function name).
+ TOK_INT, ///< Integer literal.
+ TOK_FLOAT, ///< Float literal.
+ TOK_STRING, ///< String literal.
+ TOK_FSTRING, ///< Formatted string literal (f"val is {x}").
+ TOK_CHAR, ///< Character literal.
+ TOK_LPAREN, ///< (
+ TOK_RPAREN, ///< )
+ TOK_LBRACE, ///< {
+ TOK_RBRACE, ///< }
+ TOK_LBRACKET, ///< [
+ TOK_RBRACKET, ///< ]
+ TOK_LANGLE, ///< <
+ TOK_RANGLE, ///< >
+ TOK_COMMA, ///< ,
+ TOK_COLON, ///< :
+ TOK_SEMICOLON, ///< ;
+ TOK_OP, ///< General operator (e.g. +, *, /).
+ TOK_AT, ///< @
+ TOK_DOTDOT, ///< ..
+ TOK_DOTDOT_EQ, ///< ..= (inclusive range).
+ TOK_DOTDOT_LT, ///< ..< (exclusive range, explicit).
+ TOK_ARROW, ///< -> or =>
+ TOK_PIPE, ///< |> (pipe operator).
+ TOK_TEST, ///< 'test' keyword.
+ TOK_ASSERT, ///< 'assert' keyword.
+ TOK_SIZEOF, ///< 'sizeof' keyword.
+ TOK_DEF, ///< 'def' keyword.
+ TOK_DEFER, ///< 'defer' keyword.
+ TOK_AUTOFREE, ///< 'autofree' keyword.
+ TOK_QUESTION, ///< ?
+ TOK_USE, ///< 'use' keyword.
+ TOK_QQ, ///< ?? (null coalescing).
+ TOK_QQ_EQ, ///< ??=
+ TOK_Q_DOT, ///< ?. (optional chaining).
+ TOK_DCOLON, ///< ::
+ TOK_TRAIT, ///< 'trait' keyword.
+ TOK_IMPL, ///< 'impl' keyword.
+ TOK_AND, ///< 'and' keyword.
+ TOK_OR, ///< 'or' keyword.
+ TOK_FOR, ///< 'for' keyword.
+ TOK_COMPTIME, ///< 'comptime' keyword.
+ TOK_ELLIPSIS, ///< ...
+ TOK_UNION, ///< 'union' keyword.
+ TOK_ASM, ///< 'asm' keyword.
+ TOK_VOLATILE, ///< 'volatile' keyword.
+ TOK_ASYNC, ///< 'async' keyword.
+ TOK_AWAIT, ///< 'await' keyword.
+ TOK_PREPROC, ///< Preprocessor directive (#...).
+ TOK_ALIAS, ///< 'alias' keyword.
+ TOK_COMMENT, ///< Comment (usually skipped).
+ TOK_UNKNOWN ///< Unknown token.
} TokenType;
/**
@@ -116,11 +116,11 @@ typedef enum
*/
typedef struct
{
- TokenType type; ///< Type of the token.
- const char *start; ///< Pointer to start of token in source buffer.
- int len; ///< Length of the token text.
- int line; ///< Line number (1-based).
- int col; ///< Column number (1-based).
+ TokenType type; ///< Type of the token.
+ const char *start; ///< Pointer to start of token in source buffer.
+ int len; ///< Length of the token text.
+ int line; ///< Line number (1-based).
+ int col; ///< Column number (1-based).
} Token;
/**
@@ -128,10 +128,10 @@ typedef struct
*/
typedef struct
{
- const char *src; ///< Source code buffer.
- int pos; ///< Current position index.
- int line; ///< Current line number.
- int col; ///< Current column number.
+ const char *src; ///< Source code buffer.
+ int pos; ///< Current position index.
+ int line; ///< Current line number.
+ int col; ///< Current column number.
} Lexer;
/**
@@ -343,27 +343,27 @@ void warn_null_pointer(Token t, const char *expr);
*/
typedef struct
{
- char *input_file; ///< Input source file path.
- char *output_file; ///< Output binary file path.
+ char *input_file; ///< Input source file path.
+ char *output_file; ///< Output binary file path.
// Modes.
- int mode_run; ///< 1 if 'run' command (compile & execute).
- int mode_check; ///< 1 if 'check' command (syntax/type check only).
- int emit_c; ///< 1 if --emit-c (keep generated C file).
- int verbose; ///< 1 if --verbose.
- int quiet; ///< 1 if --quiet.
- int no_zen; ///< 1 if --no-zen (disable zen facts/easter eggs).
- int repl_mode; ///< 1 if --repl (internal flag for REPL usage).
- int is_freestanding; ///< 1 if --freestanding (no stdlib).
- int mode_transpile; ///< 1 if 'transpile' command (to C).
- int use_cpp; ///< 1 if --cpp (emit C++ compatible code).
- int use_cuda; ///< 1 if --cuda (emit CUDA-compatible code).
+ int mode_run; ///< 1 if 'run' command (compile & execute).
+ int mode_check; ///< 1 if 'check' command (syntax/type check only).
+ int emit_c; ///< 1 if --emit-c (keep generated C file).
+ int verbose; ///< 1 if --verbose.
+ int quiet; ///< 1 if --quiet.
+ int no_zen; ///< 1 if --no-zen (disable zen facts/easter eggs).
+ int repl_mode; ///< 1 if --repl (internal flag for REPL usage).
+ int is_freestanding; ///< 1 if --freestanding (no stdlib).
+ int mode_transpile; ///< 1 if 'transpile' command (to C).
+ int use_cpp; ///< 1 if --cpp (emit C++ compatible code).
+ int use_cuda; ///< 1 if --cuda (emit CUDA-compatible code).
// GCC Flags accumulator.
- char gcc_flags[4096]; ///< Flags passed to the backend compiler.
+ char gcc_flags[4096]; ///< Flags passed to the backend compiler.
// C Compiler selection (default: gcc)
- char cc[64]; ///< Backend compiler command (e.g. "gcc", "clang").
+ char cc[64]; ///< Backend compiler command (e.g. "gcc", "clang").
} CompilerConfig;
extern CompilerConfig g_config;