diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json index ef33e9d..f106b26 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" }, { "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" } ] , "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.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" }, { "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" } ] , "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 diff --git a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas index aee166d..f454fbb 100644 --- a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas +++ b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas @@ -17,7 +17,7 @@ uses type IAstTypeChecker = interface(IAstVisitor) - function Execute(const RootNode: IAstNode; const Layout: IScopeLayout): IAstNode; + function Execute(const RootNode: IAstNode): IAstNode; end; TTypeChecker = class(TAstTransformer, IAstTypeChecker) @@ -30,7 +30,12 @@ type FSlotTypes: TArray; FUpvalueTypes: TArray; public - constructor Create(AParent: TTypeContext; ALayout: IScopeLayout; const AUpvalueTypes: TArray); + constructor Create( + AParent: TTypeContext; + ALayout: IScopeLayout; + const AUpvalueTypes: TArray; + ADescriptor: IScopeDescriptor + ); function LookupType(const Address: TResolvedAddress): IStaticType; procedure SetType(SlotIndex: Integer; AType: IStaticType); property Types: TArray read FSlotTypes; @@ -39,9 +44,14 @@ type private FCurrentContext: TTypeContext; FLog: ICompilerLog; + FRootScope: IExecutionScope; function CreateContextChain(L: IScopeLayout): TTypeContext; + // Helpers for Null Propagation + function PrepareBaseType(const BaseNode: IAstNode; out IsOptional: Boolean): IStaticType; + function ApplyOptionality(const AType: IStaticType; IsOptional: Boolean): IStaticType; + protected function VisitIdentifier(const Node: IIdentifierNode): IAstNode; override; function VisitVariableDeclaration(const Node: IVariableDeclarationNode): IAstNode; override; @@ -50,7 +60,7 @@ type function VisitFunctionCall(const Node: IFunctionCallNode): IAstNode; override; function VisitBlockExpression(const Node: IBlockExpressionNode): IAstNode; override; function VisitIfExpression(const Node: IIfExpressionNode): IAstNode; override; - function VisitCondExpression(const Node: ICondExpressionNode): IAstNode; override; // Replaced Ternary + function VisitCondExpression(const Node: ICondExpressionNode): IAstNode; override; function VisitMemberAccess(const Node: IMemberAccessNode): IAstNode; override; function VisitIndexer(const Node: IIndexerNode): IAstNode; override; function VisitRecordLiteral(const Node: IRecordLiteralNode): IAstNode; override; @@ -64,12 +74,17 @@ type function VisitKeyword(const Node: IKeywordNode): IAstNode; override; public - constructor Create(const RootLayout: IScopeLayout; const ALog: ICompilerLog); + constructor Create(const RootLayout: IScopeLayout; const RootScope: IExecutionScope; const ALog: ICompilerLog); destructor Destroy; override; - function Execute(const RootNode: IAstNode; const Layout: IScopeLayout): IAstNode; + function Execute(const RootNode: IAstNode): IAstNode; - class function CheckTypes(const RootNode: IAstNode; const Layout: IScopeLayout; const ALog: ICompilerLog): IAstNode; static; + class function CheckTypes( + const RootNode: IAstNode; + const Layout: IScopeLayout; + const RootScope: IExecutionScope; + const ALog: ICompilerLog + ): IAstNode; static; end; implementation @@ -80,7 +95,14 @@ uses { TTypeChecker.TTypeContext } -constructor TTypeChecker.TTypeContext.Create(AParent: TTypeContext; ALayout: IScopeLayout; const AUpvalueTypes: TArray); +constructor TTypeChecker.TTypeContext.Create( + AParent: TTypeContext; + ALayout: IScopeLayout; + const AUpvalueTypes: TArray; + ADescriptor: IScopeDescriptor +); +var + i: Integer; begin inherited Create; FParent := AParent; @@ -90,8 +112,19 @@ begin if Assigned(FLayout) then begin SetLength(FSlotTypes, FLayout.SlotCount); - for var i := 0 to High(FSlotTypes) do - FSlotTypes[i] := TTypes.Unknown; + + if Assigned(ADescriptor) then + begin + // Load known types from descriptor (e.g. for Root Scope / RTL) + for i := 0 to High(FSlotTypes) do + FSlotTypes[i] := ADescriptor.GetSymbolType(i); + end + else + begin + // Initialize with Unknown for new scopes + for i := 0 to High(FSlotTypes) do + FSlotTypes[i] := TTypes.Unknown; + end; end; end; @@ -142,21 +175,33 @@ end; function TTypeChecker.CreateContextChain(L: IScopeLayout): TTypeContext; var p: TTypeContext; + desc: IScopeDescriptor; begin if L = nil then exit(nil); p := CreateContextChain(L.Parent); - Result := TTypeContext.Create(p, L, []); + + desc := nil; + // Check if this layout is the root layout (has no parent). + // If so, attach the RootScope's descriptor to pull in RTL types (like +). + if (L.Parent = nil) and Assigned(FRootScope) then + begin + desc := FRootScope.Descriptor; + end; + + Result := TTypeContext.Create(p, L, [], desc); end; -constructor TTypeChecker.Create(const RootLayout: IScopeLayout; const ALog: ICompilerLog); +constructor TTypeChecker.Create(const RootLayout: IScopeLayout; const RootScope: IExecutionScope; const ALog: ICompilerLog); begin inherited Create; FLog := ALog; + FRootScope := RootScope; + FCurrentContext := CreateContextChain(RootLayout); if FCurrentContext = nil then - FCurrentContext := TTypeContext.Create(nil, nil, []); + FCurrentContext := TTypeContext.Create(nil, nil, [], nil); end; destructor TTypeChecker.Destroy; @@ -170,19 +215,56 @@ begin inherited; end; -class function TTypeChecker.CheckTypes(const RootNode: IAstNode; const Layout: IScopeLayout; const ALog: ICompilerLog): IAstNode; +class function TTypeChecker.CheckTypes( + const RootNode: IAstNode; + const Layout: IScopeLayout; + const RootScope: IExecutionScope; + const ALog: ICompilerLog +): IAstNode; +var + startLayout: IScopeLayout; begin - var checker := TTypeChecker.Create(Layout, ALog) as IAstTypeChecker; - Result := checker.Execute(RootNode, Layout); + // Determine the starting scope for the TypeChecker. + // The 'Layout' parameter represents the *inner* scope of the script (the "Room"). + // To correctly simulate entering this scope (via VisitLambdaExpression), the TypeChecker + // must start in the *surrounding* scope (the "Hallway"), which is Layout.Parent. + if Assigned(Layout) then + startLayout := Layout.Parent + else + startLayout := nil; + + var checker := TTypeChecker.Create(startLayout, RootScope, ALog) as IAstTypeChecker; + Result := checker.Execute(RootNode); end; -function TTypeChecker.Execute(const RootNode: IAstNode; const Layout: IScopeLayout): IAstNode; +function TTypeChecker.Execute(const RootNode: IAstNode): IAstNode; begin Result := Accept(RootNode); if not Assigned(Result) then Result := TAst.Block([], nil); end; +// --- Helper --- + +function TTypeChecker.PrepareBaseType(const BaseNode: IAstNode; out IsOptional: Boolean): IStaticType; +var + baseType: IStaticType; +begin + baseType := BaseNode.AsTypedNode.StaticType; + IsOptional := baseType.IsOptional; + Result := TTypes.Unwrap(baseType); +end; + +function TTypeChecker.ApplyOptionality(const AType: IStaticType; IsOptional: Boolean): IStaticType; +begin + if IsOptional and (AType.Kind <> stUnknown) then + Result := TTypes.MakeOptional(AType) + else + Result := AType; +end; + +// --- Visits --- + function TTypeChecker.VisitConstant(const Node: IConstantNode): IAstNode; begin Result := Node; @@ -221,7 +303,6 @@ begin for i := 0 to Node.Arguments.Count - 1 do newArgs[i] := Accept(Node.Arguments[i]); - // Wrap in List var argList := TArgumentList.Create(newArgs, Node.Arguments.Identity); Result := TAst.Recur(Node.Identity, argList, TTypes.Void); end; @@ -358,14 +439,40 @@ var finalDescriptor: IScopeDescriptor; paramIdent: IIdentifierNode; paramIdentity: INamedIdentity; + lookupAddr: TResolvedAddress; begin + // 1. Resolve Upvalue Types upvalueAddrs := Node.Upvalues; SetLength(upvalueTypes, Length(upvalueAddrs)); - for i := 0 to High(upvalueAddrs) do - upvalueTypes[i] := FCurrentContext.LookupType(upvalueAddrs[i]); - FCurrentContext := TTypeContext.Create(FCurrentContext, Node.Layout, upvalueTypes); + for i := 0 to High(upvalueAddrs) do + begin + lookupAddr := upvalueAddrs[i]; + + // CRITICAL: Scope Depth Adjustment + // The Binder calculated addresses relative to the *body* of this lambda (Internal View). + // FCurrentContext currently points to the *defining* scope (External View/Parent). + // Therefore, we must decrease the depth by 1 to look up the type in the current context. + if lookupAddr.Kind = akLocalOrParent then + begin + // Check > 0 to prevent crash if Binder somehow produced 0 (though logic says it shouldn't). + if lookupAddr.ScopeDepth > 0 then + Dec(lookupAddr.ScopeDepth) + else + begin + // Guard for Binder quirks or edge cases + if Assigned(FLog) then + FLog.AddWarning('Compiler integrity check warning: Upvalue Depth 0 encountered during type check.', Node); + end; + end; + + upvalueTypes[i] := FCurrentContext.LookupType(lookupAddr); + end; + + // 2. Enter New Scope (The "Room") + FCurrentContext := TTypeContext.Create(FCurrentContext, Node.Layout, upvalueTypes, nil); try + // 3. Register Parameters SetLength(newParams, Node.Parameters.Count); SetLength(paramTypes, Node.Parameters.Count); @@ -383,21 +490,22 @@ begin newParams[i] := TAst.Identifier(paramIdentity, paramAdr, paramTypes[i]); end; + // 4. Visit Body newBody := Accept(Node.Body); + + // 5. Determine Function Signature bodyType := newBody.AsTypedNode.StaticType; methodType := TTypes.CreateMethod(paramTypes, bodyType); - FCurrentContext.SetType(0, methodType); finalDescriptor := TScope.CreateDescriptor(Node.Layout, FCurrentContext.Types); finally + // 6. Leave Scope var temp := FCurrentContext; FCurrentContext := FCurrentContext.FParent; temp.Free; end; - // Wrap in List var paramList := TParameterList.Create(newParams, Node.Parameters.Identity); - Result := TAst.LambdaExpr( Node.Identity, @@ -493,9 +601,7 @@ begin retType := TTypes.Unknown; end; - // Wrap in List var argList := TArgumentList.Create(newArgs, Node.Arguments.Identity); - Result := TAst.FunctionCall(Node.Identity, newCallee, argList, retType, Node.IsTailCall, nil, False); end; @@ -514,7 +620,6 @@ begin else blockType := TTypes.Void; - // Wrap in List var exprList := TExpressionList.Create(newExprs, Node.Expressions.Identity); Result := TAst.Block(Node.Identity, exprList, blockType); end; @@ -561,11 +666,10 @@ var condType, branchType, resultType: IStaticType; begin SetLength(newPairs, Length(Node.Pairs)); - resultType := nil; // Start with nothing + resultType := nil; for i := 0 to High(Node.Pairs) do begin - // 1. Visit Condition var newCond := Accept(Node.Pairs[i].Condition); condType := newCond.AsTypedNode.StaticType; @@ -577,13 +681,11 @@ begin FLog.AddError(Format('Cond condition must be Boolean or Ordinal, but got %s', [condType.ToString]), Node); end; - // 2. Visit Branch var newBranch := Accept(Node.Pairs[i].Branch); branchType := newBranch.AsTypedNode.StaticType; newPairs[i] := TCondPair.Create(newCond, newBranch); - // 3. Promote Result Type if resultType = nil then resultType := branchType else @@ -603,9 +705,7 @@ begin end; end; - // 4. Visit Else newElse := Accept(Node.ElseBranch); - // Else branch is mandatory in our new AST structure (can be Nop/Void, but is present) var elseType := newElse.AsTypedNode.StaticType; if resultType = nil then @@ -631,43 +731,44 @@ end; function TTypeChecker.VisitMemberAccess(const Node: IMemberAccessNode): IAstNode; var - baseType, elemType: IStaticType; + unwrappedBaseType, elemType: IStaticType; fieldIndex: Integer; newBase, newMember: IAstNode; + isOptionalAccess: Boolean; begin newBase := Accept(Node.Base); newMember := Accept(Node.Member); - baseType := newBase.AsTypedNode.StaticType; + unwrappedBaseType := PrepareBaseType(newBase, isOptionalAccess); elemType := TTypes.Unknown; - if (baseType.Kind <> TStaticTypeKind.stUnknown) then + if (unwrappedBaseType.Kind <> TStaticTypeKind.stUnknown) then begin - if (baseType.Kind = TStaticTypeKind.stRecord) or (baseType.Kind = TStaticTypeKind.stRecordSeries) then + if (unwrappedBaseType.Kind = TStaticTypeKind.stRecord) or (unwrappedBaseType.Kind = TStaticTypeKind.stRecordSeries) then begin - fieldIndex := baseType.Definition.IndexOf(Node.Member.Value); + fieldIndex := unwrappedBaseType.Definition.IndexOf(Node.Member.Value); if fieldIndex < 0 then begin if Assigned(FLog) then - FLog.AddError(Format('Member "%s" not found in type %s', [Node.Member.Value.Name, baseType.ToString]), Node); + FLog.AddError(Format('Member "%s" not found in type %s', [Node.Member.Value.Name, unwrappedBaseType.ToString]), Node); end else begin - var fieldType := TTypes.FromScalarKind(baseType.Definition[fieldIndex].Value); - if baseType.Kind = TStaticTypeKind.stRecord then + var fieldType := TTypes.FromScalarKind(unwrappedBaseType.Definition[fieldIndex].Value); + if unwrappedBaseType.Kind = TStaticTypeKind.stRecord then elemType := fieldType else elemType := TTypes.CreateSeries(fieldType); end; end - else if (baseType.Kind = TStaticTypeKind.stGenericRecord) then + else if (unwrappedBaseType.Kind = TStaticTypeKind.stGenericRecord) then begin - var genDef := baseType.GenericDefinition; + var genDef := unwrappedBaseType.GenericDefinition; fieldIndex := genDef.IndexOf(Node.Member.Value); if fieldIndex < 0 then begin if Assigned(FLog) then - FLog.AddError(Format('Member "%s" not found in type %s', [Node.Member.Value.Name, baseType.ToString]), Node); + FLog.AddError(Format('Member "%s" not found in type %s', [Node.Member.Value.Name, unwrappedBaseType.ToString]), Node); end else elemType := genDef[fieldIndex].Value; @@ -675,38 +776,42 @@ begin else begin if Assigned(FLog) then - FLog.AddError(Format('Member access requires a record type, but got %s', [baseType.ToString]), Node); + FLog.AddError(Format('Member access requires a record type, but got %s', [unwrappedBaseType.ToString]), Node); end; end; + elemType := ApplyOptionality(elemType, isOptionalAccess); + Result := TAst.MemberAccess(Node.Identity, newBase, newMember.AsKeyword, elemType); end; function TTypeChecker.VisitIndexer(const Node: IIndexerNode): IAstNode; var - baseType, indexType, elemType: IStaticType; + unwrappedBaseType, indexType, elemType: IStaticType; newBase, newIndex: IAstNode; + isOptionalAccess: Boolean; begin newBase := Accept(Node.Base); newIndex := Accept(Node.Index); - baseType := newBase.AsTypedNode.StaticType; + unwrappedBaseType := PrepareBaseType(newBase, isOptionalAccess); + indexType := newIndex.AsTypedNode.StaticType; elemType := TTypes.Unknown; - if (baseType.Kind <> TStaticTypeKind.stUnknown) then + if (unwrappedBaseType.Kind <> TStaticTypeKind.stUnknown) then begin - if (baseType.Kind <> TStaticTypeKind.stSeries) and (baseType.Kind <> TStaticTypeKind.stRecordSeries) then + if (unwrappedBaseType.Kind <> TStaticTypeKind.stSeries) and (unwrappedBaseType.Kind <> TStaticTypeKind.stRecordSeries) then begin if Assigned(FLog) then - FLog.AddError(Format('Indexer `[]` can only be applied to series types, but got %s', [baseType.ToString]), Node); + FLog.AddError(Format('Indexer `[]` can only be applied to series types, but got %s', [unwrappedBaseType.ToString]), Node); end else begin - if baseType.Kind = TStaticTypeKind.stSeries then - elemType := baseType.ElementType + if unwrappedBaseType.Kind = TStaticTypeKind.stSeries then + elemType := unwrappedBaseType.ElementType else - elemType := TTypes.CreateRecord(baseType.Definition); + elemType := TTypes.CreateRecord(unwrappedBaseType.Definition); end; end; @@ -716,6 +821,8 @@ begin FLog.AddError(Format('Indexer `[]` requires an Ordinal index, but got %s', [indexType.ToString]), Node); end; + elemType := ApplyOptionality(elemType, isOptionalAccess); + Result := TAst.Indexer(Node.Identity, newBase, newIndex, elemType); end; @@ -770,7 +877,6 @@ begin scalarDefFields[i] := TScalarRecordField.Create(newFields[i].Key.Value, scalarKind); end; - // Wrap in List var fieldList := TRecordFieldList.Create(newFields, Node.Fields.Identity); if allScalar then diff --git a/Src/AST/Myc.Ast.Environment.pas b/Src/AST/Myc.Ast.Environment.pas index c9cae2b..baa15e9 100644 --- a/Src/AST/Myc.Ast.Environment.pas +++ b/Src/AST/Myc.Ast.Environment.pas @@ -378,7 +378,7 @@ begin var boundAst := TAstBinder.Bind(FRootScope.Descriptor.Layout, Node, Layout, Log, FFunctionRegistry, ArgTypes); // 2. Check Types (produces Typed AST with Descriptors baked into nodes) - Result := TTypeChecker.CheckTypes(boundAst, Layout, Log); + Result := TTypeChecker.CheckTypes(boundAst, Layout, FRootScope, Log); end; function TEnvironment.GetMacroRegistry: IMacroRegistry; diff --git a/Src/AST/Myc.Ast.Evaluator.pas b/Src/AST/Myc.Ast.Evaluator.pas index 29cab95..809b068 100644 --- a/Src/AST/Myc.Ast.Evaluator.pas +++ b/Src/AST/Myc.Ast.Evaluator.pas @@ -413,6 +413,10 @@ var scalarValue: TScalar; begin baseValue := Node.Base.Accept(Self); + + if baseValue.IsVoid then + exit(TDataValue.Void); + indexValue := Node.Index.Accept(Self); if (indexValue.Kind <> vkScalar) or (indexValue.AsScalar.Kind <> TScalar.TKind.Ordinal) then @@ -461,6 +465,9 @@ var begin baseValue := Node.Base.Accept(Self); + if baseValue.IsVoid then + exit(TDataValue.Void); + case baseValue.Kind of vkRecordSeries: Result := TDataValue.FromSeries(baseValue.AsRecordSeries.Fields[Node.Member.Value]); vkScalarRecord: Result := TDataValue(baseValue.AsScalarRecord.Fields[Node.Member.Value]); diff --git a/Src/AST/Myc.Ast.Script.pas b/Src/AST/Myc.Ast.Script.pas index e9bb90d..3d54aad 100644 --- a/Src/AST/Myc.Ast.Script.pas +++ b/Src/AST/Myc.Ast.Script.pas @@ -639,10 +639,9 @@ begin else if SameText(head.Token.Text, '?') then begin // (? test1 branch1 test2 branch2 ... else) - // Requires odd number of tailNodes (pairs + 1 else) var count := Length(tailNodes); if (count < 1) or ((count mod 2) = 0) then - Error('Syntax Error: ''?'' (cond) requires an odd number of arguments (pairs of condition/branch and one final else).'); + Error('Syntax Error: ''?'' (cond) requires an odd number of arguments.'); var pairs: TArray; SetLength(pairs, count div 2); @@ -667,7 +666,7 @@ begin Error('Syntax Error: ''defmacro'' requires a name, a parameter list, and a body.'); var macroName := tailNodes[0].AsIdentifier; - var macroParams := elements[2].Params; + var macroParams := elements[2].Params; // Parameter list parsing happens in ParseExpression for brackets if tailNodes[2].Kind <> akQuasiquote then Error('Syntax Error: Expected a quasiquote as macro body.'); @@ -677,25 +676,68 @@ begin else if SameText(head.Token.Text, 'assign') then begin if Length(tailNodes) <> 2 then - Error('Syntax Error: ''assign'' requires exactly 2 arguments (target and value).'); + Error('Syntax Error: ''assign'' requires exactly 2 arguments.'); Result := TAst.Assign(tailNodes[0], tailNodes[1], startLoc); end else if SameText(head.Token.Text, 'fn') then begin if Length(tailNodes) <> 2 then Error('Syntax Error: ''fn'' requires a parameter list and a body.'); + // elements[1] is the parameter list node which contains the parsed Params array Result := TAst.LambdaExpr(elements[1].Params, tailNodes[1], startLoc); end else if SameText(head.Token.Text, 'do') then + begin Result := TAst.Block(tailNodes, startLoc) + end else if SameText(head.Token.Text, 'recur') then + begin Result := TAst.Recur(tailNodes, startLoc) + end else if SameText(head.Token.Text, 'get') then begin if Length(tailNodes) <> 2 then Error('Syntax Error: ''get'' requires exactly 2 arguments (base and index).'); Result := TAst.Indexer(tailNodes[0], tailNodes[1], startLoc) end + // --- NEW: Support for new-series --- + else if SameText(head.Token.Text, 'new-series') then + begin + if Length(tailNodes) <> 1 then + Error('Syntax Error: ''new-series'' requires exactly 1 argument (definition string).'); + + // Extract definition string from constant node + if (tailNodes[0].Kind = akConstant) and (tailNodes[0].AsConstant.Value.Kind = vkText) then + Result := TAst.CreateSeries(tailNodes[0].AsConstant.Value.AsText, startLoc) + else + Error('Syntax Error: ''new-series'' argument must be a string literal.'); + end + // --- NEW: Support for add-item --- + else if SameText(head.Token.Text, 'add-item') then + begin + if not (Length(tailNodes) in [2, 3]) then + Error('Syntax Error: ''add-item'' requires 2 or 3 arguments (series, value, [lookback]).'); + + var lookback: IAstNode := nil; + if Length(tailNodes) = 3 then + lookback := tailNodes[2]; + + if tailNodes[0].Kind <> akIdentifier then + Error('Syntax Error: ''add-item'' first argument must be a series identifier.'); + + Result := TAst.AddSeriesItem(tailNodes[0].AsIdentifier, tailNodes[1], lookback, startLoc); + end + // --- NEW: Support for count (SeriesLength) --- + else if SameText(head.Token.Text, 'count') then + begin + if Length(tailNodes) <> 1 then + Error('Syntax Error: ''count'' requires exactly 1 argument (series).'); + + if tailNodes[0].Kind <> akIdentifier then + Error('Syntax Error: ''count'' argument must be a series identifier.'); + + Result := TAst.SeriesLength(tailNodes[0].AsIdentifier, startLoc); + end else if (Length(head.Token.Text) > 1) and (head.Token.Text.StartsWith('.')) then begin if Length(tailNodes) <> 1 then @@ -1136,8 +1178,6 @@ class function TAstScript.Parse(const ASource: string): IAstNode; var p: TParser; begin - if ASource.Trim.IsEmpty then - exit(nil); p := TParser.Create(ASource); try Result := p.Parse; diff --git a/Src/AST/Myc.Ast.Types.pas b/Src/AST/Myc.Ast.Types.pas index fddffd9..d8455ba 100644 --- a/Src/AST/Myc.Ast.Types.pas +++ b/Src/AST/Myc.Ast.Types.pas @@ -5,18 +5,18 @@ interface uses System.SysUtils, System.Generics.Collections, + System.Generics.Defaults, Myc.Data.Scalar, Myc.Data.Keyword; type IStaticType = interface; - // Defines the categories of types available in the language. TStaticTypeKind = ( - stUnknown, // Used during inference before a type is known + stUnknown, stVoid, - stOrdinal, // Int64 - stFloat, // Double + stOrdinal, + stFloat, stBoolean, stDateTime, stText, @@ -33,7 +33,6 @@ type function ToString: string; end; - // Defines the signature of a method IMethodSignature = interface {$region 'private'} function GetParamTypes: TArray; @@ -44,40 +43,32 @@ type function GetHashCode: Integer; end; - // Defines a mapping for generic record fields (Key -> StaticType) IGenericRecordDefinition = IKeywordMapping; TGenericRecordRegistry = TKeywordMappingRegistry; - // Represents a complete static type definition. IStaticType = interface {$region 'private'} function GetKind: TStaticTypeKind; + function GetIsOptional: Boolean; function GetElementType: IStaticType; function GetSignatures: TArray; function GetDefinition: IScalarRecordDefinition; function GetGenericDefinition: IGenericRecordDefinition; {$endregion} - // The kind of type (e.g., Ordinal, Series, etc.) property Kind: TStaticTypeKind read GetKind; - // The element type (if Kind = stSeries) + property IsOptional: Boolean read GetIsOptional; property ElementType: IStaticType read GetElementType; - - // The signatures (if Kind = stMethod). property Signatures: TArray read GetSignatures; - - // The definition (if Kind = stRecord or stRecordSeries) property Definition: IScalarRecordDefinition read GetDefinition; - // The definition (if Kind = stGenericRecord) property GenericDefinition: IGenericRecordDefinition read GetGenericDefinition; - // Checks for type equality function IsEqual(const Other: IStaticType): Boolean; + function IsStructurallyEqual(const Other: IStaticType): Boolean; function ToString: string; function GetHashCode: Integer; end; - // Factory and Flyweight access for static types. TTypes = record private class var @@ -97,9 +88,35 @@ type class var FKeyword: IStaticType; + class var + FOrdinalOpt: IStaticType; + class var + FFloatOpt: IStaticType; + class var + FBooleanOpt: IStaticType; + class var + FDateTimeOpt: IStaticType; + class var + FTextOpt: IStaticType; + class var + FKeywordOpt: IStaticType; + + class var + FSeriesCache: TDictionary; + class var + FRecordCache: TDictionary; + class var + FRecordSeriesCache: TDictionary; + class var + FGenericRecordCache: TDictionary; + class var + FMethodCache: TDictionary, IStaticType>; + class var + FOptionalCache: TDictionary; + class constructor Create; + class destructor Destroy; public - // Flyweight accessors class property Unknown: IStaticType read FUnknown; class property Void: IStaticType read FVoid; class property Ordinal: IStaticType read FOrdinal; @@ -109,7 +126,13 @@ type class property Text: IStaticType read FText; class property Keyword: IStaticType read FKeyword; - // Factory functions + class property OrdinalOpt: IStaticType read FOrdinalOpt; + class property FloatOpt: IStaticType read FFloatOpt; + class property BooleanOpt: IStaticType read FBooleanOpt; + class property DateTimeOpt: IStaticType read FDateTimeOpt; + class property TextOpt: IStaticType read FTextOpt; + class property KeywordOpt: IStaticType read FKeywordOpt; + class function CreateSeries(const AElementType: IStaticType): IStaticType; static; class function CreateMethod(const AParamTypes: TArray; const AReturnType: IStaticType): IStaticType; static; class function CreateMethodSet(const ASignatures: TArray): IStaticType; static; @@ -117,22 +140,16 @@ type class function CreateRecordSeries(const ADef: IScalarRecordDefinition): IStaticType; static; class function CreateGenericRecord(const ADef: IGenericRecordDefinition): IStaticType; static; + class function MakeOptional(const AType: IStaticType): IStaticType; static; + class function Unwrap(const AType: IStaticType): IStaticType; static; class function FromScalarKind(AKind: TScalar.TKind): IStaticType; static; end; - // Defines the rules of the type system. TTypeRules = record public - // Returns the common type (promotion) or nil if incompatible. class function Promote(const A, B: IStaticType): IStaticType; static; - - // Checks if a value of type 'Source' can be assigned to 'Target'. class function CanAssign(const Target, Source: IStaticType): Boolean; static; - - // Determines the result type of a binary operation. Returns nil on failure. class function ResolveBinaryOp(Op: TScalar.TBinaryOp; const Left, Right: IStaticType): IStaticType; static; - - // Determines the result type of a unary operation. Returns nil on failure. class function ResolveUnaryOp(Op: TScalar.TUnaryOp; const Right: IStaticType): IStaticType; static; end; @@ -150,8 +167,7 @@ type implementation uses - System.Generics.Defaults, - System.Hash; + System.Hash; // Critical for robust hash calculations { TStaticTypeKindHelper } @@ -182,15 +198,22 @@ type TAbstractStaticType = class(TInterfacedObject, IStaticType) protected function GetKind: TStaticTypeKind; virtual; abstract; + function GetIsOptional: Boolean; virtual; function GetElementType: IStaticType; virtual; function GetSignatures: TArray; virtual; function GetDefinition: IScalarRecordDefinition; virtual; function GetGenericDefinition: IGenericRecordDefinition; virtual; function IsEqual(const Other: IStaticType): Boolean; virtual; + function IsStructurallyEqual(const Other: IStaticType): Boolean; virtual; function GetHashCode: Integer; override; abstract; function ToString: string; override; end; +function TAbstractStaticType.GetIsOptional: Boolean; +begin + Result := False; +end; + function TAbstractStaticType.GetElementType: IStaticType; begin Result := nil; @@ -211,11 +234,20 @@ begin Result := nil; end; +function TAbstractStaticType.IsStructurallyEqual(const Other: IStaticType): Boolean; +begin + if not Assigned(Other) then + exit(False); + Result := (GetKind = TTypes.Unwrap(Other).Kind); +end; + function TAbstractStaticType.IsEqual(const Other: IStaticType): Boolean; begin if not Assigned(Other) then exit(False); - Result := (GetKind = Other.Kind); + if GetIsOptional <> Other.IsOptional then + exit(False); + Result := IsStructurallyEqual(Other); end; function TAbstractStaticType.ToString: string; @@ -223,6 +255,93 @@ begin Result := GetKind.ToString; end; +// --- Optional Type Decorator --- + +type + TOptionalType = class(TInterfacedObject, IStaticType) + private + FInner: IStaticType; + public + constructor Create(const AInner: IStaticType); + function GetKind: TStaticTypeKind; + function GetIsOptional: Boolean; + function GetElementType: IStaticType; + function GetSignatures: TArray; + function GetDefinition: IScalarRecordDefinition; + function GetGenericDefinition: IGenericRecordDefinition; + function IsStructurallyEqual(const Other: IStaticType): Boolean; + function IsEqual(const Other: IStaticType): Boolean; + function GetHashCode: Integer; override; + function ToString: string; override; + end; + +constructor TOptionalType.Create(const AInner: IStaticType); +begin + inherited Create; + FInner := AInner; +end; + +function TOptionalType.GetKind: TStaticTypeKind; +begin + Result := FInner.Kind; +end; + +function TOptionalType.GetIsOptional: Boolean; +begin + Result := True; +end; + +function TOptionalType.GetElementType: IStaticType; +begin + Result := FInner.ElementType; +end; + +function TOptionalType.GetSignatures: TArray; +begin + Result := FInner.Signatures; +end; + +function TOptionalType.GetDefinition: IScalarRecordDefinition; +begin + Result := FInner.Definition; +end; + +function TOptionalType.GetGenericDefinition: IGenericRecordDefinition; +begin + Result := FInner.GenericDefinition; +end; + +function TOptionalType.IsStructurallyEqual(const Other: IStaticType): Boolean; +begin + Result := FInner.IsStructurallyEqual(TTypes.Unwrap(Other)); +end; + +function TOptionalType.IsEqual(const Other: IStaticType): Boolean; +begin + if not Assigned(Other) then + exit(False); + if not Other.IsOptional then + exit(False); + Result := IsStructurallyEqual(Other); +end; + +function TOptionalType.GetHashCode: Integer; +var + h: Integer; + optionalMarker: Integer; +begin + // We mix the Inner Hash with a constant marker using BobJenkins to ensure + // T and T? have distinct, uncorrelated hashes. + h := FInner.GetHashCode; + optionalMarker := $11111111; // Arbitrary constant to signal "Optionality" + Result := THashBobJenkins.GetHashValue(optionalMarker, SizeOf(Integer), h); +end; + +function TOptionalType.ToString: string; +begin + Result := FInner.ToString + '?'; +end; + // --- Simple (Flyweight) Type Implementations --- type @@ -248,7 +367,7 @@ end; function TSimpleStaticType.GetHashCode: Integer; begin - Result := Ord(FKind); + Result := THashBobJenkins.GetHashValue(FKind, SizeOf(TStaticTypeKind), 0); end; // --- Complex Type Implementations --- @@ -261,7 +380,7 @@ type constructor Create(AElementType: IStaticType); function GetKind: TStaticTypeKind; override; function GetElementType: IStaticType; override; - function IsEqual(const Other: IStaticType): Boolean; override; + function IsStructurallyEqual(const Other: IStaticType): Boolean; override; function GetHashCode: Integer; override; function ToString: string; override; end; @@ -282,18 +401,24 @@ begin Result := FElementType; end; -function TSeriesType.IsEqual(const Other: IStaticType): Boolean; +function TSeriesType.IsStructurallyEqual(const Other: IStaticType): Boolean; begin - Result := (Assigned(Other)) and (Other.Kind = stSeries) and (Self.FElementType.IsEqual(Other.ElementType)); + var uOther := TTypes.Unwrap(Other); + Result := (uOther.Kind = stSeries) and (Self.FElementType.IsEqual(uOther.ElementType)); end; function TSeriesType.GetHashCode: Integer; +var + h: Integer; begin - Result := Ord(stSeries); + // Seed with Kind, then mix in ElementType's hash + h := Ord(stSeries); + Result := THashBobJenkins.GetHashValue(h, SizeOf(TStaticTypeKind), 0); + if Assigned(FElementType) then begin - var hash := FElementType.GetHashCode; - Result := THashBobJenkins.GetHashValue(Hash, SizeOf(Integer), Result); + h := FElementType.GetHashCode; + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); end; end; @@ -323,18 +448,23 @@ end; function TMethodSignature.GetHashCode: Integer; var - i: Integer; + i, h: Integer; begin + // Start with 0 (or a signature constant), mix ReturnType, then Params Result := 0; + if Assigned(FReturnType) then - Result := FReturnType.GetHashCode; + begin + h := FReturnType.GetHashCode; + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); + end; for i := 0 to High(FParamTypes) do begin if Assigned(FParamTypes[i]) then begin - var hash := FParamTypes[i].GetHashCode; - Result := THashBobJenkins.GetHashValue(hash, SizeOf(Integer), Result); + h := FParamTypes[i].GetHashCode; + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); end; end; end; @@ -349,7 +479,7 @@ type constructor Create(const ASignatures: TArray); function GetKind: TStaticTypeKind; override; function GetSignatures: TArray; override; - function IsEqual(const Other: IStaticType): Boolean; override; + function IsStructurallyEqual(const Other: IStaticType): Boolean; override; function GetHashCode: Integer; override; function ToString: string; override; end; @@ -386,14 +516,15 @@ begin Result := Format('Method(%s): %s', [paramStr, Sig.ReturnType.ToString]); end; -function TMethodType.IsEqual(const Other: IStaticType): Boolean; +function TMethodType.IsStructurallyEqual(const Other: IStaticType): Boolean; var i, j: Integer; begin - if (not Assigned(Other)) or (Other.Kind <> stMethod) then + var uOther := TTypes.Unwrap(Other); + if (not Assigned(uOther)) or (uOther.Kind <> stMethod) then exit(False); - var otherSigs := Other.Signatures; + var otherSigs := uOther.Signatures; if Length(Self.FSignatures) <> Length(otherSigs) then exit(False); @@ -420,14 +551,18 @@ end; function TMethodType.GetHashCode: Integer; var sig: IMethodSignature; + h: Integer; begin - Result := Ord(stMethod); + // Seed with stMethod, then mix in each signature's hash + h := Ord(stMethod); + Result := THashBobJenkins.GetHashValue(h, SizeOf(TStaticTypeKind), 0); + for sig in FSignatures do begin if Assigned(sig) then begin - var hash := sig.GetHashCode; - Result := THashBobJenkins.GetHashValue(hash, SizeOf(Integer), Result); + h := sig.GetHashCode; + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); end; end; end; @@ -471,7 +606,7 @@ type constructor Create(AKind: TStaticTypeKind; ADef: IScalarRecordDefinition); function GetKind: TStaticTypeKind; override; function GetDefinition: IScalarRecordDefinition; override; - function IsEqual(const Other: IStaticType): Boolean; override; + function IsStructurallyEqual(const Other: IStaticType): Boolean; override; function GetHashCode: Integer; override; function ToString: string; override; end; @@ -494,14 +629,15 @@ begin Result := FDefinition; end; -function TRecordType.IsEqual(const Other: IStaticType): Boolean; +function TRecordType.IsStructurallyEqual(const Other: IStaticType): Boolean; var i: Integer; begin - if (not Assigned(Other)) or (Other.Kind <> GetKind) then + var uOther := TTypes.Unwrap(Other); + if (not Assigned(uOther)) or (uOther.Kind <> GetKind) then exit(False); - var otherDef := Other.Definition; + var otherDef := uOther.Definition; if (not Assigned(Self.FDefinition)) or (not Assigned(otherDef)) then exit(False); @@ -519,19 +655,26 @@ end; function TRecordType.GetHashCode: Integer; var - i: Integer; + i, h: Integer; field: TPair; begin - Result := Ord(GetKind); + // Seed with Kind + Result := THashBobJenkins.GetHashValue(FKind, SizeOf(TStaticTypeKind), 0); + if Assigned(FDefinition) then begin for i := 0 to FDefinition.Count - 1 do begin field := FDefinition[i]; - var hash := TEqualityComparer.Default.GetHashCode(field.Key); - Result := THashBobJenkins.GetHashValue(hash, SizeOf(Pointer), Result); - var data := Ord(field.Value); - Result := THashBobJenkins.GetHashValue(data, SizeOf(Byte), Result); + + // Hash Key + // Keyword identities are unique by pointer, but let's hash their internal ID/Index for safety + h := field.Key.Idx; + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); + + // Hash Field Type Kind + h := Ord(field.Value); + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); end; end; end; @@ -564,7 +707,7 @@ type constructor Create(const ADef: IGenericRecordDefinition); function GetKind: TStaticTypeKind; override; function GetGenericDefinition: IGenericRecordDefinition; override; - function IsEqual(const Other: IStaticType): Boolean; override; + function IsStructurallyEqual(const Other: IStaticType): Boolean; override; function GetHashCode: Integer; override; function ToString: string; override; end; @@ -585,14 +728,15 @@ begin Result := FDefinition; end; -function TGenericRecordType.IsEqual(const Other: IStaticType): Boolean; +function TGenericRecordType.IsStructurallyEqual(const Other: IStaticType): Boolean; var i: Integer; begin - if (not Assigned(Other)) or (Other.Kind <> stGenericRecord) then + var uOther := TTypes.Unwrap(Other); + if (not Assigned(uOther)) or (uOther.Kind <> stGenericRecord) then exit(False); - var otherDef := Other.GenericDefinition; + var otherDef := uOther.GenericDefinition; if (not Assigned(Self.FDefinition)) or (not Assigned(otherDef)) then exit(False); @@ -601,6 +745,7 @@ begin for i := 0 to Self.FDefinition.Count - 1 do begin + // Deep Check of Field Types if (Self.FDefinition[i].Key <> otherDef[i].Key) or (not Self.FDefinition[i].Value.IsEqual(otherDef[i].Value)) then exit(False); end; @@ -610,21 +755,27 @@ end; function TGenericRecordType.GetHashCode: Integer; var - i: Integer; + i, h: Integer; field: TPair; begin - Result := Ord(stGenericRecord); + h := Ord(stGenericRecord); + Result := THashBobJenkins.GetHashValue(h, SizeOf(TStaticTypeKind), 0); + if Assigned(FDefinition) then begin for i := 0 to FDefinition.Count - 1 do begin field := FDefinition[i]; - var data := TEqualityComparer.Default.GetHashCode(field.Key); - Result := THashBobJenkins.GetHashValue(data, SizeOf(Pointer), Result); + + // Hash Key (using Idx) + h := field.Key.Idx; + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); + + // Hash Value Type if Assigned(field.Value) then begin - var hash := field.Value.GetHashCode; - Result := THashBobJenkins.GetHashValue(hash, SizeOf(Integer), Result); + h := field.Value.GetHashCode; + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); end; end; end; @@ -649,10 +800,66 @@ begin Result := Result + '}'; end; -{ TTypes (Factory) } +// --- TMethodSigArrayComparer --- + +type + TMethodSigArrayComparer = class(TEqualityComparer>) + public + function Equals(const Left, Right: TArray): Boolean; override; + function GetHashCode(const Value: TArray): Integer; override; + end; + +function TMethodSigArrayComparer.Equals(const Left, Right: TArray): Boolean; +var + i, j: Integer; +begin + if Length(Left) <> Length(Right) then + exit(False); + for i := 0 to High(Left) do + begin + if not Left[i].ReturnType.IsEqual(Right[i].ReturnType) then + exit(False); + + var pLeft := Left[i].ParamTypes; + var pRight := Right[i].ParamTypes; + if Length(pLeft) <> Length(pRight) then + exit(False); + + for j := 0 to High(pLeft) do + if not pLeft[j].IsEqual(pRight[j]) then + exit(False); + end; + Result := True; +end; + +function TMethodSigArrayComparer.GetHashCode(const Value: TArray): Integer; +var + sig: IMethodSignature; + p: IStaticType; + h: Integer; +begin + Result := 0; + for sig in Value do + begin + if Assigned(sig.ReturnType) then + begin + h := sig.ReturnType.GetHashCode; + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); + end; + + for p in sig.ParamTypes do + begin + h := p.GetHashCode; + Result := THashBobJenkins.GetHashValue(h, SizeOf(Integer), Result); + end; + end; +end; + +{ TTypes Factory } class constructor TTypes.Create; begin + // 1. Primitives FUnknown := TSimpleStaticType.Create(stUnknown); FVoid := TSimpleStaticType.Create(stVoid); FOrdinal := TSimpleStaticType.Create(stOrdinal); @@ -661,42 +868,158 @@ begin FDateTime := TSimpleStaticType.Create(stDateTime); FText := TSimpleStaticType.Create(stText); FKeyword := TSimpleStaticType.Create(stKeyword); + + // 2. Optional Primitives (pre-cached) + FOrdinalOpt := TOptionalType.Create(FOrdinal); + FFloatOpt := TOptionalType.Create(FFloat); + FBooleanOpt := TOptionalType.Create(FBoolean); + FDateTimeOpt := TOptionalType.Create(FDateTime); + FTextOpt := TOptionalType.Create(FText); + FKeywordOpt := TOptionalType.Create(FKeyword); + + // 3. Caches + FSeriesCache := TDictionary.Create; + FRecordCache := TDictionary.Create; + FRecordSeriesCache := TDictionary.Create; + FGenericRecordCache := TDictionary.Create; + FMethodCache := TDictionary, IStaticType>.Create(TMethodSigArrayComparer.Create); + FOptionalCache := TDictionary.Create; +end; + +class destructor TTypes.Destroy; +begin + FSeriesCache.Free; + FRecordCache.Free; + FRecordSeriesCache.Free; + FGenericRecordCache.Free; + FMethodCache.Free; + FOptionalCache.Free; +end; + +class function TTypes.CreateSeries(const AElementType: IStaticType): IStaticType; +begin + if not Assigned(AElementType) then + exit(FUnknown); + + TMonitor.Enter(FSeriesCache); + try + if FSeriesCache.TryGetValue(AElementType, Result) then + exit; + + Result := TSeriesType.Create(AElementType); + FSeriesCache.Add(AElementType, Result); + finally + TMonitor.Exit(FSeriesCache); + end; +end; + +class function TTypes.CreateRecord(const ADef: IScalarRecordDefinition): IStaticType; +begin + TMonitor.Enter(FRecordCache); + try + if FRecordCache.TryGetValue(ADef, Result) then + exit; + + Result := TRecordType.Create(stRecord, ADef); + FRecordCache.Add(ADef, Result); + finally + TMonitor.Exit(FRecordCache); + end; +end; + +class function TTypes.CreateRecordSeries(const ADef: IScalarRecordDefinition): IStaticType; +begin + TMonitor.Enter(FRecordSeriesCache); + try + if FRecordSeriesCache.TryGetValue(ADef, Result) then + exit; + + Result := TRecordType.Create(stRecordSeries, ADef); + FRecordSeriesCache.Add(ADef, Result); + finally + TMonitor.Exit(FRecordSeriesCache); + end; +end; + +class function TTypes.CreateGenericRecord(const ADef: IGenericRecordDefinition): IStaticType; +begin + TMonitor.Enter(FGenericRecordCache); + try + if FGenericRecordCache.TryGetValue(ADef, Result) then + exit; + + Result := TGenericRecordType.Create(ADef); + FGenericRecordCache.Add(ADef, Result); + finally + TMonitor.Exit(FGenericRecordCache); + end; end; class function TTypes.CreateMethod(const AParamTypes: TArray; const AReturnType: IStaticType): IStaticType; var sig: IMethodSignature; - sigs: TArray; begin sig := TMethodSignature.Create(AParamTypes, AReturnType); - SetLength(sigs, 1); - sigs[0] := sig; - Result := TMethodType.Create(sigs); + Result := CreateMethodSet([sig]); end; class function TTypes.CreateMethodSet(const ASignatures: TArray): IStaticType; begin - Result := TMethodType.Create(ASignatures); + if Length(ASignatures) = 0 then + exit(FUnknown); + + TMonitor.Enter(FMethodCache); + try + if FMethodCache.TryGetValue(ASignatures, Result) then + exit; + + Result := TMethodType.Create(ASignatures); + FMethodCache.Add(ASignatures, Result); + finally + TMonitor.Exit(FMethodCache); + end; end; -class function TTypes.CreateRecord(const ADef: IScalarRecordDefinition): IStaticType; +class function TTypes.MakeOptional(const AType: IStaticType): IStaticType; begin - Result := TRecordType.Create(stRecord, ADef); + if (not Assigned(AType)) or (AType.Kind = stUnknown) or (AType.Kind = stVoid) then + exit(AType); + + if AType.IsOptional then + exit(AType); + + // Fast-Path using pointer comparison on flyweights + if Pointer(AType) = Pointer(FOrdinal) then + exit(FOrdinalOpt); + if Pointer(AType) = Pointer(FFloat) then + exit(FFloatOpt); + if Pointer(AType) = Pointer(FBoolean) then + exit(FBooleanOpt); + if Pointer(AType) = Pointer(FText) then + exit(FTextOpt); + if Pointer(AType) = Pointer(FKeyword) then + exit(FKeywordOpt); + if Pointer(AType) = Pointer(FDateTime) then + exit(FDateTimeOpt); + + TMonitor.Enter(FOptionalCache); + try + if FOptionalCache.TryGetValue(AType, Result) then + exit; + + Result := TOptionalType.Create(AType); + FOptionalCache.Add(AType, Result); + finally + TMonitor.Exit(FOptionalCache); + end; end; -class function TTypes.CreateRecordSeries(const ADef: IScalarRecordDefinition): IStaticType; +class function TTypes.Unwrap(const AType: IStaticType): IStaticType; begin - Result := TRecordType.Create(stRecordSeries, ADef); -end; - -class function TTypes.CreateGenericRecord(const ADef: IGenericRecordDefinition): IStaticType; -begin - Result := TGenericRecordType.Create(ADef); -end; - -class function TTypes.CreateSeries(const AElementType: IStaticType): IStaticType; -begin - Result := TSeriesType.Create(AElementType); + if (Assigned(AType)) and (AType is TOptionalType) then + Result := (AType as TOptionalType).FInner + else + Result := AType; end; class function TTypes.FromScalarKind(AKind: TScalar.TKind): IStaticType; @@ -708,7 +1031,6 @@ begin TScalar.TKind.Boolean: Result := FBoolean; TScalar.TKind.DateTime: Result := FDateTime; else - Assert(False, 'Invalid Scalar Kind'); Result := nil; end; end; @@ -723,22 +1045,26 @@ begin if (Target.Kind = stUnknown) or (Source.Kind = stUnknown) then exit(True); - if Target.IsEqual(Source) then + // STRICTNESS RULE: Cannot assign Optional to Non-Optional + if Source.IsOptional and (not Target.IsOptional) then + exit(False); + + var uTarget := TTypes.Unwrap(Target); + var uSource := TTypes.Unwrap(Source); + + if uTarget.IsStructurallyEqual(uSource) then exit(True); - if (Target.Kind = stFloat) and (Source.Kind = stOrdinal) then + // Auto-Promotion rules + if (uTarget.Kind = stFloat) and (uSource.Kind = stOrdinal) then exit(True); - - if (Target.Kind = stOrdinal) and (Source.Kind = stBoolean) then + if (uTarget.Kind = stOrdinal) and (uSource.Kind = stBoolean) then exit(True); - - if (Target.Kind = stFloat) and (Source.Kind = stDateTime) then + if (uTarget.Kind = stFloat) and (uSource.Kind = stDateTime) then exit(True); - - if (Target.Kind = stVoid) and (Source.Kind = stMethod) then + if (uTarget.Kind = stVoid) and (uSource.Kind = stMethod) then exit(True); - - if (Target.Kind = stOrdinal) and (Source.Kind = stKeyword) then + if (uTarget.Kind = stOrdinal) and (uSource.Kind = stKeyword) then exit(True); Result := False; @@ -746,49 +1072,57 @@ end; class function TTypeRules.Promote(const A, B: IStaticType): IStaticType; begin - // Handle Unknown: If one is Unknown, the result is the other type. if A.Kind = stUnknown then exit(B); if B.Kind = stUnknown then exit(A); - // all operations involving void result void - if (A.Kind = stVoid) or (B.Kind = stVoid) then + // T + Void -> T? + if (A.Kind = stVoid) and (B.Kind <> stVoid) then + exit(TTypes.MakeOptional(B)); + if (B.Kind = stVoid) and (A.Kind <> stVoid) then + exit(TTypes.MakeOptional(A)); + + if (A.Kind = stVoid) and (B.Kind = stVoid) then exit(TTypes.Void); - // Standard Numeric promotion rule: Float wins - if (A.Kind = stFloat) and (B.Kind = stFloat) then - exit(TTypes.Float); - if (A.Kind = stFloat) and (B.Kind = stOrdinal) then - exit(TTypes.Float); - if (A.Kind = stOrdinal) and (B.Kind = stFloat) then - exit(TTypes.Float); - if (A.Kind = stOrdinal) and (B.Kind = stOrdinal) then - exit(TTypes.Ordinal); + var uA := TTypes.Unwrap(A); + var uB := TTypes.Unwrap(B); + var common: IStaticType := nil; - // If types are identical, return that type. - if A.IsEqual(B) then - exit(A); + if uA.IsStructurallyEqual(uB) then + common := uA + else if (uA.Kind = stFloat) and (uB.Kind = stFloat) then + common := TTypes.Float + else if (uA.Kind = stFloat) and (uB.Kind = stOrdinal) then + common := TTypes.Float + else if (uA.Kind = stOrdinal) and (uB.Kind = stFloat) then + common := TTypes.Float + else if (uA.Kind = stOrdinal) and (uB.Kind = stOrdinal) then + common := TTypes.Ordinal; - // No promotion possible - Result := nil; + if common = nil then + exit(nil); + + if A.IsOptional or B.IsOptional then + Result := TTypes.MakeOptional(common) + else + Result := common; end; class function TTypeRules.ResolveBinaryOp(Op: TScalar.TBinaryOp; const Left, Right: IStaticType): IStaticType; -var - promotedType: IStaticType; - promotedKind: TStaticTypeKind; begin - promotedType := Promote(Left, Right); - - // Mismatch during promotion - if not Assigned(promotedType) then + if Left.IsOptional or Right.IsOptional then exit(nil); + var promotedType := Promote(Left, Right); + + if not Assigned(promotedType) then + exit(nil); if promotedType.Kind = stUnknown then exit(TTypes.Unknown); - promotedKind := promotedType.Kind; + var promotedKind := promotedType.Kind; case Op of TScalar.TBinaryOp.Add, TScalar.TBinaryOp.Subtract, TScalar.TBinaryOp.Multiply: @@ -819,17 +1153,16 @@ begin Result := TTypes.Boolean; end; else - // Operation not supported at the AST level (might need folding later, but here it implies invalid usage) Result := nil; end; end; class function TTypeRules.ResolveUnaryOp(Op: TScalar.TUnaryOp; const Right: IStaticType): IStaticType; -var - rightKind: TStaticTypeKind; begin - rightKind := Right.Kind; + if Right.IsOptional then + exit(nil); + var rightKind := Right.Kind; if rightKind = stUnknown then exit(TTypes.Unknown); diff --git a/Src/AST/Myc.Ast.pas b/Src/AST/Myc.Ast.pas index 5fa8c7a..915a9a8 100644 --- a/Src/AST/Myc.Ast.pas +++ b/Src/AST/Myc.Ast.pas @@ -560,7 +560,12 @@ begin var paramList := TParameterList.Create(AParameters, listId); var id := TIdentities.Structural(Loc); - Result := TLambdaExpressionNode.Create(paramList, ABody, TTypes.Unknown, nil, nil, nil, False, False, id); + + var body := ABody; + if body = nil then + body := Block([]); + + Result := TLambdaExpressionNode.Create(paramList, body, TTypes.Unknown, nil, nil, nil, False, False, id); end; class function TAst.LambdaExpr( diff --git a/Test/AST/Test.Myc.Ast.NullPropagation.pas b/Test/AST/Test.Myc.Ast.NullPropagation.pas new file mode 100644 index 0000000..6d99aaa --- /dev/null +++ b/Test/AST/Test.Myc.Ast.NullPropagation.pas @@ -0,0 +1,157 @@ +unit Test.Myc.Ast.NullPropagation; + +interface + +uses + DUnitX.TestFramework, + System.SysUtils, + System.Classes, + Myc.Data.Value, + Myc.Data.Scalar, + Myc.Ast.Environment, + Myc.Ast.Nodes, // For exception types + Myc.Ast.Script; // WICHTIG: Für Parsing + +type + [TestFixture] + TTestNullPropagation = class + private + FEnv: TAstEnvironment; + public + [Setup] + procedure Setup; + [TearDown] + procedure TearDown; + + [Test] + [TestCase('ValidRecord', 'true,10')] + [TestCase('VoidRecord', 'false,0')] + procedure TestMemberAccessPropagation(const Condition: Boolean; const ExpectedVal: Int64); + + [Test] + procedure TestNestedPropagation; + + [Test] + procedure TestIndexerPropagation; + + [Test] + procedure TestStrictArithmeticFailure; + + [Test] + procedure TestStrictComparisonFailure; + end; + +implementation + +{ TTestNullPropagation } + +procedure TTestNullPropagation.Setup; +begin + // Create a fresh standard environment for each test + FEnv := TAstEnvironment.Construct(nil); +end; + +procedure TTestNullPropagation.TearDown; +begin + FEnv := Default(TAstEnvironment); +end; + +procedure TTestNullPropagation.TestMemberAccessPropagation(const Condition: Boolean; const ExpectedVal: Int64); +var + script: string; + resultVal: TDataValue; +begin + // Script: + // 1. Define 'r' which is EITHER a Record {:a 10} OR Void depending on condition. + // 2. Access field .a -> Should propagate Void if r is Void. + + script := Format('(do ' + ' (def r (if %s {:a 10}))' + ' (.a r)' + ')', [BoolToStr(Condition, True).ToLower]); + + resultVal := FEnv.Run(TAstScript.Parse(script)); + + if Condition then + begin + // Case: Object exists + Assert.AreEqual(TDataValueKind.vkScalar, resultVal.Kind, 'Should return a scalar'); + Assert.AreEqual(ExpectedVal, resultVal.AsScalar.Value.AsInt64, 'Should return the field value'); + end + else + begin + // Case: Object is Void (Null Propagation) + Assert.IsTrue(resultVal.IsVoid, 'Accessing member of Void should yield Void'); + end; +end; + +procedure TTestNullPropagation.TestNestedPropagation; +var + script: string; + resultVal: TDataValue; +begin + // Chained Access: (get (.data (if false ...)) 0) + script := '(do ' + ' (def root (if false {:data (new-series "ordinal")}))' + ' (get (.data root) 0)' + ')'; + + resultVal := FEnv.Run(TAstScript.Parse(script)); + + Assert.IsTrue(resultVal.IsVoid, 'Nested access on Void root should propagate Void all the way up'); +end; + +procedure TTestNullPropagation.TestIndexerPropagation; +var + script: string; + resultVal: TDataValue; +begin + // 1. Define 's' as Optional + // 2. Access via Indexer + script := '(do ' + ' (def s (if false (new-series "ordinal")))' + ' (get s 42)' + ')'; + + // FIX: Parse String to AST Node + resultVal := FEnv.Run(TAstScript.Parse(script)); + + Assert.IsTrue(resultVal.IsVoid, 'Indexer access on Void series should yield Void'); +end; + +procedure TTestNullPropagation.TestStrictArithmeticFailure; +begin + // Requirement: Implicit Lifting is FORBIDDEN for arithmetic. + Assert.WillRaise( + procedure + begin + FEnv.Run( + TAstScript.Parse( + ''' + (do + (def a (if true 10)) ; a is Optional + (+ a 5) ; Error: Operator + not defined for Optional + ) + ''' + ) + ); + end, + ECompilationFailed, + 'Arithmetic on optional types must trigger a compilation error' + ); +end; + +procedure TTestNullPropagation.TestStrictComparisonFailure; +begin + // Requirement: Comparisons with Optional types are FORBIDDEN. + Assert.WillRaise( + procedure + begin + FEnv.Run( + TAstScript.Parse( + '(do ' + + ' (def a (if true 10))' + + // a is Optional + ' (> a 5)' + + // Error + ')' + ) + ); + end, + ECompilationFailed, + 'Comparison on optional types must trigger a compilation error' + ); +end; + +end. diff --git a/Test/MycTests.dpr b/Test/MycTests.dpr index 300c395..32958f5 100644 --- a/Test/MycTests.dpr +++ b/Test/MycTests.dpr @@ -33,7 +33,8 @@ uses 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.RTL.TypeRegistry in 'AST\Test.Myc.Ast.RTL.TypeRegistry.pas'; + Test.Myc.Ast.RTL.TypeRegistry in 'AST\Test.Myc.Ast.RTL.TypeRegistry.pas', + Test.Myc.Ast.NullPropagation in 'AST\Test.Myc.Ast.NullPropagation.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 a52214e..9c8069a 100644 --- a/Test/MycTests.dproj +++ b/Test/MycTests.dproj @@ -135,6 +135,7 @@ $(PreBuildEvent)]]> + Base