From 4687ecb9cac0bc12b4f8a44e620fbe5de4e04171 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Sat, 1 Nov 2025 13:36:10 +0100 Subject: [PATCH] Binder refactoring - extracted macro expander --- ASTPlayground/ASTPlayground.delphilsp.json | 2 +- ASTPlayground/ASTPlayground.dpr | 3 +- ASTPlayground/ASTPlayground.dproj | 1 + ASTPlayground/MainForm.pas | 85 ++++-- Src/AST/Myc.Ast.Binding.pas | 223 +------------- Src/AST/Myc.Ast.MacroExpander.pas | 325 +++++++++++++++++++++ Src/AST/Myc.Ast.Visitor.pas | 4 +- 7 files changed, 394 insertions(+), 249 deletions(-) create mode 100644 Src/AST/Myc.Ast.MacroExpander.pas diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json index e43bb16..d088b85 100644 --- a/ASTPlayground/ASTPlayground.delphilsp.json +++ b/ASTPlayground/ASTPlayground.delphilsp.json @@ -1 +1 @@ -{ "settings": { "project": "file:///T%3A/Myc/ASTPlayground/ASTPlayground.dpr", "dllname": "dcc64370.dll", "dccOptions": "-$O- -$W+ --inline:off -$R+ -$Q+ --no-config -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG;;FRAMEWORK_FMX -E.\\Win64\\Debug -I\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -LEC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Bpl\\Win64 -LNC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NU.\\Win64\\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -OT:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -R\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -U\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -V -VN -VR -NBC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NHC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\hpp\\Win64 -NO.\\Win64\\Debug -LU" , "projectFiles":[ { "name": "MainForm", "file": "file:///T%3A/Myc/ASTPlayground/MainForm.pas" }, { "name": "Myc.Ast.Evaluator", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Evaluator.pas" }, { "name": "Myc.Ast.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Nodes.pas" }, { "name": "Myc.Ast.Scope", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Scope.pas" }, { "name": "Myc.Data.Value", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Data.Value.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.Binding", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Binding.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Text", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Text.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Unit1", "file": "file:///T%3A/Myc/ASTPlayground/Unit1.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": false, "browsingPaths": [ "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/OCX/Servers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/VCL","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/RTL/SYS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win/winrt","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/ToolsAPI","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/IBX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Internet","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/PROPERTY%20EDITORS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/XML","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Core","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/System","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Protocols","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/fmx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/components","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/engine","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/graph","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ado","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/cloud","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dbx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dsnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/vclctrls","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/connectors","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/proxygen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DataExplorer","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/src","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/tests","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Experts","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/abstraction","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/implementation","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indyimpl","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Property%20Editors/Indy10","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap/wsdlimporter","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Visualizers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XMLReporting","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XPGen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/rest","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/firedac","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/tethering","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnitX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ems","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/net","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/FlatBox2D","file:///C%3A/Users/Public/Documents/Embarcadero/Studio/37.0/Dcp/%25PLATFORM%25","file:///%25TP%25/runtime/vcl","file:///S%3A/sc_famos_src/svn_vcl/cpxedits","file:///S%3A/sc_famos_src/svn_vcl/dzChart","file:///S%3A/sc_famos_src/svn_vcl/eaeditor","file:///S%3A/sc_famos_src/svn_vcl/FamosEvents","file:///S%3A/sc_famos_src/svn_vcl/HTML_Viewer/source","file:///S%3A/sc_famos_src/svn_vcl/Myc_ChartEdit","file:///S%3A/sc_famos_src/svn_vcl/Myc_HemiDrag","file:///S%3A/sc_famos_src/svn_vcl/Myc_SplitControl","file:///S%3A/sc_famos_src/svn_vcl/NiceChart","file:///S%3A/sc_famos_src/svn_vcl/plotter","file:///S%3A/sc_famos_src/svn_vcl/SimpleIPC","file:///S%3A/sc_famos_src/svn_vcl/SynEdit-master/Source","file:///S%3A/sc_famos_src/svn_vcl/ValEdits","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib/win32","file:///S%3A/sc_famos_src/svn_vcl/Virtual-TreeView/Source","file:///S%3A/sc_famos_src/svn_common/caHelpSys","file:///S%3A/sc_famos_src/svn_common/Misc","file:///S%3A/sc_famos_src/svn_common/Myc_VecMath","file:///S%3A/sc_famos_src/svn_common/PascalScript/source","file:///S%3A/sc_famos_src/svn_common/TreeBase","file:///S%3A/sc_famos_src/svn_common/TreeBase/Medien","file:///S%3A/3rdParty/spring4d/Source","file:///S%3A/3rdParty/spring4d/Source/Base","file:///S%3A/3rdParty/spring4d/Source/Base/Collections","file:///S%3A/3rdParty/spring4d/Source/Base/Logging","file:///S%3A/3rdParty/spring4d/Source/Base/Patches","file:///S%3A/3rdParty/spring4d/Source/Core/Container","file:///S%3A/3rdParty/spring4d/Source/Core/Interception","file:///S%3A/3rdParty/spring4d/Source/Core/Logging","file:///S%3A/3rdParty/spring4d/Source/Core/Mocking","file:///S%3A/3rdParty/spring4d/Source/Core/Services","file:///S%3A/3rdParty/spring4d/Source/Extensions/Cryptography","file:///S%3A/3rdParty/spring4d/Source/Extensions/Utils","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCommon%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressGDI%2B%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLibrary/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/XP%20Theme%20Manager/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLayout%20Control/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressPageControl/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressEditors%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDocking%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressBars/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressOfficeCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressMemData/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDataController/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressNavBar/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressSkins%20Library/Sources","file:///T%3A/Myc/Src","file:///T%3A/Myc/Src/Data","file:///T%3A/Myc/Src/AST" ] , "CommonAppData": "file:///C%3A/Users/Brummel/AppData/Roaming/Embarcadero/BDS/37.0/" , "Templates": "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/ObjRepos/" } } \ No newline at end of file +{ "settings": { "project": "file:///T%3A/Myc/ASTPlayground/ASTPlayground.dpr", "dllname": "dcc64370.dll", "dccOptions": "-$O- -$W+ --inline:off -$R+ -$Q+ --no-config -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG;;FRAMEWORK_FMX -E.\\Win64\\Debug -I\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -LEC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Bpl\\Win64 -LNC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NU.\\Win64\\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -OT:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -R\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -U\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -V -VN -VR -NBC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NHC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\hpp\\Win64 -NO.\\Win64\\Debug -LU" , "projectFiles":[ { "name": "MainForm", "file": "file:///T%3A/Myc/ASTPlayground/MainForm.pas" }, { "name": "Myc.Ast.Evaluator", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Evaluator.pas" }, { "name": "Myc.Ast.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Nodes.pas" }, { "name": "Myc.Ast.Scope", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Scope.pas" }, { "name": "Myc.Data.Value", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Data.Value.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.Binding", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Binding.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Text", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Text.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Binding.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Binding.Nodes.pas" }, { "name": "Unit1", "file": "file:///T%3A/Myc/ASTPlayground/Unit1.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": false, "browsingPaths": [ "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/OCX/Servers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/VCL","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/RTL/SYS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win/winrt","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/ToolsAPI","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/IBX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Internet","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/PROPERTY%20EDITORS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/XML","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Core","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/System","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Protocols","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/fmx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/components","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/engine","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/graph","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ado","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/cloud","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dbx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dsnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/vclctrls","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/connectors","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/proxygen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DataExplorer","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/src","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/tests","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Experts","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/abstraction","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/implementation","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indyimpl","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Property%20Editors/Indy10","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap/wsdlimporter","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Visualizers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XMLReporting","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XPGen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/rest","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/firedac","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/tethering","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnitX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ems","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/net","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/FlatBox2D","file:///C%3A/Users/Public/Documents/Embarcadero/Studio/37.0/Dcp/%25PLATFORM%25","file:///%25TP%25/runtime/vcl","file:///S%3A/sc_famos_src/svn_vcl/cpxedits","file:///S%3A/sc_famos_src/svn_vcl/dzChart","file:///S%3A/sc_famos_src/svn_vcl/eaeditor","file:///S%3A/sc_famos_src/svn_vcl/FamosEvents","file:///S%3A/sc_famos_src/svn_vcl/HTML_Viewer/source","file:///S%3A/sc_famos_src/svn_vcl/Myc_ChartEdit","file:///S%3A/sc_famos_src/svn_vcl/Myc_HemiDrag","file:///S%3A/sc_famos_src/svn_vcl/Myc_SplitControl","file:///S%3A/sc_famos_src/svn_vcl/NiceChart","file:///S%3A/sc_famos_src/svn_vcl/plotter","file:///S%3A/sc_famos_src/svn_vcl/SimpleIPC","file:///S%3A/sc_famos_src/svn_vcl/SynEdit-master/Source","file:///S%3A/sc_famos_src/svn_vcl/ValEdits","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib/win32","file:///S%3A/sc_famos_src/svn_vcl/Virtual-TreeView/Source","file:///S%3A/sc_famos_src/svn_common/caHelpSys","file:///S%3A/sc_famos_src/svn_common/Misc","file:///S%3A/sc_famos_src/svn_common/Myc_VecMath","file:///S%3A/sc_famos_src/svn_common/PascalScript/source","file:///S%3A/sc_famos_src/svn_common/TreeBase","file:///S%3A/sc_famos_src/svn_common/TreeBase/Medien","file:///S%3A/3rdParty/spring4d/Source","file:///S%3A/3rdParty/spring4d/Source/Base","file:///S%3A/3rdParty/spring4d/Source/Base/Collections","file:///S%3A/3rdParty/spring4d/Source/Base/Logging","file:///S%3A/3rdParty/spring4d/Source/Base/Patches","file:///S%3A/3rdParty/spring4d/Source/Core/Container","file:///S%3A/3rdParty/spring4d/Source/Core/Interception","file:///S%3A/3rdParty/spring4d/Source/Core/Logging","file:///S%3A/3rdParty/spring4d/Source/Core/Mocking","file:///S%3A/3rdParty/spring4d/Source/Core/Services","file:///S%3A/3rdParty/spring4d/Source/Extensions/Cryptography","file:///S%3A/3rdParty/spring4d/Source/Extensions/Utils","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCommon%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressGDI%2B%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLibrary/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/XP%20Theme%20Manager/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLayout%20Control/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressPageControl/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressEditors%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDocking%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressBars/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressOfficeCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressMemData/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDataController/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressNavBar/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressSkins%20Library/Sources","file:///T%3A/Myc/Src","file:///T%3A/Myc/Src/Data","file:///T%3A/Myc/Src/AST" ] , "CommonAppData": "file:///C%3A/Users/Brummel/AppData/Roaming/Embarcadero/BDS/37.0/" , "Templates": "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/ObjRepos/" } } \ No newline at end of file diff --git a/ASTPlayground/ASTPlayground.dpr b/ASTPlayground/ASTPlayground.dpr index a947f3a..90021e7 100644 --- a/ASTPlayground/ASTPlayground.dpr +++ b/ASTPlayground/ASTPlayground.dpr @@ -22,7 +22,8 @@ uses Myc.Ast.Script in '..\Src\AST\Myc.Ast.Script.pas', Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas', Myc.Data.Keyword in '..\Src\Data\Myc.Data.Keyword.pas', - Myc.Ast.Binding.Nodes in '..\Src\AST\Myc.Ast.Binding.Nodes.pas'; + Myc.Ast.Binding.Nodes in '..\Src\AST\Myc.Ast.Binding.Nodes.pas', + Myc.Ast.MacroExpander in '..\Src\AST\Myc.Ast.MacroExpander.pas'; {$R *.res} diff --git a/ASTPlayground/ASTPlayground.dproj b/ASTPlayground/ASTPlayground.dproj index b658d33..52cbde6 100644 --- a/ASTPlayground/ASTPlayground.dproj +++ b/ASTPlayground/ASTPlayground.dproj @@ -153,6 +153,7 @@ + Base diff --git a/ASTPlayground/MainForm.pas b/ASTPlayground/MainForm.pas index 21e2afa..22a8d7c 100644 --- a/ASTPlayground/MainForm.pas +++ b/ASTPlayground/MainForm.pas @@ -38,11 +38,12 @@ uses Myc.Ast.Debugger, Myc.Fmx.AstEditor.Node, Myc.Fmx.AstEditor.Workspace, + Myc.Ast.MacroExpander, FMX.DialogService, FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base, - FMX.ListView; // Added for platform-independent dialogs + FMX.ListView; type // A test record @@ -208,25 +209,31 @@ end; function TForm1.ExecuteAst(const ANode: IAstNode; const AParentScope: IExecutionScope): TDataValue; var - binder: IAstBinder; boundAst: IAstNode; - descriptor: IScopeDescriptor; + descriptor: IScopeDescriptor; // This is the final (binder) descriptor evalScope: IExecutionScope; visitor: IEvaluatorVisitor; + macroDescriptor: IScopeDescriptor; // This is the macro-pass descriptor + expandedAst: IAstNode; begin // The new, streamlined pipeline: The binder handles macro expansion internally. FCurrUnboundAst := ANode; - // Step 1: Create a binder, passing the evaluator factory for compile-time evaluations. - binder := TAstBinder.Create(AParentScope, CreateEvaluator); + // Step 1: Expand macros (Phase 1) + // The expander uses the parent scope to find macros and the factory to eval unquotes. + expandedAst := TMacroExpander.ExpandMacros(AParentScope, ANode, macroDescriptor, CreateEvaluator); - boundAst := binder.Execute(ANode, descriptor); + // Step 2: Bind names and types (Phase 2) + // The binder runs on the *expanded* AST. It uses the same parent scope. + // It no longer needs the factory. + boundAst := TAstBinder.Bind(AParentScope, expandedAst, descriptor); // Store the final bound AST for visualization and debugging. FCurrAst := boundAst; FCurrDesc := descriptor; - // Step 2: Create the final scope and evaluator for runtime execution. + // Step 3: Create the final scope and evaluator for runtime execution. + // The runtime scope is created from the *binder's* descriptor, using the parent scope. evalScope := descriptor.CreateScope(AParentScope); visitor := CreateEvaluator(evalScope); Result := visitor.Execute(boundAst); @@ -243,9 +250,10 @@ begin TAst.RegisterLibrary( procedure(const Scope: IExecutionScope) var - smaAst, boundSmaAst: IAstNode; - binder: IAstBinder; + smaAst, boundSmaAst, expandedAst: IAstNode; + // binder: IAstBinder; // <-- REMOVED smaDescriptor: IScopeDescriptor; + macroDescriptor: IScopeDescriptor; smaScope: IExecutionScope; smaVisitor: IEvaluatorVisitor; begin @@ -300,8 +308,10 @@ begin ) ); - binder := TAstBinder.Create(Scope, CreateEvaluator); - boundSmaAst := binder.Execute(smaAst, smaDescriptor); + // Phase 1: Expand + expandedAst := TMacroExpander.ExpandMacros(Scope, smaAst, macroDescriptor, CreateEvaluator); + // Phase 2: Bind + boundSmaAst := TAstBinder.Bind(Scope, expandedAst, smaDescriptor); smaScope := smaDescriptor.CreateScope(Scope); smaVisitor := CreateEvaluator(smaScope); @@ -310,8 +320,10 @@ begin 'print', TDataValue( function(const Args: TArray): TDataValue + var + str: TStringBuilder; begin - var str := TStringBuilder.Create; + str := TStringBuilder.Create; try for var i := 0 to High(Args) do begin @@ -531,6 +543,8 @@ var jsonString: string; jsonObj: TJSONObject; converter: IJsonAstConverter; + macroDescriptor: IScopeDescriptor; + expandedAst: IAstNode; begin Memo1.Lines.BeginUpdate; try @@ -550,9 +564,13 @@ begin raise EJSONParseException.Create('Invalid JSON format.'); try - var binder := TAstBinder.Create(FGScope, CreateEvaluator); var unboundAst := converter.Deserialize(jsonObj); - FCurrAst := binder.Execute(unboundAst, FCurrDesc); + + // Phase 1: Expand + expandedAst := TMacroExpander.ExpandMacros(FGScope, unboundAst, macroDescriptor, CreateEvaluator); + // Phase 2: Bind + FCurrAst := TAstBinder.Bind(FGScope, expandedAst, FCurrDesc); + Memo1.Lines.Add('AST deserialized successfully from JSON.'); Memo1.Lines.Add('You can now visualize it (Middle Mouse Click) or pretty-print it.'); finally @@ -607,8 +625,8 @@ end; procedure TForm1.DumpButtonClick(Sender: TObject); var - binder: IAstBinder; boundNode: IAstNode; + macroDescriptor: IScopeDescriptor; begin Memo1.Lines.Clear; Memo1.Lines.Add('--- AST Dump ---'); @@ -619,9 +637,9 @@ begin exit; end; - // Re-bind the current AST against the global scope to ensure up-to-date binding info for the dump. - binder := TAstBinder.Create(FGScope, CreateEvaluator); - boundNode := binder.Execute(FCurrAst, FCurrDesc); + // Re-expand and re-bind the *unbound* AST (FCurrUnboundAst) + var expandedAst := TMacroExpander.ExpandMacros(FGScope, FCurrUnboundAst, macroDescriptor, CreateEvaluator); + boundNode := TAstBinder.Bind(FGScope, expandedAst, FCurrDesc); TAstDumper.Dump(boundNode, Memo1.Lines); end; @@ -632,7 +650,7 @@ var sw: TStopwatch; fibScope: IExecutionScope; visitor: IEvaluatorVisitor; - binder: IAstBinder; + macroDescriptor: IScopeDescriptor; begin fibAst := TAst.Block( @@ -662,9 +680,11 @@ begin ] ); - binder := TAstBinder.Create(FGScope, CreateEvaluator); + // Phase 1: Expand + var expandedAst := TMacroExpander.ExpandMacros(FGScope, fibAst, macroDescriptor, CreateEvaluator); + // Phase 2: Bind var desc: IScopeDescriptor; - boundFibAst := binder.Execute(fibAst, desc); + boundFibAst := TAstBinder.Bind(FGScope, expandedAst, desc); fibScope := desc.CreateScope(FGScope); visitor := CreateEvaluator(fibScope); @@ -900,9 +920,8 @@ var scope: IExecutionScope; values: TArray; recordValue: TScalarRecord; - binder: IAstBinder; setupAst, boundSetupAst, callAst, boundCallAst: IAstNode; - setupDescriptor, callDescriptor: IScopeDescriptor; + setupDescriptor, callDescriptor, macroDescriptor: IScopeDescriptor; seriesAddress: TResolvedSymbol; // Use TResolvedSymbol begin Memo1.Lines.Clear; @@ -958,8 +977,10 @@ begin ); // 1. Bind and execute the setup script. - binder := TAstBinder.Create(FGScope, CreateEvaluator); - boundSetupAst := binder.Execute(setupAst, setupDescriptor); + // Phase 1 + var expandedAst := TMacroExpander.ExpandMacros(FGScope, setupAst, macroDescriptor, CreateEvaluator); + // Phase 2 + boundSetupAst := TAstBinder.Bind(FGScope, expandedAst, setupDescriptor); scope := setupDescriptor.CreateScope(FGScope); var setupVisitor := CreateEvaluator(scope); @@ -971,8 +992,10 @@ begin callAst := TAst.FunctionCall(TAst.Identifier('maCrossStrategy'), [currentSeriesIdent]); // 3. Re-bind the call AST within the now-populated scope to resolve the new variable. - binder := TAstBinder.Create(scope, CreateEvaluator); - boundCallAst := binder.Execute(callAst, callDescriptor); + // Phase 1 + var expandedAst2 := TMacroExpander.ExpandMacros(scope, callAst, macroDescriptor, CreateEvaluator); + // Phase 2 + boundCallAst := TAstBinder.Bind(scope, expandedAst2, callDescriptor); // 4. Get the address of 'current_series' from the new descriptor. seriesAddress := callDescriptor.FindSymbol('current_series'); @@ -1077,8 +1100,8 @@ end; procedure TForm1.CreateTriggerExampleButtonClick(Sender: TObject); var blk: IAstNode; - binder: IAstBinder; visitor: IEvaluatorVisitor; + macroDescriptor: IScopeDescriptor; begin Memo1.Lines.Clear; Memo1.Lines.Add('--- Creating Trigger Blueprint ---'); @@ -1099,8 +1122,10 @@ begin ] ); - binder := TAstBinder.Create(FGScope, CreateEvaluator); - FCurrAst := binder.Execute(blk, FCurrDesc); + // Phase 1 + var expandedAst := TMacroExpander.ExpandMacros(FGScope, blk, macroDescriptor, CreateEvaluator); + // Phase 2 + FCurrAst := TAstBinder.Bind(FGScope, expandedAst, FCurrDesc); FTriggerScope := FCurrDesc.CreateScope(FGScope); visitor := CreateEvaluator(FTriggerScope); diff --git a/Src/AST/Myc.Ast.Binding.pas b/Src/AST/Myc.Ast.Binding.pas index c62f584..7b82417 100644 --- a/Src/AST/Myc.Ast.Binding.pas +++ b/Src/AST/Myc.Ast.Binding.pas @@ -22,25 +22,6 @@ type TAstBinder = class; // Forward declaration - TEvaluateProc = reference to function(const Node: IAstNode): TDataValue; - - // This visitor handles the expansion of a single macro body (` `...`). - TExpansionVisitor = class(TAstTransformer) - private - FEvaluate: TEvaluateProc; - FMacroScope: IExecutionScope; - function TransformAndSpliceNodes(const ANodes: TArray): TArray; - protected - function VisitUnquote(const Node: IUnquoteNode): TDataValue; override; - function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; override; - function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; override; - function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; override; - function VisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; override; - public - constructor Create(const AMacroScope: IExecutionScope; const AEvaluate: TEvaluateProc); - class function Expand(const MacroScope: IExecutionScope; const RootNode: IAstNode; const AEvaluate: TEvaluateProc): IAstNode; - end; - TAstBinder = class(TAstTransformer, IAstBinder) private type @@ -58,7 +39,6 @@ type FIsTailStack: TStack; FNextIsTail: Boolean; FBoxedDeclarations: THashSet; - FEvaluatorFactory: TEvaluatorFactory; // Operator folding maps FBinaryOperators: TDictionary; FUnaryOperators: TDictionary; @@ -93,15 +73,14 @@ type function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; override; public - constructor Create(const AInitialScope: IExecutionScope; const AEvaluatorFactory: TEvaluatorFactory); + constructor Create(const AInitialScope: IExecutionScope); destructor Destroy; override; function Execute(const RootNode: IAstNode; out Descriptor: IScopeDescriptor): IAstNode; class function Bind( const InitialScope: IExecutionScope; const RootNode: IAstNode; - out Descriptor: IScopeDescriptor; - const EvaluatorFactory: TEvaluatorFactory + out Descriptor: IScopeDescriptor ): IAstNode; static; end; @@ -120,129 +99,6 @@ type function GetHashCode(const Value: TResolvedAddress): Integer; override; end; -{ TExpansionVisitor } - -constructor TExpansionVisitor.Create(const AMacroScope: IExecutionScope; const AEvaluate: TEvaluateProc); -begin - inherited Create; - FMacroScope := AMacroScope; - FEvaluate := AEvaluate; -end; - -class function TExpansionVisitor.Expand( - const MacroScope: IExecutionScope; - const RootNode: IAstNode; - const AEvaluate: TEvaluateProc -): IAstNode; -begin - var expander := TExpansionVisitor.Create(MacroScope, AEvaluate) as IAstTransformer; - Result := expander.Execute(RootNode); -end; - -function TExpansionVisitor.TransformAndSpliceNodes(const ANodes: TArray): TArray; -var - newList: TList; - nodeToSplice: IAstNode; -begin - newList := TList.Create; - try - for var node in ANodes do - begin - if (node is TUnquoteSplicingNode) then - begin - var spliceExpr := (node as TUnquoteSplicingNode).Expression; - var evaluatedSpliceValue := VisitUnquote(TAst.Unquote(spliceExpr)); - - if (not evaluatedSpliceValue.IsVoid) and (evaluatedSpliceValue.Kind = vkInterface) then - begin - nodeToSplice := evaluatedSpliceValue.AsIntf; - if (nodeToSplice is TBlockExpressionNode) then - newList.AddRange((nodeToSplice as TBlockExpressionNode).Expressions) - else - raise Exception.Create('Expression inside unquote-splicing (`~@`) must be a list of nodes (a block).'); - end - else - raise Exception.Create('Expression inside unquote-splicing (`~@`) must evaluate to a list of nodes (a block).'); - end - else - begin - var transformedValue := node.Accept(self); - if not transformedValue.IsVoid then - newList.Add(transformedValue.AsIntf); - end; - end; - Result := newList.ToArray; - finally - newList.Free; - end; -end; - -function TExpansionVisitor.VisitUnquote(const Node: IUnquoteNode): TDataValue; -var - value: TDataValue; - expr: IAstNode; - symbol: TResolvedSymbol; -begin - expr := Node.Expression; - - if (expr is TIdentifierNode) then - begin - // Use new FindSymbol - symbol := FMacroScope.CreateDescriptor.FindSymbol((expr as TIdentifierNode).Name); - if (symbol.Address.Kind = akLocalOrParent) and (symbol.Address.ScopeDepth = 0) then - begin - // Use symbol.Address - var argValue := FMacroScope.Values[symbol.Address]; - if argValue.Kind = vkInterface then - begin - Result := argValue; - exit; - end; - end; - end; - - // externally evaluate the expression using the injected evaluator - value := FEvaluate(expr); - - // Allow unquoting scalars (which now include keywords) - if value.Kind in [vkScalar, vkText, vkVoid] then - begin - Result := TDataValue.FromIntf(TAst.Constant(value)); - end - else - raise Exception.CreateFmt('Cannot unquote complex value of type %s at compile time.', [value.Kind.ToString]); -end; - -function TExpansionVisitor.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; -begin - raise Exception.Create('Unquote-splicing (`~@`) can only appear inside a list form (e.g., a function call or a `do` block).'); -end; - -function TExpansionVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; -var - newArgs: TArray; - transformedCallee: IAstNode; -begin - transformedCallee := Self.Accept(Node.Callee).AsIntf; - newArgs := TransformAndSpliceNodes(Node.Arguments); - Result := TDataValue.FromIntf(TAst.FunctionCall(transformedCallee, newArgs)); -end; - -function TExpansionVisitor.VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; -var - newExprs: TArray; -begin - newExprs := TransformAndSpliceNodes(Node.Expressions); - Result := TDataValue.FromIntf(TAst.Block(newExprs)); -end; - -function TExpansionVisitor.VisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; -begin - // Record literals do not support splicing. - // We just use the default TAstTransformer implementation which visits child values. - Result := inherited VisitRecordLiteral(Node); -end; - { TResolvedAddressComparer } function TResolvedAddressComparer.Equals(const Left, Right: TResolvedAddress): Boolean; begin @@ -272,16 +128,14 @@ end; { TAstBinder } -constructor TAstBinder.Create(const AInitialScope: IExecutionScope; const AEvaluatorFactory: TEvaluatorFactory); +constructor TAstBinder.Create(const AInitialScope: IExecutionScope); var op: TScalar.TBinaryOp; begin inherited Create; Assert(Assigned(AInitialScope)); - Assert(Assigned(AEvaluatorFactory)); FInitialScope := AInitialScope; - FEvaluatorFactory := AEvaluatorFactory; FCurrentDescriptor := AInitialScope.CreateDescriptor; FUpvalueStack := TObjectStack.Create(True); FNestedLambdaCount := 0; @@ -329,14 +183,9 @@ begin end; end; -class function TAstBinder.Bind( - const InitialScope: IExecutionScope; - const RootNode: IAstNode; - out Descriptor: IScopeDescriptor; - const EvaluatorFactory: TEvaluatorFactory -): IAstNode; +class function TAstBinder.Bind(const InitialScope: IExecutionScope; const RootNode: IAstNode; out Descriptor: IScopeDescriptor): IAstNode; begin - var binder := TAstBinder.Create(InitialScope, EvaluatorFactory) as IAstBinder; + var binder := TAstBinder.Create(InitialScope) as IAstBinder; Result := binder.Execute(RootNode, Descriptor); end; @@ -389,7 +238,6 @@ var calleeIdentifier: TIdentifierNode; binaryOp: TScalar.TBinaryOp; unaryOp: TScalar.TUnaryOp; - macroDef: IMacroDefinitionNode; left, right: IAstNode; leftType, rightType, resultType: IStaticType; boundCall: TBoundFunctionCallNode; @@ -475,51 +323,6 @@ begin exit; end; end; - - // --- Macro Expansion --- - - macroDef := FCurrentDescriptor.FindMacro(calleeIdentifier.Name); - if macroDef <> nil then - begin - var expansionScope := TAst.CreateScope(nil); - var params := macroDef.Parameters; - if Length(Node.Arguments) <> Length(params) then - raise Exception.CreateFmt( - 'Macro %s expects %d arguments, but got %d', - [calleeIdentifier.Name, Length(params), Length(Node.Arguments)]); - - for i := 0 to High(params) do - expansionScope.Define(params[i].Name, TDataValue.FromIntf(Node.Arguments[i])); - - // expand - var expandedBody := - TExpansionVisitor.Expand( - expansionScope, - macroDef.Body.Expression, - function(const Node: IAstNode): TDataValue - var - subDescriptor: IScopeDescriptor; - begin - // in place evaluator for expanded expressions - var tempInitScope := TScope.CreateScope(FInitialScope.Parent, FCurrentDescriptor, nil); - var boundSubAst := TAstBinder.Bind(tempInitScope, Node, subDescriptor, FEvaluatorFactory); - var evalScope := subDescriptor.CreateScope(tempInitScope); - var evaluator := FEvaluatorFactory(evalScope); - Result := evaluator.Execute(boundSubAst); - end - ); - - // bind expanded body - var boundExpandedBody := Self.Accept(expandedBody).AsIntf; - - // wrap in new expansion node - var macroNode := TMacroExpansionNode.Create(Node, boundExpandedBody) as IMacroExpansionNode; - // The type of the macro node is the type of its expanded body - (macroNode as TAstNode).StaticType := (boundExpandedBody as TAstNode).StaticType; - - // done - exit(TDataValue.FromIntf(macroNode)); - end; end; // --- Default: Bind as a standard function call --- @@ -553,21 +356,9 @@ begin end; function TAstBinder.VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; -var - boundCallee: IAstNode; - boundArgs: TArray; - boundExpandedBody: IAstNode; - boundOriginalCall: IFunctionCallNode; - newMacroNode: IMacroExpansionNode; begin - boundCallee := Accept(Node.Callee).AsIntf; - boundArgs := AcceptNodes(Node.Arguments); - boundExpandedBody := Accept(Node.ExpandedBody).AsIntf; - boundOriginalCall := TAst.FunctionCall(boundCallee, boundArgs); - newMacroNode := TMacroExpansionNode.Create(boundOriginalCall, boundExpandedBody); - - // The type of the macro node is the type of its expanded body - Result := SetType(TDataValue.FromIntf(newMacroNode), (boundExpandedBody as TAstNode).StaticType); + // Macro expansion nodes should not exist by this stage. + raise Exception.Create('MacroExpansionNode is not expected in the binding pass.'); end; procedure TAstBinder.ExitScope; diff --git a/Src/AST/Myc.Ast.MacroExpander.pas b/Src/AST/Myc.Ast.MacroExpander.pas new file mode 100644 index 0000000..0132c45 --- /dev/null +++ b/Src/AST/Myc.Ast.MacroExpander.pas @@ -0,0 +1,325 @@ +unit Myc.Ast.MacroExpander; + +interface + +uses + System.SysUtils, + System.Classes, + System.Generics.Collections, + Myc.Data.Scalar, + Myc.Data.Value, + Myc.Ast.Nodes, + Myc.Ast.Visitor, + Myc.Ast.Scope, + Myc.Ast.Types, + Myc.Ast, + Myc.Ast.Binding; // Required for TAstBinder.Bind + +type + IAstMacroExpander = interface(IAstVisitor) + function Execute(const RootNode: IAstNode; out Descriptor: IScopeDescriptor): IAstNode; + end; + + // Callback type for compile-time evaluation of Unquote expressions + TEvaluateProc = reference to function(const Node: IAstNode): TDataValue; + + // --- TExpansionVisitor (Moved from Binding) --- + // This visitor handles the expansion of a *single* macro body (` `...). + TExpansionVisitor = class(TAstTransformer) + private + FEvaluate: TEvaluateProc; + FMacroScope: IExecutionScope; + function TransformAndSpliceNodes(const ANodes: TArray): TArray; + protected + function VisitUnquote(const Node: IUnquoteNode): TDataValue; override; + function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; override; + function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; override; + function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; override; + function VisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; override; + public + constructor Create(const AMacroScope: IExecutionScope; const AEvaluate: TEvaluateProc); + class function Expand(const MacroScope: IExecutionScope; const RootNode: IAstNode; const AEvaluate: TEvaluateProc): IAstNode; + end; + + // --- TMacroExpander (New main class for Phase 1) --- + // This transformer traverses the entire AST *before* the binder, + // to find and expand macros. + TMacroExpander = class(TAstTransformer, IAstMacroExpander) + private + FInitialScope: IExecutionScope; + FCurrentDescriptor: IScopeDescriptor; + FEvaluatorFactory: TEvaluatorFactory; + protected + function Accept(const Node: IAstNode): TDataValue; override; + // Finds macro definitions + function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; override; + // Finds and expands macro calls + function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; override; + public + constructor Create(const AInitialScope: IExecutionScope; const AEvaluatorFactory: TEvaluatorFactory); + function Execute(const RootNode: IAstNode; out Descriptor: IScopeDescriptor): IAstNode; + + class function ExpandMacros( + const InitialScope: IExecutionScope; + const RootNode: IAstNode; + out Descriptor: IScopeDescriptor; + const EvaluatorFactory: TEvaluatorFactory + ): IAstNode; static; + end; + +implementation + +uses + System.Generics.Defaults, + Myc.Ast.Evaluator, // Required for TEvaluatorVisitor.Execute + Myc.Data.Keyword; + +{ TExpansionVisitor } + +constructor TExpansionVisitor.Create(const AMacroScope: IExecutionScope; const AEvaluate: TEvaluateProc); +begin + inherited Create; + FMacroScope := AMacroScope; + FEvaluate := AEvaluate; +end; + +class function TExpansionVisitor.Expand( + const MacroScope: IExecutionScope; + const RootNode: IAstNode; + const AEvaluate: TEvaluateProc +): IAstNode; +begin + var expander := TExpansionVisitor.Create(MacroScope, AEvaluate) as IAstTransformer; + Result := expander.Execute(RootNode); +end; + +function TExpansionVisitor.TransformAndSpliceNodes(const ANodes: TArray): TArray; +var + newList: TList; + nodeToSplice: IAstNode; +begin + newList := TList.Create; + try + for var node in ANodes do + begin + if (node is TUnquoteSplicingNode) then + begin + var spliceExpr := (node as TUnquoteSplicingNode).Expression; + // Evaluate the unquoted expression + var evaluatedSpliceValue := FEvaluate(spliceExpr); + + if (not evaluatedSpliceValue.IsVoid) and (evaluatedSpliceValue.Kind = vkInterface) then + begin + nodeToSplice := evaluatedSpliceValue.AsIntf; + if (nodeToSplice is TBlockExpressionNode) then + newList.AddRange((nodeToSplice as TBlockExpressionNode).Expressions) + else + // Allow splicing single nodes, not just blocks + newList.Add(nodeToSplice); + end + else if (not evaluatedSpliceValue.IsVoid) then + begin + // If the value is not an AST node (e.g. a scalar), wrap it in a constant + newList.Add(TAst.Constant(evaluatedSpliceValue)); + end; + // else (if void, splice nothing) + end + else + begin + var transformedValue := node.Accept(self); + if not transformedValue.IsVoid then + newList.Add(transformedValue.AsIntf); + end; + end; + Result := newList.ToArray; + finally + newList.Free; + end; +end; + +function TExpansionVisitor.VisitUnquote(const Node: IUnquoteNode): TDataValue; +var + value: TDataValue; + expr: IAstNode; + symbol: TResolvedSymbol; +begin + expr := Node.Expression; + + // Check if we are unquoting a macro parameter (simple identifier) + if (expr is TIdentifierNode) then + begin + symbol := FMacroScope.CreateDescriptor.FindSymbol((expr as TIdentifierNode).Name); + if (symbol.Address.Kind = akLocalOrParent) and (symbol.Address.ScopeDepth = 0) then + begin + // It's a parameter. Return the TDataValue containing the AST node passed as argument. + var argValue := FMacroScope.Values[symbol.Address]; + if argValue.Kind = vkInterface then + begin + Result := argValue; + exit; + end; + end; + end; + + // If not a simple parameter, evaluate the expression at compile-time. + value := FEvaluate(expr); + + // If the result is an AST node (e.g. from a helper function), return it directly. + if value.Kind = vkInterface then + begin + Result := value; + exit; + end; + + // If the result is a scalar, text, or void, wrap it in a TConstantNode. + if value.Kind in [vkScalar, vkText, vkVoid] then + begin + Result := TDataValue.FromIntf(TAst.Constant(value)); + end + else + raise Exception.CreateFmt('Cannot unquote complex runtime value of type %s at compile time.', [value.Kind.ToString]); +end; + +function TExpansionVisitor.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; +begin + // This should be handled by the caller (VisitFunctionCall / VisitBlockExpression) + raise Exception.Create('Unquote-splicing (`~@`) can only appear inside a list form (e.g., a function call or a `do` block).'); +end; + +function TExpansionVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; +var + newArgs: TArray; + transformedCallee: IAstNode; +begin + transformedCallee := Self.Accept(Node.Callee).AsIntf; + newArgs := TransformAndSpliceNodes(Node.Arguments); + Result := TDataValue.FromIntf(TAst.FunctionCall(transformedCallee, newArgs)); +end; + +function TExpansionVisitor.VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; +var + newExprs: TArray; +begin + newExprs := TransformAndSpliceNodes(Node.Expressions); + Result := TDataValue.FromIntf(TAst.Block(newExprs)); +end; + +function TExpansionVisitor.VisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; +begin + // Record literals do not support splicing. + // We just use the default TAstTransformer implementation which visits child values. + Result := inherited VisitRecordLiteral(Node); +end; + +{ TMacroExpander } + +constructor TMacroExpander.Create(const AInitialScope: IExecutionScope; const AEvaluatorFactory: TEvaluatorFactory); +begin + inherited Create; + Assert(Assigned(AInitialScope)); + Assert(Assigned(AEvaluatorFactory)); + FInitialScope := AInitialScope; + FEvaluatorFactory := AEvaluatorFactory; + // Create the top-level descriptor for macros + FCurrentDescriptor := AInitialScope.CreateDescriptor; +end; + +class function TMacroExpander.ExpandMacros( + const InitialScope: IExecutionScope; + const RootNode: IAstNode; + out Descriptor: IScopeDescriptor; + const EvaluatorFactory: TEvaluatorFactory +): IAstNode; +begin + var expander := TMacroExpander.Create(InitialScope, EvaluatorFactory) as IAstMacroExpander; + Result := expander.Execute(RootNode, Descriptor); +end; + +function TMacroExpander.Execute(const RootNode: IAstNode; out Descriptor: IScopeDescriptor): IAstNode; +begin + // This executes the transformation (Accept) + var transformedValue := Accept(RootNode); + + if transformedValue.IsVoid then + Result := TAst.Block([]) + else + Result := transformedValue.AsIntf; + + Descriptor := FCurrentDescriptor; +end; + +function TMacroExpander.Accept(const Node: IAstNode): TDataValue; +begin + // Standard transformer Accept + if (not Assigned(Node)) or Done then + exit; + Result := Node.Accept(Self); +end; + +function TMacroExpander.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; +begin + // Register the macro in the current descriptor + FCurrentDescriptor.DefineMacro(Node.Name.Name, Node); + // Remove the (defmacro ...) node from the AST; it's compile-time only. + Result := TDataValue.Void; +end; + +function TMacroExpander.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; +var + calleeIdentifier: TIdentifierNode; + macroDef: IMacroDefinitionNode; + i: Integer; +begin + // Check if this is an identifier + if not (Node.Callee is TIdentifierNode) then + exit(inherited VisitFunctionCall(Node)); + + calleeIdentifier := Node.Callee as TIdentifierNode; + + // Check if this identifier is a macro + macroDef := FCurrentDescriptor.FindMacro(calleeIdentifier.Name); + if macroDef = nil then + exit(inherited VisitFunctionCall(Node)); // Not a macro, let transformer continue + + // --- It is a macro, expand it --- + + // 1. Create the temporary scope for the macro parameters + var expansionScope := TAst.CreateScope(nil); + var params := macroDef.Parameters; + if Length(Node.Arguments) <> Length(params) then + raise Exception + .CreateFmt('Macro %s expects %d arguments, but got %d', [calleeIdentifier.Name, Length(params), Length(Node.Arguments)]); + + // 2. Populate scope: Map parameter names to the *un-evaluated* AST nodes + for i := 0 to High(params) do + expansionScope.Define(params[i].Name, TDataValue.FromIntf(Node.Arguments[i])); + + // 3. Create the evaluation callback (TEvaluateProc) + var evaluatorProc: TEvaluateProc; + evaluatorProc := + function(const ANodeToEvaluate: IAstNode): TDataValue + var + subDescriptor: IScopeDescriptor; + begin + // This is the compile-time evaluation (Binder + Evaluator) + // It runs in the *current* context (FInitialScope + FCurrentDescriptor) + // not the expansionScope. + var tempInitScope := TScope.CreateScope(FInitialScope.Parent, FCurrentDescriptor, nil); + var boundSubAst := TAstBinder.Bind(tempInitScope, ANodeToEvaluate, subDescriptor); + var evalScope := subDescriptor.CreateScope(tempInitScope); + var evaluator := FEvaluatorFactory(evalScope); + Result := evaluator.Execute(boundSubAst); + end; + + // 4. Expand the macro body using the TExpansionVisitor + var expandedBody := TExpansionVisitor.Expand(expansionScope, macroDef.Body.Expression, evaluatorProc); + + // 5. Wrap the result in a MacroExpansionNode (for debugging/tracing) + var macroNode := TMacroExpansionNode.Create(Node, expandedBody); + + // 6. IMPORTANT: Re-run the expander on the *new* AST fragment + // to handle macros that expand into other macros. + Result := Self.Accept(macroNode); +end; + +end. diff --git a/Src/AST/Myc.Ast.Visitor.pas b/Src/AST/Myc.Ast.Visitor.pas index fd65c11..d73c657 100644 --- a/Src/AST/Myc.Ast.Visitor.pas +++ b/Src/AST/Myc.Ast.Visitor.pas @@ -267,7 +267,9 @@ end; function TAstTransformer.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; begin var identifier := Accept(Node.Identifier).AsIntf; - var initializer := Accept(Node.Initializer).AsIntf; + var initializer: IAstNode := nil; + if Node.Initializer <> nil then + initializer := Accept(Node.Initializer).AsIntf; if (identifier = Node.Identifier) and (initializer = Node.Initializer) then Result := TDataValue.FromIntf(Node) else