1st full macro expander
This commit is contained in:
+50
-43
@@ -49,25 +49,24 @@ type
|
||||
// Stack management for tail-call state is centralized here.
|
||||
function Accept(const Node: IAstNode): TDataValue; override;
|
||||
|
||||
// The binder overrides specific visit methods to enrich the AST.
|
||||
function VisitIdentifier(const Node: IIdentifierNode): TDataValue; override;
|
||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; override;
|
||||
function VisitAssignment(const Node: IAssignmentNode): TDataValue; override;
|
||||
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; override;
|
||||
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; override;
|
||||
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; override;
|
||||
function VisitRecurNode(const Node: IRecurNode): TDataValue; override;
|
||||
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; override;
|
||||
function VisitIfExpression(const Node: IIfExpressionNode): TDataValue; override;
|
||||
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; override;
|
||||
function VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue; override;
|
||||
function VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue; override;
|
||||
public
|
||||
constructor Create(const AInitialScope: IExecutionScope);
|
||||
destructor Destroy; override;
|
||||
|
||||
function Execute(const RootNode: IAstNode; out Descriptor: IScopeDescriptor): IAstNode;
|
||||
|
||||
// The binder overrides specific transform methods to enrich the AST.
|
||||
function TransformIdentifier(const Node: IIdentifierNode): IIdentifierNode; override;
|
||||
function TransformVariableDeclaration(const Node: IVariableDeclarationNode): IVariableDeclarationNode; override;
|
||||
function TransformAssignment(const Node: IAssignmentNode): IAssignmentNode; override;
|
||||
function TransformLambdaExpression(const Node: ILambdaExpressionNode): ILambdaExpressionNode; override;
|
||||
function TransformMacroDefinition(const Node: IMacroDefinitionNode): IMacroDefinitionNode; override;
|
||||
function TransformFunctionCall(const Node: IFunctionCallNode): IFunctionCallNode; override;
|
||||
function TransformRecur(const Node: IRecurNode): IRecurNode; override;
|
||||
function TransformBlockExpression(const Node: IBlockExpressionNode): IBlockExpressionNode; override;
|
||||
function TransformIfExpression(const Node: IIfExpressionNode): IIfExpressionNode; override;
|
||||
function TransformTernaryExpression(const Node: ITernaryExpressionNode): ITernaryExpressionNode; override;
|
||||
function TransformBinaryExpression(const Node: IBinaryExpressionNode): IBinaryExpressionNode; override;
|
||||
function TransformUnaryExpression(const Node: IUnaryExpressionNode): IUnaryExpressionNode; override;
|
||||
end;
|
||||
|
||||
TBoundIdentifierNode = class(TIdentifierNode)
|
||||
@@ -285,9 +284,10 @@ begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformIdentifier(const Node: IIdentifierNode): IIdentifierNode;
|
||||
function TAstBinder.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
|
||||
var
|
||||
adr: TResolvedAddress;
|
||||
boundNode: IIdentifierNode;
|
||||
begin
|
||||
adr := FCurrentDescriptor.FindSymbol(Node.Name);
|
||||
if adr.Kind = akLocalOrParent then
|
||||
@@ -306,22 +306,24 @@ begin
|
||||
upvalue.Map.Add(adr, upvalueIndex);
|
||||
end;
|
||||
|
||||
Result := TBoundIdentifierNode.Create(Node, TResolvedAddress.Create(akUpvalue, 0, upvalueIndex));
|
||||
boundNode := TBoundIdentifierNode.Create(Node, TResolvedAddress.Create(akUpvalue, 0, upvalueIndex));
|
||||
end
|
||||
else
|
||||
Result := TBoundIdentifierNode.Create(Node, adr);
|
||||
boundNode := TBoundIdentifierNode.Create(Node, adr);
|
||||
Result := TDataValue.FromIntf<IIdentifierNode>(boundNode);
|
||||
end
|
||||
else
|
||||
raise Exception.CreateFmt('Undefined identifier: "%s"', [Node.Name]);
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformVariableDeclaration(const Node: IVariableDeclarationNode): IVariableDeclarationNode;
|
||||
function TAstBinder.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
||||
var
|
||||
initializer: IAstNode;
|
||||
slotIndex: Integer;
|
||||
address: TResolvedAddress;
|
||||
boundIdentifier: IIdentifierNode;
|
||||
isBoxed: Boolean;
|
||||
boundDecl: IVariableDeclarationNode;
|
||||
begin
|
||||
if not IsValidIdentifier(Node.Identifier.Name) then
|
||||
raise Exception.CreateFmt('Invalid identifier name: "%s".', [Node.Identifier.Name]);
|
||||
@@ -340,28 +342,29 @@ begin
|
||||
isBoxed := (FBoxedDeclarations <> nil) and FBoxedDeclarations.Contains(Node);
|
||||
|
||||
// Always create a bound declaration node, passing the IsBoxed flag.
|
||||
Result := TBoundVariableDeclarationNode.Create(boundIdentifier, initializer, isBoxed);
|
||||
boundDecl := TBoundVariableDeclarationNode.Create(boundIdentifier, initializer, isBoxed);
|
||||
Result := TDataValue.FromIntf<IVariableDeclarationNode>(boundDecl);
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformAssignment(const Node: IAssignmentNode): IAssignmentNode;
|
||||
function TAstBinder.VisitAssignment(const Node: IAssignmentNode): TDataValue;
|
||||
begin
|
||||
FNextIsTail := False;
|
||||
Result := inherited TransformAssignment(Node);
|
||||
Result := inherited VisitAssignment(Node);
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformBinaryExpression(const Node: IBinaryExpressionNode): IBinaryExpressionNode;
|
||||
function TAstBinder.VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue;
|
||||
begin
|
||||
FNextIsTail := False;
|
||||
Result := inherited TransformBinaryExpression(Node);
|
||||
Result := inherited VisitBinaryExpression(Node);
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformUnaryExpression(const Node: IUnaryExpressionNode): IUnaryExpressionNode;
|
||||
function TAstBinder.VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue;
|
||||
begin
|
||||
FNextIsTail := False;
|
||||
Result := inherited TransformUnaryExpression(Node);
|
||||
Result := inherited VisitUnaryExpression(Node);
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformLambdaExpression(const Node: ILambdaExpressionNode): ILambdaExpressionNode;
|
||||
function TAstBinder.VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
|
||||
var
|
||||
i: integer;
|
||||
boundParams: TArray<IIdentifierNode>;
|
||||
@@ -370,6 +373,7 @@ var
|
||||
upvalues: TArray<TResolvedAddress>;
|
||||
hasNestedLambdas: Boolean;
|
||||
lastNestedLambdaCount: Integer;
|
||||
boundLambda: ILambdaExpressionNode;
|
||||
begin
|
||||
FUpvalueStack.Push(TUpvalueMapping.Create);
|
||||
try
|
||||
@@ -415,14 +419,16 @@ begin
|
||||
end;
|
||||
|
||||
inc(FNestedLambdaCount);
|
||||
Result := TBoundLambdaExpressionNode.Create(Node, boundBody, boundParams, lambdaScope, upvalues, hasNestedLambdas);
|
||||
boundLambda := TBoundLambdaExpressionNode.Create(Node, boundBody, boundParams, lambdaScope, upvalues, hasNestedLambdas);
|
||||
Result := TDataValue.FromIntf<ILambdaExpressionNode>(boundLambda);
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformFunctionCall(const Node: IFunctionCallNode): IFunctionCallNode;
|
||||
function TAstBinder.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
|
||||
var
|
||||
isTailCall: Boolean;
|
||||
callee: IAstNode;
|
||||
args: TArray<IAstNode>;
|
||||
boundCall: IFunctionCallNode;
|
||||
begin
|
||||
isTailCall := FIsTailStack.Peek;
|
||||
|
||||
@@ -430,19 +436,20 @@ begin
|
||||
callee := Accept(Node.Callee).AsIntf<IAstNode>;
|
||||
args := TransformNodes<IAstNode>(Node.Arguments);
|
||||
|
||||
Result := TBoundFunctionCallNode.Create(Node, callee, args, isTailCall);
|
||||
boundCall := TBoundFunctionCallNode.Create(Node, callee, args, isTailCall);
|
||||
Result := TDataValue.FromIntf<IFunctionCallNode>(boundCall);
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformRecur(const Node: IRecurNode): IRecurNode;
|
||||
function TAstBinder.VisitRecurNode(const Node: IRecurNode): TDataValue;
|
||||
begin
|
||||
if not FIsTailStack.Peek then
|
||||
raise Exception.Create('''recur'' can only be used in a tail position.');
|
||||
|
||||
FNextIsTail := False;
|
||||
Result := inherited TransformRecur(Node);
|
||||
Result := inherited VisitRecurNode(Node);
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformBlockExpression(const Node: IBlockExpressionNode): IBlockExpressionNode;
|
||||
function TAstBinder.VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
|
||||
var
|
||||
exprs: TArray<IAstNode>;
|
||||
i: Integer;
|
||||
@@ -450,16 +457,16 @@ var
|
||||
begin
|
||||
isContextTail := FIsTailStack.Peek;
|
||||
|
||||
SetLength(exprs, Node.Expressions.Count);
|
||||
for i := 0 to Node.Expressions.Count - 1 do
|
||||
SetLength(exprs, Length(Node.Expressions));
|
||||
for i := 0 to High(exprs) do
|
||||
begin
|
||||
FNextIsTail := isContextTail and (i = Node.Expressions.Count - 1);
|
||||
FNextIsTail := isContextTail and (i = High(exprs));
|
||||
exprs[i] := Accept(Node.Expressions[i]).AsIntf<IAstNode>;
|
||||
end;
|
||||
Result := TAst.Block(exprs);
|
||||
Result := TDataValue.FromIntf<IBlockExpressionNode>(TAst.Block(exprs));
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformIfExpression(const Node: IIfExpressionNode): IIfExpressionNode;
|
||||
function TAstBinder.VisitIfExpression(const Node: IIfExpressionNode): TDataValue;
|
||||
var
|
||||
isContextTail: Boolean;
|
||||
condition, thenBranch, elseBranch: IAstNode;
|
||||
@@ -474,18 +481,18 @@ begin
|
||||
elseBranch := Accept(Node.ElseBranch).AsIntf<IAstNode>;
|
||||
|
||||
if (condition <> Node.Condition) or (thenBranch <> Node.ThenBranch) or (elseBranch <> Node.ElseBranch) then
|
||||
Result := TAst.IfExpr(condition, thenBranch, elseBranch)
|
||||
Result := TDataValue.FromIntf<IIfExpressionNode>(TAst.IfExpr(condition, thenBranch, elseBranch))
|
||||
else
|
||||
Result := Node;
|
||||
Result := TDataValue.FromIntf<IIfExpressionNode>(Node);
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformMacroDefinition(const Node: IMacroDefinitionNode): IMacroDefinitionNode;
|
||||
function TAstBinder.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
||||
begin
|
||||
// The binder runs after the macro expander. It should never see a macro definition.
|
||||
raise Exception.Create('IMacroDefinitionNode found in AST after macro expansion phase.');
|
||||
end;
|
||||
|
||||
function TAstBinder.TransformTernaryExpression(const Node: ITernaryExpressionNode): ITernaryExpressionNode;
|
||||
function TAstBinder.VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
|
||||
var
|
||||
isContextTail: Boolean;
|
||||
condition, thenBranch, elseBranch: IAstNode;
|
||||
@@ -500,9 +507,9 @@ begin
|
||||
elseBranch := Accept(Node.ElseBranch).AsIntf<IAstNode>;
|
||||
|
||||
if (condition <> Node.Condition) or (thenBranch <> Node.ThenBranch) or (elseBranch <> Node.ElseBranch) then
|
||||
Result := TAst.TernaryExpr(condition, thenBranch, elseBranch)
|
||||
Result := TDataValue.FromIntf<ITernaryExpressionNode>(TAst.TernaryExpr(condition, thenBranch, elseBranch))
|
||||
else
|
||||
Result := Node;
|
||||
Result := TDataValue.FromIntf<ITernaryExpressionNode>(Node);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user