summaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser')
-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
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]))
{