Files
MycLib/Src/AST/Myc.Fmx.AstEditor.Handlers.Data.pas
T
2026-01-06 13:38:06 +01:00

441 lines
14 KiB
ObjectPascal

unit Myc.Fmx.AstEditor.Handlers.Data;
interface
uses
System.SysUtils,
System.UITypes,
Myc.Data.Keyword,
Myc.Ast,
Myc.Ast.Nodes,
Myc.Fmx.AstEditor.Render,
Myc.Fmx.AstEditor.Node;
type
// --- 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;
// --- 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;
TRecordFieldHandler = class(TBaseNodeHandler<IRecordFieldNode>)
private
FKeyLabel: TTextNode;
FValueNode: 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>)
private
FDefNode: TAstViewNode;
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
{ TVariableDeclarationNodeHandler }
procedure TVariableDeclarationNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
varLabel: TTextNode;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
varLabel := OwnerNode.AddLabel(OwnerNode, 'def'); // Changed 'var' to 'def' to match syntax
varLabel.FontSettings.Font.Style := [TFontStyle.fsBold];
FTargetNode := visu.CallAccept(FNode.Target);
if Assigned(FNode.Initializer) then
begin
// Space before value
OwnerNode.AddLabel(OwnerNode, ' ');
FInitializerNode := visu.CallAccept(FNode.Initializer);
end
else
FInitializerNode := nil;
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.Frameless := True;
OwnerNode.Orientation := loHorizontal;
OwnerNode.AddLabel(OwnerNode, 'assign ');
FTargetNode := visu.CallAccept(FNode.Target);
OwnerNode.AddLabel(OwnerNode, ' ');
FValueNode := visu.CallAccept(FNode.Value);
end;
function TAssignmentNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.Assign(FNode.Identity, FTargetNode.CreateAst, FValueNode.CreateAst, FNode.StaticType);
end;
{ TQuasiquoteNodeHandler }
procedure TQuasiquoteNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TTextNode;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
titleLabel := OwnerNode.AddLabel(OwnerNode, '`');
titleLabel.FontSettings.Font.Style := [TFontStyle.fsBold];
FExpressionNode := visu.CallAccept(FNode.Expression);
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: TTextNode;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
leftBracket := OwnerNode.AddLabel(OwnerNode, '~');
leftBracket.FontSettings.Font.Style := [TFontStyle.fsBold];
// Remove right margin to stick to expression
leftBracket.Margins := TMarginRect.Create(cNodePadding, cTitleTopPadding, 0, cTitleBottomPadding);
FExpressionNode := visu.CallAccept(FNode.Expression);
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: TTextNode;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
titleLabel := OwnerNode.AddLabel(OwnerNode, '~@');
titleLabel.FontSettings.Font.Style := [TFontStyle.fsBold];
// Remove right margin
titleLabel.Margins := TMarginRect.Create(cNodePadding, cTitleTopPadding, 0, cTitleBottomPadding);
FExpressionNode := visu.CallAccept(FNode.Expression);
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.Frameless := True;
OwnerNode.Orientation := loHorizontal;
OwnerNode.AddLabel(OwnerNode, 'get ');
FBaseNode := visu.CallAccept(FNode.Base);
OwnerNode.AddLabel(OwnerNode, ' ');
FIndexNode := visu.CallAccept(FNode.Index);
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.Frameless := True;
OwnerNode.Orientation := loHorizontal;
OwnerNode.AddLabel(OwnerNode, '.');
OwnerNode.AddLabel(OwnerNode, FNode.Member.Value.Name);
OwnerNode.AddLabel(OwnerNode, ' ');
FBaseNode := visu.CallAccept(FNode.Base);
end;
function TMemberAccessNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.MemberAccess(FNode.Identity, FBaseNode.CreateAst, TAst.Keyword(FNode.Member.Identity.AsKeyword), FNode.StaticType);
end;
{ TRecordFieldHandler }
procedure TRecordFieldHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth);
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
OwnerNode.Alignment := laCenter;
FKeyLabel := OwnerNode.AddLabel(OwnerNode, ':' + FNode.Key.Value.Name);
FKeyLabel.FontSettings.Font.Style := [TFontStyle.fsBold];
FKeyLabel.Color := TAlphaColors.Mediumvioletred;
OwnerNode.AddLabel(OwnerNode, ' ');
FValueNode := visu.CallAccept(FNode.Value);
end;
function TRecordFieldHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.RecordField(FNode.Identity, FNode.Key, FValueNode.CreateAst);
end;
{ TRecordLiteralNodeHandler }
procedure TRecordLiteralNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
braceL: TTextNode;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
OwnerNode.Alignment := laFlush; // Align left
// Visual hint: Curly braces for record
braceL := OwnerNode.AddLabel(OwnerNode, '{');
braceL.FontSettings.Font.Style := [TFontStyle.fsBold];
// Delegate to Fields Tuple (previously RecordFieldList)
FFieldsNode := visu.CallAccept(FNode.Fields);
OwnerNode.AddLabel(OwnerNode, '}');
end;
function TRecordLiteralNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result :=
TAst.RecordLiteral(
FNode.Identity,
FFieldsNode.CreateAst.AsTuple,
FNode.ScalarDefinition,
FNode.GenericDefinition,
FNode.StaticType
);
end;
{ TCreateSeriesNodeHandler }
procedure TCreateSeriesNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TTextNode;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'new-series');
titleLabel.FontSettings.Font.Style := [TFontStyle.fsBold];
// Now visualize the definition node (likely a Tuple or Keyword)
FDefNode := visu.CallAccept(FNode.DefinitionNode);
end;
function TCreateSeriesNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.CreateSeries(FNode.Identity, FDefNode.CreateAst, FNode.RecordDefinition, FNode.StaticType);
end;
{ TAddSeriesItemNodeHandler }
procedure TAddSeriesItemNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
titleLabel: TTextNode;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'add-item: ' + FNode.Series.Name);
titleLabel.FontSettings.Font.Style := [TFontStyle.fsBold];
FValueNode := visu.CallAccept(FNode.Value);
if Assigned(FNode.Lookback) then
begin
OwnerNode.AddLabel(OwnerNode, 'Lookback:');
FLookbackNode := visu.CallAccept(FNode.Lookback);
end
else
FLookbackNode := nil;
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: TTextNode;
begin
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
titleLabel := OwnerNode.AddLabel(OwnerNode, 'count ' + FNode.Series.Name);
titleLabel.FontSettings.Font.Style := [TFontStyle.fsBold];
end;
function TSeriesLengthNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result := TAst.SeriesLength(FNode.Identity, FNode.Series, FNode.StaticType);
end;
end.