Feature: Add generic support to functions#19
Closed
VxTi wants to merge 31 commits into
Closed
Conversation
…ted parsing logic
…VM function definitions
…ty and consistency
…ndling of generics
…improve generic overload handling
…e overwrite in parsing context
…e function handling in parser - Removed `const` qualifiers from certain `FieldDefinition` pointers to allow modifications. - Added `AstFunctionCall` and `AstReturnStatement` classes in the AST structure. - Introduced utilities for collecting free variables, return statements, and resolving forward references. - Added LLVM code generation logic for function declarations and calls.
… dedicated file, improve generic type resolution and argument handling
…tion in function bodies, standardize naming in function metadata - Introduced `resolve_generics_in_body` to resolve generic types in function bodies recursively, with bottom-up traversal. - Renamed `GenericFunctionMetadata` to `FunctionImplementation`, streamlining function metadata handling. - Updated logic for cloning function bodies with resolved generics. - Improved type re-inference during generic parameter substitution.
- Improved generic resolution for object initializers in the AST (`AstObjectInitializer`). - Added logic to resolve return types with generics in function declarations. - Updated expression node with the ability to set generic type arguments.
…declarations - Updated type inference to handle substitution of generic parameter names with concrete types in function calls. - Refactored `function_definition` to `function_declaration` and enhanced overload handling for generic functions. - Adjusted LLVM code generation to use resolved bodies for generic overloads. - Updated function implementation metadata to include resolved function bodies. - Minor updates to tests to integrate empty generic type lists and align with new logic.
…and expanding free variable collection for various expression types
… variable capturing
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the Stride compiler to support generic type arguments in function calls, adds a generic-overload instantiation pipeline (type resolution → forward refs → codegen), and refactors several AST/function components to support that flow.
Changes:
- Add generic type arguments to
AstFunctionCallparsing/AST, track instantiations, and resolve generic return types during type inference. - Introduce generic-function overload creation and per-instantiation forward-ref/codegen handling via
FunctionDefinition. - Rename
SourceFragment::combine→SourceFragment::joinacross the codebase, and add/replace enum handling withAstEnumType.
Reviewed changes
Copilot reviewed 53 out of 54 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/compiler/tests/utils.h | Adjust test compilation pipeline ordering (imports/functions/expressions/runtime). |
| packages/compiler/tests/test_type_inference.cpp | Update AstFunctionCall construction to include generic type list argument. |
| packages/compiler/src/files.cpp | Rename SourceFragment::combine to SourceFragment::join. |
| packages/compiler/src/errors.cpp | Update multi-span error rendering characters/formatting. |
| packages/compiler/src/compilation/program.cpp | Reorder compilation steps into symbol registration → type resolution → forward refs → validation/codegen. |
| packages/compiler/src/ast/type_inference.cpp | Add generic return-type substitution for function calls; tweak source fragments. |
| packages/compiler/src/ast/traversal/traversal.cpp | Include visitor header for traversal compilation. |
| packages/compiler/src/ast/traversal/function_visitor.cpp | Infer function type via infer_function_type; always register function in context. |
| packages/compiler/src/ast/traversal/expression_visitor.cpp | Register inferred variable types; record generic instantiations on generic calls. |
| packages/compiler/src/ast/nodes/types/type_definition.cpp | Use SourceFragment::join. |
| packages/compiler/src/ast/nodes/types/function_type.cpp | Add generic parameter cloning support; minor cleanup/emplace changes. |
| packages/compiler/src/ast/nodes/types/enum_type.cpp | New enum type parsing/AST node implementation (AstEnumType). |
| packages/compiler/src/ast/nodes/types/alias_type.cpp | Preserve function-type generic parameter names when resolving aliases. |
| packages/compiler/src/ast/nodes/return_statement.cpp | Use SourceFragment::join. |
| packages/compiler/src/ast/nodes/package.cpp | Use SourceFragment::join. |
| packages/compiler/src/ast/nodes/module.cpp | Use SourceFragment::join. |
| packages/compiler/src/ast/nodes/import.cpp | Use SourceFragment::join. |
| packages/compiler/src/ast/nodes/functions/function_declaration.cpp | Remove monolithic implementation (split into smaller compilation units). |
| packages/compiler/src/ast/nodes/functions/declaration/function_parameters.cpp | New parameter parsing helpers (duplicate detection, variadics). |
| packages/compiler/src/ast/nodes/functions/declaration/function_declaration_validation.cpp | New validation pipeline, including generic instantiation validation. |
| packages/compiler/src/ast/nodes/functions/declaration/function_declaration_forward_refs.cpp | New forward-ref generation, including generic overload variants and captures. |
| packages/compiler/src/ast/nodes/functions/declaration/function_declaration_codegen.cpp | New function codegen supporting generic overload bodies. |
| packages/compiler/src/ast/nodes/functions/declaration/function_declaration.cpp | New function parsing and IAstFunction helpers for overload dispatch. |
| packages/compiler/src/ast/nodes/functions/call/function_call_validate.cpp | New AstFunctionCall::validate() compilation unit. |
| packages/compiler/src/ast/nodes/functions/call/function_call_forward_refs.cpp | New AstFunctionCall::resolve_forward_references() compilation unit. |
| packages/compiler/src/ast/nodes/functions/call/function_call_codegen.cpp | Refactor callee resolution for generic overloads and FunctionDefinition integration. |
| packages/compiler/src/ast/nodes/functions/call/function_call.cpp | Add generic type argument parsing/storage for calls; add is_direct_function_call helper. |
| packages/compiler/src/ast/nodes/expressions/type_cast.cpp | Use SourceFragment::join. |
| packages/compiler/src/ast/nodes/expressions/member_accessor.cpp | Remove enumerable include; use SourceFragment::join. |
| packages/compiler/src/ast/nodes/expressions/identifier.cpp | Make get_definition() return non-const definition pointer; lookup tweaks. |
| packages/compiler/src/ast/nodes/expressions/expression.cpp | Use is_direct_function_call; widen source fragments for logical/comparison ops; use join. |
| packages/compiler/src/ast/nodes/expressions/comparison_operation.cpp | Improve comparison validation and error span reporting; disallow string comparisons. |
| packages/compiler/src/ast/nodes/expressions/array_member_accessor.cpp | Use SourceFragment::join. |
| packages/compiler/src/ast/nodes/expressions/array_initializer.cpp | Use SourceFragment::join. |
| packages/compiler/src/ast/nodes/enumerables.cpp | Remove old enumerable AST implementation. |
| packages/compiler/src/ast/generics.cpp | Add helpers for copying generic type lists, overload naming, and resolving generics in bodies. |
| packages/compiler/src/ast/context/parsing_context.cpp | Remove legacy symbol-definition helpers; include new FunctionDefinition. |
| packages/compiler/src/ast/context/function_registry.cpp | Add generic-count-aware function lookup signature; add generic overload helpers. |
| packages/compiler/src/ast/context/field_registry.cpp | Allow overwriting variable definitions; return non-const FieldDefinition*. |
| packages/compiler/src/ast/ast.cpp | Switch enum parsing to parse_enum_type_definition. |
| packages/compiler/include/files.h | Rename SourceFragment::combine to join. |
| packages/compiler/include/ast/visitor.h | Move IVisitor definition into visitor.h; add accept overload for AstFunctionCall. |
| packages/compiler/include/ast/type_inference.h | Rename function-type inference parameter expression → function. |
| packages/compiler/include/ast/tokens/token.h | Add Token::is_type_token() helper for generic-call lookahead. |
| packages/compiler/include/ast/parsing_context.h | Refactor definitions; move FunctionDefinition out; add setters and overwrite options. |
| packages/compiler/include/ast/nodes/types.h | Add generics to AstFunctionType; add AstEnumType; add enum member aliases. |
| packages/compiler/include/ast/nodes/type_definition.h | Fix namespace typo; add enum parse declarations and default generics arg. |
| packages/compiler/include/ast/nodes/traversal.h | Remove duplicate IVisitor interface (now in visitor.h). |
| packages/compiler/include/ast/nodes/function_declaration.h | Add overload dispatch support and generic helpers; refactor naming/definitions. |
| packages/compiler/include/ast/nodes/expression.h | Add generic args to AstFunctionCall; add is_direct_function_call declaration. |
| packages/compiler/include/ast/nodes/enumerables.h | Remove old enumerable header. |
| packages/compiler/include/ast/generics.h | Add overload-name helper and resolve_generics_in_body API. |
| packages/compiler/include/ast/definitions/function_definition.h | New header for FunctionDefinition and generic overload storage. |
| example.sr | Update example to demonstrate generics + callbacks/lambdas usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
+135
to
+166
| node = std::make_unique<AstFunctionDeclaration>( | ||
| this->get_context(), | ||
| this->get_symbol(), | ||
| std::move(instantiated_function_params), | ||
| std::move(resolved_body), | ||
| std::move(instantiated_return_ty), | ||
| this->get_visibility(), | ||
| this->get_flags(), | ||
| EMPTY_GENERIC_PARAMETER_LIST | ||
| ); | ||
|
|
||
| const auto overloaded_fn_name = get_overloaded_function_name( | ||
| this->get_registered_function_name(), | ||
| instantiated_generic_types); | ||
| llvm::FunctionType* generic_function_type = this->get_llvm_function_type( | ||
| module, | ||
| captured_types, | ||
| instantiated_generic_types | ||
| ); | ||
|
|
||
| llvm_function = llvm::Function::Create( | ||
| generic_function_type, | ||
| linkage, | ||
| overloaded_fn_name, | ||
| module | ||
| ); | ||
|
|
||
| for (const auto& instantiated_param : instantiated_function_params) | ||
| { | ||
| const auto param_symbol = Symbol(instantiated_param->get_source_fragment(), instantiated_param->get_name()); | ||
| instantiated_param->get_context()->define_variable( | ||
| param_symbol, |
Comment on lines
+32
to
+54
| if (const auto fn_def = context->get_function_definition( | ||
| fn_call->get_scoped_function_name(), | ||
| fn_call->get_argument_types(), | ||
| fn_call->get_generic_type_arguments().size() | ||
| ); | ||
| fn_def.has_value()) | ||
| { | ||
| return fn_def.value()->get_type()->get_return_type()->clone_ty(); | ||
| auto return_type = fn_def.value()->get_type()->get_return_type()->clone_ty(); | ||
|
|
||
| // For generic function calls, resolve the return type by substituting | ||
| // generic parameter names with the concrete type arguments from the call site. | ||
| // e.g. arrayOf<string>(...) has return type Array<T> → Array<string> | ||
| if (const auto& generic_args = fn_call->get_generic_type_arguments(); | ||
| !generic_args.empty()) | ||
| { | ||
| const auto& param_names = fn_def.value()->get_type()->get_generic_parameter_names(); | ||
| if (param_names.size() == generic_args.size()) | ||
| { | ||
| return_type = resolve_generics(return_type.get(), param_names, generic_args); | ||
| } | ||
| } | ||
|
|
||
| return return_type; |
…casting logic - Guarded against unresolved generic parameters in multiple cases (e.g., type extraction, casting, and assignability checks). - Updated type inference to prioritize unresolved generic parameters when resolving operation types. - Adjusted `AstVariableDeclaration` creation to use `std::optional` for annotated types.
- Extracted `codegen_ptr` from `AstIdentifier` for pointer-based code generation. - Refactored generic type resolution to include annotated types in `AstVariableDeclaration`. - Streamlined identifier resolution for globals and functions. - Simplified generic overload management and added guard clauses for absent overloads in function declarations.
- Added logic to temporarily update and restore parameter types during validation of generic function instantiations. - Refined LLVM code generation to resolve return and parameter types for generic functions. - Enhanced generic function matching in the function registry based on parameter counts.
…ric function variants before type resolution to ensure generic parameters are resolved correctly
…neric function definitions and improving instantiation logic
…pdate related parsing and traversal logic
…e resolution and improving AST traversal methods
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.