Visualizer node aggregates

Fix in macro expander
This commit is contained in:
Michael Schimmel
2025-11-04 17:45:47 +01:00
parent 2fd85be923
commit 2b8a3effed
8 changed files with 1100 additions and 915 deletions
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
<ProjectVersion>20.3</ProjectVersion> <ProjectVersion>20.3</ProjectVersion>
<FrameworkType>FMX</FrameworkType> <FrameworkType>FMX</FrameworkType>
<Base>True</Base> <Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config> <Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win64</Platform> <Platform Condition="'$(Platform)'==''">Win64</Platform>
<ProjectName Condition="'$(ProjectName)'==''">ASTPlayground</ProjectName> <ProjectName Condition="'$(ProjectName)'==''">ASTPlayground</ProjectName>
<TargetedPlatforms>2</TargetedPlatforms> <TargetedPlatforms>2</TargetedPlatforms>
+21
View File
@@ -234,8 +234,29 @@ object Form1: TForm1
object ScriptMemo: TMemo object ScriptMemo: TMemo
Touch.InteractiveGestures = [Pan, LongTap, DoubleTap] Touch.InteractiveGestures = [Pan, LongTap, DoubleTap]
DataDetectorTypes = [] DataDetectorTypes = []
Lines.Strings = (
'(do'
'(defmacro repeat [n body]'
' `(do'
' (def loop (fn [counter]'
' (if (> counter 0)'
' (do'
' ~body'
' (recur (- counter 1))'
' )'
' (do'
' )'
' )'
' ))'
' (loop ~n)'
' )'
')'
''
'(repeat 5 "hi")'
')')
StyledSettings = [Size, Style, FontColor] StyledSettings = [Size, Style, FontColor]
TextSettings.Font.Family = 'Consolas' TextSettings.Font.Family = 'Consolas'
OnChange = ScriptMemoChange
OnChangeTracking = ScriptMemoChange OnChangeTracking = ScriptMemoChange
Align = Right Align = Right
Position.X = 920.000000000000000000 Position.X = 920.000000000000000000
+10 -8
View File
@@ -1348,14 +1348,16 @@ procedure TForm1.ShowVizualization(X, Y: Single);
begin begin
FWorkspace.DeleteChildren; FWorkspace.DeleteChildren;
if FCurrAst <> nil then FWorkspace.Build(FCurrUnboundAst, TPointF.Create(X, Y));
begin //
FWorkspace.Build(FCurrAst, TPointF.Create(X, Y)); // if FCurrAst <> nil then
end // begin
else if FCurrUnboundAst <> nil then // FWorkspace.Build(FCurrAst, TPointF.Create(X, Y));
begin // end
FWorkspace.Build(FCurrUnboundAst, TPointF.Create(X, Y)); // else if FCurrUnboundAst <> nil then
end; // begin
// FWorkspace.Build(FCurrUnboundAst, TPointF.Create(X, Y));
// end;
end; end;
end. end.
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -181,9 +181,11 @@ end;
function TAstBinder.VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode; function TAstBinder.VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode;
begin begin
// The MacroExpander (Phase 1) should have unwrapped this. // The MacroExpander (Phase 1) created this node.
// We only visit the *expanded* body. // We must bind the ExpandedBody, but keep the MacroExpansionNode wrapper.
Result := Accept(Node.ExpandedBody); // The base TAstTransformer implementation already does exactly this
// by visiting Callee, Arguments, and ExpandedBody.
Result := inherited VisitMacroExpansionNode(Node);
end; end;
function TAstBinder.VisitFunctionCall(const Node: IFunctionCallNode): IAstNode; function TAstBinder.VisitFunctionCall(const Node: IFunctionCallNode): IAstNode;
+9 -8
View File
@@ -1,3 +1,6 @@
//==================================================================================================
//== FULL UNIT START: Myc.Ast.MacroExpander (from Myc.Ast.MacroExpander.pas)
//==================================================================================================
unit Myc.Ast.MacroExpander; unit Myc.Ast.MacroExpander;
interface interface
@@ -280,7 +283,8 @@ begin
// --- It is a macro, expand it --- // --- It is a macro, expand it ---
// 1. Create the temporary scope for the macro parameters // 1. Create the temporary scope for the macro parameters
var expansionScope := TAst.CreateScope(nil); // It must be parented to the *initial* scope to find other macros/globals.
var expansionScope := TAst.CreateScope(FInitialScope);
var params := macroDef.Parameters; var params := macroDef.Parameters;
if Length(Node.Arguments) <> Length(params) then if Length(Node.Arguments) <> Length(params) then
raise Exception raise Exception
@@ -301,14 +305,11 @@ begin
boundSubAst: IAstNode; boundSubAst: IAstNode;
begin begin
// This is the compile-time evaluation (Binder + Evaluator) // This is the compile-time evaluation (Binder + Evaluator)
// It runs in the *current* context (FInitialScope + FCurrentDescriptor) // [FIX] It must run in the 'expansionScope' which contains the parameters.
var tempInitScope := TScope.CreateScope(FInitialScope.Parent, FCurrentDescriptor, nil); boundSubAst := TAstBinder.Bind(expansionScope, ANodeToEvaluate, subDescriptor);
// Bind (mutates ANodeToEvaluate) and get its descriptor // Create eval scope from the new descriptor, parented to the expansion scope
boundSubAst := TAstBinder.Bind(tempInitScope, ANodeToEvaluate, subDescriptor); evalScope := subDescriptor.CreateScope(expansionScope);
// Create eval scope from the new descriptor
evalScope := subDescriptor.CreateScope(tempInitScope);
evaluator := FEvaluatorFactory(evalScope); evaluator := FEvaluatorFactory(evalScope);
Result := evaluator.Execute(boundSubAst); Result := evaluator.Execute(boundSubAst);
+18 -1
View File
@@ -68,6 +68,12 @@ type
akNop // Added Nop akNop // Added Nop
); );
// Helper for TAstNodeKind providing a string representation
TAstNodeKindHelper = record helper for TAstNodeKind
public
function ToString: string;
end;
// --- Concrete Type Definitions --- // --- Concrete Type Definitions ---
// Defines how an identifier's address was resolved. // Defines how an identifier's address was resolved.
@@ -377,7 +383,18 @@ type
implementation implementation
uses uses
System.Classes; System.Classes,
System.Rtti,
System.StrUtils;
{ TAstNodeKindHelper }
function TAstNodeKindHelper.ToString: string;
begin
Result := TRttiEnumerationType.GetName<TAstNodeKind>(Self);
Assert(StartsText('ak', Result));
Result := Result.Substring(2);
end;
{ TResolvedAddress } { TResolvedAddress }