diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json
index 188751d..aa26d72 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.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" }, { "name": "Myc.Ast.Identities", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Identities.pas" }, { "name": "Myc.Fmx.AstEditor.Visualizer", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Layout", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Layout.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Ast.Refactoring.Remove", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Refactoring.Remove.pas" }, { "name": "Myc.Fmx.AstEditor.Render", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Render.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Lists", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Lists.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Primitives", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Primitives.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Control", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Data", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Data.pas" }, { "name": "Myc.Ast.RTL.TypeRegistry", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.TypeRegistry.pas" }, { "name": "Myc.Trade.Broker", "file": "file:///T%3A/Myc/Src/Myc.Trade.Broker.pas" }, { "name": "Myc.Data.Stream.Pipes", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.Pipes.pas" }, { "name": "Myc.Data.Stream", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Pipes", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Pipes.pas" }, { "name": "Demo.Finance", "file": "file:///T%3A/Myc/Test/Demo.Finance.pas" }, { "name": "Myc.Ast.Script.Print", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.Print.pas" }, { "name": "Myc.Ast.Json.Schema.Old", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.Old.pas" }, { "name": "Myc.Ast.Attributes", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Ast.Attributes.pas" }, { "name": "Myc.Ast.Json.Schema", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.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.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" }, { "name": "Myc.Ast.Identities", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Identities.pas" }, { "name": "Myc.Fmx.AstEditor.Visualizer", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Layout", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Layout.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Ast.Refactoring.Remove", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Refactoring.Remove.pas" }, { "name": "Myc.Fmx.AstEditor.Render", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Render.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Lists", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Lists.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Primitives", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Primitives.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Control", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Data", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Data.pas" }, { "name": "Myc.Ast.RTL.TypeRegistry", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.TypeRegistry.pas" }, { "name": "Myc.Trade.Broker", "file": "file:///T%3A/Myc/Src/Myc.Trade.Broker.pas" }, { "name": "Myc.Data.Stream.Pipes", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.Pipes.pas" }, { "name": "Myc.Data.Stream", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Pipes", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Pipes.pas" }, { "name": "Demo.Finance", "file": "file:///T%3A/Myc/Test/Demo.Finance.pas" }, { "name": "Myc.Ast.Script.Print", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.Print.pas" }, { "name": "Myc.Ast.Json.Schema.Old", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.Old.pas" }, { "name": "Myc.Ast.Attributes", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Ast.Attributes.pas" }, { "name": "Myc.Ast.Json.Schema", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.pas" }, { "name": "Myc.Ast.RTL.Math", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Math.pas" }, { "name": "Myc.Ast.RTL.DateTime", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.DateTime.pas" }, { "name": "Unit1", "file": "file:///T%3A/Myc/ASTPlayground/Unit1.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": false, "browsingPaths": [ "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/OCX/Servers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/VCL","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/RTL/SYS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win/winrt","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/ToolsAPI","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/IBX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Internet","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/PROPERTY%20EDITORS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/XML","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Core","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/System","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Protocols","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/fmx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/components","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/engine","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/graph","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ado","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/cloud","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dbx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dsnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/vclctrls","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/connectors","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/proxygen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DataExplorer","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/src","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/tests","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Experts","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/abstraction","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/implementation","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indyimpl","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Property%20Editors/Indy10","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap/wsdlimporter","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Visualizers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XMLReporting","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XPGen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/rest","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/firedac","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/tethering","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnitX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ems","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/net","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/FlatBox2D","file:///C%3A/Users/Public/Documents/Embarcadero/Studio/37.0/Dcp/%25PLATFORM%25","file:///%25TP%25/runtime/vcl","file:///S%3A/sc_famos_src/svn_vcl/cpxedits","file:///S%3A/sc_famos_src/svn_vcl/dzChart","file:///S%3A/sc_famos_src/svn_vcl/eaeditor","file:///S%3A/sc_famos_src/svn_vcl/FamosEvents","file:///S%3A/sc_famos_src/svn_vcl/HTML_Viewer/source","file:///S%3A/sc_famos_src/svn_vcl/Myc_ChartEdit","file:///S%3A/sc_famos_src/svn_vcl/Myc_HemiDrag","file:///S%3A/sc_famos_src/svn_vcl/Myc_SplitControl","file:///S%3A/sc_famos_src/svn_vcl/NiceChart","file:///S%3A/sc_famos_src/svn_vcl/plotter","file:///S%3A/sc_famos_src/svn_vcl/SimpleIPC","file:///S%3A/sc_famos_src/svn_vcl/SynEdit-master/Source","file:///S%3A/sc_famos_src/svn_vcl/ValEdits","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib/win32","file:///S%3A/sc_famos_src/svn_vcl/Virtual-TreeView/Source","file:///S%3A/sc_famos_src/svn_common/caHelpSys","file:///S%3A/sc_famos_src/svn_common/Misc","file:///S%3A/sc_famos_src/svn_common/Myc_VecMath","file:///S%3A/sc_famos_src/svn_common/PascalScript/source","file:///S%3A/sc_famos_src/svn_common/TreeBase","file:///S%3A/sc_famos_src/svn_common/TreeBase/Medien","file:///S%3A/3rdParty/spring4d/Source","file:///S%3A/3rdParty/spring4d/Source/Base","file:///S%3A/3rdParty/spring4d/Source/Base/Collections","file:///S%3A/3rdParty/spring4d/Source/Base/Logging","file:///S%3A/3rdParty/spring4d/Source/Base/Patches","file:///S%3A/3rdParty/spring4d/Source/Core/Container","file:///S%3A/3rdParty/spring4d/Source/Core/Interception","file:///S%3A/3rdParty/spring4d/Source/Core/Logging","file:///S%3A/3rdParty/spring4d/Source/Core/Mocking","file:///S%3A/3rdParty/spring4d/Source/Core/Services","file:///S%3A/3rdParty/spring4d/Source/Extensions/Cryptography","file:///S%3A/3rdParty/spring4d/Source/Extensions/Utils","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCommon%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressGDI%2B%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLibrary/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/XP%20Theme%20Manager/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLayout%20Control/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressPageControl/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressEditors%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDocking%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressBars/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressOfficeCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressMemData/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDataController/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressNavBar/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressSkins%20Library/Sources","file:///T%3A/Myc/Src","file:///T%3A/Myc/Src/Data","file:///T%3A/Myc/Src/AST" ] , "CommonAppData": "file:///C%3A/Users/Brummel/AppData/Roaming/Embarcadero/BDS/37.0/" , "Templates": "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/ObjRepos/" } }
\ No newline at end of file
diff --git a/ASTPlayground/ASTPlayground.dpr b/ASTPlayground/ASTPlayground.dpr
index 5947f79..c610919 100644
--- a/ASTPlayground/ASTPlayground.dpr
+++ b/ASTPlayground/ASTPlayground.dpr
@@ -45,7 +45,10 @@ uses
Myc.Ast.Script.Print in '..\Src\AST\Myc.Ast.Script.Print.pas',
Myc.Ast.Json.Schema.Old in '..\Src\AST\Myc.Ast.Json.Schema.Old.pas',
Myc.Ast.Attributes in 'Myc.Ast.Attributes.pas',
- Myc.Ast.Json.Schema in '..\Src\AST\Myc.Ast.Json.Schema.pas';
+ Myc.Ast.Json.Schema in '..\Src\AST\Myc.Ast.Json.Schema.pas',
+ Myc.Ast.RTL.Math in '..\Src\AST\Myc.Ast.RTL.Math.pas',
+ Myc.Ast.RTL.DateTime in '..\Src\AST\Myc.Ast.RTL.DateTime.pas',
+ Myc.Ast.RTL.Series in '..\Src\AST\Myc.Ast.RTL.Series.pas';
{$R *.res}
diff --git a/ASTPlayground/ASTPlayground.dproj b/ASTPlayground/ASTPlayground.dproj
index 2744942..7850f15 100644
--- a/ASTPlayground/ASTPlayground.dproj
+++ b/ASTPlayground/ASTPlayground.dproj
@@ -176,6 +176,9 @@
+
+
+
Base
diff --git a/Src/AST/Myc.Ast.Attributes.pas b/Src/AST/Myc.Ast.Attributes.pas
index 4556b9b..81b647d 100644
--- a/Src/AST/Myc.Ast.Attributes.pas
+++ b/Src/AST/Myc.Ast.Attributes.pas
@@ -72,6 +72,26 @@ type
property Signature: string read FSignature;
end;
+ // Decorates a native function to be exported to the Myc runtime.
+ // 'IsPure' hints the compiler that the function has no side effects.
+ TRtlExportAttribute = class(TCustomAttribute)
+ type
+ TPurity = (Pure, Impure);
+ public
+ Name: string;
+ IsPure: Boolean;
+ constructor Create(const AName: string); overload;
+ constructor Create(const AName: string; APurity: TPurity); overload;
+ end;
+
+ // Decorates a class function to be exported as a constant value.
+ // The function is invoked once at registration time.
+ TRtlConstAttribute = class(TCustomAttribute)
+ public
+ Name: string;
+ constructor Create(const AName: string);
+ end;
+
implementation
{ AstTagAttribute }
@@ -116,4 +136,28 @@ begin
FSignature := ASignature;
end;
+//==================================================================================================
+// Attribute Implementations
+//==================================================================================================
+
+constructor TRtlExportAttribute.Create(const AName: string);
+begin
+ inherited Create;
+ Name := AName;
+ IsPure := False;
+end;
+
+constructor TRtlExportAttribute.Create(const AName: string; APurity: TPurity);
+begin
+ inherited Create;
+ Name := AName;
+ IsPure := APurity = Pure;
+end;
+
+constructor TRtlConstAttribute.Create(const AName: string);
+begin
+ inherited Create;
+ Name := AName;
+end;
+
end.
diff --git a/Src/AST/Myc.Ast.RTL.Core.pas b/Src/AST/Myc.Ast.RTL.Core.pas
index 48cb7be..4e7d0af 100644
--- a/Src/AST/Myc.Ast.RTL.Core.pas
+++ b/Src/AST/Myc.Ast.RTL.Core.pas
@@ -5,31 +5,20 @@ interface
uses
System.SysUtils,
System.Math,
- System.DateUtils,
- System.Generics.Collections,
- Myc.Utils,
Myc.Data.Scalar,
Myc.Data.Value,
- Myc.Ast.RTL,
- Myc.Ast.Attributes,
- Myc.Data.Keyword,
- Myc.Data.Series;
+ Myc.Ast.Attributes;
type
- { Contains the native implementations for the Myc standard library. }
- TRtlFunctions = record
+ TRtlCoreFunctions = record
public
// --- Constants ---
- // Konstanten werden als statische Funktionen ohne Parameter implementiert.
- // Das TRtlConst-Attribut sorgt dafür, dass der Rückgabewert beim Start
- // evaluiert und in den Scope eingetragen wird.
-
[TRtlConst('NaN')]
[AstDoc('Not a Number (IEEE 754).')]
class function Const_NaN: Double; static;
- // --- Arithmetic ---
+ // --- Arithmetic Operators ---
[TRtlExport('+', Pure)]
[AstDoc('Adds two numbers or concatenates two strings.')]
@@ -63,7 +52,7 @@ type
[AstSignature('(number, number) -> number')]
class function Modulus(const Args: TArray): TDataValue; static;
- // --- Comparison ---
+ // --- Comparison Operators ---
[TRtlExport('=', Pure)]
[AstDoc('Checks if A is equal to B.')]
@@ -95,7 +84,7 @@ type
[AstSignature('(number, number) -> boolean')]
class function GreaterThanOrEqual(const Args: TArray): TDataValue; static;
- // --- Logic / Bitwise ---
+ // --- Logic / Bitwise Operators ---
[TRtlExport('not', Pure)]
[AstDoc('Logical or bitwise NOT operation.')]
@@ -131,94 +120,6 @@ type
[AstSignature('(number, number) -> number')]
class function RightShift(const Args: TArray): TDataValue; static;
- // --- Math Functions ---
-
- [TRtlExport('abs', Pure)]
- [AstDoc('Returns the absolute value of a number.')]
- [AstSignature('(number) -> number')]
- class function Abs(const Arg: TScalar): TScalar; static;
-
- [TRtlExport('round', Pure)]
- [AstDoc('Rounds a float to the nearest integer.')]
- [AstSignature('(number) -> number')]
- class function Round(const Arg: TScalar): TScalar; static;
-
- [TRtlExport('trunc', Pure)]
- [AstDoc('Returns the integer part of a float.')]
- [AstSignature('(number) -> number')]
- class function Trunc(const Arg: TScalar): TScalar; static;
-
- [TRtlExport('ceil', Pure)]
- [AstDoc('Returns the smallest integer >= the argument.')]
- [AstSignature('(number) -> number')]
- class function Ceil(const Arg: TScalar): TScalar; static;
-
- [TRtlExport('floor', Pure)]
- [AstDoc('Returns the largest integer <= the argument.')]
- [AstSignature('(number) -> number')]
- class function Floor(const Arg: TScalar): TScalar; static;
-
- [TRtlExport('sign', Pure)]
- [AstDoc('Returns -1 for negative, 1 for positive, 0 for zero.')]
- [AstSignature('(number) -> number')]
- class function Sign(const Arg: TScalar): TScalar; static;
-
- [TRtlExport('sqrt', Pure)]
- [AstDoc('Returns the square root of a number.')]
- [AstSignature('(number) -> number')]
- class function Sqrt(const Arg: TScalar): TScalar; static;
-
- [TRtlExport('pow', Pure)]
- [AstDoc('Returns Base raised to the power of Exponent.')]
- [AstSignature('(number, number) -> number')]
- class function Pow(const Args: TArray): TDataValue; static;
-
- [TRtlExport('random', Impure)]
- [AstDoc('Returns a random number. No args: [0..1). Arg N: Integer [0..N).')]
- [AstSignature('() -> float')]
- [AstSignature('(number) -> number')]
- class function Random(const Args: TArray): TDataValue; static;
-
- // --- DateTime ---
-
- [TRtlExport('now', Impure)]
- [AstDoc('Returns the current system timestamp.')]
- [AstSignature('() -> datetime')]
- class function Now(const Args: TArray): TDataValue; static;
-
- [TRtlExport('date', Impure)]
- [AstDoc('Returns the current date or constructs a date from Y, M, D.')]
- [AstSignature('() -> datetime')]
- [AstSignature('(number, number, number) -> datetime')]
- class function Date(const Args: TArray): TDataValue; static;
-
- // --- Functional / Series ---
-
- [TRtlExport('memoize', Pure)]
- [AstDoc('Creates a memoized version of a function for performance.')]
- [AstSignature('((any) -> any) -> ((any) -> any)')]
- class function Memoize(const Args: TArray): TDataValue; static;
-
- [TRtlExport('map', Pure)]
- [AstDoc('Applies a function to every element of a series.')]
- [AstSignature('(series, (any) -> any) -> series')]
- class function Map(const Args: TArray): TDataValue; static;
-
- [TRtlExport('reduce', Pure)]
- [AstDoc('Collapses a series into a single value using a reducer function.')]
- [AstSignature('(series, any, (any, any) -> any) -> any')]
- class function Reduce(const Args: TArray): TDataValue; static;
-
- [TRtlExport('where', Pure)]
- [AstDoc('Filters a series based on a predicate function.')]
- [AstSignature('(series, (any) -> boolean) -> series')]
- class function Where(const Args: TArray): TDataValue; static;
-
- [TRtlExport('any', Pure)]
- [AstDoc('Returns true if at least one element satisfies the predicate.')]
- [AstSignature('(series, (any) -> boolean) -> boolean')]
- class function Any(const Args: TArray): TDataValue; static;
-
// --- Static Specializations (Targets for TypeChecker/Specializer) ---
[TRtlExport('+', Pure)]
@@ -339,52 +240,20 @@ type
class function Negate_Float_Float(A: Double): Double; static;
[TRtlExport('not', Pure)]
class function Not_Ordinal_Ordinal(A: Int64): Int64; static;
-
- [TRtlExport('abs', Pure)]
- class function Abs_Ordinal_Ordinal(A: Int64): Int64; static;
- [TRtlExport('abs', Pure)]
- class function Abs_Float_Float(A: Double): Double; static;
- [TRtlExport('round', Pure)]
- class function Round_Ordinal_Ordinal(A: Int64): Int64; static;
- [TRtlExport('round', Pure)]
- class function Round_Float_Ordinal(A: Double): Int64; static;
- [TRtlExport('trunc', Pure)]
- class function Trunc_Ordinal_Ordinal(A: Int64): Int64; static;
- [TRtlExport('trunc', Pure)]
- class function Trunc_Float_Ordinal(A: Double): Int64; static;
-
- [TRtlExport('sqrt', Pure)]
- class function Sqrt_Ordinal_Float(A: Int64): Double; static;
- [TRtlExport('sqrt', Pure)]
- class function Sqrt_Float_Float(A: Double): Double; static;
-
- [TRtlExport('pow', Pure)]
- class function Pow_Ordinal_Ordinal_Float(A, B: Int64): Double; static;
- [TRtlExport('pow', Pure)]
- class function Pow_Float_Float_Float(A, B: Double): Double; static;
- [TRtlExport('pow', Pure)]
- class function Pow_Ordinal_Float_Float(A: Int64; B: Double): Double; static;
- [TRtlExport('pow', Pure)]
- class function Pow_Float_Ordinal_Float(A: Double; B: Int64): Double; static;
-
- [TRtlExport('random', Impure)]
- class function Random_Void_Float: Double; static;
- [TRtlExport('random', Impure)]
- class function Random_Ordinal_Ordinal(Limit: Int64): Int64; static;
end;
implementation
-{ TRtlFunctions - Constants }
+{ TRtlCoreFunctions - Constants }
-class function TRtlFunctions.Const_NaN: Double;
+class function TRtlCoreFunctions.Const_NaN: Double;
begin
Result := System.Math.NaN;
end;
-{ TRtlFunctions - Operator Implementations }
+{ TRtlCoreFunctions - Operator Implementations }
-class function TRtlFunctions.Add(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.Add(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator + requires 2 arguments.');
@@ -394,7 +263,7 @@ begin
Result := Args[0].AsScalar + Args[1].AsScalar;
end;
-class function TRtlFunctions.Subtract(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.Subtract(const Args: TArray): TDataValue;
begin
if Length(Args) = 1 then
Result := -Args[0].AsScalar
@@ -404,70 +273,70 @@ begin
raise EArgumentException.Create('Operator - requires 1 or 2 arguments.');
end;
-class function TRtlFunctions.Multiply(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.Multiply(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator * requires 2 arguments.');
Result := Args[0].AsScalar * Args[1].AsScalar;
end;
-class function TRtlFunctions.Divide(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.Divide(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator / requires 2 arguments.');
Result := Args[0].AsScalar / Args[1].AsScalar;
end;
-class function TRtlFunctions.IntDivide(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.IntDivide(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator div requires 2 arguments.');
Result := Args[0].AsScalar div Args[1].AsScalar;
end;
-class function TRtlFunctions.Modulus(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.Modulus(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator mod requires 2 arguments.');
Result := Args[0].AsScalar mod Args[1].AsScalar;
end;
-class function TRtlFunctions.Equal(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.Equal(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator = requires 2 arguments.');
Result := TScalar.FromBoolean(Args[0].AsScalar = Args[1].AsScalar);
end;
-class function TRtlFunctions.NotEqual(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.NotEqual(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator <> requires 2 arguments.');
Result := TScalar.FromBoolean(Args[0].AsScalar <> Args[1].AsScalar);
end;
-class function TRtlFunctions.LessThan(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.LessThan(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator < requires 2 arguments.');
Result := TScalar.FromBoolean(Args[0].AsScalar < Args[1].AsScalar);
end;
-class function TRtlFunctions.LessThanOrEqual(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.LessThanOrEqual(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator <= requires 2 arguments.');
Result := TScalar.FromBoolean(Args[0].AsScalar <= Args[1].AsScalar);
end;
-class function TRtlFunctions.GreaterThan(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.GreaterThan(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator > requires 2 arguments.');
Result := TScalar.FromBoolean(Args[0].AsScalar > Args[1].AsScalar);
end;
-class function TRtlFunctions.GreaterThanOrEqual(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.GreaterThanOrEqual(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator >= requires 2 arguments.');
@@ -476,435 +345,128 @@ end;
// --- Logic / Bitwise ---
-class function TRtlFunctions.LogicalNot(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.LogicalNot(const Args: TArray): TDataValue;
begin
if Length(Args) <> 1 then
raise EArgumentException.Create('Operator not requires 1 argument.');
Result := not Args[0].AsScalar;
end;
-class function TRtlFunctions.BitwiseAnd(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.BitwiseAnd(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator and requires 2 arguments.');
Result := Args[0].AsScalar and Args[1].AsScalar;
end;
-class function TRtlFunctions.BitwiseOr(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.BitwiseOr(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator or requires 2 arguments.');
Result := Args[0].AsScalar or Args[1].AsScalar;
end;
-class function TRtlFunctions.BitwiseXor(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.BitwiseXor(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator xor requires 2 arguments.');
Result := Args[0].AsScalar xor Args[1].AsScalar;
end;
-class function TRtlFunctions.LeftShift(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.LeftShift(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator shl requires 2 arguments.');
Result := Args[0].AsScalar shl Args[1].AsScalar;
end;
-class function TRtlFunctions.RightShift(const Args: TArray): TDataValue;
+class function TRtlCoreFunctions.RightShift(const Args: TArray): TDataValue;
begin
if Length(Args) <> 2 then
raise EArgumentException.Create('Operator shr requires 2 arguments.');
Result := Args[0].AsScalar shr Args[1].AsScalar;
end;
-{ TRtlFunctions - Standard Functions }
-
-class function TRtlFunctions.Abs(const Arg: TScalar): TScalar;
-begin
- case Arg.Kind of
- TScalar.TKind.Ordinal: Result := TScalar.FromInt64(System.Abs(Arg.Value.AsInt64));
- TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromDouble(System.Abs(Arg.Value.AsDouble));
- else
- raise EArgumentException.Create('Abs requires a numeric argument.');
- end;
-end;
-
-class function TRtlFunctions.Round(const Arg: TScalar): TScalar;
-begin
- case Arg.Kind of
- TScalar.TKind.Ordinal: Result := Arg;
- TScalar.TKind.Float, TScalar.TKind.DateTime:
- begin
- var val: Double := Arg.Value.AsDouble;
- Result := TScalar.FromInt64(System.Round(val));
- end;
- else
- raise EArgumentException.Create('Round requires a numeric argument.');
- end;
-end;
-
-class function TRtlFunctions.Trunc(const Arg: TScalar): TScalar;
-begin
- case Arg.Kind of
- TScalar.TKind.Ordinal: Result := Arg;
- TScalar.TKind.Float, TScalar.TKind.DateTime:
- begin
- var val: Double := Arg.Value.AsDouble;
- Result := TScalar.FromInt64(System.Trunc(val));
- end;
- else
- raise EArgumentException.Create('Trunc requires a numeric argument.');
- end;
-end;
-
-class function TRtlFunctions.Ceil(const Arg: TScalar): TScalar;
-begin
- case Arg.Kind of
- TScalar.TKind.Ordinal: Result := Arg;
- TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromInt64(System.Math.Ceil(Arg.Value.AsDouble));
- else
- raise EArgumentException.Create('Ceil requires a numeric argument.');
- end;
-end;
-
-class function TRtlFunctions.Floor(const Arg: TScalar): TScalar;
-begin
- case Arg.Kind of
- TScalar.TKind.Ordinal: Result := Arg;
- TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromInt64(System.Math.Floor(Arg.Value.AsDouble));
- else
- raise EArgumentException.Create('Floor requires a numeric argument.');
- end;
-end;
-
-class function TRtlFunctions.Sign(const Arg: TScalar): TScalar;
-begin
- case Arg.Kind of
- TScalar.TKind.Ordinal: Result := TScalar.FromInt64(System.Math.Sign(Arg.Value.AsInt64));
- TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromInt64(System.Math.Sign(Arg.Value.AsDouble));
- else
- raise EArgumentException.Create('Sign requires a numeric argument.');
- end;
-end;
-
-class function TRtlFunctions.Sqrt(const Arg: TScalar): TScalar;
-begin
- var val: Double := Arg; // Implicit cast to Double handles both Ordinal and Float
- Result := TScalar.FromDouble(System.Sqrt(val));
-end;
-
-class function TRtlFunctions.Pow(const Args: TArray): TDataValue;
-begin
- if Length(Args) <> 2 then
- raise EArgumentException.Create('Pow requires 2 arguments (Base, Exponent).');
-
- var baseVal: Double := Args[0].AsScalar; // Implicit cast
- var expVal: Double := Args[1].AsScalar; // Implicit cast
- Result := TScalar.FromDouble(System.Math.Power(baseVal, expVal));
-end;
-
-class function TRtlFunctions.Random(const Args: TArray): TDataValue;
-begin
- if Length(Args) = 0 then
- Result := TScalar.FromDouble(System.Random)
- else if (Length(Args) = 1) and (Args[0].AsScalar.Kind = TScalar.TKind.Ordinal) then
- Result := TScalar.FromInt64(System.Random(Integer(Args[0].AsScalar.Value.AsInt64)))
- else
- raise EArgumentException.Create('Random expects 0 arguments or 1 integer argument.');
-end;
-
-// --- Date Constructors ---
-
-class function TRtlFunctions.Now(const Args: TArray): TDataValue;
-begin
- Result := TScalar.FromDateTime(System.SysUtils.Now);
-end;
-
-class function TRtlFunctions.Date(const Args: TArray): TDataValue;
-
- function GetInt(const V: TDataValue; ArgIndex: Integer): Word;
- begin
- if V.AsScalar.Kind <> TScalar.TKind.Ordinal then
- raise EArgumentException.CreateFmt('Date argument %d must be an Integer.', [ArgIndex]);
- Result := V.AsScalar.Value.AsInt64;
- end;
-
-begin
- if Length(Args) = 3 then
- begin
- var y := GetInt(Args[0], 1);
- var m := GetInt(Args[1], 2);
- var d := GetInt(Args[2], 3);
- Result := TScalar.FromDateTime(EncodeDate(y, m, d));
- end
- else if Length(Args) = 0 then
- Result := TScalar.FromDateTime(System.SysUtils.Date)
- else
- raise EArgumentException.Create('Date expects 0 or 3 arguments (Year, Month, Day).');
-end;
-
-// --- High-Order / Series ---
-
-class function TRtlFunctions.Memoize(const Args: TArray): TDataValue;
-var
- funcToMemoize: TDataValue.TFunc;
- memoizedFunc: TDataValue.TFunc;
-begin
- if Length(Args) <> 1 then
- raise EArgumentException.Create('Memoize requires exactly one argument.');
- if Args[0].Kind <> vkMethod then
- raise EArgumentException.Create('The argument to Memoize must be a function.');
-
- var cCache: TDataValue;
- cCache.FromObj(TDictionary.Create);
-
- funcToMemoize := Args[0].AsMethod();
-
- memoizedFunc :=
- function(const AArgs: TArray): TDataValue
- var
- argScalar: TScalar;
- key: Int64;
- begin
- if (Length(AArgs) <> 1) or (AArgs[0].Kind <> vkScalar) then
- raise EArgumentException.Create('This memoized function can only be called with a single scalar argument.');
-
- argScalar := AArgs[0].AsScalar;
- if argScalar.Kind <> TScalar.TKind.Ordinal then
- raise EArgumentException.Create('This memoized function expects an ordinal argument for caching.');
-
- key := argScalar.Value.AsInt64;
-
- var cache := TDictionary(cCache.AsObject);
-
- if cache.TryGetValue(key, Result) then
- exit;
-
- Result := funcToMemoize(AArgs);
- cache.Add(key, Result);
- end;
-
- Result := TDataValue(memoizedFunc);
-end;
-
-class function TRtlFunctions.Map(const Args: TArray): TDataValue;
-var
- sourceArg: TDataValue;
-begin
- if Length(Args) <> 2 then
- raise EArgumentException.Create('Map requires exactly two arguments: a series and a function.');
-
- sourceArg := Args[0];
- if not (sourceArg.Kind in [vkSeries]) then
- raise EArgumentException.Create('The first argument to Map must be a series.');
-
- if Args[1].Kind <> vkMethod then
- raise EArgumentException.Create('The second argument to Map must be a function.');
-
- Result := TDataValue.Map(sourceArg.AsSeries, Args[1].AsMethod());
-end;
-
-class function TRtlFunctions.Reduce(const Args: TArray): TDataValue;
-var
- sourceArg: TDataValue;
- sourceSeries: ISeries;
- accumulator: TDataValue;
- reducerFunc: TDataValue.TFunc;
- i: Integer;
- currentItem: TScalar;
- reducerArgs: TArray;
-begin
- if Length(Args) <> 3 then
- raise EArgumentException.Create('Reduce requires exactly three arguments: a series, an initial value, and a reducer function.');
-
- sourceArg := Args[0];
- if sourceArg.Kind <> vkSeries then
- raise EArgumentException.Create('The first argument to Reduce must be a series.');
-
- if Args[2].Kind <> vkMethod then
- raise EArgumentException.Create('The third argument to Reduce must be a function.');
-
- sourceSeries := sourceArg.AsSeries;
- accumulator := Args[1];
- reducerFunc := Args[2].AsMethod();
-
- for i := sourceSeries.Count - 1 downto 0 do
- begin
- currentItem := sourceSeries.Items[i];
- reducerArgs := [accumulator, TDataValue(currentItem)];
- accumulator := reducerFunc(reducerArgs);
- end;
-
- Result := accumulator;
-end;
-
-class function TRtlFunctions.Where(const Args: TArray): TDataValue;
-var
- sourceArg: TDataValue;
- sourceSeries: ISeries;
- predicateFunc: TDataValue.TFunc;
- matchingIndices: TList;
- i: Integer;
- item: TScalar;
- predicateResult: TDataValue;
- indexSeries: ISeries;
- mapperFunc: TDataValue.TFunc;
-begin
- if Length(Args) <> 2 then
- raise EArgumentException.Create('Where requires exactly two arguments: a series and a predicate function.');
-
- sourceArg := Args[0];
- if sourceArg.Kind <> vkSeries then
- raise EArgumentException.Create('The first argument to Where must be a series.');
-
- if Args[1].Kind <> vkMethod then
- raise EArgumentException.Create('The second argument to Where must be a function.');
-
- sourceSeries := sourceArg.AsSeries;
- predicateFunc := Args[1].AsMethod();
-
- matchingIndices := TList.Create;
- try
- for i := sourceSeries.Count - 1 downto 0 do
- begin
- item := sourceSeries.Items[i];
- predicateResult := predicateFunc([TDataValue(item)]);
-
- if (predicateResult.Kind = vkScalar) and (Boolean(predicateResult.AsScalar)) then
- matchingIndices.Add(i);
- end;
-
- indexSeries := TIndexSeries.Create(matchingIndices.ToArray);
- finally
- matchingIndices.Free;
- end;
-
- mapperFunc :=
- function(const AArgs: TArray): TDataValue
- var
- idx: Integer;
- begin
- idx := AArgs[0].AsScalar.Value.AsInt64;
- Result := TDataValue(sourceSeries.Items[idx]);
- end;
-
- Result := TDataValue.Map(indexSeries, mapperFunc);
-end;
-
-class function TRtlFunctions.Any(const Args: TArray): TDataValue;
-var
- sourceArg: TDataValue;
- sourceSeries: ISeries;
- predicateFunc: TDataValue.TFunc;
- i: Integer;
- item: TScalar;
- predicateResult: TDataValue;
-begin
- if Length(Args) <> 2 then
- raise EArgumentException.Create('Any requires exactly two arguments: a series and a predicate function.');
-
- sourceArg := Args[0];
- if sourceArg.Kind <> vkSeries then
- raise EArgumentException.Create('The first argument to Any must be a series.');
-
- if Args[1].Kind <> vkMethod then
- raise EArgumentException.Create('The second argument to Any must be a function.');
-
- sourceSeries := sourceArg.AsSeries;
- predicateFunc := Args[1].AsMethod();
-
- for i := 0 to sourceSeries.Count - 1 do
- begin
- item := sourceSeries.Items[i];
- predicateResult := predicateFunc([TDataValue(item)]);
-
- if (predicateResult.Kind = vkScalar) and (Boolean(predicateResult.AsScalar)) then
- begin
- Result := TScalar.FromBoolean(True);
- exit;
- end;
- end;
-
- Result := TScalar.FromBoolean(False);
-end;
-
// --- Static Specializations ---
// Add
-class function TRtlFunctions.Add_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Add_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A + B;
end;
-class function TRtlFunctions.Add_Float_Float_Float(A, B: Double): Double;
+class function TRtlCoreFunctions.Add_Float_Float_Float(A, B: Double): Double;
begin
Result := A + B;
end;
-class function TRtlFunctions.Add_Ordinal_Float_Float(A: Int64; B: Double): Double;
+class function TRtlCoreFunctions.Add_Ordinal_Float_Float(A: Int64; B: Double): Double;
begin
Result := A + B;
end;
-class function TRtlFunctions.Add_Float_Ordinal_Float(A: Double; B: Int64): Double;
+class function TRtlCoreFunctions.Add_Float_Ordinal_Float(A: Double; B: Int64): Double;
+begin
+ Result := A + B;
+end;
+class function TRtlCoreFunctions.Add_Text_Text_Text(const A: String; const B: String): String;
begin
Result := A + B;
end;
// Subtract
-class function TRtlFunctions.Subtract_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Subtract_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A - B;
end;
-class function TRtlFunctions.Subtract_Float_Float_Float(A, B: Double): Double;
+class function TRtlCoreFunctions.Subtract_Float_Float_Float(A, B: Double): Double;
begin
Result := A - B;
end;
-class function TRtlFunctions.Subtract_Ordinal_Float_Float(A: Int64; B: Double): Double;
+class function TRtlCoreFunctions.Subtract_Ordinal_Float_Float(A: Int64; B: Double): Double;
begin
Result := A - B;
end;
-class function TRtlFunctions.Subtract_Float_Ordinal_Float(A: Double; B: Int64): Double;
+class function TRtlCoreFunctions.Subtract_Float_Ordinal_Float(A: Double; B: Int64): Double;
begin
Result := A - B;
end;
// Multiply
-class function TRtlFunctions.Multiply_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Multiply_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A * B;
end;
-class function TRtlFunctions.Multiply_Float_Float_Float(A, B: Double): Double;
+class function TRtlCoreFunctions.Multiply_Float_Float_Float(A, B: Double): Double;
begin
Result := A * B;
end;
-class function TRtlFunctions.Multiply_Ordinal_Float_Float(A: Int64; B: Double): Double;
+class function TRtlCoreFunctions.Multiply_Ordinal_Float_Float(A: Int64; B: Double): Double;
begin
Result := A * B;
end;
-class function TRtlFunctions.Multiply_Float_Ordinal_Float(A: Double; B: Int64): Double;
+class function TRtlCoreFunctions.Multiply_Float_Ordinal_Float(A: Double; B: Int64): Double;
begin
Result := A * B;
end;
// Divide
-class function TRtlFunctions.Divide_Ordinal_Ordinal_Float(A, B: Int64): Double;
+class function TRtlCoreFunctions.Divide_Ordinal_Ordinal_Float(A, B: Int64): Double;
begin
if B = 0 then
raise EDivByZero.Create('Division by zero.');
Result := A / B;
end;
-class function TRtlFunctions.Divide_Float_Float_Float(A, B: Double): Double;
+class function TRtlCoreFunctions.Divide_Float_Float_Float(A, B: Double): Double;
begin
if B = 0.0 then
raise EDivByZero.Create('Division by zero.');
Result := A / B;
end;
-class function TRtlFunctions.Divide_Ordinal_Float_Float(A: Int64; B: Double): Double;
+class function TRtlCoreFunctions.Divide_Ordinal_Float_Float(A: Int64; B: Double): Double;
begin
if B = 0.0 then
raise EDivByZero.Create('Division by zero.');
Result := A / B;
end;
-class function TRtlFunctions.Divide_Float_Ordinal_Float(A: Double; B: Int64): Double;
+class function TRtlCoreFunctions.Divide_Float_Ordinal_Float(A: Double; B: Int64): Double;
begin
if B = 0 then
raise EDivByZero.Create('Division by zero.');
@@ -912,234 +474,161 @@ begin
end;
// Integer Math
-class function TRtlFunctions.Div_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Div_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A div B;
end;
-class function TRtlFunctions.Mod_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Mod_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A mod B;
end;
// Comparisons
-class function TRtlFunctions.Equal_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Equal_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := Ord(A = B);
end;
-class function TRtlFunctions.Equal_Float_Float_Ordinal(A, B: Double): Int64;
+class function TRtlCoreFunctions.Equal_Float_Float_Ordinal(A, B: Double): Int64;
begin
Result := Ord(SameValue(A, B));
end;
-class function TRtlFunctions.Equal_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
+class function TRtlCoreFunctions.Equal_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
begin
Result := Ord(SameValue(A, B));
end;
-class function TRtlFunctions.Equal_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
+class function TRtlCoreFunctions.Equal_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
begin
Result := Ord(SameValue(A, B));
end;
-class function TRtlFunctions.Equal_Keyword_Keyword_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Equal_Keyword_Keyword_Ordinal(A, B: Int64): Int64;
begin
Result := Ord(A = B);
end;
-class function TRtlFunctions.NotEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.NotEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := Ord(A <> B);
end;
-class function TRtlFunctions.NotEqual_Float_Float_Ordinal(A, B: Double): Int64;
+class function TRtlCoreFunctions.NotEqual_Float_Float_Ordinal(A, B: Double): Int64;
begin
Result := Ord(not SameValue(A, B));
end;
-class function TRtlFunctions.NotEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
+class function TRtlCoreFunctions.NotEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
begin
Result := Ord(not SameValue(A, B));
end;
-class function TRtlFunctions.NotEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
+class function TRtlCoreFunctions.NotEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
begin
Result := Ord(not SameValue(A, B));
end;
-class function TRtlFunctions.NotEqual_Keyword_Keyword_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.NotEqual_Keyword_Keyword_Ordinal(A, B: Int64): Int64;
begin
Result := Ord(A <> B);
end;
-class function TRtlFunctions.Less_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Less_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := Ord(A < B);
end;
-class function TRtlFunctions.Less_Float_Float_Ordinal(A, B: Double): Int64;
+class function TRtlCoreFunctions.Less_Float_Float_Ordinal(A, B: Double): Int64;
begin
Result := Ord(A < B);
end;
-class function TRtlFunctions.Less_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
+class function TRtlCoreFunctions.Less_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
begin
Result := Ord(A < B);
end;
-class function TRtlFunctions.Less_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
+class function TRtlCoreFunctions.Less_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
begin
Result := Ord(A < B);
end;
-class function TRtlFunctions.LessOrEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.LessOrEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := Ord(A <= B);
end;
-class function TRtlFunctions.LessOrEqual_Float_Float_Ordinal(A, B: Double): Int64;
+class function TRtlCoreFunctions.LessOrEqual_Float_Float_Ordinal(A, B: Double): Int64;
begin
Result := Ord(A <= B);
end;
-class function TRtlFunctions.LessOrEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
+class function TRtlCoreFunctions.LessOrEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
begin
Result := Ord(A <= B);
end;
-class function TRtlFunctions.LessOrEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
+class function TRtlCoreFunctions.LessOrEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
begin
Result := Ord(A <= B);
end;
-class function TRtlFunctions.Greater_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Greater_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := Ord(A > B);
end;
-class function TRtlFunctions.Greater_Float_Float_Ordinal(A, B: Double): Int64;
+class function TRtlCoreFunctions.Greater_Float_Float_Ordinal(A, B: Double): Int64;
begin
Result := Ord(A > B);
end;
-class function TRtlFunctions.Greater_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
+class function TRtlCoreFunctions.Greater_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
begin
Result := Ord(A > B);
end;
-class function TRtlFunctions.Greater_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
+class function TRtlCoreFunctions.Greater_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
begin
Result := Ord(A > B);
end;
-class function TRtlFunctions.GreaterOrEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.GreaterOrEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := Ord(A >= B);
end;
-class function TRtlFunctions.GreaterOrEqual_Float_Float_Ordinal(A, B: Double): Int64;
+class function TRtlCoreFunctions.GreaterOrEqual_Float_Float_Ordinal(A, B: Double): Int64;
begin
Result := Ord(A >= B);
end;
-class function TRtlFunctions.GreaterOrEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
+class function TRtlCoreFunctions.GreaterOrEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64;
begin
Result := Ord(A >= B);
end;
-class function TRtlFunctions.GreaterOrEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
+class function TRtlCoreFunctions.GreaterOrEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64;
begin
Result := Ord(A >= B);
end;
// Bitwise Static
-class function TRtlFunctions.And_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.And_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A and B;
end;
-class function TRtlFunctions.Or_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Or_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A or B;
end;
-class function TRtlFunctions.Xor_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Xor_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A xor B;
end;
-class function TRtlFunctions.Shl_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Shl_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A shl B;
end;
-class function TRtlFunctions.Shr_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
+class function TRtlCoreFunctions.Shr_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
begin
Result := A shr B;
end;
// Unary
-class function TRtlFunctions.Negate_Ordinal_Ordinal(A: Int64): Int64;
+class function TRtlCoreFunctions.Negate_Ordinal_Ordinal(A: Int64): Int64;
begin
Result := -A;
end;
-class function TRtlFunctions.Negate_Float_Float(A: Double): Double;
+class function TRtlCoreFunctions.Negate_Float_Float(A: Double): Double;
begin
Result := -A;
end;
-class function TRtlFunctions.Not_Ordinal_Ordinal(A: Int64): Int64;
+class function TRtlCoreFunctions.Not_Ordinal_Ordinal(A: Int64): Int64;
begin
Result := Ord(A = 0);
end;
-// Standard
-class function TRtlFunctions.Abs_Ordinal_Ordinal(A: Int64): Int64;
-begin
- Result := System.Abs(A);
-end;
-class function TRtlFunctions.Abs_Float_Float(A: Double): Double;
-begin
- Result := System.Abs(A);
-end;
-
-class function TRtlFunctions.Add_Text_Text_Text(const A: String; const B: String): String;
-begin
- Result := A + B;
-end;
-
-class function TRtlFunctions.Round_Ordinal_Ordinal(A: Int64): Int64;
-begin
- Result := A;
-end;
-class function TRtlFunctions.Round_Float_Ordinal(A: Double): Int64;
-begin
- Result := System.Round(A);
-end;
-
-class function TRtlFunctions.Trunc_Ordinal_Ordinal(A: Int64): Int64;
-begin
- Result := A;
-end;
-class function TRtlFunctions.Trunc_Float_Ordinal(A: Double): Int64;
-begin
- Result := System.Trunc(A);
-end;
-
-class function TRtlFunctions.Sqrt_Ordinal_Float(A: Int64): Double;
-begin
- Result := System.Sqrt(A);
-end;
-
-class function TRtlFunctions.Sqrt_Float_Float(A: Double): Double;
-begin
- Result := System.Sqrt(A);
-end;
-
-class function TRtlFunctions.Pow_Ordinal_Ordinal_Float(A, B: Int64): Double;
-begin
- Result := System.Math.Power(A, B);
-end;
-
-class function TRtlFunctions.Pow_Float_Float_Float(A, B: Double): Double;
-begin
- Result := System.Math.Power(A, B);
-end;
-
-class function TRtlFunctions.Pow_Ordinal_Float_Float(A: Int64; B: Double): Double;
-begin
- Result := System.Math.Power(A, B);
-end;
-
-class function TRtlFunctions.Pow_Float_Ordinal_Float(A: Double; B: Int64): Double;
-begin
- Result := System.Math.Power(A, B);
-end;
-
-class function TRtlFunctions.Random_Void_Float: Double;
-begin
- Result := System.Random;
-end;
-
-class function TRtlFunctions.Random_Ordinal_Ordinal(Limit: Int64): Int64;
-begin
- Result := System.Random(Limit);
-end;
-
end.
diff --git a/Src/AST/Myc.Ast.RTL.DateTime.pas b/Src/AST/Myc.Ast.RTL.DateTime.pas
new file mode 100644
index 0000000..12a1584
--- /dev/null
+++ b/Src/AST/Myc.Ast.RTL.DateTime.pas
@@ -0,0 +1,59 @@
+unit Myc.Ast.RTL.DateTime;
+
+interface
+
+uses
+ System.SysUtils,
+ System.DateUtils,
+ Myc.Data.Scalar,
+ Myc.Data.Value,
+ Myc.Ast.Attributes;
+
+type
+ TRtlDateTimeFunctions = record
+ public
+ [TRtlExport('now', Impure)]
+ [AstDoc('Returns the current system timestamp.')]
+ [AstSignature('() -> datetime')]
+ class function Now(const Args: TArray): TDataValue; static;
+
+ [TRtlExport('date', Impure)]
+ [AstDoc('Returns the current date or constructs a date from Y, M, D.')]
+ [AstSignature('() -> datetime')]
+ [AstSignature('(number, number, number) -> datetime')]
+ class function Date(const Args: TArray): TDataValue; static;
+ end;
+
+implementation
+
+{ TRtlDateTimeFunctions }
+
+class function TRtlDateTimeFunctions.Now(const Args: TArray): TDataValue;
+begin
+ Result := TScalar.FromDateTime(System.SysUtils.Now);
+end;
+
+class function TRtlDateTimeFunctions.Date(const Args: TArray): TDataValue;
+
+ function GetInt(const V: TDataValue; ArgIndex: Integer): Word;
+ begin
+ if V.AsScalar.Kind <> TScalar.TKind.Ordinal then
+ raise EArgumentException.CreateFmt('Date argument %d must be an Integer.', [ArgIndex]);
+ Result := V.AsScalar.Value.AsInt64;
+ end;
+
+begin
+ if Length(Args) = 3 then
+ begin
+ var y := GetInt(Args[0], 1);
+ var m := GetInt(Args[1], 2);
+ var d := GetInt(Args[2], 3);
+ Result := TScalar.FromDateTime(EncodeDate(y, m, d));
+ end
+ else if Length(Args) = 0 then
+ Result := TScalar.FromDateTime(System.SysUtils.Date)
+ else
+ raise EArgumentException.Create('Date expects 0 or 3 arguments (Year, Month, Day).');
+end;
+
+end.
diff --git a/Src/AST/Myc.Ast.RTL.Math.pas b/Src/AST/Myc.Ast.RTL.Math.pas
new file mode 100644
index 0000000..9adeb6a
--- /dev/null
+++ b/Src/AST/Myc.Ast.RTL.Math.pas
@@ -0,0 +1,270 @@
+unit Myc.Ast.RTL.Math;
+
+interface
+
+uses
+ System.SysUtils,
+ System.Math,
+ Myc.Data.Scalar,
+ Myc.Data.Value,
+ Myc.Ast.Attributes;
+
+type
+ TRtlMathFunctions = record
+ public
+ // --- Math Functions ---
+
+ [TRtlExport('abs', Pure)]
+ [AstDoc('Returns the absolute value of a number.')]
+ [AstSignature('(number) -> number')]
+ class function Abs(const Arg: TScalar): TScalar; static;
+
+ [TRtlExport('round', Pure)]
+ [AstDoc('Rounds a float to the nearest integer.')]
+ [AstSignature('(number) -> number')]
+ class function Round(const Arg: TScalar): TScalar; static;
+
+ [TRtlExport('trunc', Pure)]
+ [AstDoc('Returns the integer part of a float.')]
+ [AstSignature('(number) -> number')]
+ class function Trunc(const Arg: TScalar): TScalar; static;
+
+ [TRtlExport('ceil', Pure)]
+ [AstDoc('Returns the smallest integer >= the argument.')]
+ [AstSignature('(number) -> number')]
+ class function Ceil(const Arg: TScalar): TScalar; static;
+
+ [TRtlExport('floor', Pure)]
+ [AstDoc('Returns the largest integer <= the argument.')]
+ [AstSignature('(number) -> number')]
+ class function Floor(const Arg: TScalar): TScalar; static;
+
+ [TRtlExport('sign', Pure)]
+ [AstDoc('Returns -1 for negative, 1 for positive, 0 for zero.')]
+ [AstSignature('(number) -> number')]
+ class function Sign(const Arg: TScalar): TScalar; static;
+
+ [TRtlExport('sqrt', Pure)]
+ [AstDoc('Returns the square root of a number.')]
+ [AstSignature('(number) -> number')]
+ class function Sqrt(const Arg: TScalar): TScalar; static;
+
+ [TRtlExport('pow', Pure)]
+ [AstDoc('Returns Base raised to the power of Exponent.')]
+ [AstSignature('(number, number) -> number')]
+ class function Pow(const Args: TArray): TDataValue; static;
+
+ [TRtlExport('random', Impure)]
+ [AstDoc('Returns a random number. No args: [0..1). Arg N: Integer [0..N).')]
+ [AstSignature('() -> float')]
+ [AstSignature('(number) -> number')]
+ class function Random(const Args: TArray): TDataValue; static;
+
+ // --- Static Specializations ---
+
+ [TRtlExport('abs', Pure)]
+ class function Abs_Ordinal_Ordinal(A: Int64): Int64; static;
+ [TRtlExport('abs', Pure)]
+ class function Abs_Float_Float(A: Double): Double; static;
+
+ [TRtlExport('round', Pure)]
+ class function Round_Ordinal_Ordinal(A: Int64): Int64; static;
+ [TRtlExport('round', Pure)]
+ class function Round_Float_Ordinal(A: Double): Int64; static;
+
+ [TRtlExport('trunc', Pure)]
+ class function Trunc_Ordinal_Ordinal(A: Int64): Int64; static;
+ [TRtlExport('trunc', Pure)]
+ class function Trunc_Float_Ordinal(A: Double): Int64; static;
+
+ [TRtlExport('sqrt', Pure)]
+ class function Sqrt_Ordinal_Float(A: Int64): Double; static;
+ [TRtlExport('sqrt', Pure)]
+ class function Sqrt_Float_Float(A: Double): Double; static;
+
+ [TRtlExport('pow', Pure)]
+ class function Pow_Ordinal_Ordinal_Float(A, B: Int64): Double; static;
+ [TRtlExport('pow', Pure)]
+ class function Pow_Float_Float_Float(A, B: Double): Double; static;
+ [TRtlExport('pow', Pure)]
+ class function Pow_Ordinal_Float_Float(A: Int64; B: Double): Double; static;
+ [TRtlExport('pow', Pure)]
+ class function Pow_Float_Ordinal_Float(A: Double; B: Int64): Double; static;
+
+ [TRtlExport('random', Impure)]
+ class function Random_Void_Float: Double; static;
+ [TRtlExport('random', Impure)]
+ class function Random_Ordinal_Ordinal(Limit: Int64): Int64; static;
+ end;
+
+implementation
+
+{ TRtlMathFunctions }
+
+class function TRtlMathFunctions.Abs(const Arg: TScalar): TScalar;
+begin
+ case Arg.Kind of
+ TScalar.TKind.Ordinal: Result := TScalar.FromInt64(System.Abs(Arg.Value.AsInt64));
+ TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromDouble(System.Abs(Arg.Value.AsDouble));
+ else
+ raise EArgumentException.Create('Abs requires a numeric argument.');
+ end;
+end;
+
+class function TRtlMathFunctions.Round(const Arg: TScalar): TScalar;
+begin
+ case Arg.Kind of
+ TScalar.TKind.Ordinal: Result := Arg;
+ TScalar.TKind.Float, TScalar.TKind.DateTime:
+ begin
+ var val: Double := Arg.Value.AsDouble;
+ Result := TScalar.FromInt64(System.Round(val));
+ end;
+ else
+ raise EArgumentException.Create('Round requires a numeric argument.');
+ end;
+end;
+
+class function TRtlMathFunctions.Trunc(const Arg: TScalar): TScalar;
+begin
+ case Arg.Kind of
+ TScalar.TKind.Ordinal: Result := Arg;
+ TScalar.TKind.Float, TScalar.TKind.DateTime:
+ begin
+ var val: Double := Arg.Value.AsDouble;
+ Result := TScalar.FromInt64(System.Trunc(val));
+ end;
+ else
+ raise EArgumentException.Create('Trunc requires a numeric argument.');
+ end;
+end;
+
+class function TRtlMathFunctions.Ceil(const Arg: TScalar): TScalar;
+begin
+ case Arg.Kind of
+ TScalar.TKind.Ordinal: Result := Arg;
+ TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromInt64(System.Math.Ceil(Arg.Value.AsDouble));
+ else
+ raise EArgumentException.Create('Ceil requires a numeric argument.');
+ end;
+end;
+
+class function TRtlMathFunctions.Floor(const Arg: TScalar): TScalar;
+begin
+ case Arg.Kind of
+ TScalar.TKind.Ordinal: Result := Arg;
+ TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromInt64(System.Math.Floor(Arg.Value.AsDouble));
+ else
+ raise EArgumentException.Create('Floor requires a numeric argument.');
+ end;
+end;
+
+class function TRtlMathFunctions.Sign(const Arg: TScalar): TScalar;
+begin
+ case Arg.Kind of
+ TScalar.TKind.Ordinal: Result := TScalar.FromInt64(System.Math.Sign(Arg.Value.AsInt64));
+ TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromInt64(System.Math.Sign(Arg.Value.AsDouble));
+ else
+ raise EArgumentException.Create('Sign requires a numeric argument.');
+ end;
+end;
+
+class function TRtlMathFunctions.Sqrt(const Arg: TScalar): TScalar;
+begin
+ var val: Double := Arg; // Implicit cast handles Ordinal and Float
+ Result := TScalar.FromDouble(System.Sqrt(val));
+end;
+
+class function TRtlMathFunctions.Pow(const Args: TArray): TDataValue;
+begin
+ if Length(Args) <> 2 then
+ raise EArgumentException.Create('Pow requires 2 arguments (Base, Exponent).');
+
+ var baseVal: Double := Args[0].AsScalar;
+ var expVal: Double := Args[1].AsScalar;
+ Result := TScalar.FromDouble(System.Math.Power(baseVal, expVal));
+end;
+
+class function TRtlMathFunctions.Random(const Args: TArray): TDataValue;
+begin
+ if Length(Args) = 0 then
+ Result := TScalar.FromDouble(System.Random)
+ else if (Length(Args) = 1) and (Args[0].AsScalar.Kind = TScalar.TKind.Ordinal) then
+ Result := TScalar.FromInt64(System.Random(Integer(Args[0].AsScalar.Value.AsInt64)))
+ else
+ raise EArgumentException.Create('Random expects 0 arguments or 1 integer argument.');
+end;
+
+// --- Static Specializations ---
+
+class function TRtlMathFunctions.Abs_Ordinal_Ordinal(A: Int64): Int64;
+begin
+ Result := System.Abs(A);
+end;
+
+class function TRtlMathFunctions.Abs_Float_Float(A: Double): Double;
+begin
+ Result := System.Abs(A);
+end;
+
+class function TRtlMathFunctions.Round_Ordinal_Ordinal(A: Int64): Int64;
+begin
+ Result := A;
+end;
+
+class function TRtlMathFunctions.Round_Float_Ordinal(A: Double): Int64;
+begin
+ Result := System.Round(A);
+end;
+
+class function TRtlMathFunctions.Trunc_Ordinal_Ordinal(A: Int64): Int64;
+begin
+ Result := A;
+end;
+
+class function TRtlMathFunctions.Trunc_Float_Ordinal(A: Double): Int64;
+begin
+ Result := System.Trunc(A);
+end;
+
+class function TRtlMathFunctions.Sqrt_Ordinal_Float(A: Int64): Double;
+begin
+ Result := System.Sqrt(A);
+end;
+
+class function TRtlMathFunctions.Sqrt_Float_Float(A: Double): Double;
+begin
+ Result := System.Sqrt(A);
+end;
+
+class function TRtlMathFunctions.Pow_Ordinal_Ordinal_Float(A, B: Int64): Double;
+begin
+ Result := System.Math.Power(A, B);
+end;
+
+class function TRtlMathFunctions.Pow_Float_Float_Float(A, B: Double): Double;
+begin
+ Result := System.Math.Power(A, B);
+end;
+
+class function TRtlMathFunctions.Pow_Ordinal_Float_Float(A: Int64; B: Double): Double;
+begin
+ Result := System.Math.Power(A, B);
+end;
+
+class function TRtlMathFunctions.Pow_Float_Ordinal_Float(A: Double; B: Int64): Double;
+begin
+ Result := System.Math.Power(A, B);
+end;
+
+class function TRtlMathFunctions.Random_Void_Float: Double;
+begin
+ Result := System.Random;
+end;
+
+class function TRtlMathFunctions.Random_Ordinal_Ordinal(Limit: Int64): Int64;
+begin
+ Result := System.Random(Limit);
+end;
+
+end.
diff --git a/Src/AST/Myc.Ast.RTL.Series.pas b/Src/AST/Myc.Ast.RTL.Series.pas
new file mode 100644
index 0000000..19d0f04
--- /dev/null
+++ b/Src/AST/Myc.Ast.RTL.Series.pas
@@ -0,0 +1,247 @@
+unit Myc.Ast.RTL.Series;
+
+interface
+
+uses
+ System.SysUtils,
+ System.Generics.Collections,
+ Myc.Data.Scalar,
+ Myc.Data.Value,
+ Myc.Data.Series,
+ Myc.Ast.Attributes;
+
+type
+ TRtlSeriesFunctions = record
+ public
+ // --- Functional / Series ---
+
+ [TRtlExport('memoize', Pure)]
+ [AstDoc('Creates a memoized version of a function for performance.')]
+ [AstSignature('((any) -> any) -> ((any) -> any)')]
+ class function Memoize(const Args: TArray): TDataValue; static;
+
+ [TRtlExport('map', Pure)]
+ [AstDoc('Applies a function to every element of a series.')]
+ [AstSignature('(series, (any) -> any) -> series')]
+ class function Map(const Args: TArray): TDataValue; static;
+
+ [TRtlExport('reduce', Pure)]
+ [AstDoc('Collapses a series into a single value using a reducer function.')]
+ [AstSignature('(series, any, (any, any) -> any) -> any')]
+ class function Reduce(const Args: TArray): TDataValue; static;
+
+ [TRtlExport('where', Pure)]
+ [AstDoc('Filters a series based on a predicate function.')]
+ [AstSignature('(series, (any) -> boolean) -> series')]
+ class function Where(const Args: TArray): TDataValue; static;
+
+ [TRtlExport('any', Pure)]
+ [AstDoc('Returns true if at least one element satisfies the predicate.')]
+ [AstSignature('(series, (any) -> boolean) -> boolean')]
+ class function Any(const Args: TArray): TDataValue; static;
+ end;
+
+implementation
+
+{ TRtlSeriesFunctions }
+
+class function TRtlSeriesFunctions.Memoize(const Args: TArray): TDataValue;
+var
+ funcToMemoize: TDataValue.TFunc;
+ memoizedFunc: TDataValue.TFunc;
+begin
+ if Length(Args) <> 1 then
+ raise EArgumentException.Create('Memoize requires exactly one argument.');
+ if Args[0].Kind <> vkMethod then
+ raise EArgumentException.Create('The argument to Memoize must be a function.');
+
+ // We store the dictionary inside a TObjVal wrapped in a TDataValue to keep it alive
+ // as part of the closure's captured state (or rather, accessible via the closure).
+ // Note: In a pure closure implementation, capturing a local variable would be enough,
+ // but here we ensure explicit lifetime management via the TDataValue ownership mechanism if needed.
+ var cCache: TDataValue;
+ cCache.FromObj(TDictionary.Create);
+
+ funcToMemoize := Args[0].AsMethod();
+
+ memoizedFunc :=
+ function(const AArgs: TArray): TDataValue
+ var
+ argScalar: TScalar;
+ key: Int64;
+ begin
+ if (Length(AArgs) <> 1) or (AArgs[0].Kind <> vkScalar) then
+ raise EArgumentException.Create('This memoized function can only be called with a single scalar argument.');
+
+ argScalar := AArgs[0].AsScalar;
+ if argScalar.Kind <> TScalar.TKind.Ordinal then
+ raise EArgumentException.Create('This memoized function expects an ordinal argument for caching.');
+
+ key := argScalar.Value.AsInt64;
+
+ // Unsafe cast is safe here because we created it above
+ var cache := TDictionary(cCache.AsObject);
+
+ if cache.TryGetValue(key, Result) then
+ exit;
+
+ Result := funcToMemoize(AArgs);
+ cache.Add(key, Result);
+ end;
+
+ Result := TDataValue(memoizedFunc);
+end;
+
+class function TRtlSeriesFunctions.Map(const Args: TArray): TDataValue;
+var
+ sourceArg: TDataValue;
+begin
+ if Length(Args) <> 2 then
+ raise EArgumentException.Create('Map requires exactly two arguments: a series and a function.');
+
+ sourceArg := Args[0];
+ if not (sourceArg.Kind in [vkSeries]) then
+ raise EArgumentException.Create('The first argument to Map must be a series.');
+
+ if Args[1].Kind <> vkMethod then
+ raise EArgumentException.Create('The second argument to Map must be a function.');
+
+ Result := TDataValue.Map(sourceArg.AsSeries, Args[1].AsMethod());
+end;
+
+class function TRtlSeriesFunctions.Reduce(const Args: TArray): TDataValue;
+var
+ sourceArg: TDataValue;
+ sourceSeries: ISeries;
+ accumulator: TDataValue;
+ reducerFunc: TDataValue.TFunc;
+ i: Integer;
+ currentItem: TScalar;
+ reducerArgs: TArray;
+begin
+ if Length(Args) <> 3 then
+ raise EArgumentException.Create('Reduce requires exactly three arguments: a series, an initial value, and a reducer function.');
+
+ sourceArg := Args[0];
+ if sourceArg.Kind <> vkSeries then
+ raise EArgumentException.Create('The first argument to Reduce must be a series.');
+
+ if Args[2].Kind <> vkMethod then
+ raise EArgumentException.Create('The third argument to Reduce must be a function.');
+
+ sourceSeries := sourceArg.AsSeries;
+ accumulator := Args[1];
+ reducerFunc := Args[2].AsMethod();
+
+ // Reduce typically iterates from oldest to newest (index count-1 downto 0 in standard array,
+ // but TSeries logic might define 0 as newest. Assuming standard iteration order here).
+ // Note: Based on previous TSeries implementation, Index 0 is newest.
+ // Usually Reduce goes chronologically: Oldest (High) -> Newest (0).
+ for i := sourceSeries.Count - 1 downto 0 do
+ begin
+ currentItem := sourceSeries.Items[i];
+ reducerArgs := [accumulator, TDataValue(currentItem)];
+ accumulator := reducerFunc(reducerArgs);
+ end;
+
+ Result := accumulator;
+end;
+
+class function TRtlSeriesFunctions.Where(const Args: TArray): TDataValue;
+var
+ sourceArg: TDataValue;
+ sourceSeries: ISeries;
+ predicateFunc: TDataValue.TFunc;
+ matchingIndices: TList;
+ i: Integer;
+ item: TScalar;
+ predicateResult: TDataValue;
+ indexSeries: ISeries;
+ mapperFunc: TDataValue.TFunc;
+begin
+ if Length(Args) <> 2 then
+ raise EArgumentException.Create('Where requires exactly two arguments: a series and a predicate function.');
+
+ sourceArg := Args[0];
+ if sourceArg.Kind <> vkSeries then
+ raise EArgumentException.Create('The first argument to Where must be a series.');
+
+ if Args[1].Kind <> vkMethod then
+ raise EArgumentException.Create('The second argument to Where must be a function.');
+
+ sourceSeries := sourceArg.AsSeries;
+ predicateFunc := Args[1].AsMethod();
+
+ matchingIndices := TList.Create;
+ try
+ // We scan all items. Order doesn't strictly matter for building the index list
+ // if we just want to filter, but keeping order is good.
+ // Iterating 0 to Count-1 (Newest to Oldest) or vice versa depends on desired output series order.
+ // TIndexSeries usually expects indices.
+ for i := 0 to sourceSeries.Count - 1 do
+ begin
+ item := sourceSeries.Items[i];
+ // Perf warning: Allocation of array for every call
+ predicateResult := predicateFunc([TDataValue(item)]);
+
+ if (predicateResult.Kind = vkScalar) and (Boolean(predicateResult.AsScalar)) then
+ matchingIndices.Add(i);
+ end;
+
+ indexSeries := TIndexSeries.Create(matchingIndices.ToArray);
+ finally
+ matchingIndices.Free;
+ end;
+
+ // Create a lazy mapper that looks up the original value based on the index
+ mapperFunc :=
+ function(const AArgs: TArray): TDataValue
+ var
+ idx: Integer;
+ begin
+ idx := AArgs[0].AsScalar.Value.AsInt64;
+ Result := TDataValue(sourceSeries.Items[idx]);
+ end;
+
+ // Result is a new series containing only the filtered items
+ Result := TDataValue.Map(indexSeries, mapperFunc);
+end;
+
+class function TRtlSeriesFunctions.Any(const Args: TArray): TDataValue;
+var
+ sourceArg: TDataValue;
+ sourceSeries: ISeries;
+ predicateFunc: TDataValue.TFunc;
+ i: Integer;
+ item: TScalar;
+ predicateResult: TDataValue;
+begin
+ if Length(Args) <> 2 then
+ raise EArgumentException.Create('Any requires exactly two arguments: a series and a predicate function.');
+
+ sourceArg := Args[0];
+ if sourceArg.Kind <> vkSeries then
+ raise EArgumentException.Create('The first argument to Any must be a series.');
+
+ if Args[1].Kind <> vkMethod then
+ raise EArgumentException.Create('The second argument to Any must be a function.');
+
+ sourceSeries := sourceArg.AsSeries;
+ predicateFunc := Args[1].AsMethod();
+
+ for i := 0 to sourceSeries.Count - 1 do
+ begin
+ item := sourceSeries.Items[i];
+ predicateResult := predicateFunc([TDataValue(item)]);
+
+ if (predicateResult.Kind = vkScalar) and (Boolean(predicateResult.AsScalar)) then
+ begin
+ Result := TScalar.FromBoolean(True);
+ exit;
+ end;
+ end;
+
+ Result := TScalar.FromBoolean(False);
+end;
+
+end.
diff --git a/Src/AST/Myc.Ast.RTL.pas b/Src/AST/Myc.Ast.RTL.pas
index ba9ba65..d23e73d 100644
--- a/Src/AST/Myc.Ast.RTL.pas
+++ b/Src/AST/Myc.Ast.RTL.pas
@@ -2,9 +2,6 @@ unit Myc.Ast.RTL;
interface
-// This unit is intended to be included in a 'uses' clause.
-// It self-registers its functions via its initialization section.
-
uses
System.SysUtils,
System.Generics.Collections,
@@ -19,27 +16,11 @@ uses
Myc.Ast.Types;
type
- // Defines the export parameters for a native RTL function.
- TRtlExportAttribute = class(TCustomAttribute)
- type
- TPurity = (Pure, Impure);
- public
- Name: string;
- IsPure: Boolean;
- constructor Create(const AName: string); overload;
- constructor Create(const AName: string; APurity: TPurity); overload;
- end;
+ //==============================================================================================
+ // Internal Structures
+ //==============================================================================================
- // Defines a constant export (via class function).
- // The registry will INVOKE this function at startup and register the RESULT as a value.
- TRtlConstAttribute = class(TCustomAttribute)
- public
- Name: string;
- constructor Create(const AName: string);
- end;
-
-// Defines the key for the static bootstrap cache.
-type
+ // Key used to identify specific overloads of a function based on argument types.
TStaticSignatureKey = record
public
Name: string;
@@ -47,13 +28,14 @@ type
constructor Create(const AName: string; const AArgTypes: TArray);
end;
- // Comparer for the static signature key
+ // Equality comparer for TStaticSignatureKey to be used in dictionaries.
TStaticSignatureKeyComparer = class(TEqualityComparer)
public
function Equals(const Left, Right: TStaticSignatureKey): Boolean; override;
function GetHashCode(const Value: TStaticSignatureKey): Integer; override;
end;
+ // Holds a reference to a specialized, type-safe native function wrapper.
TSpecializedMethod = record
public
Target: TDataValue.TFunc;
@@ -62,21 +44,22 @@ type
constructor Create(const ATarget: TDataValue.TFunc; const AReturnType: IStaticType; AIsPure: Boolean);
end;
- // The cache holding TDataValue.TFunc wrappers for static native functions.
+ // Cache for static specializations.
TStaticBootstrapCache = TDictionary;
+ // Metadata for a registered function, including dynamic fallback and signatures.
TRtlFunctionInfo = class
public
DynamicWrapper: TDataValue.TFunc;
Signatures: TList;
- Doc: string; // Documentation string from AstDoc attribute
+ Doc: string;
constructor Create;
destructor Destroy; override;
end;
TRtlFunctionMap = TDictionary;
- // Container for constant metadata
+ // Metadata for a registered constant.
TRtlConstantInfo = record
Name: string;
Value: TDataValue;
@@ -85,14 +68,18 @@ type
constructor Create(const AName: string; const AValue: TDataValue; const AType: IStaticType; const ADoc: string);
end;
- //--------------------------------------------------------------------------------------------------
- //== Library Registration (RTTI-based)
- //--------------------------------------------------------------------------------------------------
+ //==============================================================================================
+ // RTL Registry
+ //==============================================================================================
- // A helper record to encapsulate the RTTI-based registration logic.
+ // Central registry logic using RTTI to scan provider classes.
TRtlRegistry = record
+ private
+ // Function pointer types for static wrappers
type
- // --- Static Wrapper Signatures ---
+ TNativeDataValueFunc = function(const Args: TArray): TDataValue;
+ TNativeScalarFunc = function(Arg: TScalar): TScalar;
+
TNativeFunc_O_O = function(A: Int64): Int64;
TNativeFunc_F_F = function(A: Double): Double;
TNativeFunc_F_O = function(A: Double): Int64;
@@ -112,15 +99,13 @@ type
private
class var
FStaticBootstrap: TStaticBootstrapCache;
- class var
FStaticFuncMap: TRtlFunctionMap;
- class var
FStaticConstList: TList;
class constructor Create;
class destructor Destroy;
- // --- Wrapper Creation Helpers ---
+ // Wrapper generators for specific function signatures
class function CreateWrapper_O_O(CodeAddress: Pointer): TDataValue.TFunc; static;
class function CreateWrapper_F_F(CodeAddress: Pointer): TDataValue.TFunc; static;
class function CreateWrapper_F_O(CodeAddress: Pointer): TDataValue.TFunc; static;
@@ -136,19 +121,14 @@ type
class function CreateWrapper_FO_O(CodeAddress: Pointer): TDataValue.TFunc; static;
class function CreateWrapper_TT_T(CodeAddress: Pointer): TDataValue.TFunc; static;
- // --- RTTI Helpers ---
- class function RttiTypeToStaticType(const AType: TRttiType): IStaticType; static;
+ // Helpers
class function TValueToDataValue(const V: TValue): TDataValue; static;
-
+ class function RttiTypeToStaticType(const AType: TRttiType): IStaticType; static;
class function ParseStaticSuffix(
const AMethodName: string;
out AArgTypes: TArray;
out AReturnType: IStaticType
): Boolean; static;
-
- public
- class procedure RegisterAll(const AScope: IExecutionScope); static;
-
class function CreateStaticWrapper(
method: TRttiMethod;
retType: IStaticType;
@@ -156,7 +136,14 @@ type
rttiParams: TArray
): TDataValue.TFunc; static;
- // Public accessor for the TStaticSpecializer
+ public
+ // Scans a specific provider type for attributes and registers them internally.
+ class procedure Scan; static;
+
+ // Dumps all registered functions and constants into the execution scope.
+ class procedure RegisterAll(const AScope: IExecutionScope); static;
+
+ // API for the type checker to retrieve specialized methods.
class function GetStaticSpecialization(const AName: string; const AArgTypes: TArray): TSpecializedMethod; static;
class procedure RegisterStaticSpecialization(
const AName: string;
@@ -165,6 +152,7 @@ type
); static;
end;
+// Main entry point for library registration.
procedure RegisterRtlFunctions(const AScope: IExecutionScope);
implementation
@@ -173,39 +161,14 @@ uses
System.Hash,
System.StrUtils,
Myc.Ast.Attributes,
- Myc.Ast.RTL.Core;
+ Myc.Ast.RTL.Core,
+ Myc.Ast.RTL.Math,
+ Myc.Ast.RTL.Series,
+ Myc.Ast.RTL.DateTime;
-type
- TNativeDataValueFunc = function(const Args: TArray): TDataValue;
- TNativeScalarFunc = function(Arg: TScalar): TScalar;
-
-//--------------------------------------------------------------------------------------------------
-//== Native Function Implementation (Core Logic)
-//--------------------------------------------------------------------------------------------------
-
-constructor TRtlExportAttribute.Create(const AName: string);
-begin
- inherited Create;
- Self.Name := AName;
- Self.IsPure := False; // Default to impure (safe)
-end;
-
-constructor TRtlExportAttribute.Create(const AName: string; APurity: TPurity);
-begin
- inherited Create;
- Self.Name := AName;
- Self.IsPure := APurity = Pure;
-end;
-
-{ TRtlConstAttribute }
-
-constructor TRtlConstAttribute.Create(const AName: string);
-begin
- inherited Create;
- Name := AName;
-end;
-
-{ TStaticSignatureKey }
+//==================================================================================================
+// Helper Structure Implementations
+//==================================================================================================
constructor TStaticSignatureKey.Create(const AName: string; const AArgTypes: TArray);
begin
@@ -213,8 +176,6 @@ begin
ArgTypes := AArgTypes;
end;
-{ TStaticSignatureKeyComparer }
-
function TStaticSignatureKeyComparer.Equals(const Left, Right: TStaticSignatureKey): Boolean;
var
i: Integer;
@@ -223,42 +184,28 @@ begin
exit(False);
if Length(Left.ArgTypes) <> Length(Right.ArgTypes) then
exit(False);
-
- // Compare types
for i := 0 to High(Left.ArgTypes) do
- begin
if not Left.ArgTypes[i].IsEqual(Right.ArgTypes[i]) then
exit(False);
- end;
-
Result := True;
end;
function TStaticSignatureKeyComparer.GetHashCode(const Value: TStaticSignatureKey): Integer;
var
- i: Integer;
- hash: Integer;
- ptrHash: Integer;
+ i, hash, ptrHash: Integer;
begin
- // 1. Hash the function name to get the initial value
hash := THashBobJenkins.GetHashValue(Value.Name);
-
- // 2. Iteratively combine the hash of each argument type
for i := 0 to High(Value.ArgTypes) do
begin
if Assigned(Value.ArgTypes[i]) then
ptrHash := Value.ArgTypes[i].GetHashCode
else
ptrHash := 0;
-
hash := THashBobJenkins.GetHashValue(ptrHash, SizeOf(Integer), hash);
end;
-
Result := hash;
end;
-{ TRtlFunctionInfo }
-
constructor TRtlFunctionInfo.Create;
begin
inherited Create;
@@ -273,8 +220,6 @@ begin
inherited Destroy;
end;
-{ TRtlConstantInfo }
-
constructor TRtlConstantInfo.Create(const AName: string; const AValue: TDataValue; const AType: IStaticType; const ADoc: string);
begin
Name := AName;
@@ -283,8 +228,6 @@ begin
Doc := ADoc;
end;
-{ TSpecializedMethod }
-
constructor TSpecializedMethod.Create(const ATarget: TDataValue.TFunc; const AReturnType: IStaticType; AIsPure: Boolean);
begin
Target := ATarget;
@@ -292,7 +235,153 @@ begin
IsPure := AIsPure;
end;
-{ TRtlRegistry }
+//==================================================================================================
+// TRtlRegistry Implementation
+//==================================================================================================
+
+class constructor TRtlRegistry.Create;
+begin
+ FStaticBootstrap := TStaticBootstrapCache.Create(TStaticSignatureKeyComparer.Create);
+ FStaticFuncMap := TRtlFunctionMap.Create;
+ FStaticConstList := TList.Create;
+end;
+
+class destructor TRtlRegistry.Destroy;
+var
+ funcInfo: TRtlFunctionInfo;
+begin
+ for funcInfo in FStaticFuncMap.Values do
+ funcInfo.Free;
+ FStaticFuncMap.Free;
+ FStaticConstList.Free;
+ FStaticBootstrap.Free;
+end;
+
+class procedure TRtlRegistry.Scan;
+var
+ ctx: TRttiContext;
+ typ: TRttiType;
+ method: TRttiMethod;
+ attribute: TCustomAttribute;
+ exportAttr: TRtlExportAttribute;
+ constAttr: TRtlConstAttribute;
+ docString, rtlName: string;
+ argTypes: TArray;
+ retType: IStaticType;
+ methodRecord: TSpecializedMethod;
+ funcInfo: TRtlFunctionInfo;
+ constInfo: TRtlConstantInfo;
+ rttiParams: TArray;
+ isDynamic: Boolean;
+ i: Integer;
+begin
+ ctx := TRttiContext.Create;
+ try
+ typ := ctx.GetType(TypeInfo(T));
+ if typ = nil then
+ exit;
+
+ for method in typ.GetMethods do
+ begin
+ if method.MethodKind <> mkClassFunction then
+ continue;
+
+ exportAttr := nil;
+ constAttr := nil;
+ docString := '';
+
+ // Extract attributes
+ for attribute in method.GetAttributes do
+ begin
+ if attribute is TRtlExportAttribute then
+ exportAttr := attribute as TRtlExportAttribute
+ else if attribute is TRtlConstAttribute then
+ constAttr := attribute as TRtlConstAttribute
+ else if attribute is AstDocAttribute then
+ docString := AstDocAttribute(attribute).Description;
+ end;
+
+ // --- CASE A: CONSTANT (via class function) ---
+ if Assigned(constAttr) then
+ begin
+ var val: TValue := method.Invoke(nil, []);
+ var dataVal: TDataValue := TValueToDataValue(val);
+ var staticType: IStaticType := RttiTypeToStaticType(method.ReturnType);
+ constInfo := TRtlConstantInfo.Create(constAttr.Name, dataVal, staticType, docString);
+ FStaticConstList.Add(constInfo);
+ continue;
+ end;
+
+ // --- CASE B: FUNCTION ---
+ if not Assigned(exportAttr) then
+ continue;
+
+ rtlName := exportAttr.Name;
+ if not FStaticFuncMap.TryGetValue(rtlName, funcInfo) then
+ begin
+ funcInfo := TRtlFunctionInfo.Create;
+ FStaticFuncMap.Add(rtlName, funcInfo);
+ end;
+
+ if (funcInfo.Doc = '') and (docString <> '') then
+ funcInfo.Doc := docString;
+
+ rttiParams := method.GetParameters;
+ isDynamic :=
+ (Length(rttiParams) = 1)
+ and (method.ReturnType.Handle = TypeInfo(TDataValue))
+ and (rttiParams[0].ParamType.Handle = TypeInfo(TArray));
+
+ if isDynamic then
+ begin
+ // Dynamic wrapper (Interpreted mode)
+ if Assigned(funcInfo.DynamicWrapper) then
+ raise EInvalidOpException.CreateFmt('Duplicate dynamic fallback defined for %s', [rtlName]);
+
+ var wrapperFactory :=
+ function(CodeAddress: Pointer): TDataValue.TFunc
+ begin
+ Result :=
+ function(const Args: TArray): TDataValue
+ begin
+ Result := TNativeDataValueFunc(CodeAddress)(Args);
+ end;
+ end;
+ funcInfo.DynamicWrapper := wrapperFactory(method.CodeAddress);
+ end
+ else
+ begin
+ // Static wrapper (Compiled mode / Fast path)
+ if not ParseStaticSuffix(method.Name, argTypes, retType) then
+ begin
+ // Fallback to RTTI if name convention fails
+ SetLength(argTypes, Length(rttiParams));
+ for i := 0 to High(rttiParams) do
+ argTypes[i] := RttiTypeToStaticType(rttiParams[i].ParamType);
+ retType := RttiTypeToStaticType(method.ReturnType);
+ end;
+
+ var sig := TMethodSignature.Create(argTypes, retType);
+ funcInfo.Signatures.Add(sig);
+
+ var wrapper := CreateStaticWrapper(method, retType, argTypes, rttiParams);
+ if Assigned(wrapper) then
+ begin
+ methodRecord := TSpecializedMethod.Create(wrapper, retType, exportAttr.IsPure);
+ RegisterStaticSpecialization(rtlName, argTypes, methodRecord);
+
+ // Use static wrapper as fallback for interpreter if no dynamic wrapper exists
+ if (not Assigned(funcInfo.DynamicWrapper)) and (Length(argTypes) = 1) and (argTypes[0].Kind = stUnknown) then
+ funcInfo.DynamicWrapper := wrapper;
+ end
+ else
+ raise ENotImplemented.CreateFmt('Wrapper for %s not implemented', [method.Name]);
+ end;
+ end;
+ finally
+ ctx.Free;
+ end;
+end;
class function TRtlRegistry.TValueToDataValue(const V: TValue): TDataValue;
begin
@@ -310,299 +399,14 @@ begin
end;
end;
-class constructor TRtlRegistry.Create;
-var
- ctx: TRttiContext;
- rtlType: TRttiType;
- method: TRttiMethod;
- attribute: TCustomAttribute;
- exportAttr: TRtlExportAttribute;
- constAttr: TRtlConstAttribute;
- rtlName: string;
- argTypes: TArray;
- retType: IStaticType;
- methodRecord: TSpecializedMethod;
- funcInfo: TRtlFunctionInfo;
- constInfo: TRtlConstantInfo;
- rttiParams: TArray;
- isDynamic: Boolean;
- i: Integer;
- docString: string;
-begin
- // 1. Create global caches
- FStaticBootstrap := TStaticBootstrapCache.Create(TStaticSignatureKeyComparer.Create);
- FStaticFuncMap := TRtlFunctionMap.Create;
- FStaticConstList := TList.Create;
-
- // 2. Perform RTTI Scan
- ctx := TRttiContext.Create;
- try
- rtlType := ctx.GetType(TypeInfo(TRtlFunctions));
-
- // --- SCAN METHODS ---
- // Includes Class Functions used as Constants!
- for method in rtlType.GetMethods do
- begin
- if method.MethodKind <> mkClassFunction then
- continue;
-
- exportAttr := nil;
- constAttr := nil;
- docString := '';
-
- for attribute in method.GetAttributes do
- begin
- if attribute is TRtlExportAttribute then
- exportAttr := attribute as TRtlExportAttribute
- else if attribute is TRtlConstAttribute then
- constAttr := attribute as TRtlConstAttribute
- else if attribute is AstDocAttribute then
- docString := AstDocAttribute(attribute).Description;
- end;
-
- // --- CASE A: CONSTANT (via class function) ---
- if Assigned(constAttr) then
- begin
- // Since this is a static method (class function), we can invoke it with nil instance
- // to get the value immediately.
- var val: TValue := method.Invoke(nil, []);
- var dataVal: TDataValue := TValueToDataValue(val);
- var staticType: IStaticType := RttiTypeToStaticType(method.ReturnType);
-
- constInfo := TRtlConstantInfo.Create(constAttr.Name, dataVal, staticType, docString);
- FStaticConstList.Add(constInfo);
- continue; // Done with this method
- end;
-
- // --- CASE B: FUNCTION ---
- if not Assigned(exportAttr) then
- continue;
-
- rtlName := exportAttr.Name;
-
- if not FStaticFuncMap.TryGetValue(rtlName, funcInfo) then
- begin
- funcInfo := TRtlFunctionInfo.Create;
- FStaticFuncMap.Add(rtlName, funcInfo);
- end;
-
- // Update documentation (if not already set or override)
- if (funcInfo.Doc = '') and (docString <> '') then
- funcInfo.Doc := docString;
-
- // Check Signature Type (Dynamic vs Static)
- rttiParams := method.GetParameters;
- isDynamic :=
- (Length(rttiParams) = 1)
- and (method.ReturnType.Handle = TypeInfo(TDataValue))
- and (rttiParams[0].ParamType.Handle = TypeInfo(TArray));
-
- if isDynamic then
- begin
- if Assigned(funcInfo.DynamicWrapper) then
- raise EInvalidOpException.CreateFmt('Duplicate dynamic fallback defined for %s', [rtlName]);
-
- var wrapperFactory :=
- function(CodeAddress: Pointer): TDataValue.TFunc
- begin
- Result :=
- function(const Args: TArray): TDataValue
- begin
- Result := TNativeDataValueFunc(CodeAddress)(Args);
- end;
- end;
- funcInfo.DynamicWrapper := wrapperFactory(method.CodeAddress);
- end
- else
- begin
- // This is a STATIC SPECIALIZATION
- if not ParseStaticSuffix(method.Name, argTypes, retType) then
- begin
- SetLength(argTypes, Length(rttiParams));
- for i := 0 to High(rttiParams) do
- argTypes[i] := RttiTypeToStaticType(rttiParams[i].ParamType);
- retType := RttiTypeToStaticType(method.ReturnType);
- end;
-
- var sig := TMethodSignature.Create(argTypes, retType);
- funcInfo.Signatures.Add(sig);
-
- var wrapper := CreateStaticWrapper(method, retType, argTypes, rttiParams);
- if Assigned(wrapper) then
- begin
- methodRecord := TSpecializedMethod.Create(wrapper, retType, exportAttr.IsPure);
- RegisterStaticSpecialization(rtlName, argTypes, methodRecord);
-
- // If this is a generic wrapper (e.g. Abs(TScalar)) and no DynamicWrapper exists yet,
- // use this wrapper as the interpreter fallback!
- if (not Assigned(funcInfo.DynamicWrapper)) and (Length(argTypes) = 1) and (argTypes[0].Kind = stUnknown) then
- begin
- funcInfo.DynamicWrapper := wrapper;
- end;
- end
- else
- raise ENotImplemented.CreateFmt('Static native method wrapper for %s() not implemented', [method.Name]);
- end;
- end;
-
- finally
- ctx.Free;
- end;
-end;
-
-class destructor TRtlRegistry.Destroy;
-var
- funcInfo: TRtlFunctionInfo;
-begin
- for funcInfo in FStaticFuncMap.Values do
- funcInfo.Free;
- FStaticFuncMap.Free;
-
- FStaticConstList.Free;
- FStaticBootstrap.Free;
-end;
-
-class function TRtlRegistry.GetStaticSpecialization(const AName: string; const AArgTypes: TArray): TSpecializedMethod;
-var
- key: TStaticSignatureKey;
-begin
- key.Name := AName;
- key.ArgTypes := AArgTypes;
- FStaticBootstrap.TryGetValue(key, Result);
-end;
-
-class procedure TRtlRegistry.RegisterStaticSpecialization(
- const AName: string;
- const AArgTypes: TArray;
- const AMethod: TSpecializedMethod
-);
-var
- key: TStaticSignatureKey;
-begin
- key := TStaticSignatureKey.Create(AName, AArgTypes);
- FStaticBootstrap.AddOrSetValue(key, AMethod);
-end;
-
-class function TRtlRegistry.RttiTypeToStaticType(const AType: TRttiType): IStaticType;
-begin
- if not Assigned(AType) then
- exit(TTypes.Unknown);
-
- if AType.Handle = TypeInfo(Int64) then
- Result := TTypes.Ordinal
- else if AType.Handle = TypeInfo(Double) then
- Result := TTypes.Float
- else if AType.Handle = TypeInfo(string) then
- Result := TTypes.Text
- else if (AType.Handle = TypeInfo(TScalar)) or (AType.Handle = TypeInfo(TDataValue)) then
- Result := TTypes.Unknown
- else
- Result := TTypes.Unknown;
-end;
-
-class function TRtlRegistry.ParseStaticSuffix(
- const AMethodName: string;
- out AArgTypes: TArray;
- out AReturnType: IStaticType
-): Boolean;
-var
- parts: TArray;
- i: Integer;
- t: IStaticType;
-
- function ParseType(const S: string): IStaticType;
- begin
- if SameText(S, 'Ordinal') then
- Result := TTypes.Ordinal
- else if SameText(S, 'Float') then
- Result := TTypes.Float
- else if SameText(S, 'Keyword') then
- Result := TTypes.Keyword
- else if SameText(S, 'Boolean') then
- Result := TTypes.Boolean
- else if SameText(S, 'DateTime') then
- Result := TTypes.DateTime
- else
- Result := TTypes.Unknown;
- end;
-
-begin
- Result := False;
- AReturnType := TTypes.Unknown;
- AArgTypes := nil;
-
- parts := AMethodName.Split(['_']);
-
- if Length(parts) < 2 then
- exit;
-
- AReturnType := ParseType(parts[High(parts)]);
- if AReturnType.Kind = stUnknown then
- exit;
-
- SetLength(AArgTypes, Length(parts) - 2);
- if Length(AArgTypes) = 0 then
- begin
- Result := True;
- exit;
- end;
-
- for i := 1 to High(parts) - 1 do
- begin
- t := ParseType(parts[i]);
- if t.Kind = stUnknown then
- begin
- AArgTypes := nil;
- AReturnType := TTypes.Unknown;
- exit(False);
- end;
- AArgTypes[i - 1] := t;
- end;
-
- Result := True;
-end;
-
-class procedure TRtlRegistry.RegisterAll(const AScope: IExecutionScope);
-var
- rtlName: string;
- funcInfo: TRtlFunctionInfo;
- constInfo: TRtlConstantInfo;
- staticType: IStaticType;
- pair: TPair;
-begin
- // Register Functions
- for pair in FStaticFuncMap do
- begin
- rtlName := pair.Key;
- funcInfo := pair.Value;
-
- if funcInfo.Signatures.Count > 0 then
- staticType := TTypes.CreateMethodSet(funcInfo.Signatures.ToArray)
- else
- staticType := nil;
-
- var wrapper := funcInfo.DynamicWrapper; // Default is Void
-
- // Pass documentation to scope definition
- AScope.Define(rtlName, wrapper, staticType, funcInfo.Doc);
- end;
-
- // Register Constants
- for constInfo in FStaticConstList do
- begin
- AScope.Define(constInfo.Name, constInfo.Value, constInfo.StaticType, constInfo.Doc);
- end;
-end;
-
-// --- Wrapper Generation ---
+// --- Wrapper Implementations ---
class function TRtlRegistry.CreateWrapper_O_O(CodeAddress: Pointer): TDataValue.TFunc;
begin
Result :=
function(const Args: TArray): TDataValue
var
- A: Int64;
- Res: Int64;
+ A, Res: Int64;
begin
A := Args[0].AsScalar.Value.AsInt64;
Res := TNativeFunc_O_O(CodeAddress)(A);
@@ -615,8 +419,7 @@ begin
Result :=
function(const Args: TArray): TDataValue
var
- A: Double;
- Res: Double;
+ A, Res: Double;
begin
A := Args[0].AsScalar.Value.AsDouble;
Res := TNativeFunc_F_F(CodeAddress)(A);
@@ -728,8 +531,7 @@ begin
function(const Args: TArray): TDataValue
var
A: Int64;
- B: Double;
- Res: Double;
+ B, Res: Double;
begin
A := Args[0].AsScalar.Value.AsInt64;
B := Args[1].AsScalar.Value.AsDouble;
@@ -791,8 +593,7 @@ begin
Result :=
function(const Args: TArray): TDataValue
var
- A: String;
- B: String;
+ A, B: String;
begin
A := Args[0].AsText;
B := Args[1].AsText;
@@ -800,6 +601,77 @@ begin
end;
end;
+class function TRtlRegistry.RttiTypeToStaticType(const AType: TRttiType): IStaticType;
+begin
+ if not Assigned(AType) then
+ exit(TTypes.Unknown);
+ if AType.Handle = TypeInfo(Int64) then
+ Result := TTypes.Ordinal
+ else if AType.Handle = TypeInfo(Double) then
+ Result := TTypes.Float
+ else if AType.Handle = TypeInfo(string) then
+ Result := TTypes.Text
+ else
+ Result := TTypes.Unknown;
+end;
+
+class function TRtlRegistry.ParseStaticSuffix(
+ const AMethodName: string;
+ out AArgTypes: TArray;
+ out AReturnType: IStaticType
+): Boolean;
+var
+ parts: TArray;
+ i: Integer;
+
+ function ParseType(const S: string): IStaticType;
+ begin
+ if SameText(S, 'Ordinal') then
+ Result := TTypes.Ordinal
+ else if SameText(S, 'Float') then
+ Result := TTypes.Float
+ else if SameText(S, 'Keyword') then
+ Result := TTypes.Keyword
+ else if SameText(S, 'Boolean') then
+ Result := TTypes.Boolean
+ else if SameText(S, 'DateTime') then
+ Result := TTypes.DateTime
+ else
+ Result := TTypes.Unknown;
+ end;
+begin
+ Result := False;
+ AReturnType := TTypes.Unknown;
+ AArgTypes := nil;
+ parts := AMethodName.Split(['_']);
+
+ // Format: Name_Arg1_Arg2_Return
+ if Length(parts) < 2 then
+ exit;
+
+ AReturnType := ParseType(parts[High(parts)]);
+ if AReturnType.Kind = stUnknown then
+ exit;
+
+ SetLength(AArgTypes, Length(parts) - 2);
+ if Length(AArgTypes) = 0 then
+ begin
+ Result := True;
+ exit;
+ end;
+
+ for i := 1 to High(parts) - 1 do
+ begin
+ AArgTypes[i - 1] := ParseType(parts[i]);
+ if AArgTypes[i - 1].Kind = stUnknown then
+ begin
+ AArgTypes := nil;
+ exit(False);
+ end;
+ end;
+ Result := True;
+end;
+
class function TRtlRegistry.CreateStaticWrapper(
method: TRttiMethod;
retType: IStaticType;
@@ -814,13 +686,9 @@ begin
case Length(argTypes) of
0:
- begin
if retType.Kind = stFloat then
Result := CreateWrapper_V_F(ptr);
- end;
-
1:
- begin
if (argTypes[0].Kind = stOrdinal) and (retType.Kind = stOrdinal) then
Result := CreateWrapper_O_O(ptr)
else if (argTypes[0].Kind = stFloat) and (retType.Kind = stFloat) then
@@ -831,25 +699,19 @@ begin
Result := CreateWrapper_O_F(ptr)
else if (argTypes[0].Kind = stUnknown) and (rttiParams[0].ParamType.Handle = TypeInfo(TScalar)) then
begin
- // This is the wrapper for: class function(Arg: TScalar): TScalar;
var wrapperFactory :=
function(CodeAddress: Pointer): TDataValue.TFunc
begin
Result :=
function(const Args: TArray): TDataValue
- var
- argScalar: TScalar;
begin
if (Length(Args) <> 1) or (Args[0].Kind <> vkScalar) then
- raise EArgumentException.Create('Invalid argument for TScalar function.');
- argScalar := Args[0].AsScalar;
- Result := TDataValue(TNativeScalarFunc(CodeAddress)(argScalar));
+ raise EArgumentException.Create('Invalid argument');
+ Result := TDataValue(TNativeScalarFunc(CodeAddress)(Args[0].AsScalar));
end;
end;
Result := wrapperFactory(ptr);
end;
- end;
-
2:
begin
var k1 := argTypes[0].Kind;
@@ -861,54 +723,96 @@ begin
if rk = stOrdinal then
Result := CreateWrapper_OO_O(ptr)
else if rk = stFloat then
- Result := CreateWrapper_OO_F(ptr); // Divide
+ Result := CreateWrapper_OO_F(ptr);
end
else if (k1 = stFloat) and (k2 = stFloat) then
begin
if rk = stFloat then
Result := CreateWrapper_FF_F(ptr)
else if rk = stOrdinal then
- Result := CreateWrapper_FF_O(ptr); // Comparisons
+ Result := CreateWrapper_FF_O(ptr);
end
else if (k1 = stOrdinal) and (k2 = stFloat) then
begin
if rk = stFloat then
Result := CreateWrapper_OF_F(ptr)
else if rk = stOrdinal then
- Result := CreateWrapper_OF_O(ptr); // Comparisons
+ Result := CreateWrapper_OF_O(ptr);
end
else if (k1 = stFloat) and (k2 = stOrdinal) then
begin
if rk = stFloat then
Result := CreateWrapper_FO_F(ptr)
else if rk = stOrdinal then
- Result := CreateWrapper_FO_O(ptr); // Comparisons
+ Result := CreateWrapper_FO_O(ptr);
end
else if (k1 = stKeyword) and (k2 = stKeyword) and (rk = stOrdinal) then
- begin
- // Keywords are passed as Int64 (index)
- Result := CreateWrapper_OO_O(ptr); // e.g. Equal_Keyword_Keyword
- end
+ Result := CreateWrapper_OO_O(ptr)
else if (k1 = stText) and (k2 = stText) then
- begin
- Result := CreateWrapper_TT_T(ptr); // e.g. String concat
- end;
+ Result := CreateWrapper_TT_T(ptr);
end;
- else
- Assert(false, 'Wrapper not implemented');
end;
end;
-procedure RegisterRtlFunctions(const AScope: IExecutionScope);
+class function TRtlRegistry.GetStaticSpecialization(const AName: string; const AArgTypes: TArray): TSpecializedMethod;
+var
+ key: TStaticSignatureKey;
+begin
+ key.Name := AName;
+ key.ArgTypes := AArgTypes;
+ FStaticBootstrap.TryGetValue(key, Result);
+end;
+
+class procedure TRtlRegistry.RegisterStaticSpecialization(
+ const AName: string;
+ const AArgTypes: TArray;
+ const AMethod: TSpecializedMethod
+);
+var
+ key: TStaticSignatureKey;
+begin
+ key := TStaticSignatureKey.Create(AName, AArgTypes);
+ FStaticBootstrap.AddOrSetValue(key, AMethod);
+end;
+
+class procedure TRtlRegistry.RegisterAll(const AScope: IExecutionScope);
+var
+ rtlName: string;
+ funcInfo: TRtlFunctionInfo;
+ constInfo: TRtlConstantInfo;
+ staticType: IStaticType;
+ pair: TPair;
begin
AScope.Define('true', TDataValue(TScalar.FromBoolean(True)), TTypes.Boolean, 'Boolean true.');
AScope.Define('false', TDataValue(TScalar.FromBoolean(False)), TTypes.Boolean, 'Boolean false.');
+ for pair in FStaticFuncMap do
+ begin
+ rtlName := pair.Key;
+ funcInfo := pair.Value;
+ if funcInfo.Signatures.Count > 0 then
+ staticType := TTypes.CreateMethodSet(funcInfo.Signatures.ToArray)
+ else
+ staticType := nil;
+
+ AScope.Define(rtlName, funcInfo.DynamicWrapper, staticType, funcInfo.Doc);
+ end;
+
+ for constInfo in FStaticConstList do
+ AScope.Define(constInfo.Name, constInfo.Value, constInfo.StaticType, constInfo.Doc);
+end;
+
+procedure RegisterRtlFunctions(const AScope: IExecutionScope);
+begin
TRtlRegistry.RegisterAll(AScope);
end;
initialization
- // Register this library's functions with the central AST factory.
+ TRtlRegistry.Scan;
+ TRtlRegistry.Scan;
+ TRtlRegistry.Scan;
+ TRtlRegistry.Scan;
+
TAst.RegisterLibrary(RegisterRtlFunctions);
end.