AST Types

This commit is contained in:
Michael Schimmel
2025-10-26 09:58:42 +01:00
parent 85f2e02893
commit e379e6694c
7 changed files with 523 additions and 91 deletions
+14 -9
View File
@@ -33,6 +33,9 @@ type
implementation
uses
Myc.Ast.Types; // Added for TTypes.Unknown
{ TUpvalueAnalyzer }
constructor TUpvalueAnalyzer.Create(const AParent: IScopeDescriptor);
@@ -71,17 +74,17 @@ end;
procedure TUpvalueAnalyzer.MarkDeclarationForBoxing(const AName: string);
var
address: TResolvedAddress;
symbol: TResolvedSymbol;
declarationScope: IScopeDescriptor;
i: Integer;
begin
address := FCurrentScope.FindSymbol(AName);
if address.Kind <> akLocalOrParent then
symbol := FCurrentScope.FindSymbol(AName);
if symbol.Address.Kind <> akLocalOrParent then
exit;
// Walk up the scope chain to find the scope where the variable was declared.
declarationScope := FCurrentScope;
for i := 1 to address.ScopeDepth do
for i := 1 to symbol.Address.ScopeDepth do
begin
if not Assigned(declarationScope.Parent) then
exit; // Should not happen in a correctly bound tree
@@ -100,13 +103,13 @@ end;
function TUpvalueAnalyzer.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
var
address: TResolvedAddress;
symbol: TResolvedSymbol;
begin
if Assigned(FCurrentScope) then
begin
address := FCurrentScope.FindSymbol(Node.Name);
symbol := FCurrentScope.FindSymbol(Node.Name);
if (address.Kind = akLocalOrParent) and (address.ScopeDepth > 0) then
if (symbol.Address.Kind = akLocalOrParent) and (symbol.Address.ScopeDepth > 0) then
begin
// This is an upvalue. Mark its original declaration for boxing.
MarkDeclarationForBoxing(Node.Name);
@@ -123,8 +126,9 @@ begin
FCurrentScope := TScope.CreateDescriptor(FCurrentScope);
try
// Define the lambda's parameters within its new scope.
// We use TTypes.Unknown as type inference hasn't run yet.
for var param in Node.Parameters do
FCurrentScope.Define(param.Name);
FCurrentScope.Define(param.Name, TTypes.Unknown);
// Traverse the lambda body within the new scope context.
Node.Body.Accept(Self);
@@ -147,7 +151,8 @@ begin
Node.Initializer.Accept(Self);
// After processing the initializer, define the variable in the current scope.
FCurrentScope.Define(Node.Identifier.Name);
// We use TTypes.Unknown as type inference hasn't run yet.
FCurrentScope.Define(Node.Identifier.Name, TTypes.Unknown);
// Map this declaration node to its scope and name for later lookup.
if not FDeclarationMap.TryGetValue(FCurrentScope, scopeDeclarations) then