Files
MycLib/Src/AST/Myc.Fmx.AstEditor.Handlers.pas
T
Michael Schimmel cd0f2ffde3 Ast editor rename
2025-11-29 20:42:01 +01:00

1152 lines
35 KiB
ObjectPascal

unit Myc.Fmx.AstEditor.Handlers;
interface
uses
System.SysUtils,
System.Classes,
System.Types,
System.UITypes,
System.Generics.Collections,
FMX.Types,
FMX.Controls,
FMX.StdCtrls,
FMX.Graphics,
Myc.Data.Value,
Myc.Data.Keyword,
Myc.Ast,
Myc.Ast.Nodes,
Myc.Ast.Identities,
Myc.Fmx.AstEditor;
type
// --- Abstract List Base ---
// Handles layout, brackets (from Identity), and child iteration
TNodeListHandler<T: IAstNode> = class(TBaseNodeHandler<INodeList<T>>)
protected
FChildNodes: TList<TAstViewNode>;
function GetOrientation: TLayoutOrientation; virtual; abstract;
function GetAlignment: TLayoutAlignment; virtual;
public
constructor Create(const ANode: INodeList<T>);
destructor Destroy; override;
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override; abstract;
end;
// --- Concrete List Handlers ---
TParameterListHandler = class(TNodeListHandler<IIdentifierNode>)
protected
function GetOrientation: TLayoutOrientation; override;
public
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TArgumentListHandler = class(TNodeListHandler<IAstNode>)
protected
function GetOrientation: TLayoutOrientation; override;
public
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TExpressionListHandler = class(TNodeListHandler<IAstNode>)
protected
function GetOrientation: TLayoutOrientation; override;
function GetAlignment: TLayoutAlignment; override;
public
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TRecordFieldListHandler = class(TNodeListHandler<IRecordFieldNode>)
protected
function GetOrientation: TLayoutOrientation; override;
function GetAlignment: TLayoutAlignment; override;
public
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
// --- Node Handlers ---
TRecordFieldHandler = class(TBaseNodeHandler<IRecordFieldNode>)
private
FKeyLabel: TLabel;
FValueNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TConstantNodeHandler = class(TBaseNodeHandler<IConstantNode>)
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TIdentifierNodeHandler = class(TBaseNodeHandler<IIdentifierNode>)
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TKeywordNodeHandler = class(TBaseNodeHandler<IKeywordNode>)
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TNopNodeHandler = class(TBaseNodeHandler<INopNode>)
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
// --- Logic & Control Flow ---
TBlockExpressionNodeHandler = class(TBaseNodeHandler<IBlockExpressionNode>)
private
FExpressionsNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TIfExpressionNodeHandler = class(TBaseNodeHandler<IIfExpressionNode>)
private
FConditionNode: TAstViewNode;
FThenNode: TAstViewNode;
FElseNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TTernaryExpressionNodeHandler = class(TBaseNodeHandler<ITernaryExpressionNode>)
private
FConditionNode: TAstViewNode;
FThenNode: TAstViewNode;
FElseNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
// --- Functions & Calls ---
TLambdaExpressionNodeHandler = class(TBaseNodeHandler<ILambdaExpressionNode>)
private
FParamsNode: TAstViewNode;
FBodyNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TFunctionCallNodeHandler = class(TBaseNodeHandler<IFunctionCallNode>)
private
FCalleeNode: TAstViewNode;
FArgumentsNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TMacroExpansionNodeHandler = class(TBaseNodeHandler<IMacroExpansionNode>)
private
FExpandedBodyNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TRecurNodeHandler = class(TBaseNodeHandler<IRecurNode>)
private
FArgumentsNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
// --- Declarations & Assignments ---
TVariableDeclarationNodeHandler = class(TBaseNodeHandler<IVariableDeclarationNode>)
private
FTargetNode: TAstViewNode;
FInitializerNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TAssignmentNodeHandler = class(TBaseNodeHandler<IAssignmentNode>)
private
FTargetNode: TAstViewNode;
FValueNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TMacroDefinitionNodeHandler = class(TBaseNodeHandler<IMacroDefinitionNode>)
private
FParamsNode: TAstViewNode;
FBodyNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
// --- Metaprogramming ---
TQuasiquoteNodeHandler = class(TBaseNodeHandler<IQuasiquoteNode>)
private
FExpressionNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TUnquoteNodeHandler = class(TBaseNodeHandler<IUnquoteNode>)
private
FExpressionNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TUnquoteSplicingNodeHandler = class(TBaseNodeHandler<IUnquoteSplicingNode>)
private
FExpressionNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
// --- Data Access & Structures ---
TIndexerNodeHandler = class(TBaseNodeHandler<IIndexerNode>)
private
FBaseNode: TAstViewNode;
FIndexNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TMemberAccessNodeHandler = class(TBaseNodeHandler<IMemberAccessNode>)
private
FBaseNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TRecordLiteralNodeHandler = class(TBaseNodeHandler<IRecordLiteralNode>)
private
FFieldsNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
// --- Series Operations ---
TCreateSeriesNodeHandler = class(TBaseNodeHandler<ICreateSeriesNode>)
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TAddSeriesItemNodeHandler = class(TBaseNodeHandler<IAddSeriesItemNode>)
private
FValueNode: TAstViewNode;
FLookbackNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TSeriesLengthNodeHandler = class(TBaseNodeHandler<ISeriesLengthNode>)
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
implementation
{ TNodeListHandler<T> }
constructor TNodeListHandler<T>.Create(const ANode: INodeList<T>);
begin
inherited Create(ANode);
FChildNodes := TList<TAstViewNode>.Create;
end;
destructor TNodeListHandler<T>.Destroy;
begin
FChildNodes.Free;
inherited;
end;
function TNodeListHandler<T>.GetAlignment: TLayoutAlignment;
begin
Result := TLayoutAlignment.laCenter;
end;
procedure TNodeListHandler<T>.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
i: Integer;
childView: TAstViewNode;
openTok, closeTok, sep: string;
listId: IListIdentity;
begin
if (FNode.Identity <> nil) and (FNode.Identity.Kind = ikList) then
begin
listId := FNode.Identity.AsList;
openTok := listId.OpenToken;
closeTok := listId.CloseToken;
sep := listId.Separator;
end
else
begin
openTok := '';
closeTok := '';
sep := ' ';
end;
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := GetOrientation;
OwnerNode.Alignment := GetAlignment;
if openTok <> '' then
OwnerNode.AddLabel(OwnerNode, openTok);
for i := 0 to FNode.Count - 1 do
begin
childView := visu.CallAccept(FNode[i]);
FChildNodes.Add(childView);
if (i < FNode.Count - 1) and (sep <> '') and (sep <> ' ') then
OwnerNode.AddLabel(OwnerNode, sep);
end;
if closeTok <> '' then
OwnerNode.AddLabel(OwnerNode, closeTok);
if FNode.Count = 0 then
begin
if (openTok = '') and (closeTok = '') then
begin
var lbl := OwnerNode.AddLabel(OwnerNode, 'ø');
lbl.Opacity := 0.5;
end;
end;
finally
OwnerNode.EndUpdate;
end;
end;
{ TParameterListHandler }
function TParameterListHandler.GetOrientation: TLayoutOrientation;
begin
Result := loHorizontal;
end;
function TParameterListHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
var
arr: TArray<IIdentifierNode>;
i: Integer;
begin
SetLength(arr, FChildNodes.Count);
for i := 0 to FChildNodes.Count - 1 do
arr[i] := FChildNodes[i].CreateAst.AsIdentifier;
Result := TParameterList.Create(arr, FNode.Identity);
end;
{ TArgumentListHandler }
function TArgumentListHandler.GetOrientation: TLayoutOrientation;
begin
Result := loHorizontal;
end;
function TArgumentListHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
var
arr: TArray<IAstNode>;
i: Integer;
begin
SetLength(arr, FChildNodes.Count);
for i := 0 to FChildNodes.Count - 1 do
arr[i] := FChildNodes[i].CreateAst;
Result := TArgumentList.Create(arr, FNode.Identity);
end;
{ TExpressionListHandler }
function TExpressionListHandler.GetOrientation: TLayoutOrientation;
begin
Result := loVertical;
end;
function TExpressionListHandler.GetAlignment: TLayoutAlignment;
begin
Result := laFlush;
end;
function TExpressionListHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
var
arr: TArray<IAstNode>;
i: Integer;
begin
SetLength(arr, FChildNodes.Count);
for i := 0 to FChildNodes.Count - 1 do
arr[i] := FChildNodes[i].CreateAst;
Result := TExpressionList.Create(arr, FNode.Identity);
end;
{ TRecordFieldListHandler }
function TRecordFieldListHandler.GetOrientation: TLayoutOrientation;
begin
Result := loVertical;
end;
function TRecordFieldListHandler.GetAlignment: TLayoutAlignment;
begin
Result := laFlush;
end;
function TRecordFieldListHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
var
arr: TArray<IRecordFieldNode>;
i: Integer;
begin
SetLength(arr, FChildNodes.Count);
for i := 0 to FChildNodes.Count - 1 do
arr[i] := FChildNodes[i].CreateAst.AsRecordField;
Result := TRecordFieldList.Create(arr, FNode.Identity);
end;
{ TRecordFieldHandler }
procedure TRecordFieldHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
OwnerNode.Alignment := laCenter;
FKeyLabel := OwnerNode.AddLabel(OwnerNode, ':' + FNode.Key.Value.Name);
FKeyLabel.Font.Style := FKeyLabel.Font.Style + [TFontStyle.fsBold];
FKeyLabel.StyledSettings := FKeyLabel.StyledSettings - [TStyledSetting.FontColor];
FKeyLabel.FontColor := TAlphaColors.Mediumvioletred;
FValueNode := visu.CallAccept(FNode.Value);
finally
OwnerNode.EndUpdate;
end;
end;
function TRecordFieldHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
// Updated to use new Factory Overload to preserve Identity
Result := TAst.RecordField(FNode.Identity, FNode.Key, FValueNode.CreateAst);
end;
{ TConstantNodeHandler }
procedure TConstantNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
valueStr: string;
isConcise: Boolean;
titleLabel: TLabel;
valueLabel: TLabel;
begin
OwnerNode.BeginUpdate;
try
valueStr := FNode.Value.ToString;
isConcise := ((FNode.Value.Kind = TDataValueKind.vkScalar) or (Pos(sLineBreak, valueStr) = 0)) and (Length(valueStr) < 40);
if isConcise then
begin
OwnerNode.Frameless := True;
OwnerNode.AddLabel(OwnerNode, valueStr);
end
else
begin
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'Const');
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
valueLabel := OwnerNode.AddLabel(OwnerNode, valueStr);
valueLabel.AutoSize := False;
valueLabel.WordWrap := True;
end;
finally
OwnerNode.EndUpdate;
end;
end;
function TConstantNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Constant(FNode.Identity.AsConstant, FNode.StaticType);
end;
{ TIdentifierNodeHandler }
procedure TIdentifierNodeHandler.BuildUI(OwnerNode: TAstViewNode);
begin
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.AddLabel(OwnerNode, FNode.Name);
finally
OwnerNode.EndUpdate;
end;
end;
function TIdentifierNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Identifier(FNode.Identity.AsNamed, FNode.Address, FNode.StaticType);
end;
{ TKeywordNodeHandler }
procedure TKeywordNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
lbl: TLabel;
begin
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
lbl := OwnerNode.AddLabel(OwnerNode, ':' + FNode.Value.Name);
lbl.StyledSettings := lbl.StyledSettings - [TStyledSetting.FontColor];
lbl.FontColor := TAlphaColors.Mediumvioletred;
finally
OwnerNode.EndUpdate;
end;
end;
function TKeywordNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Keyword(FNode.Identity.AsKeyword);
end;
{ TNopNodeHandler }
procedure TNopNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
lbl: TLabel;
begin
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Alignment := TLayoutAlignment.laCenter;
OwnerNode.Orientation := TLayoutOrientation.loHorizontal;
lbl := OwnerNode.AddLabel(OwnerNode, '...');
lbl.Font.Style := lbl.Font.Style + [TFontStyle.fsBold];
lbl.Margins.Rect := TRectF.Create(8, 4, 8, 4);
finally
OwnerNode.EndUpdate;
end;
end;
function TNopNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := FNode;
end;
{ TBlockExpressionNodeHandler }
procedure TBlockExpressionNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
OwnerNode.Alignment := laFlush;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'do');
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
FExpressionsNode := visu.CallAccept(FNode.Expressions);
FExpressionsNode.Frameless := True;
finally
OwnerNode.EndUpdate;
end;
end;
function TBlockExpressionNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Block(FNode.Identity, FExpressionsNode.CreateAst.AsExpressionList, FNode.StaticType);
end;
{ TIfExpressionNodeHandler }
procedure TIfExpressionNodeHandler.BuildUI(OwnerNode: TAstViewNode);
begin
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
OwnerNode.Alignment := laFlush;
FConditionNode := OwnerNode.AddExpr(OwnerNode, 'if', FNode.Condition);
FThenNode := OwnerNode.AddExpr(OwnerNode, 'then', FNode.ThenBranch);
if Assigned(FNode.ElseBranch) then
FElseNode := OwnerNode.AddExpr(OwnerNode, 'else', FNode.ElseBranch);
finally
OwnerNode.EndUpdate;
end;
end;
function TIfExpressionNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
var
elseAst: IAstNode;
begin
if Assigned(FElseNode) then
elseAst := FElseNode.CreateAst
else
elseAst := nil;
Result := TAst.IfExpr(FNode.Identity, FConditionNode.CreateAst, FThenNode.CreateAst, elseAst, FNode.StaticType);
end;
{ TTernaryExpressionNodeHandler }
procedure TTernaryExpressionNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
FConditionNode := visu.CallAccept(FNode.Condition);
OwnerNode.AddLabel(OwnerNode, '?');
FThenNode := visu.CallAccept(FNode.ThenBranch);
OwnerNode.AddLabel(OwnerNode, ':');
FElseNode := visu.CallAccept(FNode.ElseBranch);
finally
OwnerNode.EndUpdate;
end;
end;
function TTernaryExpressionNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.TernaryExpr(FNode.Identity, FConditionNode.CreateAst, FThenNode.CreateAst, FElseNode.CreateAst, FNode.StaticType);
end;
{ TLambdaExpressionNodeHandler }
procedure TLambdaExpressionNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleContainer: TAutoFitControl;
lbl: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, 0);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
OwnerNode.Alignment := laFlush;
OwnerNode.BackgroundColor := $090000ff;
titleContainer := OwnerNode.AddContainer(OwnerNode, loHorizontal, laCenter);
lbl := OwnerNode.AddLabel(titleContainer, 'fn');
lbl.Font.Style := lbl.Font.Style + [TFontStyle.fsBold];
// Parameters: Delegate to List Handler
var paramVisu := visu.Clone(titleContainer, 0);
FParamsNode := paramVisu.CallAccept(FNode.Parameters);
// Body
FBodyNode := visu.CallAccept(FNode.Body);
FBodyNode.Frameless := False;
finally
OwnerNode.EndUpdate;
end;
end;
function TLambdaExpressionNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result :=
TAst.LambdaExpr(
FNode.Identity,
FParamsNode.CreateAst.AsParameterList,
FBodyNode.CreateAst,
FNode.Layout,
FNode.Descriptor,
FNode.Upvalues,
FNode.HasNestedLambdas,
FNode.IsPure,
FNode.StaticType
);
end;
{ TFunctionCallNodeHandler }
procedure TFunctionCallNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
callLabel: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
callLabel := OwnerNode.AddLabel(OwnerNode, 'call ');
callLabel.Font.Style := callLabel.Font.Style + [TFontStyle.fsBold];
FCalleeNode := visu.CallAccept(FNode.Callee);
FArgumentsNode := visu.CallAccept(FNode.Arguments);
finally
OwnerNode.EndUpdate;
end;
end;
function TFunctionCallNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result :=
TAst.FunctionCall(
FNode.Identity,
FCalleeNode.CreateAst,
FArgumentsNode.CreateAst.AsArgumentList,
FNode.StaticType,
FNode.IsTailCall,
FNode.StaticTarget,
FNode.IsTargetPure
);
end;
{ TMacroExpansionNodeHandler }
procedure TMacroExpansionNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'Macro Expansion');
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
FExpandedBodyNode := visu.CallAccept(FNode.ExpandedBody);
finally
OwnerNode.EndUpdate;
end;
end;
function TMacroExpansionNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.MacroExpansionNode(FNode.Identity, FNode.CallNode, FExpandedBodyNode.CreateAst.AsTypedNode);
end;
{ TRecurNodeHandler }
procedure TRecurNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'recur');
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
FArgumentsNode := visu.CallAccept(FNode.Arguments);
finally
OwnerNode.EndUpdate;
end;
end;
function TRecurNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Recur(FNode.Identity, FArgumentsNode.CreateAst.AsArgumentList, FNode.StaticType);
end;
{ TVariableDeclarationNodeHandler }
procedure TVariableDeclarationNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
varLabel: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
varLabel := OwnerNode.AddLabel(OwnerNode, 'var');
varLabel.Font.Style := varLabel.Font.Style + [TFontStyle.fsBold];
FTargetNode := visu.CallAccept(FNode.Target);
if Assigned(FNode.Initializer) then
begin
OwnerNode.AddLabel(OwnerNode, ':=');
FInitializerNode := visu.CallAccept(FNode.Initializer);
end
else
FInitializerNode := nil;
finally
OwnerNode.EndUpdate;
end;
end;
function TVariableDeclarationNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
var
initAst: IAstNode;
begin
if Assigned(FInitializerNode) then
initAst := FInitializerNode.CreateAst
else
initAst := nil;
Result := TAst.VarDecl(FNode.Identity, FTargetNode.CreateAst, initAst, FNode.StaticType, FNode.IsBoxed);
end;
{ TAssignmentNodeHandler }
procedure TAssignmentNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
FTargetNode := visu.CallAccept(FNode.Target);
OwnerNode.AddLabel(OwnerNode, ':=');
FValueNode := visu.CallAccept(FNode.Value);
finally
OwnerNode.EndUpdate;
end;
end;
function TAssignmentNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Assign(FNode.Identity, FTargetNode.CreateAst, FValueNode.CreateAst, FNode.StaticType);
end;
{ TMacroDefinitionNodeHandler }
procedure TMacroDefinitionNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TLabel;
titleContainer: TAutoFitControl;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleContainer := OwnerNode.AddContainer(OwnerNode, loHorizontal, laCenter);
titleLabel := OwnerNode.AddLabel(titleContainer, 'Macro Def: ' + FNode.Name.Name);
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
// Parameters List
var paramVisu := visu.Clone(titleContainer, visu.ExprDepth);
FParamsNode := paramVisu.CallAccept(FNode.Parameters);
FBodyNode := visu.CallAccept(FNode.Body);
finally
OwnerNode.EndUpdate;
end;
end;
function TMacroDefinitionNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.MacroDef(FNode.Identity, FNode.Name, FParamsNode.CreateAst.AsParameterList, FBodyNode.CreateAst);
end;
{ TQuasiquoteNodeHandler }
procedure TQuasiquoteNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'Quasiquote');
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
FExpressionNode := visu.CallAccept(FNode.Expression);
finally
OwnerNode.EndUpdate;
end;
end;
function TQuasiquoteNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Quasiquote(FNode.Identity, FExpressionNode.CreateAst);
end;
{ TUnquoteNodeHandler }
procedure TUnquoteNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
leftBracket, rightBracket: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
leftBracket := OwnerNode.AddLabel(OwnerNode, '<');
leftBracket.Padding.Right := 0;
leftBracket.Margins.Right := 0;
FExpressionNode := visu.CallAccept(FNode.Expression);
rightBracket := OwnerNode.AddLabel(OwnerNode, '>');
rightBracket.Padding.Left := 0;
rightBracket.Margins.Left := 0;
finally
OwnerNode.EndUpdate;
end;
end;
function TUnquoteNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Unquote(FNode.Identity, FExpressionNode.CreateAst);
end;
{ TUnquoteSplicingNodeHandler }
procedure TUnquoteSplicingNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'Unquote-Splicing');
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
FExpressionNode := visu.CallAccept(FNode.Expression);
finally
OwnerNode.EndUpdate;
end;
end;
function TUnquoteSplicingNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.UnquoteSplicing(FNode.Identity, FExpressionNode.CreateAst.AsQuasiquote);
end;
{ TIndexerNodeHandler }
procedure TIndexerNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
FBaseNode := visu.CallAccept(FNode.Base);
OwnerNode.AddLabel(OwnerNode, '[');
FIndexNode := visu.CallAccept(FNode.Index);
OwnerNode.AddLabel(OwnerNode, ']');
finally
OwnerNode.EndUpdate;
end;
end;
function TIndexerNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Indexer(FNode.Identity, FBaseNode.CreateAst, FIndexNode.CreateAst, FNode.StaticType);
end;
{ TMemberAccessNodeHandler }
procedure TMemberAccessNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
FBaseNode := visu.CallAccept(FNode.Base);
OwnerNode.AddLabel(OwnerNode, '.');
OwnerNode.AddLabel(OwnerNode, FNode.Member.Value.Name);
finally
OwnerNode.EndUpdate;
end;
end;
function TMemberAccessNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
// Reuse Identifier, Reuse Member Keyword (via TAst.Keyword with Identity)
Result := TAst.MemberAccess(FNode.Identity, FBaseNode.CreateAst, TAst.Keyword(FNode.Member.Identity.AsKeyword), FNode.StaticType);
end;
{ TRecordLiteralNodeHandler }
procedure TRecordLiteralNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
OwnerNode.Alignment := laFlush;
// Delegate to RecordFieldList
FFieldsNode := visu.CallAccept(FNode.Fields);
finally
OwnerNode.EndUpdate;
end;
end;
function TRecordLiteralNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result :=
TAst.RecordLiteral(
FNode.Identity,
FFieldsNode.CreateAst.AsRecordFieldList,
FNode.ScalarDefinition,
FNode.GenericDefinition,
FNode.StaticType
);
end;
{ TCreateSeriesNodeHandler }
procedure TCreateSeriesNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
titleLabel: TLabel;
begin
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'Create Series: ' + FNode.Definition);
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
finally
OwnerNode.EndUpdate;
end;
end;
function TCreateSeriesNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.CreateSeries(FNode.Identity.AsDefinition, FNode.StaticType);
end;
{ TAddSeriesItemNodeHandler }
procedure TAddSeriesItemNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TLabel;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'Add Item to: ' + FNode.Series.Name);
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
FValueNode := visu.CallAccept(FNode.Value);
if Assigned(FNode.Lookback) then
FLookbackNode := visu.CallAccept(FNode.Lookback)
else
FLookbackNode := nil;
finally
OwnerNode.EndUpdate;
end;
end;
function TAddSeriesItemNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
var
lookbackAst: IAstNode;
begin
if Assigned(FLookbackNode) then
lookbackAst := FLookbackNode.CreateAst
else
lookbackAst := nil;
Result :=
TAst.AddSeriesItem(
FNode.Identity,
FNode.Series, // Reuse original Series Identifier Node
FValueNode.CreateAst,
lookbackAst,
FNode.StaticType
);
end;
{ TSeriesLengthNodeHandler }
procedure TSeriesLengthNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
titleLabel: TLabel;
begin
OwnerNode.BeginUpdate;
try
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'Length of: ' + FNode.Series.Name);
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
finally
OwnerNode.EndUpdate;
end;
end;
function TSeriesLengthNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.SeriesLength(FNode.Identity, FNode.Series, FNode.StaticType);
end;
end.