Ast environment refactoring

This commit is contained in:
Michael Schimmel
2025-11-08 15:57:12 +01:00
parent c16f47c6d5
commit 93dc19497c
5 changed files with 109 additions and 166 deletions
+31 -45
View File
@@ -109,7 +109,7 @@ type
procedure RTLListViewChange(Sender: TObject);
private
FCurrUnboundAst: IAstNode;
FCurrExec: IExecutable; // Replaced FCurrAst and FCurrDesc
FCurrExec: TDataValue.TFunc;
FEnvironment: TAstEnvironment;
FWorkspace: TAuraWorkspace;
FScriptUpdate: Boolean;
@@ -226,12 +226,8 @@ begin
FEnvironment.SetStandardMode;
try
// 2. Compile (Pipeline is inside Environment)
// We store the executable artifact in the form
FCurrExec := FEnvironment.Compile(ANode);
// 3. Execute
Result := FEnvironment.Execute(FCurrExec);
Result := FCurrExec([]);
except
on E: Exception do
@@ -260,7 +256,6 @@ begin
procedure(const Scope: IExecutionScope)
var
smaAst: IAstNode;
smaExec: IExecutable;
begin
smaAst :=
TAst.LambdaExpr(
@@ -313,13 +308,7 @@ begin
)
);
// Compile the SMA factory using the environment itself
// Note: We pass FEnvironment.RootScope as the parent scope
smaExec := FEnvironment.Compile(smaAst);
// Execute the compiled AST to define the 'CreateSMA' function in the target scope
// We must use the *target* scope (Scope) as the parent for execution.
var smaFactory := FEnvironment.Execute(smaExec);
var smaFactory := FEnvironment.Run(smaAst);
Scope.Define('CreateSMA', smaFactory); // Define the factory
@@ -641,7 +630,7 @@ begin
try
converter := TJsonAstConverter.Create;
jsonObj := converter.Serialize(FCurrExec.CompiledAst);
jsonObj := converter.Serialize(FCurrUnboundAst);
try
Memo1.Lines.Text := jsonObj.Format(4);
finally
@@ -668,7 +657,7 @@ begin
end;
// Dump the compiled AST from the executable
TAstDumper.Dump(FCurrExec.CompiledAst, Memo1.Lines);
TAstDumper.Dump(FCurrUnboundAst, Memo1.Lines);
end;
procedure TForm1.FibonacciButtonClick(Sender: TObject);
@@ -703,7 +692,7 @@ begin
var fibExec := TestEnv.Compile(TAst.FunctionCall(TAst.Identifier('fib'), [TAst.Constant(25)]));
sw := TStopwatch.StartNew;
result := TestEnv.Execute(fibExec);
result := fibExec([]);
sw.Stop;
Memo1.Lines.Add(Format('Result: fib(25) %s (calculated in %d ms)', [result.ToString, sw.ElapsedMilliseconds]));
@@ -718,11 +707,11 @@ begin
var memoizeExec := memoizeTest.Compile(TAstScript.Parse('(fib 25)'));
sw := TStopwatch.StartNew;
result := memoizeTest.Execute(memoizeExec);
result := memoizeExec([]);
sw.Stop;
Memo1.Lines.Add(Format('Result 1st call: fib(25) %s (calculated in %d ms)', [result.ToString, sw.ElapsedMilliseconds]));
sw := TStopwatch.StartNew;
result := memoizeTest.Execute(memoizeExec);
result := memoizeExec([]);
sw.Stop;
Memo1.Lines.Add(Format('Result 2nd call: fib(25) %s (calculated in %d ms)', [result.ToString, sw.ElapsedMilliseconds]));
@@ -741,7 +730,7 @@ begin
exit;
end;
Memo1.Lines.Add(TAstScript.Print(FCurrExec.CompiledAst));
Memo1.Lines.Add(TAstScript.Print(FCurrUnboundAst));
end;
procedure TForm1.RecursionButtonClick(Sender: TObject);
@@ -797,7 +786,7 @@ end;
procedure TForm1.SeriesTestButtonClick(Sender: TObject);
var
ast, callAst: IAstNode;
ast: IAstNode;
resultValue: TDataValue;
series: TScalarRecordSeries;
recordDef: IScalarRecordDefinition;
@@ -840,9 +829,9 @@ begin
)
);
callAst := TAst.FunctionCall(ast, []);
var callAst := TAst.FunctionCall(ast, []);
resultValue := testEnv.CompileAndExecute(callAst);
resultValue := testEnv.Run(callAst);
Memo1.Lines.Add(Format('Result of script: %s', [resultValue.ToString]));
UpdateScript;
@@ -851,24 +840,20 @@ end;
procedure TForm1.Test1ButtonClick(Sender: TObject);
begin
FCurrUnboundAst :=
TAst.Block(
[
TAst.LambdaExpr(
[],
TAst.Block(
[
TAst.VarDecl(TAst.Identifier('a'), TAst.Nop),
TAst.VarDecl(
TAst.Identifier('b'),
TAst.BinaryExpr(TAst.Identifier('a'), TScalar.TBinaryOp.Multiply, TAst.Constant(2))
),
TAst.BinaryExpr(TAst.Identifier('a'), TScalar.TBinaryOp.Add, TAst.Identifier('b'))
]
)
)
]
TAstScript.Parse(
'''
(do
(print txt)
)
'''
);
var fn := FEnvironment.Compile(FCurrUnboundAst, [TAst.Identifier('txt')]);
fn(['Hello World']);
FEnvironment.RootScope.Define('fn', fn);
UpdateScript;
end;
@@ -879,12 +864,14 @@ var
sw: TStopwatch;
begin
Memo1.Lines.Clear;
Memo1.Lines.Add('--- Factory Pattern Demo ---');
sw := TStopwatch.StartNew;
root :=
TAst.Block(
[
TAst.FunctionCall(TAst.Identifier('fn'), [TAst.Constant('xyz')]),
TAst.VarDecl(
TAst.Identifier('createStrategyInstance'),
TAst.LambdaExpr(
@@ -926,7 +913,6 @@ var
values: TArray<TScalar.TValue>;
recordValue: TScalarRecord;
setupAst: IAstNode;
callExec: IExecutable;
begin
Memo1.Lines.Clear;
Memo1.Lines.Add(Format('--- Simulating O(1) SMA Crossover Strategy for %d ticks ---', [numRecs]));
@@ -960,7 +946,7 @@ begin
var seriesAddress := env.RootScope.Define('current_series', TDataValue.Void);
callExec := env.Compile(TAst.FunctionCall(TAst.Identifier('maCrossStrategy'), [TAst.Identifier('current_series')]));
var callExec := env.Compile(TAst.FunctionCall(TAst.Identifier('maCrossStrategy'), [TAst.Identifier('current_series')]));
// Simulation Loop
Memo1.Lines.Clear;
@@ -998,7 +984,7 @@ begin
begin
env.RootScope[seriesAddress] := series;
var resultValue := env.Execute(callExec);
var resultValue := callExec([]);
if i mod 50 = 0 then
begin
@@ -1078,7 +1064,7 @@ begin
FTriggerTest := FEnvironment.CreateEnvironment;
FTriggerTest.Define('X', TAst.VarDecl(TAst.Identifier('X'), TAst.Constant(0)));
FTriggerTest.Define('X', TAst.Constant(0));
FTriggerTest.Define(
'tickHandler',
TAst.LambdaExpr(
@@ -1106,7 +1092,7 @@ var
begin
callAst := TAst.FunctionCall(TAst.Identifier('tickHandler'), [TAst.Constant(1)]);
var X := FTriggerTest.CompileAndExecute(callAst);
var X := FTriggerTest.Run(callAst);
Memo1.Lines.Add(Format('Tick(1)! New value of X: %s', [X.ToString]));
UpdateScript;
@@ -1118,7 +1104,7 @@ var
begin
callAst := TAst.FunctionCall(TAst.Identifier('tickHandler'), [TAst.Constant(2)]);
var X := FTriggerTest.CompileAndExecute(callAst);
var X := FTriggerTest.Run(callAst);
Memo1.Lines.Add(Format('Tick(2)! New value of X: %s', [X.ToString]));
UpdateScript;