AST list refactoring
This commit is contained in:
@@ -18,17 +18,10 @@ type
|
||||
FTarget: IAstNode;
|
||||
FRemoved: Boolean;
|
||||
|
||||
function FilterList<T: IAstNode>(const Source: INodeList<T>): TArray<T>;
|
||||
function FilterTuple(const Source: ITupleNode): TArray<IAstNode>;
|
||||
function EnsureNode(const Node: IAstNode; const ContextNode: IAstNode): IAstNode;
|
||||
|
||||
strict private
|
||||
// List Containers (Filter Logic)
|
||||
function VisitBlockExpression(const Node: IAstNode): IAstNode;
|
||||
function VisitExpressionList(const Node: IAstNode): IAstNode;
|
||||
function VisitArgumentList(const Node: IAstNode): IAstNode;
|
||||
function VisitParameterList(const Node: IAstNode): IAstNode;
|
||||
function VisitRecordFieldList(const Node: IAstNode): IAstNode;
|
||||
|
||||
// Structural Nodes (Replace Logic)
|
||||
function VisitIfExpression(const Node: IAstNode): IAstNode;
|
||||
function VisitCondExpression(const Node: IAstNode): IAstNode;
|
||||
@@ -39,7 +32,11 @@ type
|
||||
function VisitIndexer(const Node: IAstNode): IAstNode;
|
||||
function VisitMemberAccess(const Node: IAstNode): IAstNode;
|
||||
function VisitAddSeriesItem(const Node: IAstNode): IAstNode;
|
||||
|
||||
// Unified Container Handler
|
||||
function VisitTuple(const Node: IAstNode): IAstNode;
|
||||
function VisitBlockExpression(const Node: IAstNode): IAstNode;
|
||||
function VisitRecurNode(const Node: IAstNode): IAstNode;
|
||||
|
||||
protected
|
||||
procedure SetupHandlers; override;
|
||||
@@ -65,13 +62,6 @@ procedure TAstNodeRemover.SetupHandlers;
|
||||
begin
|
||||
inherited SetupHandlers; // Defaults
|
||||
|
||||
// Filter Logic
|
||||
Register(akBlockExpression, VisitBlockExpression);
|
||||
Register(akExpressionList, VisitExpressionList);
|
||||
Register(akArgumentList, VisitArgumentList);
|
||||
Register(akParameterList, VisitParameterList);
|
||||
Register(akRecordFieldList, VisitRecordFieldList);
|
||||
|
||||
// Replace Logic
|
||||
Register(akIfExpression, VisitIfExpression);
|
||||
Register(akCondExpression, VisitCondExpression);
|
||||
@@ -82,7 +72,10 @@ begin
|
||||
Register(akIndexer, VisitIndexer);
|
||||
Register(akMemberAccess, VisitMemberAccess);
|
||||
Register(akAddSeriesItem, VisitAddSeriesItem);
|
||||
Register(akBlockExpression, VisitBlockExpression);
|
||||
Register(akRecur, VisitRecurNode);
|
||||
|
||||
// List Logic
|
||||
Register(akTuple, VisitTuple);
|
||||
end;
|
||||
|
||||
@@ -129,21 +122,20 @@ begin
|
||||
Result := TAst.Nop(ContextNode.Identity);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.FilterList<T>(const Source: INodeList<T>): TArray<T>;
|
||||
function TAstNodeRemover.FilterTuple(const Source: ITupleNode): TArray<IAstNode>;
|
||||
var
|
||||
i: Integer;
|
||||
item: T;
|
||||
transformed: IAstNode;
|
||||
list: TList<T>;
|
||||
item, transformed: IAstNode;
|
||||
list: TList<IAstNode>;
|
||||
begin
|
||||
list := TList<T>.Create;
|
||||
list := TList<IAstNode>.Create;
|
||||
try
|
||||
for i := 0 to Source.Count - 1 do
|
||||
begin
|
||||
item := Source[i];
|
||||
item := Source.Items[i];
|
||||
transformed := Accept(item);
|
||||
if Assigned(transformed) then
|
||||
list.Add(T(transformed));
|
||||
list.Add(transformed);
|
||||
end;
|
||||
Result := list.ToArray;
|
||||
finally
|
||||
@@ -151,121 +143,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// List Visitors (Filtering)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function TAstNodeRemover.VisitBlockExpression(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
B: IBlockExpressionNode;
|
||||
newExprs: TArray<IAstNode>;
|
||||
newList: IExpressionList;
|
||||
changed: Boolean;
|
||||
i: Integer;
|
||||
begin
|
||||
B := Node.AsBlockExpression;
|
||||
newExprs := FilterList<IAstNode>(B.Expressions);
|
||||
|
||||
if Length(newExprs) = B.Expressions.Count then
|
||||
begin
|
||||
if not FRemoved then
|
||||
Exit(Node);
|
||||
changed := False;
|
||||
for i := 0 to High(newExprs) do
|
||||
if newExprs[i] <> B.Expressions[i] then
|
||||
changed := True;
|
||||
if not changed then
|
||||
Exit(Node);
|
||||
end;
|
||||
|
||||
newList := TExpressionList.Create(newExprs, B.Expressions.Identity);
|
||||
Result := TAst.Block(Node.Identity, newList, B.StaticType);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.VisitExpressionList(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
L: IExpressionList;
|
||||
newExprs: TArray<IAstNode>;
|
||||
changed: Boolean;
|
||||
i: Integer;
|
||||
begin
|
||||
L := Node.AsExpressionList;
|
||||
newExprs := FilterList<IAstNode>(L);
|
||||
if Length(newExprs) = L.Count then
|
||||
begin
|
||||
changed := False;
|
||||
for i := 0 to High(newExprs) do
|
||||
if newExprs[i] <> L[i] then
|
||||
changed := True;
|
||||
if not changed then
|
||||
Exit(Node);
|
||||
end;
|
||||
Result := TExpressionList.Create(newExprs, Node.Identity);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.VisitArgumentList(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
L: IArgumentList;
|
||||
newArgs: TArray<IAstNode>;
|
||||
changed: Boolean;
|
||||
i: Integer;
|
||||
begin
|
||||
L := Node.AsArgumentList;
|
||||
newArgs := FilterList<IAstNode>(L);
|
||||
if Length(newArgs) = L.Count then
|
||||
begin
|
||||
changed := False;
|
||||
for i := 0 to High(newArgs) do
|
||||
if newArgs[i] <> L[i] then
|
||||
changed := True;
|
||||
if not changed then
|
||||
Exit(Node);
|
||||
end;
|
||||
Result := TArgumentList.Create(newArgs, Node.Identity);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.VisitParameterList(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
L: IParameterList;
|
||||
newParams: TArray<IIdentifierNode>;
|
||||
changed: Boolean;
|
||||
i: Integer;
|
||||
begin
|
||||
L := Node.AsParameterList;
|
||||
newParams := FilterList<IIdentifierNode>(L);
|
||||
if Length(newParams) = L.Count then
|
||||
begin
|
||||
changed := False;
|
||||
for i := 0 to High(newParams) do
|
||||
if newParams[i] <> L[i] then
|
||||
changed := True;
|
||||
if not changed then
|
||||
Exit(Node);
|
||||
end;
|
||||
Result := TParameterList.Create(newParams, Node.Identity);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.VisitRecordFieldList(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
L: IRecordFieldList;
|
||||
newFields: TArray<IRecordFieldNode>;
|
||||
changed: Boolean;
|
||||
i: Integer;
|
||||
begin
|
||||
L := Node.AsRecordFieldList;
|
||||
newFields := FilterList<IRecordFieldNode>(L);
|
||||
if Length(newFields) = L.Count then
|
||||
begin
|
||||
changed := False;
|
||||
for i := 0 to High(newFields) do
|
||||
if newFields[i] <> L[i] then
|
||||
changed := True;
|
||||
if not changed then
|
||||
Exit(Node);
|
||||
end;
|
||||
Result := TRecordFieldList.Create(newFields, Node.Identity);
|
||||
end;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Structural Visitors (Replacement with Nop/Void)
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -345,45 +222,38 @@ end;
|
||||
function TAstNodeRemover.VisitLambdaExpression(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
L: ILambdaExpressionNode;
|
||||
newParams, newBody: IAstNode;
|
||||
newParams: TArray<IAstNode>;
|
||||
newBody: IAstNode;
|
||||
paramTuple: ITupleNode;
|
||||
begin
|
||||
L := Node.AsLambdaExpression;
|
||||
newParams := Accept(L.Parameters);
|
||||
if newParams = nil then
|
||||
newParams := TParameterList.Create([], L.Parameters.Identity);
|
||||
|
||||
// Filter parameters (removing a parameter is semantically risky but consistent with "Remove" logic)
|
||||
newParams := FilterTuple(L.Parameters);
|
||||
|
||||
newBody := EnsureNode(Accept(L.Body), Node);
|
||||
|
||||
if (newParams = L.Parameters) and (newBody = L.Body) then
|
||||
Exit(Node);
|
||||
// Factory creates new Tuple from Array
|
||||
paramTuple := TAst.Tuple(L.Parameters.Identity, newParams);
|
||||
|
||||
Result :=
|
||||
TAst.LambdaExpr(
|
||||
Node.Identity,
|
||||
newParams.AsParameterList,
|
||||
newBody,
|
||||
L.Layout,
|
||||
L.Descriptor,
|
||||
L.Upvalues,
|
||||
L.HasNestedLambdas,
|
||||
L.IsPure,
|
||||
L.StaticType
|
||||
);
|
||||
TAst.LambdaExpr(Node.Identity, paramTuple, newBody, L.Layout, L.Descriptor, L.Upvalues, L.HasNestedLambdas, L.IsPure, L.StaticType);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.VisitFunctionCall(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
C: IFunctionCallNode;
|
||||
newCallee, newArgs: IAstNode;
|
||||
newCallee: IAstNode;
|
||||
newArgs: TArray<IAstNode>;
|
||||
argsTuple: ITupleNode;
|
||||
begin
|
||||
C := Node.AsFunctionCall;
|
||||
newCallee := EnsureNode(Accept(C.Callee), Node);
|
||||
newArgs := Accept(C.Arguments);
|
||||
if newArgs = nil then
|
||||
newArgs := TArgumentList.Create([], C.Arguments.Identity);
|
||||
newArgs := FilterTuple(C.Arguments);
|
||||
|
||||
if (newCallee = C.Callee) and (newArgs = C.Arguments) then
|
||||
Exit(Node);
|
||||
Result :=
|
||||
TAst.FunctionCall(Node.Identity, newCallee, newArgs.AsArgumentList, C.StaticType, C.IsTailCall, C.StaticTarget, C.IsTargetPure);
|
||||
argsTuple := TAst.Tuple(C.Arguments.Identity, newArgs);
|
||||
|
||||
Result := TAst.FunctionCall(Node.Identity, newCallee, argsTuple, C.StaticType, C.IsTailCall, C.StaticTarget, C.IsTargetPure);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.VisitIndexer(const Node: IAstNode): IAstNode;
|
||||
@@ -432,6 +302,31 @@ begin
|
||||
Result := TAst.AddSeriesItem(Node.Identity, newSeries.AsIdentifier, newValue, newLookback, A.StaticType);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.VisitBlockExpression(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
B: IBlockExpressionNode;
|
||||
newExprs: TArray<IAstNode>;
|
||||
exprsTuple: ITupleNode;
|
||||
begin
|
||||
B := Node.AsBlockExpression;
|
||||
newExprs := FilterTuple(B.Expressions);
|
||||
|
||||
exprsTuple := TAst.Tuple(B.Expressions.Identity, newExprs);
|
||||
Result := TAst.Block(Node.Identity, exprsTuple, B.StaticType);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.VisitRecurNode(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
R: IRecurNode;
|
||||
newArgs: TArray<IAstNode>;
|
||||
argsTuple: ITupleNode;
|
||||
begin
|
||||
R := Node.AsRecur;
|
||||
newArgs := FilterTuple(R.Arguments);
|
||||
argsTuple := TAst.Tuple(R.Arguments.Identity, newArgs);
|
||||
Result := TAst.Recur(Node.Identity, argsTuple, R.StaticType);
|
||||
end;
|
||||
|
||||
function TAstNodeRemover.VisitTuple(const Node: IAstNode): IAstNode;
|
||||
var
|
||||
T: ITupleNode;
|
||||
@@ -445,9 +340,9 @@ begin
|
||||
list := TList<IAstNode>.Create;
|
||||
hasChanged := False;
|
||||
try
|
||||
for i := 0 to High(T.Elements) do
|
||||
for i := 0 to T.Count - 1 do
|
||||
begin
|
||||
item := T.Elements[i];
|
||||
item := T.Items[i];
|
||||
transformed := Accept(item);
|
||||
|
||||
if transformed <> item then
|
||||
@@ -462,7 +357,8 @@ begin
|
||||
if not hasChanged then
|
||||
Exit(Node);
|
||||
|
||||
Result := TAst.Tuple(Node.Identity, list.ToArray, T.StaticType);
|
||||
newElements := list.ToArray;
|
||||
Result := TAst.Tuple(Node.Identity, newElements, T.StaticType);
|
||||
finally
|
||||
list.Free;
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user