From 18dde168fd20219ff0163350739ecf941c4e3d5e Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Thu, 11 Dec 2025 14:22:09 +0100 Subject: [PATCH] RTL custom interface types as records --- ASTPlayground/ASTPlayground.delphilsp.json | 2 +- ASTPlayground/ASTPlayground.dpr | 3 +- ASTPlayground/ASTPlayground.dproj | 1 + Src/AST/Myc.Ast.Evaluator.pas | 6 +- Src/AST/Myc.Ast.RTL.Core.pas | 12 +- Src/AST/Myc.Ast.RTL.TypeRegistry.pas | 385 +++++++++++++++++ Src/AST/Myc.Ast.RTL.pas | 22 +- Src/AST/Myc.Ast.Script.pas | 18 +- Src/Myc.Trade.DataFeed.pas | 47 +- Test/AST/Test.Myc.Ast.RTL.TypeRegistry.pas | 481 +++++++++++++++++++++ Test/MycTests.dpr | 3 +- Test/MycTests.dproj | 1 + Test/TestDataPOD.pas | 21 - 13 files changed, 918 insertions(+), 84 deletions(-) create mode 100644 Src/AST/Myc.Ast.RTL.TypeRegistry.pas create mode 100644 Test/AST/Test.Myc.Ast.RTL.TypeRegistry.pas diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json index 31c43e1..659a578 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.Handlers", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.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" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": true, "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.Handlers", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.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" } ] , "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 2f2e8ab..6ffa0c3 100644 --- a/ASTPlayground/ASTPlayground.dpr +++ b/ASTPlayground/ASTPlayground.dpr @@ -36,7 +36,8 @@ uses Myc.Fmx.AstEditor.Handlers.Lists in '..\Src\AST\Myc.Fmx.AstEditor.Handlers.Lists.pas', Myc.Fmx.AstEditor.Handlers.Primitives in '..\Src\AST\Myc.Fmx.AstEditor.Handlers.Primitives.pas', Myc.Fmx.AstEditor.Handlers.Control in '..\Src\AST\Myc.Fmx.AstEditor.Handlers.Control.pas', - Myc.Fmx.AstEditor.Handlers.Data in '..\Src\AST\Myc.Fmx.AstEditor.Handlers.Data.pas'; + Myc.Fmx.AstEditor.Handlers.Data in '..\Src\AST\Myc.Fmx.AstEditor.Handlers.Data.pas', + Myc.Ast.RTL.TypeRegistry in '..\Src\AST\Myc.Ast.RTL.TypeRegistry.pas'; {$R *.res} diff --git a/ASTPlayground/ASTPlayground.dproj b/ASTPlayground/ASTPlayground.dproj index aeadb71..31424d8 100644 --- a/ASTPlayground/ASTPlayground.dproj +++ b/ASTPlayground/ASTPlayground.dproj @@ -167,6 +167,7 @@ + Base diff --git a/Src/AST/Myc.Ast.Evaluator.pas b/Src/AST/Myc.Ast.Evaluator.pas index 4fdd94f..80f325b 100644 --- a/Src/AST/Myc.Ast.Evaluator.pas +++ b/Src/AST/Myc.Ast.Evaluator.pas @@ -8,9 +8,9 @@ uses System.Generics.Collections, Myc.Data.Scalar, Myc.Data.Value, - Myc.Ast.Nodes, // Provides EAstException - Myc.Ast.Scope, - Myc.Data.Keyword; + Myc.Data.Keyword, + Myc.Ast.Nodes, + Myc.Ast.Scope; type // Exception for runtime errors during script evaluation diff --git a/Src/AST/Myc.Ast.RTL.Core.pas b/Src/AST/Myc.Ast.RTL.Core.pas index 9fe7fa3..01f1288 100644 --- a/Src/AST/Myc.Ast.RTL.Core.pas +++ b/Src/AST/Myc.Ast.RTL.Core.pas @@ -101,6 +101,8 @@ type class function Add_Ordinal_Float_Float(A: Int64; B: Double): Double; static; [TRtlExport('+', True)] class function Add_Float_Ordinal_Float(A: Double; B: Int64): Double; static; + [TRtlExport('+', True)] + class function Add_Text_Text_Text(const A: String; const B: String): String; static; // Subtract [TRtlExport('-', True)] @@ -249,7 +251,10 @@ class function TRtlFunctions.Add(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator + requires 2 arguments.'); - Result := Args[0].AsScalar + Args[1].AsScalar; + if (Args[0].Kind = vkText) and (Args[1].Kind = vkText) then + Result := Args[0].AsText + Args[1].AsText + else + Result := Args[0].AsScalar + Args[1].AsScalar; end; class function TRtlFunctions.Subtract(const Args: TArray): TDataValue; @@ -915,6 +920,11 @@ 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; diff --git a/Src/AST/Myc.Ast.RTL.TypeRegistry.pas b/Src/AST/Myc.Ast.RTL.TypeRegistry.pas new file mode 100644 index 0000000..50ea1a0 --- /dev/null +++ b/Src/AST/Myc.Ast.RTL.TypeRegistry.pas @@ -0,0 +1,385 @@ +unit Myc.Ast.RTL.TypeRegistry; + +interface + +uses + System.SysUtils, + System.Classes, + System.Rtti, + System.TypInfo, + System.Generics.Collections, + Myc.Data.Value, + Myc.Data.Scalar, + Myc.Data.Keyword, + Myc.Ast.Types, + Myc.Ast.Scope, + Myc.Ast.RTL; + +type + EInteropException = class(Exception); + ERecursionException = class(EInteropException); + + // Factory delegate for Interfaces + TInterfaceFactoryDelegate = reference to function(const Args: TArray): T; + + // Central registry mapping Delphi Interfaces to AST static types and handling + // runtime wrapping (Shadow Records). + TRtlTypeRegistry = class + private + class var + FCtx: TRttiContext; + FKnownTypes: TDictionary; + FAnalysisStack: TList; + + // --- Analysis --- + class function AnalyzeType(ATypeInfo: PTypeInfo): IStaticType; static; + class function GenerateInterfaceDefinition(RType: TRttiInterfaceType): IStaticType; static; + class procedure EnterAnalysis(Info: PTypeInfo); static; + class procedure ExitAnalysis(Info: PTypeInfo); static; + + // --- Marshalling --- + class function ToTValue(const AData: TDataValue; ATargetType: TRttiType): TValue; static; + class function FromTValue(const AValue: TValue): TDataValue; static; + + // --- Wrapping --- + class function WrapInstance(const Instance: IInterface; TypeInfo: PTypeInfo): TDataValue; static; + + public + class constructor Create; + class destructor Destroy; + + // --- Registration --- + // Registers a Delphi Interface type. Raises ERecursionException on cycles. + class procedure RegisterType; overload; + class procedure RegisterType(Info: PTypeInfo); overload; + + // --- Factories --- + // Registers a factory function. T must be registered via RegisterType first. + class procedure RegisterFactory( + const Scope: IExecutionScope; + const FactoryName: string; + const FactoryArgs: TArray; + const FactoryDelegate: TInterfaceFactoryDelegate + ); + + // --- Resolution --- + class function GetStaticType(Info: PTypeInfo): IStaticType; + class function ResolveType(RType: TRttiType): IStaticType; + + class property Context: TRttiContext read FCtx; + end; + +implementation + +uses + Myc.Ast.RTL.Core; + +{ TRtlTypeRegistry } + +class constructor TRtlTypeRegistry.Create; +begin + FCtx := TRttiContext.Create; + FKnownTypes := TDictionary.Create; + FAnalysisStack := TList.Create; +end; + +class destructor TRtlTypeRegistry.Destroy; +begin + FAnalysisStack.Free; + FKnownTypes.Free; + FCtx.Free; +end; + +// ----------------------------------------------------------------------------- +// Type Analysis +// ----------------------------------------------------------------------------- + +class procedure TRtlTypeRegistry.EnterAnalysis(Info: PTypeInfo); +begin + if FAnalysisStack.Contains(Info) then + raise ERecursionException.CreateFmt('Recursive type definition detected for "%s".', [string(Info.Name)]); + FAnalysisStack.Add(Info); +end; + +class procedure TRtlTypeRegistry.ExitAnalysis(Info: PTypeInfo); +begin + FAnalysisStack.Remove(Info); +end; + +class procedure TRtlTypeRegistry.RegisterType; +begin + RegisterType(TypeInfo(T)); +end; + +class procedure TRtlTypeRegistry.RegisterType(Info: PTypeInfo); +begin + if FKnownTypes.ContainsKey(Info) then + exit; + + EnterAnalysis(Info); + try + var staticType := AnalyzeType(Info); + FKnownTypes.Add(Info, staticType); + finally + ExitAnalysis(Info); + end; +end; + +class function TRtlTypeRegistry.GetStaticType(Info: PTypeInfo): IStaticType; +begin + if not FKnownTypes.TryGetValue(Info, Result) then + Result := TTypes.Unknown; +end; + +class function TRtlTypeRegistry.ResolveType(RType: TRttiType): IStaticType; +begin + if not Assigned(RType) then + exit(TTypes.Void); + + if FKnownTypes.TryGetValue(RType.Handle, Result) then + exit; + + if FAnalysisStack.Contains(RType.Handle) then + raise ERecursionException.CreateFmt('Recursive type reference detected during resolution of "%s".', [RType.Name]); + + case RType.TypeKind of + tkInteger, tkInt64: Result := TTypes.Ordinal; + tkFloat: Result := TTypes.Float; + tkString, tkUString, tkWString, tkLString, tkChar, tkWChar: Result := TTypes.Text; + tkEnumeration: + if RType.Handle = TypeInfo(Boolean) then + Result := TTypes.Boolean + else + Result := TTypes.Ordinal; + tkInterface: raise EInteropException.CreateFmt('Interface "%s" is not registered. Call RegisterType first.', [RType.Name]); + else + Result := TTypes.Unknown; + end; +end; + +class function TRtlTypeRegistry.AnalyzeType(ATypeInfo: PTypeInfo): IStaticType; +var + rType: TRttiType; +begin + rType := FCtx.GetType(ATypeInfo); + case rType.TypeKind of + tkInterface: Result := GenerateInterfaceDefinition(rType as TRttiInterfaceType); + else + Result := ResolveType(rType); + end; +end; + +class function TRtlTypeRegistry.GenerateInterfaceDefinition(RType: TRttiInterfaceType): IStaticType; +var + methods: TArray; + props: TArray; + fields: TList>; + + function MakeSig(Method: TRttiMethod): IStaticType; + var + ps: TArray; + pTypes: TArray; + returnType: IStaticType; + k: Integer; + begin + ps := Method.GetParameters; + SetLength(pTypes, Length(ps)); + for k := 0 to High(ps) do + pTypes[k] := ResolveType(ps[k].ParamType); + + if Assigned(Method.ReturnType) then + returnType := ResolveType(Method.ReturnType) + else + returnType := TTypes.Void; + + Result := TTypes.CreateMethod(pTypes, returnType); + end; + +begin + fields := TList>.Create; + try + methods := RType.GetMethods; + for var m in methods do + begin + // Only map standard procedures/functions + if m.MethodKind in [mkProcedure, mkFunction] then + fields.Add(TPair.Create(TKeywordRegistry.Intern(m.Name), MakeSig(m))); + end; + + props := RType.GetProperties; + for var p in props do + begin + if p.IsReadable then + begin + var propType := ResolveType(p.PropertyType); + var getterSig := TTypes.CreateMethod([], propType); + fields.Add(TPair.Create(TKeywordRegistry.Intern(p.Name), getterSig)); + end; + end; + + var def := TGenericRecordRegistry.Intern(fields.ToArray); + Result := TTypes.CreateGenericRecord(def); + finally + fields.Free; + end; +end; + +// ----------------------------------------------------------------------------- +// Marshalling +// ----------------------------------------------------------------------------- + +class function TRtlTypeRegistry.ToTValue(const AData: TDataValue; ATargetType: TRttiType): TValue; +begin + case AData.Kind of + vkScalar: + begin + var sc := AData.AsScalar; + case sc.Kind of + TScalar.TKind.Ordinal: + begin + if ATargetType.Handle = TypeInfo(Integer) then + Result := TValue.From(Integer(sc.Value.AsInt64)) + else if ATargetType.Handle = TypeInfo(Byte) then + Result := TValue.From(Byte(sc.Value.AsInt64)) + else if ATargetType.Handle = TypeInfo(Word) then + Result := TValue.From(Word(sc.Value.AsInt64)) + else + Result := TValue.From(sc.Value.AsInt64); + end; + TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TValue.From(sc.Value.AsDouble); + TScalar.TKind.Boolean: Result := TValue.From(sc.Value.AsInt64 <> 0); + TScalar.TKind.Keyword: + if ATargetType.TypeKind in [tkString, tkUString, tkWString, tkLString] then + Result := TValue.From(TKeywordRegistry.GetName(sc.Value.AsInt64)) + else + Result := TValue.From(sc.Value.AsInt64); + end; + end; + vkText: Result := TValue.From(AData.AsText); + vkVoid: Result := TValue.Empty; + else + raise EInteropException.CreateFmt('Marshalling for DataKind %s not implemented.', [TRttiEnumerationType.GetName(AData.Kind)]); + end; +end; + +class function TRtlTypeRegistry.FromTValue(const AValue: TValue): TDataValue; +begin + if AValue.IsEmpty then + exit(TDataValue.Void); + + case AValue.Kind of + tkInteger, tkInt64: Result := TScalar.FromInt64(AValue.AsInt64); + tkFloat: Result := TScalar.FromDouble(AValue.AsExtended); + tkString, tkUString, tkWString, tkLString: Result := AValue.AsString; + tkEnumeration: + if AValue.TypeInfo = TypeInfo(Boolean) then + Result := TScalar.FromBoolean(AValue.AsBoolean) + else + Result := TScalar.FromInt64(AValue.AsOrdinal); + + // Recursively wrap returned interfaces + tkInterface: Result := WrapInstance(AValue.AsInterface, AValue.TypeInfo); + else + Result := TDataValue.Void; + end; +end; + +// ----------------------------------------------------------------------------- +// Runtime Wrapping (Shadow Record Creation) +// ----------------------------------------------------------------------------- + +class function TRtlTypeRegistry.WrapInstance(const Instance: IInterface; TypeInfo: PTypeInfo): TDataValue; +var + rType: TRttiType; + rIntf: TRttiInterfaceType; + recFields: TDictionary; +begin + if Instance = nil then + exit(TDataValue.Void); + + rType := FCtx.GetType(TypeInfo); + if not (rType is TRttiInterfaceType) then + exit(TDataValue.Void); + + rIntf := rType as TRttiInterfaceType; + recFields := TDictionary.Create; + try + // Wrap Methods + for var m in rIntf.GetMethods do + begin + if (m.MethodKind in [mkProcedure, mkFunction]) then + begin + var key := TKeywordRegistry.Intern(m.Name); + + if recFields.ContainsKey(key) then + raise EInteropException.Create('Overloading not supported'); + + var methodFactory := + function(const Instance: IInterface; Meth: TRttiMethod): TDataValue.TFunc + begin + var inst := TValue.From(Instance); + var params := Meth.GetParameters; + Result := + function(const Args: TArray): TDataValue + var + rttiArgs: TArray; + res: TValue; + i: Integer; + begin + if Length(Args) <> Length(params) then + raise Exception.CreateFmt('Method %s expects %d args', [m.Name, Length(params)]); + + SetLength(rttiArgs, Length(params)); + for i := 0 to High(params) do + rttiArgs[i] := ToTValue(Args[i], params[i].ParamType); + + res := Meth.Invoke(inst, rttiArgs); + + Result := FromTValue(res); + end; + end; + + recFields.Add(key, methodFactory(Instance, m)); + end; + end; + + Result := TDataValue.FromGenericRecord(TKeywordMapping.Create(recFields.ToArray)); + finally + recFields.Free; + end; +end; + +// ----------------------------------------------------------------------------- +// Factories +// ----------------------------------------------------------------------------- + +class procedure TRtlTypeRegistry.RegisterFactory( + const Scope: IExecutionScope; + const FactoryName: string; + const FactoryArgs: TArray; + const FactoryDelegate: TInterfaceFactoryDelegate +); +var + staticType: IStaticType; + ti: PTypeInfo; +begin + ti := TypeInfo(T); + staticType := GetStaticType(ti); + if staticType.Kind = stUnknown then + raise EInteropException.CreateFmt('Interface "%s" must be registered via RegisterType first.', [string(ti.Name)]); + + var factoryWrapper: TDataValue.TFunc := + function(const Args: TArray): TDataValue + var + instance: T; + begin + instance := FactoryDelegate(Args); + // Result wrapping will handle reference counting via closures + Result := WrapInstance(instance, ti); + end; + + var factorySig := TTypes.CreateMethod(FactoryArgs, staticType); + Scope.Define(FactoryName, TDataValue(factoryWrapper), factorySig); +end; + +end. diff --git a/Src/AST/Myc.Ast.RTL.pas b/Src/AST/Myc.Ast.RTL.pas index 3212f12..d64d0a7 100644 --- a/Src/AST/Myc.Ast.RTL.pas +++ b/Src/AST/Myc.Ast.RTL.pas @@ -84,6 +84,7 @@ type TNativeFunc_OF_O = function(A: Int64; B: Double): Int64; TNativeFunc_FO_F = function(A: Double; B: Int64): Double; TNativeFunc_FO_O = function(A: Double; B: Int64): Int64; + TNativeFunc_TT_T = function(const A: String; const B: String): String; private class var @@ -105,6 +106,7 @@ type class function CreateWrapper_OF_O(CodeAddress: Pointer): TDataValue.TFunc; static; class function CreateWrapper_FO_F(CodeAddress: Pointer): TDataValue.TFunc; static; class function CreateWrapper_FO_O(CodeAddress: Pointer): TDataValue.TFunc; static; + class function CreateWrapper_TT_T(CodeAddress: Pointer): TDataValue.TFunc; static; class function CreateStaticWrapper( method: TRttiMethod; retType: IStaticType; @@ -656,6 +658,20 @@ begin end; end; +class function TRtlRegistry.CreateWrapper_TT_T(CodeAddress: Pointer): TDataValue.TFunc; +begin + Result := + function(const Args: TArray): TDataValue + var + A: String; + B: String; + begin + A := Args[0].AsText; + B := Args[1].AsText; + Result := TNativeFunc_TT_T(CodeAddress)(A, B); + end; +end; + class function TRtlRegistry.CreateStaticWrapper( method: TRttiMethod; retType: IStaticType; @@ -736,7 +752,11 @@ begin begin // Keywords are passed as Int64 (index) Result := CreateWrapper_OO_O(ptr); // e.g. Equal_Keyword_Keyword - end; + end + else if (k1 = stText) and (k2 = stText) then + begin + Result := CreateWrapper_TT_T(ptr); // e.g. String concat + end end; end; diff --git a/Src/AST/Myc.Ast.Script.pas b/Src/AST/Myc.Ast.Script.pas index 38e3152..e9bb90d 100644 --- a/Src/AST/Myc.Ast.Script.pas +++ b/Src/AST/Myc.Ast.Script.pas @@ -227,10 +227,6 @@ type function VisitNop(const Node: INopNode): TVoid; override; end; -// ----------------------------------------------------------------------------- -// IMPLEMENTATION: Helpers & Basic Types -// ----------------------------------------------------------------------------- - function TTokenKindHelper.ToString: String; begin case Self of @@ -259,9 +255,7 @@ begin Result := TIdentities.Location(Line, Col); end; -// ----------------------------------------------------------------------------- -// IMPLEMENTATION: Lexer -// ----------------------------------------------------------------------------- +{ EParserException } constructor EParserException.Create(const AMessage: string; ALine, ACol: Integer); begin @@ -270,6 +264,8 @@ begin FCol := ACol; end; +{ TLexer } + constructor TLexer.Create(const ASource: string); begin inherited Create; @@ -811,9 +807,7 @@ begin Result := expr.Node; end; -// ----------------------------------------------------------------------------- -// IMPLEMENTATION: PrettyPrintVisitor -// ----------------------------------------------------------------------------- +{ TPrettyPrintVisitor } constructor TPrettyPrintVisitor.Create; begin @@ -1136,9 +1130,7 @@ begin Append(')'); end; -// ----------------------------------------------------------------------------- -// IMPLEMENTATION: TAstScript Facade -// ----------------------------------------------------------------------------- +{ TAstScript } class function TAstScript.Parse(const ASource: string): IAstNode; var diff --git a/Src/Myc.Trade.DataFeed.pas b/Src/Myc.Trade.DataFeed.pas index d20de13..468a39f 100644 --- a/Src/Myc.Trade.DataFeed.pas +++ b/Src/Myc.Trade.DataFeed.pas @@ -28,15 +28,11 @@ type RecCount: Integer; end; - // Converts a TScalarBatch into a stream of IScalarRecord events using the cursor pattern. - // NOTE: This uses a zero-copy approach. Consumers must process data synchronously or copy it. - TScalarBatchUnpacker = class(TMycConverter) - private - FDef: IScalarRecordDefinition; - protected - function Consume(const Value: TScalarBatch): TState; override; - public - constructor Create(const ADef: IScalarRecordDefinition); + IBroker = interface + function GetEquity: Double; + procedure Buy(Count: Integer); + procedure Sell(Count: Integer); + property Equity: Double read GetEquity; end; IScalarBatchLoader = interface @@ -220,39 +216,6 @@ begin Result := FDef.IndexOf(Key); end; -{ TScalarBatchUnpacker } - -constructor TScalarBatchUnpacker.Create(const ADef: IScalarRecordDefinition); -begin - inherited Create; - FDef := ADef; -end; - -function TScalarBatchUnpacker.Consume(const Value: TScalarBatch): TState; -begin - if (Length(Value.Data) > 0) and (Value.RecCount > 0) then - begin - var Stride := Length(Value.Data) div Value.RecCount; - var pCursor: TScalar.PValue := @Value.Data[0]; - - // Initialize reused View object (Cursor Pattern) - // This object implements IScalarRecord and is updated for each tick. - var ViewObj := TScalarRecordView.Create(FDef); - var View := ViewObj as IScalarRecord; - - for var i := 0 to Value.RecCount - 1 do - begin - ViewObj.SetData(pCursor); - - // Broadcast to all listeners - Broadcast(View); - - Inc(pCursor, Stride); - end; - end; - Result := TState.Null; -end; - { TScalarBatchLoader.TDataFile } constructor TScalarBatchLoader.TDataFile.Create(const APath, ASymbol, AExtension: String; AYear, AMonth: Integer; const ABasename: String); diff --git a/Test/AST/Test.Myc.Ast.RTL.TypeRegistry.pas b/Test/AST/Test.Myc.Ast.RTL.TypeRegistry.pas new file mode 100644 index 0000000..d6fd50b --- /dev/null +++ b/Test/AST/Test.Myc.Ast.RTL.TypeRegistry.pas @@ -0,0 +1,481 @@ +unit Test.Myc.Ast.RTL.TypeRegistry; + +interface + +uses + System.SysUtils, + System.Classes, + System.Rtti, + DUnitX.TestFramework, + Myc.Data.Value, + Myc.Data.Scalar, + Myc.Ast.Types, + Myc.Ast.Scope, + Myc.Ast.Script, + Myc.Ast.Environment, + Myc.Ast.Evaluator, + Myc.Ast.RTL.TypeRegistry, + Myc.Ast; // Facade for parsing + +type + // --- Mocks & Interfaces for Testing --- + + // Ein untergeordnetes Interface für rekursive Tests + ISubService = interface(IInvokable) + ['{B1E8A9C4-1234-4321-ABCD-1234567890AB}'] + function GetName: string; + function Multiply(A, B: Integer): Int64; + end; + + IUnknownService = interface(IInvokable) + ['{DEADBEEF-0000-0000-0000-000000000000}'] + procedure DoNothing; + end; + + // Das Haupt-Interface + IMainService = interface(IInvokable) + ['{A1E8A9C4-1111-2222-3333-444455556666}'] + // Basic Methods + function Add(A, B: Integer): Integer; + procedure SetStatus(const Msg: string); + + // Properties + function GetCounter: Integer; + property Counter: Integer read GetCounter; + + // Recursion / Complex Return Types + function CreateSub(const Name: string): ISubService; + + // Edge Cases + function EchoFloat(val: Double): Double; + end; + + // --- New Interfaces for Corner Cases --- + + // 1. Inheritance Hierarchy + IAncestorService = interface(IInvokable) + ['{11111111-0000-0000-0000-111111111111}'] + function AncestorMethod: string; + end; + + IDescendantService = interface(IAncestorService) + ['{22222222-0000-0000-0000-222222222222}'] + function DescendantMethod: string; + end; + + // 2. Complex Edge Cases (Void, Errors, Nil, Overloads) + IEdgeCaseService = interface(IInvokable) + ['{EEEEEEEE-0000-0000-0000-EEEEEEEEEEEE}'] + // Void return (Procedure) + procedure DoSomethingVoid; + + // Native Exception + procedure TriggerError(const Msg: string); + + // Nil Interface return + function GetNullService: IAncestorService; + end; + + [TestFixture] + [IgnoreMemoryLeaks] + TTestRtlTypeRegistry = class + private + FScope: IExecutionScope; + FEnv: TAstEnvironment; + public + [Setup] + procedure Setup; + [TearDown] + procedure TearDown; + + // --- Original Tests --- + [Test] + procedure Test_TypeRegistration_Analysis; + + [Test] + procedure Test_Factory_And_MethodCall; + + [Test] + procedure Test_PropertyAccess; + + [Test] + procedure Test_Recursive_Interface_Wrapping; + + [Test] + procedure Test_Marshalling_EdgeCases; + + [Test] + procedure Test_Error_MissingRegistration; + + // --- New Corner Case Tests --- + [Test] + procedure Test_Inheritance_CallAncestorMethod; + + [Test] + procedure Test_VoidProcedure; + + [Test] + procedure Test_NativeException_Propagates; + + [Test] + procedure Test_ReturnNilInterface; + + [Test] + procedure Test_UnsupportedType_Marshalling; + end; + +implementation + +uses + System.TypInfo, + Myc.Ast.Nodes; + +// --- Mock Implementations --- + +type + TSubService = class(TInterfacedObject, ISubService) + private + FName: string; + public + constructor Create(const AName: string); + function GetName: string; + function Multiply(A, B: Integer): Int64; + end; + + TMainService = class(TInterfacedObject, IMainService) + private + FCount: Integer; + FLastStatus: string; + public + constructor Create; + function Add(A, B: Integer): Integer; + procedure SetStatus(const Msg: string); + function GetCounter: Integer; + function CreateSub(const Name: string): ISubService; + function EchoFloat(val: Double): Double; + property LastStatus: string read FLastStatus; + end; + + TInheritanceService = class(TInterfacedObject, IDescendantService) + public + function AncestorMethod: string; + function DescendantMethod: string; + end; + + TEdgeCaseService = class(TInterfacedObject, IEdgeCaseService) + private + FVoidCalled: Boolean; + public + procedure DoSomethingVoid; + procedure TriggerError(const Msg: string); + function GetNullService: IAncestorService; + property VoidCalled: Boolean read FVoidCalled; + end; + +{ TSubService } + +constructor TSubService.Create(const AName: string); +begin + FName := AName; +end; + +function TSubService.GetName: string; +begin + Result := FName; +end; + +function TSubService.Multiply(A, B: Integer): Int64; +begin + Result := Int64(A) * Int64(B); +end; + +{ TMainService } + +constructor TMainService.Create; +begin + FCount := 0; +end; + +function TMainService.Add(A, B: Integer): Integer; +begin + Result := A + B; + Inc(FCount); +end; + +function TMainService.CreateSub(const Name: string): ISubService; +begin + Result := TSubService.Create(Name); + Inc(FCount); +end; + +function TMainService.EchoFloat(val: Double): Double; +begin + Result := val; +end; + +function TMainService.GetCounter: Integer; +begin + Result := FCount; +end; + +procedure TMainService.SetStatus(const Msg: string); +begin + FLastStatus := Msg; +end; + +{ TInheritanceService } + +function TInheritanceService.AncestorMethod: string; +begin + Result := 'Ancestor'; +end; + +function TInheritanceService.DescendantMethod: string; +begin + Result := 'Descendant'; +end; + +procedure TEdgeCaseService.DoSomethingVoid; +begin + FVoidCalled := True; +end; + +function TEdgeCaseService.GetNullService: IAncestorService; +begin + Result := nil; +end; + +procedure TEdgeCaseService.TriggerError(const Msg: string); +begin + raise Exception.Create(Msg); +end; + +// --- Tests --- + +procedure TTestRtlTypeRegistry.Setup; +begin + // 1. Create Clean Environment + FEnv := TAstEnvironment.Construct(nil); + FEnv.SetStandardMode; + FScope := FEnv.RootScope; + + // 2. Register Standard Mocks + TRtlTypeRegistry.RegisterType; + TRtlTypeRegistry.RegisterType; + + TRtlTypeRegistry.RegisterFactory( + FScope, + 'create-service', + [], + function(const Args: TArray): IMainService begin Result := TMainService.Create; end + ); + + // 3. Register Corner Case Mocks + TRtlTypeRegistry.RegisterType; + TRtlTypeRegistry.RegisterType; + TRtlTypeRegistry.RegisterType; + + TRtlTypeRegistry.RegisterFactory( + FScope, + 'create-descendant', + [], + function(const Args: TArray): IDescendantService begin Result := TInheritanceService.Create; end + ); + + TRtlTypeRegistry.RegisterFactory( + FScope, + 'create-edge', + [], + function(const Args: TArray): IEdgeCaseService begin Result := TEdgeCaseService.Create; end + ); +end; + +procedure TTestRtlTypeRegistry.TearDown; +begin + // Interfaces are ref-counted, scope cleanup handles values. + FScope := nil; +end; + +procedure TTestRtlTypeRegistry.Test_TypeRegistration_Analysis; +var + staticType: IStaticType; + genRec: IGenericRecordDefinition; + idx: Integer; + methodType: IStaticType; +begin + // Verify that IMainService was analyzed correctly into an AST definition + staticType := TRtlTypeRegistry.GetStaticType(TypeInfo(IMainService)); + + Assert.AreNotEqual(TStaticTypeKind.stUnknown, staticType.Kind, 'Type should be known'); + Assert.AreEqual(TStaticTypeKind.stGenericRecord, staticType.Kind, 'Interface should map to GenericRecord'); + + genRec := staticType.GenericDefinition; + + // Check 'Add' method existence + idx := genRec.IndexOf(Myc.Data.Keyword.TKeywordRegistry.Intern('Add')); + Assert.IsTrue(idx >= 0, 'Method Add should exist in type definition'); + + methodType := genRec.Items[idx].Value; + Assert.AreEqual(TStaticTypeKind.stMethod, methodType.Kind); + // Add has 2 args (Ordinal, Ordinal) -> Ordinal + Assert.AreEqual(Int64(2), Length(methodType.Signatures[0].ParamTypes)); + Assert.AreEqual(TStaticTypeKind.stOrdinal, methodType.Signatures[0].ReturnType.Kind); +end; + +procedure TTestRtlTypeRegistry.Test_Factory_And_MethodCall; +var + script: string; + res: TDataValue; +begin + // Script: Create service, call Add(10, 20) + script := '(do ' + ' (def svc (create-service)) ' + ' ((.Add svc) 10 20) ' + ')'; + + var root := TAstScript.Parse(script); + + res := FEnv.Run(root); + + Assert.AreEqual(TDataValueKind.vkScalar, res.Kind); + Assert.AreEqual(Int64(30), res.AsScalar.Value.AsInt64); +end; + +procedure TTestRtlTypeRegistry.Test_PropertyAccess; +var + script: string; + res: TDataValue; +begin + // Script: Call Add twice (increments counter), then read Counter property + script := + '(do ' + + ' (def svc (create-service)) ' + + ' ((.Add svc) 1 1) ' + + ' ((.Add svc) 2 2) ' + + ' ((.GetCounter svc)) ' + + // Property is a getter-function in script! + ')'; + + var root := TAstScript.Parse(script); + res := FEnv.Run(root); + + Assert.AreEqual(vkScalar, res.Kind); + Assert.AreEqual(Int64(2), res.AsScalar.Value.AsInt64); +end; + +procedure TTestRtlTypeRegistry.Test_Recursive_Interface_Wrapping; +var + script: string; + res: TDataValue; +begin + // Script: + // 1. Create MainService + // 2. Call CreateSub("TestSub") -> Returns ISubService (Wrapped automatically!) + // 3. Call Multiply on that SubService + + script := '(do ' + ' (def svc (create-service)) ' + ' (def sub ((.CreateSub svc) "TestSub")) ' + ' ((.Multiply sub) 6 7) ' + ')'; + + var root := TAstScript.Parse(script); + res := FEnv.Run(root); + + Assert.AreEqual(Int64(42), res.AsScalar.Value.AsInt64); +end; + +procedure TTestRtlTypeRegistry.Test_Marshalling_EdgeCases; +var + script: string; + res: TDataValue; +begin + // Test Float Marshalling and String + // Script: Pass a float, get it back. + + script := '(do ' + ' (def svc (create-service)) ' + ' ((.EchoFloat svc) 3.1415) ' + ')'; + + var root := TAstScript.Parse(script); + res := FEnv.Run(root); + + Assert.AreEqual(3.1415, res.AsScalar.Value.AsDouble, 0.0001); +end; + +procedure TTestRtlTypeRegistry.Test_Error_MissingRegistration; +begin + // Try to create factory without registering type + Assert.WillRaise(procedure begin TRtlTypeRegistry.RegisterFactory(FScope, 'fail', [], nil); end, EInteropException); +end; + +// --- New Corner Cases --- + +procedure TTestRtlTypeRegistry.Test_Inheritance_CallAncestorMethod; +var + script: string; + res: TDataValue; +begin + // Test if we can call a method defined in the parent interface + // on an instance of the child interface. + script := + '(do ' + + ' (def svc (create-descendant)) ' + + ' (def val1 ((.DescendantMethod svc))) ' + + ' (def val2 ((.AncestorMethod svc))) ' + + ' (+ val1 val2) ' + + ')'; + + var root := TAstScript.Parse(script); + res := FEnv.Run(root); + + Assert.AreEqual(TDataValueKind.vkText, res.Kind); + Assert.AreEqual('DescendantAncestor', res.AsText); +end; + +procedure TTestRtlTypeRegistry.Test_VoidProcedure; +var + script: string; + res: TDataValue; +begin + // Procedures (void return) should return vkVoid in AST + script := '(do ' + ' (def svc (create-edge)) ' + ' ((.DoSomethingVoid svc)) ' + ')'; + + var root := TAstScript.Parse(script); + res := FEnv.Run(root); + + Assert.IsTrue(res.IsVoid, 'Procedures should return Void TDataValue'); +end; + +procedure TTestRtlTypeRegistry.Test_NativeException_Propagates; +var + script: string; +begin + // Verify that a Delphi exception crashes the script execution properly + script := '(do ' + ' (def svc (create-edge)) ' + ' ((.TriggerError svc) "Boom!") ' + ')'; + + var root := TAstScript.Parse(script); + + Assert.WillRaise(procedure begin FEnv.Run(root); end, EEvaluatorException, 'Boom!'); +end; + +procedure TTestRtlTypeRegistry.Test_ReturnNilInterface; +var + script: string; + res: TDataValue; +begin + // If a Delphi function returns nil, the AST value should be Void or handle it gracefully + script := '(do ' + ' (def svc (create-edge)) ' + ' ((.GetNullService svc)) ' + ')'; + + var root := TAstScript.Parse(script); + res := FEnv.Run(root); + + if res.Kind = vkInterface then + Assert.IsNull(res.AsIntf, 'Returned interface should be nil') + else + Assert.IsTrue(res.IsVoid, 'Nil result should be mapped to Void'); +end; + +procedure TTestRtlTypeRegistry.Test_UnsupportedType_Marshalling; +begin + // This expects the runtime to throw an error when converting TValue or invoking + // due to invalid argument types (passing string where int is expected). + var script := '(do ' + ' (def svc (create-edge)) ' + ' ((.Calc svc) "Not a number") ' + ')'; + + var root := TAstScript.Parse(script); + + Assert.WillRaise(procedure begin FEnv.Run(root); end); +end; + +end. diff --git a/Test/MycTests.dpr b/Test/MycTests.dpr index 3c46bbf..300c395 100644 --- a/Test/MycTests.dpr +++ b/Test/MycTests.dpr @@ -32,7 +32,8 @@ uses Test.Myc.Ast.Script in 'AST\Test.Myc.Ast.Script.pas', Test.Myc.Ast.Compiler.Macros in 'AST\Test.Myc.Ast.Compiler.Macros.pas', Test.Myc.Ast.RTL.DateTime in 'AST\Test.Myc.Ast.RTL.DateTime.pas', - Test.Myc.Ast.Compiler.Binder in '..\Src\AST\Test.Myc.Ast.Compiler.Binder.pas'; + Test.Myc.Ast.Compiler.Binder in '..\Src\AST\Test.Myc.Ast.Compiler.Binder.pas', + Test.Myc.Ast.RTL.TypeRegistry in 'AST\Test.Myc.Ast.RTL.TypeRegistry.pas'; { keep comment here to protect the following conditional from being removed by the IDE when adding a unit } {$IFNDEF TESTINSIGHT} diff --git a/Test/MycTests.dproj b/Test/MycTests.dproj index 961050b..a52214e 100644 --- a/Test/MycTests.dproj +++ b/Test/MycTests.dproj @@ -134,6 +134,7 @@ $(PreBuildEvent)]]> + Base diff --git a/Test/TestDataPOD.pas b/Test/TestDataPOD.pas index a4c75be..d837c60 100644 --- a/Test/TestDataPOD.pas +++ b/Test/TestDataPOD.pas @@ -23,8 +23,6 @@ type [TestCase('Float_Negative', '-3.1415926535,Float')] procedure TestScalarCreation(const AValueStr: string; AExpectedKind: TScalar.TKind); - [Test] - procedure TestScalarTuple; end; implementation @@ -56,25 +54,6 @@ begin end; end; -procedure TTestPOD.TestScalarTuple; -var - tuple: TScalarTuple; -begin - // A tuple is a heterogeneous array of TScalar - SetLength(tuple, 3); - tuple[0] := TScalar.FromInt64(123); - tuple[1] := TScalar.FromDouble(3.14); - tuple[2] := TScalar.FromInt64(-456); - - Assert.AreEqual(Int64(3), Length(tuple), 'Tuple length mismatch'); - Assert.AreEqual(TScalar.TKind.Ordinal, tuple[0].Kind, 'Tuple item 0 kind mismatch'); - Assert.AreEqual(Int64(123), tuple[0].Value.AsInt64, 'Tuple item 0 value mismatch'); - Assert.AreEqual(TScalar.TKind.Float, tuple[1].Kind, 'Tuple item 1 kind mismatch'); - Assert.AreEqual(3.14, tuple[1].Value.AsDouble, 1E-12, 'Tuple item 1 value mismatch'); - Assert.AreEqual(TScalar.TKind.Ordinal, tuple[2].Kind, 'Tuple item 2 kind mismatch'); - Assert.AreEqual(Int64(-456), tuple[2].Value.AsInt64, 'Tuple item 2 value mismatch'); -end; - initialization FormatSettings.DecimalSeparator := '.'; TDUnitX.RegisterTestFixture(TTestPOD);