Ast Playground 1. visualization

This commit is contained in:
Michael Schimmel
2025-08-30 01:38:40 +02:00
parent d2c00c6033
commit c7a865d12e
11 changed files with 1298 additions and 330 deletions
+53 -16
View File
@@ -8,6 +8,7 @@ uses
System.UITypes,
System.Classes,
System.Variants,
System.Generics.Collections,
FMX.Types,
FMX.Controls,
FMX.Forms,
@@ -18,11 +19,15 @@ uses
FMX.ScrollBox,
FMX.Memo,
FMX.Controls.Presentation,
DraggablePanel,
Myc.Ast.Visualizer,
Myc.Data.POD,
Myc.Ast.Nodes,
Myc.Ast,
Myc.Ast.Evaluator,
Myc.Ast.Printer; // Added for TExecutionScope
Myc.Ast.Printer,
FMX.Layouts,
FMX.Objects; // Added for TExecutionScope
type
TForm1 = class(TForm)
@@ -38,6 +43,9 @@ type
CrerateTriggerExampleButton: TButton;
DoTriggerButton: TButton;
DoTrigger2Button: TButton;
Panel2: TPanel;
ClearButton: TButton;
procedure ClearButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure CrerateTriggerExampleButtonClick(Sender: TObject);
procedure DebugButtonClick(Sender: TObject);
@@ -52,6 +60,8 @@ type
// Stores the last AST generated by Test1 or Test2 button clicks.
FLastAst: IAstNode;
FGScope: IExecutionScope;
FWorkspace: TAuraWorkspace;
procedure WorkspaceMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
public
{ Public declarations }
end;
@@ -67,8 +77,20 @@ uses
{$R *.fmx}
procedure TForm1.ClearButtonClick(Sender: TObject);
begin
FWorkspace.DeleteChildren;
FWorkspace.Repaint;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FWorkspace := TAuraWorkspace.Create(Panel2);
FWorkspace.Parent := Panel2;
FWorkspace.Align := TAlignLayout.Client;
FWorkspace.OnMouseDown := WorkspaceMouseDown;
FGScope := T_ExecutionScope.Create(nil);
end;
@@ -371,7 +393,6 @@ end;
procedure TForm1.CrerateTriggerExampleButtonClick(Sender: TObject);
var
lambdaAst: ILambdaExpressionNode;
visitor: IAstVisitor;
closureValue: TAstValue;
begin
@@ -384,26 +405,33 @@ begin
Memo1.Lines.Clear;
Memo1.Lines.Add('--- Creating Trigger Blueprint ---');
// 1. Initialize the variable 'X' to 0 directly in the scope.
FGScope.SetValue('X', TAstValue.FromScalar(TScalar.FromInt64(0)));
// 2. Create a lambda that takes the summand as an argument.
// AST for: (summand) => { X = X + summand; }
// Using the new Assignment node to modify 'X' in its parent scope.
lambdaAst :=
TAst.LambdaExpr(
[TAst.Identifier('summand')],
TAst.Assign(TAst.Identifier('X'), TAst.BinaryExpr(TAst.Identifier('X'), boAdd, TAst.Identifier('summand')))
var blk :=
TAst.Block(
[
TAst.VarDecl(TAst.Identifier('X'), TAst.Constant(TScalar.FromInt64(0))),
TAst.VarDecl(
TAst.Identifier('tickHandler'),
TAst.LambdaExpr(
[TAst.Identifier('summand')],
TAst.Assign(TAst.Identifier('X'), TAst.BinaryExpr(TAst.Identifier('X'), boAdd, TAst.Identifier('summand')))
)
)
]
);
// 3. Evaluate the lambda to create a closure and store it in the scope.
// lambdaAst :=
// TAst.LambdaExpr(
// [TAst.Identifier('summand')],
// TAst.Assign(TAst.Identifier('X'), TAst.BinaryExpr(TAst.Identifier('X'), boAdd, TAst.Identifier('summand')))
// );
// Evaluate the lambda to create a closure and store it in the scope.
// The closure captures the scope where 'X' is defined.
visitor := TEvaluatorVisitor.Create(FGScope);
closureValue := lambdaAst.Accept(visitor);
FGScope.SetValue('tickHandler', closureValue);
blk.Accept(visitor);
// FLastAst is not used for this parameterized example.
FLastAst := lambdaAst;
FLastAst := blk;
Memo1.Lines.Add('Variable "X" initialized to 0 in persistent scope.');
Memo1.Lines.Add('Blueprint function "tickHandler(summand)" created.');
@@ -470,4 +498,13 @@ begin
end;
end;
procedure TForm1.WorkspaceMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
if Button <> TMouseButton.mbMiddle then
exit;
if FLastAst <> nil then
FWorkspace.BuildTree(FLastAst, TPointF.Create(X, Y));
end;
end.