New visualizer
This commit is contained in:
@@ -306,7 +306,27 @@ begin
|
||||
smaScope := smaDescriptor.CreateScope(Scope);
|
||||
smaVisitor := CreateEvaluator(smaScope);
|
||||
|
||||
Scope.Define('CreateSMA', smaVisitor.Execute(boundSmaAst));
|
||||
Scope.Define(
|
||||
'print',
|
||||
TDataValue(
|
||||
function(const Args: TArray<TDataValue>): TDataValue
|
||||
begin
|
||||
var str := TStringBuilder.Create;
|
||||
try
|
||||
for var i := 0 to High(Args) do
|
||||
begin
|
||||
if Args[i].Kind = vkText then
|
||||
str.Append(Args[i].AsText)
|
||||
else
|
||||
str.Append(Args[i].ToString);
|
||||
end;
|
||||
Memo1.Lines.Add(str.ToString);
|
||||
finally
|
||||
str.Free;
|
||||
end;
|
||||
end
|
||||
)
|
||||
);
|
||||
end
|
||||
);
|
||||
|
||||
|
||||
@@ -149,7 +149,6 @@ type
|
||||
// If true, the node is drawn without a border and with a transparent background.
|
||||
FFrameless: Boolean;
|
||||
FVisualizer: IAstVisualizer;
|
||||
function AddLabel(const Txt: String): TLabel;
|
||||
procedure SetBackgroundColor(const Value: TAlphaColor);
|
||||
procedure SetBorderColor(const Value: TAlphaColor);
|
||||
procedure SetBorderWidth(const Value: Single);
|
||||
@@ -162,6 +161,11 @@ type
|
||||
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override;
|
||||
property Visualizer: IAstVisualizer read FVisualizer;
|
||||
procedure SetupNode; virtual;
|
||||
|
||||
function AddLabel(Parent: TControl; const Txt: String): TLabel;
|
||||
function AddContainer(Parent: TControl; Orientation: TLayoutOrientation; Alignment: TLayoutAlignment): TAutoFitControl;
|
||||
function AddExpr(Parent: TControl; const Title: String; const Node: IAstNode): TAuraNode;
|
||||
|
||||
public
|
||||
constructor Create(const AVisualizer: IAstVisualizer); reintroduce;
|
||||
destructor Destroy; override;
|
||||
@@ -450,7 +454,6 @@ type
|
||||
private
|
||||
FNode: IMemberAccessNode;
|
||||
FBaseNode: TAuraNode;
|
||||
// FMemberNode is handled by a label, store Base only
|
||||
protected
|
||||
procedure SetupNode; override;
|
||||
public
|
||||
@@ -930,10 +933,29 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TAuraNode.AddLabel(const Txt: String): TLabel;
|
||||
function TAuraNode.AddContainer(Parent: TControl; Orientation: TLayoutOrientation; Alignment: TLayoutAlignment): TAutoFitControl;
|
||||
begin
|
||||
Result := TAutoFitControl.Create(Self);
|
||||
Result.Parent := Parent;
|
||||
Result.Orientation := Orientation;
|
||||
Result.Alignment := Alignment;
|
||||
Result.HitTest := False; // Pass clicks to parent
|
||||
end;
|
||||
|
||||
function TAuraNode.AddExpr(Parent: TControl; const Title: String; const Node: IAstNode): TAuraNode;
|
||||
begin
|
||||
var cont := AddContainer(Parent, loHorizontal, laCenter);
|
||||
|
||||
var lbl := AddLabel(cont, Title);
|
||||
lbl.Font.Style := lbl.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
Result := FVisualizer.Clone(cont, FVisualizer.ExprDepth + 1).CallAccept(Node);
|
||||
end;
|
||||
|
||||
function TAuraNode.AddLabel(Parent: TControl; const Txt: String): TLabel;
|
||||
begin
|
||||
Result := TLabel.Create(Self); // Owner is the node itself
|
||||
Result.Parent := Self;
|
||||
Result.Parent := Parent;
|
||||
|
||||
Result.Position.Point := TPoint.Create(cNodePadding, cNodePadding);
|
||||
Result.Margins.Left := cNodePadding;
|
||||
@@ -1134,7 +1156,7 @@ begin
|
||||
begin
|
||||
// Display value directly in a centered label, frameless node
|
||||
Frameless := true;
|
||||
AddLabel(valueStr);
|
||||
AddLabel(Self, valueStr);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@@ -1142,11 +1164,11 @@ begin
|
||||
Frameless := False;
|
||||
Orientation := loVertical;
|
||||
|
||||
var titleLabel := AddLabel('Const');
|
||||
var titleLabel := AddLabel(Self, 'Const');
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
// Value Label
|
||||
var valueLabel := AddLabel(valueStr);
|
||||
var valueLabel := AddLabel(Self, valueStr);
|
||||
valueLabel.AutoSize := False; // ***Important: Disable AutoSize when Align=Client***
|
||||
valueLabel.WordWrap := True; // Allow wrapping for long text
|
||||
end;
|
||||
@@ -1173,7 +1195,7 @@ begin
|
||||
BeginUpdate;
|
||||
try
|
||||
Frameless := true; // Identifiers are frameless
|
||||
AddLabel(FNode.Name); // Add label with the identifier name
|
||||
AddLabel(Self, FNode.Name); // Add label with the identifier name
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
@@ -1214,7 +1236,7 @@ begin
|
||||
visu.CallAccept(FNode.Left);
|
||||
|
||||
// 2. Operator Label
|
||||
AddLabel(FNode.Operator.ToString);
|
||||
AddLabel(Self, FNode.Operator.ToString);
|
||||
|
||||
// 3. RightNode Expression Node (Visited Recursively)
|
||||
visu.CallAccept(FNode.Right);
|
||||
@@ -1282,15 +1304,10 @@ begin
|
||||
if i = High(FNode.Expressions) then
|
||||
begin
|
||||
// Last expression: create a horizontal container for "return [expr]"
|
||||
returnContainer := TAutoFitControl.Create(Self);
|
||||
returnContainer.Parent := Self; // Parent is the main block node
|
||||
returnContainer.Orientation := loHorizontal;
|
||||
returnContainer.Alignment := laCenter; // Center "return" label vertically next to the expression
|
||||
returnContainer.HitTest := False; // Pass clicks through
|
||||
returnContainer := AddContainer(Self, loHorizontal, laCenter);
|
||||
|
||||
// Add "return" label to the container
|
||||
titleLabel := AddLabel('return'); // Use AddLabel from TAuraNode (Self)
|
||||
titleLabel.Parent := returnContainer; // Set parent to the new container
|
||||
titleLabel := AddLabel(returnContainer, 'return'); // Use AddLabel from TAuraNode (Self)
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
// Create a new visualizer targeting this container
|
||||
@@ -1339,7 +1356,7 @@ begin
|
||||
Orientation := loVertical;
|
||||
|
||||
// Title
|
||||
titleLabel := AddLabel('Unary Op: ' + FNode.Operator.ToString);
|
||||
titleLabel := AddLabel(Self, 'Unary Op: ' + FNode.Operator.ToString);
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
// Child
|
||||
@@ -1373,24 +1390,18 @@ end;
|
||||
procedure TAuraIfExpressionNode.SetupNode;
|
||||
var
|
||||
visu: IAstVisualizer;
|
||||
titleLabel: TLabel;
|
||||
lbl: TLabel;
|
||||
begin
|
||||
visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
|
||||
|
||||
BeginUpdate;
|
||||
try
|
||||
Frameless := False;
|
||||
Orientation := loVertical;
|
||||
Alignment := laFlush;
|
||||
|
||||
titleLabel := AddLabel('if');
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
// Add children
|
||||
FConditionNode := visu.CallAccept(FNode.Condition);
|
||||
FThenNode := visu.CallAccept(FNode.ThenBranch);
|
||||
FConditionNode := AddExpr(Self, 'if', FNode.Condition);
|
||||
FThenNode := AddExpr(Self, 'then', FNode.ThenBranch);
|
||||
if Assigned(FNode.ElseBranch) then
|
||||
FElseNode := visu.CallAccept(FNode.ElseBranch);
|
||||
|
||||
FElseNode := AddExpr(Self, 'else', FNode.ElseBranch);
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
@@ -1421,9 +1432,9 @@ begin
|
||||
Orientation := loHorizontal;
|
||||
|
||||
FConditionNode := visu.CallAccept(FNode.Condition);
|
||||
AddLabel('?');
|
||||
AddLabel(Self, '?');
|
||||
FThenNode := visu.CallAccept(FNode.ThenBranch);
|
||||
AddLabel(':');
|
||||
AddLabel(Self, ':');
|
||||
FElseNode := visu.CallAccept(FNode.ElseBranch);
|
||||
finally
|
||||
EndUpdate;
|
||||
@@ -1475,36 +1486,33 @@ begin
|
||||
BackgroundColor := $090000ff;
|
||||
|
||||
// Create a horizontal container for the title/params
|
||||
titleContainer := TAutoFitControl.Create(Self);
|
||||
titleContainer.Parent := Self;
|
||||
titleContainer.Orientation := loHorizontal;
|
||||
titleContainer.HitTest := False; // Pass clicks to parent
|
||||
titleContainer := AddContainer(Self, loHorizontal, laCenter);
|
||||
|
||||
// 1. Lambda Symbol Label (Title)
|
||||
paramLabel := AddLabel(WideChar($03BB)); // Lambda
|
||||
paramLabel := AddLabel(Self, WideChar($03BB)); // Lambda
|
||||
paramLabel.Parent := titleContainer; // Add to title container
|
||||
paramLabel.Font.Style := paramLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
// 2. Add Parameters
|
||||
paramLabel := AddLabel('(');
|
||||
paramLabel := AddLabel(Self, '(');
|
||||
paramLabel.Parent := titleContainer;
|
||||
FParamLabels.Add(paramLabel);
|
||||
|
||||
for i := 0 to High(FNode.Parameters) do
|
||||
begin
|
||||
paramLabel := AddLabel(FNode.Parameters[i].Name);
|
||||
paramLabel := AddLabel(Self, FNode.Parameters[i].Name);
|
||||
paramLabel.Parent := titleContainer;
|
||||
FParamLabels.Add(paramLabel);
|
||||
|
||||
if i < High(FNode.Parameters) then
|
||||
begin
|
||||
paramLabel := AddLabel(',');
|
||||
paramLabel := AddLabel(Self, ',');
|
||||
paramLabel.Parent := titleContainer;
|
||||
FParamLabels.Add(paramLabel);
|
||||
end;
|
||||
end;
|
||||
|
||||
paramLabel := AddLabel(')');
|
||||
paramLabel := AddLabel(Self, ')');
|
||||
paramLabel.Parent := titleContainer;
|
||||
FParamLabels.Add(paramLabel);
|
||||
|
||||
@@ -1557,7 +1565,7 @@ begin
|
||||
Frameless := True; // Horizontal layout
|
||||
Orientation := loHorizontal;
|
||||
|
||||
var callLabel := AddLabel('call ');
|
||||
var callLabel := AddLabel(Self, 'call ');
|
||||
callLabel.Font.Style := callLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
// Callee
|
||||
@@ -1566,7 +1574,7 @@ begin
|
||||
// Arguments
|
||||
if Length(FNode.Arguments) > 0 then
|
||||
begin
|
||||
AddLabel('(');
|
||||
AddLabel(Self, '(');
|
||||
|
||||
for i := 0 to High(FNode.Arguments) do
|
||||
begin
|
||||
@@ -1574,10 +1582,10 @@ begin
|
||||
FArgumentNodes.Add(argNode);
|
||||
|
||||
if i < High(FNode.Arguments) then
|
||||
AddLabel(',');
|
||||
AddLabel(Self, ',');
|
||||
end;
|
||||
|
||||
AddLabel(')');
|
||||
AddLabel(Self, ')');
|
||||
end;
|
||||
finally
|
||||
EndUpdate;
|
||||
@@ -1611,7 +1619,7 @@ begin
|
||||
Frameless := False;
|
||||
Orientation := loVertical;
|
||||
|
||||
titleLabel := AddLabel('Macro Expansion');
|
||||
titleLabel := AddLabel(Self, 'Macro Expansion');
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
FExpandedBodyNode := visu.CallAccept(FNode.ExpandedBody);
|
||||
@@ -1662,11 +1670,11 @@ begin
|
||||
Orientation := loHorizontal;
|
||||
|
||||
// 1. 'recur' keyword
|
||||
titleLabel := AddLabel(WideChar($03BB));
|
||||
titleLabel := AddLabel(Self, WideChar($03BB));
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
// 2. Arguments
|
||||
AddLabel('(');
|
||||
AddLabel(Self, '(');
|
||||
|
||||
for i := 0 to High(FNode.Arguments) do
|
||||
begin
|
||||
@@ -1674,10 +1682,10 @@ begin
|
||||
FArgumentNodes.Add(argNode);
|
||||
|
||||
if i < High(FNode.Arguments) then
|
||||
AddLabel(',');
|
||||
AddLabel(Self, ',');
|
||||
end;
|
||||
|
||||
AddLabel(')');
|
||||
AddLabel(Self, ')');
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
@@ -1717,15 +1725,15 @@ begin
|
||||
Frameless := True; // Horizontal layout
|
||||
Orientation := loHorizontal;
|
||||
|
||||
varLabel := AddLabel('var');
|
||||
varLabel := AddLabel(Self, 'var');
|
||||
varLabel.Font.Style := varLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
// Add identifier name as a label
|
||||
AddLabel(FNode.Identifier.Name);
|
||||
AddLabel(Self, FNode.Identifier.Name);
|
||||
|
||||
if Assigned(FNode.Initializer) then
|
||||
begin
|
||||
AddLabel(':=');
|
||||
AddLabel(Self, ':=');
|
||||
FInitializerNode := visu.CallAccept(FNode.Initializer);
|
||||
end;
|
||||
finally
|
||||
@@ -1759,9 +1767,9 @@ begin
|
||||
Orientation := loHorizontal;
|
||||
|
||||
// Add identifier name as a label
|
||||
AddLabel(FNode.Identifier.Name);
|
||||
AddLabel(Self, FNode.Identifier.Name);
|
||||
|
||||
AddLabel(':=');
|
||||
AddLabel(Self, ':=');
|
||||
|
||||
FValueNode := visu.CallAccept(FNode.Value);
|
||||
finally
|
||||
@@ -1811,7 +1819,7 @@ begin
|
||||
paramStr := paramStr + FNode.Parameters[i].Name;
|
||||
end;
|
||||
|
||||
titleLabel := AddLabel('Macro Def: ' + FNode.Name.Name + ' (' + paramStr + ')');
|
||||
titleLabel := AddLabel(Self, 'Macro Def: ' + FNode.Name.Name + ' (' + paramStr + ')');
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
FBodyNode := visu.CallAccept(FNode.Body);
|
||||
@@ -1843,7 +1851,7 @@ begin
|
||||
try
|
||||
Frameless := False;
|
||||
Orientation := loVertical;
|
||||
titleLabel := AddLabel('Quasiquote');
|
||||
titleLabel := AddLabel(Self, 'Quasiquote');
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
FExpressionNode := visu.CallAccept(FNode.Expression);
|
||||
finally
|
||||
@@ -1874,13 +1882,13 @@ begin
|
||||
Frameless := True; // Horizontal layout
|
||||
Orientation := loHorizontal;
|
||||
|
||||
var leftBracket := AddLabel('<');
|
||||
var leftBracket := AddLabel(Self, '<');
|
||||
leftBracket.Padding.Right := 0;
|
||||
leftBracket.Margins.Right := 0;
|
||||
|
||||
visu.CallAccept(FNode.Expression);
|
||||
|
||||
var rightBracket := AddLabel('>');
|
||||
var rightBracket := AddLabel(Self, '>');
|
||||
rightBracket.Padding.Left := 0;
|
||||
rightBracket.Margins.Left := 0;
|
||||
finally
|
||||
@@ -1911,7 +1919,7 @@ begin
|
||||
try
|
||||
Frameless := False;
|
||||
Orientation := loVertical;
|
||||
titleLabel := AddLabel('Unquote-Splicing');
|
||||
titleLabel := AddLabel(Self, 'Unquote-Splicing');
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
FExpressionNode := visu.CallAccept(FNode.Expression);
|
||||
finally
|
||||
@@ -1943,9 +1951,9 @@ begin
|
||||
Orientation := loHorizontal;
|
||||
|
||||
FBaseNode := visu.CallAccept(FNode.Base);
|
||||
AddLabel('[');
|
||||
AddLabel(Self, '[');
|
||||
FIndexNode := visu.CallAccept(FNode.Index);
|
||||
AddLabel(']');
|
||||
AddLabel(Self, ']');
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
@@ -1976,10 +1984,10 @@ begin
|
||||
Orientation := loHorizontal;
|
||||
|
||||
FBaseNode := visu.CallAccept(FNode.Base);
|
||||
AddLabel('.');
|
||||
AddLabel(Self, '.');
|
||||
|
||||
// Add member name as a label
|
||||
AddLabel(FNode.Member.Name);
|
||||
AddLabel(Self, FNode.Member.Name);
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
@@ -2006,7 +2014,7 @@ begin
|
||||
try
|
||||
Frameless := False; // Leaf node, but framed
|
||||
Orientation := loVertical;
|
||||
titleLabel := AddLabel('Create Series: ' + FNode.Definition);
|
||||
titleLabel := AddLabel(Self, 'Create Series: ' + FNode.Definition);
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
finally
|
||||
EndUpdate;
|
||||
@@ -2045,7 +2053,7 @@ begin
|
||||
Frameless := False;
|
||||
Orientation := loVertical;
|
||||
|
||||
titleLabel := AddLabel('Add Item to: ' + FNode.Series.Name);
|
||||
titleLabel := AddLabel(Self, 'Add Item to: ' + FNode.Series.Name);
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
|
||||
FValueNode := visu.CallAccept(FNode.Value);
|
||||
@@ -2077,7 +2085,7 @@ begin
|
||||
try
|
||||
Frameless := False; // Leaf node, but framed
|
||||
Orientation := loVertical;
|
||||
titleLabel := AddLabel('Length of: ' + FNode.Series.Name);
|
||||
titleLabel := AddLabel(Self, 'Length of: ' + FNode.Series.Name);
|
||||
titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
|
||||
finally
|
||||
EndUpdate;
|
||||
|
||||
Reference in New Issue
Block a user