Skip to content

Feature: Add generic support to functions#19

Closed
VxTi wants to merge 31 commits into
mainfrom
feature/add-generic-support-to-functions
Closed

Feature: Add generic support to functions#19
VxTi wants to merge 31 commits into
mainfrom
feature/add-generic-support-to-functions

Conversation

@VxTi
Copy link
Copy Markdown
Owner

@VxTi VxTi commented Mar 16, 2026

No description provided.

VxTi added 19 commits March 15, 2026 14:50
…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
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 AstFunctionCall parsing/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::combineSourceFragment::join across the codebase, and add/replace enum handling with AstEnumType.

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 expressionfunction.
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 thread packages/compiler/include/ast/nodes/types.h Outdated
Comment thread packages/compiler/src/ast/nodes/functions/call/function_call.cpp Outdated
Comment thread packages/compiler/tests/utils.h Outdated
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;
Comment thread packages/compiler/src/ast/context/function_registry.cpp
Comment thread packages/compiler/src/ast/context/function_registry.cpp
VxTi added 8 commits March 16, 2026 21:07
…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
@VxTi VxTi closed this Mar 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants