diff options
Diffstat (limited to 'src/parser')
| -rw-r--r-- | src/parser/parser.h | 441 | ||||
| -rw-r--r-- | src/parser/parser_core.c | 5 | ||||
| -rw-r--r-- | src/parser/parser_stmt.c | 22 | ||||
| -rw-r--r-- | src/parser/parser_type.c | 11 | ||||
| -rw-r--r-- | src/parser/parser_utils.c | 23 |
5 files changed, 287 insertions, 215 deletions
diff --git a/src/parser/parser.h b/src/parser/parser.h index 815164c..1e047b4 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -6,19 +6,20 @@ #include "zprep.h" // Operator precedence for expression parsing -typedef enum { - PREC_NONE, - PREC_ASSIGNMENT, - PREC_TERNARY, - PREC_OR, - PREC_AND, - PREC_EQUALITY, - PREC_COMPARISON, - PREC_TERM, - PREC_FACTOR, - PREC_UNARY, - PREC_CALL, - PREC_PRIMARY +typedef enum +{ + PREC_NONE, + PREC_ASSIGNMENT, + PREC_TERNARY, + PREC_OR, + PREC_AND, + PREC_EQUALITY, + PREC_COMPARISON, + PREC_TERM, + PREC_FACTOR, + PREC_UNARY, + PREC_CALL, + PREC_PRIMARY } Precedence; // Main entry points @@ -31,219 +32,248 @@ ASTNode *parse_program(ParserContext *ctx, Lexer *l); extern ParserContext *g_parser_ctx; // Symbol table -typedef struct Symbol { - char *name; - char *type_name; - Type *type_info; - int is_mutable; - int is_used; - int is_autofree; - Token decl_token; - int is_const_value; - int const_int_val; - struct Symbol *next; +typedef struct Symbol +{ + char *name; + char *type_name; + Type *type_info; + int is_mutable; + int is_used; + int is_autofree; + Token decl_token; + int is_const_value; + int const_int_val; + struct Symbol *next; } Symbol; -typedef struct Scope { - Symbol *symbols; - struct Scope *parent; +typedef struct Scope +{ + Symbol *symbols; + struct Scope *parent; } Scope; // Function registry -typedef struct FuncSig { - char *name; - Token decl_token; // For LSP - int total_args; - char **defaults; - Type **arg_types; - Type *ret_type; - int is_varargs; - int is_async; // Async function flag - int must_use; // Attribute: warn if return value discarded - struct FuncSig *next; +typedef struct FuncSig +{ + char *name; + Token decl_token; // For LSP + int total_args; + char **defaults; + Type **arg_types; + Type *ret_type; + int is_varargs; + int is_async; // Async function flag + int must_use; // Attribute: warn if return value discarded + struct FuncSig *next; } FuncSig; // Lambda tracking -typedef struct LambdaRef { - ASTNode *node; - struct LambdaRef *next; +typedef struct LambdaRef +{ + ASTNode *node; + struct LambdaRef *next; } LambdaRef; -typedef struct GenericTemplate { - char *name; - ASTNode *struct_node; - struct GenericTemplate *next; +typedef struct GenericTemplate +{ + char *name; + ASTNode *struct_node; + struct GenericTemplate *next; } GenericTemplate; -typedef struct GenericFuncTemplate { - char *name; - char *generic_param; - ASTNode *func_node; - struct GenericFuncTemplate *next; +typedef struct GenericFuncTemplate +{ + char *name; + char *generic_param; + ASTNode *func_node; + struct GenericFuncTemplate *next; } GenericFuncTemplate; -typedef struct GenericImplTemplate { - char *struct_name; - char *generic_param; - ASTNode *impl_node; - struct GenericImplTemplate *next; +typedef struct GenericImplTemplate +{ + char *struct_name; + char *generic_param; + ASTNode *impl_node; + struct GenericImplTemplate *next; } GenericImplTemplate; -typedef struct ImportedFile { - char *path; - struct ImportedFile *next; +typedef struct ImportedFile +{ + char *path; + struct ImportedFile *next; } ImportedFile; -typedef struct VarMutability { - char *name; - int is_mutable; - struct VarMutability *next; +typedef struct VarMutability +{ + char *name; + int is_mutable; + struct VarMutability *next; } VarMutability; // Instantiation tracking -typedef struct Instantiation { - char *name; - char *template_name; - char *concrete_arg; - ASTNode *struct_node; - struct Instantiation *next; +typedef struct Instantiation +{ + char *name; + char *template_name; + char *concrete_arg; + ASTNode *struct_node; + struct Instantiation *next; } Instantiation; -typedef struct StructRef { - ASTNode *node; - struct StructRef *next; +typedef struct StructRef +{ + ASTNode *node; + struct StructRef *next; } StructRef; -typedef struct StructDef { - char *name; - ASTNode *node; - struct StructDef *next; +typedef struct StructDef +{ + char *name; + ASTNode *node; + struct StructDef *next; } StructDef; // Type tracking -typedef struct SliceType { - char *name; - struct SliceType *next; +typedef struct SliceType +{ + char *name; + struct SliceType *next; } SliceType; -typedef struct TupleType { - char *sig; - struct TupleType *next; +typedef struct TupleType +{ + char *sig; + struct TupleType *next; } TupleType; // Enum tracking -typedef struct EnumVariantReg { - char *enum_name; - char *variant_name; - int tag_id; - struct EnumVariantReg *next; +typedef struct EnumVariantReg +{ + char *enum_name; + char *variant_name; + int tag_id; + struct EnumVariantReg *next; } EnumVariantReg; // Deprecated function tracking -typedef struct DeprecatedFunc { - char *name; - char *reason; // Optional reason message - struct DeprecatedFunc *next; +typedef struct DeprecatedFunc +{ + char *name; + char *reason; // Optional reason message + struct DeprecatedFunc *next; } DeprecatedFunc; // Module system -typedef struct Module { - char *alias; - char *path; - char *base_name; - int is_c_header; - struct Module *next; +typedef struct Module +{ + char *alias; + char *path; + char *base_name; + int is_c_header; + struct Module *next; } Module; -typedef struct SelectiveImport { - char *symbol; - char *alias; - char *source_module; - struct SelectiveImport *next; +typedef struct SelectiveImport +{ + char *symbol; + char *alias; + char *source_module; + struct SelectiveImport *next; } SelectiveImport; // Impl cache -typedef struct ImplReg { - char *trait; - char *strct; - struct ImplReg *next; +typedef struct ImplReg +{ + char *trait; + char *strct; + struct ImplReg *next; } ImplReg; // Plugin tracking -typedef struct ImportedPlugin { - char *name; // Original plugin name (for example, "brainfuck") - char *alias; // Optional alias (for example, "bf"), NULL if no alias - struct ImportedPlugin *next; +typedef struct ImportedPlugin +{ + char *name; // Original plugin name (for example, "brainfuck") + char *alias; // Optional alias (for example, "bf"), NULL if no alias + struct ImportedPlugin *next; } ImportedPlugin; -struct ParserContext { - Scope *current_scope; - FuncSig *func_registry; +typedef struct TypeAlias +{ + char *alias; + char *original_type; + struct TypeAlias *next; +} TypeAlias; - // Lambdas - LambdaRef *global_lambdas; - int lambda_counter; +struct ParserContext +{ + Scope *current_scope; + FuncSig *func_registry; + + // Lambdas + LambdaRef *global_lambdas; + int lambda_counter; // Generics #define MAX_KNOWN_GENERICS 1024 - char *known_generics[MAX_KNOWN_GENERICS]; - int known_generics_count; - GenericTemplate *templates; - GenericFuncTemplate *func_templates; - GenericImplTemplate *impl_templates; - - // Instantiations - Instantiation *instantiations; - ASTNode *instantiated_structs; - ASTNode *instantiated_funcs; - - // Structs/Enums - StructRef *parsed_structs_list; - StructRef *parsed_enums_list; - StructRef *parsed_funcs_list; - StructRef *parsed_impls_list; - StructRef *parsed_globals_list; - StructDef *struct_defs; - EnumVariantReg *enum_variants; - ImplReg *registered_impls; - - // Types - SliceType *used_slices; - TupleType *used_tuples; - - // Modules/Imports - Module *modules; - SelectiveImport *selective_imports; - char *current_module_prefix; - ImportedFile *imported_files; - ImportedPlugin *imported_plugins; // Plugin imports - - // Config/State - int immutable_by_default; - char *current_impl_struct; - - // Internal tracking - VarMutability *var_mutability_table; - DeprecatedFunc *deprecated_funcs; - - // LSP / Fault Tolerance - int is_fault_tolerant; - void *error_callback_data; - void (*on_error)(void *data, Token t, const char *msg); - - // LSP: Flat symbol list (persists after parsing for LSP queries) - Symbol *all_symbols; - - // 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; - - // Codegen state: - FILE *hoist_out; // For plugins to hoist code to file scope - int skip_preamble; // If 1, codegen_node(NODE_ROOT) won't emit preamble - int is_repl; // REPL mode flag - int has_async; // Track if async features are used + char *known_generics[MAX_KNOWN_GENERICS]; + int known_generics_count; + GenericTemplate *templates; + GenericFuncTemplate *func_templates; + GenericImplTemplate *impl_templates; + + // Instantiations + Instantiation *instantiations; + ASTNode *instantiated_structs; + ASTNode *instantiated_funcs; + + // Structs/Enums + StructRef *parsed_structs_list; + StructRef *parsed_enums_list; + StructRef *parsed_funcs_list; + StructRef *parsed_impls_list; + StructRef *parsed_globals_list; + StructDef *struct_defs; + EnumVariantReg *enum_variants; + ImplReg *registered_impls; + + // Types + SliceType *used_slices; + TupleType *used_tuples; + TypeAlias *type_aliases; + + // Modules/Imports + Module *modules; + SelectiveImport *selective_imports; + char *current_module_prefix; + ImportedFile *imported_files; + ImportedPlugin *imported_plugins; // Plugin imports + + // Config/State + int immutable_by_default; + char *current_impl_struct; + + // Internal tracking + VarMutability *var_mutability_table; + DeprecatedFunc *deprecated_funcs; + + // LSP / Fault Tolerance + int is_fault_tolerant; + void *error_callback_data; + void (*on_error)(void *data, Token t, const char *msg); + + // LSP: Flat symbol list (persists after parsing for LSP queries) + Symbol *all_symbols; + + // 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; + + // Codegen state: + FILE *hoist_out; // For plugins to hoist code to file scope + int skip_preamble; // If 1, codegen_node(NODE_ROOT) won't emit preamble + int is_repl; // REPL mode flag + int has_async; // Track if async features are used }; // Token helpers @@ -261,10 +291,9 @@ void warn_c_reserved_word(Token t, const char *name); // Symbol table void enter_scope(ParserContext *ctx); void exit_scope(ParserContext *ctx); -void add_symbol(ParserContext *ctx, const char *n, const char *t, - Type *type_info); -void add_symbol_with_token(ParserContext *ctx, const char *n, const char *t, - Type *type_info, Token tok); +void add_symbol(ParserContext *ctx, const char *n, const char *t, Type *type_info); +void add_symbol_with_token(ParserContext *ctx, const char *n, const char *t, Type *type_info, + Token tok); Type *find_symbol_type_info(ParserContext *ctx, const char *n); char *find_symbol_type(ParserContext *ctx, const char *n); Symbol *find_symbol_entry(ParserContext *ctx, const char *n); @@ -273,18 +302,17 @@ Symbol *find_symbol_in_all(ParserContext *ctx, char *find_similar_symbol(ParserContext *ctx, const char *name); // Function registry -void register_func(ParserContext *ctx, const char *name, int count, - char **defaults, Type **arg_types, Type *ret_type, - int is_varargs, int is_async, Token decl_token); -void register_func_template(ParserContext *ctx, const char *name, - const char *param, ASTNode *node); +void register_func(ParserContext *ctx, const char *name, int count, char **defaults, + Type **arg_types, Type *ret_type, int is_varargs, int is_async, + Token decl_token); +void register_func_template(ParserContext *ctx, const char *name, const char *param, ASTNode *node); GenericFuncTemplate *find_func_template(ParserContext *ctx, const char *name); // Generic/template helpers void register_generic(ParserContext *ctx, char *name); int is_known_generic(ParserContext *ctx, char *name); -void register_impl_template(ParserContext *ctx, const char *sname, - const char *param, ASTNode *node); +void register_impl_template(ParserContext *ctx, const char *sname, const char *param, + ASTNode *node); void add_to_struct_list(ParserContext *ctx, ASTNode *node); void add_to_enum_list(ParserContext *ctx, ASTNode *node); void add_to_func_list(ParserContext *ctx, ASTNode *node); @@ -292,24 +320,21 @@ void add_to_impl_list(ParserContext *ctx, ASTNode *node); void add_to_global_list(ParserContext *ctx, ASTNode *node); void register_builtins(ParserContext *ctx); void add_instantiated_func(ParserContext *ctx, ASTNode *fn); -void instantiate_generic(ParserContext *ctx, const char *name, - const char *concrete_type, Token t); -char *sanitize_mangled_name(const char *s); +void instantiate_generic(ParserContext *ctx, const char *name, const char *concrete_type, Token t); +char *sanitize_mangled_name(const char *name); +void register_type_alias(ParserContext *ctx, const char *alias, const char *original); +const char *find_type_alias(ParserContext *ctx, const char *alias); void register_impl(ParserContext *ctx, const char *trait, const char *strct); int check_impl(ParserContext *ctx, const char *trait, const char *strct); void register_template(ParserContext *ctx, const char *name, ASTNode *node); -void register_deprecated_func(ParserContext *ctx, const char *name, - const char *reason); +void register_deprecated_func(ParserContext *ctx, const char *name, const char *reason); DeprecatedFunc *find_deprecated_func(ParserContext *ctx, const char *name); -ASTNode *parse_arrow_lambda_single(ParserContext *ctx, Lexer *l, - char *param_name); -ASTNode *parse_arrow_lambda_multi(ParserContext *ctx, Lexer *l, - char **param_names, int num_params); +ASTNode *parse_arrow_lambda_single(ParserContext *ctx, Lexer *l, char *param_name); +ASTNode *parse_arrow_lambda_multi(ParserContext *ctx, Lexer *l, char **param_names, int num_params); // Utils -char *parse_and_convert_args(ParserContext *ctx, Lexer *l, char ***defaults_out, - int *count_out, Type ***types_out, - char ***names_out, int *is_varargs_out); +char *parse_and_convert_args(ParserContext *ctx, Lexer *l, char ***defaults_out, int *count_out, + Type ***types_out, char ***names_out, int *is_varargs_out); int is_file_imported(ParserContext *ctx, const char *path); void mark_file_imported(ParserContext *ctx, const char *path); void register_plugin(ParserContext *ctx, const char *name, const char *alias); @@ -320,15 +345,13 @@ void print_type_defs(ParserContext *ctx, FILE *out, ASTNode *nodes); 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); -Type *replace_type_formal(Type *t, const char *p, const char *c, const char *os, - const char *ns); -ASTNode *copy_ast_replacing(ASTNode *n, const char *p, const char *c, - const char *os, const char *ns); +Type *replace_type_formal(Type *t, const char *p, const char *c, const char *os, const char *ns); +ASTNode *copy_ast_replacing(ASTNode *n, const char *p, const char *c, const char *os, + const char *ns); char *extract_module_name(const char *path); // Enum helpers -void register_enum_variant(ParserContext *ctx, const char *ename, - const char *vname, int tag); +void register_enum_variant(ParserContext *ctx, const char *ename, const char *vname, int tag); EnumVariantReg *find_enum_variant(ParserContext *ctx, const char *vname); // Lambda helpers @@ -346,13 +369,12 @@ void register_struct_def(ParserContext *ctx, const char *name, ASTNode *node); // Module system Module *find_module(ParserContext *ctx, const char *alias); void register_module(ParserContext *ctx, const char *alias, const char *path); -void register_selective_import(ParserContext *ctx, const char *symbol, - const char *alias, const char *source_module); +void register_selective_import(ParserContext *ctx, const char *symbol, const char *alias, + const char *source_module); SelectiveImport *find_selective_import(ParserContext *ctx, const char *name); // Mutability tracking -void register_var_mutability(ParserContext *ctx, const char *name, - int is_mutable); +void register_var_mutability(ParserContext *ctx, const char *name, int is_mutable); int is_var_mutable(ParserContext *ctx, const char *name); // External symbol tracking (C interop) @@ -365,8 +387,7 @@ void init_builtins(); // Expression rewriting char *rewrite_expr_methods(ParserContext *ctx, char *raw); -char *process_fstring(ParserContext *ctx, const char *content, - char ***used_syms, int *count); +char *process_fstring(ParserContext *ctx, const char *content, char ***used_syms, int *count); char *instantiate_function_template(ParserContext *ctx, const char *name, const char *concrete_type); FuncSig *find_func(ParserContext *ctx, const char *name); @@ -398,8 +419,8 @@ ASTNode *parse_guard(ParserContext *ctx, Lexer *l); ASTNode *parse_match(ParserContext *ctx, Lexer *l); ASTNode *parse_return(ParserContext *ctx, Lexer *l); -char *process_printf_sugar(ParserContext *ctx, const char *content, int newline, - const char *target, char ***used_syms, int *count); +char *process_printf_sugar(ParserContext *ctx, const char *content, int newline, const char *target, + char ***used_syms, int *count); ASTNode *parse_assert(ParserContext *ctx, Lexer *l); ASTNode *parse_defer(ParserContext *ctx, Lexer *l); ASTNode *parse_asm(ParserContext *ctx, Lexer *l); diff --git a/src/parser/parser_core.c b/src/parser/parser_core.c index c72e87a..3e683fb 100644 --- a/src/parser/parser_core.c +++ b/src/parser/parser_core.c @@ -15,7 +15,6 @@ ASTNode *parse_program_nodes(ParserContext *ctx, Lexer *l) { skip_comments(l); Token t = lexer_peek(l); - if (t.type == TOK_EOF) { break; @@ -411,6 +410,10 @@ ASTNode *parse_program_nodes(ParserContext *ctx, Lexer *l) lexer_next(l); } } + else if (t.type == TOK_ALIAS) + { + s = parse_type_alias(ctx, l); + } else if (t.type == TOK_ASYNC) { lexer_next(l); diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c index 6f019b7..f391f97 100644 --- a/src/parser/parser_stmt.c +++ b/src/parser/parser_stmt.c @@ -1358,16 +1358,31 @@ ASTNode *parse_const(ParserContext *ctx, Lexer *l) ASTNode *parse_type_alias(ParserContext *ctx, Lexer *l) { - lexer_next(l); + lexer_next(l); // consume 'type' or 'alias' Token n = lexer_next(l); - lexer_next(l); + if (n.type != TOK_IDENT) + { + zpanic_at(n, "Expected identifier for type alias"); + } + + lexer_next(l); // consume '=' + char *o = parse_type(ctx, l); - lexer_next(l); + // printf("DEBUG: parse_type returned '%s'\n", o); + + lexer_next(l); // consume ';' (parse_type doesn't consume it? parse_type calls parse_type_formal + // which doesn't consume ;?) + // Note: parse_type_stmt usually expects ; but parse_type just parses type expression. + // Check previous implementation: it had lexer_next(l) at end. This assumes ;. + ASTNode *node = ast_create(NODE_TYPE_ALIAS); node->type_alias.alias = xmalloc(n.len + 1); strncpy(node->type_alias.alias, n.start, n.len); node->type_alias.alias[n.len] = 0; node->type_alias.original_type = o; + + register_type_alias(ctx, node->type_alias.alias, o); + return node; } @@ -3260,6 +3275,7 @@ ASTNode *parse_struct(ParserContext *ctx, Lexer *l, int is_union) { skip_comments(l); Token t = lexer_peek(l); + // printf("DEBUG: parse_struct loop seeing '%.*s'\n", t.len, t.start); if (t.type == TOK_RBRACE) { lexer_next(l); diff --git a/src/parser/parser_type.c b/src/parser/parser_type.c index 6e884f6..3b4abf3 100644 --- a/src/parser/parser_type.c +++ b/src/parser/parser_type.c @@ -27,6 +27,16 @@ Type *parse_type_base(ParserContext *ctx, Lexer *l) lexer_next(l); char *name = token_strdup(t); + // Check for alias + const char *aliased = find_type_alias(ctx, name); + if (aliased) + { + free(name); + Lexer tmp; + lexer_init(&tmp, aliased); + return parse_type_formal(ctx, &tmp); + } + // Self type alias: Replace "Self" with current impl struct type if (strcmp(name, "Self") == 0 && ctx->current_impl_struct) { @@ -535,7 +545,6 @@ Type *parse_type_formal(ParserContext *ctx, Lexer *l) if (lexer_peek(l).type == TOK_IDENT && strncmp(lexer_peek(l).start, "fn", 2) == 0 && lexer_peek(l).len == 2) { - lexer_next(l); // eat 'fn' Type *fn_type = type_new(TYPE_FUNCTION); fn_type->is_varargs = 0; diff --git a/src/parser/parser_utils.c b/src/parser/parser_utils.c index e013a40..6129990 100644 --- a/src/parser/parser_utils.c +++ b/src/parser/parser_utils.c @@ -402,6 +402,29 @@ void add_to_struct_list(ParserContext *ctx, ASTNode *node) ctx->parsed_structs_list = r; } +void register_type_alias(ParserContext *ctx, const char *alias, const char *original) +{ + TypeAlias *ta = xmalloc(sizeof(TypeAlias)); + ta->alias = xstrdup(alias); + ta->original_type = xstrdup(original); + ta->next = ctx->type_aliases; + ctx->type_aliases = ta; +} + +const char *find_type_alias(ParserContext *ctx, const char *alias) +{ + TypeAlias *ta = ctx->type_aliases; + while (ta) + { + if (strcmp(ta->alias, alias) == 0) + { + return ta->original_type; + } + ta = ta->next; + } + return NULL; +} + void add_to_enum_list(ParserContext *ctx, ASTNode *node) { StructRef *r = xmalloc(sizeof(StructRef)); |
