diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analysis/typecheck.c | 8 | ||||
| -rw-r--r-- | src/analysis/typecheck.h | 6 | ||||
| -rw-r--r-- | src/ast/ast.h | 186 | ||||
| -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 | ||||
| -rw-r--r-- | src/constants.h | 33 | ||||
| -rw-r--r-- | src/lsp/json_rpc.h | 8 | ||||
| -rw-r--r-- | src/lsp/lsp_index.h | 22 | ||||
| -rw-r--r-- | src/parser/parser.h | 188 | ||||
| -rw-r--r-- | src/parser/parser_decl.c | 5 | ||||
| -rw-r--r-- | src/parser/parser_expr.c | 56 | ||||
| -rw-r--r-- | src/parser/parser_utils.c | 4 | ||||
| -rw-r--r-- | src/plugins/plugin_manager.h | 2 | ||||
| -rw-r--r-- | src/repl/repl.h | 2 | ||||
| -rw-r--r-- | src/zen/zen_facts.h | 2 | ||||
| -rw-r--r-- | src/zprep.h | 172 |
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; |
