diff options
Diffstat (limited to 'src/parser')
| -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 |
4 files changed, 147 insertions, 106 deletions
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])) { |
