From 5a289492a372e928ed1938ed08aecb08a13080a8 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Sat, 25 Oct 2025 18:33:38 +0200 Subject: [PATCH] AST Types --- Src/AST/Myc.Ast.Binding.pas | 168 ++++++++++++++++++++++++++++++------ 1 file changed, 143 insertions(+), 25 deletions(-) diff --git a/Src/AST/Myc.Ast.Binding.pas b/Src/AST/Myc.Ast.Binding.pas index aeddd42..353ce37 100644 --- a/Src/AST/Myc.Ast.Binding.pas +++ b/Src/AST/Myc.Ast.Binding.pas @@ -45,7 +45,6 @@ type TUpvalueMapping = class public Map: TDictionary; - Nodes: TList; constructor Create; destructor Destroy; override; end; @@ -95,52 +94,102 @@ type ): IAstNode; static; end; - TBoundIdentifierNode = class(TIdentifierNode) + // New base class for all bound nodes + TBoundNode = class abstract(TInterfacedObject, IAstNode) + public + function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract; + end; + + // Concrete bound identifier node + TBoundIdentifierNode = class(TBoundNode, IIdentifierNode) private + FSource: IIdentifierNode; // The original Node. FAddress: TResolvedAddress; + function GetName: string; public - constructor Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress); + constructor Create(const ASource: IIdentifierNode; const AAddress: TResolvedAddress); + function Accept(const Visitor: IAstVisitor): TDataValue; override; property Address: TResolvedAddress read FAddress; + property Name: string read GetName; + property Source: IIdentifierNode read FSource; end; - TBoundVariableDeclarationNode = class(TVariableDeclarationNode) + // Bound variable declaration node + TBoundVariableDeclarationNode = class(TBoundNode, IVariableDeclarationNode) private + FSource: IVariableDeclarationNode; + FIdentifier: IIdentifierNode; + FInitializer: IAstNode; FIsBoxed: Boolean; + function GetIdentifier: IIdentifierNode; + function GetInitializer: IAstNode; public - constructor Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean); + constructor Create( + const ASource: IVariableDeclarationNode; + const AIdentifier: IIdentifierNode; // This is the bound identifier + AInitializer: IAstNode; // This is the bound initializer + AIsBoxed: Boolean + ); + function Accept(const Visitor: IAstVisitor): TDataValue; override; property IsBoxed: Boolean read FIsBoxed; + property Source: IVariableDeclarationNode read FSource; + // IVariableDeclarationNode implementation + property Identifier: IIdentifierNode read GetIdentifier; + property Initializer: IAstNode read GetInitializer; end; - TBoundLambdaExpressionNode = class(TLambdaExpressionNode) + // Bound lambda expression node + TBoundLambdaExpressionNode = class(TBoundNode, ILambdaExpressionNode) private + FSource: ILambdaExpressionNode; + FParameters: TArray; // Bound parameters + FBody: IAstNode; // Bound body FScopeDescriptor: IScopeDescriptor; FUpvalues: TArray; FHasNestedLambdas: Boolean; + function GetBody: IAstNode; + function GetParameters: TArray; public constructor Create( - const AUnboundNode: ILambdaExpressionNode; - const ABody: IAstNode; - const AParameters: TArray; + const ASource: ILambdaExpressionNode; + const ABody: IAstNode; // Bound body + const AParameters: TArray; // Bound parameters const AScopeDescriptor: IScopeDescriptor; const AUpvalues: TArray; AHasNestedLambdas: Boolean ); + function Accept(const Visitor: IAstVisitor): TDataValue; override; property ScopeDescriptor: IScopeDescriptor read FScopeDescriptor; property Upvalues: TArray read FUpvalues; property HasNestedLambdas: Boolean read FHasNestedLambdas; + property Source: ILambdaExpressionNode read FSource; + // ILambdaExpressionNode implementation + property Parameters: TArray read GetParameters; + property Body: IAstNode read GetBody; end; - TBoundFunctionCallNode = class(TFunctionCallNode) + // Bound function call node + TBoundFunctionCallNode = class(TBoundNode, IFunctionCallNode) private + FSource: IFunctionCallNode; + FCallee: IAstNode; // Bound callee + FArguments: TArray; // Bound arguments FIsTailCall: Boolean; + function GetArguments: TArray; + function GetCallee: IAstNode; public constructor Create( - const AUnboundNode: IFunctionCallNode; - const ACallee: IAstNode; - const AArguments: TArray; + const ASource: IFunctionCallNode; + const ACallee: IAstNode; // Bound callee + const AArguments: TArray; // Bound arguments AIsTailCall: Boolean ); + function Accept(const Visitor: IAstVisitor): TDataValue; override; property IsTailCall: Boolean read FIsTailCall; + property Source: IFunctionCallNode read FSource; + // IFunctionCallNode implementation + property Callee: IAstNode read GetCallee; + property Arguments: TArray read GetArguments; end; implementation @@ -268,22 +317,57 @@ begin end; { TBoundIdentifierNode } -constructor TBoundIdentifierNode.Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress); + +constructor TBoundIdentifierNode.Create(const ASource: IIdentifierNode; const AAddress: TResolvedAddress); begin - inherited Create(AUnboundNode.Name); + inherited Create; + FSource := ASource; FAddress := AAddress; end; -{ TBoundVariableDeclarationNode } -constructor TBoundVariableDeclarationNode.Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean); +function TBoundIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue; begin - inherited Create(AIdentifier, AInitializer); + Result := Visitor.VisitIdentifier(Self); +end; + +function TBoundIdentifierNode.GetName: string; +begin + Result := FSource.Name; +end; + +{ TBoundVariableDeclarationNode } +constructor TBoundVariableDeclarationNode.Create( + const ASource: IVariableDeclarationNode; + const AIdentifier: IIdentifierNode; + AInitializer: IAstNode; + AIsBoxed: Boolean +); +begin + inherited Create; + FSource := ASource; + FIdentifier := AIdentifier; + FInitializer := AInitializer; FIsBoxed := AIsBoxed; end; +function TBoundVariableDeclarationNode.Accept(const Visitor: IAstVisitor): TDataValue; +begin + Result := Visitor.VisitVariableDeclaration(Self); +end; + +function TBoundVariableDeclarationNode.GetIdentifier: IIdentifierNode; +begin + Result := FIdentifier; +end; + +function TBoundVariableDeclarationNode.GetInitializer: IAstNode; +begin + Result := FInitializer; +end; + { TBoundLambdaExpressionNode } constructor TBoundLambdaExpressionNode.Create( - const AUnboundNode: ILambdaExpressionNode; + const ASource: ILambdaExpressionNode; const ABody: IAstNode; const AParameters: TArray; const AScopeDescriptor: IScopeDescriptor; @@ -291,24 +375,60 @@ constructor TBoundLambdaExpressionNode.Create( AHasNestedLambdas: Boolean ); begin - inherited Create(AParameters, ABody); + inherited Create; + FSource := ASource; + FBody := ABody; + FParameters := AParameters; FScopeDescriptor := AScopeDescriptor; FUpvalues := AUpvalues; FHasNestedLambdas := AHasNestedLambdas; end; +function TBoundLambdaExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue; +begin + Result := Visitor.VisitLambdaExpression(Self); +end; + +function TBoundLambdaExpressionNode.GetBody: IAstNode; +begin + Result := FBody; +end; + +function TBoundLambdaExpressionNode.GetParameters: TArray; +begin + Result := FParameters; +end; + { TBoundFunctionCallNode } constructor TBoundFunctionCallNode.Create( - const AUnboundNode: IFunctionCallNode; + const ASource: IFunctionCallNode; const ACallee: IAstNode; const AArguments: TArray; AIsTailCall: Boolean ); begin - inherited Create(ACallee, AArguments); + inherited Create; + FSource := ASource; + FCallee := ACallee; + FArguments := AArguments; FIsTailCall := AIsTailCall; end; +function TBoundFunctionCallNode.Accept(const Visitor: IAstVisitor): TDataValue; +begin + Result := Visitor.VisitFunctionCall(Self); +end; + +function TBoundFunctionCallNode.GetArguments: TArray; +begin + Result := FArguments; +end; + +function TBoundFunctionCallNode.GetCallee: IAstNode; +begin + Result := FCallee; +end; + { TResolvedAddressComparer } function TResolvedAddressComparer.Equals(const Left, Right: TResolvedAddress): Boolean; begin @@ -328,12 +448,10 @@ constructor TAstBinder.TUpvalueMapping.Create; begin inherited Create; Map := TDictionary.Create(TResolvedAddressComparer.Create); - Nodes := TList.Create(); end; destructor TAstBinder.TUpvalueMapping.Destroy; begin - Nodes.Free; Map.Free; inherited Destroy; end; @@ -776,7 +894,7 @@ begin address := TResolvedAddress.Create(akLocalOrParent, 0, slotIndex); boundIdentifier := TBoundIdentifierNode.Create(Node.Identifier, address); isBoxed := (FBoxedDeclarations <> nil) and FBoxedDeclarations.Contains(Node); - boundDecl := TBoundVariableDeclarationNode.Create(boundIdentifier, initializer, isBoxed); + boundDecl := TBoundVariableDeclarationNode.Create(Node, boundIdentifier, initializer, isBoxed); Result := TDataValue.FromIntf(boundDecl); end;