diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json index d90215c..ba0e7b0 100644 --- a/ASTPlayground/ASTPlayground.delphilsp.json +++ b/ASTPlayground/ASTPlayground.delphilsp.json @@ -1 +1 @@ -{ "settings": { "project": "file:///T%3A/Myc/ASTPlayground/ASTPlayground.dpr", "dllname": "dcc64370.dll", "dccOptions": "-$O- -$W+ --inline:off -$R+ -$Q+ --no-config -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG;;FRAMEWORK_FMX -E.\\Win64\\Debug -I\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -LEC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Bpl\\Win64 -LNC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NU.\\Win64\\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -OT:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -R\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -U\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -V -VN -VR -NBC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NHC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\hpp\\Win64 -NO.\\Win64\\Debug -LU" , "projectFiles":[ { "name": "MainForm", "file": "file:///T%3A/Myc/ASTPlayground/MainForm.pas" }, { "name": "Myc.Ast.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Nodes.pas" }, { "name": "Myc.Ast.Scope", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Scope.pas" }, { "name": "Myc.Data.Value", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Data.Value.pas" }, { "name": "Myc.Ast.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Compiler.TCO", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TCO.pas" }, { "name": "Myc.Ast.Compiler.Binder", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Binder.pas" }, { "name": "Myc.Ast.Compiler.Lowering", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Lowering.pas" }, { "name": "Myc.Ast.Compiler.TypeChecker", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TypeChecker.pas" }, { "name": "Myc.Ast.Compiler.Macros", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Macros.pas" }, { "name": "Myc.Ast.Compiler.Specializer", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Specializer.pas" }, { "name": "Myc.Ast.Environment", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Environment.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Analysis.Purity", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Analysis.Purity.pas" }, { "name": "Myc.Ast.Identities", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Identities.pas" }, { "name": "Myc.Fmx.AstEditor.Visualizer", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Layout", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Layout.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Ast.Refactoring.Remove", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Refactoring.Remove.pas" }, { "name": "Myc.Fmx.AstEditor.Render", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Render.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Lists", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Lists.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Primitives", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Primitives.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Control", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Data", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Data.pas" }, { "name": "Myc.Ast.RTL.TypeRegistry", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.TypeRegistry.pas" }, { "name": "Myc.Trade.Broker", "file": "file:///T%3A/Myc/Src/Myc.Trade.Broker.pas" }, { "name": "Myc.Data.Stream.Pipes", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.Pipes.pas" }, { "name": "Myc.Data.Stream", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Pipes", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Pipes.pas" }, { "name": "Demo.Finance", "file": "file:///T%3A/Myc/Test/Demo.Finance.pas" }, { "name": "Myc.Ast.Script.Print", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.Print.pas" }, { "name": "Myc.Ast.Json.Schema", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.pas" }, { "name": "Myc.Ast.Attributes", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Ast.Attributes.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": true, "browsingPaths": [ "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/OCX/Servers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/VCL","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/RTL/SYS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win/winrt","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/ToolsAPI","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/IBX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Internet","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/PROPERTY%20EDITORS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/XML","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Core","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/System","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Protocols","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/fmx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/components","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/engine","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/graph","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ado","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/cloud","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dbx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dsnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/vclctrls","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/connectors","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/proxygen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DataExplorer","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/src","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/tests","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Experts","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/abstraction","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/implementation","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indyimpl","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Property%20Editors/Indy10","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap/wsdlimporter","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Visualizers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XMLReporting","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XPGen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/rest","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/firedac","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/tethering","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnitX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ems","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/net","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/FlatBox2D","file:///C%3A/Users/Public/Documents/Embarcadero/Studio/37.0/Dcp/%25PLATFORM%25","file:///%25TP%25/runtime/vcl","file:///S%3A/sc_famos_src/svn_vcl/cpxedits","file:///S%3A/sc_famos_src/svn_vcl/dzChart","file:///S%3A/sc_famos_src/svn_vcl/eaeditor","file:///S%3A/sc_famos_src/svn_vcl/FamosEvents","file:///S%3A/sc_famos_src/svn_vcl/HTML_Viewer/source","file:///S%3A/sc_famos_src/svn_vcl/Myc_ChartEdit","file:///S%3A/sc_famos_src/svn_vcl/Myc_HemiDrag","file:///S%3A/sc_famos_src/svn_vcl/Myc_SplitControl","file:///S%3A/sc_famos_src/svn_vcl/NiceChart","file:///S%3A/sc_famos_src/svn_vcl/plotter","file:///S%3A/sc_famos_src/svn_vcl/SimpleIPC","file:///S%3A/sc_famos_src/svn_vcl/SynEdit-master/Source","file:///S%3A/sc_famos_src/svn_vcl/ValEdits","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib/win32","file:///S%3A/sc_famos_src/svn_vcl/Virtual-TreeView/Source","file:///S%3A/sc_famos_src/svn_common/caHelpSys","file:///S%3A/sc_famos_src/svn_common/Misc","file:///S%3A/sc_famos_src/svn_common/Myc_VecMath","file:///S%3A/sc_famos_src/svn_common/PascalScript/source","file:///S%3A/sc_famos_src/svn_common/TreeBase","file:///S%3A/sc_famos_src/svn_common/TreeBase/Medien","file:///S%3A/3rdParty/spring4d/Source","file:///S%3A/3rdParty/spring4d/Source/Base","file:///S%3A/3rdParty/spring4d/Source/Base/Collections","file:///S%3A/3rdParty/spring4d/Source/Base/Logging","file:///S%3A/3rdParty/spring4d/Source/Base/Patches","file:///S%3A/3rdParty/spring4d/Source/Core/Container","file:///S%3A/3rdParty/spring4d/Source/Core/Interception","file:///S%3A/3rdParty/spring4d/Source/Core/Logging","file:///S%3A/3rdParty/spring4d/Source/Core/Mocking","file:///S%3A/3rdParty/spring4d/Source/Core/Services","file:///S%3A/3rdParty/spring4d/Source/Extensions/Cryptography","file:///S%3A/3rdParty/spring4d/Source/Extensions/Utils","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCommon%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressGDI%2B%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLibrary/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/XP%20Theme%20Manager/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLayout%20Control/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressPageControl/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressEditors%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDocking%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressBars/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressOfficeCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressMemData/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDataController/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressNavBar/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressSkins%20Library/Sources","file:///T%3A/Myc/Src","file:///T%3A/Myc/Src/Data","file:///T%3A/Myc/Src/AST" ] , "CommonAppData": "file:///C%3A/Users/Brummel/AppData/Roaming/Embarcadero/BDS/37.0/" , "Templates": "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/ObjRepos/" } } \ No newline at end of file +{ "settings": { "project": "file:///T%3A/Myc/ASTPlayground/ASTPlayground.dpr", "dllname": "dcc64370.dll", "dccOptions": "-$O- -$W+ --inline:off -$R+ -$Q+ --no-config -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG;;FRAMEWORK_FMX -E.\\Win64\\Debug -I\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -LEC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Bpl\\Win64 -LNC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NU.\\Win64\\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -OT:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -R\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -U\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -V -VN -VR -NBC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NHC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\hpp\\Win64 -NO.\\Win64\\Debug -LU" , "projectFiles":[ { "name": "MainForm", "file": "file:///T%3A/Myc/ASTPlayground/MainForm.pas" }, { "name": "Myc.Ast.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Nodes.pas" }, { "name": "Myc.Ast.Scope", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Scope.pas" }, { "name": "Myc.Data.Value", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Data.Value.pas" }, { "name": "Myc.Ast.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Compiler.TCO", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TCO.pas" }, { "name": "Myc.Ast.Compiler.Binder", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Binder.pas" }, { "name": "Myc.Ast.Compiler.Lowering", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Lowering.pas" }, { "name": "Myc.Ast.Compiler.TypeChecker", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TypeChecker.pas" }, { "name": "Myc.Ast.Compiler.Macros", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Macros.pas" }, { "name": "Myc.Ast.Compiler.Specializer", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Specializer.pas" }, { "name": "Myc.Ast.Environment", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Environment.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Analysis.Purity", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Analysis.Purity.pas" }, { "name": "Myc.Ast.Identities", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Identities.pas" }, { "name": "Myc.Fmx.AstEditor.Visualizer", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Layout", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Layout.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Ast.Refactoring.Remove", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Refactoring.Remove.pas" }, { "name": "Myc.Fmx.AstEditor.Render", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Render.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Lists", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Lists.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Primitives", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Primitives.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Control", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Data", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Data.pas" }, { "name": "Myc.Ast.RTL.TypeRegistry", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.TypeRegistry.pas" }, { "name": "Myc.Trade.Broker", "file": "file:///T%3A/Myc/Src/Myc.Trade.Broker.pas" }, { "name": "Myc.Data.Stream.Pipes", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.Pipes.pas" }, { "name": "Myc.Data.Stream", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Pipes", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Pipes.pas" }, { "name": "Demo.Finance", "file": "file:///T%3A/Myc/Test/Demo.Finance.pas" }, { "name": "Myc.Ast.Script.Print", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.Print.pas" }, { "name": "Myc.Ast.Json.Schema", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.pas" }, { "name": "Myc.Ast.Attributes", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Ast.Attributes.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": false, "browsingPaths": [ "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/OCX/Servers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/VCL","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/RTL/SYS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win/winrt","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/ToolsAPI","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/IBX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Internet","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/PROPERTY%20EDITORS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/XML","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Core","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/System","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Protocols","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/fmx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/components","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/engine","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/graph","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ado","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/cloud","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dbx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dsnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/vclctrls","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/connectors","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/proxygen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DataExplorer","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/src","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/tests","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Experts","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/abstraction","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/implementation","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indyimpl","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Property%20Editors/Indy10","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap/wsdlimporter","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Visualizers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XMLReporting","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XPGen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/rest","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/firedac","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/tethering","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnitX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ems","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/net","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/FlatBox2D","file:///C%3A/Users/Public/Documents/Embarcadero/Studio/37.0/Dcp/%25PLATFORM%25","file:///%25TP%25/runtime/vcl","file:///S%3A/sc_famos_src/svn_vcl/cpxedits","file:///S%3A/sc_famos_src/svn_vcl/dzChart","file:///S%3A/sc_famos_src/svn_vcl/eaeditor","file:///S%3A/sc_famos_src/svn_vcl/FamosEvents","file:///S%3A/sc_famos_src/svn_vcl/HTML_Viewer/source","file:///S%3A/sc_famos_src/svn_vcl/Myc_ChartEdit","file:///S%3A/sc_famos_src/svn_vcl/Myc_HemiDrag","file:///S%3A/sc_famos_src/svn_vcl/Myc_SplitControl","file:///S%3A/sc_famos_src/svn_vcl/NiceChart","file:///S%3A/sc_famos_src/svn_vcl/plotter","file:///S%3A/sc_famos_src/svn_vcl/SimpleIPC","file:///S%3A/sc_famos_src/svn_vcl/SynEdit-master/Source","file:///S%3A/sc_famos_src/svn_vcl/ValEdits","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib/win32","file:///S%3A/sc_famos_src/svn_vcl/Virtual-TreeView/Source","file:///S%3A/sc_famos_src/svn_common/caHelpSys","file:///S%3A/sc_famos_src/svn_common/Misc","file:///S%3A/sc_famos_src/svn_common/Myc_VecMath","file:///S%3A/sc_famos_src/svn_common/PascalScript/source","file:///S%3A/sc_famos_src/svn_common/TreeBase","file:///S%3A/sc_famos_src/svn_common/TreeBase/Medien","file:///S%3A/3rdParty/spring4d/Source","file:///S%3A/3rdParty/spring4d/Source/Base","file:///S%3A/3rdParty/spring4d/Source/Base/Collections","file:///S%3A/3rdParty/spring4d/Source/Base/Logging","file:///S%3A/3rdParty/spring4d/Source/Base/Patches","file:///S%3A/3rdParty/spring4d/Source/Core/Container","file:///S%3A/3rdParty/spring4d/Source/Core/Interception","file:///S%3A/3rdParty/spring4d/Source/Core/Logging","file:///S%3A/3rdParty/spring4d/Source/Core/Mocking","file:///S%3A/3rdParty/spring4d/Source/Core/Services","file:///S%3A/3rdParty/spring4d/Source/Extensions/Cryptography","file:///S%3A/3rdParty/spring4d/Source/Extensions/Utils","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCommon%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressGDI%2B%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLibrary/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/XP%20Theme%20Manager/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLayout%20Control/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressPageControl/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressEditors%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDocking%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressBars/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressOfficeCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressMemData/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDataController/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressNavBar/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressSkins%20Library/Sources","file:///T%3A/Myc/Src","file:///T%3A/Myc/Src/Data","file:///T%3A/Myc/Src/AST" ] , "CommonAppData": "file:///C%3A/Users/Brummel/AppData/Roaming/Embarcadero/BDS/37.0/" , "Templates": "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/ObjRepos/" } } \ No newline at end of file diff --git a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas index eb05637..ddda86c 100644 --- a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas +++ b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas @@ -687,30 +687,77 @@ var newBase, newIndex: IAstNode; baseType, elemType: IStaticType; isOpt: Boolean; + idx: Integer; + key: IKeyword; begin I := Node.AsIndexer; newBase := Accept(I.Base); newIndex := Accept(I.Index); - baseType := PrepareBaseType(newBase, isOpt); + // Unwrap optional types to check the underlying structure + baseType := PrepareBaseType(newBase, isOpt); elemType := TTypes.Unknown; - if baseType.Kind = stSeries then - elemType := baseType.AsSeries.ElementType - else if baseType.Kind = stRecordSeries then - elemType := TTypes.CreateRecord(baseType.AsRecord.Definition) - else if baseType.Kind = stTuple then - begin - // Tuple Indexing (requires constant index for strong typing!) - if (newIndex.Kind = akConstant) and (newIndex.AsConstant.Value.Kind = vkScalar) then + + case baseType.Kind of + // Case 1: Accessing Tuples (Heterogeneous fixed-size lists) + // Static typing requires the index to be a constant integer to determine the specific element type. + stTuple: begin - var idx := newIndex.AsConstant.Value.AsScalar.Value.AsInt64; - var tpl := baseType.AsTuple; - if (idx >= 0) and (idx < tpl.Count) then - elemType := tpl.Elements[Integer(idx)]; + if (newIndex.Kind = akConstant) and (newIndex.AsConstant.Value.Kind = vkScalar) then + begin + var intIdx := newIndex.AsConstant.Value.AsScalar.Value.AsInt64; + var tpl := baseType.AsTuple; + if (intIdx >= 0) and (intIdx < tpl.Count) then + elemType := tpl.Elements[Integer(intIdx)]; + end; + end; + + // Case 2: Accessing Records or Record Series (Field Access) + // Static typing requires the index to be a Keyword literal. + stRecord, stRecordSeries: + begin + if newIndex.Kind = akKeyword then + begin + key := newIndex.AsKeyword.Value; + var def := baseType.AsRecord.Definition; + + idx := def.IndexOf(key); + if idx >= 0 then + begin + var fieldType := TTypes.FromScalarKind(def[idx]); + + // If we access a field on a Stream/Series of Records, the result is a Series of that field (Column). + // If we access a field on a single Record, the result is the scalar value. + if baseType.Kind = stRecordSeries then + elemType := TTypes.CreateSeries(fieldType) + else + elemType := fieldType; + end + else if Assigned(FLog) then + FLog.AddError(Format('Field ":%s" not found in record definition.', [key.Name]), Node); + end + else if Assigned(FLog) then + FLog.AddError('Record access requires a constant keyword literal (e.g. :close).', Node); + end; + + // Case 3: Accessing Series via Integer Index (Row Access) + // Returns the scalar element at the specific position. + stSeries: + begin + elemType := baseType.AsSeries.ElementType; + end; + + // Case 4: Vector / Matrix (Homogeneous) + // Accessing a Vector returns the ElementType. + stVector: + begin + elemType := baseType.AsVector.ElementType; end; end; + // Propagate nullability if the base object was optional elemType := ApplyOptionality(elemType, isOpt); + Result := TAst.Indexer(Node.Identity, newBase, newIndex, elemType); end; diff --git a/Src/AST/Myc.Ast.Script.pas b/Src/AST/Myc.Ast.Script.pas index 9e00126..ed0636b 100644 --- a/Src/AST/Myc.Ast.Script.pas +++ b/Src/AST/Myc.Ast.Script.pas @@ -4,10 +4,15 @@ interface uses System.SysUtils, + System.Classes, + System.Generics.Collections, + System.Character, + System.Rtti, // Wichtig für die EBNF-Extraktion Myc.Data.Value, Myc.Ast.Nodes, Myc.Ast.Visitor, - Myc.Ast.Script.Print; + Myc.Ast.Script.Print, + Myc.Ast; type EParserException = class(EAstException) @@ -20,48 +25,61 @@ type property Col: Integer read FCol; end; + { Attribut zur Dokumentation der Grammatik direkt am Code } + EbnfAttribute = class(TCustomAttribute) + private + FRule: string; + public + constructor Create(const ARule: string); + property Rule: string read FRule; + end; + TAstScript = record public class function Parse(const ASource: string): IAstNode; static; class function Print(const ANode: IAstNode): string; static; + + { Extrahiert die vollständige EBNF-Grammatik aus den Annotationen des Parsers } + class function GetGrammar: string; static; end; implementation uses - System.Classes, - System.Generics.Collections, - System.Character, - System.Math, + System.TypInfo, + System.Generics.Defaults, Myc.Data.Scalar, Myc.Data.Keyword, - Myc.Ast, Myc.Ast.Identities; +{ EbnfAttribute } + +constructor EbnfAttribute.Create(const ARule: string); +begin + inherited Create; + FRule := ARule; +end; + type TTokenKind = ( - tkLeftParen, - tkRightParen, - tkLeftBracket, - tkRightBracket, - tkLeftBrace, - tkRightBrace, - tkQuote, - tkBacktick, - tkTilde, - tkAt, - tkIdentifier, - tkKeyword, - tkNumber, - tkString, + tkLeftParen, // ( + tkRightParen, // ) + tkLeftBracket, // [ + tkRightBracket, // ] + tkLeftBrace, // { + tkRightBrace, // } + tkQuote, // ' + tkBacktick, // ` + tkTilde, // ~ + tkAt, // @ + tkIdentifier, // abc, +, .field + tkKeyword, // :abc + tkNumber, // 123, 12.34 + tkString, // "..." tkEOF, tkError ); - TTokenKindHelper = record helper for TTokenKind - function ToString: String; - end; - TToken = record Kind: TTokenKind; Text: string; @@ -70,6 +88,9 @@ type function GetLocation: ISourceLocation; end; + // ------------------------------------------------------------------------- + // LEXER + // ------------------------------------------------------------------------- TLexer = class private FSource: string; @@ -91,63 +112,137 @@ type property CurrentCol: Integer read GetCurrentCol; end; - TExpr = record - Token: TToken; - Node: IAstNode; - end; + // ------------------------------------------------------------------------- + // PARSER + // ------------------------------------------------------------------------- + // Wir erzwingen RTTI für private Methoden, damit wir die EbnfAttributes lesen können + {$RTTI EXPLICIT METHODS([vcPrivate, vcProtected, vcPublic])} TParser = class + private + type + TSpecialFormParser = function: IAstNode of object; private FLexer: TLexer; FCurrentToken: TToken; + FSpecialForms: TDictionary; + procedure Error(const Msg: string); procedure ErrorFmt(const Msg: string; const Args: array of const); procedure Consume(AExpectedKind: TTokenKind); procedure NextToken; + function Match(AKind: TTokenKind): Boolean; + // --- EBNF Non-Terminal Methods --- + + // Entry Point + [Ebnf('script ::= expression EOF')] + function ParseScript: IAstNode; + + // Core Expressions + [Ebnf('expression ::= atom | list | vector | map | reader-macro')] + function ParseExpression: IAstNode; + + [Ebnf('atom ::= identifier | keyword | number | string | nop')] + function ParseAtom: IAstNode; + + [Ebnf('list ::= "(" list-content ")"')] function ParseList: IAstNode; - function ParseRecordLiteral: IAstNode; - function ParseVector: IAstNode; - function ParseExpression: TExpr; + [Ebnf('vector ::= "[" { expression } "]"')] + function ParseVector: IAstNode; + + [Ebnf('map ::= "{" { keyword expression } "}"')] + function ParseMap: IAstNode; + + [Ebnf('reader-macro ::= "''" expression | "`" expression | "~" expression | "~@" expression')] + function ParseReaderMacro: IAstNode; + + // Atoms + [Ebnf('identifier ::= ? defined by lexer ?')] + function ParseIdentifier: IAstNode; + + [Ebnf('keyword ::= ":" identifier')] + function ParseKeyword: IAstNode; + + [Ebnf('number ::= ? integer or float literal ?')] + function ParseNumber: IAstNode; + + [Ebnf('string ::= """ ? characters ? """')] + function ParseString: IAstNode; + + [Ebnf('nop ::= "..."')] + function ParseNop: IAstNode; + + // List Content & Dispatch + [Ebnf('list-content ::= special-form | member-access-sugar | function-call')] + function ParseListContent: IAstNode; + + [Ebnf('special-form ::= form-if | form-cond | form-fn | ... (* dispatched by head identifier *)')] + function ParseSpecialForm(const FormName: string): IAstNode; + + [Ebnf('member-access-sugar ::= dot-identifier expression')] + function ParseMemberAccessSugar: IAstNode; + + [Ebnf('function-call ::= expression { expression }')] + function ParseFunctionCall: IAstNode; + + // Special Forms (Sub-Rules) + [Ebnf('form-if ::= "if" expression expression [ expression ]')] + function ParseIf: IAstNode; + + [Ebnf('form-cond ::= "?" { expression expression } [ expression ]')] + function ParseCond: IAstNode; + + [Ebnf('form-fn ::= "fn" vector expression')] + function ParseFn: IAstNode; + + [Ebnf('form-defmacro ::= "defmacro" identifier vector expression')] + function ParseDefMacro: IAstNode; + + [Ebnf('form-def ::= "def" expression [ expression ]')] + function ParseDef: IAstNode; + + [Ebnf('form-assign ::= "assign" expression expression')] + function ParseAssign: IAstNode; + + [Ebnf('form-do ::= "do" { expression }')] + function ParseDo: IAstNode; + + [Ebnf('form-recur ::= "recur" { expression }')] + function ParseRecur: IAstNode; + + [Ebnf('form-quote ::= "quote" expression')] + function ParseQuoteForm: IAstNode; + + [Ebnf('form-pipe ::= "pipe" vector expression')] + function ParsePipe: IAstNode; + + [Ebnf('form-series ::= "new-series" expression')] + function ParseNewSeries: IAstNode; + + [Ebnf('form-add ::= "add-item" expression expression [ expression ]')] + function ParseAddItem: IAstNode; + + [Ebnf('form-count ::= "count" expression')] + function ParseCount: IAstNode; + + [Ebnf('form-get ::= "get" expression expression')] + function ParseGet: IAstNode; + + // Helpers + function ParseTupleBody(StopToken: TTokenKind): TArray; function ExtractIdentifiers(const Node: IAstNode; const Context: string): TArray; + procedure InitSpecialForms; + public constructor Create(const ASource: string); destructor Destroy; override; function Parse: IAstNode; end; -{ TTokenKindHelper } -function TTokenKindHelper.ToString: String; -begin - case Self of - tkLeftParen: Result := '('; - tkRightParen: Result := ')'; - tkLeftBracket: Result := '['; - tkRightBracket: Result := ']'; - tkLeftBrace: Result := '{'; - tkRightBrace: Result := '}'; - tkQuote: Result := ''''; - tkBacktick: Result := '`'; - tkTilde: Result := '~'; - tkAt: Result := '@'; - tkIdentifier: Result := ''; - tkKeyword: Result := ''; - tkNumber: Result := ''; - tkString: Result := ''; - tkEOF: Result := ''; - else - Result := ''; - end; -end; - -{ TToken } -function TToken.GetLocation: ISourceLocation; -begin - Result := TIdentities.Location(Line, Col); -end; - { EParserException } + constructor EParserException.Create(const AMessage: string; ALine, ACol: Integer); begin inherited CreateFmt('[Line %d, Col %d] %s', [ALine, ACol, AMessage]); @@ -155,7 +250,15 @@ begin FCol := ACol; end; +{ TToken } + +function TToken.GetLocation: ISourceLocation; +begin + Result := TIdentities.Location(Line, Col); +end; + { TLexer } + constructor TLexer.Create(const ASource: string); begin inherited Create; @@ -189,13 +292,10 @@ begin end; procedure TLexer.Advance; -var - c: Char; begin if FCurrentPos <= Length(FSource) then begin - c := FSource[FCurrentPos]; - if c = #10 then + if FSource[FCurrentPos] = #10 then begin Inc(FLine); FLineStart := FCurrentPos + 1; @@ -209,7 +309,8 @@ var startPos: Integer; begin startPos := FCurrentPos; - while (Peek <> #0) and (not (Peek.IsWhiteSpace or CharInSet(Peek, ['(', ')', '[', ']', '{', '}', '''', '`', '~', ';']))) do + // Identifiers can contain almost anything except structural chars and whitespace + while (Peek <> #0) and (not (Peek.IsWhiteSpace or CharInSet(Peek, ['(', ')', '[', ']', '{', '}', '"', '''', '`', '~', ';', '@']))) do Advance; Result := Copy(FSource, startPos, FCurrentPos - startPos); end; @@ -221,7 +322,6 @@ begin startPos := FCurrentPos; if (Peek = '-') then Advance; - while (Peek <> #0) and (Peek.IsDigit or (Peek = '.')) do Advance; Result := Copy(FSource, startPos, FCurrentPos - startPos); @@ -229,11 +329,11 @@ end; function TLexer.ReadString: string; var - builder: TStringBuilder; + sb: TStringBuilder; c: Char; begin - Advance; - builder := TStringBuilder.Create; + Advance; // Skip opening quote + sb := TStringBuilder.Create; try while (FCurrentPos <= Length(FSource)) do begin @@ -241,25 +341,23 @@ begin if c = '"' then begin Advance; - Result := builder.ToString; + Result := sb.ToString; exit; end; - if c = '\' then begin Advance; if FCurrentPos > Length(FSource) then - Error('Syntax Error: String literal ends with an escape character.'); - + Error('Unterminated string'); c := Peek; case c of - '"': builder.Append('"'); - '\': builder.Append('\'); - 'n': builder.Append(sLineBreak); - 't': builder.Append(#9); - 'r': builder.Append(#13); + 'n': sb.Append(#10); + 'r': sb.Append(#13); + 't': sb.Append(#9); + '"': sb.Append('"'); + '\': sb.Append('\'); else - builder.Append(c); + sb.Append(c); end; Advance; end @@ -267,13 +365,13 @@ begin begin if c = #0 then break; - builder.Append(c); + sb.Append(c); Advance; end; end; - Error('Syntax Error: Unterminated string literal.'); + Error('Unterminated string'); finally - builder.Free; + sb.Free; end; end; @@ -281,23 +379,24 @@ function TLexer.GetNextToken: TToken; begin while FCurrentPos <= Length(FSource) do begin - if FSource[FCurrentPos].IsWhiteSpace then + // Skip Whitespace + if Peek.IsWhiteSpace then begin Advance; continue; end; - - if FSource[FCurrentPos] = ';' then + // Skip Comment + if Peek = ';' then begin - while (FCurrentPos <= Length(FSource)) and (not CharInSet(FSource[FCurrentPos], [#10, #13])) do + while (Peek <> #0) and (Peek <> #10) and (Peek <> #13) do Advance; continue; end; break; end; - Result.Line := CurrentLine; - Result.Col := CurrentCol; + Result.Line := FLine; + Result.Col := (FCurrentPos - FLineStart + 1); if FCurrentPos > Length(FSource) then begin @@ -310,51 +409,61 @@ begin '(': begin Result.Kind := tkLeftParen; + Result.Text := '('; Advance; end; ')': begin Result.Kind := tkRightParen; + Result.Text := ')'; Advance; end; '[': begin Result.Kind := tkLeftBracket; + Result.Text := '['; Advance; end; ']': begin Result.Kind := tkRightBracket; + Result.Text := ']'; Advance; end; '{': begin Result.Kind := tkLeftBrace; + Result.Text := '{'; Advance; end; '}': begin Result.Kind := tkRightBrace; + Result.Text := '}'; Advance; end; '''': begin Result.Kind := tkQuote; + Result.Text := ''''; Advance; end; '`': begin Result.Kind := tkBacktick; + Result.Text := '`'; Advance; end; '~': begin Result.Kind := tkTilde; + Result.Text := '~'; Advance; end; '@': begin Result.Kind := tkAt; + Result.Text := '@'; Advance; end; '"': @@ -367,10 +476,9 @@ begin Advance; Result.Kind := tkKeyword; Result.Text := ReadIdentifier; - if Result.Text.IsEmpty then - Result.Kind := tkError; end; else + // Number detection: digit or minus followed by digit if c.IsDigit or ((c = '-') and (FCurrentPos < Length(FSource)) and FSource[FCurrentPos + 1].IsDigit) then begin Result.Kind := tkNumber; @@ -390,15 +498,36 @@ constructor TParser.Create(const ASource: string); begin inherited Create; FLexer := TLexer.Create(ASource); + InitSpecialForms; NextToken; end; destructor TParser.Destroy; begin + FSpecialForms.Free; FLexer.Free; inherited; end; +procedure TParser.InitSpecialForms; +begin + FSpecialForms := TDictionary.Create(TStringComparer.Ordinal); + FSpecialForms.Add('if', ParseIf); + FSpecialForms.Add('?', ParseCond); + FSpecialForms.Add('fn', ParseFn); + FSpecialForms.Add('defmacro', ParseDefMacro); + FSpecialForms.Add('def', ParseDef); + FSpecialForms.Add('assign', ParseAssign); + FSpecialForms.Add('do', ParseDo); + FSpecialForms.Add('recur', ParseRecur); + FSpecialForms.Add('quote', ParseQuoteForm); + FSpecialForms.Add('pipe', ParsePipe); + FSpecialForms.Add('new-series', ParseNewSeries); + FSpecialForms.Add('add-item', ParseAddItem); + FSpecialForms.Add('count', ParseCount); + FSpecialForms.Add('get', ParseGet); +end; + procedure TParser.Error(const Msg: string); begin raise EParserException.Create(Msg, FCurrentToken.Line, FCurrentToken.Col); @@ -406,7 +535,7 @@ end; procedure TParser.ErrorFmt(const Msg: string; const Args: array of const); begin - raise EParserException.Create(Format(Msg, Args), FCurrentToken.Line, FCurrentToken.Col); + Error(Format(Msg, Args)); end; procedure TParser.NextToken; @@ -417,319 +546,514 @@ end; procedure TParser.Consume(AExpectedKind: TTokenKind); begin if FCurrentToken.Kind <> AExpectedKind then - ErrorFmt('Syntax Error: Expected token %s, but found %s', [AExpectedKind.ToString, FCurrentToken.Kind.ToString]); + ErrorFmt('Expected %s but found %s', [GetEnumName(TypeInfo(TTokenKind), Ord(AExpectedKind)), FCurrentToken.Text]); + NextToken; +end; + +function TParser.Match(AKind: TTokenKind): Boolean; +begin + Result := FCurrentToken.Kind = AKind; + if Result then + NextToken; +end; + +// ============================================================================= +// EBNF Implementation +// ============================================================================= + +function TParser.Parse: IAstNode; +begin + Result := ParseScript; +end; + +function TParser.ParseScript: IAstNode; +begin + Result := ParseExpression; + if FCurrentToken.Kind <> tkEOF then + Error('Unexpected chars after end of expression (EOF expected).'); +end; + +function TParser.ParseExpression: IAstNode; +begin + case FCurrentToken.Kind of + tkLeftParen: Result := ParseList; + tkLeftBracket: Result := ParseVector; + tkLeftBrace: Result := ParseMap; + + tkQuote, tkBacktick, tkTilde: Result := ParseReaderMacro; + + else + Result := ParseAtom; + end; +end; + +function TParser.ParseList: IAstNode; +begin + Consume(tkLeftParen); + + if FCurrentToken.Kind = tkRightParen then + Error('Syntax Error: Empty list () is not a valid expression.'); + + Result := ParseListContent; + + Consume(tkRightParen); +end; + +function TParser.ParseListContent: IAstNode; +var + headToken: TToken; + headName: string; +begin + // Look ahead at the head of the list + headToken := FCurrentToken; + + if headToken.Kind = tkIdentifier then + begin + headName := headToken.Text; + + // 1. Special Form? + if FSpecialForms.ContainsKey(headName) then + begin + NextToken; // Consume Head + Result := ParseSpecialForm(headName); + Exit; + end; + + // 2. Member Access Sugar (.prop obj)? + if (headName.Length > 1) and (headName.StartsWith('.')) then + begin + Result := ParseMemberAccessSugar; + Exit; + end; + end; + + // 3. Default: Function Call + Result := ParseFunctionCall; +end; + +function TParser.ParseSpecialForm(const FormName: string): IAstNode; +var + parser: TSpecialFormParser; +begin + parser := FSpecialForms[FormName]; + Result := parser(); +end; + +function TParser.ParseMemberAccessSugar: IAstNode; +var + loc: ISourceLocation; + propName: string; + propKey: IKeywordNode; + baseObj: IAstNode; +begin + // Current Token is the dot-identifier (e.g. ".price") + loc := FCurrentToken.GetLocation; + propName := FCurrentToken.Text.Substring(1); // Strip dot + NextToken; // Consume dot-identifier + + baseObj := ParseExpression; + propKey := TAst.Keyword(propName, loc); + + Result := TAst.MemberAccess(baseObj, propKey, loc); +end; + +function TParser.ParseFunctionCall: IAstNode; +var + loc: ISourceLocation; + callee: IAstNode; + args: TArray; + argList: TList; +begin + loc := FCurrentToken.GetLocation; + + // First expression is the callee + callee := ParseExpression; + + // Remaining expressions until ')' are arguments + argList := TList.Create; + try + while FCurrentToken.Kind <> tkRightParen do + begin + if FCurrentToken.Kind = tkEOF then + Error('Unexpected EOF in function call'); + argList.Add(ParseExpression); + end; + args := argList.ToArray; + finally + argList.Free; + end; + + Result := TAst.FunctionCall(callee, args, loc); +end; + +function TParser.ParseAtom: IAstNode; +begin + case FCurrentToken.Kind of + tkIdentifier: Result := ParseIdentifier; + tkKeyword: Result := ParseKeyword; + tkNumber: Result := ParseNumber; + tkString: Result := ParseString; + else + ErrorFmt('Unexpected token for atom: %s', [FCurrentToken.Text]); + Result := nil; // satisfy compiler + end; +end; + +function TParser.ParseIdentifier: IAstNode; +var + loc: ISourceLocation; + name: string; +begin + loc := FCurrentToken.GetLocation; + name := FCurrentToken.Text; + NextToken; + + if name = '...' then + Result := ParseNop + else + Result := TAst.Identifier(name, loc); +end; + +function TParser.ParseNop: IAstNode; +begin + // Nop is handled via Identifier branch, but structurally it's an atom kind + Result := TAst.Nop(FCurrentToken.GetLocation); +end; + +function TParser.ParseKeyword: IAstNode; +var + loc: ISourceLocation; +begin + loc := FCurrentToken.GetLocation; + Result := TAst.Keyword(FCurrentToken.Text, loc); + NextToken; +end; + +function TParser.ParseNumber: IAstNode; +var + loc: ISourceLocation; + s: string; + i64: Int64; + dbl: Double; +begin + loc := FCurrentToken.GetLocation; + s := FCurrentToken.Text; + NextToken; + + if TryStrToInt64(s, i64) then + Result := TAst.Constant(i64, loc) + else if TryStrToFloat(s, dbl, TFormatSettings.Invariant) then + Result := TAst.Constant(dbl, loc) + else + Error('Invalid number format'); +end; + +function TParser.ParseString: IAstNode; +var + loc: ISourceLocation; +begin + loc := FCurrentToken.GetLocation; + Result := TAst.Constant(FCurrentToken.Text, loc); NextToken; end; function TParser.ParseVector: IAstNode; var - items: TList; - startLoc: ISourceLocation; + loc: ISourceLocation; + elems: TArray; begin - startLoc := FCurrentToken.GetLocation; + loc := FCurrentToken.GetLocation; Consume(tkLeftBracket); - items := TList.Create; - try - while FCurrentToken.Kind <> tkRightBracket do - begin - if FCurrentToken.Kind = tkEOF then - Error('Syntax Error: Unexpected end of file in vector.'); - items.Add(ParseExpression.Node); - end; - - Result := TAst.Tuple(items.ToArray, startLoc); - finally - items.Free; - end; - Consume(tkRightBracket); + elems := ParseTupleBody(tkRightBracket); + Result := TAst.Tuple(elems, loc); end; -function TParser.ExtractIdentifiers(const Node: IAstNode; const Context: string): TArray; -var - tuple: ITupleNode; - i: Integer; -begin - if Node.Kind <> akTuple then - ErrorFmt('%s expects a vector [...]', [Context]); - - tuple := Node.AsTuple; - // Updated to use Elements property - var elements := tuple.Elements; - SetLength(Result, Length(elements)); - for i := 0 to High(elements) do - begin - if elements[i].Kind <> akIdentifier then - ErrorFmt('%s vector must contain only identifiers.', [Context]); - Result[i] := elements[i].AsIdentifier; - end; -end; - -function TParser.ParseRecordLiteral: IAstNode; +function TParser.ParseMap: IAstNode; var + loc: ISourceLocation; fields: TList; - fieldName: string; - fieldValue: IAstNode; - keyToken: TToken; - keyNode: IKeywordNode; + keyNode: IAstNode; + valNode: IAstNode; begin - var startLoc := FCurrentToken.GetLocation; + loc := FCurrentToken.GetLocation; Consume(tkLeftBrace); + fields := TList.Create; try while FCurrentToken.Kind <> tkRightBrace do begin if FCurrentToken.Kind = tkEOF then - Error('Syntax Error: Unexpected end of file in record literal.'); + Error('Unexpected EOF in map'); - if FCurrentToken.Kind <> tkKeyword then - Error('Syntax Error: Expected keyword (e.g., :key) as field name in record literal.'); - - keyToken := FCurrentToken; - fieldName := FCurrentToken.Text; - keyNode := TAst.Keyword(fieldName, keyToken.GetLocation); - NextToken; + keyNode := ParseExpression; + if keyNode.Kind <> akKeyword then + Error('Map keys must be keywords'); if FCurrentToken.Kind = tkRightBrace then - Error('Syntax Error: Missing value for key ' + fieldName + ' in record literal.'); + Error('Missing value in map'); - fieldValue := ParseExpression.Node; + valNode := ParseExpression; - fields.Add(TAst.RecordField(keyNode, fieldValue, keyToken.GetLocation)); + fields.Add(TAst.RecordField(keyNode.AsKeyword, valNode)); end; - // Factory automatically wraps array into TupleNode - Result := TAst.RecordLiteral(fields.ToArray, startLoc); + + Consume(tkRightBrace); + Result := TAst.RecordLiteral(fields.ToArray, loc); finally fields.Free; end; - Consume(tkRightBrace); end; -function TParser.ParseList: IAstNode; +function TParser.ParseReaderMacro: IAstNode; var - elements: TList; - head: TExpr; - tailNodes: TArray; - startLoc: ISourceLocation; + loc: ISourceLocation; begin - startLoc := FCurrentToken.GetLocation; - Consume(tkLeftParen); - if FCurrentToken.Kind = tkRightParen then - Error('Syntax Error: Empty list () is not a valid expression.'); + loc := FCurrentToken.GetLocation; - elements := TList.Create; + if Match(tkQuote) then + begin + // 'expr -> (quote expr) + Result := TAst.FunctionCall(TAst.Identifier('quote', loc), [ParseExpression], loc); + end + else if Match(tkBacktick) then + begin + // `expr -> Quasiquote + Result := TAst.Quasiquote(ParseExpression, loc); + end + else if Match(tkTilde) then + begin + if Match(tkAt) then + // ~@expr -> UnquoteSplicing + Result := TAst.UnquoteSplicing(ParseExpression.AsQuasiquote, loc) + else + // ~expr -> Unquote + Result := TAst.Unquote(ParseExpression, loc); + end + else + begin + Error('Unknown reader macro'); + Result := nil; + end; +end; + +// --- Special Forms Sub-Parsers --- + +function TParser.ParseIf: IAstNode; +var + cond, thenBr, elseBr: IAstNode; +begin + cond := ParseExpression; + thenBr := ParseExpression; + + if FCurrentToken.Kind <> tkRightParen then + elseBr := ParseExpression + else + elseBr := nil; + + Result := TAst.IfExpr(cond, thenBr, elseBr); +end; + +function TParser.ParseCond: IAstNode; +var + pairs: TList; + elseBr: IAstNode; + cond, br: IAstNode; +begin + pairs := TList.Create; try while FCurrentToken.Kind <> tkRightParen do begin - if FCurrentToken.Kind = tkEOF then - Error('Syntax Error: Unexpected end of file.'); - elements.Add(ParseExpression); + cond := ParseExpression; + + if FCurrentToken.Kind = tkRightParen then + begin + // Odd number of args -> Last one is Else + elseBr := cond; + Result := TAst.CondExpr(pairs.ToArray, elseBr); + Exit; + end; + + br := ParseExpression; + pairs.Add(TCondPair.Create(cond, br)); end; - head := elements[0]; - SetLength(tailNodes, elements.Count - 1); - for var i := 0 to High(tailNodes) do - tailNodes[i] := elements[i + 1].Node; - - if head.Token.Kind = tkIdentifier then - begin - if SameText(head.Token.Text, 'pipe') then - begin - // (pipe [[stream1 [:Key1 :Key2]] [stream2 [:Key3]]] (fn ...)) - if Length(tailNodes) <> 2 then - Error('Syntax Error: ''pipe'' requires [inputs] vector and (fn) transformation.'); - - if tailNodes[0].Kind <> akTuple then - Error('Syntax Error: ''pipe'' first argument must be a vector [...].'); - - // NOTE: We do NOT validate inner tuples or keywords here anymore. - // It is just a Tuple of Tuples structurally. - // The TypeChecker will ensure valid structure (Series + Keywords). - - if tailNodes[1].Kind <> akLambdaExpression then - Error('Syntax Error: Pipe transformation must be a lambda (fn).'); - - Result := TAst.Pipe(tailNodes[0].AsTuple, tailNodes[1].AsLambdaExpression, 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.'); - var params := ExtractIdentifiers(tailNodes[0], 'fn'); - Result := TAst.LambdaExpr(params, tailNodes[1], startLoc); - end - else if SameText(head.Token.Text, 'defmacro') then - begin - if (Length(tailNodes) <> 3) or (elements[1].Token.Kind <> tkIdentifier) then - Error('Syntax Error: ''defmacro'' requires name, params, body.'); - var params := ExtractIdentifiers(tailNodes[1], 'defmacro'); - Result := TAst.MacroDef(tailNodes[0].AsIdentifier, params, tailNodes[2], startLoc); - end - else if SameText(head.Token.Text, 'if') then - begin - var elseNode: IAstNode := nil; - if Length(tailNodes) = 3 then - elseNode := tailNodes[2]; - Result := TAst.IfExpr(tailNodes[0], tailNodes[1], elseNode, startLoc); - end - else if SameText(head.Token.Text, '?') then - begin - var count := Length(tailNodes); - if (count < 1) or ((count mod 2) = 0) then - Error('Syntax Error: ''?'' (cond) requires an odd number of arguments.'); - - var pairs: TArray; - SetLength(pairs, count div 2); - for var i := 0 to High(pairs) do - pairs[i] := TCondPair.Create(tailNodes[i * 2], tailNodes[i * 2 + 1]); - - var elseNode := tailNodes[High(tailNodes)]; - Result := TAst.CondExpr(pairs, elseNode, startLoc); - end - else if SameText(head.Token.Text, 'def') then - begin - var initializer: IAstNode := nil; - if Length(tailNodes) = 2 then - initializer := tailNodes[1]; - Result := TAst.VarDecl(tailNodes[0], initializer, startLoc); - end - else if SameText(head.Token.Text, 'assign') then - begin - Result := TAst.Assign(tailNodes[0], tailNodes[1], startLoc); - end - else if SameText(head.Token.Text, 'do') then - begin - // Factory takes Array and creates Tuple - Result := TAst.Block(tailNodes, startLoc) - end - else if SameText(head.Token.Text, 'recur') then - begin - // Factory takes Array and creates Tuple - Result := TAst.Recur(tailNodes, startLoc) - end - else if SameText(head.Token.Text, 'get') then - begin - Result := TAst.Indexer(tailNodes[0], tailNodes[1], startLoc) - end - else if SameText(head.Token.Text, 'new-series') then - begin - if Length(tailNodes) <> 1 then - Error('Syntax Error: ''new-series'' requires exactly one argument (the definition vector).'); - - // UPDATED: Accept any node (usually a vector) as definition - Result := TAst.CreateSeries(tailNodes[0], startLoc); - end - else if SameText(head.Token.Text, 'add-item') then - begin - var lookback: IAstNode := nil; - if Length(tailNodes) = 3 then - lookback := tailNodes[2]; - Result := TAst.AddSeriesItem(tailNodes[0].AsIdentifier, tailNodes[1], lookback, startLoc); - end - else if SameText(head.Token.Text, 'count') then - begin - Result := TAst.SeriesLength(tailNodes[0].AsIdentifier, startLoc); - end - else if (Length(head.Token.Text) > 1) and (head.Token.Text.StartsWith('.')) then - begin - Result := TAst.MemberAccess(tailNodes[0], TAst.Keyword(head.Token.Text.Substring(1), head.Token.GetLocation), startLoc); - end - else - Result := nil; - end; - - if Result = nil then - // Factory automatically creates Tuple from Array for Arguments - Result := TAst.FunctionCall(head.Node, tailNodes, startLoc); - + // Even args -> No explicit else + Result := TAst.CondExpr(pairs.ToArray, nil); finally - elements.Free; + pairs.Free; end; - Consume(tkRightParen); end; -function TParser.ParseExpression: TExpr; +function TParser.ParseFn: IAstNode; var - startLoc: ISourceLocation; - i64: Int64; - dbl: Double; + params, body: IAstNode; begin - Result.Token := FCurrentToken; - startLoc := FCurrentToken.GetLocation; + params := ParseVector; // Expects [ ... ] + body := ParseExpression; + Result := TAst.LambdaExpr(ExtractIdentifiers(params, 'fn'), body); +end; - case FCurrentToken.Kind of - tkLeftBracket: - begin - Result.Node := ParseVector; - exit; - end; - tkBacktick: - begin - NextToken; - Result.Node := TAst.Quasiquote(ParseExpression.Node, startLoc); - exit; - end; - tkTilde: - begin - NextToken; - if FCurrentToken.Kind = tkAt then - begin - NextToken; - Result.Node := TAst.UnquoteSplicing(ParseExpression.Node.AsQuasiquote, startLoc); - end - else - Result.Node := TAst.Unquote(ParseExpression.Node, startLoc); - exit; - end; - tkQuote: - begin - NextToken; - Result.Node := TAst.FunctionCall(TAst.Identifier('quote', startLoc), [ParseExpression.Node], startLoc); - exit; - end; - end; +function TParser.ParseDefMacro: IAstNode; +var + name, params, body: IAstNode; +begin + name := ParseExpression; + if name.Kind <> akIdentifier then + Error('defmacro name must be identifier'); - case FCurrentToken.Kind of - tkNumber: - begin - if TryStrToInt64(FCurrentToken.Text, i64) then - Result.Node := TAst.Constant(i64, startLoc) - else if TryStrToFloat(FCurrentToken.Text, dbl, TFormatSettings.Invariant) then - Result.Node := TAst.Constant(dbl, startLoc) - else - Error('Invalid number'); - NextToken; - end; - tkString: - begin - Result.Node := TAst.Constant(FCurrentToken.Text, startLoc); - NextToken; - end; - tkKeyword: - begin - Result.Node := TAst.Keyword(FCurrentToken.Text, startLoc); - NextToken; - end; - tkIdentifier: - begin - if FCurrentToken.Text = '...' then - Result.Node := TAst.Nop(startLoc) - else - Result.Node := TAst.Identifier(FCurrentToken.Text, startLoc); - NextToken; - end; - tkLeftParen: Result.Node := ParseList; - tkLeftBrace: Result.Node := ParseRecordLiteral; + params := ParseVector; + body := ParseExpression; + + Result := TAst.MacroDef(name.AsIdentifier, ExtractIdentifiers(params, 'defmacro'), body); +end; + +function TParser.ParseDef: IAstNode; +var + name, init: IAstNode; +begin + name := ParseExpression; + + if FCurrentToken.Kind <> tkRightParen then + init := ParseExpression else - Error('Unexpected token'); + init := nil; + + Result := TAst.VarDecl(name, init); +end; + +function TParser.ParseAssign: IAstNode; +var + target, val: IAstNode; +begin + target := ParseExpression; + val := ParseExpression; + Result := TAst.Assign(target, val); +end; + +function TParser.ParseDo: IAstNode; +var + list: TList; +begin + list := TList.Create; + try + while FCurrentToken.Kind <> tkRightParen do + list.Add(ParseExpression); + Result := TAst.Block(list.ToArray); + finally + list.Free; end; end; -function TParser.Parse: IAstNode; +function TParser.ParseRecur: IAstNode; +var + list: TList; begin - var expr := ParseExpression; - if FCurrentToken.Kind <> tkEOF then - Error('Unexpected chars after end.'); - Result := expr.Node; + list := TList.Create; + try + while FCurrentToken.Kind <> tkRightParen do + list.Add(ParseExpression); + Result := TAst.Recur(list.ToArray); + finally + list.Free; + end; +end; + +function TParser.ParseQuoteForm: IAstNode; +begin + Result := TAst.Quasiquote(ParseExpression); +end; + +function TParser.ParsePipe: IAstNode; +var + inputs, transform: IAstNode; +begin + inputs := ParseVector; + transform := ParseExpression; + + if inputs.Kind <> akTuple then + Error('Pipe inputs must be a vector'); + if transform.Kind <> akLambdaExpression then + Error('Pipe transform must be a fn'); + + Result := TAst.Pipe(inputs.AsTuple, transform.AsLambdaExpression); +end; + +function TParser.ParseNewSeries: IAstNode; +begin + Result := TAst.CreateSeries(ParseExpression); +end; + +function TParser.ParseAddItem: IAstNode; +var + s, v, lb: IAstNode; +begin + s := ParseExpression; + if s.Kind <> akIdentifier then + Error('Series argument must be an identifier'); + + v := ParseExpression; + + if FCurrentToken.Kind <> tkRightParen then + lb := ParseExpression + else + lb := nil; + + Result := TAst.AddSeriesItem(s.AsIdentifier, v, lb); +end; + +function TParser.ParseCount: IAstNode; +var + s: IAstNode; +begin + s := ParseExpression; + if s.Kind <> akIdentifier then + Error('Count argument must be an identifier'); + Result := TAst.SeriesLength(s.AsIdentifier); +end; + +function TParser.ParseGet: IAstNode; +var + base, idx: IAstNode; +begin + base := ParseExpression; + idx := ParseExpression; + Result := TAst.Indexer(base, idx); +end; + +// --- Helpers --- + +function TParser.ParseTupleBody(StopToken: TTokenKind): TArray; +var + list: TList; +begin + list := TList.Create; + try + while FCurrentToken.Kind <> StopToken do + begin + if FCurrentToken.Kind = tkEOF then + Error('Unexpected EOF inside tuple/vector'); + list.Add(ParseExpression); + end; + Result := list.ToArray; + finally + list.Free; + end; + Consume(StopToken); +end; + +function TParser.ExtractIdentifiers(const Node: IAstNode; const Context: string): TArray; +begin + if Node.Kind <> akTuple then + ErrorFmt('%s expects a vector of identifiers.', [Context]); + + var elements := Node.AsTuple.Elements; + SetLength(Result, Length(elements)); + for var i := 0 to High(elements) do + begin + if elements[i].Kind <> akIdentifier then + ErrorFmt('Element at index %d in %s is not an identifier.', [i, Context]); + Result[i] := elements[i].AsIdentifier; + end; end; { TAstScript } @@ -748,16 +1072,55 @@ end; class function TAstScript.Print(const ANode: IAstNode): string; var - visitor: TPrettyPrintVisitor; + v: TPrettyPrintVisitor; begin - if not Assigned(ANode) then - exit(''); - visitor := TPrettyPrintVisitor.Create; + v := TPrettyPrintVisitor.Create; try - visitor.Execute(ANode); - Result := visitor.GetResult; + v.Execute(ANode); + Result := v.GetResult; finally - visitor.Free; + v.Free; + end; +end; + +class function TAstScript.GetGrammar: string; +var + ctx: TRttiContext; + t: TRttiType; + m: TRttiMethod; + attr: TCustomAttribute; + sb: TStringBuilder; + rules: TList; +begin + ctx := TRttiContext.Create; + rules := TList.Create; + sb := TStringBuilder.Create; + try + t := ctx.GetType(TParser); + for m in t.GetMethods do + begin + for attr in m.GetAttributes do + begin + if attr is EbnfAttribute then + begin + rules.Add(EbnfAttribute(attr).Rule); + end; + end; + end; + + // Sort to ensure deterministic output (optional, but good for docs) + rules.Sort; + + sb.AppendLine('(* Myc Script Grammar (Auto-Generated) *)'); + sb.AppendLine; + for var rule in rules do + sb.AppendLine(rule); + + Result := sb.ToString; + finally + sb.Free; + rules.Free; + ctx.Free; end; end;