418 lines
13 KiB
ObjectPascal
418 lines
13 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;
|
|
|
|
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;
|
|
|
|
end.
|