diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json
index 8662a1a..bbbb104 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.Fmx.AstVisualizer", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstVisualizer.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" } ] , "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 7341e7d..36976ee 100644
--- a/ASTPlayground/ASTPlayground.dpr
+++ b/ASTPlayground/ASTPlayground.dpr
@@ -20,8 +20,7 @@ uses
Myc.Fmx.AstEditor.Text in 'Myc.Fmx.AstEditor.Text.pas',
Myc.Utils in '..\Src\Myc.Utils.pas',
Myc.Ast.Script in '..\Src\AST\Myc.Ast.Script.pas',
- Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas',
- Myc.Fmx.AstVisualizer in 'Myc.Fmx.AstVisualizer.pas';
+ Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas';
{$R *.res}
diff --git a/ASTPlayground/ASTPlayground.dproj b/ASTPlayground/ASTPlayground.dproj
index 0372725..aa0dad9 100644
--- a/ASTPlayground/ASTPlayground.dproj
+++ b/ASTPlayground/ASTPlayground.dproj
@@ -151,7 +151,6 @@
-
Base
diff --git a/ASTPlayground/MainForm.pas b/ASTPlayground/MainForm.pas
index 3655b38..6e197a4 100644
--- a/ASTPlayground/MainForm.pas
+++ b/ASTPlayground/MainForm.pas
@@ -36,7 +36,6 @@ uses
FMX.Layouts,
FMX.Objects,
Myc.Ast.Debugger,
- Myc.Fmx.AstVisualizer,
Myc.Fmx.AstEditor.Node,
Myc.Fmx.AstEditor.Workspace,
FMX.DialogService,
diff --git a/ASTPlayground/Myc.Fmx.AstEditor.Node.pas b/ASTPlayground/Myc.Fmx.AstEditor.Node.pas
index f878c3b..127007a 100644
--- a/ASTPlayground/Myc.Fmx.AstEditor.Node.pas
+++ b/ASTPlayground/Myc.Fmx.AstEditor.Node.pas
@@ -8,14 +8,134 @@ uses
System.UITypes,
System.Types,
System.Math.Vectors,
+ System.Math,
+ System.Generics.Defaults,
+ System.Generics.Collections,
FMX.Types,
FMX.Controls,
FMX.Objects,
- FMX.Graphics;
+ FMX.Graphics,
+ FMX.StdCtrls,
+ Myc.Data.Scalar,
+ Myc.Data.Value,
+ Myc.Ast.Nodes,
+ Myc.Ast.Visitor,
+ Myc.Ast,
+ Myc.Fmx.AstEditor.Workspace;
+
+const
+ cNodePadding = 10;
+ cTitleTopPadding = 2;
+ cTitleBottomPadding = 4;
+ cMinNodeWidth = 10;
+ cMinNodeHeight = 10;
type
+ TAuraNode = class;
+
+ IAstVisualizer = interface
+ {$region 'private'}
+ function GetExprDepth: Integer;
+ function GetParentControl: TControl;
+ {$endregion}
+
+ function Clone(ParentControl: TControl; ExprDepth: Integer): IAstVisualizer;
+ function CallAccept(const Node: IAstNode): TAuraNode;
+ function GetWorkspace: TAuraWorkspace;
+
+ property ExprDepth: Integer read GetExprDepth;
+ property ParentControl: TControl read GetParentControl;
+ property Workspace: TAuraWorkspace read GetWorkspace;
+ end;
+
+ TAstVisualizer = class(TAstVisitor, IAstVisualizer)
+ private
+ FExprDepth: Integer;
+ FParentControl: TControl;
+ FWorkspace: TAuraWorkspace;
+ // Calls Accept on the node and returns the resulting TAuraNode.
+ function CallAccept(const Node: IAstNode): TAuraNode;
+ function GetExprDepth: Integer;
+ function GetParentControl: TControl;
+ function GetWorkspace: TAuraWorkspace;
+ procedure SetExprDepth(const Value: Integer);
+ procedure SetParentControl(const Value: TControl);
+ protected
+ // Visitor implementations for each AST node type.
+ function VisitConstant(const Node: IConstantNode): TDataValue; override;
+ function VisitIdentifier(const Node: IIdentifierNode): TDataValue; override;
+ function VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue; override;
+ function VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue; override;
+ function VisitIfExpression(const Node: IIfExpressionNode): TDataValue; override;
+ function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; override;
+ function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; override;
+ function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; override;
+ function VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; override;
+ function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; override;
+ function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; override;
+ function VisitAssignment(const Node: IAssignmentNode): TDataValue; override;
+ function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; override;
+ function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; override;
+ function VisitUnquote(const Node: IUnquoteNode): TDataValue; override;
+ function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; override;
+ function VisitIndexer(const Node: IIndexerNode): TDataValue; override;
+ function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue; override;
+ function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; override;
+ function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; override;
+ function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; override;
+ function VisitRecurNode(const Node: IRecurNode): TDataValue; override;
+
+ public
+ constructor Create(AWorkspace: TAuraWorkspace; AParentControl: TControl; AExprDepth: Integer);
+ destructor Destroy; override;
+
+ function Clone(ParentControl: TControl; ExprDepth: Integer): IAstVisualizer;
+
+ property ExprDepth: Integer read GetExprDepth write SetExprDepth;
+ property ParentControl: TControl read GetParentControl write SetParentControl;
+ property Workspace: TAuraWorkspace read GetWorkspace;
+ end;
+
+ // Defines the layout direction for children within TAutoFitControl
+ TLayoutOrientation = (loVertical, loHorizontal);
+
+ // Defines the alignment of children on the cross-axis
+ TLayoutAlignment = (laCenter, laFlush);
+
+ // A styled control that automatically adjusts its size to fit its children, including padding.
+ TAutoFitControl = class(TStyledControl)
+ private
+ FUpdatingOwnSize: Boolean; // Recursion guard
+ FNeedRecalcSize: Boolean; // Flag for EndUpdate
+ FOrientation: TLayoutOrientation; // Storage for Orientation
+ FAlignment: TLayoutAlignment; // Storage for Alignment
+ procedure RecalcOwnSize;
+ procedure SetOrientation(const Value: TLayoutOrientation);
+ procedure SetAlignment(const Value: TLayoutAlignment);
+ protected
+
+ // Called by children when their size, position, or visibility changes
+ procedure ParentContentChanged; override;
+ // Called when our own padding changes
+ procedure PaddingChanged; override;
+ // Called after children list has changed (add/remove)
+ procedure ChangeChildren; override;
+ // Initial calculation after loading
+ procedure Loaded; override;
+ // Handle pending recalc after updates
+ procedure DoEndUpdate; override;
+ public
+ constructor Create(AOwner: TComponent); override;
+
+ published
+ // Make Padding published if needed
+ property Padding;
+ property Orientation: TLayoutOrientation read FOrientation write SetOrientation default TLayoutOrientation.loHorizontal;
+ property Alignment: TLayoutAlignment read FAlignment write SetAlignment default TLayoutAlignment.laCenter;
+ end;
+
// A movable panel with a custom-painted border. Content (like title) is added externally.
- TAuraNode = class(TStyledControl)
+ TAuraNode = class(TAutoFitControl)
private
FBackgroundColor: TAlphaColor;
// Flag to indicate if the control is currently being dragged.
@@ -28,7 +148,8 @@ type
FBorderRadius: Single;
// If true, the node is drawn without a border and with a transparent background.
FFrameless: Boolean;
-
+ FVisualizer: IAstVisualizer;
+ function AddLabel(const Txt: String): TLabel;
procedure SetBackgroundColor(const Value: TAlphaColor);
procedure SetBorderColor(const Value: TAlphaColor);
procedure SetBorderWidth(const Value: Single);
@@ -39,9 +160,17 @@ type
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override;
procedure MouseMove(Shift: TShiftState; X, Y: Single); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override;
+ property Visualizer: IAstVisualizer read FVisualizer;
+ procedure SetupNode; virtual;
public
- constructor Create(AOwner: TComponent); override;
+ constructor Create(const AVisualizer: IAstVisualizer); reintroduce;
destructor Destroy; override;
+
+ procedure AfterConstruction; override;
+
+ // Creates an AST from the visualization
+ function CreateAst: IAstNode; virtual;
+
published
// Custom border properties
property BorderColor: TAlphaColor read FBorderColor write SetBorderColor;
@@ -60,9 +189,6 @@ type
property DragMode default TDragMode.dmManual;
property Enabled;
property Height;
- property HelpContext;
- property HelpKeyword;
- property HelpType;
property Hint;
property HitTest default True;
property Locked;
@@ -75,7 +201,6 @@ type
property RotationCenter;
property Scale;
property Size;
- property StyleLookup;
property Visible;
property Width;
property OnClick;
@@ -88,13 +213,684 @@ type
property OnMouseLeave;
end;
+ TAuraConstantNode = class(TAuraNode)
+ private
+ FNode: IConstantNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IConstantNode);
+
+ function CreateAst: IAstNode; override;
+
+ property Node: IConstantNode read FNode;
+ end;
+
+ TAuraIdentifierNode = class(TAuraNode)
+ private
+ FNode: IIdentifierNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IIdentifierNode);
+ function CreateAst: IAstNode; override;
+
+ property Node: IIdentifierNode read FNode;
+ end;
+
+ TAuraBinaryExpressionNode = class(TAuraNode)
+ private
+ FNode: IBinaryExpressionNode;
+ function GetLeftNode: TAuraNode;
+ function GetRightNode: TAuraNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IBinaryExpressionNode);
+ function CreateAst: IAstNode; override;
+
+ property LeftNode: TAuraNode read GetLeftNode;
+ property RightNode: TAuraNode read GetRightNode;
+
+ property Node: IBinaryExpressionNode read FNode;
+ end;
+
+ TAuraBlockExpressionNode = class(TAuraNode)
+ private
+ FNode: IBlockExpressionNode;
+ FChildNodes: TList; // To store children for CreateAst
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IBlockExpressionNode);
+ destructor Destroy; override;
+ function CreateAst: IAstNode; override;
+ property Node: IBlockExpressionNode read FNode;
+ end;
+
+ TAuraUnaryExpressionNode = class(TAuraNode)
+ private
+ FNode: IUnaryExpressionNode;
+ FChildNode: TAuraNode; // Stores the single child
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IUnaryExpressionNode);
+ function CreateAst: IAstNode; override;
+ property Node: IUnaryExpressionNode read FNode;
+ end;
+
+ TAuraIfExpressionNode = class(TAuraNode)
+ private
+ FNode: IIfExpressionNode;
+ FConditionNode: TAuraNode;
+ FThenNode: TAuraNode;
+ FElseNode: TAuraNode; // Can be nil
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IIfExpressionNode);
+ function CreateAst: IAstNode; override;
+ property Node: IIfExpressionNode read FNode;
+ end;
+
+ TAuraTernaryExpressionNode = class(TAuraNode)
+ private
+ FNode: ITernaryExpressionNode;
+ FConditionNode: TAuraNode;
+ FThenNode: TAuraNode;
+ FElseNode: TAuraNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: ITernaryExpressionNode);
+ function CreateAst: IAstNode; override;
+ property Node: ITernaryExpressionNode read FNode;
+ end;
+
+ TAuraLambdaExpressionNode = class(TAuraNode)
+ private
+ FNode: ILambdaExpressionNode;
+ FBodyNode: TAuraNode;
+ FParamLabels: TList; // To store param labels
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: ILambdaExpressionNode);
+ destructor Destroy; override;
+ function CreateAst: IAstNode; override;
+ property Node: ILambdaExpressionNode read FNode;
+ end;
+
+ TAuraFunctionCallNode = class(TAuraNode)
+ private
+ FNode: IFunctionCallNode;
+ FCalleeNode: TAuraNode;
+ FArgumentNodes: TList;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IFunctionCallNode);
+ destructor Destroy; override;
+ function CreateAst: IAstNode; override;
+ property Node: IFunctionCallNode read FNode;
+ end;
+
+ TAuraMacroExpansionNode = class(TAuraNode)
+ private
+ FNode: IMacroExpansionNode;
+ FExpandedBodyNode: TAuraNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IMacroExpansionNode);
+ function CreateAst: IAstNode; override;
+ property Node: IMacroExpansionNode read FNode;
+ end;
+
+ TAuraRecurNode = class(TAuraNode)
+ private
+ FNode: IRecurNode;
+ FArgumentNodes: TList;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IRecurNode);
+ destructor Destroy; override;
+ function CreateAst: IAstNode; override;
+ property Node: IRecurNode read FNode;
+ end;
+
+ TAuraVariableDeclarationNode = class(TAuraNode)
+ private
+ FNode: IVariableDeclarationNode;
+ FInitializerNode: TAuraNode; // Can be nil
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IVariableDeclarationNode);
+ function CreateAst: IAstNode; override;
+ property Node: IVariableDeclarationNode read FNode;
+ end;
+
+ TAuraAssignmentNode = class(TAuraNode)
+ private
+ FNode: IAssignmentNode;
+ FValueNode: TAuraNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IAssignmentNode);
+ function CreateAst: IAstNode; override;
+ property Node: IAssignmentNode read FNode;
+ end;
+
+ TAuraMacroDefinitionNode = class(TAuraNode)
+ private
+ FNode: IMacroDefinitionNode;
+ FBodyNode: TAuraNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IMacroDefinitionNode);
+ function CreateAst: IAstNode; override;
+ property Node: IMacroDefinitionNode read FNode;
+ end;
+
+ TAuraQuasiquoteNode = class(TAuraNode)
+ private
+ FNode: IQuasiquoteNode;
+ FExpressionNode: TAuraNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IQuasiquoteNode);
+ function CreateAst: IAstNode; override;
+ property Node: IQuasiquoteNode read FNode;
+ end;
+
+ TAuraUnquoteNode = class(TAuraNode)
+ private
+ FNode: IUnquoteNode;
+ FExpressionNode: TAuraNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IUnquoteNode);
+ function CreateAst: IAstNode; override;
+ property Node: IUnquoteNode read FNode;
+ end;
+
+ TAuraUnquoteSplicingNode = class(TAuraNode)
+ private
+ FNode: IUnquoteSplicingNode;
+ FExpressionNode: TAuraNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IUnquoteSplicingNode);
+ function CreateAst: IAstNode; override;
+ property Node: IUnquoteSplicingNode read FNode;
+ end;
+
+ TAuraIndexerNode = class(TAuraNode)
+ private
+ FNode: IIndexerNode;
+ FBaseNode: TAuraNode;
+ FIndexNode: TAuraNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IIndexerNode);
+ function CreateAst: IAstNode; override;
+ property Node: IIndexerNode read FNode;
+ end;
+
+ TAuraMemberAccessNode = class(TAuraNode)
+ private
+ FNode: IMemberAccessNode;
+ FBaseNode: TAuraNode;
+ // FMemberNode is handled by a label, store Base only
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IMemberAccessNode);
+ function CreateAst: IAstNode; override;
+ property Node: IMemberAccessNode read FNode;
+ end;
+
+ TAuraCreateSeriesNode = class(TAuraNode)
+ private
+ FNode: ICreateSeriesNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: ICreateSeriesNode);
+ function CreateAst: IAstNode; override;
+ property Node: ICreateSeriesNode read FNode;
+ end;
+
+ TAuraAddSeriesItemNode = class(TAuraNode)
+ private
+ FNode: IAddSeriesItemNode;
+ FValueNode: TAuraNode;
+ FLookbackNode: TAuraNode; // Can be nil
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: IAddSeriesItemNode);
+ function CreateAst: IAstNode; override;
+ property Node: IAddSeriesItemNode read FNode;
+ end;
+
+ TAuraSeriesLengthNode = class(TAuraNode)
+ private
+ FNode: ISeriesLengthNode;
+ protected
+ procedure SetupNode; override;
+ public
+ constructor Create(const AVisualizer: IAstVisualizer; const ANode: ISeriesLengthNode);
+ function CreateAst: IAstNode; override;
+ property Node: ISeriesLengthNode read FNode;
+ end;
+
implementation
+{ TAstVisualizer }
+
+constructor TAstVisualizer.Create(AWorkspace: TAuraWorkspace; AParentControl: TControl; AExprDepth: Integer);
+begin
+ inherited Create;
+ FWorkspace := AWorkspace;
+ FParentControl := AParentControl;
+ FExprDepth := AExprDepth;
+end;
+
+destructor TAstVisualizer.Destroy;
+begin
+ inherited;
+end;
+
+// Calls Accept on the node and returns the resulting TAuraNode.
+function TAstVisualizer.CallAccept(const Node: IAstNode): TAuraNode;
+var
+ DataValue: TDataValue;
+begin
+ if not Assigned(Node) then
+ Exit(nil); // Handle nil input node gracefully
+
+ DataValue := Node.Accept(Self);
+
+ // Check if the result is actually a TAuraNode before casting
+ if DataValue.Kind = TDataValueKind.vkGeneric then
+ begin
+ // Assuming the visitor correctly returns TAuraNode wrapped in TDataValue.
+ Result := DataValue.AsGeneric;
+ end
+ else
+ begin
+ Result := nil;
+ end;
+end;
+
+function TAstVisualizer.Clone(ParentControl: TControl; ExprDepth: Integer): IAstVisualizer;
+begin
+ Result := TAstVisualizer.Create(FWorkspace, ParentControl, ExprDepth);
+end;
+
+function TAstVisualizer.GetExprDepth: Integer;
+begin
+ Result := FExprDepth;
+end;
+
+function TAstVisualizer.GetParentControl: TControl;
+begin
+ Result := FParentControl;
+end;
+
+function TAstVisualizer.GetWorkspace: TAuraWorkspace;
+begin
+ Result := FWorkspace;
+end;
+
+procedure TAstVisualizer.SetExprDepth(const Value: Integer);
+begin
+ FExprDepth := Value;
+end;
+
+procedure TAstVisualizer.SetParentControl(const Value: TControl);
+begin
+ FParentControl := Value;
+end;
+
+function TAstVisualizer.VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraAddSeriesItemNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitAssignment(const Node: IAssignmentNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraAssignmentNode.Create(Self, Node));
+end;
+
+// --- Visitor Implementations ---
+
+function TAstVisualizer.VisitConstant(const Node: IConstantNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraConstantNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraIdentifierNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraBinaryExpressionNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraBlockExpressionNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraCreateSeriesNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraFunctionCallNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraUnaryExpressionNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitIfExpression(const Node: IIfExpressionNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraIfExpressionNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitIndexer(const Node: IIndexerNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraIndexerNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraLambdaExpressionNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraMacroDefinitionNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraMacroExpansionNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitMemberAccess(const Node: IMemberAccessNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraMemberAccessNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraQuasiquoteNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitRecurNode(const Node: IRecurNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraRecurNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraSeriesLengthNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraTernaryExpressionNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitUnquote(const Node: IUnquoteNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraUnquoteNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraUnquoteSplicingNode.Create(Self, Node));
+end;
+
+function TAstVisualizer.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
+begin
+ Result := TDataValue.FromGeneric(TAuraVariableDeclarationNode.Create(Self, Node));
+end;
+
+{ TAutoFitControl }
+
+constructor TAutoFitControl.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ HitTest := True;
+ FOrientation := TLayoutOrientation.loHorizontal;
+ FAlignment := TLayoutAlignment.laCenter; // Default alignment
+end;
+
+procedure TAutoFitControl.SetAlignment(const Value: TLayoutAlignment);
+begin
+ if FAlignment <> Value then
+ begin
+ FAlignment := Value;
+ RecalcOwnSize; // Re-layout on alignment change
+ end;
+end;
+
+procedure TAutoFitControl.SetOrientation(const Value: TLayoutOrientation);
+begin
+ if FOrientation <> Value then
+ begin
+ FOrientation := Value;
+ RecalcOwnSize; // Recalculate layout when orientation changes
+ end;
+end;
+
+procedure TAutoFitControl.RecalcOwnSize;
+var
+ I: Integer;
+ Child: TControl;
+ ChildrenToLayout: TList; // Still used to filter relevant children
+ CurrentX, CurrentY: Single;
+ RequiredWidth, RequiredHeight: Single;
+ ChildWidthWithMargins, ChildHeightWithMargins: Single;
+ HasVisibleChild: Boolean;
+begin
+ if FUpdatingOwnSize then
+ Exit;
+ if IsUpdating then
+ begin
+ FNeedRecalcSize := True;
+ Exit;
+ end;
+
+ FUpdatingOwnSize := True;
+ ChildrenToLayout := nil;
+ try
+ RequiredWidth := Padding.Left + Padding.Right;
+ RequiredHeight := Padding.Top + Padding.Bottom;
+ CurrentX := Padding.Left;
+ CurrentY := Padding.Top;
+ HasVisibleChild := False;
+
+ // Collect relevant children
+ ChildrenToLayout := TList.Create;
+ for I := 0 to ChildrenCount - 1 do
+ begin
+ if Children[I] is TControl then
+ begin
+ Child := TControl(Children[I]);
+ if Child.Visible and (Child.Align = TAlignLayout.None) then
+ begin
+ ChildrenToLayout.Add(Child);
+ HasVisibleChild := True;
+ end;
+ end;
+ end;
+
+ if HasVisibleChild then
+ begin
+ // Perform layout based on orientation
+ if FOrientation = TLayoutOrientation.loVertical then
+ begin
+ // Pass 1: Calculate total height and max width. Set Y pos.
+ for Child in ChildrenToLayout do
+ begin
+ // Store Y position
+ Child.Position.Y := CurrentY + Child.Margins.Top;
+ CurrentY := Child.Position.Y + Child.Height + Child.Margins.Bottom;
+
+ // Calculate max width
+ ChildWidthWithMargins := Padding.Left + Child.Margins.Left + Child.Width + Child.Margins.Right + Padding.Right;
+ RequiredWidth := System.Math.Max(RequiredWidth, ChildWidthWithMargins);
+ end;
+ RequiredHeight := CurrentY + Padding.Bottom;
+
+ // Pass 2: Align children horizontally based on FAlignment
+ if FAlignment = TLayoutAlignment.laFlush then
+ begin
+ // Flush (left-aligned)
+ for Child in ChildrenToLayout do
+ begin
+ Child.Position.X := Padding.Left + Child.Margins.Left;
+ end;
+ end
+ else
+ begin
+ // Center-aligned
+ var contentWidth := RequiredWidth - Padding.Left - Padding.Right;
+ for Child in ChildrenToLayout do
+ begin
+ var childTotalWidth := Child.Width + Child.Margins.Left + Child.Margins.Right;
+ var childX := Padding.Left + ((contentWidth - childTotalWidth) / 2) + Child.Margins.Left;
+ Child.Position.X := childX;
+ end;
+ end;
+ end
+ else // loHorizontal
+ begin
+ // Pass 1: Calculate total width and max height. Set X pos.
+ for Child in ChildrenToLayout do
+ begin
+ // Store X position
+ Child.Position.X := CurrentX + Child.Margins.Left;
+ CurrentX := Child.Position.X + Child.Width + Child.Margins.Right;
+
+ // Calculate max height
+ ChildHeightWithMargins := Padding.Top + Child.Margins.Top + Child.Height + Child.Margins.Bottom + Padding.Bottom;
+ RequiredHeight := System.Math.Max(RequiredHeight, ChildHeightWithMargins);
+ end;
+ RequiredWidth := CurrentX + Padding.Right;
+
+ // Pass 2: Align children vertically based on FAlignment
+ if FAlignment = TLayoutAlignment.laFlush then
+ begin
+ // Flush (top-aligned)
+ for Child in ChildrenToLayout do
+ begin
+ Child.Position.Y := Padding.Top + Child.Margins.Top;
+ end;
+ end
+ else
+ begin
+ // Center-aligned
+ var contentHeight := RequiredHeight - Padding.Top - Padding.Bottom;
+ for Child in ChildrenToLayout do
+ begin
+ var childTotalHeight := Child.Height + Child.Margins.Top + Child.Margins.Bottom;
+ var childY := Padding.Top + ((contentHeight - childTotalHeight) / 2) + Child.Margins.Top;
+ Child.Position.Y := childY;
+ end;
+ end;
+ end;
+ end
+ else
+ begin
+ RequiredWidth := Padding.Left + Padding.Right;
+ RequiredHeight := Padding.Top + Padding.Bottom;
+ end;
+
+ RequiredWidth := System.Math.Max(0, RequiredWidth);
+ RequiredHeight := System.Math.Max(0, RequiredHeight);
+
+ if not SameValue(RequiredWidth, Width, TEpsilon.Position) or not SameValue(RequiredHeight, Height, TEpsilon.Position) then
+ begin
+ FSize.SetSizeWithoutNotification(TSizeF.Create(RequiredWidth, RequiredHeight));
+ HandleSizeChanged;
+ end;
+
+ finally
+ ChildrenToLayout.Free;
+ FUpdatingOwnSize := False;
+ end;
+end;
+
+procedure TAutoFitControl.Loaded;
+begin
+ inherited Loaded;
+ // Perform initial size calculation after all children are loaded
+ RecalcOwnSize;
+end;
+
+procedure TAutoFitControl.ChangeChildren;
+begin
+ inherited ChangeChildren;
+ // Recalculate size when children are added or removed
+ RecalcOwnSize;
+end;
+
+procedure TAutoFitControl.PaddingChanged;
+begin
+ inherited PaddingChanged;
+ // Recalculate size when padding changes
+ RecalcOwnSize;
+end;
+
+procedure TAutoFitControl.ParentContentChanged;
+begin
+ inherited ParentContentChanged;
+ // Recalculate size when a child signals a potential layout change
+ RecalcOwnSize;
+end;
+
+procedure TAutoFitControl.DoEndUpdate;
+begin
+ inherited;
+ // If a recalc was deferred during BeginUpdate/EndUpdate, do it now
+ if FNeedRecalcSize then
+ begin
+ FNeedRecalcSize := False;
+ RecalcOwnSize;
+ end;
+end;
+
{ TAuraNode }
-constructor TAuraNode.Create(AOwner: TComponent);
+constructor TAuraNode.Create(const AVisualizer: IAstVisualizer);
begin
- inherited Create(AOwner);
+ inherited Create(AVisualizer.Workspace);
+
+ Parent := AVisualizer.ParentControl;
+
+ FVisualizer := AVisualizer.Clone(Self, AVisualizer.ExprDepth);
+
FIsDragging := False;
// Default border settings
@@ -106,13 +902,27 @@ begin
// Default state for frameless mode
FFrameless := False;
- Width := 80;
- Height := 45;
+ // Set a default minimum size, will be adjusted later
+ Width := cMinNodeWidth;
+ Height := cMinNodeHeight;
// The panel must be able to receive mouse events.
HitTest := True; // Make sure HitTest is True to receive mouse events
// Clip children to the panel's bounds.
ClipChildren := True;
+
+ Margins.Left := 4;
+ Margins.Top := 4;
+ Margins.Right := 4;
+ Margins.Bottom := 4;
+ Padding.Left := 3;
+ Padding.Top := 3;
+ Padding.Right := 3;
+ Padding.Bottom := 3;
+
+ var cn: cardinal := $ea - (7 * FVisualizer.ExprDepth);
+ var c: cardinal := $ff000000 or (cn shl 16) or (cn shl 8) or cn;
+ BackgroundColor := c;
end;
destructor TAuraNode.Destroy;
@@ -120,6 +930,37 @@ begin
inherited;
end;
+function TAuraNode.AddLabel(const Txt: String): TLabel;
+begin
+ Result := TLabel.Create(Self); // Owner is the node itself
+ Result.Parent := Self;
+
+ Result.Position.Point := TPoint.Create(cNodePadding, cNodePadding);
+ Result.Margins.Left := cNodePadding;
+ Result.Margins.Right := cNodePadding;
+ Result.Margins.Top := cTitleTopPadding;
+ Result.Margins.Bottom := cTitleBottomPadding;
+ Result.WordWrap := false;
+ Result.AutoSize := True; // Let label determine its own size initially (do NOT use Align, because it will override AutoSize)
+ Result.HitTest := False; // Title label should not intercept clicks intended for the node
+
+ Result.StyledSettings := Result.StyledSettings - [TStyledSetting.Style]; // Tell FMX not to manage Font.Style via styles
+
+ Result.Text := Txt;
+ Result.ApplyStyleLookup;
+end;
+
+procedure TAuraNode.AfterConstruction;
+begin
+ inherited;
+ SetupNode;
+end;
+
+function TAuraNode.CreateAst: IAstNode;
+begin
+ Result := TAst.Block([]);
+end;
+
procedure TAuraNode.Paint;
var
rect: TRectF;
@@ -260,4 +1101,987 @@ begin
Repaint;
end;
+procedure TAuraNode.SetupNode;
+begin
+
+end;
+
+{ TAuraConstantNode }
+
+constructor TAuraConstantNode.Create(const AVisualizer: IAstVisualizer; const ANode: IConstantNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraConstantNode.CreateAst: IAstNode;
+begin
+ Result := FNode;
+end;
+
+procedure TAuraConstantNode.SetupNode;
+var
+ valueStr: string;
+ isConcise: Boolean;
+begin
+ BeginUpdate;
+ try
+ valueStr := FNode.Value.ToString;
+ // Check if it's a number or a single-line text and not excessively long
+ isConcise := ((FNode.Value.Kind = TDataValueKind.vkScalar) or (Pos(sLineBreak, valueStr) = 0)) and (Length(valueStr) < 40);
+
+ if isConcise then
+ begin
+ // Display value directly in a centered label, frameless node
+ Frameless := true;
+ AddLabel(valueStr);
+ end
+ else
+ begin
+ // Use standard framed node with Title label + Value label
+ Frameless := False;
+ Orientation := loVertical;
+
+ var titleLabel := AddLabel('Const');
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+
+ // Value Label
+ var valueLabel := AddLabel(valueStr);
+ valueLabel.AutoSize := False; // ***Important: Disable AutoSize when Align=Client***
+ valueLabel.WordWrap := True; // Allow wrapping for long text
+ end;
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraIdentifierNode }
+
+constructor TAuraIdentifierNode.Create(const AVisualizer: IAstVisualizer; const ANode: IIdentifierNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraIdentifierNode.CreateAst: IAstNode;
+begin
+ Result := TAst.Identifier(FNode.Name);
+end;
+
+procedure TAuraIdentifierNode.SetupNode;
+begin
+ BeginUpdate;
+ try
+ Frameless := true; // Identifiers are frameless
+ AddLabel(FNode.Name); // Add label with the identifier name
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraBinaryExpressionNode }
+
+constructor TAuraBinaryExpressionNode.Create(const AVisualizer: IAstVisualizer; const ANode: IBinaryExpressionNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraBinaryExpressionNode.CreateAst: IAstNode;
+begin
+ Result := TAst.BinaryExpr(LeftNode.CreateAst, FNode.Operator, RightNode.CreateAst);
+end;
+
+function TAuraBinaryExpressionNode.GetLeftNode: TAuraNode;
+begin
+ Result := Children[0] as TAuraNode;
+end;
+
+function TAuraBinaryExpressionNode.GetRightNode: TAuraNode;
+begin
+ Result := Children[2] as TAuraNode;
+end;
+
+procedure TAuraBinaryExpressionNode.SetupNode;
+begin
+ var visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := true; // Generally make binary expressions frameless containers
+ Orientation := loHorizontal;
+
+ visu.CallAccept(FNode.Left);
+
+ // 2. Operator Label
+ AddLabel(FNode.Operator.ToString);
+
+ // 3. RightNode Expression Node (Visited Recursively)
+ visu.CallAccept(FNode.Right);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraBlockExpressionNode }
+
+constructor TAuraBlockExpressionNode.Create(const AVisualizer: IAstVisualizer; const ANode: IBlockExpressionNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+ FChildNodes := TList.Create;
+end;
+
+destructor TAuraBlockExpressionNode.Destroy;
+begin
+ FChildNodes.Free;
+ inherited Destroy;
+end;
+
+function TAuraBlockExpressionNode.CreateAst: IAstNode;
+var
+ exprs: TArray;
+ childNode: TAuraNode;
+ i: Integer;
+begin
+ SetLength(exprs, FChildNodes.Count);
+ for i := 0 to FChildNodes.Count - 1 do
+ begin
+ childNode := FChildNodes[i];
+ if Assigned(childNode) then
+ exprs[i] := childNode.CreateAst
+ else
+ exprs[i] := TAst.Constant(TDataValue.Void); // Or handle error
+ end;
+ Result := TAst.Block(exprs);
+end;
+
+procedure TAuraBlockExpressionNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ childNode: TAuraNode;
+ expr: IAstNode;
+ titleLabel: TLabel;
+ i: Integer;
+ returnContainer: TAutoFitControl;
+ visuReturn: IAstVisualizer;
+begin
+ // This visualizer parents children directly to Self
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := true;
+ Orientation := loVertical;
+ Alignment := laFlush; // Align all child rows to the left
+
+ for i := 0 to High(FNode.Expressions) do
+ begin
+ expr := FNode.Expressions[i];
+
+ if i = High(FNode.Expressions) then
+ begin
+ // Last expression: create a horizontal container for "return [expr]"
+ returnContainer := TAutoFitControl.Create(Self);
+ returnContainer.Parent := Self; // Parent is the main block node
+ returnContainer.Orientation := loHorizontal;
+ returnContainer.Alignment := laCenter; // Center "return" label vertically next to the expression
+ returnContainer.HitTest := False; // Pass clicks through
+
+ // Add "return" label to the container
+ titleLabel := AddLabel('return'); // Use AddLabel from TAuraNode (Self)
+ titleLabel.Parent := returnContainer; // Set parent to the new container
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+
+ // Create a new visualizer targeting this container
+ visuReturn := FVisualizer.Clone(returnContainer, FVisualizer.ExprDepth + 1);
+
+ // Add the expression node to the container
+ childNode := visuReturn.CallAccept(expr);
+ FChildNodes.Add(childNode); // Store for CreateAst
+ end
+ else
+ begin
+ // Not the last expression, add directly to Self
+ childNode := visu.CallAccept(expr);
+ FChildNodes.Add(childNode); // Store for CreateAst
+ end;
+ end;
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraUnaryExpressionNode }
+
+constructor TAuraUnaryExpressionNode.Create(const AVisualizer: IAstVisualizer; const ANode: IUnaryExpressionNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraUnaryExpressionNode.CreateAst: IAstNode;
+begin
+ Result := TAst.UnaryExpr(FNode.Operator, FChildNode.CreateAst);
+end;
+
+procedure TAuraUnaryExpressionNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ titleLabel: TLabel;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ // Vertical layout, framed
+ Frameless := False;
+ Orientation := loVertical;
+
+ // Title
+ titleLabel := AddLabel('Unary Op: ' + FNode.Operator.ToString);
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+
+ // Child
+ FChildNode := visu.CallAccept(FNode.Right);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraIfExpressionNode }
+
+constructor TAuraIfExpressionNode.Create(const AVisualizer: IAstVisualizer; const ANode: IIfExpressionNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+ FElseNode := nil;
+end;
+
+function TAuraIfExpressionNode.CreateAst: IAstNode;
+var
+ elseAst: IAstNode;
+begin
+ if Assigned(FElseNode) then
+ elseAst := FElseNode.CreateAst
+ else
+ elseAst := nil;
+
+ Result := TAst.IfExpr(FConditionNode.CreateAst, FThenNode.CreateAst, elseAst);
+end;
+
+procedure TAuraIfExpressionNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ titleLabel: TLabel;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := False;
+ Orientation := loVertical;
+
+ titleLabel := AddLabel('if');
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+
+ // Add children
+ FConditionNode := visu.CallAccept(FNode.Condition);
+ FThenNode := visu.CallAccept(FNode.ThenBranch);
+ if Assigned(FNode.ElseBranch) then
+ FElseNode := visu.CallAccept(FNode.ElseBranch);
+
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraTernaryExpressionNode }
+
+constructor TAuraTernaryExpressionNode.Create(const AVisualizer: IAstVisualizer; const ANode: ITernaryExpressionNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraTernaryExpressionNode.CreateAst: IAstNode;
+begin
+ Result := TAst.TernaryExpr(FConditionNode.CreateAst, FThenNode.CreateAst, FElseNode.CreateAst);
+end;
+
+procedure TAuraTernaryExpressionNode.SetupNode;
+var
+ visu: IAstVisualizer;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := True; // Horizontal layout
+ Orientation := loHorizontal;
+
+ FConditionNode := visu.CallAccept(FNode.Condition);
+ AddLabel('?');
+ FThenNode := visu.CallAccept(FNode.ThenBranch);
+ AddLabel(':');
+ FElseNode := visu.CallAccept(FNode.ElseBranch);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraLambdaExpressionNode }
+
+constructor TAuraLambdaExpressionNode.Create(const AVisualizer: IAstVisualizer; const ANode: ILambdaExpressionNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+ FParamLabels := TList.Create;
+end;
+
+destructor TAuraLambdaExpressionNode.Destroy;
+begin
+ FParamLabels.Free;
+ inherited Destroy;
+end;
+
+function TAuraLambdaExpressionNode.CreateAst: IAstNode;
+var
+ params: TArray;
+ i: Integer;
+begin
+ // Re-use FNode.Parameters which is the source of truth
+ SetLength(params, Length(FNode.Parameters));
+ for i := 0 to High(FNode.Parameters) do
+ params[i] := TAst.Identifier(FNode.Parameters[i].Name);
+
+ Result := TAst.LambdaExpr(params, FBodyNode.CreateAst);
+end;
+
+procedure TAuraLambdaExpressionNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ titleContainer: TAutoFitControl;
+ paramLabel: TLabel;
+ i: Integer;
+begin
+ visu := FVisualizer.Clone(Self, 0);
+
+ BeginUpdate;
+ try
+ Frameless := False;
+ Orientation := loVertical; // Main node is vertical
+ Alignment := laFlush;
+ BackgroundColor := $090000ff;
+
+ // Create a horizontal container for the title/params
+ titleContainer := TAutoFitControl.Create(Self);
+ titleContainer.Parent := Self;
+ titleContainer.Orientation := loHorizontal;
+ titleContainer.HitTest := False; // Pass clicks to parent
+
+ // 1. Lambda Symbol Label (Title)
+ paramLabel := AddLabel(WideChar($03BB)); // Lambda
+ paramLabel.Parent := titleContainer; // Add to title container
+ paramLabel.Font.Style := paramLabel.Font.Style + [TFontStyle.fsBold];
+
+ // 2. Add Parameters
+ paramLabel := AddLabel('(');
+ paramLabel.Parent := titleContainer;
+ FParamLabels.Add(paramLabel);
+
+ for i := 0 to High(FNode.Parameters) do
+ begin
+ paramLabel := AddLabel(FNode.Parameters[i].Name);
+ paramLabel.Parent := titleContainer;
+ FParamLabels.Add(paramLabel);
+
+ if i < High(FNode.Parameters) then
+ begin
+ paramLabel := AddLabel(',');
+ paramLabel.Parent := titleContainer;
+ FParamLabels.Add(paramLabel);
+ end;
+ end;
+
+ paramLabel := AddLabel(')');
+ paramLabel.Parent := titleContainer;
+ FParamLabels.Add(paramLabel);
+
+ // 3. Body
+ FBodyNode := visu.CallAccept(FNode.Body);
+ FBodyNode.Frameless := false;
+
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraFunctionCallNode }
+
+constructor TAuraFunctionCallNode.Create(const AVisualizer: IAstVisualizer; const ANode: IFunctionCallNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+ FArgumentNodes := TList.Create;
+end;
+
+destructor TAuraFunctionCallNode.Destroy;
+begin
+ FArgumentNodes.Free;
+ inherited Destroy;
+end;
+
+function TAuraFunctionCallNode.CreateAst: IAstNode;
+var
+ args: TArray;
+ i: Integer;
+begin
+ SetLength(args, FArgumentNodes.Count);
+ for i := 0 to FArgumentNodes.Count - 1 do
+ args[i] := FArgumentNodes[i].CreateAst;
+
+ Result := TAst.FunctionCall(FCalleeNode.CreateAst, args);
+end;
+
+procedure TAuraFunctionCallNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ i: Integer;
+ argNode: TAuraNode;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := True; // Horizontal layout
+ Orientation := loHorizontal;
+
+ var callLabel := AddLabel('call ');
+ callLabel.Font.Style := callLabel.Font.Style + [TFontStyle.fsBold];
+
+ // Callee
+ FCalleeNode := visu.CallAccept(FNode.Callee);
+
+ // Arguments
+ if Length(FNode.Arguments) > 0 then
+ begin
+ AddLabel('(');
+
+ for i := 0 to High(FNode.Arguments) do
+ begin
+ argNode := visu.CallAccept(FNode.Arguments[i]);
+ FArgumentNodes.Add(argNode);
+
+ if i < High(FNode.Arguments) then
+ AddLabel(',');
+ end;
+
+ AddLabel(')');
+ end;
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraMacroExpansionNode }
+
+constructor TAuraMacroExpansionNode.Create(const AVisualizer: IAstVisualizer; const ANode: IMacroExpansionNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraMacroExpansionNode.CreateAst: IAstNode;
+begin
+ // Re-create the node using the original FNode (which is an IFunctionCallNode)
+ // and the CreateAst of the expanded body.
+ Result := TAst.MacroExpansionNode(FNode, FExpandedBodyNode.CreateAst);
+end;
+
+procedure TAuraMacroExpansionNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ titleLabel: TLabel;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := False;
+ Orientation := loVertical;
+
+ titleLabel := AddLabel('Macro Expansion');
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+
+ FExpandedBodyNode := visu.CallAccept(FNode.ExpandedBody);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraRecurNode }
+
+constructor TAuraRecurNode.Create(const AVisualizer: IAstVisualizer; const ANode: IRecurNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+ FArgumentNodes := TList.Create;
+end;
+
+destructor TAuraRecurNode.Destroy;
+begin
+ FArgumentNodes.Free;
+ inherited Destroy;
+end;
+
+function TAuraRecurNode.CreateAst: IAstNode;
+var
+ args: TArray;
+ i: Integer;
+begin
+ SetLength(args, FArgumentNodes.Count);
+ for i := 0 to FArgumentNodes.Count - 1 do
+ args[i] := FArgumentNodes[i].CreateAst;
+
+ Result := TAst.Recur(args);
+end;
+
+procedure TAuraRecurNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ i: Integer;
+ argNode: TAuraNode;
+ titleLabel: TLabel;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := True; // Horizontal layout
+ Orientation := loHorizontal;
+
+ // 1. 'recur' keyword
+ titleLabel := AddLabel(WideChar($03BB));
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+
+ // 2. Arguments
+ AddLabel('(');
+
+ for i := 0 to High(FNode.Arguments) do
+ begin
+ argNode := visu.CallAccept(FNode.Arguments[i]);
+ FArgumentNodes.Add(argNode);
+
+ if i < High(FNode.Arguments) then
+ AddLabel(',');
+ end;
+
+ AddLabel(')');
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraVariableDeclarationNode }
+
+constructor TAuraVariableDeclarationNode.Create(const AVisualizer: IAstVisualizer; const ANode: IVariableDeclarationNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+ FInitializerNode := nil;
+end;
+
+function TAuraVariableDeclarationNode.CreateAst: IAstNode;
+var
+ initAst: IAstNode;
+begin
+ if Assigned(FInitializerNode) then
+ initAst := FInitializerNode.CreateAst
+ else
+ initAst := nil;
+
+ // Re-create the identifier node from the original FNode
+ Result := TAst.VarDecl(TAst.Identifier(FNode.Identifier.Name), initAst);
+end;
+
+procedure TAuraVariableDeclarationNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ varLabel: TLabel;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := True; // Horizontal layout
+ Orientation := loHorizontal;
+
+ varLabel := AddLabel('var');
+ varLabel.Font.Style := varLabel.Font.Style + [TFontStyle.fsBold];
+
+ // Add identifier name as a label
+ AddLabel(FNode.Identifier.Name);
+
+ if Assigned(FNode.Initializer) then
+ begin
+ AddLabel(':=');
+ FInitializerNode := visu.CallAccept(FNode.Initializer);
+ end;
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraAssignmentNode }
+
+constructor TAuraAssignmentNode.Create(const AVisualizer: IAstVisualizer; const ANode: IAssignmentNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraAssignmentNode.CreateAst: IAstNode;
+begin
+ // Re-create identifier from FNode
+ Result := TAst.Assign(TAst.Identifier(FNode.Identifier.Name), FValueNode.CreateAst);
+end;
+
+procedure TAuraAssignmentNode.SetupNode;
+var
+ visu: IAstVisualizer;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := True; // Horizontal layout
+ Orientation := loHorizontal;
+
+ // Add identifier name as a label
+ AddLabel(FNode.Identifier.Name);
+
+ AddLabel(':=');
+
+ FValueNode := visu.CallAccept(FNode.Value);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraMacroDefinitionNode }
+
+constructor TAuraMacroDefinitionNode.Create(const AVisualizer: IAstVisualizer; const ANode: IMacroDefinitionNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraMacroDefinitionNode.CreateAst: IAstNode;
+begin
+ // This assumes FBodyNode will create a valid IQuasiquoteNode.
+ Result :=
+ TAst.MacroDef(
+ TAst.Identifier(FNode.Name.Name),
+ FNode.Parameters, // Re-use original parameters
+ IQuasiquoteNode(FBodyNode.CreateAst)
+ );
+end;
+
+procedure TAuraMacroDefinitionNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ titleLabel: TLabel;
+ paramStr: string;
+ i: Integer;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+
+ BeginUpdate;
+ try
+ Frameless := False;
+ Orientation := loVertical;
+
+ // Build parameter string
+ paramStr := '';
+ for i := 0 to High(FNode.Parameters) do
+ begin
+ if i > 0 then
+ paramStr := paramStr + ', ';
+ paramStr := paramStr + FNode.Parameters[i].Name;
+ end;
+
+ titleLabel := AddLabel('Macro Def: ' + FNode.Name.Name + ' (' + paramStr + ')');
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+
+ FBodyNode := visu.CallAccept(FNode.Body);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraQuasiquoteNode }
+
+constructor TAuraQuasiquoteNode.Create(const AVisualizer: IAstVisualizer; const ANode: IQuasiquoteNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraQuasiquoteNode.CreateAst: IAstNode;
+begin
+ Result := TAst.Quasiquote(FExpressionNode.CreateAst);
+end;
+
+procedure TAuraQuasiquoteNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ titleLabel: TLabel;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+ BeginUpdate;
+ try
+ Frameless := False;
+ Orientation := loVertical;
+ titleLabel := AddLabel('Quasiquote');
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+ FExpressionNode := visu.CallAccept(FNode.Expression);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraUnquoteNode }
+
+constructor TAuraUnquoteNode.Create(const AVisualizer: IAstVisualizer; const ANode: IUnquoteNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraUnquoteNode.CreateAst: IAstNode;
+begin
+ Result := TAst.Unquote(FExpressionNode.CreateAst);
+end;
+
+procedure TAuraUnquoteNode.SetupNode;
+var
+ visu: IAstVisualizer;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+ BeginUpdate;
+ try
+ Frameless := True; // Horizontal layout
+ Orientation := loHorizontal;
+
+ var leftBracket := AddLabel('<');
+ leftBracket.Padding.Right := 0;
+ leftBracket.Margins.Right := 0;
+
+ visu.CallAccept(FNode.Expression);
+
+ var rightBracket := AddLabel('>');
+ rightBracket.Padding.Left := 0;
+ rightBracket.Margins.Left := 0;
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraUnquoteSplicingNode }
+
+constructor TAuraUnquoteSplicingNode.Create(const AVisualizer: IAstVisualizer; const ANode: IUnquoteSplicingNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraUnquoteSplicingNode.CreateAst: IAstNode;
+begin
+ Result := TAst.UnquoteSplicing(FExpressionNode.CreateAst);
+end;
+
+procedure TAuraUnquoteSplicingNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ titleLabel: TLabel;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+ BeginUpdate;
+ try
+ Frameless := False;
+ Orientation := loVertical;
+ titleLabel := AddLabel('Unquote-Splicing');
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+ FExpressionNode := visu.CallAccept(FNode.Expression);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraIndexerNode }
+
+constructor TAuraIndexerNode.Create(const AVisualizer: IAstVisualizer; const ANode: IIndexerNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraIndexerNode.CreateAst: IAstNode;
+begin
+ Result := TAst.Indexer(FBaseNode.CreateAst, FIndexNode.CreateAst);
+end;
+
+procedure TAuraIndexerNode.SetupNode;
+var
+ visu: IAstVisualizer;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+ BeginUpdate;
+ try
+ Frameless := True; // Horizontal layout: Base[Index]
+ Orientation := loHorizontal;
+
+ FBaseNode := visu.CallAccept(FNode.Base);
+ AddLabel('[');
+ FIndexNode := visu.CallAccept(FNode.Index);
+ AddLabel(']');
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraMemberAccessNode }
+
+constructor TAuraMemberAccessNode.Create(const AVisualizer: IAstVisualizer; const ANode: IMemberAccessNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraMemberAccessNode.CreateAst: IAstNode;
+begin
+ // Re-create identifier from FNode
+ Result := TAst.MemberAccess(FBaseNode.CreateAst, TAst.Identifier(FNode.Member.Name));
+end;
+
+procedure TAuraMemberAccessNode.SetupNode;
+var
+ visu: IAstVisualizer;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+ BeginUpdate;
+ try
+ Frameless := True; // Horizontal layout: Base.Member
+ Orientation := loHorizontal;
+
+ FBaseNode := visu.CallAccept(FNode.Base);
+ AddLabel('.');
+
+ // Add member name as a label
+ AddLabel(FNode.Member.Name);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraCreateSeriesNode }
+
+constructor TAuraCreateSeriesNode.Create(const AVisualizer: IAstVisualizer; const ANode: ICreateSeriesNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraCreateSeriesNode.CreateAst: IAstNode;
+begin
+ Result := TAst.CreateSeries(FNode.Definition);
+end;
+
+procedure TAuraCreateSeriesNode.SetupNode;
+var
+ titleLabel: TLabel;
+begin
+ BeginUpdate;
+ try
+ Frameless := False; // Leaf node, but framed
+ Orientation := loVertical;
+ titleLabel := AddLabel('Create Series: ' + FNode.Definition);
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraAddSeriesItemNode }
+
+constructor TAuraAddSeriesItemNode.Create(const AVisualizer: IAstVisualizer; const ANode: IAddSeriesItemNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+ FLookbackNode := nil;
+end;
+
+function TAuraAddSeriesItemNode.CreateAst: IAstNode;
+var
+ lookbackAst: IAstNode;
+begin
+ if Assigned(FLookbackNode) then
+ lookbackAst := FLookbackNode.CreateAst
+ else
+ lookbackAst := nil;
+
+ Result := TAst.AddSeriesItem(TAst.Identifier(FNode.Series.Name), FValueNode.CreateAst, lookbackAst);
+end;
+
+procedure TAuraAddSeriesItemNode.SetupNode;
+var
+ visu: IAstVisualizer;
+ titleLabel: TLabel;
+begin
+ visu := FVisualizer.Clone(Self, FVisualizer.ExprDepth + 1);
+ BeginUpdate;
+ try
+ Frameless := False;
+ Orientation := loVertical;
+
+ titleLabel := AddLabel('Add Item to: ' + FNode.Series.Name);
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+
+ FValueNode := visu.CallAccept(FNode.Value);
+ if Assigned(FNode.Lookback) then
+ FLookbackNode := visu.CallAccept(FNode.Lookback);
+ finally
+ EndUpdate;
+ end;
+end;
+
+{ TAuraSeriesLengthNode }
+
+constructor TAuraSeriesLengthNode.Create(const AVisualizer: IAstVisualizer; const ANode: ISeriesLengthNode);
+begin
+ inherited Create(AVisualizer);
+ FNode := ANode;
+end;
+
+function TAuraSeriesLengthNode.CreateAst: IAstNode;
+begin
+ Result := TAst.SeriesLength(TAst.Identifier(FNode.Series.Name));
+end;
+
+procedure TAuraSeriesLengthNode.SetupNode;
+var
+ titleLabel: TLabel;
+begin
+ BeginUpdate;
+ try
+ Frameless := False; // Leaf node, but framed
+ Orientation := loVertical;
+ titleLabel := AddLabel('Length of: ' + FNode.Series.Name);
+ titleLabel.Font.Style := titleLabel.Font.Style + [TFontStyle.fsBold];
+ finally
+ EndUpdate;
+ end;
+end;
+
end.
diff --git a/ASTPlayground/Myc.Fmx.AstEditor.Workspace.pas b/ASTPlayground/Myc.Fmx.AstEditor.Workspace.pas
index e9f818d..34026d5 100644
--- a/ASTPlayground/Myc.Fmx.AstEditor.Workspace.pas
+++ b/ASTPlayground/Myc.Fmx.AstEditor.Workspace.pas
@@ -91,7 +91,7 @@ implementation
uses
System.Math,
FMX.Platform,
- Myc.Fmx.AstVisualizer;
+ Myc.Fmx.AstEditor.Node;
{ TPinConnection }
@@ -111,7 +111,8 @@ end;
procedure TAuraWorkspace.Build(const RootNode: IAstNode; const Position: TPointF);
begin
- RootNode.Accept(TAstVisualizer.CreateVisitor(Self, Position));
+ var visu := TAstVisualizer.Create(Self, Self, 0) as IAstVisualizer;
+ visu.CallAccept(RootNode);
end;
procedure TAuraWorkspace.DoDeleteChildren;
diff --git a/ASTPlayground/Myc.Fmx.AstVisualizer.pas b/ASTPlayground/Myc.Fmx.AstVisualizer.pas
index 6b1f7bf..6c6d4fd 100644
--- a/ASTPlayground/Myc.Fmx.AstVisualizer.pas
+++ b/ASTPlayground/Myc.Fmx.AstVisualizer.pas
@@ -1,4 +1,4 @@
-unit Myc.Fmx.AstVisualizer;
+unit Myc.Fmx.AstVisualizer deprecated;
interface
@@ -25,14 +25,13 @@ uses
type
// Visits the AST and creates visual TAuraNode representations on a TAuraWorkspace.
- TAstVisualizer = class(TAstVisitor)
+ TAstVisualizer = class(TAstVisitor, IAstVisualizer)
private
- FWorkspace: TAuraWorkspace;
- FParentControl: TControl; // The current parent FMX control for newly created nodes
- FCurrentPos: TPointF; // Current position for the next node relative to FParentControl
- FNodeVerticalGap: Single; // Vertical gap between nodes
+ FCurrentPos: TPointF;
FExprDepth: Integer;
-
+ FWorkspace: TAuraWorkspace;
+ FNodeVerticalGap: Single;
+ FParentControl: TControl;
// Helper to create and initialize a TAuraNode for a given AST node.
function CreateNode(const Node: IAstNode): TAuraNode;
function AddLabel(const ParentNode: TAuraNode; const Txt: String): TLabel;
@@ -44,7 +43,12 @@ type
// Calls Accept on the node and returns the resulting TAuraNode.
function CallAccept(const Node: IAstNode): TAuraNode;
-
+ function GetCurrentPos: TPointF;
+ function GetExprDepth: Integer;
+ function GetParentControl: TControl;
+ procedure SetCurrentPos(const Value: TPointF);
+ procedure SetExprDepth(const Value: Integer);
+ procedure SetParentControl(const Value: TControl);
protected
// Visitor implementations for each AST node type.
function VisitConstant(const Node: IConstantNode): TDataValue; override;
@@ -71,10 +75,22 @@ type
function VisitRecurNode(const Node: IRecurNode): TDataValue; override;
public
- constructor Create(AWorkspace: TAuraWorkspace; AParentControl: TControl; const AStartPosition: TPointF);
+ constructor Create(
+ AWorkspace: TAuraWorkspace;
+ AParentControl: TControl;
+ const AStartPosition: TPointF;
+ ANodeVerticalGap: Single = 15;
+ AExprDepth: Integer = 0
+ );
destructor Destroy; override;
+ function Clone: IAstVisualizer;
+
class function CreateVisitor(AWorkspace: TAuraWorkspace; const StartPosition: TPointF): IAstVisitor;
+
+ property CurrentPos: TPointF read GetCurrentPos write SetCurrentPos;
+ property ExprDepth: Integer read GetExprDepth write SetExprDepth;
+ property ParentControl: TControl read GetParentControl write SetParentControl;
end;
implementation
@@ -89,24 +105,25 @@ uses
Myc.Fmx.AstEditor.Text;
const
- cNodePadding = 10; // Reduced padding
- cTitleTopPadding = 2;
- cTitleBottomPadding = 4;
cChildAreaTopPadding = 5;
cNodeVerticalGap = 10; // Reduced gap
- cMinNodeWidth = 10;
- cMinNodeHeight = 10;
{ TAstVisualizer }
-constructor TAstVisualizer.Create(AWorkspace: TAuraWorkspace; AParentControl: TControl; const AStartPosition: TPointF);
+constructor TAstVisualizer.Create(
+ AWorkspace: TAuraWorkspace;
+ AParentControl: TControl;
+ const AStartPosition: TPointF;
+ ANodeVerticalGap: Single = 15;
+ AExprDepth: Integer = 0
+);
begin
inherited Create;
FWorkspace := AWorkspace;
FParentControl := AParentControl;
FCurrentPos := AStartPosition;
- FNodeVerticalGap := 15; // Vertical gap between child nodes
- FExprDepth := 0;
+ FNodeVerticalGap := ANodeVerticalGap;
+ FExprDepth := AExprDepth;
end;
destructor TAstVisualizer.Destroy;
@@ -264,6 +281,26 @@ begin
end;
end;
+function TAstVisualizer.Clone: IAstVisualizer;
+begin
+ Result := TAstVisualizer.Create(FWorkspace, FParentControl, FCurrentPos, FNodeVerticalGap, FExprDepth);
+end;
+
+function TAstVisualizer.GetCurrentPos: TPointF;
+begin
+ Result := FCurrentPos;
+end;
+
+function TAstVisualizer.GetExprDepth: Integer;
+begin
+ Result := FExprDepth;
+end;
+
+function TAstVisualizer.GetParentControl: TControl;
+begin
+ Result := FParentControl;
+end;
+
// Generic processing logic for AST nodes with children. Returns the created TAuraNode.
function TAstVisualizer.ProcessStub(const ATitle: string; const ANode: IAstNode; const AChildren: TArray): TAuraNode;
var
@@ -308,157 +345,62 @@ begin
Result := auraNode; // Return the created node
end;
+procedure TAstVisualizer.SetCurrentPos(const Value: TPointF);
+begin
+ FCurrentPos := Value;
+end;
+
+procedure TAstVisualizer.SetExprDepth(const Value: Integer);
+begin
+ FExprDepth := Value;
+end;
+
+procedure TAstVisualizer.SetParentControl(const Value: TControl);
+begin
+ FParentControl := Value;
+end;
+
// --- Visitor Implementations ---
function TAstVisualizer.VisitConstant(const Node: IConstantNode): TDataValue;
-var
- auraNode: TAuraNode;
- valueStr: string;
- isConcise: Boolean;
begin
- valueStr := Node.Value.ToString;
- // Check if it's a number or a single-line text and not excessively long
- isConcise := ((Node.Value.Kind = TDataValueKind.vkScalar) or (Pos(sLineBreak, valueStr) = 0)) and (Length(valueStr) < 40);
+ var auraNode := TAuraConstantNode.CreateConstantNode(FWorkspace, Node, Self);
- auraNode := CreateNode(Node); // Create node without title
- auraNode.BeginUpdate;
- try
- if isConcise then
- begin
- // Display value directly in a centered label, frameless node
- auraNode.Frameless := true;
- AddLabel(auraNode, valueStr);
- end
- else
- begin
- // Use standard framed node with Title label + Value label
- auraNode.Frameless := False;
-
- // Title Label
- var titleLabelHeight := AddTitleLabel(auraNode, 'Constant');
-
- // Value Label
- var valueLabel := AddLabel(auraNode, valueStr);
- valueLabel.Position.Y := valueLabel.Position.Y + titleLabelHeight;
- valueLabel.AutoSize := False; // ***Important: Disable AutoSize when Align=Client***
- valueLabel.WordWrap := True; // Allow wrapping for long text
- end;
-
- AdjustParentNodeSize(auraNode, []); // Adjust based on labels' sizes
- finally
- auraNode.EndUpdate;
- end;
// Move current position down for the next sibling node
FCurrentPos.Y := FCurrentPos.Y + auraNode.Height + FNodeVerticalGap;
+
Result := TDataValue.FromGeneric(auraNode); // Return the created node
end;
function TAstVisualizer.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
var
- auraNode: TAuraNode;
+ auraNode: TAuraIdentifierNode; // Use specific type
begin
- // Leaf node, direct creation without ProcessStub
- auraNode := CreateNode(Node);
- auraNode.Frameless := True; // Make identifiers frameless like concise constants
- auraNode.BeginUpdate;
- try
- auraNode.Frameless := true;
- AddLabel(auraNode, Node.Name);
- AdjustParentNodeSize(auraNode, []); // Fallback just in case
- finally
- auraNode.EndUpdate;
- end;
+ // Create the specific node type using its factory
+ auraNode := TAuraIdentifierNode.CreateIdentifierNode(FWorkspace, Node, Self);
+
+ // Move current position down for the next sibling node
FCurrentPos.Y := FCurrentPos.Y + auraNode.Height + FNodeVerticalGap;
- Result := TDataValue.FromGeneric(auraNode); // Return the created node
+
+ Result := TDataValue.FromGeneric(auraNode); // Return as generic TAuraNode
end;
function TAstVisualizer.VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue;
var
- auraNode: TAuraNode;
- leftNode: TAuraNode; // Use TAuraNode directly
- operatorLabel: TLabel;
- rightNode: TAuraNode; // Use TAuraNode directly
- savedParent: TControl;
+ auraNode: TAuraBinaryExpressionNode; // Use specific type
savedPos: TPointF;
- currentX: Single; // Track horizontal position
- maxHeightInRow: Single; // Track max height for row alignment
- yPos: Single; // Y position for elements in this row
begin
- // Create the main node, frameless as it primarily serves as a container
- auraNode := CreateNode(Node);
- auraNode.BeginUpdate;
- inc(FExprDepth);
- try
- auraNode.Frameless := true;
+ // Store position before creating the node
+ savedPos := FCurrentPos;
- // Start position for children inside the node
- currentX := cNodePadding;
- yPos := cNodePadding; // Initial Y position
- maxHeightInRow := 0;
+ // Create the specific node type using its factory
+ auraNode := TAuraBinaryExpressionNode.CreateBinaryExpressionNode(FWorkspace, Node, Self);
- // 1. Left Expression Node (Visited Recursively)
- savedParent := FParentControl;
- savedPos := FCurrentPos; // Store original position for siblings
- FParentControl := auraNode; // Children are added to this node
- FCurrentPos := TPointF.Create(currentX, yPos); // Set position for the child node
+ // Move current position down for the next sibling node
+ // Use the position saved *before* creating this node, plus the node's final height
+ FCurrentPos.Y := savedPos.Y + auraNode.Height + FNodeVerticalGap;
- leftNode := CallAccept(Node.Left); // Use CallAccept and store result
-
- if Assigned(leftNode) then
- begin
- // Update currentX based on the right edge of the left control + gap
- currentX := leftNode.Position.X + leftNode.Width + leftNode.Margins.Right + cNodePadding;
- maxHeightInRow := Max(maxHeightInRow, leftNode.Height + leftNode.Margins.Top + leftNode.Margins.Bottom);
- end;
-
- // 2. Operator Label
- operatorLabel := AddLabel(auraNode, Node.Operator.ToString);
- operatorLabel.Position.Point := TPointF.Create(currentX, yPos); // Position next to left operand
- currentX := operatorLabel.Position.X + operatorLabel.Width + operatorLabel.Margins.Right + cNodePadding; // Update X pos
- maxHeightInRow := Max(maxHeightInRow, operatorLabel.Height + operatorLabel.Margins.Top + operatorLabel.Margins.Bottom);
-
- // 3. Right Expression Node (Visited Recursively)
- // FParentControl is already auraNode
- FCurrentPos := TPointF.Create(currentX, yPos); // Set position for the child node
-
- rightNode := CallAccept(Node.Right); // Use CallAccept and store result
-
- if Assigned(rightNode) then
- begin
- // Update currentX based on the right edge of the right control
- currentX := rightNode.Position.X + rightNode.Width + rightNode.Margins.Right;
- maxHeightInRow := Max(maxHeightInRow, rightNode.Height + rightNode.Margins.Top + rightNode.Margins.Bottom);
- end;
-
- FParentControl := savedParent; // Restore parent for siblings
- FCurrentPos := savedPos; // Restore position for siblings
-
- // --- Adjust parent size ---
- auraNode.Width := Max(cMinNodeWidth, currentX + cNodePadding); // Total width needed + right padding
- auraNode.Height := Max(cMinNodeHeight, maxHeightInRow + 2 * cNodePadding); // Max height + top/bottom padding
-
- // --- Optional Vertical Centering ---
- var centerOffsetY: Single := (auraNode.Height / 2);
- if Assigned(leftNode) then
- leftNode.Position.Y :=
- centerOffsetY - (leftNode.Height + leftNode.Margins.Top + leftNode.Margins.Bottom) / 2 + leftNode.Margins.Top;
- if Assigned(operatorLabel) then
- operatorLabel.Position.Y :=
- centerOffsetY
- - (operatorLabel.Height + operatorLabel.Margins.Top + operatorLabel.Margins.Bottom) / 2
- + operatorLabel.Margins.Top;
- if Assigned(rightNode) then
- rightNode.Position.Y :=
- centerOffsetY - (rightNode.Height + rightNode.Margins.Top + rightNode.Margins.Bottom) / 2 + rightNode.Margins.Top;
- // --- End Optional Vertical Centering ---
-
- finally
- dec(FExprDepth);
- auraNode.EndUpdate;
- end;
- // Move current position down for the next sibling node in the outer scope
- FCurrentPos.Y := savedPos.Y + auraNode.Height + FNodeVerticalGap; // Use savedPos.Y for vertical alignment with siblings
- Result := TDataValue.FromGeneric(auraNode); // Return the created node
+ Result := TDataValue.FromGeneric(auraNode); // Return as generic TAuraNode
end;
function TAstVisualizer.VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue;
diff --git a/Src/AST/Myc.Ast.pas b/Src/AST/Myc.Ast.pas
index 658ebe7..527c605 100644
--- a/Src/AST/Myc.Ast.pas
+++ b/Src/AST/Myc.Ast.pas
@@ -105,7 +105,7 @@ type
function GetOperator: TScalar.TBinaryOp;
function GetRight: IAstNode;
public
- constructor Create(ALeft: IAstNode; AOperator: TScalar.TBinaryOp; ARight: IAstNode);
+ constructor Create(const ALeft: IAstNode; AOperator: TScalar.TBinaryOp; const ARight: IAstNode);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
end;
@@ -369,7 +369,7 @@ end;
{ TBinaryExpressionNode }
-constructor TBinaryExpressionNode.Create(ALeft: IAstNode; AOperator: TScalar.TBinaryOp; ARight: IAstNode);
+constructor TBinaryExpressionNode.Create(const ALeft: IAstNode; AOperator: TScalar.TBinaryOp; const ARight: IAstNode);
begin
inherited Create;
FLeft := ALeft;
diff --git a/Src/Data/Myc.Data.Value.pas b/Src/Data/Myc.Data.Value.pas
index f7fc619..fca96e2 100644
--- a/Src/Data/Myc.Data.Value.pas
+++ b/Src/Data/Myc.Data.Value.pas
@@ -143,7 +143,8 @@ begin
if FKind <> vkGeneric then
raise EInvalidCast.Create('Cannot read value as generic of ' + String(PTypeInfo(TypeInfo(T)).Name) + '.');
{$ifdef DEBUG}
- if TVal(FInterface).TypeHandle <> TypeInfo(T) then
+ var val := TVal(FInterface);
+ if val.TypeHandle <> TypeInfo(T) then
raise EInvalidCast.Create('Generic type is not a ' + String(PTypeInfo(TypeInfo(T)).Name) + '.');
{$endif}
Result := TVal(FInterface).Value;