Anonymous recursions
This commit is contained in:
@@ -19,7 +19,8 @@ uses
|
||||
Myc.Ast.Binding in '..\Src\AST\Myc.Ast.Binding.pas',
|
||||
Myc.Ast.RTL in '..\Src\AST\Myc.Ast.RTL.pas',
|
||||
Myc.Ast.Dumper in '..\Src\AST\Myc.Ast.Dumper.pas',
|
||||
Myc.Ast.RTL.Core in '..\Src\AST\Myc.Ast.RTL.Core.pas';
|
||||
Myc.Ast.RTL.Core in '..\Src\AST\Myc.Ast.RTL.Core.pas',
|
||||
Myc.Utils in '..\Src\Myc.Utils.pas';
|
||||
|
||||
{$R *.res}
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
<DCCReference Include="..\Src\AST\Myc.Ast.RTL.pas"/>
|
||||
<DCCReference Include="..\Src\AST\Myc.Ast.Dumper.pas"/>
|
||||
<DCCReference Include="..\Src\AST\Myc.Ast.RTL.Core.pas"/>
|
||||
<DCCReference Include="..\Src\Myc.Utils.pas"/>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
|
||||
+42
-14
@@ -31,6 +31,9 @@ uses
|
||||
Myc.Ast.Evaluator,
|
||||
Myc.Ast.Printer,
|
||||
Myc.Ast.Dumper,
|
||||
Myc.Data.Decimal,
|
||||
Myc.Ast.Binding,
|
||||
Myc.Ast.RTL,
|
||||
FMX.Layouts,
|
||||
FMX.Objects,
|
||||
Myc.Ast.Debugger;
|
||||
@@ -110,8 +113,6 @@ implementation
|
||||
|
||||
uses
|
||||
Myc.Data.Scalar.JSON,
|
||||
Myc.Data.Decimal,
|
||||
Myc.Ast.Binding,
|
||||
System.Diagnostics, // For TStopwatch
|
||||
Myc.Ast.Json; // For TAstJson serialization
|
||||
|
||||
@@ -184,9 +185,6 @@ begin
|
||||
|
||||
resultValue := ExecuteAst(mainBlock, FGScope);
|
||||
|
||||
//TODO Dieses Assert löst aus:
|
||||
// "The final result should be 15, but is 10 (T:\Myc\ASTPlayground\MainForm.pas, line 186)"
|
||||
|
||||
Assert(TScalar.FromInteger(15) = resultValue.AsScalar, 'The final result should be 15, but is ' + resultValue.AsScalar.ToString);
|
||||
end;
|
||||
|
||||
@@ -282,14 +280,14 @@ var
|
||||
result: TDataValue;
|
||||
sw: TStopwatch;
|
||||
begin
|
||||
Memo1.Lines.Clear;
|
||||
Memo1.Lines.Add('--- Recursive fib with AST---');
|
||||
sw := TStopwatch.StartNew;
|
||||
|
||||
root :=
|
||||
// Create a setup script to define a memoize-compatible 'fib' function globally.
|
||||
var fibAst :=
|
||||
TAst.Block(
|
||||
[
|
||||
TAst.VarDecl(
|
||||
// 1. var fib; (Declare the name so it can be captured by the lambda. Initializer is nil)
|
||||
TAst.VarDecl(TAst.Identifier('fib')),
|
||||
// 2. var fib_impl = lambda(n) { ... fib(n-1) + fib(n-2) ... };
|
||||
TAst.Assign(
|
||||
TAst.Identifier('fib'),
|
||||
TAst.LambdaExpr(
|
||||
[TAst.Identifier('n')],
|
||||
@@ -297,6 +295,7 @@ begin
|
||||
TAst.BinaryExpr(TAst.Identifier('n'), boLess, TAst.Constant(TScalar.FromInt64(2))),
|
||||
TAst.Identifier('n'),
|
||||
TAst.BinaryExpr(
|
||||
// Recursive calls now use the re-bindable name 'fib' instead of 'Self'
|
||||
TAst.FunctionCall(
|
||||
TAst.Identifier('Self'),
|
||||
[TAst.BinaryExpr(TAst.Identifier('n'), boSubtract, TAst.Constant(TScalar.FromInt64(1)))]
|
||||
@@ -309,14 +308,43 @@ begin
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
]
|
||||
);
|
||||
|
||||
var fibScope := TAstBinder.Bind(fibAst, FGScope).CreateScope(FGScope);
|
||||
var visitor := CreateVisitor(fibScope);
|
||||
Result := visitor.Execute(fibAst);
|
||||
|
||||
Memo1.Lines.Clear;
|
||||
Memo1.Lines.Add('--- Recursive fib with AST---');
|
||||
sw := TStopwatch.StartNew;
|
||||
|
||||
root := TAst.FunctionCall(TAst.Identifier('fib'), [TAst.Constant(TScalar.FromInt64(30))]);
|
||||
|
||||
FLastAst := root;
|
||||
// Execute with fibScope as parent. The helper function handles debug/prod switching.
|
||||
result := ExecuteAst(root, fibScope);
|
||||
|
||||
sw.Stop;
|
||||
Memo1.Lines.Add(Format('Result: fib(30) %s (calculated in %d ms)', [result.ToString, sw.ElapsedMilliseconds]));
|
||||
|
||||
Memo1.Lines.Add('');
|
||||
Memo1.Lines.Add('--- Memoized recursive fib with AST (using global fib)---');
|
||||
sw := TStopwatch.StartNew;
|
||||
|
||||
root :=
|
||||
TAst.Block(
|
||||
[
|
||||
// Create a memoized version by calling the RTL function on the global 'fib'
|
||||
TAst.Assign(TAst.Identifier('fib'), TAst.FunctionCall(TAst.Identifier('Memoize'), [TAst.Identifier('fib')])),
|
||||
// Call the memoized function
|
||||
TAst.FunctionCall(TAst.Identifier('fib'), [TAst.Constant(TScalar.FromInt64(30))])
|
||||
]
|
||||
);
|
||||
|
||||
FLastAst := root;
|
||||
// Execute with FGScope as parent. The helper function handles debug/prod switching.
|
||||
result := ExecuteAst(root, FGScope);
|
||||
result := ExecuteAst(root, fibScope);
|
||||
|
||||
sw.Stop;
|
||||
Memo1.Lines.Add(Format('Result: fib(30) %s (calculated in %d ms)', [result.ToString, sw.ElapsedMilliseconds]));
|
||||
|
||||
Reference in New Issue
Block a user