From 1c6a6fe5a077e8994b9aac8e4e2ab5ed4226842d Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Tue, 13 Jan 2026 17:01:33 +0100 Subject: [PATCH] RTL refactoring --- ASTPlayground/ASTPlayground.delphilsp.json | 2 +- ASTPlayground/ASTPlayground.dpr | 5 +- ASTPlayground/ASTPlayground.dproj | 3 + Src/AST/Myc.Ast.Attributes.pas | 44 ++ Src/AST/Myc.Ast.RTL.Core.pas | 675 +++---------------- Src/AST/Myc.Ast.RTL.DateTime.pas | 59 ++ Src/AST/Myc.Ast.RTL.Math.pas | 270 ++++++++ Src/AST/Myc.Ast.RTL.Series.pas | 247 +++++++ Src/AST/Myc.Ast.RTL.pas | 738 +++++++++------------ 9 files changed, 1031 insertions(+), 1012 deletions(-) create mode 100644 Src/AST/Myc.Ast.RTL.DateTime.pas create mode 100644 Src/AST/Myc.Ast.RTL.Math.pas create mode 100644 Src/AST/Myc.Ast.RTL.Series.pas 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.