From 1d13d0cdaa29b37f91012bcc9d5c31882251b837 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Sun, 7 Dec 2025 12:06:29 +0100 Subject: [PATCH] Ast ternary expr replaced by cond expr --- ASTPlayground/ASTPlayground.delphilsp.json | 2 +- Src/AST/Myc.Ast.Analysis.Purity.pas | 15 ++- Src/AST/Myc.Ast.Compiler.TCO.pas | 41 +++++-- Src/AST/Myc.Ast.Compiler.TypeChecker.pas | 100 +++++++++++++----- Src/AST/Myc.Ast.Debugger.pas | 11 +- Src/AST/Myc.Ast.Dumper.pas | 22 ++-- Src/AST/Myc.Ast.Evaluator.pas | 20 ++-- Src/AST/Myc.Ast.JSON.pas | 76 +++++++++---- Src/AST/Myc.Ast.Nodes.pas | 80 ++++++++------ Src/AST/Myc.Ast.Refactoring.Remove.pas | 36 +++++-- Src/AST/Myc.Ast.Script.pas | 35 ++++-- Src/AST/Myc.Ast.Visitor.pas | 54 +++++++--- Src/AST/Myc.Ast.pas | 49 ++++++--- .../Myc.Fmx.AstEditor.Handlers.Control.pas | 82 +++++++++++--- Src/AST/Myc.Fmx.AstEditor.Visualizer.pas | 6 +- 15 files changed, 449 insertions(+), 180 deletions(-) diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json index 0fb8594..31c43e1 100644 --- a/ASTPlayground/ASTPlayground.delphilsp.json +++ b/ASTPlayground/ASTPlayground.delphilsp.json @@ -1 +1 @@ -{ "settings": { "project": "file:///T%3A/Myc/ASTPlayground/ASTPlayground.dpr", "dllname": "dcc64370.dll", "dccOptions": "-$O- -$W+ --inline:off -$R+ -$Q+ --no-config -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG;;FRAMEWORK_FMX -E.\\Win64\\Debug -I\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -LEC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Bpl\\Win64 -LNC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NU.\\Win64\\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -OT:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -R\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -U\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -V -VN -VR -NBC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NHC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\hpp\\Win64 -NO.\\Win64\\Debug -LU" , "projectFiles":[ { "name": "MainForm", "file": "file:///T%3A/Myc/ASTPlayground/MainForm.pas" }, { "name": "Myc.Ast.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Nodes.pas" }, { "name": "Myc.Ast.Scope", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Scope.pas" }, { "name": "Myc.Data.Value", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Data.Value.pas" }, { "name": "Myc.Ast.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Compiler.TCO", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TCO.pas" }, { "name": "Myc.Ast.Compiler.Binder", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Binder.pas" }, { "name": "Myc.Ast.Compiler.Lowering", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Lowering.pas" }, { "name": "Myc.Ast.Compiler.TypeChecker", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TypeChecker.pas" }, { "name": "Myc.Ast.Compiler.Macros", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Macros.pas" }, { "name": "Myc.Ast.Compiler.Specializer", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Specializer.pas" }, { "name": "Myc.Ast.Environment", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Environment.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Analysis.Purity", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Analysis.Purity.pas" }, { "name": "Myc.Ast.Identities", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Identities.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.pas" }, { "name": "Myc.Fmx.AstEditor.Visualizer", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Layout", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Layout.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Ast.Refactoring.Remove", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Refactoring.Remove.pas" }, { "name": "Myc.Fmx.AstEditor.Render", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Render.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Lists", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Lists.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Primitives", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Primitives.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Control", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Data", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Data.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": 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" } ] , "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.Analysis.Purity.pas b/Src/AST/Myc.Ast.Analysis.Purity.pas index ccfdaa6..99eb6b9 100644 --- a/Src/AST/Myc.Ast.Analysis.Purity.pas +++ b/Src/AST/Myc.Ast.Analysis.Purity.pas @@ -23,7 +23,7 @@ type function VisitConstant(const Node: IConstantNode): Boolean; override; function VisitKeyword(const Node: IKeywordNode): Boolean; override; function VisitIfExpression(const Node: IIfExpressionNode): Boolean; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): Boolean; override; + function VisitCondExpression(const Node: ICondExpressionNode): Boolean; override; // Replaces Ternary function VisitBlockExpression(const Node: IBlockExpressionNode): Boolean; override; function VisitRecordLiteral(const Node: IRecordLiteralNode): Boolean; override; function VisitVariableDeclaration(const Node: IVariableDeclarationNode): Boolean; override; @@ -184,9 +184,18 @@ begin Result := Accept(Node.Condition) and Accept(Node.ThenBranch) and Accept(Node.ElseBranch); end; -function TPurityAnalyzer.VisitTernaryExpression(const Node: ITernaryExpressionNode): Boolean; +function TPurityAnalyzer.VisitCondExpression(const Node: ICondExpressionNode): Boolean; +var + pair: TCondPair; begin - Result := Accept(Node.Condition) and Accept(Node.ThenBranch) and Accept(Node.ElseBranch); + // All conditions and all branches must be pure + for pair in Node.Pairs do + begin + if not (Accept(pair.Condition) and Accept(pair.Branch)) then + Exit(False); + end; + // And the Else branch + Result := Accept(Node.ElseBranch); end; function TPurityAnalyzer.VisitBlockExpression(const Node: IBlockExpressionNode): Boolean; diff --git a/Src/AST/Myc.Ast.Compiler.TCO.pas b/Src/AST/Myc.Ast.Compiler.TCO.pas index 34b5162..46e52e7 100644 --- a/Src/AST/Myc.Ast.Compiler.TCO.pas +++ b/Src/AST/Myc.Ast.Compiler.TCO.pas @@ -33,7 +33,7 @@ type // Overrides for TCO propagation function VisitBlockExpression(const Node: IBlockExpressionNode): IAstNode; override; function VisitIfExpression(const Node: IIfExpressionNode): IAstNode; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; override; + function VisitCondExpression(const Node: ICondExpressionNode): IAstNode; override; // Replaces Ternary function VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; override; function VisitRecurNode(const Node: IRecurNode): IAstNode; override; function VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode; override; @@ -160,27 +160,46 @@ begin Result := TAst.IfExpr(Node.Identity, newCond, newThen, newElse, Node.StaticType); end; -function TAstTCO.VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; +function TAstTCO.VisitCondExpression(const Node: ICondExpressionNode): IAstNode; var isContextTail: Boolean; - newCond, newThen, newElse: IAstNode; + hasChanged: Boolean; + i: Integer; + newPairs: TArray; + newElse: IAstNode; + newCond, newBranch: IAstNode; begin isContextTail := FIsTailStack.Peek; + hasChanged := False; + SetLength(newPairs, Length(Node.Pairs)); - // Condition is never in tail position - FNextIsTail := False; - newCond := Accept(Node.Condition); + for i := 0 to High(Node.Pairs) do + begin + // 1. Condition is never in tail position + FNextIsTail := False; + newCond := Accept(Node.Pairs[i].Condition); - // Then/Else branches ARE in tail position if the TernaryExpr is + // 2. Branch IS in tail position (if CondExpr is) + FNextIsTail := isContextTail; + newBranch := Accept(Node.Pairs[i].Branch); + + newPairs[i] := TCondPair.Create(newCond, newBranch); + + if (newCond <> Node.Pairs[i].Condition) or (newBranch <> Node.Pairs[i].Branch) then + hasChanged := True; + end; + + // 3. Else Branch IS in tail position FNextIsTail := isContextTail; - newThen := Accept(Node.ThenBranch); newElse := Accept(Node.ElseBranch); - if (newCond = Node.Condition) and (newThen = Node.ThenBranch) and (newElse = Node.ElseBranch) then + if newElse <> Node.ElseBranch then + hasChanged := True; + + if not hasChanged then Result := Node else - // CoW: Reuse Identity - Result := TAst.TernaryExpr(Node.Identity, newCond, newThen, newElse, Node.StaticType); + Result := TAst.CondExpr(Node.Identity, newPairs, newElse, Node.StaticType); end; function TAstTCO.VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; diff --git a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas index 0b9a54f..0a23f51 100644 --- a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas +++ b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas @@ -50,7 +50,7 @@ type function VisitFunctionCall(const Node: IFunctionCallNode): IAstNode; override; function VisitBlockExpression(const Node: IBlockExpressionNode): IAstNode; override; function VisitIfExpression(const Node: IIfExpressionNode): IAstNode; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; override; + function VisitCondExpression(const Node: ICondExpressionNode): IAstNode; override; // Replaced Ternary function VisitMemberAccess(const Node: IMemberAccessNode): IAstNode; override; function VisitIndexer(const Node: IIndexerNode): IAstNode; override; function VisitRecordLiteral(const Node: IRecordLiteralNode): IAstNode; override; @@ -221,7 +221,7 @@ begin for i := 0 to Node.Arguments.Count - 1 do newArgs[i] := Accept(Node.Arguments[i]); - // FIX: Wrap in List + // Wrap in List var argList := TArgumentList.Create(newArgs, Node.Arguments.Identity); Result := TAst.Recur(Node.Identity, argList, TTypes.Void); end; @@ -395,7 +395,7 @@ begin temp.Free; end; - // FIX: Wrap in List + // Wrap in List var paramList := TParameterList.Create(newParams, Node.Parameters.Identity); Result := @@ -493,7 +493,7 @@ begin retType := TTypes.Unknown; end; - // FIX: Wrap in List + // Wrap in List var argList := TArgumentList.Create(newArgs, Node.Arguments.Identity); Result := TAst.FunctionCall(Node.Identity, newCallee, argList, retType, Node.IsTailCall, nil, False); @@ -514,7 +514,7 @@ begin else blockType := TTypes.Void; - // FIX: Wrap in List + // Wrap in List var exprList := TExpressionList.Create(newExprs, Node.Expressions.Identity); Result := TAst.Block(Node.Identity, exprList, blockType); end; @@ -553,36 +553,80 @@ begin Result := TAst.IfExpr(Node.Identity, newCond, newThen, newElse, resultType); end; -function TTypeChecker.VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; +function TTypeChecker.VisitCondExpression(const Node: ICondExpressionNode): IAstNode; var - conditionType, thenType, elseType, resultType: IStaticType; - newCond, newThen, newElse: IAstNode; + i: Integer; + newPairs: TArray; + newElse: IAstNode; + condType, branchType, resultType: IStaticType; begin - newCond := Accept(Node.Condition); - newThen := Accept(Node.ThenBranch); + SetLength(newPairs, Length(Node.Pairs)); + resultType := nil; // Start with nothing + + for i := 0 to High(Node.Pairs) do + begin + // 1. Visit Condition + var newCond := Accept(Node.Pairs[i].Condition); + condType := newCond.AsTypedNode.StaticType; + + if (condType.Kind <> stUnknown) + and not TTypeRules.CanAssign(TTypes.Ordinal, condType) + and not TTypeRules.CanAssign(TTypes.Boolean, condType) then + begin + if Assigned(FLog) then + 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 + begin + var promoted := TTypeRules.Promote(resultType, branchType); + if promoted = nil then + begin + if Assigned(FLog) then + FLog.AddError( + Format('Incompatible types in Cond branches: %s and %s', [resultType.ToString, branchType.ToString]), + Node + ); + resultType := TTypes.Unknown; + end + else + resultType := promoted; + 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; - conditionType := newCond.AsTypedNode.StaticType; - if (conditionType.Kind <> stUnknown) - and not TTypeRules.CanAssign(TTypes.Ordinal, conditionType) - and not TTypeRules.CanAssign(TTypes.Boolean, conditionType) then - begin - if Assigned(FLog) then - FLog.AddError(Format('Ternary condition must be Boolean or Ordinal, but got %s', [conditionType.ToString]), Node); - end; - - thenType := newThen.AsTypedNode.StaticType; - elseType := newElse.AsTypedNode.StaticType; - - resultType := TTypeRules.Promote(thenType, elseType); if resultType = nil then + resultType := elseType + else begin - if Assigned(FLog) then - FLog.AddError(Format('Cannot promote types %s and %s in Ternary-Expression', [thenType.ToString, elseType.ToString]), Node); - resultType := TTypes.Unknown; + var promoted := TTypeRules.Promote(resultType, elseType); + if promoted = nil then + begin + if Assigned(FLog) then + FLog.AddError( + Format('Incompatible types in Cond branches (Else): %s and %s', [resultType.ToString, elseType.ToString]), + Node + ); + resultType := TTypes.Unknown; + end + else + resultType := promoted; end; - Result := TAst.TernaryExpr(Node.Identity, newCond, newThen, newElse, resultType); + Result := TAst.CondExpr(Node.Identity, newPairs, newElse, resultType); end; function TTypeChecker.VisitMemberAccess(const Node: IMemberAccessNode): IAstNode; @@ -726,7 +770,7 @@ begin scalarDefFields[i] := TScalarRecordField.Create(newFields[i].Key.Value, scalarKind); end; - // FIX: Wrap in List + // Wrap in List var fieldList := TRecordFieldList.Create(newFields, Node.Fields.Identity); if allScalar then diff --git a/Src/AST/Myc.Ast.Debugger.pas b/Src/AST/Myc.Ast.Debugger.pas index 4bbab0a..a5d7137 100644 --- a/Src/AST/Myc.Ast.Debugger.pas +++ b/Src/AST/Myc.Ast.Debugger.pas @@ -37,7 +37,7 @@ type function VisitIdentifier(const Node: IIdentifierNode): TDataValue; override; function VisitKeyword(const Node: IKeywordNode): TDataValue; override; function VisitIfExpression(const Node: IIfExpressionNode): TDataValue; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; override; + function VisitCondExpression(const Node: ICondExpressionNode): TDataValue; override; // Replaces Ternary function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; override; function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; override; function VisitAssignment(const Node: IAssignmentNode): TDataValue; override; @@ -250,12 +250,15 @@ begin AppendLine(Format('} -> %s', [Result.ToString])); end; -function TDebugEvaluatorVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; +function TDebugEvaluatorVisitor.VisitCondExpression(const Node: ICondExpressionNode): TDataValue; begin - AppendLine('TernaryExpr {'); + AppendLine(Format('CondExpr (%d pairs) {', [Length(Node.Pairs)])); Indent; try - Result := inherited VisitTernaryExpression(Node); + // We just call inherited, which does the logic. + // We don't log every branch check here to avoid spamming output, + // but the recursive evaluation of conditions will show up in the log naturally. + Result := inherited VisitCondExpression(Node); finally Unindent; end; diff --git a/Src/AST/Myc.Ast.Dumper.pas b/Src/AST/Myc.Ast.Dumper.pas index b3d6ef4..48041a5 100644 --- a/Src/AST/Myc.Ast.Dumper.pas +++ b/Src/AST/Myc.Ast.Dumper.pas @@ -34,7 +34,7 @@ type function VisitIdentifier(const Node: IIdentifierNode): TVoid; override; function VisitKeyword(const Node: IKeywordNode): TVoid; override; function VisitIfExpression(const Node: IIfExpressionNode): TVoid; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): TVoid; override; + function VisitCondExpression(const Node: ICondExpressionNode): TVoid; override; // Replaced Ternary function VisitLambdaExpression(const Node: ILambdaExpressionNode): TVoid; override; function VisitFunctionCall(const Node: IFunctionCallNode): TVoid; override; function VisitMacroExpansionNode(const Node: IMacroExpansionNode): TVoid; override; @@ -187,14 +187,22 @@ begin Unindent; end; -function TAstDumper.VisitTernaryExpression(const Node: ITernaryExpressionNode): TVoid; +function TAstDumper.VisitCondExpression(const Node: ICondExpressionNode): TVoid; +var + i: Integer; begin - Log('TernaryExpression', Node); + LogFmt('CondExpression (%d pairs)', [Length(Node.Pairs)], Node); Indent; - Log('Condition:'); - Node.Condition.Accept(Self); - Log('Then:'); - Node.ThenBranch.Accept(Self); + for i := 0 to High(Node.Pairs) do + begin + LogFmt('Pair %d:', [i]); + Indent; + Log('Condition:'); + Node.Pairs[i].Condition.Accept(Self); + Log('Branch:'); + Node.Pairs[i].Branch.Accept(Self); + Unindent; + end; Log('Else:'); Node.ElseBranch.Accept(Self); Unindent; diff --git a/Src/AST/Myc.Ast.Evaluator.pas b/Src/AST/Myc.Ast.Evaluator.pas index 2e10e4a..b82b494 100644 --- a/Src/AST/Myc.Ast.Evaluator.pas +++ b/Src/AST/Myc.Ast.Evaluator.pas @@ -34,7 +34,7 @@ type function VisitRecordField(const Node: IRecordFieldNode): TDataValue; virtual; function VisitIfExpression(const Node: IIfExpressionNode): TDataValue; virtual; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; virtual; + function VisitCondExpression(const Node: ICondExpressionNode): TDataValue; virtual; // Replaces Ternary function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; virtual; function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; virtual; function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; virtual; @@ -590,12 +590,20 @@ begin Result := TDataValue.Void; end; -function TEvaluatorVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; +function TEvaluatorVisitor.VisitCondExpression(const Node: ICondExpressionNode): TDataValue; +var + pair: TCondPair; begin - if IsTruthy(Node.Condition.Accept(Self)) then - Result := Node.ThenBranch.Accept(Self) - else - Result := Node.ElseBranch.Accept(Self); + for pair in Node.Pairs do + begin + if IsTruthy(pair.Condition.Accept(Self)) then + begin + Result := pair.Branch.Accept(Self); + Exit; + end; + end; + // Else branch is mandatory in AST (though can be Nop/Void in source if omitted and normalized) + Result := Node.ElseBranch.Accept(Self); end; function TEvaluatorVisitor.VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; diff --git a/Src/AST/Myc.Ast.JSON.pas b/Src/AST/Myc.Ast.JSON.pas index 8b5ea78..97cdf3a 100644 --- a/Src/AST/Myc.Ast.JSON.pas +++ b/Src/AST/Myc.Ast.JSON.pas @@ -31,7 +31,8 @@ type function JsonToIdentifierNode(const AObj: TJSONObject): IIdentifierNode; function JsonToKeywordNode(const AObj: TJSONObject): IKeywordNode; function JsonToIfExprNode(const AObj: TJSONObject): IIfExpressionNode; - function JsonToTernaryExprNode(const AObj: TJSONObject): ITernaryExpressionNode; + function JsonToCondExprNode(const AObj: TJSONObject): ICondExpressionNode; + function JsonToTernaryExprNode(const AObj: TJSONObject): IAstNode; // Backward Compatibility function JsonToLambdaExprNode(const AObj: TJSONObject): ILambdaExpressionNode; function JsonToMacroDefNode(const AObj: TJSONObject): IMacroDefinitionNode; function JsonToQuasiquoteNode(const AObj: TJSONObject): IQuasiquoteNode; @@ -44,7 +45,7 @@ type function JsonToVarDeclNode(const AObj: TJSONObject): IVariableDeclarationNode; function JsonToAssignmentNode(const AObj: TJSONObject): IAssignmentNode; function JsonToIndexerNode(const AObj: TJSONObject): IIndexerNode; - function JsonToMemberAccessNode(const AObj: TJSONObject): IMemberAccessNode; // <--- KORRIGIERT + function JsonToMemberAccessNode(const AObj: TJSONObject): IMemberAccessNode; function JsonToRecordLiteralNode(const AObj: TJSONObject): IRecordLiteralNode; function JsonToCreateSeriesNode(const AObj: TJSONObject): ICreateSeriesNode; function JsonToAddSeriesItemNode(const AObj: TJSONObject): IAddSeriesItemNode; @@ -57,7 +58,7 @@ type function VisitIdentifier(const Node: IIdentifierNode): TJSONObject; override; function VisitKeyword(const Node: IKeywordNode): TJSONObject; override; - // List Visitors (stubbed mostly, as parents handle array generation for JSON structure) + // List Visitors function VisitParameterList(const Node: IParameterList): TJSONObject; override; function VisitArgumentList(const Node: IArgumentList): TJSONObject; override; function VisitExpressionList(const Node: IExpressionList): TJSONObject; override; @@ -65,7 +66,7 @@ type function VisitRecordField(const Node: IRecordFieldNode): TJSONObject; override; function VisitIfExpression(const Node: IIfExpressionNode): TJSONObject; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): TJSONObject; override; + function VisitCondExpression(const Node: ICondExpressionNode): TJSONObject; override; function VisitLambdaExpression(const Node: ILambdaExpressionNode): TJSONObject; override; function VisitMacroDefinition(const Node: IMacroDefinitionNode): TJSONObject; override; function VisitQuasiquote(const Node: IQuasiquoteNode): TJSONObject; override; @@ -186,19 +187,32 @@ begin Result.AddPair('ElseBranch', TJSONNull.Create); end; -function TJsonAstConverter.VisitTernaryExpression(const Node: ITernaryExpressionNode): TJSONObject; +function TJsonAstConverter.VisitCondExpression(const Node: ICondExpressionNode): TJSONObject; var - condObj, thenObj, elseObj: TJSONObject; + pairsArray: TJSONArray; + pairObj: TJSONObject; + elseObj: TJSONObject; + i: Integer; begin - condObj := Accept(Node.Condition); - thenObj := Accept(Node.ThenBranch); - elseObj := Accept(Node.ElseBranch); + pairsArray := TJSONArray.Create; + for i := 0 to High(Node.Pairs) do + begin + pairObj := TJSONObject.Create; + pairObj.AddPair('Condition', Accept(Node.Pairs[i].Condition)); + pairObj.AddPair('Branch', Accept(Node.Pairs[i].Branch)); + pairsArray.Add(pairObj); + end; + + elseObj := Accept(Node.ElseBranch); // Accept handles nil Result := TJSONObject.Create; - Result.AddPair('NodeType', TJSONString.Create('TernaryExpr')); - Result.AddPair('Condition', condObj); - Result.AddPair('ThenBranch', thenObj); - Result.AddPair('ElseBranch', elseObj); + Result.AddPair('NodeType', TJSONString.Create('CondExpr')); + Result.AddPair('Pairs', pairsArray); + + if Assigned(elseObj) then + Result.AddPair('ElseBranch', elseObj) + else + Result.AddPair('ElseBranch', TJSONNull.Create); end; function TJsonAstConverter.VisitLambdaExpression(const Node: ILambdaExpressionNode): TJSONObject; @@ -451,10 +465,6 @@ begin end; // --- List Visitors (Placeholder return) --- -// Since we iterate manually in parent nodes to form JSON Arrays, these are technically not used -// by the current logic, but required by the interface. -// Note: If we wanted strict visitor compliance, VisitFunctionCall would call Accept(List), -// which would return TJSONObject wrapping the array. We skip that level of nesting here. function TJsonAstConverter.VisitParameterList(const Node: IParameterList): TJSONObject; begin @@ -544,13 +554,39 @@ begin Result := TAst.IfExpr(condNode, thenNode, elseNode); end; -function TJsonAstConverter.JsonToTernaryExprNode(const AObj: TJSONObject): ITernaryExpressionNode; +function TJsonAstConverter.JsonToCondExprNode(const AObj: TJSONObject): ICondExpressionNode; +var + pairsArray: TJSONArray; + pairs: TArray; + elseNode: IAstNode; + i: Integer; + pairObj: TJSONObject; +begin + pairsArray := AObj.GetValue('Pairs'); + SetLength(pairs, pairsArray.Count); + for i := 0 to pairsArray.Count - 1 do + begin + pairObj := pairsArray.Items[i] as TJSONObject; + pairs[i] := TCondPair.Create(JsonToNode(pairObj.GetValue('Condition')), JsonToNode(pairObj.GetValue('Branch'))); + end; + + if not (AObj.GetValue('ElseBranch') is TJSONNull) then + elseNode := JsonToNode(AObj.GetValue('ElseBranch')) + else + elseNode := nil; + + Result := TAst.CondExpr(pairs, elseNode); +end; + +function TJsonAstConverter.JsonToTernaryExprNode(const AObj: TJSONObject): IAstNode; var condNode, thenNode, elseNode: IAstNode; begin condNode := JsonToNode(AObj.GetValue('Condition')); thenNode := JsonToNode(AObj.GetValue('ThenBranch')); elseNode := JsonToNode(AObj.GetValue('ElseBranch')); + + // Map to CondExpr using the helper in TAst Result := TAst.TernaryExpr(condNode, thenNode, elseNode); end; @@ -775,8 +811,10 @@ begin Result := JsonToKeywordNode(obj) else if nodeType = 'IfExpr' then Result := JsonToIfExprNode(obj) + else if nodeType = 'CondExpr' then + Result := JsonToCondExprNode(obj) else if nodeType = 'TernaryExpr' then - Result := JsonToTernaryExprNode(obj) + Result := JsonToTernaryExprNode(obj) // Backward Compatibility else if nodeType = 'LambdaExpr' then Result := JsonToLambdaExprNode(obj) else if nodeType = 'MacroDef' then diff --git a/Src/AST/Myc.Ast.Nodes.pas b/Src/AST/Myc.Ast.Nodes.pas index 91040f0..2e294ba 100644 --- a/Src/AST/Myc.Ast.Nodes.pas +++ b/Src/AST/Myc.Ast.Nodes.pas @@ -91,7 +91,7 @@ type // Control Flow & Structure IIfExpressionNode = interface; - ITernaryExpressionNode = interface; + ICondExpressionNode = interface; ILambdaExpressionNode = interface; IFunctionCallNode = interface; IMacroExpansionNode = interface; @@ -123,7 +123,7 @@ type akRecordFieldList, akRecordField, akIfExpression, - akTernaryExpression, + akCondExpression, akLambdaExpression, akFunctionCall, akMacroExpansion, @@ -149,6 +149,13 @@ type function ToString: string; end; + // Represents a single branch in a Cond expression (Condition -> Branch) + TCondPair = record + Condition: IAstNode; + Branch: IAstNode; + constructor Create(const ACondition, ABranch: IAstNode); + end; + // --- Base Interfaces --- IAstNode = interface @@ -173,7 +180,7 @@ type function AsRecordField: IRecordFieldNode; function AsIfExpression: IIfExpressionNode; - function AsTernaryExpression: ITernaryExpressionNode; + function AsCondExpression: ICondExpressionNode; function AsLambdaExpression: ILambdaExpressionNode; function AsFunctionCall: IFunctionCallNode; function AsMacroExpansion: IMacroExpansionNode; @@ -279,14 +286,12 @@ type property ElseBranch: IAstNode read GetElseBranch; end; - ITernaryExpressionNode = interface(IAstTypedNode) + ICondExpressionNode = interface(IAstTypedNode) {$region 'private'} - function GetCondition: IAstNode; - function GetThenBranch: IAstNode; + function GetPairs: TArray; function GetElseBranch: IAstNode; {$endregion} - property Condition: IAstNode read GetCondition; - property ThenBranch: IAstNode read GetThenBranch; + property Pairs: TArray read GetPairs; property ElseBranch: IAstNode read GetElseBranch; end; @@ -467,7 +472,7 @@ type function VisitRecordField(const Node: IRecordFieldNode): TDataValue; function VisitIfExpression(const Node: IIfExpressionNode): TDataValue; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; + function VisitCondExpression(const Node: ICondExpressionNode): TDataValue; function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; function VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; @@ -515,7 +520,7 @@ type function AsRecordField: IRecordFieldNode; virtual; function AsIfExpression: IIfExpressionNode; virtual; - function AsTernaryExpression: ITernaryExpressionNode; virtual; + function AsCondExpression: ICondExpressionNode; virtual; function AsLambdaExpression: ILambdaExpressionNode; virtual; function AsFunctionCall: IFunctionCallNode; virtual; function AsMacroExpansion: IMacroExpansionNode; virtual; @@ -694,21 +699,22 @@ type function AsIfExpression: IIfExpressionNode; override; end; - TTernaryExpressionNode = class(TAstTypedNode, ITernaryExpressionNode) + TCondExpressionNode = class(TAstTypedNode, ICondExpressionNode) private - FCondition, FThenBranch, FElseBranch: IAstNode; - function GetCondition: IAstNode; - function GetThenBranch: IAstNode; + FPairs: TArray; + FElseBranch: IAstNode; + function GetPairs: TArray; function GetElseBranch: IAstNode; function GetKind: TAstNodeKind; override; public constructor Create( - const ACondition, AThenBranch, AElseBranch: IAstNode; + const APairs: TArray; + const AElseBranch: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; - function AsTernaryExpression: ITernaryExpressionNode; override; + function AsCondExpression: ICondExpressionNode; override; end; TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition) @@ -1004,6 +1010,14 @@ begin Result := Result.Substring(2); end; +{ TCondPair } + +constructor TCondPair.Create(const ACondition, ABranch: IAstNode); +begin + Condition := ACondition; + Branch := ABranch; +end; + { TCompilerError } constructor TCompilerError.Create(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode); @@ -1174,7 +1188,7 @@ function TAstNode.AsIfExpression: IIfExpressionNode; begin Result := nil; end; -function TAstNode.AsTernaryExpression: ITernaryExpressionNode; +function TAstNode.AsCondExpression: ICondExpressionNode; begin Result := nil; end; @@ -1567,45 +1581,43 @@ begin Result := akIfExpression; end; -{ TTernaryExpressionNode } +{ TCondExpressionNode } -constructor TTernaryExpressionNode.Create( - const ACondition, AThenBranch, AElseBranch: IAstNode; +constructor TCondExpressionNode.Create( + const APairs: TArray; + const AElseBranch: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); - FCondition := ACondition; - FThenBranch := AThenBranch; + FPairs := APairs; FElseBranch := AElseBranch; end; -function TTernaryExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue; +function TCondExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue; begin - Result := Visitor.VisitTernaryExpression(Self); + Result := Visitor.VisitCondExpression(Self); end; -function TTernaryExpressionNode.AsTernaryExpression: ITernaryExpressionNode; +function TCondExpressionNode.AsCondExpression: ICondExpressionNode; begin Result := Self; end; -function TTernaryExpressionNode.GetCondition: IAstNode; +function TCondExpressionNode.GetPairs: TArray; begin - Result := FCondition; + Result := FPairs; end; -function TTernaryExpressionNode.GetThenBranch: IAstNode; -begin - Result := FThenBranch; -end; -function TTernaryExpressionNode.GetElseBranch: IAstNode; + +function TCondExpressionNode.GetElseBranch: IAstNode; begin Result := FElseBranch; end; -function TTernaryExpressionNode.GetKind: TAstNodeKind; + +function TCondExpressionNode.GetKind: TAstNodeKind; begin - Result := akTernaryExpression; + Result := akCondExpression; end; { TLambdaExpressionNode } diff --git a/Src/AST/Myc.Ast.Refactoring.Remove.pas b/Src/AST/Myc.Ast.Refactoring.Remove.pas index 2d73db6..daa6b85 100644 --- a/Src/AST/Myc.Ast.Refactoring.Remove.pas +++ b/Src/AST/Myc.Ast.Refactoring.Remove.pas @@ -38,7 +38,7 @@ type // --- Structural Nodes (Replace Logic) --- function VisitIfExpression(const Node: IIfExpressionNode): IAstNode; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; override; + function VisitCondExpression(const Node: ICondExpressionNode): IAstNode; override; // Replaces Ternary function VisitAssignment(const Node: IAssignmentNode): IAstNode; override; function VisitVariableDeclaration(const Node: IVariableDeclarationNode): IAstNode; override; function VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; override; @@ -279,18 +279,38 @@ begin Result := TAst.IfExpr(Node.Identity, newCond, newThen, newElse, Node.StaticType); end; -function TAstNodeRemover.VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; +function TAstNodeRemover.VisitCondExpression(const Node: ICondExpressionNode): IAstNode; var - newCond, newThen, newElse: IAstNode; + i: Integer; + newPairs: TArray; + newElse: IAstNode; + newCond, newBranch: IAstNode; + hasChanged: Boolean; begin - newCond := EnsureNode(Accept(Node.Condition), Node); - newThen := EnsureNode(Accept(Node.ThenBranch), Node); - newElse := EnsureNode(Accept(Node.ElseBranch), Node); + SetLength(newPairs, Length(Node.Pairs)); + hasChanged := False; - if (newCond = Node.Condition) and (newThen = Node.ThenBranch) and (newElse = Node.ElseBranch) then + for i := 0 to High(Node.Pairs) do + begin + // Ensure mandatory children exist (replace with Nop if removed) + newCond := EnsureNode(Accept(Node.Pairs[i].Condition), Node); + newBranch := EnsureNode(Accept(Node.Pairs[i].Branch), Node); + + newPairs[i] := TCondPair.Create(newCond, newBranch); + + if (newCond <> Node.Pairs[i].Condition) or (newBranch <> Node.Pairs[i].Branch) then + hasChanged := True; + end; + + // Else branch is effectively mandatory in the structure, even if it's Nop/Void + newElse := EnsureNode(Accept(Node.ElseBranch), Node); + if newElse <> Node.ElseBranch then + hasChanged := True; + + if not hasChanged then Exit(Node); - Result := TAst.TernaryExpr(Node.Identity, newCond, newThen, newElse, Node.StaticType); + Result := TAst.CondExpr(Node.Identity, newPairs, newElse, Node.StaticType); end; function TAstNodeRemover.VisitAssignment(const Node: IAssignmentNode): IAstNode; diff --git a/Src/AST/Myc.Ast.Script.pas b/Src/AST/Myc.Ast.Script.pas index b32d264..38e3152 100644 --- a/Src/AST/Myc.Ast.Script.pas +++ b/Src/AST/Myc.Ast.Script.pas @@ -50,7 +50,7 @@ var list_content ::= special_form | function_call special_form ::= "if" expression expression expression? - | "?" expression expression expression + | "?" (expression expression)* expression (* cond1 branch1 ... else *) | "def" identifier expression? | "defmacro" identifier parameter_list expression | "assign" identifier expression @@ -206,7 +206,7 @@ type function VisitRecordField(const Node: IRecordFieldNode): TVoid; override; function VisitIfExpression(const Node: IIfExpressionNode): TVoid; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): TVoid; override; + function VisitCondExpression(const Node: ICondExpressionNode): TVoid; override; function VisitLambdaExpression(const Node: ILambdaExpressionNode): TVoid; override; function VisitMacroDefinition(const Node: IMacroDefinitionNode): TVoid; override; function VisitQuasiquote(const Node: IQuasiquoteNode): TVoid; override; @@ -642,9 +642,19 @@ begin end else if SameText(head.Token.Text, '?') then begin - if Length(tailNodes) <> 3 then - Error('Syntax Error in ternary statement.'); - Result := TAst.TernaryExpr(tailNodes[0], tailNodes[1], tailNodes[2], startLoc); + // (? 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).'); + + 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 @@ -946,13 +956,18 @@ begin Append(')'); end; -function TPrettyPrintVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): TVoid; +function TPrettyPrintVisitor.VisitCondExpression(const Node: ICondExpressionNode): TVoid; begin - Append('(? '); - Node.Condition.Accept(Self); + Append('(?'); Indent; - NewLine; - Node.ThenBranch.Accept(Self); + for var pair in Node.Pairs do + begin + NewLine; + pair.Condition.Accept(Self); + Append(' '); + pair.Branch.Accept(Self); + end; + // Else NewLine; Node.ElseBranch.Accept(Self); Unindent; diff --git a/Src/AST/Myc.Ast.Visitor.pas b/Src/AST/Myc.Ast.Visitor.pas index f61548d..eca479b 100644 --- a/Src/AST/Myc.Ast.Visitor.pas +++ b/Src/AST/Myc.Ast.Visitor.pas @@ -26,7 +26,7 @@ type function IAstVisitor.VisitRecordField = DoVisitRecordField; function IAstVisitor.VisitIfExpression = DoVisitIfExpression; - function IAstVisitor.VisitTernaryExpression = DoVisitTernaryExpression; + function IAstVisitor.VisitCondExpression = DoVisitCondExpression; // Updated function IAstVisitor.VisitLambdaExpression = DoVisitLambdaExpression; function IAstVisitor.VisitFunctionCall = DoVisitFunctionCall; function IAstVisitor.VisitMacroExpansionNode = DoVisitMacroExpansionNode; @@ -58,7 +58,7 @@ type function DoVisitRecordField(const Node: IRecordFieldNode): TDataValue; function DoVisitIfExpression(const Node: IIfExpressionNode): TDataValue; - function DoVisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; + function DoVisitCondExpression(const Node: ICondExpressionNode): TDataValue; // Updated function DoVisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; function DoVisitFunctionCall(const Node: IFunctionCallNode): TDataValue; function DoVisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; @@ -94,7 +94,7 @@ type function VisitRecordField(const Node: IRecordFieldNode): T; virtual; function VisitIfExpression(const Node: IIfExpressionNode): T; virtual; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): T; virtual; + function VisitCondExpression(const Node: ICondExpressionNode): T; virtual; // Updated function VisitLambdaExpression(const Node: ILambdaExpressionNode): T; virtual; function VisitFunctionCall(const Node: IFunctionCallNode): T; virtual; function VisitMacroExpansionNode(const Node: IMacroExpansionNode): T; virtual; @@ -128,7 +128,7 @@ type function VisitRecordField(const Node: IRecordFieldNode): IAstNode; override; function VisitIfExpression(const Node: IIfExpressionNode): IAstNode; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; override; + function VisitCondExpression(const Node: ICondExpressionNode): IAstNode; override; // Updated function VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; override; function VisitFunctionCall(const Node: IFunctionCallNode): IAstNode; override; function VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode; override; @@ -204,9 +204,9 @@ function TAstVisitor.DoVisitIfExpression(const Node: IIfExpressionNode): TDat begin Result := TDataValue.FromGeneric(VisitIfExpression(Node)); end; -function TAstVisitor.DoVisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; +function TAstVisitor.DoVisitCondExpression(const Node: ICondExpressionNode): TDataValue; begin - Result := TDataValue.FromGeneric(VisitTernaryExpression(Node)); + Result := TDataValue.FromGeneric(VisitCondExpression(Node)); end; function TAstVisitor.DoVisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; begin @@ -341,11 +341,16 @@ begin Accept(Node.ElseBranch); end; -function TAstVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): T; +function TAstVisitor.VisitCondExpression(const Node: ICondExpressionNode): T; +var + pair: TCondPair; begin Result := Default(T); - Accept(Node.Condition); - Accept(Node.ThenBranch); + for pair in Node.Pairs do + begin + Accept(pair.Condition); + Accept(pair.Branch); + end; Accept(Node.ElseBranch); end; @@ -621,18 +626,35 @@ begin Result := TAst.IfExpr(Node.Identity, newCond, newThen, newElse, Node.StaticType); end; -function TAstTransformer.VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; +function TAstTransformer.VisitCondExpression(const Node: ICondExpressionNode): IAstNode; var - newCond, newThen, newElse: IAstNode; + newPairs: TArray; + newElse: IAstNode; + hasChanged: Boolean; + i: Integer; + newCond, newBranch: IAstNode; begin - newCond := Accept(Node.Condition); - newThen := Accept(Node.ThenBranch); - newElse := Accept(Node.ElseBranch); + hasChanged := False; + SetLength(newPairs, Length(Node.Pairs)); - if (newCond = Node.Condition) and (newThen = Node.ThenBranch) and (newElse = Node.ElseBranch) then + for i := 0 to High(Node.Pairs) do + begin + newCond := Accept(Node.Pairs[i].Condition); + newBranch := Accept(Node.Pairs[i].Branch); + newPairs[i] := TCondPair.Create(newCond, newBranch); + + if (newCond <> Node.Pairs[i].Condition) or (newBranch <> Node.Pairs[i].Branch) then + hasChanged := True; + end; + + newElse := Accept(Node.ElseBranch); // Accept handles nil + if newElse <> Node.ElseBranch then + hasChanged := True; + + if not hasChanged then Result := Node else - Result := TAst.TernaryExpr(Node.Identity, newCond, newThen, newElse, Node.StaticType); + Result := TAst.CondExpr(Node.Identity, newPairs, newElse, Node.StaticType); end; function TAstTransformer.VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; diff --git a/Src/AST/Myc.Ast.pas b/Src/AST/Myc.Ast.pas index 8be07db..445d928 100644 --- a/Src/AST/Myc.Ast.pas +++ b/Src/AST/Myc.Ast.pas @@ -101,19 +101,26 @@ type const AStaticType: IStaticType = nil ): IIfExpressionNode; overload; static; - // --- TERNARY --- + // --- COND (Previously Ternary) --- + class function CondExpr( + const APairs: TArray; + const AElseBranch: IAstNode; + const Loc: ISourceLocation = nil + ): ICondExpressionNode; overload; static; + + class function CondExpr( + const Identity: IAstIdentity; + const APairs: TArray; + const AElseBranch: IAstNode; + const AStaticType: IStaticType = nil + ): ICondExpressionNode; overload; static; + + // Convenience wrapper for Ternary operator behavior using CondExpr class function TernaryExpr( const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode; const Loc: ISourceLocation = nil - ): ITernaryExpressionNode; overload; static; - - class function TernaryExpr( - const Identity: IAstIdentity; - const ACondition: IAstNode; - const AThenBranch, AElseBranch: IAstNode; - const AStaticType: IStaticType = nil - ): ITernaryExpressionNode; overload; static; + ): ICondExpressionNode; overload; static; // --- LAMBDA --- class function LambdaExpr( @@ -488,22 +495,22 @@ begin ); end; -class function TAst.TernaryExpr(const ACondition, AThenBranch, AElseBranch: IAstNode; const Loc: ISourceLocation): ITernaryExpressionNode; +class function TAst.CondExpr(const APairs: TArray; const AElseBranch: IAstNode; const Loc: ISourceLocation): ICondExpressionNode; begin var id := TIdentities.Structural(Loc); - Result := TTernaryExpressionNode.Create(ACondition, AThenBranch, AElseBranch, TTypes.Unknown, id); + Result := TCondExpressionNode.Create(APairs, AElseBranch, TTypes.Unknown, id); end; -class function TAst.TernaryExpr( +class function TAst.CondExpr( const Identity: IAstIdentity; - const ACondition, AThenBranch, AElseBranch: IAstNode; + const APairs: TArray; + const AElseBranch: IAstNode; const AStaticType: IStaticType -): ITernaryExpressionNode; +): ICondExpressionNode; begin Result := - TTernaryExpressionNode.Create( - ACondition, - AThenBranch, + TCondExpressionNode.Create( + APairs, AElseBranch, if AStaticType <> nil then AStaticType else TTypes.Unknown, @@ -511,6 +518,14 @@ begin ); end; +class function TAst.TernaryExpr(const ACondition, AThenBranch, AElseBranch: IAstNode; const Loc: ISourceLocation): ICondExpressionNode; +var + pair: TCondPair; +begin + pair := TCondPair.Create(ACondition, AThenBranch); + Result := TAst.CondExpr([pair], AElseBranch, Loc); +end; + class function TAst.LambdaExpr( const AParameters: TArray; const ABody: IAstNode; diff --git a/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas b/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas index 79cc50f..4d231da 100644 --- a/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas +++ b/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas @@ -32,12 +32,20 @@ type function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override; end; - TTernaryExpressionNodeHandler = class(TBaseNodeHandler) + // Handles the 'cond' expression (multi-branch if/else) + TCondExpressionNodeHandler = class(TBaseNodeHandler) private - FConditionNode: TAstViewNode; - FThenNode: TAstViewNode; + type + TBranchView = record + Condition: TAstViewNode; + Branch: TAstViewNode; + end; + private + FBranchNodes: TList; FElseNode: TAstViewNode; public + constructor Create(const ANode: ICondExpressionNode); + destructor Destroy; override; procedure BuildUI(OwnerNode: TAstViewNode); override; function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override; end; @@ -152,26 +160,74 @@ begin Result := TAst.IfExpr(FNode.Identity, FConditionNode.CreateAst, FThenNode.CreateAst, elseAst, FNode.StaticType); end; -{ TTernaryExpressionNodeHandler } +{ TCondExpressionNodeHandler } -procedure TTernaryExpressionNodeHandler.BuildUI(OwnerNode: TAstViewNode); +constructor TCondExpressionNodeHandler.Create(const ANode: ICondExpressionNode); +begin + inherited Create(ANode); + FBranchNodes := TList.Create; +end; + +destructor TCondExpressionNodeHandler.Destroy; +begin + FBranchNodes.Free; + inherited; +end; + +procedure TCondExpressionNodeHandler.BuildUI(OwnerNode: TAstViewNode); var visu: IAstVisualizer; + pair: TCondPair; + i: Integer; + row: TAutoFitLayout; + bv: TBranchView; begin visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1); - OwnerNode.Frameless := True; - OwnerNode.Orientation := loHorizontal; - FConditionNode := visu.CallAccept(FNode.Condition); - OwnerNode.AddLabel(OwnerNode, '?'); - FThenNode := visu.CallAccept(FNode.ThenBranch); - OwnerNode.AddLabel(OwnerNode, ':'); + OwnerNode.Frameless := False; + OwnerNode.Orientation := loVertical; + OwnerNode.Alignment := laFlush; + + var title := OwnerNode.AddLabel(OwnerNode, '?'); + title.FontSettings.Font.Style := [TFontStyle.fsBold]; + + for i := 0 to High(FNode.Pairs) do + begin + pair := FNode.Pairs[i]; + row := OwnerNode.AddContainer(OwnerNode, loHorizontal, laCenter); + row.Margins := TMarginRect.Create(0, 2, 0, 2); + + bv.Condition := visu.CallAccept(pair.Condition); + row.AddChild(bv.Condition); + + OwnerNode.AddLabel(row, '->'); + bv.Branch := visu.CallAccept(pair.Branch); + row.AddChild(bv.Branch); + + FBranchNodes.Add(bv); + end; + + // Else Branch + var elseRow := OwnerNode.AddContainer(OwnerNode, loHorizontal, laCenter); + elseRow.Margins := TMarginRect.Create(0, 4, 0, 0); // Extra spacing + OwnerNode.AddLabel(elseRow, 'else ->'); FElseNode := visu.CallAccept(FNode.ElseBranch); + // FIX: Use AddChild instead of assigning Parent directly + elseRow.AddChild(FElseNode); end; -function TTernaryExpressionNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode; +function TCondExpressionNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode; +var + newPairs: TArray; + i: Integer; begin - Result := TAst.TernaryExpr(FNode.Identity, FConditionNode.CreateAst, FThenNode.CreateAst, FElseNode.CreateAst, FNode.StaticType); + SetLength(newPairs, FBranchNodes.Count); + for i := 0 to FBranchNodes.Count - 1 do + begin + newPairs[i] := TCondPair.Create(FBranchNodes[i].Condition.CreateAst, FBranchNodes[i].Branch.CreateAst); + end; + + Result := TAst.CondExpr(FNode.Identity, newPairs, FElseNode.CreateAst, FNode.StaticType); end; { TLambdaExpressionNodeHandler } diff --git a/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas b/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas index cdb48f8..14893c4 100644 --- a/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas +++ b/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas @@ -43,7 +43,7 @@ type // Control Flow function VisitIfExpression(const Node: IIfExpressionNode): TAstViewNode; override; - function VisitTernaryExpression(const Node: ITernaryExpressionNode): TAstViewNode; override; + function VisitCondExpression(const Node: ICondExpressionNode): TAstViewNode; override; // Replaces Ternary function VisitBlockExpression(const Node: IBlockExpressionNode): TAstViewNode; override; function VisitRecurNode(const Node: IRecurNode): TAstViewNode; override; function VisitNop(const Node: INopNode): TAstViewNode; override; @@ -225,9 +225,9 @@ begin Result := TAstViewNode.Create(Self, TIfExpressionNodeHandler.Create(Node)); end; -function TAstVisualizer.VisitTernaryExpression(const Node: ITernaryExpressionNode): TAstViewNode; +function TAstVisualizer.VisitCondExpression(const Node: ICondExpressionNode): TAstViewNode; begin - Result := TAstViewNode.Create(Self, TTernaryExpressionNodeHandler.Create(Node)); + Result := TAstViewNode.Create(Self, TCondExpressionNodeHandler.Create(Node)); end; function TAstVisualizer.VisitRecurNode(const Node: IRecurNode): TAstViewNode;