diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json
index b4e5cd8..e6957cc 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.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.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Text", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Text.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Compiler.TCO", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TCO.pas" }, { "name": "Myc.Ast.Compiler.Binder", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Binder.pas" }, { "name": "Myc.Ast.Compiler.Lowering", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Lowering.pas" }, { "name": "Myc.Ast.Compiler.TypeChecker", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TypeChecker.pas" }, { "name": "Myc.Ast.Compiler.Macros", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Macros.pas" }, { "name": "Myc.Ast.Compiler.Specializer", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Specializer.pas" }, { "name": "Myc.Ast.Environment", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Environment.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.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.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.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Text", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Fmx.AstEditor.Text.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Compiler.TCO", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TCO.pas" }, { "name": "Myc.Ast.Compiler.Binder", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Binder.pas" }, { "name": "Myc.Ast.Compiler.Lowering", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Lowering.pas" }, { "name": "Myc.Ast.Compiler.TypeChecker", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TypeChecker.pas" }, { "name": "Myc.Ast.Compiler.Macros", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Macros.pas" }, { "name": "Myc.Ast.Compiler.Specializer", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Specializer.pas" }, { "name": "Myc.Ast.Environment", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Environment.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Analysis.Purity", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Analysis.Purity.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 bc030d8..0e0365d 100644
--- a/ASTPlayground/ASTPlayground.dpr
+++ b/ASTPlayground/ASTPlayground.dpr
@@ -26,7 +26,8 @@ uses
Myc.Ast.Compiler.Macros in '..\Src\AST\Myc.Ast.Compiler.Macros.pas',
Myc.Ast.Compiler.Specializer in '..\Src\AST\Myc.Ast.Compiler.Specializer.pas',
Myc.Ast.Environment in '..\Src\AST\Myc.Ast.Environment.pas',
- Myc.Ast.Debugger in '..\Src\AST\Myc.Ast.Debugger.pas';
+ Myc.Ast.Debugger in '..\Src\AST\Myc.Ast.Debugger.pas',
+ Myc.Ast.Analysis.Purity in '..\Src\AST\Myc.Ast.Analysis.Purity.pas';
{$R *.res}
diff --git a/ASTPlayground/ASTPlayground.dproj b/ASTPlayground/ASTPlayground.dproj
index 541fa8b..7c8d3b7 100644
--- a/ASTPlayground/ASTPlayground.dproj
+++ b/ASTPlayground/ASTPlayground.dproj
@@ -157,6 +157,7 @@
+
Base
@@ -212,6 +213,12 @@
true
+
+
+ ASTPlayground.rsm
+ true
+
+
ASTPlayground.exe
diff --git a/ASTPlayground/MainForm.fmx b/ASTPlayground/MainForm.fmx
index b666098..ae7e376 100644
--- a/ASTPlayground/MainForm.fmx
+++ b/ASTPlayground/MainForm.fmx
@@ -197,7 +197,7 @@ object Form1: TForm1
'Expanded'
'Bound'
'Specialized')
- ItemIndex = 0
+ ItemIndex = 3
Position.X = 672.000000000000000000
Position.Y = 576.000000000000000000
Size.Width = 104.000000000000000000
diff --git a/ASTPlayground/MainForm.pas b/ASTPlayground/MainForm.pas
index fdad466..cf1d221 100644
--- a/ASTPlayground/MainForm.pas
+++ b/ASTPlayground/MainForm.pas
@@ -110,7 +110,7 @@ type
procedure RTLListViewChange(Sender: TObject);
private
FCurrUnboundAst: IAstNode;
- FCurrExec: TDataValue.TFunc;
+ FCurrExec: TCompiledFunction;
FEnvironment: TAstEnvironment;
FWorkspace: TAuraWorkspace;
FScriptUpdate: Boolean;
@@ -262,7 +262,7 @@ end;
function TForm1.ExecuteAst(const ANode: IAstNode): TDataValue;
begin
FCurrUnboundAst := ANode;
- FCurrExec := nil; // Clear previous
+ FCurrExec := Default(TCompiledFunction);
// 1. Set strategy based on UI
if DebugBox.IsChecked then
@@ -273,12 +273,21 @@ begin
try
// Wrap in Lambda to compile
var funcDef := TAst.LambdaExpr([], ANode);
- FCurrExec := FEnvironment.Compile(funcDef).Func;
- Result := FCurrExec([]);
+ FCurrExec := FEnvironment.Compile(funcDef);
+
+ if Assigned(FCurrExec.Func) then
+ begin
+ Memo1.Lines.Add(
+ Format('Compiled. Signature: %s, IsPure=%s', [FCurrExec.StaticType.ToString, BoolToStr(FCurrExec.IsPure, true)])
+ );
+ end;
+
+ Result := FCurrExec.Func([]);
except
on E: Exception do
begin
+ FCurrExec.Func := nil;
Memo1.Lines.Add('--- ERROR ---');
Memo1.Lines.Add(E.ClassName + ': ' + E.Message);
Result := TDataValue.Void;
@@ -645,7 +654,7 @@ begin
FCurrUnboundAst := converter.Deserialize(jsonObj);
// Run the full pipeline via environment
- FCurrExec := FEnvironment.Compile(FCurrUnboundAst).Func;
+ FCurrExec := FEnvironment.Compile(FCurrUnboundAst);
Memo1.Lines.Add('AST deserialized and bound successfully from JSON.');
Memo1.Lines.Add('You can now visualize it (Middle Mouse Click) or pretty-print it.');
@@ -655,7 +664,6 @@ begin
except
on E: Exception do
begin
- FCurrExec := nil;
Memo1.Lines.Add('Error deserializing AST from JSON:');
Memo1.Lines.Add(E.Message);
Memo1.Lines.Add('--- Original JSON ---');
@@ -675,7 +683,7 @@ var
begin
Memo1.Lines.Clear;
- if not Assigned(FCurrExec) then
+ if not Assigned(FCurrExec.Func) then
begin
Memo1.Lines.Add('No AST available to serialize. Please generate one first.');
exit;
@@ -703,7 +711,7 @@ begin
Memo1.Lines.Clear;
Memo1.Lines.Add('--- AST Dump ---');
- if not Assigned(FCurrExec) then
+ if not Assigned(FCurrExec.Func) then
begin
Memo1.Lines.Add('No *compiled* AST has been generated yet. Click a test button first.');
exit;
diff --git a/Src/AST/Myc.Ast.Analysis.Purity.pas b/Src/AST/Myc.Ast.Analysis.Purity.pas
new file mode 100644
index 0000000..41b12fe
--- /dev/null
+++ b/Src/AST/Myc.Ast.Analysis.Purity.pas
@@ -0,0 +1,250 @@
+unit Myc.Ast.Analysis.Purity;
+
+interface
+
+uses
+ System.SysUtils,
+ Myc.Data.Value,
+ Myc.Ast.Nodes,
+ Myc.Ast.Visitor,
+ Myc.Ast.Scope;
+
+type
+ ///
+ /// Analyzes an AST to determine if it is referentially transparent and free of side effects.
+ ///
+ TPurityAnalyzer = class(TAstVisitor)
+ protected
+ // Default behavior: Visit children. If all children return True, then True.
+ // However, we must explicitly define what is allowed.
+ function Accept(const Node: IAstNode): Boolean; override;
+
+ // --- Safe Leaves / Constructs ---
+ function VisitConstant(const Node: IConstantNode): Boolean; override;
+ function VisitKeyword(const Node: IKeywordNode): Boolean; override;
+ function VisitIfExpression(const Node: IIfExpressionNode): Boolean; override;
+ function VisitTernaryExpression(const Node: ITernaryExpressionNode): Boolean; override;
+ function VisitBlockExpression(const Node: IBlockExpressionNode): Boolean; override;
+ function VisitRecordLiteral(const Node: IRecordLiteralNode): Boolean; override;
+ function VisitVariableDeclaration(const Node: IVariableDeclarationNode): Boolean; override;
+ function VisitSeriesLength(const Node: ISeriesLengthNode): Boolean; override;
+
+ // --- Critical Checks ---
+ function VisitIdentifier(const Node: IIdentifierNode): Boolean; override;
+ function VisitFunctionCall(const Node: IFunctionCallNode): Boolean; override;
+ function VisitRecurNode(const Node: IRecurNode): Boolean; override;
+
+ // --- Forbidden Constructs (Side Effects / Unsafe) ---
+ function VisitAssignment(const Node: IAssignmentNode): Boolean; override;
+ function VisitAddSeriesItem(const Node: IAddSeriesItemNode): Boolean; override;
+
+ // Allocation is considered pure in this context (it creates a new value, doesn't mutate existing world)
+ function VisitCreateSeries(const Node: ICreateSeriesNode): Boolean; override;
+
+ function VisitIndexer(const Node: IIndexerNode): Boolean; override;
+ function VisitMemberAccess(const Node: IMemberAccessNode): Boolean; override;
+
+ // Ignored / Irrelevant for Runtime Purity (Compile-time constructs or Definitions)
+ function VisitLambdaExpression(const Node: ILambdaExpressionNode): Boolean; override;
+ function VisitMacroDefinition(const Node: IMacroDefinitionNode): Boolean; override;
+ function VisitQuasiquote(const Node: IQuasiquoteNode): Boolean; override;
+ function VisitUnquote(const Node: IUnquoteNode): Boolean; override;
+ function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): Boolean; override;
+ function VisitMacroExpansionNode(const Node: IMacroExpansionNode): Boolean; override;
+ function VisitNop(const Node: INopNode): Boolean; override;
+
+ public
+ class function IsPure(const RootNode: IAstNode): Boolean;
+ end;
+
+implementation
+
+{ TPurityAnalyzer }
+
+class function TPurityAnalyzer.IsPure(const RootNode: IAstNode): Boolean;
+begin
+ var analyzer := TPurityAnalyzer.Create;
+ try
+ Result := analyzer.Accept(RootNode);
+ finally
+ analyzer.Free;
+ end;
+end;
+
+function TPurityAnalyzer.Accept(const Node: IAstNode): Boolean;
+begin
+ // If a node is nil (e.g. optional else-branch), it's "nothing", which is pure.
+ if not Assigned(Node) then
+ exit(True);
+
+ // Dispatch to specific Visit method via generic base
+ Result := Node.Accept(Self).AsGeneric;
+end;
+
+// --- Safe Leaves ---
+
+function TPurityAnalyzer.VisitConstant(const Node: IConstantNode): Boolean;
+begin
+ Result := True;
+end;
+
+function TPurityAnalyzer.VisitKeyword(const Node: IKeywordNode): Boolean;
+begin
+ Result := True;
+end;
+
+function TPurityAnalyzer.VisitNop(const Node: INopNode): Boolean;
+begin
+ Result := True;
+end;
+
+// --- Identifier: Only local variables are safe ---
+
+function TPurityAnalyzer.VisitIdentifier(const Node: IIdentifierNode): Boolean;
+begin
+ // We only allow access to local variables (ScopeDepth = 0).
+ // Accessing Parent/Upvalues (ScopeDepth > 0) makes the function state-dependent (closure state),
+ // effectively impure regarding referential transparency across different closure instances,
+ // unless we could prove the upvalue is constant (which we don't track yet).
+
+ // Note: Parameters are also ScopeDepth=0 in the Binder logic.
+ Result := (Node.Address.Kind = akLocalOrParent) and (Node.Address.ScopeDepth = 0);
+end;
+
+// --- Function Call: The Core Logic ---
+
+function TPurityAnalyzer.VisitFunctionCall(const Node: IFunctionCallNode): Boolean;
+begin
+ // 1. The target function MUST be marked as Pure (from RTL or previous inference).
+ if not Node.IsTargetPure then
+ exit(False);
+
+ // 2. All arguments must be pure expressions.
+ for var arg in Node.Arguments do
+ if not Accept(arg) then
+ exit(False);
+
+ Result := True;
+end;
+
+// --- Recursion ---
+
+function TPurityAnalyzer.VisitRecurNode(const Node: IRecurNode): Boolean;
+begin
+ // 'recur' is just control flow. It is pure if its arguments are pure.
+ for var arg in Node.Arguments do
+ if not Accept(arg) then
+ exit(False);
+ Result := True;
+end;
+
+// --- Structures: Recursive Checks ---
+
+function TPurityAnalyzer.VisitIfExpression(const Node: IIfExpressionNode): Boolean;
+begin
+ Result := Accept(Node.Condition) and Accept(Node.ThenBranch) and Accept(Node.ElseBranch);
+end;
+
+function TPurityAnalyzer.VisitTernaryExpression(const Node: ITernaryExpressionNode): Boolean;
+begin
+ Result := Accept(Node.Condition) and Accept(Node.ThenBranch) and Accept(Node.ElseBranch);
+end;
+
+function TPurityAnalyzer.VisitBlockExpression(const Node: IBlockExpressionNode): Boolean;
+begin
+ for var expr in Node.Expressions do
+ if not Accept(expr) then
+ exit(False);
+ Result := True;
+end;
+
+function TPurityAnalyzer.VisitVariableDeclaration(const Node: IVariableDeclarationNode): Boolean;
+begin
+ // 'def x = ...' is locally pure if the initializer is pure.
+ // It mutates the local scope (stack), but that is contained within the function execution.
+ Result := Accept(Node.Initializer);
+end;
+
+function TPurityAnalyzer.VisitRecordLiteral(const Node: IRecordLiteralNode): Boolean;
+begin
+ for var field in Node.Fields do
+ if not Accept(field.Value) then
+ exit(False);
+ Result := True;
+end;
+
+function TPurityAnalyzer.VisitIndexer(const Node: IIndexerNode): Boolean;
+begin
+ // Reading from a structure is pure if the indices/base are pure.
+ Result := Accept(Node.Base) and Accept(Node.Index);
+end;
+
+function TPurityAnalyzer.VisitMemberAccess(const Node: IMemberAccessNode): Boolean;
+begin
+ Result := Accept(Node.Base);
+end;
+
+function TPurityAnalyzer.VisitSeriesLength(const Node: ISeriesLengthNode): Boolean;
+begin
+ // Querying length is pure.
+ // The series identifier check happens in VisitIdentifier.
+ Result := True;
+end;
+
+// --- Forbidden (Impure) ---
+
+function TPurityAnalyzer.VisitAssignment(const Node: IAssignmentNode): Boolean;
+begin
+ // Mutation of variables is defined as impure.
+ Result := False;
+end;
+
+function TPurityAnalyzer.VisitAddSeriesItem(const Node: IAddSeriesItemNode): Boolean;
+begin
+ // Mutation of a series (side effect).
+ Result := False;
+end;
+
+function TPurityAnalyzer.VisitCreateSeries(const Node: ICreateSeriesNode): Boolean;
+begin
+ // Creating a NEW object is considered pure in this context,
+ // as it does not mutate existing global state.
+ Result := True;
+end;
+
+// --- Irrelevant / Nested (Definitions are pure, execution logic checked separately) ---
+
+function TPurityAnalyzer.VisitLambdaExpression(const Node: ILambdaExpressionNode): Boolean;
+begin
+ // Defining a function is a pure operation.
+ // Whether the function itself is pure when executed is determined when *that* function is compiled.
+ Result := True;
+end;
+
+function TPurityAnalyzer.VisitMacroDefinition(const Node: IMacroDefinitionNode): Boolean;
+begin
+ Result := True; // Compile-time construct
+end;
+
+function TPurityAnalyzer.VisitQuasiquote(const Node: IQuasiquoteNode): Boolean;
+begin
+ Result := True; // Structural construction
+end;
+
+function TPurityAnalyzer.VisitUnquote(const Node: IUnquoteNode): Boolean;
+begin
+ Result := Accept(Node.Expression);
+end;
+
+function TPurityAnalyzer.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): Boolean;
+begin
+ Result := Accept(Node.Expression);
+end;
+
+function TPurityAnalyzer.VisitMacroExpansionNode(const Node: IMacroExpansionNode): Boolean;
+begin
+ // We analyze the already expanded body.
+ Result := Accept(Node.ExpandedBody);
+end;
+
+end.
diff --git a/Src/AST/Myc.Ast.Compiler.Binder.pas b/Src/AST/Myc.Ast.Compiler.Binder.pas
index 0dd0748..a211e23 100644
--- a/Src/AST/Myc.Ast.Compiler.Binder.pas
+++ b/Src/AST/Myc.Ast.Compiler.Binder.pas
@@ -368,7 +368,7 @@ begin
// If FLambdaCounter increased by more than just 1 (myself), children were visited.
hasNested := FLambdaCounter > (startCount + 1);
- Result := TAst.LambdaExpr(newParams, newBody, finalLayout, nil, upvaluesList, hasNested);
+ Result := TAst.LambdaExpr(newParams, newBody, finalLayout, nil, upvaluesList, hasNested, Node.IsPure);
end;
function TAstBinder.VisitFunctionCall(const Node: IFunctionCallNode): IAstNode;
diff --git a/Src/AST/Myc.Ast.Compiler.Macros.pas b/Src/AST/Myc.Ast.Compiler.Macros.pas
index 6810b31..8bb62b6 100644
--- a/Src/AST/Myc.Ast.Compiler.Macros.pas
+++ b/Src/AST/Myc.Ast.Compiler.Macros.pas
@@ -219,7 +219,7 @@ begin
newBody := Accept(Node.Body);
- Result := TAst.LambdaExpr(newParams, newBody, nil, nil, nil, False, TTypes.Unknown);
+ Result := TAst.LambdaExpr(newParams, newBody, nil, nil, nil, False, Node.IsPure, TTypes.Unknown);
end;
function TExpansionVisitor.VisitUnquote(const Node: IUnquoteNode): IAstNode;
diff --git a/Src/AST/Myc.Ast.Compiler.Specializer.pas b/Src/AST/Myc.Ast.Compiler.Specializer.pas
index f75c3f5..4db470d 100644
--- a/Src/AST/Myc.Ast.Compiler.Specializer.pas
+++ b/Src/AST/Myc.Ast.Compiler.Specializer.pas
@@ -22,6 +22,7 @@ type
// This transformer runs *after* TypeChecker.
// It specializes all statically resolvable function calls (RTL and user-defined)
// by replacing them with nodes that have a direct StaticTarget.
+ // It propagates Purity information but does NOT perform Constant Folding yet.
TStaticSpecializer = class(TAstTransformer, IAstSpecializer)
private
FEnvironment: IEnvironment;
@@ -35,7 +36,6 @@ type
constructor Create(const AEnvironment: IEnvironment);
function Execute(const RootNode: IAstNode): IAstNode;
- // Descriptor removed from signature as it is not needed for specialization
class function Specialize(const AEnvironment: IEnvironment; const RootNode: IAstNode): IAstNode; static;
end;
@@ -128,7 +128,16 @@ begin
if FEnvironment.MonomorphCache.TryGetValue(key, specializedMethod) then
begin
// 4a. Cache Hit (Environment)
- Result := TAst.FunctionCall(newCallee, newArgs, specializedMethod.ReturnType, Node.IsTailCall, specializedMethod.Target);
+ // Propagate IsPure flag from cache to AST node
+ Result :=
+ TAst.FunctionCall(
+ newCallee,
+ newArgs,
+ specializedMethod.ReturnType,
+ Node.IsTailCall,
+ specializedMethod.Target,
+ specializedMethod.IsPure
+ );
exit;
end;
@@ -139,7 +148,16 @@ begin
// 5a. Cache Hit (RTL)
FEnvironment.MonomorphCache.Add(key, specializedMethod);
- Result := TAst.FunctionCall(newCallee, newArgs, specializedMethod.ReturnType, Node.IsTailCall, specializedMethod.Target);
+ // Propagate IsPure flag from RTL definition to AST node
+ Result :=
+ TAst.FunctionCall(
+ newCallee,
+ newArgs,
+ specializedMethod.ReturnType,
+ Node.IsTailCall,
+ specializedMethod.Target,
+ specializedMethod.IsPure
+ );
exit;
end;
@@ -148,7 +166,7 @@ begin
if (funcDef <> nil) then
begin
- // Cannot specialize closures safely without more complex analysis
+ // Cannot specialize closures safely without more complex analysis if they have state
if funcDef.Kind = akLambdaExpression then
begin
var lambdaDef := funcDef.AsLambdaExpression;
@@ -160,17 +178,18 @@ begin
end;
// 6a. Compile func with KNOWN TYPES
- // This recursively triggers Bind -> Check -> Specialize for the callee body!
+ // This recursively triggers Bind -> Check -> Specialize -> Purity Inference for the callee body!
var compiled := FEnvironment.Compile(funcDef, argTypes);
// 6b. Store in cache
// Get the return type from the *full function type* returned by Compile
var returnType := compiled.StaticType.Signatures[0].ReturnType;
- specializedMethod := TSpecializedMethod.Create(compiled.Func, returnType);
+ specializedMethod := TSpecializedMethod.Create(compiled.Func, returnType, compiled.IsPure);
FEnvironment.MonomorphCache.Add(key, specializedMethod);
// 6c. Return the new node
- Result := TAst.FunctionCall(newCallee, newArgs, returnType, Node.IsTailCall, compiled.Func);
+ // Propagate the inferred IsPure flag to the AST node
+ Result := TAst.FunctionCall(newCallee, newArgs, returnType, Node.IsTailCall, compiled.Func, compiled.IsPure);
exit;
end;
diff --git a/Src/AST/Myc.Ast.Compiler.TCO.pas b/Src/AST/Myc.Ast.Compiler.TCO.pas
index f0f8154..968f384 100644
--- a/Src/AST/Myc.Ast.Compiler.TCO.pas
+++ b/Src/AST/Myc.Ast.Compiler.TCO.pas
@@ -180,7 +180,18 @@ begin
begin
// Rebuild using factory.
// IMPORTANT: Pass Layout AND Descriptor (TCO runs after TypeChecker).
- Result := TAst.LambdaExpr(newParams, newBody, Node.Layout, Node.Descriptor, Node.Upvalues, Node.HasNestedLambdas, Node.StaticType);
+ // (* FIX: Pass Node.IsPure to preserve it *)
+ Result :=
+ TAst.LambdaExpr(
+ newParams,
+ newBody,
+ Node.Layout,
+ Node.Descriptor,
+ Node.Upvalues,
+ Node.HasNestedLambdas,
+ Node.IsPure,
+ Node.StaticType
+ );
end;
end;
@@ -242,7 +253,8 @@ begin
newArgs,
Node.StaticType,
isTailCall,
- Node.StaticTarget // Preserve the static target from Specializer
+ Node.StaticTarget, // Preserve the static target from Specializer
+ Node.IsTargetPure // (* FIX: Preserve the purity flag from Specializer! *)
);
end;
diff --git a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas
index 479d9d7..e4784f6 100644
--- a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas
+++ b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas
@@ -400,7 +400,8 @@ begin
end;
// 9. Create new node with the Descriptor attached!
- Result := TAst.LambdaExpr(newParams, newBody, Node.Layout, finalDescriptor, Node.Upvalues, Node.HasNestedLambdas, methodType);
+ Result :=
+ TAst.LambdaExpr(newParams, newBody, Node.Layout, finalDescriptor, Node.Upvalues, Node.HasNestedLambdas, Node.IsPure, methodType);
end;
function TTypeChecker.VisitFunctionCall(const Node: IFunctionCallNode): IAstNode;
diff --git a/Src/AST/Myc.Ast.Dumper.pas b/Src/AST/Myc.Ast.Dumper.pas
index 138125a..474e654 100644
--- a/Src/AST/Myc.Ast.Dumper.pas
+++ b/Src/AST/Myc.Ast.Dumper.pas
@@ -201,7 +201,12 @@ var
slot: Integer;
typ: IStaticType;
begin
- LogFmt('LambdaExpression (HasNested: %s)', [Node.HasNestedLambdas.ToString(TUseBoolStrs.True)], Node);
+ // (* UPDATED: Added IsPure output *)
+ LogFmt(
+ 'LambdaExpression (HasNested: %s, IsPure: %s)',
+ [Node.HasNestedLambdas.ToString(TUseBoolStrs.True), BoolToStr(Node.IsPure, True)],
+ Node
+ );
Indent;
// 1. Layout & Symbols
@@ -277,7 +282,12 @@ begin
else
staticStatus := 'nil';
- LogFmt('FunctionCall (IsTailCall: %s, StaticTarget: %s%s)', [Node.IsTailCall.ToString(TUseBoolStrs.True), staticStatus, sigStr], Node);
+ // (* UPDATED: Added IsTargetPure output *)
+ LogFmt(
+ 'FunctionCall (IsTailCall: %s, StaticTarget: %s%s, IsTargetPure: %s)',
+ [Node.IsTailCall.ToString(TUseBoolStrs.True), staticStatus, sigStr, BoolToStr(Node.IsTargetPure, True)],
+ Node
+ );
Indent;
Log('Callee:');
diff --git a/Src/AST/Myc.Ast.Environment.pas b/Src/AST/Myc.Ast.Environment.pas
index 15b4448..c9ebe85 100644
--- a/Src/AST/Myc.Ast.Environment.pas
+++ b/Src/AST/Myc.Ast.Environment.pas
@@ -41,7 +41,8 @@ type
public
Func: TDataValue.TFunc;
StaticType: IStaticType;
- constructor Create(const AFunc: TDataValue.TFunc; const AStaticType: IStaticType);
+ IsPure: Boolean;
+ constructor Create(const AFunc: TDataValue.TFunc; const AStaticType: IStaticType; AIsPure: Boolean);
end;
IExecutionStrategy = interface
@@ -143,7 +144,8 @@ uses
Myc.Ast.Compiler.Binder,
Myc.Ast.Compiler.TypeChecker,
Myc.Ast.Compiler.Specializer,
- Myc.Ast.Compiler.TCO;
+ Myc.Ast.Compiler.TCO,
+ Myc.Ast.Analysis.Purity;
{ TMonoCacheKey }
@@ -202,10 +204,11 @@ end;
{ TCompiledFunction }
-constructor TCompiledFunction.Create(const AFunc: TDataValue.TFunc; const AStaticType: IStaticType);
+constructor TCompiledFunction.Create(const AFunc: TDataValue.TFunc; const AStaticType: IStaticType; AIsPure: Boolean);
begin
Func := AFunc;
StaticType := AStaticType;
+ IsPure := AIsPure;
end;
type
@@ -344,6 +347,8 @@ end;
procedure TAstEnvironment.Define(const Name: String; const AScript: IAstNode);
begin
var compiled := Compile(AScript);
+ // Note: Define now potentially handles Pure flags internally via the Node metadata,
+ // but the runtime value is just the TDataValue.
RootScope.Define(Name, compiled.Func([]), compiled.StaticType);
end;
@@ -526,6 +531,7 @@ var
typedNode: IAstNode;
specialized: IAstNode;
tcoOptimized: IAstNode;
+ isPure: Boolean;
begin
// 0. Wrap in Lambda to create an isolatable compilation unit (scope)
var prg := TAst.LambdaExpr(Params, Node);
@@ -549,25 +555,27 @@ begin
// 4. Optimize (TCO)
tcoOptimized := TAstTCO.Optimize(specialized);
- // 5. Create Evaluator
- // We create a scope based on the descriptor to run the lambda body.
- // The lambda itself (as a node) is evaluated to produce a closure.
- // Since we wrapped the user code in a LambdaExpr, evaluating 'tcoOptimized'
- // returns the closure (TFunc).
+ // 5. Purity Inference
+ // Check the body of the optimized lambda for purity.
+ // Note: tcoOptimized is a LambdaExpressionNode. Its body is what we check.
+ isPure := TPurityAnalyzer.IsPure(tcoOptimized.AsLambdaExpression.Body);
+
+ // 6. Create Evaluator
var visitor := FExecutionStrategy.CreateVisitor(descriptor.CreateScope(FRootScope));
// Execute the AST to get the TFunc (Closure)
- var closure := tcoOptimized.Accept(visitor);
+ var closure := tcoOptimized.Accept(visitor).AsMethod();
// Wrap TCO handling for the final result
finalFunc :=
function(const Args: TArray): TDataValue
begin
- Result := closure.AsMethod()(Args);
+ Result := closure(Args);
TEvaluatorVisitor.HandleTCO(Result);
end;
- Result := TCompiledFunction.Create(finalFunc, funcType);
+ // Pass IsPure flag to the compiled function record
+ Result := TCompiledFunction.Create(finalFunc, funcType, isPure);
end;
function TEnvironment.Compile(const Node: IFunctionDefinition; const ArgTypes: TArray): TCompiledFunction;
@@ -578,6 +586,7 @@ var
finalFunc: TDataValue.TFunc;
typedNode, specialized, tcoOptimized: IAstNode;
+ isPure: Boolean;
begin
// Same steps as above, but Node is already a definition (Lambda)
var expanded := ExpandMacros(Node);
@@ -590,6 +599,9 @@ begin
specialized := Specialize(typedNode);
tcoOptimized := TAstTCO.Optimize(specialized);
+ // Purity Inference
+ isPure := TPurityAnalyzer.IsPure(tcoOptimized.AsLambdaExpression.Body);
+
var visitor := FExecutionStrategy.CreateVisitor(descriptor.CreateScope(FRootScope));
var closure := tcoOptimized.Accept(visitor);
@@ -600,7 +612,7 @@ begin
TEvaluatorVisitor.HandleTCO(Result);
end;
- Result := TCompiledFunction.Create(finalFunc, funcType);
+ Result := TCompiledFunction.Create(finalFunc, funcType, isPure);
end;
function TEnvironment.ExpandMacros(const Node: IAstNode): IAstNode;
diff --git a/Src/AST/Myc.Ast.Nodes.pas b/Src/AST/Myc.Ast.Nodes.pas
index fa19c5d..c37773c 100644
--- a/Src/AST/Myc.Ast.Nodes.pas
+++ b/Src/AST/Myc.Ast.Nodes.pas
@@ -158,9 +158,11 @@ type
{$region 'private'}
function GetBody: IAstNode;
function GetParameters: TArray;
+ function GetIsPure: Boolean; // (* ADDED *)
{$endregion}
property Body: IAstNode read GetBody;
property Parameters: TArray read GetParameters;
+ property IsPure: Boolean read GetIsPure; // (* ADDED *)
end;
INopNode = interface(IAstTypedNode)
@@ -228,6 +230,7 @@ type
function GetUpvalues: TArray;
function GetHasNestedLambdas: Boolean;
+ // GetIsPure is inherited from IFunctionDefinition
{$endregion}
property Parameters: TArray read GetParameters;
@@ -238,6 +241,7 @@ type
property Upvalues: TArray read GetUpvalues;
property HasNestedLambdas: Boolean read GetHasNestedLambdas;
+ // IsPure is inherited
end;
IFunctionCallNode = interface(IAstTypedNode)
@@ -246,11 +250,13 @@ type
function GetArguments: TArray;
function GetIsTailCall: Boolean;
function GetStaticTarget: TDataValue.TFunc;
+ function GetIsTargetPure: Boolean; // (* ADDED *)
{$endregion}
property Callee: IAstNode read GetCallee;
property Arguments: TArray read GetArguments;
property IsTailCall: Boolean read GetIsTailCall;
property StaticTarget: TDataValue.TFunc read GetStaticTarget;
+ property IsTargetPure: Boolean read GetIsTargetPure; // (* ADDED *)
end;
// A node representing a macro call.
diff --git a/Src/AST/Myc.Ast.RTL.pas b/Src/AST/Myc.Ast.RTL.pas
index 68c4959..c6f7e67 100644
--- a/Src/AST/Myc.Ast.RTL.pas
+++ b/Src/AST/Myc.Ast.RTL.pas
@@ -47,11 +47,11 @@ type
public
Target: TDataValue.TFunc;
ReturnType: IStaticType;
- constructor Create(const ATarget: TDataValue.TFunc; const AReturnType: IStaticType);
+ IsPure: Boolean; // (* ADDED *)
+ constructor Create(const ATarget: TDataValue.TFunc; const AReturnType: IStaticType; AIsPure: Boolean);
end;
// The cache holding TDataValue.TFunc wrappers for static native functions.
- // Verwendet den generischen TSpecializedMethod-Record aus Myc.Ast.Types
TStaticBootstrapCache = TDictionary;
TRtlFunctionInfo = class
@@ -153,7 +153,7 @@ constructor TRtlExportAttribute.Create(const AName: string);
begin
inherited Create;
Self.Name := AName;
- Self.IsPure := False; // Default to impure
+ Self.IsPure := False; // Default to impure (safe)
end;
constructor TRtlExportAttribute.Create(const AName: string; AIsPure: Boolean);
@@ -230,6 +230,15 @@ begin
inherited Destroy;
end;
+{ TSpecializedMethod }
+
+constructor TSpecializedMethod.Create(const ATarget: TDataValue.TFunc; const AReturnType: IStaticType; AIsPure: Boolean);
+begin
+ Target := ATarget;
+ ReturnType := AReturnType;
+ IsPure := AIsPure;
+end;
+
{ TRtlRegistry }
class constructor TRtlRegistry.Create;
@@ -252,7 +261,7 @@ begin
FStaticBootstrap := TStaticBootstrapCache.Create(TStaticSignatureKeyComparer.Create);
FStaticFuncMap := TRtlFunctionMap.Create;
- // 2. Perform RTTI Scan (formerly Pass 1 of RegisterAll)
+ // 2. Perform RTTI Scan
ctx := TRttiContext.Create;
try
rtlType := ctx.GetType(TypeInfo(TRtlFunctions));
@@ -292,7 +301,7 @@ begin
if isDynamic then
begin
- if Assigned(funcInfo.DynamicWrapper) and Assigned(funcInfo.DynamicWrapper) then
+ if Assigned(funcInfo.DynamicWrapper) then
raise EInvalidOpException.CreateFmt('Duplicate dynamic fallback defined for %s', [rtlName]);
var wrapperFactory :=
@@ -323,8 +332,8 @@ begin
var wrapper := CreateStaticWrapper(method, retType, argTypes, rttiParams);
if Assigned(wrapper) then
begin
- methodRecord := TSpecializedMethod.Create(wrapper, retType);
- // Use renamed static helper
+ // (* UPDATED: Capture IsPure from attribute *)
+ methodRecord := TSpecializedMethod.Create(wrapper, retType, exportAttr.IsPure);
RegisterStaticSpecialization(rtlName, argTypes, methodRecord);
end
else
@@ -366,8 +375,6 @@ var
key: TStaticSignatureKey;
begin
key := TStaticSignatureKey.Create(AName, AArgTypes);
- // This allows multiple RTTI scans (e.g. in tests) without crashing,
- // though only the class constructor should call this now.
FStaticBootstrap.AddOrSetValue(key, AMethod);
end;
@@ -724,12 +731,6 @@ begin
TRtlRegistry.RegisterAll(AScope);
end;
-constructor TSpecializedMethod.Create(const ATarget: TDataValue.TFunc; const AReturnType: IStaticType);
-begin
- Target := ATarget;
- ReturnType := AReturnType;
-end;
-
initialization
// Register this library's functions with the central AST factory.
TAst.RegisterLibrary(RegisterRtlFunctions);
diff --git a/Src/AST/Myc.Ast.Visitor.pas b/Src/AST/Myc.Ast.Visitor.pas
index 2dd7fe5..d55b862 100644
--- a/Src/AST/Myc.Ast.Visitor.pas
+++ b/Src/AST/Myc.Ast.Visitor.pas
@@ -486,7 +486,17 @@ begin
else
begin
// Use TAst factory and copy properties via interface getters
- Result := TAst.LambdaExpr(newParams, newBody, Node.Layout, Node.Descriptor, Node.Upvalues, Node.HasNestedLambdas, Node.StaticType);
+ Result :=
+ TAst.LambdaExpr(
+ newParams,
+ newBody,
+ Node.Layout,
+ Node.Descriptor,
+ Node.Upvalues,
+ Node.HasNestedLambdas,
+ Node.IsPure,
+ Node.StaticType
+ );
end;
end;
diff --git a/Src/AST/Myc.Ast.pas b/Src/AST/Myc.Ast.pas
index 323fad3..b0935c2 100644
--- a/Src/AST/Myc.Ast.pas
+++ b/Src/AST/Myc.Ast.pas
@@ -56,14 +56,15 @@ type
const AStaticType: IStaticType = nil
): ITernaryExpressionNode; static;
- // Factory Updated: Includes Layout (mandatory) and Descriptor (optional)
+ // (* UPDATED Factory: Added AIsPure *)
class function LambdaExpr(
const AParameters: TArray;
const ABody: IAstNode;
- const ALayout: IScopeLayout = nil; // Nil allowed only for raw AST construction (before Binder)
- const ADescriptor: IScopeDescriptor = nil; // Nil allowed before TypeChecker
+ const ALayout: IScopeLayout = nil;
+ const ADescriptor: IScopeDescriptor = nil;
const AUpvalues: TArray = nil;
const AHasNestedLambdas: Boolean = False;
+ const AIsPure: Boolean = False; // (* ADDED *)
const AStaticType: IStaticType = nil
): ILambdaExpressionNode; static;
@@ -76,12 +77,14 @@ type
class function Unquote(const AExpression: IAstNode): IUnquoteNode; static;
class function UnquoteSplicing(const AExpression: IQuasiquoteNode): IUnquoteSplicingNode; static;
+ // (* UPDATED Factory: Added AIsTargetPure *)
class function FunctionCall(
const ACallee: IAstNode;
const AArguments: TArray;
const AStaticType: IStaticType = nil;
const AIsTailCall: Boolean = False;
- const AStaticTarget: TDataValue.TFunc = nil
+ const AStaticTarget: TDataValue.TFunc = nil;
+ const AIsTargetPure: Boolean = False // (* ADDED *)
): IFunctionCallNode; static;
class function MacroExpansionNode(
@@ -194,6 +197,7 @@ type
FDescriptor: IScopeDescriptor;
FUpvalues: TArray;
FHasNestedLambdas: Boolean;
+ FIsPure: Boolean; // (* ADDED *)
function GetParameters: TArray;
function GetBody: IAstNode;
@@ -201,6 +205,7 @@ type
function GetDescriptor: IScopeDescriptor;
function GetUpvalues: TArray;
function GetHasNestedLambdas: Boolean;
+ function GetIsPure: Boolean; // (* ADDED *)
function GetKind: TAstNodeKind; override;
public
constructor Create(
@@ -210,7 +215,8 @@ type
const ALayout: IScopeLayout;
const ADescriptor: IScopeDescriptor;
const AUpvalues: TArray;
- const AHasNestedLambdas: Boolean
+ const AHasNestedLambdas: Boolean;
+ const AIsPure: Boolean // (* ADDED *)
);
destructor Destroy; override;
function Accept(const Visitor: IAstVisitor): TDataValue; override;
@@ -223,10 +229,12 @@ type
FArguments: TArray;
FIsTailCall: Boolean;
FStaticTarget: TDataValue.TFunc;
+ FIsTargetPure: Boolean; // (* ADDED *)
function GetCallee: IAstNode;
function GetArguments: TArray;
function GetIsTailCall: Boolean;
function GetStaticTarget: TDataValue.TFunc;
+ function GetIsTargetPure: Boolean; // (* ADDED *)
function GetKind: TAstNodeKind; override;
public
constructor Create(
@@ -234,12 +242,14 @@ type
const AArguments: TArray;
const AStaticType: IStaticType;
const AIsTailCall: Boolean;
- const AStaticTarget: TDataValue.TFunc
+ const AStaticTarget: TDataValue.TFunc;
+ const AIsTargetPure: Boolean // (* ADDED *)
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsFunctionCall: IFunctionCallNode; override;
end;
+ // ... (Other node definitions unchanged) ...
TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode)
private
FIdentifier: IIdentifierNode;
@@ -260,8 +270,6 @@ type
function AsVariableDeclaration: IVariableDeclarationNode; override;
end;
- // --- Other internal node classes ---
-
TConstantNode = class(TAstTypedNode, IConstantNode)
private
FValue: TDataValue;
@@ -644,7 +652,6 @@ end;
class function TAst.Constant(const AValue: TDataValue; const AStaticType: IStaticType = nil): IConstantNode;
begin
var constType := AStaticType;
-
if constType = nil then
begin
case AValue.Kind of
@@ -655,7 +662,6 @@ begin
constType := TTypes.Unknown;
end;
end;
-
Result := TConstantNode.Create(AValue, constType);
end;
@@ -684,7 +690,8 @@ class function TAst.FunctionCall(
const AArguments: TArray;
const AStaticType: IStaticType = nil;
const AIsTailCall: Boolean = False;
- const AStaticTarget: TDataValue.TFunc = nil
+ const AStaticTarget: TDataValue.TFunc = nil;
+ const AIsTargetPure: Boolean = False // (* ADDED *)
): IFunctionCallNode;
begin
Result :=
@@ -694,7 +701,8 @@ begin
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
AIsTailCall,
- AStaticTarget
+ AStaticTarget,
+ AIsTargetPure
);
end;
@@ -759,6 +767,7 @@ class function TAst.LambdaExpr(
const ADescriptor: IScopeDescriptor = nil;
const AUpvalues: TArray = nil;
const AHasNestedLambdas: Boolean = False;
+ const AIsPure: Boolean = False; // (* ADDED *)
const AStaticType: IStaticType = nil
): ILambdaExpressionNode;
begin
@@ -771,7 +780,8 @@ begin
ALayout,
ADescriptor,
AUpvalues,
- AHasNestedLambdas
+ AHasNestedLambdas,
+ AIsPure
);
end;
@@ -1247,7 +1257,8 @@ constructor TLambdaExpressionNode.Create(
const ALayout: IScopeLayout;
const ADescriptor: IScopeDescriptor;
const AUpvalues: TArray;
- const AHasNestedLambdas: Boolean
+ const AHasNestedLambdas: Boolean;
+ const AIsPure: Boolean // (* ADDED *)
);
begin
inherited Create(AStaticType);
@@ -1257,6 +1268,7 @@ begin
FDescriptor := ADescriptor;
FUpvalues := AUpvalues;
FHasNestedLambdas := AHasNestedLambdas;
+ FIsPure := AIsPure;
// Consistency Check
if Assigned(FDescriptor) and (FDescriptor.Layout <> FLayout) then
@@ -1308,6 +1320,11 @@ begin
Result := FHasNestedLambdas;
end;
+function TLambdaExpressionNode.GetIsPure: Boolean; // (* ADDED *)
+begin
+ Result := FIsPure;
+end;
+
function TLambdaExpressionNode.GetKind: TAstNodeKind;
begin
Result := akLambdaExpression;
@@ -1444,7 +1461,8 @@ constructor TFunctionCallNode.Create(
const AArguments: TArray;
const AStaticType: IStaticType;
const AIsTailCall: Boolean;
- const AStaticTarget: TDataValue.TFunc
+ const AStaticTarget: TDataValue.TFunc;
+ const AIsTargetPure: Boolean // (* ADDED *)
);
begin
inherited Create(AStaticType);
@@ -1452,6 +1470,7 @@ begin
FArguments := AArguments;
FIsTailCall := AIsTailCall;
FStaticTarget := AStaticTarget;
+ FIsTargetPure := AIsTargetPure;
end;
function TFunctionCallNode.Accept(const Visitor: IAstVisitor): TDataValue;
@@ -1489,6 +1508,11 @@ begin
Result := FStaticTarget;
end;
+function TFunctionCallNode.GetIsTargetPure: Boolean; // (* ADDED *)
+begin
+ Result := FIsTargetPure;
+end;
+
{ TMacroExpansionNode }
constructor TMacroExpansionNode.Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode);