From 0d5f018d45b08125f8f440b5509c9ee98aeb37ed Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Tue, 25 Feb 2025 09:53:13 +0100 Subject: [PATCH 01/53] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7e6aa69f2a..36f2d1d47c 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ [![MSBuild](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml/badge.svg?branch=master)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml) [![Sponsor](https://img.shields.io/badge/patreon-donate-green.svg)](https://www.patreon.com/elena_lang) [![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&link=https://github.com/sponsors/arakov)](https://github.com/sponsors/arakov) +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W01B4CV8) From 796ad4baadeb891ea10fe041b55a5d839e938613 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Tue, 25 Feb 2025 09:53:53 +0100 Subject: [PATCH 02/53] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 36f2d1d47c..cbd98a21c3 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,13 @@ [![MSBuild](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml/badge.svg?branch=master)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml) [![Sponsor](https://img.shields.io/badge/patreon-donate-green.svg)](https://www.patreon.com/elena_lang) [![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&link=https://github.com/sponsors/arakov)](https://github.com/sponsors/arakov) -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W01B4CV8) +
+ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W01B4CV8) +
+ ELENA is a general-purpose language with late binding. It is multi-paradigm, combining features of functional and object-oriented programming. It supports both strong and weak types, run-time conversions, boxing and unboxing primitive types, direct usage of external libraries. A rich set of tools is provided to deal with message dispatching : multi-methods, message qualifying, generic message handlers. Multiple-inheritance can be simulated using mixins and type interfaces. The built-in script engine allows incorporating custom-defined scripts into your applications. Both stand-alone applications and Virtual machine clients are supported. ### Features From 8bf52f9f1004186f5fe008ff048188cd40fa9e61 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Tue, 25 Feb 2025 09:54:22 +0100 Subject: [PATCH 03/53] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cbd98a21c3..70a4dcb64d 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,9 @@
- [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W01B4CV8) + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W01B4CV8) +
ELENA is a general-purpose language with late binding. It is multi-paradigm, combining features of functional and object-oriented programming. It supports both strong and weak types, run-time conversions, boxing and unboxing primitive types, direct usage of external libraries. A rich set of tools is provided to deal with message dispatching : multi-methods, message qualifying, generic message handlers. Multiple-inheritance can be simulated using mixins and type interfaces. The built-in script engine allows incorporating custom-defined scripts into your applications. Both stand-alone applications and Virtual machine clients are supported. From 936c16f68402191ef2f19f9a8cb3abd78f11968f Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Tue, 25 Feb 2025 09:55:00 +0100 Subject: [PATCH 04/53] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index af19cc93dc..80de143b87 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -3,7 +3,7 @@ github: [arakov] patreon: elena_lang open_collective: # Replace with a single Open Collective username -ko_fi: https://buymeacoffee.com/elenaproglang +ko_fi: https://ko-fi.com/elenaprolang tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # elena-lang liberapay: # Replace with a single Liberapay username From 1c1432b38987d600d277a7169849c58464cba170 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Tue, 25 Feb 2025 09:55:36 +0100 Subject: [PATCH 05/53] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 80de143b87..24bcaab755 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -3,7 +3,7 @@ github: [arakov] patreon: elena_lang open_collective: # Replace with a single Open Collective username -ko_fi: https://ko-fi.com/elenaprolang +ko_fi: elenaprolang tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # elena-lang liberapay: # Replace with a single Liberapay username From 6551aededf9349fd8813e552f555f760352d9dc0 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Tue, 25 Feb 2025 09:56:30 +0100 Subject: [PATCH 06/53] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 70a4dcb64d..343b745cc9 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,6 @@ -
- -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W01B4CV8) - -
- ELENA is a general-purpose language with late binding. It is multi-paradigm, combining features of functional and object-oriented programming. It supports both strong and weak types, run-time conversions, boxing and unboxing primitive types, direct usage of external libraries. A rich set of tools is provided to deal with message dispatching : multi-methods, message qualifying, generic message handlers. Multiple-inheritance can be simulated using mixins and type interfaces. The built-in script engine allows incorporating custom-defined scripts into your applications. Both stand-alone applications and Virtual machine clients are supported. ### Features @@ -132,3 +126,9 @@ Reach out with any questions you may have and we'll make sure to answer them as The compiler and executables distributed in this package fall under MIT License, for more information read the file LICENSE. + +
+ +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W01B4CV8) + +
From af106a3aaf51ed8b115566ef54ed229c27dc0aa0 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Tue, 25 Feb 2025 10:05:02 +0100 Subject: [PATCH 07/53] Update FUNDING.yml --- .github/FUNDING.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 24bcaab755..7115c51f58 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -9,4 +9,3 @@ community_bridge: # elena-lang liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username -custom: https://paypal.me/elenaprolang From e5a973053375e123372c9144a0efc2c6cec47f04 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Thu, 13 Mar 2025 13:27:15 +0100 Subject: [PATCH 08/53] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 343b745cc9..bebda041e8 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,10 @@ ELENA is a general-purpose language with late binding. It is multi-paradigm, com - **Windows** : x86 (32-bit) / x86-64 (64-bit) - **Linux** : x86 (32-bit) / x86-64 (64-bit) / ppc64le / arm64 (a64) +## Platforms to be supported + +- **macOS** : arm64 (a64) + ## Source Download and Compilation To acquire the source code clone the git repository: From c325eba292a5e170e175e1e4dbba6b6ba0f66996 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 15 Mar 2025 14:50:31 +0100 Subject: [PATCH 09/53] Iteration37 (#710) * [ADDED] CORE_MATH_TABLE core table * [ADDED] ppc64le : fexp * [ADDED] aarch64 : fexp * [FIXED]linux ide - compile the project * [FIXED] ide linux - displaying text * [ADDED] ppc64le : fln * [ADDED] Linux - open a file * working on #283 : unboxing duplicate object * working on xforms - supporting RadioButtonGroup * [ADDED] xforms : supporting RadioButton, Panel * [ADDED] API : forms'Combobox * [SM][ADDED] supporting $regex rules * supporting \d regex symbol * upndown - fixing an error with selecting radio button group before the control is created * [ADDED] aarch64 : fln * [IDE] Linux - set focus on activate * [ADDED] #708 : introducing macos subversion * #708 : introduce macOs elc version, dummy macholinker * reoginizing linux configuration to compile the library to lib60, instead of directly to \usr\... * #34 : introducing HttpClient draft --- CHANGELOG.md | 7 + VERSION | 2 +- asm/aarch64/core60.asm | 273 ++++++- asm/amd64/core60.asm | 7 + asm/ppc64le/core60.asm | 252 +++++++ asm/x32/core60.asm | 7 + ...al.elc60.config.bak => local.elc60.config} | 0 bin/scripts/xforms60.es | 192 ++++- bin/templates/lib60.config | 2 - bin/templates/local.lib60.config | 6 - build/aarch64/build_package_arm64.script | 30 +- build/aarch64/control | 2 +- build/amd64/build_package_amd64.script | 30 +- build/amd64/control | 2 +- build/create_package_x86.bat | 8 + build/elena_inno.iss | 6 +- build/i386/build_package_i386.script | 30 +- build/i386/control | 2 +- build/ppc64le/build_package_ppc64le.script | 30 +- build/ppc64le/control | 2 +- doc/features | 17 + doc/todo.txt | 86 +-- elenasrc3/common/lists.h | 2 +- elenasrc3/common/streams.h | 6 +- elenasrc3/common/tree.h | 6 +- elenasrc3/elc/cliconst.h | 2 +- elenasrc3/elc/codeblocks/elc_mac_arm64.mak | 146 ++++ elenasrc3/elc/compiler.cpp | 258 ++++++- elenasrc3/elc/compiler.h | 35 +- elenasrc3/elc/compiling.cpp | 118 ++- elenasrc3/elc/compiling.h | 7 + elenasrc3/elc/linux/elc.cpp | 277 ++++--- elenasrc3/elc/linux/elfarmimage.h | 4 +- elenasrc3/elc/macos/elc.cpp | 251 ++++++ elenasrc3/elc/macos/machoarmimage.cpp | 11 + elenasrc3/elc/macos/machoarmimage.h | 45 ++ elenasrc3/elc/macos/machoarmlinker64.cpp | 11 + elenasrc3/elc/macos/machoarmlinker64.h | 30 + elenasrc3/elc/macos/machoimage.cpp | 22 + elenasrc3/elc/macos/machoimage.h | 78 ++ elenasrc3/elc/macos/macholinker.cpp | 17 + elenasrc3/elc/macos/macholinker.h | 33 + elenasrc3/elc/macos/macholinker64.cpp | 11 + elenasrc3/elc/macos/macholinker64.h | 30 + elenasrc3/elc/windows/elc.cpp | 108 +-- elenasrc3/elenart/rtcommon.h | 2 +- elenasrc3/elenasm/cfparser.cpp | 205 ++--- elenasrc3/elenasm/cfparser.h | 25 +- elenasrc3/elenasm/regex.cpp | 416 ++++++++++ elenasrc3/elenasm/regex.h | 431 +++++++++++ elenasrc3/elenasm/smcommon.h | 4 +- elenasrc3/elenasm/vs/elenasm.vcxproj | 2 + elenasrc3/engine/core.h | 3 +- elenasrc3/engine/elena.h | 8 + elenasrc3/engine/elenaconst.h | 4 +- elenasrc3/engine/elenamachine.cpp | 1 - elenasrc3/engine/gcroutines.cpp | 2 +- elenasrc3/engine/jitcompiler.cpp | 9 +- elenasrc3/engine/langcommon.h | 4 + elenasrc3/engine/libman.cpp | 2 + elenasrc3/engine/linux/presenter.cpp | 2 +- elenasrc3/engine/linux/presenter.h | 2 +- elenasrc3/engine/projectbase.h | 2 + elenasrc3/engine/rtmanager.cpp | 2 +- elenasrc3/engine/windows/presenter.cpp | 21 +- elenasrc3/gui/gtklinux/gtkcommon.cpp | 3 +- elenasrc3/gui/gtklinux/gtkcommon.h | 73 +- elenasrc3/gui/gtklinux/gtkgraphic.h | 57 +- elenasrc3/gui/gtklinux/gtktabbar.cpp | 24 +- elenasrc3/gui/gtklinux/gtktabbar.h | 4 +- elenasrc3/gui/gtklinux/gtktextframe.cpp | 7 +- elenasrc3/gui/gtklinux/gtktextframe.h | 4 +- elenasrc3/gui/gtklinux/gtktextview.cpp | 65 +- elenasrc3/gui/gtklinux/gtktextview.h | 14 +- elenasrc3/gui/text.h | 3 +- elenasrc3/ide/codeblocks/elide_gtk.cbp | 4 + elenasrc3/ide/eng/messages.h | 2 +- elenasrc3/ide/gtklinux/factory.cpp | 30 +- elenasrc3/ide/gtklinux/factory.h | 15 + elenasrc3/ide/gtklinux/gtkdialogs.cpp | 714 ++++++++++++++++++ elenasrc3/ide/gtklinux/gtkdialogs.h | 240 ++++++ elenasrc3/ide/gtklinux/gtkide.cpp | 41 +- elenasrc3/ide/gtklinux/gtkide.h | 16 +- elenasrc3/ide/gtklinux/gtkidetextview.cpp | 37 + elenasrc3/ide/gtklinux/gtkidetextview.h | 26 + elenasrc3/ide/gtklinux/textframe.cpp | 0 elenasrc3/ide/ideversion.h | 2 +- elenasrc3/tools/asmc/armassembler.cpp | 30 +- elenasrc3/tools/asmc/armassembler.h | 3 +- elenasrc3/tools/asmc/asmconst.h | 2 +- elenasrc3/tools/asmc/assembler.cpp | 5 +- elenasrc3/tools/asmc/assembler.h | 3 +- elenasrc3/tools/asmc/ppc64assembler.cpp | 16 +- elenasrc3/tools/asmc/ppc64assembler.h | 3 +- elenasrc3/tools/asmc/x86assembler.cpp | 7 +- elenasrc3/tools/asmc/x86assembler.h | 3 +- examples60/gui/helloworld/helloworld.xs | 2 +- recompile60.mac.sh | 1 + src60/core/system.core_routines.esm | 22 + src60/elena_api.linux.prjcol | 7 + ...xtensions.project => extensions.linux.prj} | 0 src60/forms/forms.prj | 2 +- src60/forms/win32_controls.l | 72 +- .../{ltests.project => ltests.linux.prj} | 0 src60/net/http/common.l | 19 +- src60/net/http/httpclient.l | 44 ++ src60/net/http/httpheaders.l | 23 + src60/net/http/httpresponse.l | 14 + src60/net/net.prj | 4 +- src60/system/io/lnx_files.l | 32 + src60/system/net/networkstream.l | 87 ++- src60/system/net/win_sockets.l | 99 ++- src60/system/pointers.l | 34 +- .../{system.project => system.linux.prj} | 10 +- src60/system/text/parsing/regex.l | 6 +- src60/system/winforms/win_common.l | 4 + src60/system/winforms/win_controls.l | 1 + tests60/sandbox/sandbox.l | 76 +- tests60/system_tests/basic.l | 26 +- tests60/system_tests/system_tests.prj | 20 + tests60/system_tests/system_tests.project | 32 - 121 files changed, 4872 insertions(+), 866 deletions(-) rename bin/{local.elc60.config.bak => local.elc60.config} (100%) create mode 100644 elenasrc3/elc/codeblocks/elc_mac_arm64.mak create mode 100644 elenasrc3/elc/macos/elc.cpp create mode 100644 elenasrc3/elc/macos/machoarmimage.cpp create mode 100644 elenasrc3/elc/macos/machoarmimage.h create mode 100644 elenasrc3/elc/macos/machoarmlinker64.cpp create mode 100644 elenasrc3/elc/macos/machoarmlinker64.h create mode 100644 elenasrc3/elc/macos/machoimage.cpp create mode 100644 elenasrc3/elc/macos/machoimage.h create mode 100644 elenasrc3/elc/macos/macholinker.cpp create mode 100644 elenasrc3/elc/macos/macholinker.h create mode 100644 elenasrc3/elc/macos/macholinker64.cpp create mode 100644 elenasrc3/elc/macos/macholinker64.h create mode 100644 elenasrc3/elenasm/regex.cpp create mode 100644 elenasrc3/elenasm/regex.h create mode 100644 elenasrc3/ide/gtklinux/gtkdialogs.cpp create mode 100644 elenasrc3/ide/gtklinux/gtkdialogs.h create mode 100644 elenasrc3/ide/gtklinux/gtkidetextview.cpp create mode 100644 elenasrc3/ide/gtklinux/gtkidetextview.h create mode 100644 elenasrc3/ide/gtklinux/textframe.cpp create mode 100644 recompile60.mac.sh create mode 100644 src60/elena_api.linux.prjcol rename src60/extensions/{extensions.project => extensions.linux.prj} (100%) rename src60/ltests/{ltests.project => ltests.linux.prj} (100%) create mode 100644 src60/net/http/httpheaders.l create mode 100644 src60/net/http/httpresponse.l rename src60/system/{system.project => system.linux.prj} (95%) delete mode 100644 tests60/system_tests/system_tests.project diff --git a/CHANGELOG.md b/CHANGELOG.md index 117a86f8c8..2f4f6695ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## ELENA 6.6.0 +- ELENA + - [ADDED] user defined type alias + - ELC - [ADDED] new option "-xj" to turn on jump alignment - [ADDED] if:nil / if:not:nil / if:not template statements @@ -19,6 +22,7 @@ - [FIXED] ppc64le extopen / extclose opcode - [FIXED] #704 : Porting to FreeBSD/PowerPC64 - [FIXED] aarch64 extopen / extclose opcode + - [FIXED] #283 : unboxing duplicate object - API - [ADDED] net'http'HttpClient, net'http'Uri @@ -33,6 +37,9 @@ - IDE - [FIXED]debugger : step over multi-select statement +- Tools + - [ADDED][LDOC] static methods are in the separate category + ## ELENA 6.5.0 - ELENA diff --git a/VERSION b/VERSION index ba92e72f57..3eae443131 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.6.1 \ No newline at end of file +6.6.2 \ No newline at end of file diff --git a/asm/aarch64/core60.asm b/asm/aarch64/core60.asm index 0114c3b4f2..fac1d4776f 100644 --- a/asm/aarch64/core60.asm +++ b/asm/aarch64/core60.asm @@ -9,6 +9,7 @@ define THREAD_WAIT 10007h define CORE_TOC 20001h define SYSTEM_ENV 20002h define CORE_GC_TABLE 20003h +define CORE_MATH_TABLE 20004h define CORE_SINGLE_CONTENT 2000Bh define VOID 2000Dh define VOIDPTR 2000Eh @@ -68,6 +69,36 @@ structure % CORE_TOC dq 0 // ; address of import section end + +structure % CORE_MATH_TABLE + + dbl "1.4426950408889634074" // ; 00 : FM_DOUBLE_LOG2OFE + dbl "2.30933477057345225087e-2" // ; 08 : + dbl "2.02020656693165307700e1" // ; 16 : + dbl "1.51390680115615096133e3" // ; 24 : + dbl "1.0" // ; 32 : + dbl "0.5" // ; 40 : + dbl "2.33184211722314911771e2" // ; 48 + dbl "4.36821166879210612817e3" // ; 56 + + dbl "1.41421356237309504880" // ; 64 + + dbl "1.01875663804580931796e-4" // ; 72 + dbl "4.97494994976747001425e-1" // ; 80 + dbl "4.70579119878881725854e0" // ; 88 + dbl "1.44989225341610930846e1" // ; 96 + dbl "1.79368678507819816313e1" // ; 104 + dbl "7.70838733755885391666e0" // ; 112 + + dbl "1.12873587189167450590e1" // ; 120 + dbl "4.52279145837532221105e1" // ; 128 + dbl "8.29875266912776603211e1" // ; 136 + dbl "7.11544750618563894466e1" // ; 144 + dbl "2.31251620126765340583e1" // ; 152 + + dbl "6.9314718055994530942e-1" // ; 160 + +end structure % CORE_SINGLE_CONTENT @@ -1020,62 +1051,226 @@ end // ; fexpdp inline %07Ah -//; static double expo(double n) { -//; int a = 0, b = n > 0; -//; double c = 1, d = 1, e = 1; -//; for (b || (n = -n); e + .00001 < (e += (d *= n) / (c *= ++a));); -//; // approximately 15 iterations -//; return b ? e : 1 / e; + movz x17, rdata_ptr32lo : %CORE_MATH_TABLE + movk x17, rdata_ptr32hi : %CORE_MATH_TABLE, lsl #16 - mov x15, #0 - fmov d14, #"1E-4" // ; diff = 0.00001 + add x19, x29, __arg12_1 // ; dest (x19) - ldr d7, [x0] // ; n + ldr d17, [x0] // ; x (d17) - fcmp d7, #0 - blt labSkip - fneg d7, d7 - mov x15, #1 + // ; x = x * FM_DOUBLE_LOG2OFE + ldr d20, [x17] + fmul d17, d17, d20 -labSkip: - mov x4, #0 // ; a = 0 + // ; ipart = x + 0.5 + ldr d20, [x17, #40] + fadd d18, d17, d20 + // ; ipart(d18) + frintz d18, d18 // ; ipart = floor(ipart) - fmov d3, #"1E0" // ; e = 1 - fmov d5, d3 // ; c = 1 - fmov d6, d3 // ; d = 1 + fsub d19, d17, d18 // ; fpart = x - ipart; (d19) - // ; e = d3 a = x4, c = d5, d = d6 ; n = d7 + // ; FM_DOUBLE_INIT_EXP(epart,ipart); + frintx d20, d18 + fcvtzs x18, d20 + add x18, x18, #1023 + mov x20, #20 + lsl x18, x18, x20 + mov x20, #0 + str x20, [x19] + str w18, [x19, #4] -labNext: - // ; e + .00001 < (e += (d *= n) / (c *= ++a)) - fmov d13, d3 + fmul d17, d19, d19 // ; x = fpart*fpart; - add x4, x4, #1 // ; ++a - fmov d4, x4 - frintx d4, d4 + ldr d20, [x17, #8] // ; px = fm_exp2_p[0]; - fmul d5, d5, d4 // ; c *= (++a) - fmul d6, d6, d7 // ; d *= n - fdiv d12, d6, d5 // ; (d *= n) / (c *= ++a) - fadd d3, d3, d12 // ; e += (d *= n) / (c *= ++a) + // ; px = px*x + fm_exp2_p[1]; + fmul d20, d20, d17 + ldr d21, [x17, #16] + fadd d20, d20, d21 - fsub d13, d13, d3 - fcmp d13, d14 - bgt labNext + // ; qx = x + fm_exp2_q[0]; + ldr d22, [x17, #48] + fadd d22, d22, d17 - cmp x15, #0 - fmov d16, #"1E0" - bne labSkip2 - fdiv d3, d16, d3 + // ; px = px*x + fm_exp2_p[2]; + fmul d20, d20, d17 + ldr d21, [x17, #24] -labSkip2: - add x19, x29, __arg12_1 - str d3, [x19] + fadd d20, d20, d21 + + // ; qx = qx*x + fm_exp2_q[1]; + fmul d22, d22, d17 + ldr d21, [x17, #56] + fadd d22, d22, d21 + + // ; px = px * fpart; + fmul d20, d20, d19 + + // ; x = 1.0 + 2.0*(px/(qx-px)) + ldr d16, [x17, #32] + + fmov d17, d16 + + fadd d16, d16, d16 + + fsub d21, d22, d20 + fdiv d21, d20, d21 + fmul d16, d16, d21 + fadd d17, d17, d16 + + // ; epart.f*x; + ldr d20, [x19] + fmul d20, d20, d17 + str d20, [x19] end // ; fln inline %07Bh + + movz x17, rdata_ptr32lo : %CORE_MATH_TABLE + movk x17, rdata_ptr32hi : %CORE_MATH_TABLE, lsl #16 + + add x19, x29, __arg12_1 // ; dest (x19) + + ldr d17, [x0] // ; x (d17) + +//; udi_t val; +//; double z (d21), px(d18), qx(d19); +//; int32_t ipart (x18), fpart (x16); + +//; val.f = x; + str d17, [x19] + + //; extract exponent and part of the mantissa */ + +//; fpart = val.s.i1 & FM_DOUBLE_MMASK; + movz x20, #0FFFFh + movk x20, #0Fh, lsl #16 + + ldrsw x16, [x19, #4] + and x16, x16, x20 +//; ipart = val.s.i1 & FM_DOUBLE_EMASK; + movz x20, #0 + movk x20, #7FF0h, lsl #16 + ldrsw x18, [x19, #4] + and x18, x18, x20 + +//; /* set exponent to 0 to get the prefactor to 2**ipart */ +//; fpart |= FM_DOUBLE_EZERO; + movz x20, #0 + movk x20, #3FF0h, lsl #16 + orr x16, x16, x20 +//; val.s.i1 = fpart; + str w16, [x19, #4] +//; x = val.f; + ldr d17, [x19] + +//; /* extract exponent */ +//; ipart >>= FM_DOUBLE_MBITS; + movz x20, #20 + lsr x18, x18, x20 + +//; ipart -= FM_DOUBLE_BIAS; + movz x20, #1023 + sub x18, x18, x20 + +//; /* the polynomial is computed for sqrt(0.5) < x < sqrt(2), +//; but we have the mantissa in the interval 1 < x < 2. +//; adjust by dividing x by 2 and incrementing ipart, if needed. */ +//; if (x > FM_DOUBLE_SQRT2) { + ldr d20, [x17, #64] + fcmp d17, d20 + blt labSkip + beq labSkip + +//; x *= 0.5; + ldr d20, [x17, #40] + fmul d17, d17, d20 +//; ++ipart; + add x18, x18, #1 +//; } +labSkip: + +//; /* use polynomial approximation for log(1+x) */ +//; x -= 1.0; + ldr d20, [x17, #32] + fsub d17, d17, d20 + +//; px = fm_log2_p[0]; + ldr d18, [x17, #72] + +//; px = px * x + fm_log2_p[1]; + ldr d20, [x17, #80] + fmul d18, d18, d17 + fadd d18, d18, d20 + +//; px = px * x + fm_log2_p[2]; + ldr d20, [x17, #88] + fmul d18, d18, d17 + fadd d18, d18, d20 + +//; px = px * x + fm_log2_p[3]; + ldr d20, [x17, #96] + fmul d18, d18, d17 + fadd d18, d18, d20 + +//; px = px * x + fm_log2_p[4]; + ldr d20, [x17, #104] + fmul d18, d18, d17 + fadd d18, d18, d20 + +//; px = px * x + fm_log2_p[5]; + ldr d20, [x17, #112] + fmul d18, d18, d17 + fadd d18, d18, d20 + +//; qx = x + fm_log2_q[0]; + ldr d20, [x17, #120] + fadd d19, d17, d20 + +//; qx = qx * x + fm_log2_q[1]; + ldr d20, [x17, #128] + fmul d19, d19, d17 + fadd d19, d19, d20 + +//; qx = qx * x + fm_log2_q[2]; + ldr d20, [x17, #136] + fmul d19, d19, d17 + fadd d19, d19, d20 + +//; qx = qx * x + fm_log2_q[3]; + ldr d20, [x17, #144] + fmul d19, d19, d17 + fadd d19, d19, d20 + +//; qx = qx * x + fm_log2_q[4]; + ldr d20, [x17, #152] + fmul d19, d19, d17 + fadd d19, d19, d20 + +//; z = x * x; + fmul d21, d17, d17 + +//; z = x * (z * px / qx) - 0.5 * z + x; + fmul d20, d21, d18 + fdiv d20, d20, d19 + fmul d22, d20, d17 + + ldr d20, [x17, #40] + fmul d20, d20, d21 + fsub d22, d22, d20 + fadd d21, d22, d17 + +//; z += ((double)ipart) * FM_DOUBLE_LOGEOF2; + scvtf d20, x18 + ldr d18, [x17, #160] + fmul d20, d20, d18 + fadd d21, d21, d20 + + str d21, [x19] + end // ; fsin diff --git a/asm/amd64/core60.asm b/asm/amd64/core60.asm index 91468f6e82..a7ae9ba15b 100644 --- a/asm/amd64/core60.asm +++ b/asm/amd64/core60.asm @@ -11,6 +11,7 @@ define THREAD_WAIT 10007h define CORE_TOC 20001h define SYSTEM_ENV 20002h define CORE_GC_TABLE 20003h +define CORE_MATH_TABLE 20004h define CORE_SINGLE_CONTENT 2000Bh define VOID 2000Dh define VOIDPTR 2000Eh @@ -68,6 +69,12 @@ structure % CORE_TOC dq 0 // ; reserved end + +structure % CORE_MATH_TABLE + + dq 0 // ; reserved + +end structure % CORE_SINGLE_CONTENT diff --git a/asm/ppc64le/core60.asm b/asm/ppc64le/core60.asm index 53150e4246..88c766e309 100644 --- a/asm/ppc64le/core60.asm +++ b/asm/ppc64le/core60.asm @@ -9,6 +9,7 @@ define THREAD_WAIT 10007h define CORE_TOC 20001h define SYSTEM_ENV 20002h define CORE_GC_TABLE 20003h +define CORE_MATH_TABLE 20004h define CORE_SINGLE_CONTENT 2000Bh define VOID 2000Dh define VOIDPTR 2000Eh @@ -92,6 +93,36 @@ structure % CORE_TOC dq code : %PREPARE // ; address of alloc function end + +structure % CORE_MATH_TABLE + + dbl "1.4426950408889634074" // ; 00 : FM_DOUBLE_LOG2OFE + dbl "2.30933477057345225087e-2" // ; 08 : + dbl "2.02020656693165307700e1" // ; 16 : + dbl "1.51390680115615096133e3" // ; 24 : + dbl "1.0" // ; 32 : + dbl "0.5" // ; 40 : + dbl "2.33184211722314911771e2" // ; 48 + dbl "4.36821166879210612817e3" // ; 56 + + dbl "1.41421356237309504880" // ; 64 + + dbl "1.01875663804580931796e-4" // ; 72 + dbl "4.97494994976747001425e-1" // ; 80 + dbl "4.70579119878881725854e0" // ; 88 + dbl "1.44989225341610930846e1" // ; 96 + dbl "1.79368678507819816313e1" // ; 104 + dbl "7.70838733755885391666e0" // ; 112 + + dbl "1.12873587189167450590e1" // ; 120 + dbl "4.52279145837532221105e1" // ; 128 + dbl "8.29875266912776603211e1" // ; 136 + dbl "7.11544750618563894466e1" // ; 144 + dbl "2.31251620126765340583e1" // ; 152 + + dbl "6.9314718055994530942e-1" // ; 160 + +end structure % CORE_SINGLE_CONTENT @@ -1085,10 +1116,231 @@ end // ; fexpdp inline %07Ah + ld r17, toc_rdata(r2) + addis r17, r17, rdata_disp32hi : %CORE_MATH_TABLE + addi r17, r17, rdata_disp32lo : %CORE_MATH_TABLE + + addi r19, r31, __arg16_1 // ; dest (r19) + + lfd f17, 0(r3) // ; x (f17) + + // ; x = x * FM_DOUBLE_LOG2OFE + lfd f20, 0(r17) + fmul f17, f17, f20 + + // ; ipart = x + 0.5 + lfd f20, 40(r17) + fadd f18, f17, f20 + // ; ipart(f18) + friz f18, f18 // ; ipart = floor(ipart) + + fsub f19, f17, f18 // ; fpart = x - ipart; (f19) + + // ; FM_DOUBLE_INIT_EXP(epart,ipart); + fctidz f20, f18 + stfd f20, 0(r19) + ld r18, 0(r19) + li r20, 1023 + add r18, r18, r20 + li r20, 20 + sld r18, r18, r20 + li r20, 0 + std r20, 0(r19) + stw r18, 4(r19) + + fmul f17, f19, f19 // ; x = fpart*fpart; + + lfd f20, 8(r17) // ; px = fm_exp2_p[0]; + + // ; px = px*x + fm_exp2_p[1]; + fmul f20, f20, f17 + lfd f21, 16(r17) + fadd f20, f20, f21 + + // ; qx = x + fm_exp2_q[0]; + lfd f22, 48(r17) + fadd f22, f22, f17 + + // ; px = px*x + fm_exp2_p[2]; + fmul f20, f20, f17 + lfd f21, 24(r17) + fadd f20, f20, f21 + + // ; qx = qx*x + fm_exp2_q[1]; + fmul f22, f22, f17 + lfd f21, 56(r17) + fadd f22, f22, f21 + + // ; px = px * fpart; + fmul f20, f20, f19 + + // ; x = 1.0 + 2.0*(px/(qx-px)) + lfd f16, 32(r17) + + // ; mr f17, f16 + stfd f16, -8(r1) + lfd f17, -8(r1) + + fadd f16, f16, f16 + + fsub f21, f22, f20 + fdiv f21, f20, f21 + fmul f16, f16, f21 + fadd f17, f17, f16 + + // ; epart.f*x; + lfd f20, 0(r19) + fmul f20, f20, f17 + stfd f20, 0(r19) + end // ; fln inline %07Bh + + ld r17, toc_rdata(r2) + addis r17, r17, rdata_disp32hi : %CORE_MATH_TABLE + addi r17, r17, rdata_disp32lo : %CORE_MATH_TABLE + + addi r19, r31, __arg16_1 // ; dest (r19) + + lfd f17, 0(r3) // ; x (f17) + +//; udi_t val; +//; double z (f21), px(f18), qx(f19); +//; int32_t ipart (r18), fpart (r16); + +//; val.f = x; + stfd f17, 0(r19) + + //; extract exponent and part of the mantissa */ + +//; fpart = val.s.i1 & FM_DOUBLE_MMASK; + li r20, -1 + andi. r20, r20, 0FFFFh + addis r20, r20, 0Fh + lwz r16, 4(r19) + and r16, r16, r20 +//; ipart = val.s.i1 & FM_DOUBLE_EMASK; + lis r20, 7FF0h + lwz r18, 4(r19) + and r18, r18, r20 + +//; /* set exponent to 0 to get the prefactor to 2**ipart */ +//; fpart |= FM_DOUBLE_EZERO; + lis r20, 3FF0h + or r16, r16, r20 +//; val.s.i1 = fpart; + stw r16, 4(r19) +//; x = val.f; + lfd f17, 0(r19) + +//; /* extract exponent */ +//; ipart >>= FM_DOUBLE_MBITS; + li r20, 20 + srd r18, r18, r20 + +//; ipart -= FM_DOUBLE_BIAS; + li r20, 1023 + sub r18, r18, r20 + +//; /* the polynomial is computed for sqrt(0.5) < x < sqrt(2), +//; but we have the mantissa in the interval 1 < x < 2. +//; adjust by dividing x by 2 and incrementing ipart, if needed. */ +//; if (x > FM_DOUBLE_SQRT2) { + lfd f20, 64(r17) + fcmpu f17, f20 + blt labSkip + beq labSkip + +//; x *= 0.5; + lfd f20, 40(r17) + fmul f17, f17, f20 +//; ++ipart; + addi r18, r18, 1 +//; } +labSkip: + +//; /* use polynomial approximation for log(1+x) */ +//; x -= 1.0; + lfd f20, 32(r17) + fsub f17, f17, f20 + +//; px = fm_log2_p[0]; + lfd f18, 72(r17) + +//; px = px * x + fm_log2_p[1]; + lfd f20, 80(r17) + fmul f18, f18, f17 + fadd f18, f18, f20 + +//; px = px * x + fm_log2_p[2]; + lfd f20, 88(r17) + fmul f18, f18, f17 + fadd f18, f18, f20 + +//; px = px * x + fm_log2_p[3]; + lfd f20, 96(r17) + fmul f18, f18, f17 + fadd f18, f18, f20 + +//; px = px * x + fm_log2_p[4]; + lfd f20, 104(r17) + fmul f18, f18, f17 + fadd f18, f18, f20 + +//; px = px * x + fm_log2_p[5]; + lfd f20, 112(r17) + fmul f18, f18, f17 + fadd f18, f18, f20 + +//; qx = x + fm_log2_q[0]; + lfd f20, 120(r17) + fadd f19, f17, f20 + +//; qx = qx * x + fm_log2_q[1]; + lfd f20, 128(r17) + fmul f19, f19, f17 + fadd f19, f19, f20 + +//; qx = qx * x + fm_log2_q[2]; + lfd f20, 136(r17) + fmul f19, f19, f17 + fadd f19, f19, f20 + +//; qx = qx * x + fm_log2_q[3]; + lfd f20, 144(r17) + fmul f19, f19, f17 + fadd f19, f19, f20 + +//; qx = qx * x + fm_log2_q[4]; + lfd f20, 152(r17) + fmul f19, f19, f17 + fadd f19, f19, f20 + +//; z = x * x; + fmul f21, f17, f17 + +//; z = x * (z * px / qx) - 0.5 * z + x; + fmul f20, f21, f18 + fdiv f20, f20, f19 + fmul f22, f20, f17 + + lfd f20, 40(r17) + fmul f20, f20, f21 + fsub f22, f22, f20 + fadd f21, f22, f17 + +//; z += ((double)ipart) * FM_DOUBLE_LOGEOF2; + std r18, 0(r19) + lfd f20, 0(r19) + fcfid f20, f20 + lfd f18, 160(r17) + fmul f20, f20, f18 + fadd f21, f21, f20 + + stfd f21, 0(r19) + end // ; fsin diff --git a/asm/x32/core60.asm b/asm/x32/core60.asm index 06d68ea1e4..528861bf86 100644 --- a/asm/x32/core60.asm +++ b/asm/x32/core60.asm @@ -9,6 +9,7 @@ define THREAD_WAIT 10007h define CORE_TOC 20001h define SYSTEM_ENV 20002h define CORE_GC_TABLE 20003h +define CORE_MATH_TABLE 20004h define CORE_SINGLE_CONTENT 2000Bh define VOID 2000Dh define VOIDPTR 2000Eh @@ -71,6 +72,12 @@ structure % CORE_TOC end +structure % CORE_MATH_TABLE + + dd 0 // ; reserved + +end + structure % CORE_SINGLE_CONTENT dd 0 // ; et_critical_handler ; +x00 - pointer to ELENA critical handler diff --git a/bin/local.elc60.config.bak b/bin/local.elc60.config similarity index 100% rename from bin/local.elc60.config.bak rename to bin/local.elc60.config diff --git a/bin/scripts/xforms60.es b/bin/scripts/xforms60.es index 98d0872c12..b1ca4ab20e 100644 --- a/bin/scripts/xforms60.es +++ b/bin/scripts/xforms60.es @@ -22,6 +22,14 @@ root ( method ( nameattr( identifier = onInit ) code ( + expression ( + assign_operation ( + new_variable ( identifier = current ) + expression ( + object ( identifier = self ) + ) + ) + ) => { val_form_prop | form_prop }* ">" member* form_closing_tag <= @@ -31,7 +39,7 @@ root ( #define field_list ::= <= $buffer => $eps; - #define member ::= { label | button }; + #define member ::= { label | button | radiobuttongroup | panel | edit | combobox }; #define label ::= <= @@ -50,7 +58,7 @@ root ( <= expression ( message_operation ( - object ( identifier = self ) + object ( super_identifier = current ) message ( identifier = appendControl ) expression ( object ( identifier = current ) @@ -81,7 +89,7 @@ root ( <= expression ( message_operation ( - object ( identifier = self ) + object ( super_identifier = current ) message ( identifier = appendControl ) expression ( object ( identifier = current ) @@ -95,6 +103,145 @@ root ( #define button_declaration ::= %<= field ( type ( reference = forms'Button ) nameattr ( identifier = $current ) ) =>; + #define combobox ::= +<= + code ( + expression ( + assign_operation ( + new_variable ( identifier = current ) + message_operation ( + object ( reference = forms'Combobox ) + message ( identifier = new ) + ) + ) + ) +=> + "<" "Combobox" combobox_name_prop { val_prop | prop }* ">" combobox_closing_tag +<= + expression ( + message_operation ( + object ( super_identifier = current ) + message ( identifier = appendControl ) + expression ( + object ( identifier = current ) + ) + ) + ) + ) +=>; + + #define combobox_name_prop ::= ":" "Name" "=" combobox_declaration control_assigning; + + #define combobox_declaration ::= %<= field ( type ( reference = forms'Combobox ) nameattr ( identifier = $current ) ) =>; + + #define edit ::= +<= + code ( + expression ( + assign_operation ( + new_variable ( identifier = current ) + message_operation ( + object ( reference = forms'Edit ) + message ( identifier = new ) + ) + ) + ) +=> + "<" "Edit" edit_name_prop { val_prop | prop }* ">" edit_closing_tag +<= + expression ( + message_operation ( + object ( super_identifier = current ) + message ( identifier = appendControl ) + expression ( + object ( identifier = current ) + ) + ) + ) + ) +=>; + + #define edit_name_prop ::= ":" "Name" "=" edit_declaration control_assigning; + + #define edit_declaration ::= %<= field ( type ( reference = forms'Edit ) nameattr ( identifier = $current ) ) =>; + + #define radiobuttongroup ::= +<= + code ( + expression ( + assign_operation ( + new_variable ( identifier = current ) + message_operation ( + object ( reference = forms'RadioButtonGroup ) + message ( identifier = new ) + ) + ) + ) +=> + "<" "RadioButtonGroup" rbgroup_name_prop { val_prop | prop }* ">" item* rbgroup_closing_tag +<= + expression ( + message_operation ( + object ( super_identifier = current ) + message ( identifier = appendControl ) + expression ( + object ( identifier = current ) + ) + ) + ) + ) +=>; + + #define rbgroup_name_prop ::= ":" "Name" "=" rbgroup_declaration control_assigning; + + #define rbgroup_declaration ::= %<= field ( type ( reference = forms'RadioButtonGroup ) nameattr ( identifier = $current ) ) =>; + + #define panel ::= +<= + code ( + expression ( + assign_operation ( + new_variable ( identifier = current ) + message_operation ( + object ( reference = forms'Panel ) + message ( identifier = new ) + ) + ) + ) +=> + "<" "Panel" panel_name_prop { val_prop | prop }* ">" member* panel_closing_tag +<= + expression ( + message_operation ( + object ( super_identifier = current ) + message ( identifier = appendControl ) + expression ( + object ( identifier = current ) + ) + ) + ) + ) +=>; + + #define panel_name_prop ::= ":" "Name" "=" panel_declaration control_assigning; + + #define panel_declaration ::= %<= field ( type ( reference = forms'Panel ) nameattr ( identifier = $current ) ) =>; + + #define item ::= +<= + expression ( + message_operation ( + object ( identifier = current ) + message ( identifier = appendItem ) +=> + "<" "Item" itemval_prop ">" item_closing_tag +<= + ) + ) +=>; + + #define itemval_prop ::= "Caption" "=" prop_str_value; + #define control_assigning ::= <= expression ( @@ -190,6 +337,18 @@ root ( ) =>; + #define prop_value ::= +<= + expression ( + object ( + identifier = +=> + nonint_quote +<= + ) + ) +=>; + #define prop_value ::= <= expression ( @@ -198,7 +357,7 @@ root ( object ( identifier = => - nonint_quote + closure_quote <= ) ) @@ -218,11 +377,12 @@ root ( ) =>; - #define ident_value ::= <= identifier = $literal =>; - #define identifier ::= <= identifier = $identifier =>; - #define int_quote ::= <= $intliteral =>; - #define nonint_quote::= <= $nonintliteral =>; - #define quote ::= <= "$literal" =>; + #define ident_value ::= <= identifier = $literal =>; + #define identifier ::= <= identifier = $identifier =>; + #define int_quote ::= <= $regex "^""(?\d+)""$" =>; + #define nonint_quote ::= <= $regex "^""(?[a-zA-Z_]\w*)""$" =>; + #define closure_quote ::= <= $regex "^""&(?[a-zA-Z_]\w*)""$" =>; + #define quote ::= <= "$literal" =>; #define form_closing_tag ::= "<" "/" "Form" ">"; @@ -233,4 +393,18 @@ root ( #define button_closing_tag ::= "<" "/" "Button" ">"; + #define edit_closing_tag ::= + "<" "/" "Edit" ">"; + + #define rbgroup_closing_tag ::= + "<" "/" "RadioButtonGroup" ">"; + + #define item_closing_tag ::= + "<" "/" "Item" ">"; + + #define panel_closing_tag ::= + "<" "/" "Panel" ">"; + + #define combobox_closing_tag ::= + "<" "/" "Combobox" ">"; ]] diff --git a/bin/templates/lib60.config b/bin/templates/lib60.config index 6db2c2acba..d6cd268604 100644 --- a/bin/templates/lib60.config +++ b/bin/templates/lib60.config @@ -50,8 +50,6 @@ system'BaseLazyExpression system'Nullable#1 system'UnsafePointer - meta$preloadedSymbols - meta$preloadedSymbols system'YieldStateEnumerator diff --git a/bin/templates/local.lib60.config b/bin/templates/local.lib60.config index 0530a1e765..daca90e1e1 100644 --- a/bin/templates/local.lib60.config +++ b/bin/templates/local.lib60.config @@ -23,10 +23,6 @@ import system; - system'attributes'attributes - system'predefined'defaults - system'predefined'aliases - system'operations'statements system'Object system'nilValue system'IntNumber @@ -54,8 +50,6 @@ system'BaseLazyExpression system'Nullable#1 system'UnsafePointer - meta$preloadedSymbols - meta$preloadedSymbols system'YieldStateEnumerator diff --git a/build/aarch64/build_package_arm64.script b/build/aarch64/build_package_arm64.script index 46a5e0e2d6..92a7376352 100755 --- a/build/aarch64/build_package_arm64.script +++ b/build/aarch64/build_package_arm64.script @@ -1,6 +1,7 @@ #!/bin/bash -RELEASE=elena-6.6.1.aarch64-linux +RELEASE=elena-6.6.2.aarch64-linux +mkdir -p ../lib60_64 mkdir -p /usr/share/elena mkdir -p /etc/elena/ mkdir -p /etc/elena/templates/ @@ -85,7 +86,7 @@ fi # # echo compiling lib50 files - ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm /usr/lib/elena/lib60_64 + ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm ../../lib60_64 ret=$? if [ $ret -eq 0 ] then @@ -95,7 +96,7 @@ fi exit 1 fi - ../../bin/elena64-cli ../../src60/system/system.project + ../../bin/elena64-cli ../../src60/elena_api.linux.prjcol ret=$? if [ $ret -eq 2 ] then @@ -105,27 +106,10 @@ fi echo . fi - ../../bin/elena64-cli ../../src60/extensions/extensions.project - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli ../../src60/ltests/ltests.project - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi + cp ../../lib60_64/*.nl /usr/lib/elena/lib60_64 + cp ../../lib60_64/*.dnl /usr/lib/elena/lib60_64 - ../../bin/elena64-cli ../../tests60/system_tests/system_tests.project + elena64-cli ../../tests60/system_tests/system_tests.prj ret=$? if [ $ret -eq 2 ] then diff --git a/build/aarch64/control b/build/aarch64/control index c8b0e51e02..76ec1e5ad4 100644 --- a/build/aarch64/control +++ b/build/aarch64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.1 +Version: 6.6.2 Architecture: aarch64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/amd64/build_package_amd64.script b/build/amd64/build_package_amd64.script index 5ba44dca30..4309011910 100755 --- a/build/amd64/build_package_amd64.script +++ b/build/amd64/build_package_amd64.script @@ -1,6 +1,7 @@ #!/bin/bash -RELEASE=elena-6.6.1.amd64-linux +RELEASE=elena-6.6.2.amd64-linux +mkdir -p ../lib60_64 mkdir -p /usr/share/elena mkdir -p /etc/elena/ mkdir -p /etc/elena/templates/ @@ -97,7 +98,7 @@ fi # # echo compiling lib50 files - ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm /usr/lib/elena/lib60_64 + ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm ../../lib60_64 ret=$? if [ $ret -eq 0 ] then @@ -107,7 +108,7 @@ fi exit 1 fi - ../../bin/elena64-cli ../../src60/system/system.project + ../../bin/elena64-cli ../../src60/elena_api.linux.prjcol ret=$? if [ $ret -eq 2 ] then @@ -117,27 +118,10 @@ fi echo . fi - ../../bin/elena64-cli ../../src60/extensions/extensions.project - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli ../../src60/ltests/ltests.project - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi + cp ../../lib60_64/*.nl /usr/lib/elena/lib60_64 + cp ../../lib60_64/*.dnl /usr/lib/elena/lib60_64 - ../../bin/elena64-cli ../../tests60/system_tests/system_tests.project + elena64-cli ../../tests60/system_tests/system_tests.prj ret=$? if [ $ret -eq 2 ] then diff --git a/build/amd64/control b/build/amd64/control index 005b5c58ea..6ef35ce178 100644 --- a/build/amd64/control +++ b/build/amd64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.1 +Version: 6.6.2 Architecture: amd64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/create_package_x86.bat b/build/create_package_x86.bat index 510d1f5257..9f16033ad3 100644 --- a/build/create_package_x86.bat +++ b/build/create_package_x86.bat @@ -74,6 +74,11 @@ md %~dp0\x86\examples60\gui\helloworld md %~dp0\x86\examples60\db md %~dp0\x86\examples60\db\sqlite +md %~dp0\x86\examples60\threads +md %~dp0\x86\examples60\threads\async +md %~dp0\x86\examples60\threads\tasks +md %~dp0\x86\examples60\threads\threadpool + copy %~dp0\..\bin\asm-cli.exe %~dp0\x86\bin copy %~dp0\..\bin\elena-cli.exe %~dp0\x86\bin copy %~dp0\..\bin\elena-ide.exe %~dp0\x86\bin @@ -297,6 +302,9 @@ copy %~dp0\..\examples60\files\textdb\*.txt %~dp0\x86\examples60\files\textdb copy %~dp0\..\examples60\files\textfile\*.l %~dp0\x86\examples60\files\textfile copy %~dp0\..\examples60\files\textfile\*.txt %~dp0\x86\examples60\files\textfile +xcopy %~dp0\..\examples60\threads\*.l %~dp0\x86\examples60\threads /s +xcopy %~dp0\..\examples60\threads\*.prj %~dp0\x86\examples60\threads /s + goto:eof ::ERRORS ::--------------------- diff --git a/build/elena_inno.iss b/build/elena_inno.iss index 4f3eb8ab3d..66ef664798 100644 --- a/build/elena_inno.iss +++ b/build/elena_inno.iss @@ -7,8 +7,8 @@ ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{3CAA69D3-0F98-44B1-A73E-E864BA51D5BD} AppName=ELENA Programming Language -AppVersion=6.6.1 -;AppVerName=ELENA Programming Language 6.5.0 +AppVersion=6.6.2 +;AppVerName=ELENA Programming Language 6.6.0 AppPublisher=Alexey Rakov AppPublisherURL=http://github.com/ELENA-LANG/elena-lang AppSupportURL=http://github.com/ELENA-LANG/elena-lang @@ -18,7 +18,7 @@ DefaultGroupName=ELENA Programming Language AllowNoIcons=yes LicenseFile=..\doc\license InfoAfterFile=..\CHANGELOG.md -OutputBaseFilename=elena-lang-6.5.0.x86-win-setup +OutputBaseFilename=elena-lang-6.6.2.x86-win-setup Compression=lzma SolidCompression=yes ChangesEnvironment=yes diff --git a/build/i386/build_package_i386.script b/build/i386/build_package_i386.script index 15c69ca273..2aa893271a 100755 --- a/build/i386/build_package_i386.script +++ b/build/i386/build_package_i386.script @@ -1,6 +1,7 @@ #!/bin/bash -RELEASE=elena-6.6.1.i386-linux +RELEASE=elena-6.6.2.i386-linux +mkdir -p ../lib60 mkdir -p /usr/share/elena mkdir -p /etc/elena/ mkdir -p /etc/elena/templates/ @@ -99,7 +100,7 @@ fi echo compiling lib60 files - ../../bin/asm-cli -bc32 ../../src60/core/system.core_routines.esm /usr/lib/elena/lib60 + ../../bin/asm-cli -bc32 ../../src60/core/system.core_routines.esm ../../lib60 ret=$? if [ $ret -eq 0 ] then @@ -109,7 +110,7 @@ echo compiling lib60 files exit 1 fi - ../../bin/elena-cli ../../src60/system/system.project + ../../bin/elena-cli ../../src60/elena_api.linux.prjcol ret=$? if [ $ret -eq 2 ] then @@ -119,27 +120,10 @@ echo compiling lib60 files echo . fi - ../../bin/elena-cli ../../src60/extensions/extensions.project - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli ../../src60/ltests/ltests.project - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi + cp ../../lib60/*.nl /usr/lib/elena/lib60 + cp ../../lib60/*.dnl /usr/lib/elena/lib60 - ../../bin/elena-cli ../../tests60/system_tests/system_tests.project + elena-cli ../../tests60/system_tests/system_tests.prj ret=$? if [ $ret -eq 2 ] then diff --git a/build/i386/control b/build/i386/control index 6b60abeba6..e8744dca25 100644 --- a/build/i386/control +++ b/build/i386/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.1 +Version: 6.6.2 Architecture: i386 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/ppc64le/build_package_ppc64le.script b/build/ppc64le/build_package_ppc64le.script index 182a54d626..c807419d4a 100755 --- a/build/ppc64le/build_package_ppc64le.script +++ b/build/ppc64le/build_package_ppc64le.script @@ -1,6 +1,7 @@ #!/bin/bash -RELEASE=elena-6.6.1.ppc64le-linux +RELEASE=elena-6.6.2.ppc64le-linux +mkdir -p ../lib60_64 mkdir -p /usr/share/elena mkdir -p /etc/elena/ mkdir -p /etc/elena/templates/ @@ -85,7 +86,7 @@ fi # # echo compiling lib50 files - ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm /usr/lib/elena/lib60_64 + ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm ../../lib60_64 ret=$? if [ $ret -eq 0 ] then @@ -95,7 +96,7 @@ fi exit 1 fi - ../../bin/elena64-cli ../../src60/system/system.project + ../../bin/elena64-cli ../../src60/elena_api.linux.prjcol ret=$? if [ $ret -eq 2 ] then @@ -105,27 +106,10 @@ fi echo . fi - ../../bin/elena64-cli ../../src60/extensions/extensions.project - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli ../../src60/ltests/ltests.project - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi + cp ../../lib60_64/*.nl /usr/lib/elena/lib60_64 + cp ../../lib60_64/*.dnl /usr/lib/elena/lib60_64 - ../../bin/elena64-cli ../../tests60/system_tests/system_tests.project + elena64-cli ../../tests60/system_tests/system_tests.prj ret=$? if [ $ret -eq 2 ] then diff --git a/build/ppc64le/control b/build/ppc64le/control index 7e95aa9864..3f0a0e7cc7 100644 --- a/build/ppc64le/control +++ b/build/ppc64le/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.1 +Version: 6.6.2 Architecture: ppc64le Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/doc/features b/doc/features index 2f2bbaf815..5334167efe 100644 --- a/doc/features +++ b/doc/features @@ -199,3 +199,20 @@ public program() console.writeLine($"Processor type:{Environment.ProcessorType}"); console.writeLine($"Processor count:{Environment.ProcessorCount}"); } + +---------------------------------------------------------------------------- + Accessing a variable from the upper scope +---------------------------------------------------------------------------- + +import extensions; + +public program() +{ + var variable := "Level 0"; + { + var variable := "Level 1"; + + console.printLine(super variable); + console.printLine(variable); + } +} diff --git a/doc/todo.txt b/doc/todo.txt index 101cbcde5a..9ff643e3d6 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -3,84 +3,60 @@ In development: ------ [development] - ### EPIC: elena 6.6 ### - - === Iteration 36 (13.03) === - -------------------------------------- - * aarch64 : fix exceptionTest, methodNotFoundTest - -------------------------------------- - * fix extopen / extclose + ### EPIC: elena 6.7 ### - === Iteration 37 === + === Iteration 38 (05.04) === -------------------------------------- dev: - - upndown (connector) + - upndown (connector - interaction) - #496 - #622 - * #34 : web api - - http client (https get, post, put, patch, delete, head, options, trace) + - #34 : http client (http get, https get (https://github.com/HISONA/https_client), post, put, patch, delete, head, options, trace), web api + - MTA support for Linux + - #708 : compile the project (elc, og, sg, asm, ecv), create Linker + - implement ExtensionMessage.equal + ide: + - linux - select tab, save, close + - fix syntax highlighting (see system'net:win_common.l) + - ide : windows gen: - - lpad : generate a code based on a record + - lpad / elt : declare an extension, parse it and apply to the input maint: - - #702 + - pi samples for ppc64, aarch64 + - test all x86-64 examples - unit tests : bt optimization - - test binary file operations - - api refactoring : all symbols must start with a capital letter - - redesign winforms - - api : add descriptions - - threading samples must be included into release files - - ide : windows - - review pi performance (must < 6) - - linux editor - open / close / save / exit - - test binary file reader / writer - - matrix sample : review the code, it should be possible to use the lambda function without specifying the exact output type - - implement ExtensionMessage.equal - - support subexpression for "?." and "\." (e.g. object.__getClass()\.__dto_properties()) - - support function call with double colon (e.g. ::printing() - is always a function) - - redesign switch statement : it should be possible to use as an expression as well (so we cannot use => anymore : e.g. - console.printLine(x => 1 { "first" } 2 { "second" } 3 { "third" }) ) console.printLine(x $sel 1 => "first", 2 => "second", 3 => "third") - warn if typecasting method returns itself, it leads to infinite call - + - test binary file reader / writer + - api : add descriptions + - api refactoring : all symbols must start with a capital letter (e.g. printingLn) port: + - chat sample + - rosetta code : moving to 6.5 + - x86-64 : mta - test net examples for mta + - test all x86-64 examples (net) + - pi samples for ppc64, aarch64 tools: - #658 : connect with ldbg from VSCode prom: bi-posting weekly -------------------------------------- - * ide : linux - open, edit, save, close - * ide : linux - show the file - * fixing #283 - * fix chat server - it is blocked - * x86-64 : mta - test net examples for mta - * rosetta code : moving to 6.5 - * http client : get (quick & dirty) - * test all x86 examples (net) - * redesign chat sample : send, leave - * IDE : fix syntax highlighting (see system'net:win_common.l) - * redesign chat sample : connect - * user defined type alias - * declare and use alias with meta operations - * it must be possible to declare them inside the module; it must be possible to import module containing - the custom aliases - * type alias - * fix pi sample for aarch64 - -------------------------------------- - * fix pi sample for ppc64le - -------------------------------------- - * ppc64 : ln - * ppc64 : exp + -------------------------------------- + -------------------------------------- - === Iteration 38 === + === Iteration 39 === -------------------------------------- dev: gen: maint: + - review pi performance (must < 6) port: prom: -------------------------------------- -------------------------------------- -------------------------------------- - === Iteration 39 === + ### EPIC: elena 6.8 ### + + === Iteration 40 === -------------------------------------- dev: gen: @@ -91,9 +67,7 @@ In development: -------------------------------------- -------------------------------------- - ### EPIC: elena 6.7 ### - - === Iteration 40 === + === Iteration 41 === -------------------------------------- dev: gen: diff --git a/elenasrc3/common/lists.h b/elenasrc3/common/lists.h index f87c002ae1..28941c7851 100644 --- a/elenasrc3/common/lists.h +++ b/elenasrc3/common/lists.h @@ -1028,7 +1028,7 @@ namespace elena_lang } Queue(T defItem) - : _list(_defaultItem) + : _list(defItem) { _defaultItem = defItem; } diff --git a/elenasrc3/common/streams.h b/elenasrc3/common/streams.h index 2bf5a1b1d9..f5101adf4b 100644 --- a/elenasrc3/common/streams.h +++ b/elenasrc3/common/streams.h @@ -3,7 +3,7 @@ // // This header contains the declaration of abstract stream reader // and writer classes -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef STREAMS_H @@ -337,6 +337,10 @@ namespace elena_lang { return write(&value, sizeof(size_t)); } + bool writeDouble(double value) + { + return write(&value, sizeof(double)); + } virtual bool writeBytes(unsigned char ch, pos_t count) { diff --git a/elenasrc3/common/tree.h b/elenasrc3/common/tree.h index 5f46bfab8b..8db4071b0e 100644 --- a/elenasrc3/common/tree.h +++ b/elenasrc3/common/tree.h @@ -3,7 +3,7 @@ // // This file contains ELENA Tree template classes // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef TREE_H @@ -301,7 +301,7 @@ namespace elena_lang this->arg.strArgPosition = INVALID_POS; _tree->save(_position, key, arg); - } + } void setStrArgument(ustr_t value) { this->arg.value = 0; @@ -501,7 +501,7 @@ namespace elena_lang // enclose the node with a new one Node encloseNode(Key key, int argument = 0) { - NodeRecord* record = (NodeRecord*)_tree->_body.get(_position); + //NodeRecord* record = (NodeRecord*)_tree->_body.get(_position); _tree->injectChild(_position, this->key, this->arg); diff --git a/elenasrc3/elc/cliconst.h b/elenasrc3/elc/cliconst.h index 9f826b8f23..a03b045369 100644 --- a/elenasrc3/elc/cliconst.h +++ b/elenasrc3/elc/cliconst.h @@ -13,7 +13,7 @@ namespace elena_lang { - #define ELC_REVISION_NUMBER 0x007B + #define ELC_REVISION_NUMBER 0x0084 #if defined _M_IX86 || _M_X64 diff --git a/elenasrc3/elc/codeblocks/elc_mac_arm64.mak b/elenasrc3/elc/codeblocks/elc_mac_arm64.mak new file mode 100644 index 0000000000..890e1c7ff6 --- /dev/null +++ b/elenasrc3/elc/codeblocks/elc_mac_arm64.mak @@ -0,0 +1,146 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = gcc +CXX = g++ +AR = ar +LD = g++ +WINDRES = windres + +INC = -I.. -I../../engine -I../../common +CFLAGS = -Wall -std=c++20 -march=armv8-a +RESINC = +LIBDIR = +LIB = +LDFLAGS = -static-libgcc -static-libstdc++ -ldl -march=armv8-a + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../temp/elena64-cli +DEP_RELEASE = +OUT_RELEASE = ../../../bin/elena64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/arm64compiler.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/macos/elc.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../bin || mkdir -p ../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/engine/macos || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/macos + test -d $(OBJDIR_RELEASE)/__/macos || mkdir -p $(OBJDIR_RELEASE)/__/macos + test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/common/config.o: ../../common/config.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/config.cpp -o $(OBJDIR_RELEASE)/__/__/common/config.o + +$(OBJDIR_RELEASE)/__/__/common/dump.o: ../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/common/files.o: ../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/common/paths.o: ../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/common/ustring.o: ../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/common/xmltree.o: ../../common/xmltree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/xmltree.cpp -o $(OBJDIR_RELEASE)/__/__/common/xmltree.o + +$(OBJDIR_RELEASE)/__/__/engine/bcwriter.o: ../../engine/bcwriter.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/bcwriter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o + +$(OBJDIR_RELEASE)/__/__/engine/codescope.o: ../../engine/codescope.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/codescope.cpp -o $(OBJDIR_RELEASE)/__/__/engine/codescope.o + +$(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o: ../../engine/jitcompiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/jitcompiler.cpp -o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o + +$(OBJDIR_RELEASE)/__/__/engine/jitlinker.o: ../../engine/jitlinker.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/jitlinker.cpp -o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o + +$(OBJDIR_RELEASE)/__/__/engine/libman.o: ../../engine/libman.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/libman.cpp -o $(OBJDIR_RELEASE)/__/__/engine/libman.o + +$(OBJDIR_RELEASE)/__/__/engine/module.o: ../../engine/module.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/module.cpp -o $(OBJDIR_RELEASE)/__/__/engine/module.o + +$(OBJDIR_RELEASE)/__/__/engine/parsertable.o: ../../engine/parsertable.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/parsertable.cpp -o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o + +$(OBJDIR_RELEASE)/__/__/engine/section.o: ../../engine/section.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/section.cpp -o $(OBJDIR_RELEASE)/__/__/engine/section.o + +$(OBJDIR_RELEASE)/__/__/engine/arm64compiler.o: ../../engine/arm64compiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/arm64compiler.cpp -o $(OBJDIR_RELEASE)/__/__/engine/arm64compiler.o + +$(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o: ../../engine/syntaxtree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/syntaxtree.cpp -o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o + +$(OBJDIR_RELEASE)/__/__/engine/bytecode.o: ../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o: ../../engine/xmlprojectbase.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/xmlprojectbase.cpp -o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o + +$(OBJDIR_RELEASE)/__/codeimage.o: ../codeimage.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../codeimage.cpp -o $(OBJDIR_RELEASE)/__/codeimage.o + +$(OBJDIR_RELEASE)/__/compiler.o: ../compiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../compiler.cpp -o $(OBJDIR_RELEASE)/__/compiler.o + +$(OBJDIR_RELEASE)/__/compiling.o: ../compiling.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../compiling.cpp -o $(OBJDIR_RELEASE)/__/compiling.o + +$(OBJDIR_RELEASE)/__/derivation.o: ../derivation.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../derivation.cpp -o $(OBJDIR_RELEASE)/__/derivation.o + +$(OBJDIR_RELEASE)/__/compilerlogic.o: ../compilerlogic.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../compilerlogic.cpp -o $(OBJDIR_RELEASE)/__/compilerlogic.o + +$(OBJDIR_RELEASE)/__/modulescope.o: ../modulescope.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../modulescope.cpp -o $(OBJDIR_RELEASE)/__/modulescope.o + +$(OBJDIR_RELEASE)/__/macos/elc.o: ../macos/elc.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../macos/elc.cpp -o $(OBJDIR_RELEASE)/__/macos/elc.o + +$(OBJDIR_RELEASE)/__/parser.o: ../parser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../parser.cpp -o $(OBJDIR_RELEASE)/__/parser.o + +$(OBJDIR_RELEASE)/__/separser.o: ../separser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../separser.cpp -o $(OBJDIR_RELEASE)/__/separser.o + +$(OBJDIR_RELEASE)/__/project.o: ../project.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../project.cpp -o $(OBJDIR_RELEASE)/__/project.o + +$(OBJDIR_RELEASE)/__/source.o: ../source.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../source.cpp -o $(OBJDIR_RELEASE)/__/source.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/macos + rm -rf $(OBJDIR_RELEASE)/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/elc/compiler.cpp b/elenasrc3/elc/compiler.cpp index a07e1b6c06..b2a725ef2b 100644 --- a/elenasrc3/elc/compiler.cpp +++ b/elenasrc3/elc/compiler.cpp @@ -6,6 +6,8 @@ // (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- +//#define FULL_OUTOUT_INFO 1 + #include "compiler.h" #include "langcommon.h" #include @@ -13,7 +15,11 @@ #include "bytecode.h" -//#define FULL_OUTOUT_INFO 1 +#ifdef FULL_OUTOUT_INFO + +#include "serializer.h" + +#endif using namespace elena_lang; @@ -52,12 +58,18 @@ MethodHint operator | (const ref_t& l, const MethodHint& r) // } //} -//inline void storeNode(SyntaxNode node) -//{ -// DynamicUStr target; -// -// SyntaxTreeSerializer::save(node, target); -//} +#ifdef FULL_OUTOUT_INFO + +inline void printTree(PresenterBase* presenter, SyntaxNode node) +{ + DynamicUStr target; + + SyntaxTreeSerializer::save(node, target); + + presenter->print(target.str()); +} + +#endif // FULL_OUTOUT_INFO //inline void storeNode(BuildNode node) //{ @@ -912,7 +924,7 @@ ObjectInfo Compiler::NamespaceScope::defineObjectInfo(ref_t reference, Expressio info.reference = reference; } else { - if (checkMode) { + if (checkMode && !metaOne) { ClassInfo classInfo; if (moduleScope->loadClassInfo(classInfo, reference, true) != 0) { // if it is an extension @@ -1600,14 +1612,14 @@ bool Compiler::CodeScope::resolveAutoType(ObjectInfo& info, TypeInfo typeInfo, i // --- Compiler::ExprScope --- Compiler::ExprScope::ExprScope(SourceScope* parent) - : Scope(parent), tempLocals({}) + : Scope(parent), trackingClosureLocals(false), unboxingConflictFound(false), tempLocals({}), trackingLocals({}) { allocatedArgs = 0; tempAllocated2 = tempAllocated1 = 0; } Compiler::ExprScope::ExprScope(CodeScope* parent) - : Scope(parent), tempLocals({}) + : Scope(parent), trackingClosureLocals(false), unboxingConflictFound(false), tempLocals({}), trackingLocals({}) { allocatedArgs = 0; tempAllocated1 = parent->allocated1; @@ -1621,6 +1633,21 @@ int Compiler::ExprScope::newTempLocal() return tempAllocated1; } +ObjectInfo Compiler::ExprScope :: mapIdentifier(ustr_t identifier, bool referenceOne, ExpressionAttribute attr) +{ + ObjectInfo info = Scope::mapIdentifier(identifier, referenceOne, attr); + if (unboxingConflictFound && !trackingClosureLocals && info.kind != ObjectKind::Unknown) { + ObjectKey key = { info.kind, info.reference }; + + ObjectInfo temp = tempLocals.get(key); + if (temp.mode == TargetMode::RefUnboxingRequired) { + return temp; + } + } + + return info; +} + ObjectInfo Compiler::ExprScope::mapGlobal(ustr_t globalReference) { NamespaceScope* nsScope = Scope::getScope(*this, ScopeLevel::Namespace); @@ -1768,7 +1795,10 @@ ObjectInfo Compiler::InlineClassScope::mapIdentifier(ustr_t identifier, bool ref else { Outer outer = outers.get(identifier); if (outer.reference != INVALID_REF) { - return { ObjectKind::Outer, outer.outerObject.typeInfo, outer.reference, outer.outerObject.reference }; + if (outer.outerObject.kind == ObjectKind::TempLocal && outer.outerObject.mode == TargetMode::RefUnboxingRequired) { + return { ObjectKind::OuterField, outer.outerObject.typeInfo, outer.reference, TargetMode::RefUnboxingRequired }; + } + else return { ObjectKind::Outer, outer.outerObject.typeInfo, outer.reference, outer.outerObject.reference }; } else { outer.outerObject = parent->mapIdentifier(identifier, referenceOne, attr); @@ -1784,6 +1814,7 @@ ObjectInfo Compiler::InlineClassScope::mapIdentifier(ustr_t identifier, bool ref case ObjectKind::Param: case ObjectKind::ParamAddress: case ObjectKind::Local: + case ObjectKind::TempLocal: case ObjectKind::Outer: case ObjectKind::OuterField: case ObjectKind::OuterSelf: @@ -1802,6 +1833,10 @@ ObjectInfo Compiler::InlineClassScope::mapIdentifier(ustr_t identifier, bool ref if (outer.outerObject.kind == ObjectKind::OuterSelf) { return { ObjectKind::OuterSelf, outer.outerObject.typeInfo, outer.reference }; } + else if (outer.outerObject.kind == ObjectKind::TempLocal && outer.outerObject.mode == TargetMode::RefUnboxingRequired) { + // NOTE : recognize the updatable captured variable + return { ObjectKind::OuterField, outer.outerObject.typeInfo, outer.reference, TargetMode::RefUnboxingRequired }; + } else return { ObjectKind::Outer, outer.outerObject.typeInfo, outer.reference }; } case ObjectKind::Unknown: @@ -1822,25 +1857,30 @@ ObjectInfo Compiler::InlineClassScope::mapIdentifier(ustr_t identifier, bool ref bool Compiler::InlineClassScope::markAsPresaved(ObjectInfo object) { - if (object.kind == ObjectKind::Outer) { + if (object.kind == ObjectKind::Outer || (object.kind == ObjectKind::OuterField && object.mode == TargetMode::RefUnboxingRequired)) { auto it = outers.start(); while (!it.eof()) { if ((*it).reference == object.reference) { - if ((*it).outerObject.kind == ObjectKind::Local || (*it).outerObject.kind == ObjectKind::LocalAddress) { - (*it).updated = true; - - return true; - } - else if ((*it).outerObject.kind == ObjectKind::Outer) { - InlineClassScope* closure = (InlineClassScope*)parent->getScope(Scope::ScopeLevel::Class); - if (closure->markAsPresaved((*it).outerObject)) { + switch ((*it).outerObject.kind) { + case ObjectKind::Local: + case ObjectKind::TempLocal: + case ObjectKind::LocalAddress: (*it).updated = true; return true; + case ObjectKind::Outer: + { + InlineClassScope* closure = (InlineClassScope*)parent->getScope(Scope::ScopeLevel::Class); + if (closure->markAsPresaved((*it).outerObject)) { + (*it).updated = true; + + return true; + } + else return false; } - else return false; + default: + break; } - break; } it++; @@ -5089,6 +5129,11 @@ void Compiler::declareTemplate(TemplateScope& scope, SyntaxNode& node) saveTemplate(scope, node); +#ifdef FULL_OUTOUT_INFO + _presenter->print("\nSyntax tree:\n"); + printTree(_presenter, node); +#endif + node.setKey(SyntaxKey::Idle); } @@ -6804,7 +6849,7 @@ ObjectInfo Compiler::mapConstant(Scope& scope, SyntaxNode node) ObjectInfo Compiler::mapIntConstant(Scope& scope, SyntaxNode node, int radix) { - int integer = StrConvertor::toInt(node.identifier(), radix); + int integer = node.identifier().empty() ? 0 : StrConvertor::toInt(node.identifier(), radix); if (errno == ERANGE) scope.raiseError(errInvalidIntNumber, node); @@ -11044,6 +11089,11 @@ bool Compiler::Class::isParentDeclared(SyntaxNode node) void Compiler::Class::declare(SyntaxNode node) { +#ifdef FULL_OUTOUT_INFO + compiler->_presenter->print("\nSyntax tree:\n"); + printTree(compiler->_presenter, node); +#endif + bool extensionDeclaration = isExtensionDeclaration(node); resolveClassPostfixes(node, extensionDeclaration); @@ -11370,6 +11420,45 @@ ObjectInfo Compiler::Expression::compileSymbolRoot(SyntaxNode bodyNode, EAttr mo return retVal; } +inline int countClosures(SyntaxNode node) +{ + SyntaxNode current = node.firstChild(); + int counter = 0; + while (current != SyntaxKey::None) { + switch (current.key) { + case SyntaxKey::Expression: + case SyntaxKey::Object: + case SyntaxKey::MessageOperation: + case SyntaxKey::PropertyOperation: + counter += countClosures(current); + break; + case SyntaxKey::NestedBlock: + case SyntaxKey::ClosureBlock: + case SyntaxKey::LazyOperation: + counter++; + break; + default: + break; + } + + current = current.nextNode(); + } + + return counter; +} + +inline bool isClosureConflictExpected(SyntaxNode node) +{ + SyntaxNode current = node == SyntaxKey::Expression ? node.firstChild() : node; + switch (current.key) { + case SyntaxKey::MessageOperation: + case SyntaxKey::PropertyOperation: + return countClosures(current) > 1; + default: + return false; + } +} + ObjectInfo Compiler::Expression::compileRoot(SyntaxNode node, EAttr mode) { SyntaxNode current = node.firstChild(); @@ -11384,6 +11473,12 @@ ObjectInfo Compiler::Expression::compileRoot(SyntaxNode node, EAttr mode) Compiler::addBreakpoint(*writer, findObjectNode(node), BuildKey::Breakpoint); } + if (isClosureConflictExpected(node)) { + scope.trackingClosureLocals = true; + + mode = mode | EAttr::LookaheadExprMode; + } + auto retVal = compile(node, 0, mode, nullptr); //if (isBoxingRequired(retVal)) { @@ -11723,6 +11818,19 @@ ObjectInfo Compiler::Expression :: compileObject(SyntaxNode node, ExpressionAttr else return compile(node, 0, mode, updatedOuterArgs); } +void Compiler::Expression :: prepareConflictResolution() +{ + scope.trackingClosureLocals = false; + + for (auto it = scope.trackingLocals.start(); !it.eof(); ++it) { + if ((*it).mode == TrackingMode::Updated) { + ObjectInfo local = { it.key().value1, (*it).typeInfo, it.key().value2 }; + + scope.tempLocals.add(it.key(), boxRefArgumentInPlace(local)); + } + } +} + ObjectInfo Compiler::Expression::compileLookAhead(SyntaxNode node, ref_t targetRef, ExpressionAttribute mode) { BuildNode lastNode = writer->CurrentNode().lastChild(); @@ -11741,8 +11849,11 @@ ObjectInfo Compiler::Expression::compileLookAhead(SyntaxNode node, ref_t targetR break; } - if (!targetRef && compiler->_logic->isEmbeddable(*scope.moduleScope, retVal.typeInfo.typeRef)) { - targetRef = retVal.typeInfo.typeRef; + bool overrideTarget = !targetRef && compiler->_logic->isEmbeddable(*scope.moduleScope, retVal.typeInfo.typeRef); + if (overrideTarget || scope.unboxingConflictFound) { + if (overrideTarget) + targetRef = retVal.typeInfo.typeRef; + // bad luck, we must rollback the changes and compile again lastNode = lastNode.nextNode(); while (lastNode != BuildKey::None) { @@ -11751,6 +11862,10 @@ ObjectInfo Compiler::Expression::compileLookAhead(SyntaxNode node, ref_t targetR lastNode = lastNode.nextNode(); } + if (scope.unboxingConflictFound) { + prepareConflictResolution(); + } + switch (node.key) { case SyntaxKey::MessageOperation: retVal = compileMessageOperation(node, targetRef, mode); @@ -13437,6 +13552,22 @@ void Compiler::Expression :: compileNestedInitializing(InlineClassScope& classSc break; } + // HOTFIX : tracking possible conflict with closure unwrapping + bool needToBeTracked = arg.kind == ObjectKind::Local && scope.trackingClosureLocals; + if (needToBeTracked) { + ObjectKey key = { arg.kind, arg.reference }; + + TrackingMode trackInfo = scope.trackingLocals.get(key).mode; + if (((*it).updated && trackInfo != TrackingMode::None) + || trackInfo == TrackingMode::Updated) + { + scope.unboxingConflictFound = true; + } + + scope.trackingLocals.erase(key); + scope.trackingLocals.add(key, { arg.typeInfo, (*it).updated ? TrackingMode::Updated : TrackingMode::Captched }); + } + if (updatedOuterArgs && (*it).updated) { if (!preservedContext) { updatedOuterArgs->add({ ObjectKind::ContextInfo }); @@ -14240,7 +14371,7 @@ ObjectInfo Compiler::Expression::boxArgumentLocally(ObjectInfo info, } } -ObjectInfo Compiler::Expression::unboxArguments(ObjectInfo retVal, ArgumentsInfo* updatedOuterArgs) +ObjectInfo Compiler::Expression :: unboxArguments(ObjectInfo retVal, ArgumentsInfo* updatedOuterArgs) { // unbox the arguments if required bool resultSaved = false; @@ -14266,9 +14397,18 @@ ObjectInfo Compiler::Expression::unboxArguments(ObjectInfo retVal, ArgumentsInfo unboxArgumentLocaly(temp, key); } else if (temp.mode == TargetMode::RefUnboxingRequired) { - temp.kind = ObjectKind::Local; + if (temp.kind == ObjectKind::LocalReference) { + temp.kind = ObjectKind::Local; - compileAssigningOp({ ObjectKind::Local, temp.typeInfo, key.value2 }, temp, dummy); + compileAssigningOp({ ObjectKind::Local, temp.typeInfo, key.value2 }, temp, dummy); + } + else { + writeObjectInfo(temp); + writer->appendNode(BuildKey::Field); + compileAssigningOp( + { ObjectKind::Local, temp.typeInfo, key.value2 }, + { ObjectKind::Object, temp.typeInfo, 0 }, dummy); + } } else if (key.value1 == ObjectKind::RefLocal) { writeObjectInfo(temp); @@ -14413,7 +14553,12 @@ bool Compiler::Expression::compileAssigningOp(ObjectInfo target, ObjectInfo expr fieldMode = true; break; case ObjectKind::OuterField: - scope.markAsAssigned(target); + if (target.mode == TargetMode::RefUnboxingRequired) { + InlineClassScope* closure = Scope::getScope(scope, Scope::ScopeLevel::Class); + if (!closure->markAsPresaved(target)) + return false; + } + else scope.markAsAssigned(target); operationType = BuildKey::FieldAssigning; operand = target.extra; fieldFieldMode = fieldMode = true; @@ -14585,8 +14730,31 @@ ObjectInfo Compiler::Expression::compileBranchingOperation(SyntaxNode node, Obje else { context.weakMessage = compiler->resolveOperatorMessage(scope.moduleScope, operatorId); + // HOTFIX : to deal with conflicting unboxing captured locals + scope.trackingClosureLocals = true; + BuildNode lastNode = writer->CurrentNode().lastChild(); + roperand = compileClosure(rnode, 0, EAttr::None, updatedOuterArgs); roperand2 = compileClosure(r2node, 0, EAttr::None, updatedOuterArgs); + + scope.trackingClosureLocals = false; + if (scope.unboxingConflictFound) { + // bad luck, we have to rollback the latest changes and compile them again + lastNode = lastNode.nextNode(); + while (lastNode != BuildKey::None) { + lastNode.setKey(BuildKey::Idle); + + lastNode = lastNode.nextNode(); + } + + prepareConflictResolution(); + updatedOuterArgs->clear(); + + roperand = compileClosure(rnode, 0, EAttr::None, updatedOuterArgs); + roperand2 = compileClosure(r2node, 0, EAttr::None, updatedOuterArgs); + + scope.unboxingConflictFound = false; + } } ArgumentsInfo messageArguments; @@ -15325,7 +15493,7 @@ ObjectInfo Compiler::Expression::boxArgument(ObjectInfo info, bool stackSafe, bo retVal = boxArgumentInPlace(info, targetRef); } - else retVal = boxRefArgumentInPlace(info, targetRef); + else retVal = boxRefArgumentLocallyInPlace(info, targetRef); if (!boxInPlace) scope.tempLocals.add(key, retVal); @@ -15483,7 +15651,7 @@ void Compiler::Expression::unboxOuterArgs(ArgumentsInfo* updatedOuterArgs) closure.extra = info.reference; compileAssigningOp(source, closure, dummy); } - else if (source.kind == ObjectKind::Outer) { + else if (source.kind == ObjectKind::Outer || (source.kind == ObjectKind::TempLocal && source.mode == TargetMode::RefUnboxingRequired)) { // ignore outer fields } else assert(false); @@ -15625,7 +15793,7 @@ ObjectInfo Compiler::Expression::boxArgumentInPlace(ObjectInfo info, ref_t targe return tempLocal; } -ObjectInfo Compiler::Expression::boxRefArgumentInPlace(ObjectInfo info, ref_t targetRef) +ObjectInfo Compiler::Expression :: boxRefArgumentLocallyInPlace(ObjectInfo info, ref_t targetRef) { bool dummy = false; ref_t typeRef = targetRef; @@ -15643,6 +15811,32 @@ ObjectInfo Compiler::Expression::boxRefArgumentInPlace(ObjectInfo info, ref_t ta return tempLocal; } +ObjectInfo Compiler::Expression :: boxRefArgumentInPlace(ObjectInfo info, ref_t targetRef) +{ + bool dummy = false; + ref_t typeRef = targetRef; + if (!typeRef) + typeRef = compiler->resolveStrongType(scope, info.typeInfo); + + ObjectInfo tempLocal = declareTempLocal(typeRef); + tempLocal.mode = TargetMode::RefUnboxingRequired; + + info.kind = ObjectKind::TempLocal; + + writeObjectInfo(info); + writer->appendNode(BuildKey::SavingInStack, 0); + + // create a wrapper + writer->newNode(BuildKey::CreatingClass, 1); + writer->appendNode(BuildKey::Type, scope.moduleScope->buildins.superReference); + writer->closeNode(); + writer->appendNode(BuildKey::FieldAssigning, 0); + + compileAssigningOp(tempLocal, { ObjectKind::Object }, dummy); + + return tempLocal; +} + ObjectInfo Compiler::Expression :: boxVariadicArgument(ObjectInfo info) { bool dummy = false; diff --git a/elenasrc3/elc/compiler.h b/elenasrc3/elc/compiler.h index 068a91f851..099c59cfdf 100644 --- a/elenasrc3/elc/compiler.h +++ b/elenasrc3/elc/compiler.h @@ -121,6 +121,13 @@ namespace elena_lang Weak, }; + enum class TrackingMode + { + None = 0, + Captched, + Updated + }; + enum DeclResult : int { Success = 0, @@ -249,8 +256,25 @@ namespace elena_lang } }; + struct ObjectTrackingInfo + { + TypeInfo typeInfo; + TrackingMode mode; + + ObjectTrackingInfo() + : typeInfo({}), mode(TrackingMode::None) + { + } + ObjectTrackingInfo(TypeInfo typeInfo, TrackingMode mode) + : typeInfo(typeInfo), mode(mode) + { + + } + }; + typedef Pair ObjectKey; - typedef MemoryMap, Map_GetKey> ObjectKeys; + typedef MemoryMap, Map_GetKey> ObjectKeyMap; + typedef Map ObjectTrackingMap; typedef CachedList TemplateTypeList; struct Parameter @@ -967,7 +991,10 @@ namespace elena_lang struct ExprScope : Scope { - ObjectKeys tempLocals; + bool trackingClosureLocals; + bool unboxingConflictFound; + ObjectKeyMap tempLocals; + ObjectTrackingMap trackingLocals; // is used to keep track of used in the closure local variables (when trackingClosureLocals is on) pos_t allocatedArgs; pos_t tempAllocated1; @@ -1015,6 +1042,7 @@ namespace elena_lang else return {}; } + ObjectInfo mapIdentifier(ustr_t identifier, bool referenceOne, ExpressionAttribute attr) override; ObjectInfo mapMember(ustr_t identifier) override; ObjectInfo mapGlobal(ustr_t globalReference) override; @@ -1318,6 +1346,8 @@ namespace elena_lang bool checkValidity(ObjectInfo target, CheckMethodResult& result, bool allowPrivateCall); bool checkValidity(ObjectInfo target, MessageResolution& resolution, bool allowPrivateCall); + void prepareConflictResolution(); + ObjectInfo compileLookAhead(SyntaxNode node, ref_t targetRef, ExpressionAttribute attrs); @@ -1396,6 +1426,7 @@ namespace elena_lang ObjectInfo boxLocally(ObjectInfo info, bool stackSafe); ObjectInfo boxPtrLocally(ObjectInfo info); ObjectInfo boxArgumentInPlace(ObjectInfo info, ref_t targetRef = 0); + ObjectInfo boxRefArgumentLocallyInPlace(ObjectInfo info, ref_t targetRef = 0); ObjectInfo boxRefArgumentInPlace(ObjectInfo info, ref_t targetRef = 0); ObjectInfo boxVariadicArgument(ObjectInfo info); diff --git a/elenasrc3/elc/compiling.cpp b/elenasrc3/elc/compiling.cpp index 363e2b8d20..6c54df8c21 100644 --- a/elenasrc3/elc/compiling.cpp +++ b/elenasrc3/elc/compiling.cpp @@ -326,7 +326,8 @@ CompilingProcess :: CompilingProcess(path_t appPath, path_t exeExtension, ) : _appPath(appPath), _templateGenerator(this), - _forwards(nullptr) + _forwards(nullptr), + _parser(nullptr) { _exeExtension = exeExtension; _modulePrologName = modulePrologName; @@ -688,7 +689,7 @@ void CompilingProcess :: compile(ProjectBase& project, LexicalMap::Iterator lexical_it = project.getLexicalIterator(); compiled |= buildModule( - env, + env, lexical_it, *module_it, &syntaxTree, &project, moduleSettings, @@ -706,6 +707,10 @@ void CompilingProcess :: compile(ProjectBase& project, void CompilingProcess :: link(Project& project, LinkerBase& linker, bool withTLS) { + // ignore link operation for trace mode + if (project.BoolSetting(ProjectOption::TracingMode)) + return; + PlatformType uiType = project.UITargetType(); _presenter->print(ELC_LINKING); @@ -763,7 +768,10 @@ void CompilingProcess :: cleanUp(ProjectBase& project) _libraryProvider.resolvePath(module_it->name(), path); // remove a module - PathUtil::removeFile(*path); + if (!PathUtil::removeFile(*path) && _verbose) { + if (PathUtil::ifExist(*path)) + _presenter->printPath("cannot remove file %s\n", *path); + } // remove a debug module path.changeExtension("dnl"); @@ -895,3 +903,107 @@ int CompilingProcess :: build(Project& project, return ERROR_RET_CODE; } } + +// --- CommandHelper --- + +void CommandHelper :: handleOption(ustr_t arg, IdentifierString& profile, Project& project, CompilingProcess& process, + ErrorProcessor& errorProcessor, bool& cleanMode) +{ + switch (arg[1]) { + case 'e': + if (arg.compare("-el5")) { + project.setSyntaxVersion(SyntaxVersion::L5); + } + else if (arg.compare("-el6")) { + project.setSyntaxVersion(SyntaxVersion::L6); + } + break; + case 'f': + process.addForward(arg + 2); + break; + case 'l': + profile.copy(arg + 2); + break; + case 'm': + project.addBoolSetting(ProjectOption::MappingOutputMode, true); + break; + case 'o': + if (arg[2] == '0') { + project.addIntSetting(ProjectOption::OptimizationMode, optNone); + } + else if (arg[2] == '1') { + project.addIntSetting(ProjectOption::OptimizationMode, optLow); + } + else if (arg[2] == '2') { + project.addIntSetting(ProjectOption::OptimizationMode, optMiddle); + } + else if (arg[2] == '3') { + project.addIntSetting(ProjectOption::OptimizationMode, optHigh); + } + break; + case 'p': + { + PathString path(arg + 2); + + project.setBasePath(*path); + break; + } + case 'r': + cleanMode = true; + break; + case 's': + { + ustr_t setting = arg + 2; + if (setting.compareSub("stackReserv:", 0, 12)) { + ustr_t valStr = setting + 12; + int val = StrConvertor::toInt(valStr, 10); + project.addIntSetting(ProjectOption::StackReserved, val); + } + break; + } + case 'v': + process.setVerboseOn(); + break; + case 'w': + if (arg[2] == '0') { + errorProcessor.setWarningLevel(WarningLevel::Level0); + } + else if (arg[2] == '1') { + errorProcessor.setWarningLevel(WarningLevel::Level1); + } + else if (arg[2] == '2') { + errorProcessor.setWarningLevel(WarningLevel::Level2); + } + else if (arg[2] == '3') { + errorProcessor.setWarningLevel(WarningLevel::Level3); + } + break; + case 'x': + if (arg[2] == 'b') { + project.addBoolSetting(ProjectOption::ConditionalBoxing, arg[3] != '-'); + } + else if (arg[2] == 'e') { + project.addBoolSetting(ProjectOption::EvaluateOp, arg[3] != '-'); + } + else if (arg[2] == 'j') { + project.addBoolSetting(ProjectOption::WithJumpAlignment, arg[3] != '-'); + } + else if (arg[2] == 'm') { + project.addBoolSetting(ProjectOption::ModuleExtensionAutoLoad, arg[3] != '-'); + } + else if (arg[2] == 'p') { + project.addBoolSetting(ProjectOption::GenerateParamNameInfo, arg[3] != '-'); + } + else if (arg[2] == 's') { + project.addBoolSetting(ProjectOption::StrictTypeEnforcing, arg[3] != '-'); + } + break; + case '-': + if (arg.compare("--tracing")) { + project.addBoolSetting(ProjectOption::TracingMode, true); + } + break; + default: + break; + } +} diff --git a/elenasrc3/elc/compiling.h b/elenasrc3/elc/compiling.h index e88a798e52..5ab42ac70f 100644 --- a/elenasrc3/elc/compiling.h +++ b/elenasrc3/elc/compiling.h @@ -169,6 +169,13 @@ namespace elena_lang freeobj(_compiler); } }; + + class CommandHelper + { + public: + static void handleOption(ustr_t arg, IdentifierString& profile, Project& project, CompilingProcess& process, + ErrorProcessor& errorProcessor, bool& cleanMode); + }; } #endif // COMPLING_H diff --git a/elenasrc3/elc/linux/elc.cpp b/elenasrc3/elc/linux/elc.cpp index bd5e0930cc..68a51910f9 100644 --- a/elenasrc3/elc/linux/elc.cpp +++ b/elenasrc3/elc/linux/elc.cpp @@ -3,7 +3,7 @@ // // This file contains the main body of the Linux command-line compiler // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -160,168 +160,161 @@ JITCompilerBase* createJITCompiler(LibraryLoaderBase* loader, PlatformType platf } } +void handleOption(char* arg, IdentifierString& profile, Project& project, CompilingProcess& process, + ErrorProcessor& errorProcessor, path_t dataPath, bool& cleanMode) +{ + switch (arg[1]) { + case 't': + { + IdentifierString configName(arg + 2); + + project.loadConfigByName(dataPath, *configName, true); + break; + } + case 'p': + project.setBasePath(arg + 2); + break; + default: + { + IdentifierString argStr(arg); + + CommandHelper::handleOption(*argStr, profile, project, process, errorProcessor, cleanMode); + break; + } + } +} + +int compileProject(int argc, char** argv, path_t dataPath, ErrorProcessor& errorProcessor, + CompilingProcess& process) +{ + bool cleanMode = false; + + Project project(dataPath, CURRENT_PLATFORM, &Presenter::getInstance()); + LinuxLinker linker(&errorProcessor, &LinuxImageFormatter::getInstance(&project)); + + // Initializing... + path_t defaultConfigPath = PathHelper::retrieveFilePath(LOCAL_DEFAULT_CONFIG); + if (defaultConfigPath.compare(LOCAL_DEFAULT_CONFIG)) { + // if the local config file was not found + defaultConfigPath = DEFAULT_CONFIG; + } + + PathString configPath(dataPath, PathHelper::retrieveFilePath(defaultConfigPath)); + project.loadConfig(*configPath, nullptr, false); + + IdentifierString profile; + for (int i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + handleOption(argv[i], profile, project, process, + errorProcessor, dataPath, cleanMode); + } + else if (PathUtil::checkExtension(argv[i], "prj")) { + PathString path(argv[i]); + if (!project.loadProject(*path, *profile)) { + return ERROR_RET_CODE; + } + + if (profile.empty() && project.availableProfileList.count() != 0) { + IdentifierString profileList; + for (auto it = project.availableProfileList.start(); !it.eof(); ++it) { + if (profileList.length() != 0) + profileList.append(", "); + + profileList.append(*it); + } + + Presenter::getInstance().printLine(ELC_PROFILE_WARNING, *profileList); + } + } + else if (PathUtil::checkExtension(argv[i], "prjcol")) { + Presenter::getInstance().printLine(ELC_PRJ_COLLECTION_WARNING); + return -2; + } + else { + FileNameString fileName(argv[i]); + + project.addSource(*fileName, argv[i], nullptr, nullptr); + } + } + + if (cleanMode) { + return process.clean(project); + } + else { + // Building... + return process.build(project, linker, + DEFAULT_STACKALIGNMENT, + DEFAULT_RAW_STACKALIGNMENT, + DEFAULT_EHTABLE_ENTRY_SIZE, + MINIMAL_ARG_LIST, + *profile); + } +} + +int compileProjectCollection(int argc, char** argv, path_t path, path_t dataPath, + ErrorProcessor& errorProcessor, CompilingProcess& process) +{ + Presenter* presenter = &Presenter::getInstance(); + + int retVal = 0; + ProjectCollection collection; + + if (!collection.load(path)) { + presenter->printPath(presenter->getMessage(wrnInvalidConfig), path); + + return ERROR_RET_CODE; + } + + for (auto it = collection.paths.start(); !it.eof(); ++it) { + size_t destLen = FILENAME_MAX; + char projectPath[FILENAME_MAX]; + StrConvertor::copy(projectPath, (*it).str(), (*it).length(), destLen); + projectPath[destLen] = 0; + + argv[argc - 1] = projectPath; + presenter->printPath(ELC_COMPILING_PROJECT, projectPath); + + int result = compileProject(argc, argv, dataPath, errorProcessor, process); + if (result == ERROR_RET_CODE) { + return ERROR_RET_CODE; + } + else if (result == WARNING_RET_CODE) { + retVal = WARNING_RET_CODE; + } + } + + return retVal; +} + const char* dataFileList[] = { BC_RULES_FILE, BT_RULES_FILE, SYNTAX60_FILE }; int main(int argc, char* argv[]) { try { - bool cleanMode = false; - PathString dataPath(PathHelper::retrievePath(dataFileList, 3, DATA_PATH)); JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_STACKRESERV, 1, true, true }; ErrorProcessor errorProcessor(&Presenter::getInstance()); - Project project(*dataPath, CURRENT_PLATFORM, &Presenter::getInstance()); - LinuxLinker linker(&errorProcessor, &LinuxImageFormatter::getInstance(&project)); CompilingProcess process(*dataPath, nullptr, "", "", "", &Presenter::getInstance(), &errorProcessor, VA_ALIGNMENT, defaultCoreSettings, createJITCompiler); process.greeting(); - // Initializing... - path_t defaultConfigPath = PathHelper::retrieveFilePath(LOCAL_DEFAULT_CONFIG); - if (defaultConfigPath.compare(LOCAL_DEFAULT_CONFIG)) { - // if the local config file was not found - defaultConfigPath = DEFAULT_CONFIG; - } - - PathString configPath(*dataPath, PathHelper::retrieveFilePath(defaultConfigPath)); - project.loadConfig(*configPath, nullptr, false); - - // Reading command-line arguments... + // Reading command-line arguments... if (argc < 2) { Presenter::getInstance().printLine(ELC_HELP_INFO); - return -3; - } - - IdentifierString profile; - for (int i = 1; i < argc; i++) { - if (argv[i][0] == '-') { - switch (argv[i][1]) { - case 'f': - { - IdentifierString setting(argv[i] + 2); - process.addForward(*setting); - - break; - } - case 'l': - profile.copy(argv[i] + 2); - break; - case 'm': - project.addBoolSetting(ProjectOption::MappingOutputMode, true); - break; - case 'o': - if (argv[i][2] == '0') { - project.addIntSetting(ProjectOption::OptimizationMode, optNone); - } - else if (argv[i][2] == '1') { - project.addIntSetting(ProjectOption::OptimizationMode, optLow); - } - else if (argv[i][2] == '2') { - project.addIntSetting(ProjectOption::OptimizationMode, optMiddle); - } - else if (argv[i][2] == '3') { - project.addIntSetting(ProjectOption::OptimizationMode, optHigh); - } - break; - case 'p': - project.setBasePath(argv[i] + 2); - break; - case 'r': - cleanMode = true; - break; - case 's': - { - IdentifierString setting(argv[i] + 2); - if (setting.compare("stackReserv:", 0, 12)) { - ustr_t valStr = *setting + 12; - int val = StrConvertor::toInt(valStr, 10); - project.addIntSetting(ProjectOption::StackReserved, val); - } - break; - } - case 't': - { - IdentifierString configName(argv[i] + 2); - - project.loadConfigByName(*dataPath, *configName, true); - break; - } - case 'v': - process.setVerboseOn(); - break; - case 'w': - if (argv[i][2] == '0') { - errorProcessor.setWarningLevel(WarningLevel::Level0); - } - else if (argv[i][2] == '1') { - errorProcessor.setWarningLevel(WarningLevel::Level1); - } - else if (argv[i][2] == '2') { - errorProcessor.setWarningLevel(WarningLevel::Level2); - } - else if (argv[i][2] == '3') { - errorProcessor.setWarningLevel(WarningLevel::Level3); - } - break; - case 'x': - if (argv[i][2] == 'b') { - project.addBoolSetting(ProjectOption::ConditionalBoxing, argv[i][3] != '-'); - } - else if (argv[i][2] == 'e') { - project.addBoolSetting(ProjectOption::EvaluateOp, argv[i][3] != '-'); - } - else if (argv[i][2] == 'p') { - project.addBoolSetting(ProjectOption::GenerateParamNameInfo, argv[i][3] != '-'); - } - break; - default: - break; - } - } - else if (PathUtil::checkExtension(argv[i], "project")) { - PathString path(argv[i]); - - if (!project.loadProject(*path, *profile)) { - errorProcessor.raisePathError(errProjectAlreadyLoaded, *path); - } - else if (profile.empty() && project.availableProfileList.count() != 0) { - IdentifierString profileList; - for (auto it = project.availableProfileList.start(); !it.eof(); ++it) { - if (profileList.length() != 0) - profileList.append(", "); - - profileList.append(*it); - } - - Presenter::getInstance().printLine(ELC_PROFILE_WARNING, *profileList); - } - } - else { - FileNameString fileName(argv[i]); - - project.addSource(*fileName, argv[i], nullptr, nullptr); - } - } - - if (cleanMode) { - return process.clean(project); + return -2; } - else { - // Building... - return process.build(project, linker, - DEFAULT_STACKALIGNMENT, - DEFAULT_RAW_STACKALIGNMENT, - DEFAULT_EHTABLE_ENTRY_SIZE, - MINIMAL_ARG_LIST, - *profile); + else if (argv[argc - 1][0] != '-' && PathUtil::checkExtension(argv[argc - 1], "prjcol")) { + return compileProjectCollection(argc, argv, argv[argc - 1], + *dataPath, errorProcessor, process); } + else return compileProject(argc, argv, *dataPath, errorProcessor, process); } - catch (CLIException e) + catch (CLIException) { - return -2; + return ERROR_RET_CODE; } } diff --git a/elenasrc3/elc/linux/elfarmimage.h b/elenasrc3/elc/linux/elfarmimage.h index d30ff8c49c..adb41afb7d 100644 --- a/elenasrc3/elc/linux/elfarmimage.h +++ b/elenasrc3/elc/linux/elfarmimage.h @@ -6,8 +6,8 @@ // (C)2021-2023, by Aleksey Rakov //--------------------------------------------------------------------------- -#ifndef ELFPPCIMAGE_H -#define ELFPPCIMAGE_H +#ifndef ELFARMIMAGE_H +#define ELFARMIMAGE_H #include "elfimage.h" diff --git a/elenasrc3/elc/macos/elc.cpp b/elenasrc3/elc/macos/elc.cpp new file mode 100644 index 0000000000..8d31208b39 --- /dev/null +++ b/elenasrc3/elc/macos/elc.cpp @@ -0,0 +1,251 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA command-Line Compiler +// +// This file contains the main body of the macOS command-line compiler +// +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "elena.h" +// -------------------------------------------------------------------------- +#include "cliconst.h" +#include "compiling.h" +#include "project.h" +//#include "elfimage.h" + +#if defined(__aarch64__) + +//#include "elfarmlinker64.h" +//#include "arm64compiler.h" +//#include "elfarmimage.h" + +#endif + +#include "constants.h" +#include "messages.h" +#include "linux/presenter.h" +//#include "linux/pathmanager.h" + +#include + +using namespace elena_lang; + +#if defined(__aarch64__) + +constexpr auto CURRENT_PLATFORM = PlatformType::MacOS_ARM64; + +constexpr int MINIMAL_ARG_LIST = 2; + +constexpr auto DEFAULT_STACKALIGNMENT = 2; +constexpr auto DEFAULT_RAW_STACKALIGNMENT = 16; +constexpr auto DEFAULT_EHTABLE_ENTRY_SIZE = 32; + +typedef MachOARM64Linker MacOSLinker; +typedef MachOARM64ImageFormatter MacOSImageFormatter; + +#endif + +constexpr int DEFAULT_MGSIZE = 688128; +constexpr int DEFAULT_YGSIZE = 204800; +constexpr int DEFAULT_STACKRESERV = 0x100000; + +class Presenter : public LinuxConsolePresenter +{ +public: + ustr_t getMessage(int code) + { + for(size_t i = 0; i < MessageLength; i++) { + if (Messages[i].value1 == code) + return Messages[i].value2; + } + + return errMsgUnrecognizedError; + } + + static Presenter& getInstance() + { + static Presenter instance; + + return instance; + } + +private: + Presenter() = default; + +public: + Presenter(Presenter const&) = delete; + void operator=(Presenter const&) = delete; + + ~Presenter() = default; +}; + +JITCompilerBase* createJITCompiler(LibraryLoaderBase* loader, PlatformType platform) +{ + switch (platform) { +#if defined(__aarch64__) + case PlatformType::MacOS_ARM64: + return new ARM64JITCompiler(); +#endif + default: + return nullptr; + } +} + +void handleOption(char* arg, IdentifierString& profile, Project& project, CompilingProcess& process, + ErrorProcessor& errorProcessor, path_t dataPath, bool& cleanMode) +{ + switch (arg[1]) { + case 't': + { + IdentifierString configName(arg + 2); + + project.loadConfigByName(dataPath, *configName, true); + break; + } + case 'p': + project.setBasePath(arg + 2); + break; + default: + { + IdentifierString argStr(arg); + + CommandHelper::handleOption(*argStr, profile, project, process, errorProcessor, cleanMode); + break; + } + } +} + +int compileProject(int argc, char** argv, path_t dataPath, ErrorProcessor& errorProcessor, + CompilingProcess& process) +{ + bool cleanMode = false; + + Project project(dataPath, CURRENT_PLATFORM, &Presenter::getInstance()); + MacOSLinker linker(&errorProcessor, &MacOSImageFormatter::getInstance(&project)); + + // Initializing... + path_t defaultConfigPath /*= PathHelper::retrieveFilePath(LOCAL_DEFAULT_CONFIG)*/; +// if (defaultConfigPath.compare(LOCAL_DEFAULT_CONFIG)) { + // if the local config file was not found + defaultConfigPath = DEFAULT_CONFIG; +// } + + PathString configPath(dataPath, /*PathHelper::retrieveFilePath(*/defaultConfigPath/*)*/); + project.loadConfig(*configPath, nullptr, false); + + IdentifierString profile; + for (int i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + handleOption(argv[i], profile, project, process, + errorProcessor, dataPath, cleanMode); + } + else if (PathUtil::checkExtension(argv[i], "prj")) { + PathString path(argv[i]); + if (!project.loadProject(*path, *profile)) { + return ERROR_RET_CODE; + } + + if (profile.empty() && project.availableProfileList.count() != 0) { + IdentifierString profileList; + for (auto it = project.availableProfileList.start(); !it.eof(); ++it) { + if (profileList.length() != 0) + profileList.append(", "); + + profileList.append(*it); + } + + Presenter::getInstance().printLine(ELC_PROFILE_WARNING, *profileList); + } + } + else if (PathUtil::checkExtension(argv[i], "prjcol")) { + Presenter::getInstance().printLine(ELC_PRJ_COLLECTION_WARNING); + return -2; + } + else { + FileNameString fileName(argv[i]); + + project.addSource(*fileName, argv[i], nullptr, nullptr); + } + } + + if (cleanMode) { + return process.clean(project); + } + else { + // Building... + return process.build(project, linker, + DEFAULT_STACKALIGNMENT, + DEFAULT_RAW_STACKALIGNMENT, + DEFAULT_EHTABLE_ENTRY_SIZE, + MINIMAL_ARG_LIST, + *profile); + } +} + +int compileProjectCollection(int argc, char** argv, path_t path, path_t dataPath, + ErrorProcessor& errorProcessor, CompilingProcess& process) +{ + Presenter* presenter = &Presenter::getInstance(); + + int retVal = 0; + ProjectCollection collection; + + if (!collection.load(path)) { + presenter->printPath(presenter->getMessage(wrnInvalidConfig), path); + + return ERROR_RET_CODE; + } + + for (auto it = collection.paths.start(); !it.eof(); ++it) { + size_t destLen = FILENAME_MAX; + char projectPath[FILENAME_MAX]; + StrConvertor::copy(projectPath, (*it).str(), (*it).length(), destLen); + projectPath[destLen] = 0; + + argv[argc - 1] = projectPath; + presenter->printPath(ELC_COMPILING_PROJECT, projectPath); + + int result = compileProject(argc, argv, dataPath, errorProcessor, process); + if (result == ERROR_RET_CODE) { + return ERROR_RET_CODE; + } + else if (result == WARNING_RET_CODE) { + retVal = WARNING_RET_CODE; + } + } + + return retVal; +} + +//const char* dataFileList[] = { BC_RULES_FILE, BT_RULES_FILE, SYNTAX60_FILE }; + +int main(int argc, char* argv[]) +{ + try + { + PathString dataPath(/*PathHelper::retrievePath(dataFileList, 3, */DATA_PATH/*)*/); + + JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_STACKRESERV, 1, true, true }; + ErrorProcessor errorProcessor(&Presenter::getInstance()); + CompilingProcess process(*dataPath, nullptr, "", "", "", + &Presenter::getInstance(), &errorProcessor, + VA_ALIGNMENT, defaultCoreSettings, createJITCompiler); + + process.greeting(); + + // Reading command-line arguments... + if (argc < 2) { + Presenter::getInstance().printLine(ELC_HELP_INFO); + return -2; + } + else if (argv[argc - 1][0] != '-' && PathUtil::checkExtension(argv[argc - 1], "prjcol")) { + return compileProjectCollection(argc, argv, argv[argc - 1], + *dataPath, errorProcessor, process); + } + else return compileProject(argc, argv, *dataPath, errorProcessor, process); + } + catch (CLIException) + { + return ERROR_RET_CODE; + } +} diff --git a/elenasrc3/elc/macos/machoarmimage.cpp b/elenasrc3/elc/macos/machoarmimage.cpp new file mode 100644 index 0000000000..e37a3489e1 --- /dev/null +++ b/elenasrc3/elc/macos/machoarmimage.cpp @@ -0,0 +1,11 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This file contains ELENA Executive MachO Image class implementation +// supported platform: ARM64 +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "clicommon.h" +// -------------------------------------------------------------------------- +#include "machoarmimage.h" diff --git a/elenasrc3/elc/macos/machoarmimage.h b/elenasrc3/elc/macos/machoarmimage.h new file mode 100644 index 0000000000..3f8ffe8af1 --- /dev/null +++ b/elenasrc3/elc/macos/machoarmimage.h @@ -0,0 +1,45 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Executive MachO Image class declaration +// supported platform: ARM64 +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef ELFPPCIMAGE_H +#define ELFPPCIMAGE_H + +#include "machoimage.h" + +namespace elena_lang +{ + // --- ElfARM64ImageFormatter --- + class MachOARM64ImageFormatter : public MachO64ImageFormatter + { + MachOARM64ImageFormatter(ForwardResolverBase* resolver) + : MachO64ImageFormatter(resolver) + { + } + + //int getRelocationType() override; + + //void fillElfData(ImageProviderBase& provider, ElfData& elfData, pos_t fileAlignment, + // RelocationMap& importMapping) override; + + //void writePLTStartEntry(MemoryWriter& codeWriter, ref_t gotReference, pos_t disp) override; + //pos_t writePLTEntry(MemoryWriter& codeWriter, pos_t symbolIndex, ref_t gotReference, pos_t gofOffset, int entryIndex) override; + + //void fixSection(MemoryBase* section, AddressSpace& map) override; + //void fixImportSection(MemoryBase* section, AddressSpace& map) override; + + public: + static MachOARM64ImageFormatter& getInstance(ForwardResolverBase* resolver) + { + static MachOARM64ImageFormatter instance(resolver); + + return instance; + } + }; +} + +#endif \ No newline at end of file diff --git a/elenasrc3/elc/macos/machoarmlinker64.cpp b/elenasrc3/elc/macos/machoarmlinker64.cpp new file mode 100644 index 0000000000..1eab168a6c --- /dev/null +++ b/elenasrc3/elc/macos/machoarmlinker64.cpp @@ -0,0 +1,11 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Executive Linker class body +// Supported platforms: MacOS ARM64 +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "machoarmlinker64.h" + +using namespace elena_lang; diff --git a/elenasrc3/elc/macos/machoarmlinker64.h b/elenasrc3/elc/macos/machoarmlinker64.h new file mode 100644 index 0000000000..1e96073cd5 --- /dev/null +++ b/elenasrc3/elc/macos/machoarmlinker64.h @@ -0,0 +1,30 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Executive Linker class declaration +// Supported platforms: Linux ARM64 +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef MACHOARMLINKER64_H +#define MACHOARMLINKER64_H + +#include "macholinker64.h" + +namespace elena_lang +{ + // --- MachOARM64Linker --- + class MachOARM64Linker : public MachOLinker64 + { + protected: + + public: + MachOARM64Linker(ErrorProcessorBase* errorProcessor) + : MachOLinker64(errorProcessor) + { + + } + }; +} + +#endif diff --git a/elenasrc3/elc/macos/machoimage.cpp b/elenasrc3/elc/macos/machoimage.cpp new file mode 100644 index 0000000000..dbc7c5f4e6 --- /dev/null +++ b/elenasrc3/elc/macos/machoimage.cpp @@ -0,0 +1,22 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This file contains ELENA Executive MachO Image class implementation +// +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "clicommon.h" +// -------------------------------------------------------------------------- +#include "elfimage.h" +#include "elfcommon.h" + +using namespace elena_lang; + +// --- MachOImageFormatter --- + +void MachOImageFormatter:: prepareImage(ImageProviderBase& provider, AddressSpace& map, ImageSections& sections, + pos_t sectionAlignment, pos_t fileAlignment, bool withDebugInfo) +{ + // !! temporally stub +} diff --git a/elenasrc3/elc/macos/machoimage.h b/elenasrc3/elc/macos/machoimage.h new file mode 100644 index 0000000000..a42bdfb4e0 --- /dev/null +++ b/elenasrc3/elc/macos/machoimage.h @@ -0,0 +1,78 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Executive MachO Image class declaration +// supported platform: ARM64 +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef MACHOIMAGE_H +#define MACHOIMAGE_H + +namespace elena_lang +{ + //typedef List LibraryList; + + // --- MachOImageFormatter --- + class MachOImageFormatter : public ImageFormatter + { + protected: + ForwardResolverBase* _resolver; + + //struct ElfData + //{ + // ReferenceMap functions; + // LibraryList libraries; + + // pos_t dynamicOffset; + // pos_t dynamicSize; + + // ElfData() + // : functions(0), libraries(nullptr) + // { + // dynamicOffset = dynamicSize = 0; + // } + //}; + + MachOImageFormatter(ForwardResolverBase* resolver) + { + _resolver = resolver; + } + + //virtual pos_t fillImportTable(AddressMap::Iterator it, ElfData& elfData); + //virtual void fillElfData(ImageProviderBase& provider, ElfData& elfData, pos_t fileAlignment, RelocationMap& importMapping) = 0; + + //virtual void fixSection(MemoryBase* section, AddressSpace& map) = 0; + //virtual void fixImportSection(MemoryBase* section, AddressSpace& map) = 0; + + //void mapImage(ImageProviderBase& provider, AddressSpace& map, ImageSections& sections, pos_t sectionAlignment, + // pos_t fileAlignment, ElfData& elfData); + //void fixImage(ImageProviderBase& provider, AddressSpace& map, bool withDebugInfo); + + public: + void prepareImage(ImageProviderBase& provider, AddressSpace& map, ImageSections& sections, + pos_t sectionAlignment, pos_t fileAlignment, bool withDebugInfo) override; + }; + + // --- MachO64ImageFormatter --- + class MachO64ImageFormatter : public MachOImageFormatter + { + protected: + MachO64ImageFormatter(ForwardResolverBase* resolver) + : MachOImageFormatter(resolver) + { + + } + + //virtual void writePLTStartEntry(MemoryWriter& codeWriter, ref_t gotReference, pos_t disp) = 0; + //virtual pos_t writePLTEntry(MemoryWriter& codeWriter, pos_t symbolIndex, ref_t gotReference, pos_t gofOffset, int entryIndex) = 0; + + //virtual int getRelocationType() = 0; + + //void fillElfData(ImageProviderBase& provider, ElfData& elfData, pos_t fileAlignment, RelocationMap& importMapping) override; + public: + + }; +} + +#endif diff --git a/elenasrc3/elc/macos/macholinker.cpp b/elenasrc3/elc/macos/macholinker.cpp new file mode 100644 index 0000000000..cc5b3dee28 --- /dev/null +++ b/elenasrc3/elc/macos/macholinker.cpp @@ -0,0 +1,17 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This file contains ELENA Executive Linker class implementation +// Supported platforms: MacOS +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "macholinker.h" + +using namespace elena_lang; + +LinkResult MachOLinker :: run(ProjectBase& project, ImageProviderBase& provider, PlatformType, path_t) +{ + // !! temporal stub + return {}; +} \ No newline at end of file diff --git a/elenasrc3/elc/macos/macholinker.h b/elenasrc3/elc/macos/macholinker.h new file mode 100644 index 0000000000..f6a3cd1398 --- /dev/null +++ b/elenasrc3/elc/macos/macholinker.h @@ -0,0 +1,33 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Executive Linker class declaration +// Supported platforms: MacOS +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef MACHOLINKER_H +#define MACHOLINKER_H + +#include "clicommon.h" + +namespace elena_lang +{ + // --- ElfLinker --- + class MachOLinker : public LinkerBase + { + protected: + + public: + LinkResult run(ProjectBase& project, ImageProviderBase& code, PlatformType uiType, + path_t exeExtension) override; + + MachOLinker(ErrorProcessorBase* errorProcessor/*, ImageFormatter* imageFormatter*/) + : LinkerBase(errorProcessor) + { + _imageFormatter = imageFormatter; + } + }; +} + +#endif diff --git a/elenasrc3/elc/macos/macholinker64.cpp b/elenasrc3/elc/macos/macholinker64.cpp new file mode 100644 index 0000000000..4e9e44af8d --- /dev/null +++ b/elenasrc3/elc/macos/macholinker64.cpp @@ -0,0 +1,11 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Executive Linker class body +// Supported platforms: MacOS 64 +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "macholinker64.h" + +using namespace elena_lang; diff --git a/elenasrc3/elc/macos/macholinker64.h b/elenasrc3/elc/macos/macholinker64.h new file mode 100644 index 0000000000..6ee74b6e59 --- /dev/null +++ b/elenasrc3/elc/macos/macholinker64.h @@ -0,0 +1,30 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains ELENA Executive Linker class declaration +// Supported platforms: MacOS 64 +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef MACHOLINKER64_H +#define MACHOLINKER64_H + +#include "macholinker.h" + +namespace elena_lang +{ + // --- ElfLinker --- + class MachOLinker64 : public MachOLinker + { + protected: + + public: + MachOLinker64(ErrorProcessorBase* errorProcessor/*, ImageFormatter* imageFormatter*/) + : MachOLinker(errorProcessor) + { + _imageFormatter = imageFormatter; + } + }; +} + +#endif diff --git a/elenasrc3/elc/windows/elc.cpp b/elenasrc3/elc/windows/elc.cpp index 050995007a..90c4aa2ff1 100644 --- a/elenasrc3/elc/windows/elc.cpp +++ b/elenasrc3/elc/windows/elc.cpp @@ -3,7 +3,7 @@ // // This file contains the main body of the win32 / win64 command-line compiler // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include @@ -39,7 +39,7 @@ constexpr auto CURRENT_PLATFORM = PlatformType::Win_x86; constexpr int DEFAULT_MGSIZE = 344064; constexpr int DEFAULT_YGSIZE = 86016; -constexpr int DEFAULT_SACKRESERV = 0x200000; +constexpr int DEFAULT_STACKRESERV = 0x200000; constexpr int MINIMAL_ARG_LIST = 1; @@ -56,7 +56,7 @@ constexpr auto CURRENT_PLATFORM = PlatformType::Win_x86_64; constexpr int DEFAULT_MGSIZE = 688128; constexpr int DEFAULT_YGSIZE = 204800; -constexpr int DEFAULT_SACKRESERV = 0x200000; +constexpr int DEFAULT_STACKRESERV = 0x200000; constexpr int MINIMAL_ARG_LIST = 2; @@ -123,108 +123,22 @@ JITCompilerBase* createJITCompiler(LibraryLoaderBase* loader, PlatformType platf void handleOption(wchar_t* arg, IdentifierString& profile, Project& project, CompilingProcess& process, ErrorProcessor& errorProcessor, path_t appPath, bool& cleanMode) { - switch (arg[1]) { - case 'e': - if (wstr_t(arg).compare(L"-el5")) { - project.setSyntaxVersion(SyntaxVersion::L5); - } - else if (wstr_t(arg).compare(L"-el6")) { - project.setSyntaxVersion(SyntaxVersion::L6); - } - break; - case 'f': - { - IdentifierString setting(arg + 2); - process.addForward(*setting); - - break; - } - case 'l': - { - IdentifierString setting(arg + 2); - profile.copy(*setting); - break; - } - case 'm': - project.addBoolSetting(ProjectOption::MappingOutputMode, true); - break; - case 'o': - if (arg[2] == '0') { - project.addIntSetting(ProjectOption::OptimizationMode, optNone); - } - else if (arg[2] == '1') { - project.addIntSetting(ProjectOption::OptimizationMode, optLow); - } - else if (arg[2] == '2') { - project.addIntSetting(ProjectOption::OptimizationMode, optMiddle); - } - else if (arg[2] == '3') { - project.addIntSetting(ProjectOption::OptimizationMode, optHigh); - } - break; - case 'p': - project.setBasePath(arg + 2); - break; - case 'r': - cleanMode = true; - break; - case 's': - { - IdentifierString setting(arg + 2); - if (setting.compare("stackReserv:", 0, 12)) { - ustr_t valStr = *setting + 12; - int val = StrConvertor::toInt(valStr, 10); - project.addIntSetting(ProjectOption::StackReserved, val); - } - break; - } + switch(arg[1]) { case 't': { IdentifierString configName(arg + 2); - if(!project.loadConfigByName(appPath, *configName, true)) + if (!project.loadConfigByName(appPath, *configName, true)) errorProcessor.info(wrnInvalidConfig, *configName); break; } - case 'v': - process.setVerboseOn(); - break; - case 'w': - if (arg[2] == '0') { - errorProcessor.setWarningLevel(WarningLevel::Level0); - } - else if (arg[2] == '1') { - errorProcessor.setWarningLevel(WarningLevel::Level1); - } - else if (arg[2] == '2') { - errorProcessor.setWarningLevel(WarningLevel::Level2); - } - else if (arg[2] == '3') { - errorProcessor.setWarningLevel(WarningLevel::Level3); - } - break; - case 'x': - if (arg[2] == 'b') { - project.addBoolSetting(ProjectOption::ConditionalBoxing, arg[3] != '-'); - } - else if (arg[2] == 'e') { - project.addBoolSetting(ProjectOption::EvaluateOp, arg[3] != '-'); - } - else if (arg[2] == 'j') { - project.addBoolSetting(ProjectOption::WithJumpAlignment, arg[3] != '-'); - } - else if (arg[2] == 'm') { - project.addBoolSetting(ProjectOption::ModuleExtensionAutoLoad, arg[3] != '-'); - } - else if (arg[2] == 'p') { - project.addBoolSetting(ProjectOption::GenerateParamNameInfo, arg[3] != '-'); - } - else if (arg[2] == 's') { - project.addBoolSetting(ProjectOption::StrictTypeEnforcing, arg[3] != '-'); - } - break; default: + { + IdentifierString argStr(arg); + + CommandHelper::handleOption(*argStr, profile, project, process, errorProcessor, cleanMode); break; + } } } @@ -331,7 +245,7 @@ int main() PathString appPath; getAppPath(appPath); - JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_SACKRESERV, 1, true, true }; + JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_STACKRESERV, 1, true, true }; ErrorProcessor errorProcessor(&Presenter::getInstance()); CompilingProcess process(*appPath, L"exe", L"", L"", L"", &Presenter::getInstance(), &errorProcessor, diff --git a/elenasrc3/elenart/rtcommon.h b/elenasrc3/elenart/rtcommon.h index 871eea561e..d258a76808 100644 --- a/elenasrc3/elenart/rtcommon.h +++ b/elenasrc3/elenart/rtcommon.h @@ -14,7 +14,7 @@ namespace elena_lang { -#define ELENART_REVISION_NUMBER 0x0009 +#define ELENART_REVISION_NUMBER 0x000A } diff --git a/elenasrc3/elenasm/cfparser.cpp b/elenasrc3/elenasm/cfparser.cpp index c778f896f1..a8182817da 100644 --- a/elenasrc3/elenasm/cfparser.cpp +++ b/elenasrc3/elenasm/cfparser.cpp @@ -1,12 +1,13 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA VM Script Engine // -// (C)2023-2024, by Aleksey Rakov +// (C)2023-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" // -------------------------------------------------------------------------- #include "cfparser.h" +#include "regex.h" using namespace elena_lang; @@ -21,9 +22,8 @@ constexpr auto EOL_KEYWORD = "$eol"; constexpr auto ANYCHR_KEYWORD = "$chr"; // > 32 constexpr auto CURRENT_KEYWORD = "$current"; constexpr auto CHARACTER_KEYWORD = "$character"; -constexpr auto INTLITERAL_KEYWORD = "$intliteral"; // NOTE : quote containing a number -constexpr auto NONINTLITERAL_KEYWORD = "$nonintliteral"; // NOTE : quote containing a number constexpr auto BUFFER_KEYWORD = "$buffer"; // NOTE : quote containing a number +constexpr auto REGEX_KEYWORD = "$regex"; constexpr auto REFERENCE_MODE = 1; constexpr auto IDENTIFIER_MODE = 2; @@ -38,9 +38,8 @@ constexpr auto EXCLUDE_MODE = 10; constexpr auto CHARACTER_MODE = 11; constexpr auto IF_MODE = 12; constexpr auto IFNOT_MODE = 13; -constexpr auto INTLITERAL_MODE = 14; constexpr auto BUFFER_MODE = 15; -constexpr auto NONINTLITERAL_MODE = 16; +constexpr auto REGEX_MODE = 17; constexpr auto WITHFORWARD_MASK = 0x80000000; constexpr auto POSTFIXSAVE_MODE = 0x80000000; @@ -54,38 +53,82 @@ inline void readToken(ScriptEngineReaderBase& reader, ScriptBookmark& bm, ustr_t throw SyntaxError("invalid grammar rule", bm.lineInfo); } -void saveReference(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) +class ReferenceSaver : public ScriptEngineCFParser::SaverBase { - ScriptBookmark bm; - parser->readScriptBookmark(ptr, bm); +public: + void saveTo(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) override + { + ScriptBookmark bm; + parser->readScriptBookmark(ptr, bm); + + log.writeCoord(bm.lineInfo); + log.write(scriptReader.lookup(bm)); + } - log.writeCoord(bm.lineInfo); - log.write(scriptReader.lookup(bm)); -} + static ScriptEngineCFParser::SaverBase* getInstance() + { + static ReferenceSaver instance; + + return &instance; + } +}; -void saveLiteralContent(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) +class LiteralContentSaver : public ScriptEngineCFParser::SaverBase { - ScriptBookmark bm; - parser->readScriptBookmark(ptr, bm); +public: + void saveTo(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) override + { + ScriptBookmark bm; + parser->readScriptBookmark(ptr, bm); + + log.writeCoord(bm.lineInfo); + log.write(scriptReader.lookup(bm)); + } - log.writeCoord(bm.lineInfo); - log.write(scriptReader.lookup(bm)); -} + static ScriptEngineCFParser::SaverBase* getInstance() + { + static LiteralContentSaver instance; -void saveLiteral(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) + return &instance; + } +}; + +class LiteralSaver : public ScriptEngineCFParser::SaverBase { - ScriptBookmark bm; - parser->readScriptBookmark(ptr, bm); +public: + void saveTo(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) override + { + ScriptBookmark bm; + parser->readScriptBookmark(ptr, bm); + + log.writeCoord(bm.lineInfo); + log.writeQuote(scriptReader.lookup(bm)); + } - log.writeCoord(bm.lineInfo); - log.writeQuote(scriptReader.lookup(bm)); -} + static ScriptEngineCFParser::SaverBase* getInstance() + { + static LiteralSaver instance; + + return &instance; + } +}; -void saveBuffer(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) +class BufferSaver : public ScriptEngineCFParser::SaverBase { - parser->flushBuffer(log); - parser->clearBuffer(); -} +public: + void saveTo(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) override + { + parser->flushBuffer(log); + parser->clearBuffer(); + } + + static ScriptEngineCFParser::SaverBase* getInstance() + { + static BufferSaver instance; + + return &instance; + } +}; bool nonterminalApplyRule(ScriptEngineCFParser::Rule&, ScriptBookmark&, ScriptEngineReaderBase&, ScriptEngineCFParser*) { @@ -102,30 +145,6 @@ bool normalLiteralApplyRule(ScriptEngineCFParser::Rule&, ScriptBookmark& bm, Scr return (bm.state == dfaQuote); } -bool normalIntLiteralApplyRule(ScriptEngineCFParser::Rule&, ScriptBookmark& bm, ScriptEngineReaderBase& reader, ScriptEngineCFParser*) -{ - if (bm.state == dfaQuote) { - ustr_t value = reader.lookup(bm); - for (pos_t i = 0; i < getlength(value); i++) { - if (value[i] < '0' || value[i] > '9') - return false; - } - - return true; - } - return false; -} - -bool normalNonIntLiteralApplyRule(ScriptEngineCFParser::Rule&, ScriptBookmark& bm, ScriptEngineReaderBase& reader, ScriptEngineCFParser*) -{ - if (bm.state == dfaQuote) { - ustr_t value = reader.lookup(bm); - if (value[0] < '0' || value[0] > '9') - return true; - } - return false; -} - bool normalNumericApplyRule(ScriptEngineCFParser::Rule&, ScriptBookmark& bm, ScriptEngineReaderBase&, ScriptEngineCFParser*) { return (bm.state == dfaInteger || bm.state == dfaLong || bm.state == dfaReal); @@ -187,6 +206,11 @@ bool normalApplyRule(ScriptEngineCFParser::Rule& rule, ScriptBookmark& bm, Scrip return bm.state != dfaEOF && parser->compareToken(reader, bm, rule.terminal); } +bool regexApplyRule(ScriptEngineCFParser::Rule& rule, ScriptBookmark& bm, ScriptEngineReaderBase& reader, ScriptEngineCFParser* parser) +{ + return rule.saver->isMatched(reader.lookup(bm), bm.state); +} + // --- ScriptEngineCFParser --- inline pos_t createKey(pos_t id, int index) @@ -281,6 +305,18 @@ void ScriptEngineCFParser :: setScriptPtr(ScriptBookmark& bm, Rule& rule, bool p } } +ScriptEngineCFParser::SaverBase* ScriptEngineCFParser::createRegEx(ScriptBookmark& bm, ustr_t regex) +{ + auto regEx = RegExFactory::generate(regex); + if (!regEx) { + throw SyntaxError("invalid grammar rule", bm.lineInfo); + } + + _regExList.add(regEx); + + return regEx; +} + void ScriptEngineCFParser :: defineApplyRule(Rule& rule, int mode, RuleTypeModifier modifier) { if (rule.type == RuleType::Normal) { @@ -297,12 +333,6 @@ void ScriptEngineCFParser :: defineApplyRule(Rule& rule, int mode, RuleTypeModif case LITERAL_MODE: rule.apply = normalLiteralApplyRule; break; - case INTLITERAL_MODE: - rule.apply = normalIntLiteralApplyRule; - break; - case NONINTLITERAL_MODE: - rule.apply = normalNonIntLiteralApplyRule; - break; case NUMERIC_MODE: rule.apply = normalNumericApplyRule; break; @@ -343,6 +373,9 @@ void ScriptEngineCFParser :: defineApplyRule(Rule& rule, int mode, RuleTypeModif case EXCLUDE_MODE: rule.apply = excludeApplyRule; break; + case REGEX_MODE: + rule.apply = regexApplyRule; + break; default: rule.apply = normalApplyRule; break; @@ -384,56 +417,52 @@ void ScriptEngineCFParser :: saveScript(ScriptEngineReaderBase& reader, Rule& ru if (forwardMode) throw SyntaxError("invalid grammar rule", bm.lineInfo); - if (rule.saveTo != nullptr || (!prefixMode && !reader.compare(CURRENT_KEYWORD))) + if (rule.saver != nullptr || (!prefixMode && !reader.compare(CURRENT_KEYWORD))) throw SyntaxError("invalid grammar rule", bm.lineInfo); if (reader.compare(REFERENCE_KEYWORD)) { rule.terminal = INVALID_REF; - rule.saveTo = saveReference; + rule.saver = ReferenceSaver::getInstance(); mode = REFERENCE_MODE; } else if (reader.compare(IDENTIFIER_KEYWORD)) { rule.terminal = INVALID_REF; - rule.saveTo = saveReference; + rule.saver = ReferenceSaver::getInstance(); mode = IDENTIFIER_MODE; } else if (reader.compare(CHARACTER_KEYWORD)) { rule.terminal = INVALID_REF; - rule.saveTo = saveLiteralContent; + rule.saver = LiteralContentSaver::getInstance(); mode = CHARACTER_MODE; } else if (reader.compare(LITERAL_KEYWORD)) { rule.terminal = INVALID_REF; - rule.saveTo = saveLiteralContent; + rule.saver = LiteralContentSaver::getInstance(); mode = LITERAL_MODE; } - else if (reader.compare(INTLITERAL_KEYWORD)) { - rule.terminal = INVALID_REF; - rule.saveTo = saveReference; - - mode = INTLITERAL_MODE; - } - else if (reader.compare(NONINTLITERAL_KEYWORD)) { - rule.terminal = INVALID_REF; - rule.saveTo = saveReference; - - mode = NONINTLITERAL_MODE; - } else if (reader.compare(NUMERIC_KEYWORD)) { rule.terminal = INVALID_REF; - rule.saveTo = saveReference; + rule.saver = ReferenceSaver::getInstance(); mode = NUMERIC_MODE; } if (reader.compare(CURRENT_KEYWORD)) { - rule.saveTo = saveReference; + rule.saver = ReferenceSaver::getInstance(); } else if (reader.compare(BUFFER_KEYWORD)) { - rule.saveTo = saveBuffer; + rule.saver = BufferSaver::getInstance(); + } + else if (reader.compare(REGEX_KEYWORD)) { + bm = reader.read(); + + rule.terminal = INVALID_REF; + rule.saver = createRegEx(bm, reader.lookup(bm)); + + mode = REGEX_MODE; } writer.writeChar((char)0); @@ -444,7 +473,7 @@ void ScriptEngineCFParser :: saveScript(ScriptEngineReaderBase& reader, Rule& ru throw SyntaxError("invalid grammar rule", bm.lineInfo); rule.terminal = INVALID_REF; - rule.saveTo = saveLiteral; + rule.saver = LiteralSaver::getInstance(); mode = REFERENCE_MODE; @@ -456,7 +485,7 @@ void ScriptEngineCFParser :: saveScript(ScriptEngineReaderBase& reader, Rule& ru throw SyntaxError("invalid grammar rule", bm.lineInfo); rule.terminal = INVALID_REF; - rule.saveTo = saveLiteral; + rule.saver = LiteralSaver::getInstance(); mode = IDENTIFIER_MODE; @@ -468,7 +497,7 @@ void ScriptEngineCFParser :: saveScript(ScriptEngineReaderBase& reader, Rule& ru throw SyntaxError("invalid grammar rule", bm.lineInfo); rule.terminal = INVALID_REF; - rule.saveTo = saveLiteral; + rule.saver = LiteralSaver::getInstance(); mode = LITERAL_MODE; @@ -480,7 +509,7 @@ void ScriptEngineCFParser :: saveScript(ScriptEngineReaderBase& reader, Rule& ru throw SyntaxError("invalid grammar rule", bm.lineInfo); rule.terminal = INVALID_REF; - rule.saveTo = saveLiteral; + rule.saver = LiteralSaver::getInstance(); mode = NUMERIC_MODE; @@ -492,7 +521,7 @@ void ScriptEngineCFParser :: saveScript(ScriptEngineReaderBase& reader, Rule& ru throw SyntaxError("invalid grammar rule", bm.lineInfo); rule.terminal = INVALID_REF; - rule.saveTo = saveLiteral; + rule.saver = LiteralSaver::getInstance(); mode = CHARACTER_MODE; @@ -1150,8 +1179,8 @@ void ScriptEngineCFParser :: saveRuleOutput(Rule& rule, pos_t terminal, ScriptEn if (!test(rule.type, RuleType::WithForward)) lineLen += log.write(getBodyText(rule.prefix1Ptr)); - if (rule.saveTo != NULL) - rule.saveTo(scriptReader, this, terminal, log); + if (rule.saver != NULL) + rule.saver->saveTo(scriptReader, this, terminal, log); // HOTFIX: to prevent too long line if (lineLen > 0x10) { @@ -1229,7 +1258,7 @@ void ScriptEngineCFParser :: generateOutput(pos_t offset, ScriptEngineReaderBase // NOTE: reset level to -1 to match the backward calculated levels level = -1; Stack postfixes(0); - Stack functions(0); + Stack functions(nullptr); while (stack.count() > 0) { item = stack.pop(); if (item.ruleKey == 0) { @@ -1242,10 +1271,10 @@ void ScriptEngineCFParser :: generateOutput(pos_t offset, ScriptEngineReaderBase log.write(getBodyText(ptr)); - auto saveTo = functions.pop(); + auto saver = functions.pop(); int terminal = postfixes.pop(); - saveTo(scriptReader, this, terminal, log); + saver->saveTo(scriptReader, this, terminal, log); ptr = postfixes.pop(); } @@ -1284,7 +1313,7 @@ void ScriptEngineCFParser :: generateOutput(pos_t offset, ScriptEngineReaderBase postfixes.push(rule.postfix2Ptr); postfixes.push(item.terminal); - functions.push(rule.saveTo); + functions.push(rule.saver); postfixes.push(rule.prefix2Ptr | POSTFIXSAVE_MODE); } else postfixes.push(rule.prefix2Ptr); diff --git a/elenasrc3/elenasm/cfparser.h b/elenasrc3/elenasm/cfparser.h index 6b3174a6d5..0d662f2b54 100644 --- a/elenasrc3/elenasm/cfparser.h +++ b/elenasrc3/elenasm/cfparser.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA Script Engine // -// (C)2023-24, by Aleksey Rakov +// (C)2023-25, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef CFPARSER_H @@ -47,7 +47,16 @@ namespace elena_lang BufferMode }; - typedef void (*SaveToSign)(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log); + class SaverBase + { + public: + virtual bool isMatched(ustr_t token, char state) + { + return true; + } + + virtual void saveTo(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) = 0; + }; struct Rule { @@ -60,7 +69,8 @@ namespace elena_lang pos_t postfix2Ptr; bool(*apply)(Rule& rule, ScriptBookmark& bm, ScriptEngineReaderBase& reader, ScriptEngineCFParser* parser); - SaveToSign saveTo; + + SaverBase* saver; Rule() { @@ -70,7 +80,7 @@ namespace elena_lang postfix2Ptr = prefix2Ptr = 0; apply = nullptr; - saveTo = nullptr; + saver = nullptr; } }; @@ -120,6 +130,7 @@ namespace elena_lang //typedef MemoryHashTable SyntaxTable; typedef HashTable SyntaxTable; typedef Queue DerivationQueue; + typedef List RegExList; protected: ScriptEngineParserBase* _baseParser; @@ -131,6 +142,8 @@ namespace elena_lang bool _symbolMode; bool _generating; + RegExList _regExList; + ref_t mapRuleId(ustr_t name) { return mapKey(_names, name, _names.count() + 1); @@ -173,6 +186,8 @@ namespace elena_lang void insertForwards(Stack>& forwards, int level, ScriptEngineLog& log); + SaverBase* createRegEx(ScriptBookmark& bm, ustr_t regex); + public: void flushBuffer(ScriptEngineLog& log) { @@ -199,7 +214,7 @@ namespace elena_lang void parse(ScriptEngineReaderBase& reader, MemoryDump* output) override; ScriptEngineCFParser(ScriptEngineParserBase* baseParser) - : _table({}), _names(0) + : _table({}), _names(0), _regExList(nullptr) { _baseParser = baseParser; diff --git a/elenasrc3/elenasm/regex.cpp b/elenasrc3/elenasm/regex.cpp new file mode 100644 index 0000000000..28e7a8abc7 --- /dev/null +++ b/elenasrc3/elenasm/regex.cpp @@ -0,0 +1,416 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA command-Line Compiler +// +// This file contains the pattern engine implementation +// +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "elena.h" +// -------------------------------------------------------------------------- +#include "regex.h" + +using namespace elena_lang; + +const char* Postfix = "+*?"; +const char* Reserved = "$^[]+*?()\\"; + +// --- RegExFactory --- + +PatternRule* RegExFactory :: defineEscRule(char ch) +{ + if (ch == 'w') { + return new AnyWordChar(); + } + else if (ch == 'd') { + return new DigitChar(); + } + + return new CharRule(ch); +} + +PatternRule* RegExFactory :: defineRule(char ch) +{ + if (ch == '.') { + return new AnyRule(); + } + + if (ustr_t(Reserved).find(ch) != NOTFOUND_POS) + { + return nullptr; + } + + return new CharRule(ch); +} + +PatternRule* RegExFactory :: defineRule(ustr_t regex, size_t& start, char ch) +{ + size_t i = start; + PatternRule* rule = nullptr; + if (regex[i + 1] == '-') { + i += 2; + + char lastCh = regex[i]; + rule = new CharRangeRule(ch, lastCh); + } + else if (ch == '\\') { + i++; + ch = regex[i]; + rule = defineEscRule(ch); + } + else rule = defineRule(ch); + + start = i; + + return rule; +} + + +PatternRule* RegExFactory :: parseGroup(ustr_t regex, size_t& start, size_t end, PatternPool& pool) +{ + size_t i = start + 1; + + auto orList = new List(nullptr); + while (i < end) { + char ch = regex[i]; + + if (ch == ']') { + i++; + break; + } + else { + PatternRule* rule = defineRule(regex, i, ch); + if (rule != nullptr) { + pool.add(rule);// keep the list of unique rules + orList->add(rule); + } + else return nullptr; + } + + i++; + } + + start = i; + if (orList->count() == 1) { + auto rule = *orList->start(); + + freeobj(orList); + + return rule; + } + + PatternRule* orRule = new OrRule(orList); + pool.add(orRule);// keep the list of unique rules + + return orRule; +} + +PatternRule* RegExFactory :: parseBrackets(ustr_t pattern, size_t& start, size_t end, PatternPool& pool) +{ + bool selectMode = true; + auto orList = new List(nullptr); + + size_t i = start + 1; + + if (pattern[i] == '?') { + i++; + + if (pattern.compareSub("", i, 9)) { + selectMode = true; + i += 9; + } + else + { + freeobj(orList); + + return nullptr; + } + } + + bool closed = false; + while (i < end) { + PatternRule* rule = parseLine(pattern, i, end, ')', pool); + if (!rule) { + freeobj(orList); + + return nullptr; + } + + orList->add(rule); + if (pattern[i] == ')') { + i++; + closed = true; + + break; + } + + i++; + } + + if (!closed) { + freeobj(orList); + + return nullptr; + } + + start = i; + if (orList->count() == 1) { + auto rule = new NestedRule(*orList->start()); + + if (selectMode) { + rule->setMode(1); + } + + pool.add(rule); // keep the list of unique rules + + freeobj(orList); + + return rule; + } + else if (selectMode) { + freeobj(orList); + + return nullptr; + } + + auto orRule = new OrRule(orList); + pool.add(orRule); // keep the list of unique rules + + return orRule; +} + +PatternRule* RegExFactory :: parseLine(ustr_t pattern, size_t& start, size_t end, char terminator, PatternPool& pool) +{ + auto list = new List(nullptr); + if (parseLine(pattern, *list, start, end, terminator, pool)) { + auto first = linkRules(*list); + + freeobj(list); + + return first; + } + + return nullptr; +} + +PatternRule* RegExFactory :: linkRules(List& rules) +{ + for (auto it = rules.start(); !it.eof(); ++it) + { + auto next = it; + next++; + + if (!next.eof()) { + (*it)->setNext(*next); + + if ((*it)->getMode() == 1) { + (*next)->setMode(2); + } + } + + } + + return *rules.start(); +} + +bool RegExFactory :: parseLine(ustr_t pattern, List& rules, size_t& start, size_t end, char terminator, PatternPool& pool) +{ + ustr_t postfix(Postfix); + + size_t i = start; + while (i < end) { + char ch = pattern[i]; + + if (ch == terminator || ch == '|') { + break; + } + else if (postfix.find(ch) != NOTFOUND_POS) { + if (rules.count() == 0) + return false; + + PatternRule* rule = nullptr; + switch (ch) { + case '?': + rule = new OptionalRule(*rules.end()); + pool.add(rule); // keep the list of unique rules + break; + case '*': + rule = new RecursiveRule(*rules.end()); + pool.add(rule); // keep the list of unique rules + break; + case '+': + { + PatternRule* last = *rules.end(); + PatternRule* nested = new NestedRule(last); + rule = new RecursiveRule(last); + *(rules.end()) = nested; + rules.add(rule); + + pool.add(rule); // keep the list of unique rules + pool.add(nested); // keep the list of unique rules + + break; + } + default: + break; + } + + *(rules.end()) = rule; + } + else { + bool continueMode = false; + PatternRule* rule = nullptr; + + switch (ch) + { + case '[': + rule = parseGroup(pattern, i, end, pool); + continueMode = true; + break; + case '(': + rule = parseBrackets(pattern, i, end, pool); + continueMode = true; + break; + default: + rule = defineRule(pattern, i, ch); + pool.add(rule); // keep the list of unique rules + break; + } + + if (!rule) + return false; + + rules.add(rule); + + if (continueMode) + continue; + } + + i++; + } + + start = i; + return true; +} + +PatternRule* RegExFactory :: parsePattern(ustr_t regex, List& rules, size_t start, size_t end, PatternPool& pool) +{ + if (!parseLine(regex, rules, start, end, 0, pool)) { + return nullptr; + } + + if (start < end) { + return nullptr; + } + + rules.add(EOLRule::getInstance()); + + return linkRules(rules); +} + +ScriptEngineCFParser::SaverBase* RegExFactory :: generate(ustr_t pattern) +{ + if (pattern.startsWith("^\"") && pattern.endsWith("\"$")) { + auto rules = new List(nullptr); + PatternPool* pool = new PatternPool(nullptr); + + auto startRule = parsePattern(pattern, *rules, 2, pattern.length() - 2, *pool); + if (startRule) { + auto re = new QuoteRegEx(startRule, pool); + + freeobj(rules); + + return re; + } + else { + freeobj(rules); + freeobj(pool); + + return nullptr; + } + } + + return nullptr; +} + +// --- RegEx --- + +bool RegEx :: isMatched(ustr_t token, char) +{ + Stack parents(nullptr); + + size_t len = token.length(); + size_t index = 0; + PatternRule* current = _startRule; + while (index < len) { + char ch = token[index]; + + current = current->makeStep(token, index, ch, parents); + if(!current) { + return false; + } + + index++; + }; + + return current->makeStep(token, len, '\0', parents) != nullptr; +} + +void RegEx :: extract(ScriptEngineLog& log, ustr_t token) +{ + Stack parents(nullptr); + + size_t len = token.length(); + size_t index = 0; + size_t start = 0; + size_t end = len; + PatternRule* current = _startRule; + while (index < len) { + switch (current->getMode()) { + case 1: + start = index; + break; + case 2: + end = index; + break; + default: + break; + } + + char ch = token[index]; + + current = current->makeStep(token, index, ch, parents); + if (!current) { + break; + } + + index++; + }; + + if (end == len) { + log.write(token + start); + } + else if ((end - start) < IDENTIFIER_LEN) { + IdentifierString tmp(token + start, end - start); + + log.write(tmp.str()); + } + else { + DynamicString tmp; + tmp.copy(token + start, end - start); + + log.write(tmp.str()); + } +} + +// --- QuoteRegEx --- + +void QuoteRegEx :: saveTo(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) +{ + ScriptBookmark bm; + parser->readScriptBookmark(ptr, bm); + + log.writeCoord(bm.lineInfo); + + extract(log, scriptReader.lookup(bm)); +} \ No newline at end of file diff --git a/elenasrc3/elenasm/regex.h b/elenasrc3/elenasm/regex.h new file mode 100644 index 0000000000..3c2ed37efd --- /dev/null +++ b/elenasrc3/elenasm/regex.h @@ -0,0 +1,431 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA command-Line Compiler +// +// This file contains the regex engine declaration +// +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef REGEX_H +#define REGEX_H + +#include "cfparser.h" + +namespace elena_lang +{ + // --- RegEx --- + class PatternRule + { + protected: + + public: + virtual void setNext(PatternRule* next) = 0; + + static bool isLetter(char ch) + { + if (ch >= 0x41 && ch <= 0x5A) + { + return true; + }; + + if (ch >= 0x61 && ch <= 0x7A) + { + return true; + }; + + if (ch >= 0x370 && ch <= 0x3FB) + { + return true; + }; + + if (ch >= 0x400 && ch <= 0x4FF) + { + return true; + }; + + return false; + } + + static bool isDigit(char ch) + { + if (ch >= '0' && ch <= '9') + { + return true; + }; + + return false; + } + + virtual void setMode(int mode) = 0; + virtual int getMode() = 0; + + virtual PatternRule* gotoNext(Stack& parents) = 0; + virtual PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) = 0; + + virtual ~PatternRule() = default; + }; + + typedef List PatternPool; + + class LinkRule : public PatternRule + { + protected: + PatternRule* nextRule; + int _mode; + + public: + void setMode(int mode) override + { + _mode = mode; + } + + int getMode() override + { + return _mode; + } + + void setNext(PatternRule* next) override + { + nextRule = next; + } + + PatternRule* gotoNext(Stack& parents) override + { + if (!nextRule) { + return parents.pop()->gotoNext(parents); + } + + return nextRule; + } + + LinkRule() + : _mode(0) + { + } + }; + + class GroupRule : public LinkRule + { + protected: + List* _rules; + + public: + GroupRule() + { + _rules = nullptr; + } + GroupRule(List* rules) + { + _rules = rules; + } + + ~GroupRule() override + { + freeobj(_rules); + } + }; + + class NestedRule : public LinkRule + { + protected: + PatternRule* child; + + public: + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + parents.push(this); + PatternRule* next = child->makeStep(s, index, ch, parents); + if (!next) { + parents.pop(); + }; + + return next; + } + + NestedRule(PatternRule* child) + : child(child) + { + + } + }; + + class OptionalRule : public NestedRule + { + public: + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + parents.push(this); + PatternRule* next = child->makeStep(s, index, ch, parents); + if (!next) { + parents.pop(); + + return gotoNext(parents)->makeStep(s, index, ch, parents); + }; + + return next; + } + + OptionalRule(PatternRule* child) + : NestedRule(child) + { + + } + }; + + class RecursiveRule : public NestedRule + { + public: + PatternRule* gotoNext(Stack& parents) override + { + return this; + } + + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + parents.push(this); + PatternRule* next = child->makeStep(s, index, ch, parents); + if (!next) { + parents.pop(); + + return NestedRule::gotoNext(parents)->makeStep(s, index, ch, parents); + }; + + return next; + } + + RecursiveRule(PatternRule* child) + : NestedRule(child) + { + + } + }; + + class OrRule : public GroupRule + { + public: + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + parents.push(this); + + for (auto it = _rules->start(); !it.eof(); ++it) { + PatternRule* next = (*it)->makeStep(s, index, ch, parents); + if (next) { + return next; + } + } + + parents.pop(); + + return nullptr; + } + + OrRule(List* list) + : GroupRule(list) + { + } + }; + + class CharRangeRule : public LinkRule + { + char chFrom; + char chTill; + + public: + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + if (ch >= chFrom && ch <= chTill) { + return gotoNext(parents); + } + + return nullptr; + } + + CharRangeRule(char from, char till) + : chFrom(from), chTill(till) + { + } + }; + + class AnyWordChar : public LinkRule + { + public: + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + if (PatternRule::isLetter(ch)) { + return gotoNext(parents); + } + if (PatternRule::isDigit(ch)) { + return gotoNext(parents); + } + + return nullptr; + } + + AnyWordChar() + { + } + }; + + class DigitChar : public LinkRule + { + public: + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + if (PatternRule::isDigit(ch)) { + return gotoNext(parents); + } + + return nullptr; + } + + DigitChar() + { + } + }; + + class AnyRule : public LinkRule + { + public: + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + if (ch == 10 || ch == 0) { + return nullptr; + } + + if (index < s.length_int()) { + return gotoNext(parents); + } + + return nullptr; + } + + AnyRule() + { + } + }; + + class CharRule : public LinkRule + { + protected: + char _ch; + + public: + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + if (_ch == ch) { + return gotoNext(parents); + } + + return nullptr; + } + + CharRule(char ch) + : _ch(ch) + { + + } + }; + + class EOLRule : public PatternRule + { + public: + void setNext(PatternRule* next) override + { + throw AbortError(); + } + + PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + { + return ch == 0 ? this : nullptr; + } + + PatternRule* gotoNext(Stack& parents) override + { + return nullptr; + } + + int getMode() override + { + return 0; + } + + void setMode(int mode) override + { + if (mode != 2) { + throw AbortError(); + } + } + + static PatternRule* getInstance() + { + static EOLRule rule; + + return &rule; + } + }; + + class RegEx : public ScriptEngineCFParser::SaverBase + { + protected: + PatternRule* _startRule; + PatternPool* _pool; + + public: + bool isMatched(ustr_t token, char) override; + + void extract(ScriptEngineLog& log, ustr_t token); + + RegEx(PatternRule* startRule, PatternPool* pool) + : _startRule(startRule), _pool(pool) + { + } + + virtual ~RegEx() + { + freeobj(_pool); + } + }; + + class QuoteRegEx : public RegEx + { + public: + bool isMatched(ustr_t token, char state) override + { + if (state == dfaQuote) { + return RegEx::isMatched(token, state); + } + } + + void saveTo(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) override; + + QuoteRegEx(PatternRule* startRule, PatternPool* pool) + : RegEx(startRule, pool) + { + + } + }; + + // --- RegExFactory --- + class RegExFactory + { + static PatternRule* defineEscRule(char ch); + static PatternRule* defineRule(ustr_t regex, size_t& start, char ch); + static PatternRule* defineRule(char ch); + + static PatternRule* parseGroup(ustr_t regex, size_t& start, size_t end, PatternPool& pool); + static PatternRule* parseBrackets(ustr_t regex, size_t& start, size_t end, PatternPool& pool); + + static PatternRule* parseLine(ustr_t regex, size_t& start, size_t end, char terminator, PatternPool& pool); + + static PatternRule* linkRules(List& rules); + + static bool parseLine(ustr_t regex, List& rules, size_t& start, size_t end, char terminator, PatternPool& pool); + static PatternRule* parsePattern(ustr_t regex, List& rules, size_t start, size_t end, PatternPool& pool); + + public: + static ScriptEngineCFParser::SaverBase* generate(ustr_t regex); + }; + +} + +#endif diff --git a/elenasrc3/elenasm/smcommon.h b/elenasrc3/elenasm/smcommon.h index 036a404af8..6b0a437783 100644 --- a/elenasrc3/elenasm/smcommon.h +++ b/elenasrc3/elenasm/smcommon.h @@ -3,13 +3,13 @@ // // This file contains the compiler common interfaces & types // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef RTCOMMON_H #define RTCOMMON_H -#define ELENASM_REVISION_NUMBER 0x0013 +#define ELENASM_REVISION_NUMBER 0x0015 namespace elena_lang { diff --git a/elenasrc3/elenasm/vs/elenasm.vcxproj b/elenasrc3/elenasm/vs/elenasm.vcxproj index 83f30356ca..27e4ab5020 100644 --- a/elenasrc3/elenasm/vs/elenasm.vcxproj +++ b/elenasrc3/elenasm/vs/elenasm.vcxproj @@ -183,6 +183,7 @@ + @@ -199,6 +200,7 @@ + diff --git a/elenasrc3/engine/core.h b/elenasrc3/engine/core.h index dea8b47a6a..f1ab164a9f 100644 --- a/elenasrc3/engine/core.h +++ b/elenasrc3/engine/core.h @@ -2,7 +2,7 @@ // // This file contains common ELENA Core constants // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //------------------------------------------------------------------------------ #ifndef CORE_H @@ -53,6 +53,7 @@ namespace elena_lang constexpr ref_t CORE_TOC = 0x20001; constexpr ref_t SYSTEM_ENV = 0x20002; constexpr ref_t CORE_GC_TABLE = 0x20003; + constexpr ref_t CORE_MATH_TABLE = 0x20004; constexpr ref_t CORE_SINGLE_CONTENT = 0x2000B; constexpr ref_t VOIDOBJ = 0x2000D; constexpr ref_t VOIDPTR = 0x2000E; diff --git a/elenasrc3/engine/elena.h b/elenasrc3/engine/elena.h index 13f80b592f..46c054b90e 100644 --- a/elenasrc3/engine/elena.h +++ b/elenasrc3/engine/elena.h @@ -710,6 +710,14 @@ namespace elena_lang StrConvertor::copy(_string + len, s, getlength(s), subLen); _string[len + subLen] = 0; } + void appendUstr(const char* s, size_t str_len) + { + size_t len = length(); + + size_t subLen = MESSAGE_LEN - length(); + StrConvertor::copy(_string + len, s, str_len, subLen); + _string[len + subLen] = 0; + } WideMessage() { diff --git a/elenasrc3/engine/elenaconst.h b/elenasrc3/engine/elenaconst.h index 71978e3989..1f195e657f 100644 --- a/elenasrc3/engine/elenaconst.h +++ b/elenasrc3/engine/elenaconst.h @@ -13,7 +13,7 @@ namespace elena_lang { // --- Common ELENA Engine constants --- #define ENGINE_MAJOR_VERSION 6 // ELENA Engine version - #define ENGINE_MINOR_VERSION 5 + #define ENGINE_MINOR_VERSION 6 constexpr auto LINE_LEN = 0x1000; // the maximal source line length constexpr auto IDENTIFIER_LEN = 0x0300; // the maximal identifier length @@ -220,6 +220,8 @@ namespace elena_lang Linux_PPC64le = 0x00025, Linux_PPC32le = 0x00026, + MacOS_ARM64 = 0x00034, + TargetMask = 0x00F00, Standalone = 0x00000, VMClient = 0x00100, diff --git a/elenasrc3/engine/elenamachine.cpp b/elenasrc3/engine/elenamachine.cpp index c778444ea8..638de5cf75 100644 --- a/elenasrc3/engine/elenamachine.cpp +++ b/elenasrc3/engine/elenamachine.cpp @@ -367,7 +367,6 @@ bool SystemRoutineProvider :: CheckMessage(MemoryBase* msection, void* classPtr, RTManager manager(msection, nullptr); VMTHeader* header = (VMTHeader*)((uintptr_t)classPtr - elVMTClassOffset); - size_t counter = 0; // NOTE : skip the dispatcher for (pos_t i = 1; i < header->count; i++) { if (((VMTEntry*)classPtr)[i].message == message) diff --git a/elenasrc3/engine/gcroutines.cpp b/elenasrc3/engine/gcroutines.cpp index 78ed792d0a..3782b55a58 100644 --- a/elenasrc3/engine/gcroutines.cpp +++ b/elenasrc3/engine/gcroutines.cpp @@ -433,7 +433,7 @@ void* SystemRoutineProvider :: GCRoutine(GCTable* table, GCRoot* roots, size_t s CollectMG2YGRoots(table, shadowPtr); // ; collect perm yg roots - if (table->gc_perm_current > table->gc_perm_current) + if (table->gc_perm_current > table->gc_perm_end) CollectPermYGRoots(table, shadowPtr); // ; save gc_yg_current to mark objects diff --git a/elenasrc3/engine/jitcompiler.cpp b/elenasrc3/engine/jitcompiler.cpp index ba9c9bf75a..4adce0fa5a 100644 --- a/elenasrc3/engine/jitcompiler.cpp +++ b/elenasrc3/engine/jitcompiler.cpp @@ -3,7 +3,7 @@ // // This file contains ELENA JIT compiler class implementation. // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -75,11 +75,11 @@ constexpr ref_t coreVariables[coreVariableNumber] = CORE_GC_TABLE, CORE_SINGLE_CONTENT, CORE_THREAD_TABLE }; -constexpr int coreConstantNumber = 4; +constexpr int coreConstantNumber = 5; constexpr ref_t coreConstants[coreConstantNumber] = { // NOTE: SYSTEM_ENV should be the last one to add correctly extra fields: GCMGSize, GCYGSize - CORE_TOC, VOIDOBJ, VOIDPTR, SYSTEM_ENV + CORE_TOC, VOIDOBJ, VOIDPTR, CORE_MATH_TABLE, SYSTEM_ENV }; // preloaded gc routines @@ -943,10 +943,9 @@ void elena_lang::loadFrameDispOp(JITCompilerScope* scope) scope->constants->dataOffset), 0); break; default: - // to make compiler happy + writeCoreReference(scope, entries->reference, entries->offset, code); break; } - //else writeCoreReference(); entries++; count--; diff --git a/elenasrc3/engine/langcommon.h b/elenasrc3/engine/langcommon.h index 53cc113557..30161b1e9a 100644 --- a/elenasrc3/engine/langcommon.h +++ b/elenasrc3/engine/langcommon.h @@ -731,6 +731,8 @@ namespace elena_lang constexpr auto LINUX_PPC64le_KEY = "Linux_PPC64le"; constexpr auto LINUX_ARM64_KEY = "Linux_ARM64"; + constexpr auto MACOS_ARM64_KEY = "MacOS_ARM64"; + constexpr auto LIBRARY_KEY = "Library"; constexpr auto CONSOLE_KEY = "STA Console"; constexpr auto GUI_KEY = "STA GUI"; @@ -796,6 +798,8 @@ namespace elena_lang return LINUX_PPC64le_KEY; case PlatformType::Linux_ARM64: return LINUX_ARM64_KEY; + case PlatformType::MacOS_ARM64: + return MACOS_ARM64_KEY; default: return nullptr; } diff --git a/elenasrc3/engine/libman.cpp b/elenasrc3/engine/libman.cpp index 161ab0ba24..a98ef62bd8 100644 --- a/elenasrc3/engine/libman.cpp +++ b/elenasrc3/engine/libman.cpp @@ -498,6 +498,8 @@ ReferenceInfo LibraryProvider :: retrieveReferenceInfo(ustr_t referenceName, For ModuleBase* LibraryProvider :: createModule(ustr_t name) { + assert(!_modules.exist(name)); + auto module = new Module(name); _modules.add(name, module); diff --git a/elenasrc3/engine/linux/presenter.cpp b/elenasrc3/engine/linux/presenter.cpp index faaacabdd6..9dda270926 100644 --- a/elenasrc3/engine/linux/presenter.cpp +++ b/elenasrc3/engine/linux/presenter.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA command-Line Compiler // -// This file contains the Windows Presenter implementation +// This file contains the Linux Presenter implementation // // (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- diff --git a/elenasrc3/engine/linux/presenter.h b/elenasrc3/engine/linux/presenter.h index 060c8e4b6f..b9c089f831 100644 --- a/elenasrc3/engine/linux/presenter.h +++ b/elenasrc3/engine/linux/presenter.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA command-Line Compiler // -// This file contains the Windows Presenter declaration +// This file contains the Linux Presenter declaration // // (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- diff --git a/elenasrc3/engine/projectbase.h b/elenasrc3/engine/projectbase.h index c89b6190a2..f79d0df643 100644 --- a/elenasrc3/engine/projectbase.h +++ b/elenasrc3/engine/projectbase.h @@ -75,6 +75,8 @@ namespace elena_lang ConditionalBoxing, EvaluateOp, + TracingMode, + Prolog, Epilog, diff --git a/elenasrc3/engine/rtmanager.cpp b/elenasrc3/engine/rtmanager.cpp index f92d74d749..6701cf7d72 100644 --- a/elenasrc3/engine/rtmanager.cpp +++ b/elenasrc3/engine/rtmanager.cpp @@ -51,7 +51,7 @@ bool RTManager :: readAddressInfo(addr_t retAddress, LibraryLoaderBase& provider if (!vmMode) { reader.read(&tempAddr, sizeof(tempAddr)); - ustr_t ns = reader.getString(DEFAULT_STR); + /*ustr_t ns = */reader.getString(DEFAULT_STR); } // search through debug section until the ret point is inside two consecutive steps within the same object diff --git a/elenasrc3/engine/windows/presenter.cpp b/elenasrc3/engine/windows/presenter.cpp index 553b5a6902..9c346ea9d3 100644 --- a/elenasrc3/engine/windows/presenter.cpp +++ b/elenasrc3/engine/windows/presenter.cpp @@ -107,9 +107,24 @@ void WinConsolePresenter :: printPath(ustr_t msg, path_t arg) void WinConsolePresenter :: print(ustr_t msg) { - WideMessage wstr(msg); - - ::print(wstr.str()); + size_t len = msg.length(); + if (len < MESSAGE_LEN) { + WideMessage wstr(msg); + + ::print(wstr.str()); + } + else { + while (len > 0) { + WideMessage wstr; + size_t sublen = _min(msg.length(), MESSAGE_LEN); + + wstr.appendUstr(msg, sublen); + ::print(wstr.str()); + + len -= sublen; + msg = msg + sublen; + } + } } void WinConsolePresenter :: print(ustr_t msg, ustr_t path, int col, int row, ustr_t s) diff --git a/elenasrc3/gui/gtklinux/gtkcommon.cpp b/elenasrc3/gui/gtklinux/gtkcommon.cpp index 8cf1871430..419a0582b2 100644 --- a/elenasrc3/gui/gtklinux/gtkcommon.cpp +++ b/elenasrc3/gui/gtklinux/gtkcommon.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // GTK Common Window Implementation -// (C)2024, by Alexei Rakov +// (C)2024-2025, by Alexei Rakov //--------------------------------------------------------------------------- #include "gtkcommon.h" @@ -26,4 +26,5 @@ int WindowApp :: run(GUIControlBase* mainWindow, bool maximized, EventBase* star void WindowApp :: notify(EventBase* event) { + _eventBroadcaster->sendMessage(event); } diff --git a/elenasrc3/gui/gtklinux/gtkcommon.h b/elenasrc3/gui/gtklinux/gtkcommon.h index 8ce12b538b..752fab543f 100644 --- a/elenasrc3/gui/gtklinux/gtkcommon.h +++ b/elenasrc3/gui/gtklinux/gtkcommon.h @@ -1,70 +1,22 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE -// GTK Common Header File -// (C)2024, by Aleksey Rakov +// GUI common classes header File +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef GTKCOMMON_H #define GTKCOMMON_H -#include #include "guicommon.h" +#include namespace elena_lang { - // --- Color --- - struct Color + // --- BroadcasterBase --- + class BroadcasterBase { - double red; - double green; - double blue; - double alpha; - - bool operator == (Color& color) - { - if (red == color.red && green == color.green && blue == color.blue && alpha == color.alpha) { - return true; - } - else return false; - } - - bool operator != (Color& color) - { - if (red != color.red || green != color.green || blue != color.blue || alpha != color.alpha) { - return true; - } - else return false; - } - - void set(double red, double green, double blue) - { - this->red = red; - this->green = green; - this->blue = blue; - this->alpha = 1.0; - } - - void set(double red, double green, double blue, double alpha) - { - this->red = red; - this->green = green; - this->blue = blue; - this->alpha = alpha; - } - - Color() - { - set(0, 0, 0); - } - Color(double red, double green, double blue) - { - set(red, green, blue); - } - - Color(double red, double green, double blue, double alpha) - { - set(red, green, blue, alpha); - } + public: + virtual void sendMessage(EventBase* event) = 0; }; // --- WindowBase --- @@ -115,11 +67,18 @@ namespace elena_lang // --- WindowApp --- class WindowApp : public GUIApp { + BroadcasterBase* _eventBroadcaster; + public: + int run(GUIControlBase* mainWindow, bool maximized, EventBase* startEvent) override; + void notify(EventBase* event) override; - int run(GUIControlBase* mainWindow, bool maximized, EventBase* startEvent) override; + WindowApp(BroadcasterBase* eventBroadcaster) + { + _eventBroadcaster = eventBroadcaster; + } }; } -#endif // GTKCOMMON_H +#endif diff --git a/elenasrc3/gui/gtklinux/gtkgraphic.h b/elenasrc3/gui/gtklinux/gtkgraphic.h index e23b065065..1cd9d0bb95 100644 --- a/elenasrc3/gui/gtklinux/gtkgraphic.h +++ b/elenasrc3/gui/gtklinux/gtkgraphic.h @@ -12,6 +12,62 @@ namespace elena_lang { +// --- Colour --- + +struct Color +{ + double red; + double green; + double blue; + double alpha; + + bool operator == (Color& color) + { + if (red == color.red && green == color.green && blue == color.blue && alpha == color.alpha) { + return true; + } + else return false; + } + + bool operator != (Color& color) + { + if (red != color.red || green != color.green || blue != color.blue || alpha != color.alpha) { + return true; + } + else return false; + } + + void set(double red, double green, double blue) + { + this->red = red; + this->green = green; + this->blue = blue; + this->alpha = 1.0; + } + + void set(double red, double green, double blue, double alpha) + { + this->red = red; + this->green = green; + this->blue = blue; + this->alpha = alpha; + } + + Color() + { + set(0, 0, 0); + } + Color(double red, double green, double blue) + { + set(red, green, blue); + } + + Color(double red, double green, double blue, double alpha) + { + set(red, green, blue, alpha); + } +}; + // --- Font --- struct Font : public FontBase @@ -117,4 +173,3 @@ struct Canvas } // elena_lang #endif // gtkgraphicH - diff --git a/elenasrc3/gui/gtklinux/gtktabbar.cpp b/elenasrc3/gui/gtklinux/gtktabbar.cpp index 99fefbb205..98def95b2c 100644 --- a/elenasrc3/gui/gtklinux/gtktabbar.cpp +++ b/elenasrc3/gui/gtklinux/gtktabbar.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // GTK+ TabBar Implementation File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- @@ -27,3 +27,25 @@ void TabBar :: addTab(const char* name, Gtk::Widget* control) append_page(*hb, name); // !! temporal } + +Gtk::Widget* TabBar :: getCurrentControl() +{ + Gtk::HBox* hb = dynamic_cast(get_nth_page(get_current_page())); + + auto list = hb->get_children(); + + return list[0]; +} + +/*Gtk::Widget* TabBar :: getTabControl(int index) const +{ + if (index == -1) + return nullptr; + + TabPages::Iterator it = _tabs.start(); + while (index > 0) { + index--; + it++; + } + return (*it)->control; +}*/ diff --git a/elenasrc3/gui/gtklinux/gtktabbar.h b/elenasrc3/gui/gtklinux/gtktabbar.h index 55ea27e1a5..1635b002ca 100644 --- a/elenasrc3/gui/gtklinux/gtktabbar.h +++ b/elenasrc3/gui/gtklinux/gtktabbar.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // GTK+ TabBar Header File -// (C)2024, by Aleksey Rakov +// (C)2024-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef GTKTABBAR_H @@ -17,6 +17,8 @@ namespace elena_lang public: void addTab(const char* name, Gtk::Widget* control); + Gtk::Widget* getCurrentControl(); + TabBar(); }; } diff --git a/elenasrc3/gui/gtklinux/gtktextframe.cpp b/elenasrc3/gui/gtklinux/gtktextframe.cpp index 2931b642ed..03b19f1252 100644 --- a/elenasrc3/gui/gtklinux/gtktextframe.cpp +++ b/elenasrc3/gui/gtklinux/gtktextframe.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // Linux EditFrame container File -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "gtklinux/gtktextframe.h" @@ -51,3 +51,8 @@ void TextViewFrame :: beforeDocumentClose(int index) void TextViewFrame :: onDocumentClose(int index, bool empty) { } + +TextViewWindow* TextViewFrame :: getCurrentTextView() +{ + return dynamic_cast(getCurrentControl()); +} diff --git a/elenasrc3/gui/gtklinux/gtktextframe.h b/elenasrc3/gui/gtklinux/gtktextframe.h index b8e201c4d9..458de65dd8 100644 --- a/elenasrc3/gui/gtklinux/gtktextframe.h +++ b/elenasrc3/gui/gtklinux/gtktextframe.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // Linux EditFrame container File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef GTKTEXTFRAME_H @@ -21,6 +21,8 @@ namespace elena_lang ViewStyles* _styles; TextViewControllerBase* _controller; + TextViewWindow* getCurrentTextView(); + public: void onDocumentNew(int index) override; void onDocumentSelect(int index) override; diff --git a/elenasrc3/gui/gtklinux/gtktextview.cpp b/elenasrc3/gui/gtklinux/gtktextview.cpp index d84cdd1159..c2cf90d94e 100644 --- a/elenasrc3/gui/gtklinux/gtktextview.cpp +++ b/elenasrc3/gui/gtklinux/gtktextview.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // GTK+ TextView Control Implementation File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "gtklinux/gtktextview.h" @@ -189,17 +189,15 @@ void TextViewWindow::TextDrawingArea :: onResize(int x, int y, int width, int he update(true); } -void TextView::TextDrawingArea :: onEditorChange() +void TextViewWindow::TextDrawingArea :: onDocumentUpdate(DocumentChangeStatus& changeStatus) { -// if (_document->status.isViewChanged()) { -// _cached = false; -// -// refresh(); -// } + if (changeStatus.isViewChanged()) { + //_cached = false; + _caret_x = 0; + } + _caretChanged = changeStatus.caretChanged; update(false); - - _view->_textview_changed.emit(); } void TextViewWindow::TextDrawingArea :: paint(Canvas& canvas , int viewWidth, int viewHeight) @@ -330,7 +328,7 @@ void TextViewWindow::TextDrawingArea :: resizeDocument(int width, int height) void TextViewWindow::TextDrawingArea :: update(bool resized) { if (_model) { - auto docView = _model->DocView(); + //auto docView = _model->DocView(); _view->updateVScroller(resized); // if (docView->status.maxColChanged) { @@ -412,7 +410,7 @@ bool TextViewWindow::TextDrawingArea :: on_key_press_event(GdkEventKey* event) } else return Gtk::DrawingArea::on_key_press_event(event); } - onEditorChange(); + //onEditorChange(); return true; } @@ -439,10 +437,9 @@ bool TextViewWindow::TextDrawingArea :: on_button_press_event(GdkEventButton* ev // if (margin) { // notify(IDE_EDITOR_MARGINCLICKED); // } - _captureMouse(); + //_captureMouse(); - // refresh(true); - onEditorChange(); + // refresh(true); onDocumentUpdate(status); } return true; @@ -450,16 +447,16 @@ bool TextViewWindow::TextDrawingArea :: on_button_press_event(GdkEventButton* ev else return false; } -bool TextView::TextDrawingArea :: mouseToScreen(Point point, int& col, int& row, bool& margin) +bool TextViewWindow::TextDrawingArea :: mouseToScreen(Point point, int& col, int& row, bool& margin) { // //Rectangle rect = getRectangle(); - Style defaultStyle = _styles[STYLE_DEFAULT]; - if (defaultStyle.valid) { - int marginWidth = _styles.getMarginWidth() + getLineNumberMargin(); - int offset = defaultStyle.avgCharWidth / 2; + Style* defaultStyle = _styles->getStyle(STYLE_DEFAULT); + if (defaultStyle->valid) { + int marginWidth = getLineNumberMargin(); + int offset = defaultStyle->avgCharWidth / 2; - col = (point.x/* - rect.topLeft.x*/ - marginWidth + offset) / defaultStyle.avgCharWidth; - row = (point.y/* - rect.topLeft.y*/) / (_styles.getLineHeight()); + col = (point.x/* - rect.topLeft.x*/ - marginWidth + offset) / defaultStyle->avgCharWidth; + row = (point.y/* - rect.topLeft.y*/) / (_styles->getLineHeight()); margin = (point.x/* - rect.topLeft.x*/ < marginWidth); return true; @@ -467,25 +464,32 @@ bool TextView::TextDrawingArea :: mouseToScreen(Point point, int& col, int& row, else return false; } -bool TextView::TextDrawingArea :: on_button_release_event (GdkEventButton* event) +bool TextViewWindow::TextDrawingArea :: on_button_release_event (GdkEventButton* event) { //_releaseMouse(); return true; } -bool TextView::TextDrawingArea :: on_scroll_event(GdkEventScroll* scroll_event) +bool TextViewWindow::TextDrawingArea :: on_scroll_event(GdkEventScroll* scroll_event) { - if (_document) { + DocumentChangeStatus status = {}; + + auto docView = _model->DocView(); + if (docView) { int offset = (scroll_event->direction == GDK_SCROLL_UP) ? -1 : 1; - if (_ELENA_::test(scroll_event->state, GDK_CONTROL_MASK)) { - offset *= _document->getSize().y; + if (test((int)scroll_event->state, GDK_CONTROL_MASK)) { + offset *= docView->getSize().y; } - _document->vscroll(offset); + docView->vscroll(status, offset); + + onDocumentUpdate(status); - onEditorChange(); + return true; } + + return false; } // --- TextViewWindow --- @@ -504,3 +508,8 @@ void TextViewWindow :: updateVScroller(bool resized) // if (resized) // _vadjustment->changed(); } + +void TextViewWindow :: onDocumentUpdate(DocumentChangeStatus& changeStatus) +{ + _area.onDocumentUpdate(changeStatus); +} diff --git a/elenasrc3/gui/gtklinux/gtktextview.h b/elenasrc3/gui/gtklinux/gtktextview.h index 6c334b4fc8..553eb28761 100644 --- a/elenasrc3/gui/gtklinux/gtktextview.h +++ b/elenasrc3/gui/gtklinux/gtktextview.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // GTK TextView Control Header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef GTKTEXTVIEW_H @@ -107,7 +107,6 @@ namespace elena_lang bool on_scroll_event (GdkEventScroll* scroll_event) override; void onResize(int x, int y, int width, int height); - void onEditorChange(); bool mouseToScreen(Point point, int& col, int& row, bool& margin); @@ -118,14 +117,23 @@ namespace elena_lang void paint(Canvas& canvas, int viewWidth, int viewHeight); public: + void onDocumentUpdate(DocumentChangeStatus& changeStatus); + TextDrawingArea(TextViewWindow* view, TextViewModelBase* model, TextViewControllerBase* controller, ViewStyles* styles); }; protected: - TextDrawingArea _area; + TextDrawingArea _area; + + void on_grab_focus() override + { + _area.grab_focus(); + } public: + void onDocumentUpdate(DocumentChangeStatus& changeStatus); + void updateVScroller(bool resized); TextViewWindow(TextViewModelBase* model, TextViewControllerBase* controller, diff --git a/elenasrc3/gui/text.h b/elenasrc3/gui/text.h index 8c0774a044..647778e692 100644 --- a/elenasrc3/gui/text.h +++ b/elenasrc3/gui/text.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // Text class header -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef TEXT_H @@ -117,6 +117,7 @@ namespace elena_lang return true; } + else return true; } else return false; #elif _MSC_VER diff --git a/elenasrc3/ide/codeblocks/elide_gtk.cbp b/elenasrc3/ide/codeblocks/elide_gtk.cbp index aa75f8664b..d810e4db5c 100644 --- a/elenasrc3/ide/codeblocks/elide_gtk.cbp +++ b/elenasrc3/ide/codeblocks/elide_gtk.cbp @@ -126,6 +126,10 @@ + + + + diff --git a/elenasrc3/ide/eng/messages.h b/elenasrc3/ide/eng/messages.h index df37aea22f..458a84950a 100644 --- a/elenasrc3/ide/eng/messages.h +++ b/elenasrc3/ide/eng/messages.h @@ -9,7 +9,7 @@ namespace elena_lang { - constexpr auto APP_NAME = _T("ELENA IDE 6.1"); + constexpr auto APP_NAME = _T("ELENA IDE 6.6"); constexpr auto OPEN_FILE_CAPTION = _T("Open File"); constexpr auto OPEN_PROJECT_CAPTION = _T("Open Project"); diff --git a/elenasrc3/ide/gtklinux/factory.cpp b/elenasrc3/ide/gtklinux/factory.cpp index 8f4915a800..facd3322af 100644 --- a/elenasrc3/ide/gtklinux/factory.cpp +++ b/elenasrc3/ide/gtklinux/factory.cpp @@ -1,13 +1,13 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // IDE windows factory -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "factory.h" #include "gtklinux/gtkcommon.h" #include "gtklinux/gtkide.h" -#include "gtklinux/gtktextframe.h" +#include "gtklinux/gtkidetextview.h" #include "gtklinux/gtktextview.h" //#include "text.h" //#include "sourceformatter.h" @@ -66,6 +66,24 @@ StyleInfo darkStyles[STYLE_MAX + 1] = { constexpr auto STYLE_SCHEME_COUNT = 3; +// --- IDEBroadcaster --- + +IDEBroadcaster :: IDEBroadcaster() +{ +} + +void IDEBroadcaster :: sendMessage(EventBase* event) +{ + int eventId = event->eventId(); + switch (eventId) { + case EVENT_TEXTVIEW_MODEL_CHANGED: + textview_changed.emit(*(TextViewModelEvent*)event); + break; + default: + break; + } +} + // --- IDEFactory --- IDEFactory :: IDEFactory(IDEModel* ideModel, IDEController* controller, @@ -98,7 +116,9 @@ Gtk::Widget* IDEFactory :: createTextControl() reloadStyles(viewModel); //TextViewWindow* view = new TextViewWindow(/*_model->viewModel(), &_styles*//*, &_controller->sourceController*/); - TextViewFrame* frame = new TextViewFrame(_model->viewModel(), &_controller->sourceController, &_styles); + IDETextViewFrame* frame = new IDETextViewFrame(_model->viewModel(), &_controller->sourceController, &_styles); + + _broadcaster.textview_changed.connect(sigc::mem_fun(*frame, &IDETextViewFrame::on_text_model_change)); return frame; } @@ -139,12 +159,14 @@ GUIControlBase* IDEFactory :: createMainWindow(NotifierBase* notifier, ProcessBa ideWindow->populate(counter, children); ideWindow->setLayout(textIndex, -1, -1, -1, -1); + _broadcaster.textview_changed.connect(sigc::mem_fun(*ideWindow, >KIDEWindow::on_text_model_change)); + return new WindowWrapper(ideWindow); } GUIApp* IDEFactory :: createApp() { - WindowApp* app = new WindowApp(); + WindowApp* app = new WindowApp(&_broadcaster); return app; } diff --git a/elenasrc3/ide/gtklinux/factory.h b/elenasrc3/ide/gtklinux/factory.h index 4942a9cfc7..e17de9163f 100644 --- a/elenasrc3/ide/gtklinux/factory.h +++ b/elenasrc3/ide/gtklinux/factory.h @@ -17,10 +17,25 @@ namespace elena_lang { + typedef sigc::signal type_textview_changed; + + // --- IDEBroadcaster --- + class IDEBroadcaster : public BroadcasterBase + { + public: + type_textview_changed textview_changed; + + void sendMessage(EventBase* event) override; + + IDEBroadcaster(); + }; + // --- IDEFactory --- class IDEFactory : public GUIFactoryBase, public ViewFactoryBase { protected: + IDEBroadcaster _broadcaster; + FontFactory _fontFactory; ViewStyles _styles; StyleInfo* _schemes[3]; diff --git a/elenasrc3/ide/gtklinux/gtkdialogs.cpp b/elenasrc3/ide/gtklinux/gtkdialogs.cpp new file mode 100644 index 0000000000..0ae250431b --- /dev/null +++ b/elenasrc3/ide/gtklinux/gtkdialogs.cpp @@ -0,0 +1,714 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA IDE +// GTK Static dialog implementations +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "gtkdialogs.h" + +//#include "Resource.h" +//#include "eng/messages.h" + +using namespace elena_lang; + +//// --- MsgBox --- +// +//int MsgBox :: show(HWND owner, const wchar_t* message, int type) +//{ +// return ::MessageBox(owner, message, APP_NAME, type); +//} +// +//int MsgBox :: showQuestion(HWND owner, const wchar_t* message) +//{ +// return show(owner, message, MB_YESNOCANCEL | MB_ICONQUESTION); +//} + +// --- FileDialog --- + +//const wchar_t* FileDialog::ProjectFilter = _T("ELENA Project file\0*.prj\0All types\0*.*\0\0"); +//const wchar_t* FileDialog::SourceFilter = _T("ELENA source file\0*.l\0All types\0*.*\0\0"); +// +FileDialog :: FileDialog(Gtk::Window* owner, const char** filter, int filterCounter, + const char* caption, const char* initialDir) +{ + _owner = owner; + _caption = caption; + _filter = filter; + _filterCounter = filterCounter; + _initialDir = initialDir; +} + +bool FileDialog :: openFile(PathString& path) +{ + Gtk::FileChooserDialog dialog(_caption, Gtk::FILE_CHOOSER_ACTION_OPEN); + dialog.set_transient_for(*_owner); + + if (!emptystr(_initialDir)) + dialog.set_current_folder (_initialDir); + + dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL); + dialog.add_button("_Open", Gtk::RESPONSE_OK); + + for (int i = 0; i < _filterCounter; i += 2) { + Glib::RefPtr filter_l = Gtk::FileFilter::create(); + + filter_l->set_name(_filter[i + 1]); + filter_l->add_pattern(_filter[i]); + dialog.add_filter(filter_l); + } + + int result = dialog.run(); + if (result == Gtk::RESPONSE_OK) { + std::string filename = dialog.get_filename(); + + path.copy(filename.c_str()); + + return true; + } + return false; +} + +bool FileDialog :: openFiles(List& files) +{ + Gtk::FileChooserDialog dialog(_caption, Gtk::FILE_CHOOSER_ACTION_OPEN); + dialog.set_transient_for(*_owner); + + if (!emptystr(_initialDir)) + dialog.set_current_folder (_initialDir); + + dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL); + dialog.add_button("_Open", Gtk::RESPONSE_OK); + + for (int i = 0; i < _filterCounter; i += 2) { + Glib::RefPtr filter_l = Gtk::FileFilter::create(); + + filter_l->set_name(_filter[i + 1]); + filter_l->add_pattern(_filter[i]); + dialog.add_filter(filter_l); + } + + int result = dialog.run(); + if (result == Gtk::RESPONSE_OK) { + std::string filename = dialog.get_filename(); + + files.add(StrUtil::clone(filename.c_str())); + + return true; + } + return false; + + return false; +} + +bool FileDialog :: saveFile(path_t ext, PathString& path) +{ +// _struct.Flags = _defaultFlags | OFN_PATHMUSTEXIST; +// _struct.lpstrDefExt = ext; +// +// if (::GetSaveFileName(&_struct)) { +// path.copy(_fileName); +// +// return true; +// } + /*else */return false; +} + +//MessageDialogBase::Answer MessageDialog :: question(text_str message, text_str param) +//{ +// WideMessage wideMessage(message); +// wideMessage.append(param); +// +// int result = MsgBox::show(_owner->handle(), *wideMessage, MB_YESNOCANCEL | MB_ICONQUESTION); +// +// if (MsgBox::isYes(result)) { +// return Answer::Yes; +// } +// else if (MsgBox::isCancel(result)) { +// return Answer::Cancel; +// } +// else return Answer::No; +//} +// +//MessageDialogBase::Answer MessageDialog :: question(text_str message) +//{ +// int result = MsgBox::show(_owner->handle(), message, MB_YESNOCANCEL | MB_ICONQUESTION); +// +// if (MsgBox::isYes(result)) { +// return Answer::Yes; +// } +// else if (MsgBox::isCancel(result)) { +// return Answer::Cancel; +// } +// else return Answer::No; +//} +// +//void MessageDialog :: info(text_str message) +//{ +// ::MessageBox(_owner->handle(), message, APP_NAME, MB_OK | MB_ICONWARNING); +//} +// +//// --- WinDialog --- +// +//BOOL CALLBACK WinDialog::DialogProc(HWND hWnd, size_t message, WPARAM wParam, LPARAM lParam) +//{ +// WinDialog* dialog = (WinDialog*)::GetWindowLongPtr(hWnd, GWLP_USERDATA); +// switch (message) { +// case WM_INITDIALOG: +// dialog = (WinDialog*)lParam; +// dialog->_handle = hWnd; +// ::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)lParam); +// +// dialog->onCreate(); +// +// return 0; +// case WM_COMMAND: +// dialog->doCommand(LOWORD(wParam), HIWORD(wParam)); +// return TRUE; +// default: +// return FALSE; +// } +//} +// +//void WinDialog :: doCommand(int id, int command) +//{ +// switch (id) { +// case IDOK: +// onOK(); +// ::EndDialog(_handle, IDOK); +// break; +// case IDCANCEL: +// ::EndDialog(_handle, IDCANCEL); +// break; +// } +//} +// +//int WinDialog :: show() +//{ +// return (int)::DialogBoxParam(_instance, MAKEINTRESOURCE(_dialogId), +// _owner->handle(), (DLGPROC)DialogProc, (LPARAM)this); +//} +// +//void WinDialog :: clearComboBoxItem(int id) +//{ +// LRESULT counter = ::SendDlgItemMessage(_handle, id, CB_GETCOUNT, 0, 0); +// while (counter > 0) { +// ::SendDlgItemMessage(_handle, id, CB_DELETESTRING, 0, 0); +// +// counter--; +// } +//} +// +//void WinDialog :: addComboBoxItem(int id, const wchar_t* text) +//{ +// ::SendDlgItemMessage(_handle, id, CB_ADDSTRING, 0, (LPARAM)text); +//} +// +//void WinDialog :: setComboBoxIndex(int id, int index) +//{ +// ::SendDlgItemMessage(_handle, id, CB_SETCURSEL, index, 0); +//} +// +//int WinDialog :: getComboBoxIndex(int id) +//{ +// return (int)::SendDlgItemMessage(_handle, id, CB_GETCURSEL, 0, 0); +//} +// +//void WinDialog :: addListItem(int id, const wchar_t* text) +//{ +// ::SendDlgItemMessage(_handle, id, LB_ADDSTRING, 0, (LPARAM)text); +//} +// +//int WinDialog :: getListSelCount(int id) +//{ +// return (int)::SendDlgItemMessage(_handle, id, LB_GETSELCOUNT, 0, 0); +//} +// +//int WinDialog :: getListIndex(int id) +//{ +// return (int)::SendDlgItemMessage(_handle, id, LB_GETCURSEL, 0, 0); +//} +// +//void WinDialog :: setText(int id, const wchar_t* text) +//{ +// ::SendDlgItemMessage(_handle, id, WM_SETTEXT, 0, (LPARAM)text); +//} +// +//void WinDialog :: setIntText(int id, int value) +//{ +// String s; +// s.appendInt(value); +// +// ::SendDlgItemMessage(_handle, id, WM_SETTEXT, 0, (LPARAM)(s.str())); +//} +// +//void WinDialog :: setTextLimit(int id, int maxLength) +//{ +// ::SendDlgItemMessage(_handle, id, EM_SETLIMITTEXT, maxLength, 0); +//} +// +//void WinDialog :: getText(int id, wchar_t** text, int length) +//{ +// ::SendDlgItemMessage(_handle, id, WM_GETTEXT, length, (LPARAM)text); +//} +// +//int WinDialog :: getIntText(int id) +//{ +// wchar_t s[13]; +// +// ::SendDlgItemMessage(_handle, id, WM_GETTEXT, 12, (LPARAM)s); +// +// return StrConvertor::toInt(s, 10); +//} +// +//void WinDialog :: setCheckState(int id, bool value) +//{ +// ::SendDlgItemMessage(_handle, id, BM_SETCHECK, value ? BST_CHECKED : BST_UNCHECKED, 0); +//} +// +//void WinDialog :: setUndefinedCheckState(int id) +//{ +// ::SendDlgItemMessage(_handle, id, BM_SETCHECK, BST_INDETERMINATE, 0); +//} +// +//bool WinDialog :: getCheckState(int id) +//{ +// return test((int)::SendDlgItemMessage(_handle, id, BM_GETCHECK, 0, 0), BST_CHECKED); +//} +// +//bool WinDialog :: isUndefined(int id) +//{ +// return test((int)::SendDlgItemMessage(_handle, id, BM_GETCHECK, 0, 0), BST_INDETERMINATE); +//} +// +//void WinDialog :: enable(int id, bool enabled) +//{ +// ::EnableWindow(::GetDlgItem(_handle, id), enabled ? TRUE : FALSE); +//} +// +//// --- ProjectSettings --- +// +//ProjectSettings :: ProjectSettings(HINSTANCE instance, WindowBase* owner, ProjectModel* model) +// : WinDialog(instance, owner, IDD_SETTINGS) +//{ +// _model = model; +//} +// +//void ProjectSettings :: loadTemplateList() +//{ +// int selected = 0; +// int current = 0; +// for (auto it = _model->projectTypeList.start(); !it.eof(); ++it) { +// ustr_t key = *it; +// if (_model->templateName.compare(key)) { +// selected = current; +// } +// +// WideMessage caption(key); +// addComboBoxItem(IDC_SETTINGS_TEPMPLATE, *caption); +// current++; +// } +// +// setComboBoxIndex(IDC_SETTINGS_TEPMPLATE, selected); +//} +// +//void ProjectSettings :: loadProfileList() +//{ +// int selected = 0; +// int current = 0; +// for (auto it = _model->profileList.start(); !it.eof(); ++it) { +// ustr_t key = *it; +// if (_model->profile.compare(key)) { +// selected = current; +// } +// +// WideMessage caption(key); +// addComboBoxItem(IDC_SETTINGS_PROFILE, *caption); +// current++; +// } +// +// setComboBoxIndex(IDC_SETTINGS_PROFILE, selected); +//} +// +//void ProjectSettings :: onCreate() +//{ +// setTextLimit(IDC_SETTINGS_PACKAGE, IDENTIFIER_LEN); +// +// WideMessage caption(*_model->package); +// setText(IDC_SETTINGS_PACKAGE, caption.str()); +// +// WideMessage optionCaption(*_model->options); +// setText(IDC_SETTINGS_OPTIONS, optionCaption.str()); +// +// WideMessage targetCaption(*_model->target); +// setText(IDC_SETTINGS_TARGET, targetCaption.str()); +// +// setText(IDC_SETTINGS_OUTPUT, *_model->outputPath); +// +// setText(IDC_SETTINGS_ARGUMENT, *_model->debugArguments); +// +// addComboBoxItem(IDC_SETTINGS_DEBUG, _T("Disabled")); +// addComboBoxItem(IDC_SETTINGS_DEBUG, _T("Enabled")); +// +// //int mode = _project->getDebugMode(); +// //if (mode != 0) { +// setComboBoxIndex(IDC_SETTINGS_DEBUG, 1); +// //} +// //else setComboBoxIndex(IDC_SETTINGS_DEBUG, 0); +// +// if (_model->strictType == FLAG_UNDEFINED) { +// setUndefinedCheckState(IDC_SETTINGS_STRICTTYPE); +// } +// else setCheckState(IDC_SETTINGS_STRICTTYPE, _model->strictType == -1); +// +// loadTemplateList(); +// loadProfileList(); +//} +// +//void ProjectSettings :: onOK() +//{ +// wchar_t name[IDENTIFIER_LEN + 1]; +// +// if (getComboBoxIndex(IDC_SETTINGS_TEPMPLATE) != -1) { +// getText(IDC_SETTINGS_TEPMPLATE, (wchar_t**)(&name), IDENTIFIER_LEN); +// +// IdentifierString value(name); +// _model->templateName.copy(*value); +// } +// +// if (getComboBoxIndex(IDC_SETTINGS_PROFILE) != -1) { +// getText(IDC_SETTINGS_PROFILE, (wchar_t**)(&name), IDENTIFIER_LEN); +// +// IdentifierString value(name); +// _model->profile.copy(*value); +// } +// +// getText(IDC_SETTINGS_PACKAGE, (wchar_t**)(&name), IDENTIFIER_LEN); +// if (getlength(name) > 0) { +// IdentifierString value(name); +// _model->package.copy(*value); +// } +// else _model->package.clear(); +// +// getText(IDC_SETTINGS_OPTIONS, (wchar_t**)(&name), IDENTIFIER_LEN); +// if (getlength(name) > 0) { +// IdentifierString value(name); +// _model->options.copy(*value); +// } +// else _model->options.clear(); +// +// getText(IDC_SETTINGS_TARGET, (wchar_t**)(&name), IDENTIFIER_LEN); +// if (getlength(name) > 0) { +// IdentifierString value(name); +// _model->target.copy(*value); +// } +// else _model->target.clear(); +// +// getText(IDC_SETTINGS_OUTPUT, (wchar_t**)(&name), IDENTIFIER_LEN); +// _model->outputPath.copy(name); +// +// getText(IDC_SETTINGS_ARGUMENT, (wchar_t**)(&name), IDENTIFIER_LEN); +// _model->debugArguments.copy(name); +// +// if (isUndefined(IDC_SETTINGS_STRICTTYPE)) { +// _model->strictType = FLAG_UNDEFINED; +// } +// else if (getCheckState(IDC_SETTINGS_STRICTTYPE)) { +// _model->strictType = -1; +// } +// else _model->strictType = 0; +// +// if (!_model->singleSourceProject) +// _model->notSaved = true; +//} +// +//bool ProjectSettings :: showModal() +//{ +// return show() == IDOK; +//} +// +//// --- EditorSettings --- +// +//EditorSettings :: EditorSettings(HINSTANCE instance, WindowBase* owner, TextViewModelBase* model) +// : WinDialog(instance, owner, IDD_EDITOR_SETTINGS) +//{ +// _model = model; +//} +// +//void EditorSettings::onCreate() +//{ +// addComboBoxItem(IDC_EDITOR_COLORSCHEME, _T("Default")); +// addComboBoxItem(IDC_EDITOR_COLORSCHEME, _T("Classic")); +// addComboBoxItem(IDC_EDITOR_COLORSCHEME, _T("Dark")); +// +// setComboBoxIndex(IDC_EDITOR_COLORSCHEME, _model->schemeIndex); +// +// setCheckState(IDC_EDITOR_HIGHLIGHSYNTAXFLAG, _model->highlightSyntax); +// setCheckState(IDC_EDITOR_LINENUMBERFLAG, _model->lineNumbersVisible); +// +// // populate font size combo box +// String size; +// for (int i = 8; i < 25; i++) { +// size.appendInt(i); +// addComboBoxItem(IDC_EDITOR_FONTSIZE, size.str()); +// size.clear(); +// } +// +// setComboBoxIndex(IDC_EDITOR_FONTSIZE, _model->fontSize - 8); +//} +// +//void EditorSettings :: onOK() +//{ +// int index = getComboBoxIndex(IDC_EDITOR_COLORSCHEME); +// if (index != -1) +// _model->schemeIndex = index; +// +// int fontSize = getComboBoxIndex(IDC_EDITOR_COLORSCHEME) + 8; +// if (_model->fontSize != fontSize) { +// _model->fontSize = fontSize; +// } +// +// bool value = getCheckState(IDC_EDITOR_HIGHLIGHSYNTAXFLAG); +// if (_model->highlightSyntax != value) +// _model->setHighlightMode(value); +// +// _model->lineNumbersVisible = getCheckState(IDC_EDITOR_LINENUMBERFLAG); +//} +// +//bool EditorSettings :: showModal() +//{ +// return show() == IDOK; +//} +// +//// --- IDESettings --- +// +//IDESettings :: IDESettings(HINSTANCE instance, WindowBase* owner, IDEModel* model) +// : WinDialog(instance, owner, IDD_IDE_SETTINGS) +//{ +// _model = model; +//} +// +//void IDESettings :: onCreate() +//{ +// setCheckState(IDC_IDE_REMEMBERPATH, _model->rememberLastPath); +// setCheckState(IDC_IDE_REMEMBERPROJECT, _model->rememberLastProject); +// setCheckState(IDC_IDE_PERSIST_CONSOLE, _model->projectModel.withPersistentConsole); +// setCheckState(IDC_IDE_APPMAXIMIZED, _model->appMaximized); +// setCheckState(IDC_IDE_AUTORECOMPILE, _model->projectModel.autoRecompile); +// setCheckState(IDC_IDE_AUTOSAVE, _model->autoSave); +//} +// +//void IDESettings :: onOK() +//{ +// _model->rememberLastPath = getCheckState(IDC_IDE_REMEMBERPATH); +// _model->rememberLastProject = getCheckState(IDC_IDE_REMEMBERPROJECT); +// _model->appMaximized = getCheckState(IDC_IDE_APPMAXIMIZED); +// _model->projectModel.withPersistentConsole = getCheckState(IDC_IDE_PERSIST_CONSOLE); +// _model->projectModel.autoRecompile = getCheckState(IDC_IDE_AUTORECOMPILE); +// _model->autoSave = getCheckState(IDC_IDE_AUTOSAVE); +//} +// +//bool IDESettings :: showModal() +//{ +// return show() == IDOK; +//} +// +//// --- DebuggerSettings --- +// +//DebuggerSettings :: DebuggerSettings(HINSTANCE instance, WindowBase* owner, ProjectModel* model) +// : WinDialog(instance, owner, IDD_DEBUGGER_SETTINGS) +//{ +// _model = model; +//} +// +//void DebuggerSettings :: onCreate() +//{ +// setText(IDC_DEBUGGER_SRCPATH, *_model->paths.librarySourceRoot); +// setText(IDC_DEBUGGER_LIBPATH, *_model->paths.libraryRoot); +//} +// +//void DebuggerSettings :: onOK() +//{ +// wchar_t value[IDENTIFIER_LEN + 1]; +// +// getText(IDC_DEBUGGER_SRCPATH, (wchar_t**)(&value), IDENTIFIER_LEN); +// _model->paths.librarySourceRoot.copy(value); +// +// getText(IDC_DEBUGGER_LIBPATH, (wchar_t**)(&value), IDENTIFIER_LEN); +// _model->paths.libraryRoot.copy(value); +//} +// +//bool DebuggerSettings::showModal() +//{ +// return show() == IDOK; +//} +// +//// --- FindDialog --- +// +//FindDialog :: FindDialog(HINSTANCE instance, WindowBase* owner, bool replaceMode, FindModel* model) +// : WinDialog(instance, owner, replaceMode ? IDD_EDITOR_REPLACE : IDD_EDITOR_FIND) +//{ +// _replaceMode = replaceMode; +// _model = model; +//} +// +//void FindDialog :: copyHistory(int id, SearchHistory* history) +//{ +// clearComboBoxItem(id); +// +// SearchHistory::Iterator it = history->start(); +// while (!it.eof()) { +// addComboBoxItem(id, *it); +// +// ++it; +// } +//} +// +//bool FindDialog :: showModal() +//{ +// return show() == IDOK; +//} +// +//void FindDialog :: onCreate() +//{ +// setText(IDC_FIND_TEXT, _model->text.str()); +// if (_replaceMode) { +// setText(IDC_REPLACE_TEXT, _model->newText.str()); +// } +// setCheckState(IDC_FIND_CASE, _model->matchCase); +// setCheckState(IDC_FIND_WHOLE, _model->wholeWord); +// +// copyHistory(IDC_FIND_TEXT, &_model->searchHistory); +// +// //if (_replaceHistory) { +// // copyHistory(IDC_REPLACE_TEXT, _replaceHistory); +// //} +//} +// +//void FindDialog :: onOK() +//{ +// wchar_t s[200]; +// +// getText(IDC_FIND_TEXT, (wchar_t**)(&s), 255); +// _model->text.copy(s); +// +// if (_replaceMode) { +// getText(IDC_REPLACE_TEXT, (wchar_t**)(&s), 255); +// _model->newText.copy(s); +// } +// +// _model->matchCase = getCheckState(IDC_FIND_CASE); +// _model->wholeWord = getCheckState(IDC_FIND_WHOLE); +//} +// +//// --- GoToLineDialog --- +// +//GoToLineDialog :: GoToLineDialog(HINSTANCE instance, WindowBase* owner) +// : WinDialog(instance, owner, IDD_GOTOLINE) +//{ +//} +// +//void GoToLineDialog :: onCreate() +//{ +// setIntText(IDC_GOTOLINE_LINENUMBER, _lineNumber); +//} +// +//void GoToLineDialog :: onOK() +//{ +// _lineNumber = getIntText(IDC_GOTOLINE_LINENUMBER); +//} +// +//bool GoToLineDialog :: showModal(int& row) +//{ +// _lineNumber = row; +// +// if (show() == IDOK) { +// row = _lineNumber; +// +// return true; +// } +// +// return false; +//} +// +//// --- WindowListDialog --- +// +//WindowListDialog :: WindowListDialog(HINSTANCE instance, WindowBase* owner, TextViewModel* model) +// : WinDialog(instance, owner, IDD_WINDOWS) +//{ +// _model = model; +// _selectedIndex = -1; +//} +// +//void WindowListDialog :: onListChange() +//{ +// enable(IDOK, (getListSelCount(IDC_WINDOWS_LIST) == 1)); +//} +// +//void WindowListDialog :: doCommand(int id, int command) +//{ +// switch (id) { +// case IDC_WINDOWS_LIST: +// if (command == LBN_SELCHANGE) { +// onListChange(); +// } +// break; +// case IDC_WINDOWS_CLOSE: +// _selectedIndex = getSelectedWindow(); +// ::EndDialog(_handle, -2); +// break; +// default: +// WinDialog::doCommand(id, command); +// break; +// } +//} +// +//int WindowListDialog :: getSelectedWindow() +//{ +// return getListIndex(IDC_WINDOWS_LIST); +//} +// +//void WindowListDialog :: onOK() +//{ +// _selectedIndex = getSelectedWindow(); +//} +// +//void WindowListDialog :: onCreate() +//{ +// int count = _model->getDocumentCount(); +// for (int i = 1; i <= count; i++) { +// path_t path = _model->getDocumentPath(i); +// +// addListItem(IDC_WINDOWS_LIST, path); +// } +//} +// +//WindowListDialogBase::SelectResult WindowListDialog :: selectWindow() +//{ +// int retVal = show(); +// +// if (retVal == IDOK) { +// return { _selectedIndex + 1, Mode::Activate }; +// } +// if (retVal == -2) { +// return { _selectedIndex + 1, Mode::Close }; +// } +// +// return { 0, Mode::None }; +//} +// +//// --- AboutDialog --- +// +//AboutDialog :: AboutDialog(HINSTANCE instance, WindowBase* owner) +// : WinDialog(instance, owner, IDD_ABOUT) +//{ +//} +// +//void AboutDialog :: onCreate() +//{ +// setText(IDC_ABOUT_LICENCE_TEXT, MIT_LICENSE); +// setText(IDC_ABOUT_HOME, ELENA_HOMEPAGE); +//} +// +//void AboutDialog :: onOK() +//{ +//} diff --git a/elenasrc3/ide/gtklinux/gtkdialogs.h b/elenasrc3/ide/gtklinux/gtkdialogs.h new file mode 100644 index 0000000000..250d973c60 --- /dev/null +++ b/elenasrc3/ide/gtklinux/gtkdialogs.h @@ -0,0 +1,240 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA IDE +// GTK: Static dialogs header +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef GTKDIALOGS_H +#define GTKDIALOGS_H + +#include "controller.h" +#include "gtklinux/gtkcommon.h" +//#include "editcontrol.h" +//#include "ideproject.h" +//#include "ideview.h" + +namespace elena_lang +{ +// class MsgBox +// { +// public: +// static int show(HWND owner, const wchar_t* message, int type); +// +// static int showQuestion(HWND owner, const wchar_t* message); +// +// static bool isCancel(int result) { return result == IDCANCEL; } +// static bool isYes(int result) { return result == IDYES; } +// static bool isNo(int result) { return result == IDNO; } +// }; + + // --- FileDialog --- + class FileDialog : public FileDialogBase + { + Gtk::Window* _owner; + + const char* _initialDir; + const char* _caption; + + const char** _filter; + int _filterCounter; +// +// OPENFILENAME _struct; +// wchar_t _fileName[MAX_PATH * 8]; // ?? +// int _defaultFlags; +// + public: +// static const wchar_t* ProjectFilter; +// static const wchar_t* SourceFilter; + + bool openFile(PathString& path) override; + bool openFiles(List& files) override; + bool saveFile(path_t ext, PathString& path) override; + + FileDialog(Gtk::Window* owner, const char** filter, int filterCounter, const char* caption, + const char* initialDir = nullptr); + }; +// +// class MessageDialog : public MessageDialogBase +// { +// WindowBase* _owner; +// +// public: +// Answer question(text_str message, text_str param) override; +// Answer question(text_str message) override; +// +// void info(text_str message) override; +// +// MessageDialog(WindowBase* owner) +// { +// _owner = owner; +// } +// }; +// +// class WinDialog +// { +// protected: +// HINSTANCE _instance; +// HWND _handle; +// +// WindowBase* _owner; +// int _dialogId; +// +// virtual void onCreate() = 0; +// virtual void onOK() = 0; +// +// virtual void doCommand(int id, int command); +// +// void enable(int id, bool enabled); +// +// void addComboBoxItem(int id, const wchar_t* text); +// void setComboBoxIndex(int id, int index); +// int getComboBoxIndex(int id); +// void clearComboBoxItem(int id); +// +// void addListItem(int id, const wchar_t* text); +// int getListSelCount(int id); +// int getListIndex(int id); +// +// void setText(int id, const wchar_t* text); +// void setIntText(int id, int value); +// void getText(int id, wchar_t** text, int length); +// int getIntText(int id); +// void setTextLimit(int id, int maxLength); +// +// void setCheckState(int id, bool value); +// void setUndefinedCheckState(int id); +// bool getCheckState(int id); +// bool isUndefined(int id); +// +// public: +// static BOOL CALLBACK DialogProc(HWND hwnd, size_t message, WPARAM wParam, LPARAM lParam); +// +// int show(); +// +// WinDialog(HINSTANCE instance, WindowBase* owner, int dialogId) +// : _handle(nullptr) +// { +// _instance = instance; +// _owner = owner; +// _dialogId = dialogId; +// } +// }; +// +// class ProjectSettings : public WinDialog, public ProjectSettingsBase +// { +// ProjectModel* _model; +// +// void loadTemplateList(); +// void loadProfileList(); +// +// void onCreate() override; +// void onOK() override; +// +// public: +// bool showModal() override; +// +// ProjectSettings(HINSTANCE instance, WindowBase* owner, ProjectModel* model); +// }; +// +// class EditorSettings : public WinDialog, public EditorSettingsBase +// { +// TextViewModelBase* _model; +// +// void onCreate() override; +// void onOK() override; +// +// public: +// bool showModal() override; +// +// EditorSettings(HINSTANCE instance, WindowBase* owner, TextViewModelBase* model); +// }; +// +// class IDESettings : public WinDialog, public IDESettingsBase +// { +// IDEModel* _model; +// +// void onCreate() override; +// void onOK() override; +// +// public: +// bool showModal() override; +// +// IDESettings(HINSTANCE instance, WindowBase* owner, IDEModel* model); +// }; +// +// class DebuggerSettings : public WinDialog, public DebuggerSettingsBase +// { +// ProjectModel* _model; +// +// void onCreate() override; +// void onOK() override; +// +// public: +// bool showModal() override; +// +// DebuggerSettings(HINSTANCE instance, WindowBase* owner, ProjectModel* model); +// }; +// +// class FindDialog : public WinDialog, public FindDialogBase +// { +// FindModel* _model; +// bool _replaceMode; +// +// void copyHistory(int id, SearchHistory* history); +// +// void onCreate() override; +// void onOK() override; +// +// public: +// bool showModal() override; +// +// FindDialog(HINSTANCE instance, WindowBase* owner, bool replaceMode, FindModel* model); +// }; +// +// // --- GoToLineDialog --- +// +// class GoToLineDialog : public WinDialog, public GotoDialogBase +// { +// int _lineNumber; +// +// void onCreate() override; +// void onOK() override; +// +// public: +// bool showModal(int& row) override; +// +// GoToLineDialog(HINSTANCE instance, WindowBase* owner); +// }; +// +// class WindowListDialog : public WinDialog, public WindowListDialogBase +// { +// TextViewModel* _model; +// int _selectedIndex; +// +// void doCommand(int id, int command) override; +// +// void onListChange(); +// +// int getSelectedWindow(); +// +// public: +// SelectResult selectWindow() override; +// +// void onCreate() override; +// void onOK() override; +// +// WindowListDialog(HINSTANCE instance, WindowBase* owner, TextViewModel* model); +// }; +// +// class AboutDialog : public WinDialog +// { +// public: +// void onCreate() override; +// void onOK() override; +// +// AboutDialog(HINSTANCE instance, WindowBase* owner); +// }; + +} + +#endif diff --git a/elenasrc3/ide/gtklinux/gtkide.cpp b/elenasrc3/ide/gtklinux/gtkide.cpp index a8f3cd30fb..ff227e747d 100644 --- a/elenasrc3/ide/gtklinux/gtkide.cpp +++ b/elenasrc3/ide/gtklinux/gtkide.cpp @@ -1,14 +1,14 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // Linux-GTK+ GTK IDE -// (C)2024, by Aleksey Rakov +// (C)2024-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "gtklinux/gtkide.h" +#include "eng/messages.h" using namespace elena_lang; - static Glib::ustring ui_info = "" " " @@ -126,9 +126,18 @@ static Glib::ustring ui_info = // " " ""; +const char* SOURCE_FILE_FILTER[] = +{ + "*.l", + "ELENA source file", + "*", + "Any files" +}; + // --- GTKIDEWindow --- GTKIDEWindow :: GTKIDEWindow(IDEController* controller, IDEModel* model) + : fileDialog(this, SOURCE_FILE_FILTER, 4, OPEN_FILE_CAPTION, *model->projectModel.paths.lastPath) { _model = model; _controller = controller; @@ -228,3 +237,31 @@ void GTKIDEWindow :: populateMenu() loadUI(ui_info, "/MenuBar"); } + +void GTKIDEWindow :: on_text_model_change(TextViewModelEvent event) +{ +// if (test(rec->status, STATUS_COLORSCHEME_CHANGED)) { +// onColorSchemeChange(); +// } +// + onDocumentUpdate(event.changeStatus); + onIDEStatusChange(event.status); +// if (test(rec->status, STATUS_FRAME_CHANGED)) { +// onDocumentSelection(); +// } +} + +void GTKIDEWindow :: onDocumentUpdate(DocumentChangeStatus changeStatus) +{ +} + +void GTKIDEWindow :: onIDEStatusChange(int status) +{ + //if (test(rec->status, STATUS_FRAME_VISIBILITY_CHANGED)) { + // if (_model->sourceViewModel.isAssigned()) { + //_children[_model->ideScheme.textFrameId]->show(); + //_children[_model->ideScheme.textFrameId]->setFocus(); + // } + //else _children[_model->ideScheme.textFrameId]->hide(); + //} +} diff --git a/elenasrc3/ide/gtklinux/gtkide.h b/elenasrc3/ide/gtklinux/gtkide.h index f379386652..b80752a095 100644 --- a/elenasrc3/ide/gtklinux/gtkide.h +++ b/elenasrc3/ide/gtklinux/gtkide.h @@ -1,18 +1,19 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA Linux-GTK IDE // -// (C)2024, by Aleksey Rakov +// (C)2024-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef GTKIDE_H #define GTKIDE_H #include "gtklinux/gtksdi.h" +#include "gtklinux/gtkdialogs.h" #include "idecontroller.h" - namespace elena_lang { + // --- GTKIDEView --- class GTKIDEWindow : public SDIWindow @@ -21,6 +22,8 @@ class GTKIDEWindow : public SDIWindow IDEModel* _model; IDEController* _controller; + FileDialog fileDialog; + void populateMenu(); // event signals @@ -34,7 +37,9 @@ class GTKIDEWindow : public SDIWindow } void on_menu_file_open_source() { - //_controller->doOpenFile(); + _controller->doOpenFile(fileDialog, _model); + //_recentFileList.reload(); + //_recentProjectList.reload(); } void on_menu_file_open_project() { @@ -262,7 +267,12 @@ class GTKIDEWindow : public SDIWindow { } + void onDocumentUpdate(DocumentChangeStatus changeStatus); + void onIDEStatusChange(int status); + public: + void on_text_model_change(TextViewModelEvent event); + GTKIDEWindow(/*const char* caption, */IDEController* controller, IDEModel* model); }; diff --git a/elenasrc3/ide/gtklinux/gtkidetextview.cpp b/elenasrc3/ide/gtklinux/gtkidetextview.cpp new file mode 100644 index 0000000000..c566964dd6 --- /dev/null +++ b/elenasrc3/ide/gtklinux/gtkidetextview.cpp @@ -0,0 +1,37 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA IDE +// Linux TextView container implementation +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "gtklinux/gtkidetextview.h" + +using namespace elena_lang; + +// --- IDETextViewFrame --- + +IDETextViewFrame :: IDETextViewFrame(TextViewModel* model, TextViewControllerBase* controller, ViewStyles* styles) + : TextViewFrame(model, controller, styles) +{ + +} + +void IDETextViewFrame :: on_text_model_change(TextViewModelEvent event) +{ + auto client = getCurrentTextView(); + if (client) + client->onDocumentUpdate(event.changeStatus); + + if (test(event.status, STATUS_FRAME_VISIBILITY_CHANGED)) { + if (client) + client->grab_focus(); + + //grab_focus(); + } + // if (_model->sourceViewModel.isAssigned()) { + //_children[_model->ideScheme.textFrameId]->show(); + //_children[_model->ideScheme.textFrameId]->setFocus(); + // } + //else _children[_model->ideScheme.textFrameId]->hide(); + //} +} diff --git a/elenasrc3/ide/gtklinux/gtkidetextview.h b/elenasrc3/ide/gtklinux/gtkidetextview.h new file mode 100644 index 0000000000..9461f0af98 --- /dev/null +++ b/elenasrc3/ide/gtklinux/gtkidetextview.h @@ -0,0 +1,26 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA IDE +// Linux TextView container declaration +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef GTKIDETEXTFRAME_H +#define GTKIDETEXTFRAME_H + +#include "gtklinux/gtktextframe.h" +#include "idecommon.h" + +namespace elena_lang +{ + +class IDETextViewFrame : public TextViewFrame +{ +public: + void on_text_model_change(TextViewModelEvent event); + + IDETextViewFrame(TextViewModel* model, TextViewControllerBase* controller, ViewStyles* styles); +}; + +} // _GUI_ + +#endif // winideH diff --git a/elenasrc3/ide/gtklinux/textframe.cpp b/elenasrc3/ide/gtklinux/textframe.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/elenasrc3/ide/ideversion.h b/elenasrc3/ide/ideversion.h index 483f561f32..62ed0a82af 100644 --- a/elenasrc3/ide/ideversion.h +++ b/elenasrc3/ide/ideversion.h @@ -1,2 +1,2 @@ -#define IDE_REVISION_NUMBER 19 +#define IDE_REVISION_NUMBER 21 diff --git a/elenasrc3/tools/asmc/armassembler.cpp b/elenasrc3/tools/asmc/armassembler.cpp index 5ea51e5b05..f71134ff6b 100644 --- a/elenasrc3/tools/asmc/armassembler.cpp +++ b/elenasrc3/tools/asmc/armassembler.cpp @@ -3,7 +3,7 @@ // // This file contains AARCH64 Assembler implementation // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -1148,6 +1148,12 @@ bool Arm64Assembler :: compileLDR(ScriptToken& tokenInfo, ARMOperand rt, ARMOper else if (rt.isDR() && ptr.isPostindex()) { writer.writeDWord(ARMHelper::makeImm9Opcode(3, 7, 1, 0, 1, 0, ptr.imm, 1, ptr.type, rt.type)); } + else if (rt.isDR() && ptr.isPreindex()) { + writer.writeDWord(ARMHelper::makeImm9Opcode(3, 7, 1, 0, 1, 0, ptr.imm, 3, ptr.type, rt.type)); + } + else if (rt.isDR() && ptr.isUnsigned()) { + writer.writeDWord(ARMHelper::makeImm12Opcode(3, 7, 1, 1, 1, ptr.imm >> 3, ptr.type, rt.type)); + } else return false; return true; @@ -1203,7 +1209,7 @@ bool Arm64Assembler :: compileLDRSW(ScriptToken& tokenInfo, ARMOperand rt, ARMOp writeReference(tokenInfo, ptr.reference, writer, ASM_INVALID_SOURCE); } else if (rt.isXR() && ptr.isUnsigned()) { - writer.writeDWord(ARMHelper::makeImm12Opcode(2, 7, 0, 1, 2, ptr.imm >> 3, ptr.type, rt.type)); + writer.writeDWord(ARMHelper::makeImm12Opcode(2, 7, 0, 1, 2, ptr.imm >> 2, ptr.type, rt.type)); } else return false; @@ -1448,6 +1454,9 @@ bool Arm64Assembler :: compileSTR(ScriptToken& tokenInfo, ARMOperand rt, ARMOper if (ptr.reference) writeReference(tokenInfo, ptr.reference, writer, ASM_INVALID_SOURCE); } + else if (rt.isWR() && ptr.isUnsigned()) { + writer.writeDWord(ARMHelper::makeImm12Opcode(2, 7, 0, 1, 0, ptr.imm >> 2, ptr.type, rt.type)); + } else if (rt.isXR() && ptr.isPostindex()) { writer.writeDWord(ARMHelper::makeImm9Opcode(3, 7, 0, 0, 0, 0, ptr.imm, 1, ptr.type, rt.type)); } @@ -1460,6 +1469,9 @@ bool Arm64Assembler :: compileSTR(ScriptToken& tokenInfo, ARMOperand rt, ARMOper else if (rt.isDR() && ptr.isPostindex()) { writer.writeDWord(ARMHelper::makeImm9Opcode(3, 7, 1, 0, 0, 0, ptr.imm, 1, ptr.type, rt.type)); } + else if (rt.isDR() && ptr.isUnsigned()) { + writer.writeDWord(ARMHelper::makeImm12Opcode(3, 7, 1, 1, 0, ptr.imm >> 3, ptr.type, rt.type)); + } else return false; return true; @@ -2937,6 +2949,20 @@ void Arm64Assembler::compileDQField(ScriptToken& tokenInfo, MemoryWriter& writer else writer.writeQWord(d); } +void Arm64Assembler :: compileDoubleField(ScriptToken& tokenInfo, MemoryWriter& writer) +{ + read(tokenInfo); + + if (tokenInfo.state == dfaQuote) { + double val = StrConvertor::toDouble(*tokenInfo.token); + + writer.writeDouble(val); + + read(tokenInfo); + } + else throw SyntaxError(ASM_INVALID_COMMAND, tokenInfo.lineInfo); +} + void Arm64Assembler :: compileProcedure(ScriptToken& tokenInfo) { ARMLabelHelper helper; diff --git a/elenasrc3/tools/asmc/armassembler.h b/elenasrc3/tools/asmc/armassembler.h index 5391ef075a..442d59f5b6 100644 --- a/elenasrc3/tools/asmc/armassembler.h +++ b/elenasrc3/tools/asmc/armassembler.h @@ -3,7 +3,7 @@ // // This header contains AARCH64 Assembler declarations // -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ARMASSEMBLER_H @@ -185,6 +185,7 @@ namespace elena_lang void compileDWField(ScriptToken& tokenInfo, MemoryWriter& writer) override; void compileDDField(ScriptToken& tokenInfo, MemoryWriter& writer) override; void compileDQField(ScriptToken& tokenInfo, MemoryWriter& writer) override; + void compileDoubleField(ScriptToken& tokenInfo, MemoryWriter& writer) override; void compileProcedure(ScriptToken& tokenInfo) override; diff --git a/elenasrc3/tools/asmc/asmconst.h b/elenasrc3/tools/asmc/asmconst.h index b15c9eb01f..a1545d57d6 100644 --- a/elenasrc3/tools/asmc/asmconst.h +++ b/elenasrc3/tools/asmc/asmconst.h @@ -12,7 +12,7 @@ namespace elena_lang { - #define ASM_REVISION_NUMBER 0x0008 + #define ASM_REVISION_NUMBER 0x000B constexpr auto N_ARGUMENT1 = "__n_1"; constexpr auto N_ARGUMENT2 = "__n_2"; diff --git a/elenasrc3/tools/asmc/assembler.cpp b/elenasrc3/tools/asmc/assembler.cpp index c40f8d2b6a..0f830b1248 100644 --- a/elenasrc3/tools/asmc/assembler.cpp +++ b/elenasrc3/tools/asmc/assembler.cpp @@ -3,7 +3,7 @@ // // This file contains the implementation of ELENA Assembler // classes. -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -431,6 +431,9 @@ void AssemblerBase :: compileStructure(ScriptToken& tokenInfo) else if (tokenInfo.compare("dq")) { compileDQField(tokenInfo, writer); } + else if (tokenInfo.compare("dbl")) { + compileDoubleField(tokenInfo, writer); + } else throw SyntaxError(ASM_SYNTAXERROR, tokenInfo.lineInfo); } } diff --git a/elenasrc3/tools/asmc/assembler.h b/elenasrc3/tools/asmc/assembler.h index 98c278afa4..a48f03a523 100644 --- a/elenasrc3/tools/asmc/assembler.h +++ b/elenasrc3/tools/asmc/assembler.h @@ -3,7 +3,7 @@ // // This header contains abstract Assembler declarations // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ASSEMBLER_H @@ -148,6 +148,7 @@ namespace elena_lang virtual void compileDWField(ScriptToken& tokenInfo, MemoryWriter& writer) = 0; virtual void compileDDField(ScriptToken& tokenInfo, MemoryWriter& writer) = 0; virtual void compileDQField(ScriptToken& tokenInfo, MemoryWriter& writer) = 0; + virtual void compileDoubleField(ScriptToken& tokenInfo, MemoryWriter& writer) = 0; virtual void compileProcedure(ScriptToken& tokenInfo) = 0; diff --git a/elenasrc3/tools/asmc/ppc64assembler.cpp b/elenasrc3/tools/asmc/ppc64assembler.cpp index 97c92e9bac..1c977a15fb 100644 --- a/elenasrc3/tools/asmc/ppc64assembler.cpp +++ b/elenasrc3/tools/asmc/ppc64assembler.cpp @@ -3,7 +3,7 @@ // // This file contains PPC64 Assembler implementation // -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -1923,6 +1923,20 @@ void PPC64Assembler::compileDQField(ScriptToken& tokenInfo, MemoryWriter& writer else writer.writeQWord(d); } +void PPC64Assembler::compileDoubleField(ScriptToken& tokenInfo, MemoryWriter& writer) +{ + read(tokenInfo); + + if (tokenInfo.state == dfaQuote) { + double val = StrConvertor::toDouble(*tokenInfo.token); + + writer.writeDouble(val); + + read(tokenInfo); + } + else throw SyntaxError(ASM_INVALID_COMMAND, tokenInfo.lineInfo); +} + bool PPC64Assembler :: compileAOpCode(ScriptToken& tokenInfo, MemoryWriter& writer) { if (tokenInfo.compare("addi")) { diff --git a/elenasrc3/tools/asmc/ppc64assembler.h b/elenasrc3/tools/asmc/ppc64assembler.h index b0a57254ee..52c864e1c1 100644 --- a/elenasrc3/tools/asmc/ppc64assembler.h +++ b/elenasrc3/tools/asmc/ppc64assembler.h @@ -3,7 +3,7 @@ // // This header contains PPC64 Assembler declarations // -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef PPC64ASSEMBLER_H @@ -148,6 +148,7 @@ namespace elena_lang void compileDWField(ScriptToken& tokenInfo, MemoryWriter& writer) override; void compileDDField(ScriptToken& tokenInfo, MemoryWriter& writer) override; void compileDQField(ScriptToken& tokenInfo, MemoryWriter& writer) override; + void compileDoubleField(ScriptToken& tokenInfo, MemoryWriter& writer) override; bool compileAOpCode(ScriptToken& tokenInfo, MemoryWriter& writer) override; bool compileBOpCode(ScriptToken& tokenInfo, MemoryWriter& writer, LabelScope& labelScope) override; diff --git a/elenasrc3/tools/asmc/x86assembler.cpp b/elenasrc3/tools/asmc/x86assembler.cpp index 4fbde60660..77874b3469 100644 --- a/elenasrc3/tools/asmc/x86assembler.cpp +++ b/elenasrc3/tools/asmc/x86assembler.cpp @@ -3,7 +3,7 @@ // // This file contains the implementation of ELENA Intel X86 Assembler // classes. -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -1460,6 +1460,11 @@ void X86Assembler :: compileDQField(ScriptToken& tokenInfo, MemoryWriter& writer else throw SyntaxError(ASM_INVALID_COMMAND, tokenInfo.lineInfo); } +void X86Assembler :: compileDoubleField(ScriptToken& tokenInfo, MemoryWriter& writer) +{ + throw SyntaxError(ASM_INVALID_COMMAND, tokenInfo.lineInfo); +} + bool X86Assembler :: compileAdc(X86Operand source, X86Operand target, MemoryWriter& writer) { if (source.type == X86OperandType::EAX && target.type == X86OperandType::DD) { diff --git a/elenasrc3/tools/asmc/x86assembler.h b/elenasrc3/tools/asmc/x86assembler.h index b9ff795c1b..4552ab53f8 100644 --- a/elenasrc3/tools/asmc/x86assembler.h +++ b/elenasrc3/tools/asmc/x86assembler.h @@ -3,7 +3,7 @@ // // This header contains x86 and x86-64 Assembler declarations // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef X86ASSEMBLER_H @@ -207,6 +207,7 @@ namespace elena_lang void compileDWField(ScriptToken& tokenInfo, MemoryWriter& writer) override; void compileDDField(ScriptToken& tokenInfo, MemoryWriter& writer) override; void compileDQField(ScriptToken& tokenInfo, MemoryWriter& writer) override; + void compileDoubleField(ScriptToken& tokenInfo, MemoryWriter& writer) override; bool compileAOpCode(ScriptToken& tokenInfo, MemoryWriter& writer) override; bool compileBOpCode(ScriptToken& tokenInfo, MemoryWriter& writer, LabelScope& labelScope) override; diff --git a/examples60/gui/helloworld/helloworld.xs b/examples60/gui/helloworld/helloworld.xs index dd4ae1a801..ddd4a8d5d8 100644 --- a/examples60/gui/helloworld/helloworld.xs +++ b/examples60/gui/helloworld/helloworld.xs @@ -1,6 +1,6 @@
-
\ No newline at end of file diff --git a/recompile60.mac.sh b/recompile60.mac.sh new file mode 100644 index 0000000000..a9bf588e2f --- /dev/null +++ b/recompile60.mac.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/src60/core/system.core_routines.esm b/src60/core/system.core_routines.esm index 8f663844d1..b2dcfe48e9 100644 --- a/src60/core/system.core_routines.esm +++ b/src60/core/system.core_routines.esm @@ -1181,6 +1181,17 @@ procedure __readIntPtrVal end +procedure __readPtrVal + + peek sp:0 + get i:0 + load + peek sp:1 + save + peek sp:0 + +end + procedure __readRealPtrVal peek sp:0 @@ -1192,6 +1203,17 @@ procedure __readRealPtrVal end +procedure __readLongPtrVal + + peek sp:0 + get i:0 + lload + peek sp:1 + lsave + peek sp:0 + +end + procedure __clearPtr(self) xflush sp:0 diff --git a/src60/elena_api.linux.prjcol b/src60/elena_api.linux.prjcol new file mode 100644 index 0000000000..7a185cdea8 --- /dev/null +++ b/src60/elena_api.linux.prjcol @@ -0,0 +1,7 @@ + + + system/system.linux.prj + extensions/extensions.linux.prj + ltests/ltests.linux.prj + + \ No newline at end of file diff --git a/src60/extensions/extensions.project b/src60/extensions/extensions.linux.prj similarity index 100% rename from src60/extensions/extensions.project rename to src60/extensions/extensions.linux.prj diff --git a/src60/forms/forms.prj b/src60/forms/forms.prj index 10747cc76e..9160cf818a 100644 --- a/src60/forms/forms.prj +++ b/src60/forms/forms.prj @@ -17,7 +17,7 @@ ELENA GUI Library - 6.5.0 + 6.6.0 Aleksey Rakov diff --git a/src60/forms/win32_controls.l b/src60/forms/win32_controls.l index 15cd840101..abdb73616b 100644 --- a/src60/forms/win32_controls.l +++ b/src60/forms/win32_controls.l @@ -316,7 +316,6 @@ abstract class BaseEdit : BaseWinControl retVal := styles } - } // --- Edit --- @@ -476,6 +475,66 @@ public closed class RadioButton : BaseButton, interface } } +// --- BaseList --- + +abstract class BaseList : BaseWinControl +{ + List _items; + + protected constructor new() + <= super new() + { + _items := new List(); + } + + internal updateStyles(ref int retVal) + { + int styles := retVal; + + if(_visible) + { styles := styles | WS_VISIBLE }; + if(_tabStop) + { styles := styles | WS_TABSTOP }; + + retVal := styles + } + + appendItem(string s) + { + _items.append(s); + } +} + +// --- Combobox --- + +public sealed class Combobox : BaseList, interface +{ + constructor new() + <= super new() + { + } + + internal createHandle() + { + WindowHandle parent := _parent; + + int styles := WS_CHILD | CBS_DROPDOWNLIST; + self.updateStyles(ref styles); + + _region.read(out int x, out int y, out int width, out int height); + + _handle := new WindowHandle( + 0, + ComboboxClass, + WideString.MinValue, + styles, + x, y, width, height, + parent, + CurrentInstance, + UnsafePointer.Default) + } +} + // --- Paintbox --- class PaintboxListener : WindowCallback @@ -879,9 +938,14 @@ public sealed class RadioButtonGroup : BasePanel, interface parent, CurrentInstance, paramPtr); - - if(_selected != -1 && nil != onIndexChanged) - { onIndexChanged(self) } + + if (_selected != -1) { + setChecked(true); + + if(nil != onIndexChanged) + { onIndexChanged(self) } + } + } int SelectedIndex diff --git a/src60/ltests/ltests.project b/src60/ltests/ltests.linux.prj similarity index 100% rename from src60/ltests/ltests.project rename to src60/ltests/ltests.linux.prj diff --git a/src60/net/http/common.l b/src60/net/http/common.l index 05bedec2e1..f359e0672d 100644 --- a/src60/net/http/common.l +++ b/src60/net/http/common.l @@ -1,4 +1,5 @@ import system'text'parsing; +import system'net; internal static RegEx UrlRegEx = new RegEx("^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]((\.|-+)?[0-9a-zA-Z])*(:(0-9)*)?(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_=]*)?$"); @@ -6,6 +7,7 @@ public sealed class Uri { string _scheme; string _host; + string _ip; string _port; string _path; string _query; @@ -21,9 +23,21 @@ public sealed class Uri get string Host() = _host; - get string Port() + get string IP() + = _query; + + get string PortValue() = _port ?? String.MinValue; + get short Port() + { + if:not:nil(_port) { + ^ ShortConvertor.convert(_port, 10); + }; + + ^ 0; + } + get string Path() = _path ?? String.MinValue; @@ -72,6 +86,9 @@ public sealed class Uri _query := url.Substring(index, len - index); }; + hostent h := hostent.load(_host); + _ip := h.IP; + ^ true; } diff --git a/src60/net/http/httpclient.l b/src60/net/http/httpclient.l index e69de29bb2..239992a365 100644 --- a/src60/net/http/httpclient.l +++ b/src60/net/http/httpclient.l @@ -0,0 +1,44 @@ +import system'net; +import system'threading; + +public class HttpClient +{ + HttpHeaders _headers; + Socket _socket; + + constructor new() + { + headers := new HttpHeaders(); + } + + HttpHeaders Headers + = headers; + + async Task getAsync(Uri uri) + { + /* Create TCP socket */ + _socket := new Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + /* Set remote->sin_addr.s_addr */ + SOCKADDR_IN remote := default; + + remote.Ip_address := uri.IP; + remote.Port := uri.Port; + + /* Connect */ + socket.open(remote); + + /* Send headers to server */ + NetworkStream stream := new NetworkStream(socket); + + :await stream.writeAsync(headers.Value); + + ^ new HttpResponse(stream); + + } + + close() + { + _socket.close() + } +} \ No newline at end of file diff --git a/src60/net/http/httpheaders.l b/src60/net/http/httpheaders.l new file mode 100644 index 0000000000..d8869a0730 --- /dev/null +++ b/src60/net/http/httpheaders.l @@ -0,0 +1,23 @@ +import system'text; + +public class HttpHeaders +{ + StringBuilder content; + + constructor() + { + content := new StringBuilder(); + } + + add(string name, string content) + { + content + .append(name) + .append(":") + .append(content) + .append($13$10); + } + + get string Value() + => content; +} \ No newline at end of file diff --git a/src60/net/http/httpresponse.l b/src60/net/http/httpresponse.l new file mode 100644 index 0000000000..92e9877916 --- /dev/null +++ b/src60/net/http/httpresponse.l @@ -0,0 +1,14 @@ +public class HttpResponse +{ + NetworkStream _stream; + + internal constructor(NetworkStream stream) + { + _stream := stream + } + + async Task ReadAsStringAsync() + { + + } +} \ No newline at end of file diff --git a/src60/net/net.prj b/src60/net/net.prj index 857cb9d639..62bed2577b 100644 --- a/src60/net/net.prj +++ b/src60/net/net.prj @@ -15,7 +15,7 @@ ELENA Network Provider Library - 6.5.0 + 6.6.0 Aleksey Rakov @@ -26,6 +26,8 @@ http\common.l + http\httpheaders.l + http\httpresponse.l http\httpclient.l diff --git a/src60/system/io/lnx_files.l b/src60/system/io/lnx_files.l index 8a7df41948..9687cfe8a7 100644 --- a/src60/system/io/lnx_files.l +++ b/src60/system/io/lnx_files.l @@ -2,6 +2,8 @@ import system'text; namespace io { + const int F_OK = 0; + const int SEEK_SET = 0; const int SEEK_CUR = 1; const int SEEK_END = 2; @@ -102,9 +104,39 @@ namespace io singleton fileControl { TextReader newReader(path) = TextStreamReader.new(path); + + TextWriter writer(path) = StreamWriter.new(FileStream.openForReWrite(path), UTF8Encoder); + + TextWriter writer(string path, Encoder encoder) = StreamWriter.new(FileStream.openForReWrite(path), encoder); + + TextWriter logger(path) = StreamWriter.new(FileStream.openForAppend(path), UTF8Encoder); + + bool isAvailable(path) + { + int ret := extern libc.access(path as::String, F_OK); + + ^ ret == 0 + } + + bool delete(path) + { + int ret := extern libc.remove(path as::String); + + ^ ret == 0 + } } singleton directoryControl { + bool isAvailable(path) + { + string s := path as::String; + if:not(s.endingWith("/")) + s := s + "/"; + + int ret := extern libc.access(s, F_OK); + + ^ ret == 0 + } } } \ No newline at end of file diff --git a/src60/system/net/networkstream.l b/src60/system/net/networkstream.l index 4dcba21987..8ba1fc3bcc 100644 --- a/src60/system/net/networkstream.l +++ b/src60/system/net/networkstream.l @@ -1,5 +1,6 @@ import system; import system'io; +import system'text; import system'threading; public class NetworkStream : Stream @@ -47,20 +48,57 @@ public class NetworkStream : Stream int read(byte[] dump, int length) = _socket.receive(dump, length, 0); - write(byte[] dump, int length) + int write(byte[] dump, int length) { - _socket.send(dump, length, 0); + int retVal := _socket.send(dump, length, 0); + + ^ retVal } indexed internal Task readAsync(byte[] dump, int length) = _socket.receiveAsync(dump, length, 0); - indexed internal Task writeAsync(byte[] dump, int length) + indexed internal Task writeAsync(byte[] dump, int length) = _socket.sendAsync(dump, length, 0); indexed internal bool isDataAvailable = _socket.available() != 0; + indexed async internal Task writeAsync(string s) + { + byte tmp[1024]; + int len := s.Length; + int index := 0; + while (len > 0) { + int sublen := 1024; + if (len < sublen) { + sublen := len; + }; + + int converted := UTF8Encoder.toByteArray(s, index, ref sublen, tmp, 0, 1024); + + converted := :await self.writeAsync(tmp, converted); + + index += converted; + len -= converted; + }; + } + + indexed async internal Task readAsStringAsync() + { + MemoryBuffer buffer := MemoryBuffer.allocate(); + + byte tmp[1024]; + int read := :await self.readAsync(tmp, 1024); + while (read > 0) { + buffer.write(0, read, tmp); + + read := :await self.readAsync(tmp, 1024); + }; + + ^ UTF8Encoding.toString(0, buffer.Length, buffer.Value); + } + close() { if (_ownStream) @@ -76,9 +114,50 @@ public extension AsyncStreamExtension : NetworkStream Task readAsync(byte[] dump, int length) = self.readAsync(dump, length); - Task writeAsync(byte[] dump, int length) + Task writeAsync(byte[] dump, int length) = self.writeAsync(dump, length); + Task writeAsync(string s) + = self.writeAsync(s); + + Task readAsStringAsync() + = self.readAsStringAsync(); + +// async Task writeAsync(string s) +// { +// byte tmp[1024]; +// int len := s.Length; +// int index := 0; +// while (len > 0) { +// int sublen := 1024; +// if (len < sublen) { +// sublen := len; +// }; +// +// int converted := UTF8Encoder.toByteArray(s, index, ref sublen, tmp, 0, 1024); +// +// converted := :await self.writeAsync(tmp, converted); +// +// index += converted; +// len -= converted; +// }; +// } + +// async Task readAsStringAsync() +// { +// MemoryBuffer buffer := MemoryBuffer.allocate(); +// +// byte tmp[1024]; +// int read := :await self.readAsync(tmp, 1024); +// while (read > 0) { +// buffer.write(0, read, tmp); +// +// read := :await self.readAsync(tmp, 1024); +// }; +// +// ^ UTF8Encoding.toString(0, buffer.Length, buffer.Value); +// } + bool isDataAvailable = self.isDataAvailable; } diff --git a/src60/system/net/win_sockets.l b/src60/system/net/win_sockets.l index 2fe003ed28..76986fea53 100644 --- a/src60/system/net/win_sockets.l +++ b/src60/system/net/win_sockets.l @@ -79,23 +79,93 @@ public sealed struct IN_ADDR } } +// --- hostent --- +public sealed struct hostent +{ + pointer h_name; + pointer h_aliases; + short h_addrtype; + short h_length; + pointer h_addr_list; + + static hostent load(string host) + { + hostent tmp := default; + + pointer ptr := extern WS2_32.gethostbyname(host); + + ptr.copyToUnsafe(tmp, $size tmp); + + ^ tmp + } + + get string IP() + { + if (h_addrtype == AF_INET) { + pointer addr := h_addr_list.Value; + pointer paddr_in := addr.Value; + + IN_ADDR addr_in := default; + addr_in.Value := paddr_in.getLongValue(); + + pointer pip := extern WS2_32.inet_ntoa(addr_in); + + ^ pip.getStringUnsafe(); + } + else { + SocketException.new("gethostbyname failed").raise() + }; + + ^ nil; + } +} + // --- SOCKADDR_IN --- public sealed packed SOCKADDR_IN { - short family : prop; - short port : prop; + short family; + short port; IN_ADDR sin_addr; byte sin_zero[4]; get constructor Default() = default; - set ip_address(string ip) + short Family { - long addr := extern WS2_32.inet_addr(ip); - - sin_addr.Value := addr + get() { ^ family } + + set(val) + { + family := val + } + } + + set Ip_address(string ip) + { + family := AF_INET; + + int retVal := extern WS2_32.inet_pton(AF_INET, ip, sin_addr); + + if (retVal < 0) { + SocketException.new("Can't set remote->sin_addr.s_addr", retVal).raise(); + } + else if (retVal == 0) { + SocketException.new("Not a valid IP", retVal).raise(); + } + } + + set Port(short value) + { + port := extern WS2_32.htons(value); + } + + get short Port() + { + short val := extern WS2_32.ntohs(port); + + ^ val } } @@ -211,6 +281,17 @@ public sealed const struct Socket { SocketException.new("Error at socket").raise() } } + open(SOCKADDR_IN sockAddr) + { + int retVal := extern WS2_32.connect( + _handle, + sockAddr, + $size sockAddr); + + if (SOCKET_ERROR == retVal) + { SocketException.new("Error at socket").raise() } + } + bind(pointer sockAddrPtr, int nameLen) { int retVal := extern WS2_32.bind(_handle, sockAddrPtr, nameLen); @@ -237,9 +318,9 @@ public sealed const struct Socket connect(string ip_address, int port) { SOCKADDR_IN addr := SOCKADDR_IN.Default; - addr.port := port; - addr.family := system'net'AF_INET; - addr.ip_address := ip_address; + addr.Port := port; + addr.Family := system'net'AF_INET; + addr.Ip_address := ip_address; pointer ptr := addr; int retVal := extern WS2_32.connect(_handle, ptr, SOCKADDR_IN_SIZE); diff --git a/src60/system/pointers.l b/src60/system/pointers.l index 98e89a10b0..686d624827 100644 --- a/src60/system/pointers.l +++ b/src60/system/pointers.l @@ -40,8 +40,10 @@ public sealed const struct UnsafePointer private clear() : external(system'core_routines'__clearPtr); private readIntPtr(out int retVal) : external(system'core_routines'__readIntPtr); + private readPtrValue(out UnsafePointer retVal) : external(system'core_routines'__readPtrVal); private readIntPtrValue(out int retVal) : external(system'core_routines'__readIntPtrVal); private readRealPtrValue(out real retVal) : external(system'core_routines'__readRealPtrVal); + private readLongPtrValue(out long retVal) : external(system'core_routines'__readLongPtrVal); private assignPtr(object obj) : external(system'core_routines'__assignPtr); constructor() @@ -88,7 +90,14 @@ public sealed const struct UnsafePointer ^ retVal } - get int Value() + get pointer Value() + { + self.readPtrValue(out pointer retVal); + + ^ retVal + } + + get retoverload int Value() { self.readIntPtrValue(out int retVal); @@ -102,6 +111,13 @@ public sealed const struct UnsafePointer ^ retVal } + get retoverload long Value() + { + self.readLongPtrValue(out long retVal); + + ^ retVal + } + get retoverload string Value() { ^ PrimitivePointerOperations.readString(self); @@ -112,6 +128,22 @@ public sealed const struct UnsafePointer ^ PrimitivePointerOperations.readWideString(self); } + long getLongValue() + { + long val := self.Value; + + ^ val; + } + + string getStringUnsafe() + { + string str := self.Value; + + ^ str + } + + copyToUnsafe(object ptr, int length) : external(system'core_routines'__ptrCopyTo); + copyTo(byte[] target, int len) : external(system'core_routines'__ptrCopyTo); copyTo(byte[] target, int index, int len) : external(system'core_routines'__ptrCopySubTo); } diff --git a/src60/system/system.project b/src60/system/system.linux.prj similarity index 95% rename from src60/system/system.project rename to src60/system/system.linux.prj index 7e4d453943..550fad335e 100644 --- a/src60/system/system.project +++ b/src60/system/system.linux.prj @@ -1,7 +1,7 @@ - /usr/lib/elena/lib60 + ../../lib60 @@ -12,7 +12,7 @@ - /usr/lib/elena/lib60_64 + ../../lib60_64 @@ -23,7 +23,7 @@ - /usr/lib/elena/lib60_64 + ../../lib60_64 @@ -34,7 +34,7 @@ - /usr/lib/elena/lib60_64 + ../../lib60_64 @@ -50,7 +50,7 @@ ELENA Standard Library - 6.5.0 + 6.6.0 Aleksey Rakov diff --git a/src60/system/text/parsing/regex.l b/src60/system/text/parsing/regex.l index f67f83a502..4740d58ffe 100644 --- a/src60/system/text/parsing/regex.l +++ b/src60/system/text/parsing/regex.l @@ -244,8 +244,8 @@ public sealed class RegEx private PatternRule? defineRule(char ch) { - ch => - $47: { ^ new AnyRule() }; + ch => + $46: { ^ new AnyRule() }; if (isReserved(ch)) { ^ nil }; @@ -436,7 +436,7 @@ public sealed class RegEx List list := new List(); parseLine(list, pattern, ref i, len, $36); - if (i < len && pattern[i] == $36) { + if (i < len && pattern[i] == $36) { list.append(EOLRule); i++; diff --git a/src60/system/winforms/win_common.l b/src60/system/winforms/win_common.l index 9e1d461af0..a1f69f39c9 100644 --- a/src60/system/winforms/win_common.l +++ b/src60/system/winforms/win_common.l @@ -70,6 +70,10 @@ public const int BS_AUTORADIOBUTTON = 9; public const int BST_CHECKED = 1; public const int BST_UNCHECKED = 0; +// --- combobox styles --- +public const int CBS_DROPDOWNLIST = 3; +public const int CBS_DROPDOWN = 2; + // --- Notifications --- public const int BN_CLICKED = 0000h; public const int EN_CHANGE = 0300h; diff --git a/src60/system/winforms/win_controls.l b/src60/system/winforms/win_controls.l index 8713d2fac6..453d93e600 100644 --- a/src60/system/winforms/win_controls.l +++ b/src60/system/winforms/win_controls.l @@ -5,6 +5,7 @@ import system'drawing; public const wide ButtonClass = "Button"w; public const wide EditClass = "Edit"w; public const wide StaticClass = "Static"w; +public const wide ComboboxClass = "Combobox"w; // --- WindowHandle --- diff --git a/tests60/sandbox/sandbox.l b/tests60/sandbox/sandbox.l index 55a74ffb70..78169e0623 100644 --- a/tests60/sandbox/sandbox.l +++ b/tests60/sandbox/sandbox.l @@ -1,75 +1,11 @@ import extensions; -//import system'math; -// -//public extension lazyOp -//{ -// whileFalse(Func action) -// { -// until(self) -// { -// action() -// } -// } -//} -// -//public program() -//{ -// var n := 1; -// -// (:lazy (n.sqr().mod(100) == 64)).whileFalse({ n := n + 1 }); -// -// console.printLine(n) -//} -//#new __symbol aliases; - -//#let aliases["myint"] := system'IntNumber; - -//#load sandbox'aliases; - -//myint X = 2; -/* -class MyException : Exception -{ - constructor new(s) - <= super new(s); -} -*/ -class MyException2 : Exception +public program() { - constructor new(s) - <= super new(s); -} + real r := 1.0; -singleton ExecTester -{ -/* break() - { - MyException.new("OnError handler works").raise() - } -*/ - break2() - { - MyException2.new("OnError2 handler works").raise() - } -/* - break3() - { - MyException2.new("Nested OnError2 handler works").raise() - }*/ -} + real z := r.exp(); + console.printLine(z); -public program() -{ -/* try - { - ExecTester.break2() - } - catch:: - { - function(MyException2 e) - { - } - };*/ - console.write("."); -} + console.printLine(z.ln()); +} \ No newline at end of file diff --git a/tests60/system_tests/basic.l b/tests60/system_tests/basic.l index 361d5c447f..50ca86802e 100644 --- a/tests60/system_tests/basic.l +++ b/tests60/system_tests/basic.l @@ -1411,20 +1411,24 @@ public duplicateBoxing() : testCase() t := 2; t2 += 1; }); - + console.write("."); + Assert.ifTrue(t == 2); Assert.ifTrue(t2 == 2); + console.write("."); -// var mode := -1; -// var value := false; -// value ? { mode := 0 } : { mode := 1 } ; -// -// Assert.ifTrue(mode == 1); -// -// value := true; -// value ? { mode := 0 } : { mode := 1 } ; -// -// Assert.ifTrue(mode == 0); + var mode := -1; + var value := false; + value ? { mode := 0 } ! { mode := 1 }; + + Assert.ifTrue(mode == 1); + console.write("."); + + mode := -1; + value := true; + value ? { mode := 0 } ! { mode := 1 }; + + Assert.ifTrue(mode == 0); console.write(".") } diff --git a/tests60/system_tests/system_tests.prj b/tests60/system_tests/system_tests.prj index 8c2e75a518..c94bea0737 100644 --- a/tests60/system_tests/system_tests.prj +++ b/tests60/system_tests/system_tests.prj @@ -9,6 +9,26 @@ system_tests64.exe + + + 4129 + + + + + 4130 + + + + + 4133 + + + + + 4132 + + system_tests diff --git a/tests60/system_tests/system_tests.project b/tests60/system_tests/system_tests.project deleted file mode 100644 index ea1cfa66e0..0000000000 --- a/tests60/system_tests/system_tests.project +++ /dev/null @@ -1,32 +0,0 @@ - - - - 4129 - - - - - 4130 - - - - - 4133 - - - - - 4132 - - - - system_tests - - - - - main.l - basic.l - - - \ No newline at end of file From d0314b6f6c836debf711468541c90afcd3dd7f1b Mon Sep 17 00:00:00 2001 From: arakov Date: Sat, 15 Mar 2025 15:06:10 +0100 Subject: [PATCH 10/53] fixing net library --- src60/net/http/httpclient.l | 12 ++++++------ src60/net/http/httpresponse.l | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src60/net/http/httpclient.l b/src60/net/http/httpclient.l index 239992a365..55c414aced 100644 --- a/src60/net/http/httpclient.l +++ b/src60/net/http/httpclient.l @@ -8,11 +8,11 @@ public class HttpClient constructor new() { - headers := new HttpHeaders(); + _headers := new HttpHeaders(); } HttpHeaders Headers - = headers; + = _headers; async Task getAsync(Uri uri) { @@ -26,14 +26,14 @@ public class HttpClient remote.Port := uri.Port; /* Connect */ - socket.open(remote); + _socket.open(remote); /* Send headers to server */ - NetworkStream stream := new NetworkStream(socket); + NetworkStream stream := new NetworkStream(_socket); - :await stream.writeAsync(headers.Value); + :await stream.writeAsync(_headers.Value); - ^ new HttpResponse(stream); + ^ HttpResponse.assign(stream); } diff --git a/src60/net/http/httpresponse.l b/src60/net/http/httpresponse.l index 92e9877916..ee530ab9c2 100644 --- a/src60/net/http/httpresponse.l +++ b/src60/net/http/httpresponse.l @@ -1,8 +1,11 @@ +import system'net; +import system'threading; + public class HttpResponse { NetworkStream _stream; - internal constructor(NetworkStream stream) + internal constructor assign(NetworkStream stream) { _stream := stream } From 933c9fa1afa6cf8324068dc0389144eae76f7689 Mon Sep 17 00:00:00 2001 From: arakov Date: Sun, 16 Mar 2025 17:16:14 +0100 Subject: [PATCH 11/53] house keeping --- build/amd64/build_package_amd64.script | 2 +- build/amd64/local_build_package_amd64.script | 106 +++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 build/amd64/local_build_package_amd64.script diff --git a/build/amd64/build_package_amd64.script b/build/amd64/build_package_amd64.script index 4309011910..0caaeae1d6 100755 --- a/build/amd64/build_package_amd64.script +++ b/build/amd64/build_package_amd64.script @@ -1,7 +1,7 @@ #!/bin/bash RELEASE=elena-6.6.2.amd64-linux -mkdir -p ../lib60_64 +mkdir -p ../../lib60_64 mkdir -p /usr/share/elena mkdir -p /etc/elena/ mkdir -p /etc/elena/templates/ diff --git a/build/amd64/local_build_package_amd64.script b/build/amd64/local_build_package_amd64.script new file mode 100644 index 0000000000..3cd77ccf1b --- /dev/null +++ b/build/amd64/local_build_package_amd64.script @@ -0,0 +1,106 @@ +#!/bin/bash + +mkdir -p ../../lib60_64 +mkdir -p ../../bin/amd64 + +echo compiling data files + +../../bin/sg64-cli ../../dat/sg/syntax60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli ../../dat/og/bc_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli -s ../../dat/og/bt_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + + +cp ../../dat/og/*.dat ../../bin +cp ../../dat/sg/syntax60.dat ../../bin + +echo compiling assembly files + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60.asm ../../bin/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60_lnx.asm ../../bin/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +# echo compiling lib60 files + + ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm ../../lib60_64 + ret=$? + if [ $ret -eq 0 ] + then + echo . + else + echo "Failure" >&2 + exit 1 + fi + + ../../bin/elena64-cli ../../src60/elena_api.linux.prjcol + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + elena64-cli ../../tests60/system_tests/system_tests.prj + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + ../../tests60/system_tests/system_tests + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + +exit 0 \ No newline at end of file From 9f656e3bc3d39a4913266cf9ee932305030a57e4 Mon Sep 17 00:00:00 2001 From: arakov Date: Thu, 20 Mar 2025 09:20:02 +0100 Subject: [PATCH 12/53] adding nightly work flow --- .github/workflows/nightly.yml | 80 +++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 .github/workflows/nightly.yml diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000000..f5c87ade7b --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,80 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: MSBuild + +on: + schedule: + - cron: '30 2 * * *' # Run once per day, to avoid Coverity's submission limits + push: + branches: [ "iteration38" ] + paths: + - elenasrc3/** + - asm/** + - src60/** + - examples60/** + +env: + # Path to the solution file relative to the root of the project. + SOLUTION_FILE_PATH: .\elenasrc3\elenasrc3.sln + + # Configuration type to build. + # You can convert this to a build matrix if you need coverage of multiple configuration types. + # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + BUILD_CONFIGURATION: Debug + + BUILD_TAG: 6.6.3 + +permissions: + contents: read + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [windows-latest] + platform: [x86, x64] + + steps: + - uses: actions/checkout@v4 + + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v2 + + - name: Setup Nuget + uses: Nuget/setup-nuget@v1.0.5 + + - name: Restore nuget packages + run: nuget restore ${{env.SOLUTION_FILE_PATH}} + + - name: Build + working-directory: ${{env.GITHUB_WORKSPACE}} + # Add additional options to the MSBuild command line here (like platform or verbosity level). + # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference + run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} /p:platform=${{ matrix.platform }} /m:2 + + - name: Generate Data + shell: cmd + run: build\rebuild_data60_${{matrix.platform}}.bat + + - name: Run Tests + shell: cmd + run: bin\elena-tests-${{matrix.platform}}.exe + + - name: Compile Lib + shell: cmd + run: build\rebuild_lib60_${{matrix.platform}}.bat + + - name: Prepare Artifact + shell: cmd + run: build\create_package_${{matrix.platform}}.bat + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }} + path: build\${{matrix.platform}} From 4fd59efcc3ba7eecf3973e362e3b1467c8971183 Mon Sep 17 00:00:00 2001 From: arakov Date: Thu, 20 Mar 2025 09:22:33 +0100 Subject: [PATCH 13/53] housekeeping --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index f5c87ade7b..30782f980c 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -3,7 +3,7 @@ # separate terms of service, privacy policy, and support # documentation. -name: MSBuild +name: Nightly MSBuild on: schedule: From 6561efaa077b3805881b0c17c647d2d060b24f93 Mon Sep 17 00:00:00 2001 From: arakov Date: Thu, 20 Mar 2025 09:26:29 +0100 Subject: [PATCH 14/53] testing --- .github/workflows/nightly.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 30782f980c..a98bc8c934 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -6,6 +6,11 @@ name: Nightly MSBuild on: + workflow_call: + inputs: + env: + description: 'Test' + required: true schedule: - cron: '30 2 * * *' # Run once per day, to avoid Coverity's submission limits push: From b94d88805a933ee0887e9b824be2e87dc8dfaa7d Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Thu, 20 Mar 2025 09:30:27 +0100 Subject: [PATCH 15/53] Update nightly.yml --- .github/workflows/nightly.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index a98bc8c934..cc5632b2e3 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -7,10 +7,6 @@ name: Nightly MSBuild on: workflow_call: - inputs: - env: - description: 'Test' - required: true schedule: - cron: '30 2 * * *' # Run once per day, to avoid Coverity's submission limits push: From d05dbdb116e8d024bd7776783e9478ff5d8c61b8 Mon Sep 17 00:00:00 2001 From: arakov Date: Thu, 20 Mar 2025 09:33:50 +0100 Subject: [PATCH 16/53] housekeeping --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index cc5632b2e3..46cca2603b 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -6,7 +6,6 @@ name: Nightly MSBuild on: - workflow_call: schedule: - cron: '30 2 * * *' # Run once per day, to avoid Coverity's submission limits push: @@ -16,6 +15,7 @@ on: - asm/** - src60/** - examples60/** + workflow_dispatch: # Put here!! env: # Path to the solution file relative to the root of the project. From 5e71e1eddd11922bd55454aa0c4e416c8638c7e7 Mon Sep 17 00:00:00 2001 From: arakov Date: Thu, 20 Mar 2025 09:50:07 +0100 Subject: [PATCH 17/53] housekeeping --- .github/workflows/msbuild.yml | 1 + .github/workflows/nightly.yml | 9 ++------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 7954345aee..93beae0c08 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -10,6 +10,7 @@ on: branches: [ "master" ] pull_request: branches: [ "master" ] + workflow_dispatch: # Put here!! env: # Path to the solution file relative to the root of the project. diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 46cca2603b..0909aef742 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -8,13 +8,6 @@ name: Nightly MSBuild on: schedule: - cron: '30 2 * * *' # Run once per day, to avoid Coverity's submission limits - push: - branches: [ "iteration38" ] - paths: - - elenasrc3/** - - asm/** - - src60/** - - examples60/** workflow_dispatch: # Put here!! env: @@ -42,6 +35,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + ref: iteration38 - name: Add MSBuild to PATH uses: microsoft/setup-msbuild@v2 From 3ad6e65e646a7d53098dc5c432f3e5650080505a Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Thu, 20 Mar 2025 09:52:30 +0100 Subject: [PATCH 18/53] Update nightly.yml --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 0909aef742..f5d7c44ee8 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -7,7 +7,7 @@ name: Nightly MSBuild on: schedule: - - cron: '30 2 * * *' # Run once per day, to avoid Coverity's submission limits + - cron: '30 2 * * *' # Run once per day workflow_dispatch: # Put here!! env: From dfc59e63122466775e6ef4568ac5c6505ef1f63d Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Thu, 20 Mar 2025 10:01:10 +0100 Subject: [PATCH 19/53] Update nightly.yml --- .github/workflows/nightly.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index f5d7c44ee8..b52dbba6fa 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -33,11 +33,11 @@ jobs: os: [windows-latest] platform: [x86, x64] - steps: + steps: - uses: actions/checkout@v4 - with: - ref: iteration38 - + with: + ref: iteration38 + - name: Add MSBuild to PATH uses: microsoft/setup-msbuild@v2 From 92a06862885414477c2cf9974e094f4b5d27cc6c Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Thu, 20 Mar 2025 17:31:05 +0100 Subject: [PATCH 20/53] Update nightly.yml --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index b52dbba6fa..4227b55ed8 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -17,7 +17,7 @@ env: # Configuration type to build. # You can convert this to a build matrix if you need coverage of multiple configuration types. # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - BUILD_CONFIGURATION: Debug + BUILD_CONFIGURATION: Release BUILD_TAG: 6.6.3 From 3e5ba220aedb3629392170b1800f7c670e0bc896 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 22 Mar 2025 20:43:27 +0100 Subject: [PATCH 21/53] Update nightly.yml --- .github/workflows/nightly.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 4227b55ed8..4b04fec438 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -74,3 +74,19 @@ jobs: with: name: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }} path: build\${{matrix.platform}} + + - name: Create zip + uses: ihiroky/archive-action@v1 + with: + root_dir: build\${{matrix.platform}} + file_path: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + + - name: Upload Release + uses: softprops/action-gh-release@v2 + with: + tag_name: nightly + draft: false + prerelease: true + files: | + build\${{matrix.platform}}\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + From 0df7adf5cec27c76a6b3321766202f405782ec90 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 22 Mar 2025 21:13:57 +0100 Subject: [PATCH 22/53] Update nightly.yml --- .github/workflows/nightly.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 4b04fec438..64af6ae113 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -75,11 +75,7 @@ jobs: name: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }} path: build\${{matrix.platform}} - - name: Create zip - uses: ihiroky/archive-action@v1 - with: - root_dir: build\${{matrix.platform}} - file_path: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + - run: Compress-Archive -Path build/${{matrix.platform}}/* -Destination build/${{matrix.platform}}/elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip - name: Upload Release uses: softprops/action-gh-release@v2 From 734f0bc33c9b1447693e13806c28e5db9bc10e55 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 22 Mar 2025 21:20:51 +0100 Subject: [PATCH 23/53] Update nightly.yml --- .github/workflows/nightly.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 64af6ae113..3357da7c9d 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -21,8 +21,7 @@ env: BUILD_TAG: 6.6.3 -permissions: - contents: read +permissions: write-all jobs: build: From d9ce4f81b06a30648c3da17a85ed7137e4495853 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 22 Mar 2025 21:31:40 +0100 Subject: [PATCH 24/53] Update nightly.yml --- .github/workflows/nightly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 3357da7c9d..59ffcf90fd 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -74,7 +74,7 @@ jobs: name: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }} path: build\${{matrix.platform}} - - run: Compress-Archive -Path build/${{matrix.platform}}/* -Destination build/${{matrix.platform}}/elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + - run: Compress-Archive -Path .\build\${{matrix.platform}}\* -Destination .\build\${{matrix.platform}}\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip - name: Upload Release uses: softprops/action-gh-release@v2 @@ -83,5 +83,5 @@ jobs: draft: false prerelease: true files: | - build\${{matrix.platform}}\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + .\build\${{matrix.platform}}\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip From 1ceff50096d62f17947627f2fdbf02e81d881530 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 22 Mar 2025 21:42:16 +0100 Subject: [PATCH 25/53] Update nightly.yml --- .github/workflows/nightly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 59ffcf90fd..36fdcf2024 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -74,7 +74,7 @@ jobs: name: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }} path: build\${{matrix.platform}} - - run: Compress-Archive -Path .\build\${{matrix.platform}}\* -Destination .\build\${{matrix.platform}}\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip - name: Upload Release uses: softprops/action-gh-release@v2 @@ -83,5 +83,5 @@ jobs: draft: false prerelease: true files: | - .\build\${{matrix.platform}}\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + .\build\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip From 5c4fdd17635e0c50440668206b0bb29615f28994 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 22 Mar 2025 22:11:30 +0100 Subject: [PATCH 26/53] Update nightly.yml --- .github/workflows/nightly.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 36fdcf2024..c313f55759 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -75,6 +75,8 @@ jobs: path: build\${{matrix.platform}} - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + + - run: ls .\build - name: Upload Release uses: softprops/action-gh-release@v2 From 80f53ebf315207858bf7976d3367e48fd5aa4380 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 22 Mar 2025 22:18:37 +0100 Subject: [PATCH 27/53] Update nightly.yml --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c313f55759..a77f28033e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -85,5 +85,5 @@ jobs: draft: false prerelease: true files: | - .\build\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + ./build/*.zip From ae823eea7e011f2e92f016cc1168658b6e114af9 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 22 Mar 2025 22:40:06 +0100 Subject: [PATCH 28/53] Update nightly.yml --- .github/workflows/nightly.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index a77f28033e..a8a53db014 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -75,8 +75,6 @@ jobs: path: build\${{matrix.platform}} - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip - - - run: ls .\build - name: Upload Release uses: softprops/action-gh-release@v2 From cb97e21829279240da586730e421e0f22246d9fb Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 22 Mar 2025 22:46:39 +0100 Subject: [PATCH 29/53] Update msbuild.yml --- .github/workflows/msbuild.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 93beae0c08..4ed19252d0 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -68,9 +68,15 @@ jobs: - name: Prepare Artifact shell: cmd run: build\create_package_${{matrix.platform}}.bat - - - name: Upload artifact - uses: actions/upload-artifact@v4 + + - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-${{ env.BUILD_TAG }}.zip + + - name: Upload Release + uses: softprops/action-gh-release@v2 with: - name: elena-lang-${{matrix.platform}}-${{ env.BUILD_TAG }} - path: build\${{matrix.platform}} + tag_name: v${{ env.BUILD_TAG }} + draft: false + prerelease: true + files: | + ./build/*.zip + From 3942cfd6f93b16f00486a3ab694ac6b9aaa324e9 Mon Sep 17 00:00:00 2001 From: arakov Date: Wed, 26 Mar 2025 11:22:29 +0100 Subject: [PATCH 30/53] adding linux release action --- .github/workflow/ci_i386.yml | 17 ----------------- .github/workflows/make.yml | 35 +++++++++++++++++++++++++++++++++++ .github/workflows/msbuild.yml | 10 ++++++---- 3 files changed, 41 insertions(+), 21 deletions(-) delete mode 100644 .github/workflow/ci_i386.yml create mode 100644 .github/workflows/make.yml diff --git a/.github/workflow/ci_i386.yml b/.github/workflow/ci_i386.yml deleted file mode 100644 index 6202cf3805..0000000000 --- a/.github/workflow/ci_i386.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: CI - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Build - run: make all_i386 diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml new file mode 100644 index 0000000000..8efb0e531b --- /dev/null +++ b/.github/workflows/make.yml @@ -0,0 +1,35 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Linux Make Build + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + workflow_dispatch: # Put here!! + +permissions: write-all + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-latest] + platform: [i386, amd64] + + steps: + - uses: actions/checkout@v4 + + - name: Set version + run: | + VER=$(cat VERSION) + echo "BUILD_TAG=$VER" >> $GITHUB_ENV + + - name: Build + run: make all_${{ matrix.platform }} diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 4ed19252d0..5852a2e312 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -21,10 +21,7 @@ env: # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix BUILD_CONFIGURATION: Release - BUILD_TAG: 6.6.1 - -permissions: - contents: read +permissions: write-all jobs: build: @@ -46,6 +43,11 @@ jobs: - name: Restore nuget packages run: nuget restore ${{env.SOLUTION_FILE_PATH}} + + - name: Set version + run: | + VER=$(cat VERSION) + echo "BUILD_TAG=$VER" >> $GITHUB_ENV - name: Build working-directory: ${{env.GITHUB_WORKSPACE}} From 2cd28d28791d5b389f91b5aa5c505a03c1f7b018 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Wed, 26 Mar 2025 11:27:51 +0100 Subject: [PATCH 31/53] Update make.yml --- .github/workflows/make.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index 8efb0e531b..708b2c282b 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -31,5 +31,9 @@ jobs: VER=$(cat VERSION) echo "BUILD_TAG=$VER" >> $GITHUB_ENV + - name: Install dependencies + run: | + sudo apt-get install -y gcc-11 g++-11 + - name: Build run: make all_${{ matrix.platform }} From 614aa58617423db616c619e3e9926231e67f5b07 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Wed, 26 Mar 2025 11:32:53 +0100 Subject: [PATCH 32/53] Update make.yml --- .github/workflows/make.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index 708b2c282b..f206080e30 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - platform: [i386, amd64] + platform: [amd64] steps: - uses: actions/checkout@v4 From f333b246d90240cf8c5d70c9a5fcb02785cbddc5 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Wed, 26 Mar 2025 11:36:44 +0100 Subject: [PATCH 33/53] Update make.yml --- .github/workflows/make.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index f206080e30..2e0d72b1d5 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - platform: [amd64] + platform: [i386, amd64] steps: - uses: actions/checkout@v4 @@ -33,7 +33,7 @@ jobs: - name: Install dependencies run: | - sudo apt-get install -y gcc-11 g++-11 + sudo apt-get install gcc-multilib g++-multilib - name: Build run: make all_${{ matrix.platform }} From 81d1323f372ea9667e5632d014f91e9058d8f451 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Fri, 28 Mar 2025 17:55:48 +0100 Subject: [PATCH 34/53] Iteration38 (#726) * initial submit * #34 : working on httpclient * refactoring template generation * [FIXED] #716 : applying highlight setting changes immediately * [FIXED] IDE : fix syntax highlighting with character constants * [FIXED] #717 : The setting to change code editor font size doesn't work * [FIXED] #715 : There is no options available to change the code editor font * fixing async method routine * fixing httpget sample * [FIXED] system'threading'Task - raise an exception if the task was completed before * fixing net'http code * [FIXED] default built-in variable inside the constructor * #34 : setting default port 80 * [FIXED] displaying short struct field * #34 : working on http client * [FIXED] BlockingQueue implementation * [FIXED] GC routine in MTA * [ADDED] supporting auto field * [FIXED] using try / catch / finally inside async / yield method * [ADDED] #721 : Dragging files into the IDE to open doesn't work * fixing string interpolation * #34 : supporting chunked response * api refactoring : all symbols must start with a capital letter (e.g. printingLn) * [ADDED] #723 : include path to approot temporally inside IDE * [FIXED] ppc64le : fiadd, fisub, fimul, fidiv opcodes * [ADDED] #184 : linux - select tab * migrating ldbg into a separate repo * [ADDED] project collection : support sub folders * [ADDED] #722 : [IDE] Scrolling experience * #725 : providing settings to control toolbar size --- .github/workflows/msbuild.yml | 3 +- .github/workflows/nightly.yml | 5 +- CHANGELOG.md | 38 +- VERSION | 2 +- asm/ppc64le/core60.asm | 14 +- build/aarch64/build_package_arm64.script | 18 +- build/aarch64/control | 2 +- build/amd64/build_package_amd64.script | 18 +- build/amd64/control | 2 +- build/create_package_x64.bat | 134 +------- build/create_package_x86.bat | 215 +----------- build/elena_inno.iss | 4 +- build/i386/build_package_i386.script | 14 +- build/i386/control | 2 +- build/ppc64le/build_package_ppc64le.script | 18 +- build/ppc64le/control | 2 +- doc/api/extensions-routines-summary.html | 24 +- doc/api/extensions-routines.html | 45 ++- doc/api/forms-summary.html | 39 ++- doc/api/forms.html | 164 +++++++++ doc/api/system-culture-summary.html | 9 + doc/api/system-culture.html | 94 ++++- doc/api/system-io.html | 10 +- doc/api/system-net.html | 194 +++++++---- doc/api/system-text.html | 8 +- doc/api/system-winforms-summary.html | 165 +++++---- doc/api/system-winforms.html | 111 ++++++ doc/api/system.html | 49 ++- doc/contributors | 1 + doc/features | 25 +- doc/readme.txt | 4 +- doc/tech/bytecode60.txt | 8 + doc/todo.txt | 50 +-- elenasrc3/common/tree.h | 23 +- elenasrc3/common/ustring.cpp | 2 +- elenasrc3/common/ustring.h | 14 +- elenasrc3/dpa/dpa_common.h | 17 - elenasrc3/dpa/dpa_queue.h | 67 ---- elenasrc3/dpa/dpa_session.cpp | 59 ---- elenasrc3/dpa/dpa_session.h | 51 --- elenasrc3/dpa/dpa_stream.cpp | 26 -- elenasrc3/dpa/dpa_stream.h | 31 -- elenasrc3/elc/clicommon.h | 93 ++--- elenasrc3/elc/cliconst.h | 2 +- elenasrc3/elc/compiler.cpp | 325 +++++++++++++----- elenasrc3/elc/compiler.h | 66 +++- elenasrc3/elc/compilerlogic.cpp | 4 + elenasrc3/elc/compiling.cpp | 9 + elenasrc3/elc/errors.h | 3 +- elenasrc3/elc/messages.h | 3 +- elenasrc3/elc/modulescope.cpp | 32 +- elenasrc3/elc/modulescope.h | 8 +- elenasrc3/elc/project.cpp | 33 +- elenasrc3/elc/source.cpp | 65 ++-- elenasrc3/elc/source.h | 4 +- elenasrc3/elc/windows/elc.cpp | 23 +- elenasrc3/elena-tests/tests_common.h | 4 + elenasrc3/elenart/rtcommon.h | 4 +- elenasrc3/elenasm/regex.h | 2 + elenasrc3/elenasrc3.sln | 2 - elenasrc3/elenavm/windows/dllmain.cpp | 3 + elenasrc3/engine/bcwriter.cpp | 250 +++++++++----- elenasrc3/engine/bcwriter.h | 37 +- elenasrc3/engine/buildtree.h | 21 +- elenasrc3/engine/bytecode.cpp | 7 +- elenasrc3/engine/bytecode.h | 15 + elenasrc3/engine/elena.h | 21 +- elenasrc3/engine/elenaconst.h | 7 +- elenasrc3/engine/gcroutines.cpp | 32 +- elenasrc3/engine/langcommon.h | 2 + elenasrc3/engine/libman.cpp | 76 ++-- elenasrc3/engine/libman.h | 6 +- elenasrc3/engine/textparser.h | 3 +- elenasrc3/engine/xmlprojectbase.h | 1 - elenasrc3/gui/controller.cpp | 18 +- elenasrc3/gui/controller.h | 23 +- elenasrc3/gui/document.cpp | 20 +- elenasrc3/gui/document.h | 8 +- elenasrc3/gui/gtklinux/gtktabbar.cpp | 9 + elenasrc3/gui/gtklinux/gtktabbar.h | 17 + elenasrc3/gui/guieditor.h | 52 ++- elenasrc3/gui/view.cpp | 6 +- elenasrc3/gui/view.h | 4 +- elenasrc3/gui/windows/wincanvas.cpp | 19 +- elenasrc3/gui/windows/wincanvas.h | 9 +- elenasrc3/gui/windows/wincommon.cpp | 6 +- elenasrc3/gui/windows/wincommon.h | 4 +- elenasrc3/gui/windows/winsdi.cpp | 3 + elenasrc3/gui/windows/winsdi.h | 4 +- elenasrc3/gui/windows/winsplitter.cpp | 4 +- elenasrc3/gui/windows/winsplitter.h | 2 +- elenasrc3/gui/windows/wintextview.cpp | 8 +- elenasrc3/gui/windows/wintextview.h | 4 +- elenasrc3/gui/windows/wintoolbar.cpp | 42 ++- elenasrc3/gui/windows/wintoolbar.h | 4 +- elenasrc3/ide/debugcontroller.cpp | 25 +- elenasrc3/ide/debugcontroller.h | 7 +- elenasrc3/ide/editframe.cpp | 6 +- elenasrc3/ide/editframe.h | 4 +- elenasrc3/ide/gtklinux/factory.cpp | 26 +- elenasrc3/ide/gtklinux/factory.h | 6 +- elenasrc3/ide/gtklinux/gtkide.cpp | 5 + elenasrc3/ide/gtklinux/gtkide.h | 1 + elenasrc3/ide/gtklinux/gtkidetextview.cpp | 34 +- elenasrc3/ide/gtklinux/gtkidetextview.h | 7 +- elenasrc3/ide/idecommon.h | 11 +- elenasrc3/ide/idecontroller.cpp | 68 +++- elenasrc3/ide/idecontroller.h | 17 +- elenasrc3/ide/ideproject.cpp | 1 + elenasrc3/ide/ideproject.h | 23 +- elenasrc3/ide/ideversion.h | 2 +- elenasrc3/ide/ideview.h | 4 +- elenasrc3/ide/sourceformatter.cpp | 12 +- elenasrc3/ide/windows/Resource.h | 22 +- elenasrc3/ide/windows/elide.rc | Bin 43924 -> 46214 bytes elenasrc3/ide/windows/factory.cpp | 58 +++- elenasrc3/ide/windows/factory.h | 4 +- elenasrc3/ide/windows/icons/closeAll.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/closeAll_l.bmp | Bin 0 -> 3126 bytes elenasrc3/ide/windows/icons/closeFile.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/closeFile_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/copy.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/copy_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/cut.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/cut_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/goto.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/goto_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/newFile.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/newFile_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/openFile.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/openFile_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/paste.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/paste_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/redo.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/redo_l.bmp | Bin 0 -> 3126 bytes elenasrc3/ide/windows/icons/run.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/run_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/saveAll.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/saveAll_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/saveFile.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/saveFile_l.bmp | Bin 0 -> 1818 bytes elenasrc3/ide/windows/icons/stepinto.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/stepinto_l.bmp | Bin 0 -> 1654 bytes elenasrc3/ide/windows/icons/stepover.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/stepover_l.bmp | Bin 0 -> 1774 bytes elenasrc3/ide/windows/icons/stop.bmp | Bin 246 -> 822 bytes elenasrc3/ide/windows/icons/stop_l.bmp | Bin 0 -> 2102 bytes elenasrc3/ide/windows/icons/undo.bmp | Bin 1334 -> 822 bytes elenasrc3/ide/windows/icons/undo_l.bmp | Bin 0 -> 3126 bytes elenasrc3/ide/windows/main.cpp | 14 +- elenasrc3/ide/windows/win32debugprocess.cpp | 52 ++- elenasrc3/ide/windows/win32debugprocess.h | 7 +- elenasrc3/ide/windows/windialogs.cpp | 76 +++- elenasrc3/ide/windows/windialogs.h | 18 +- elenasrc3/ide/windows/winide.cpp | 42 ++- elenasrc3/ide/windows/winide.h | 6 +- elenasrc3/ldbg/ldbg_common.h | 28 -- elenasrc3/ldbg/ldbg_const.h | 1 - elenasrc3/ldbg/ldbg_session.cpp | 51 --- elenasrc3/ldbg/ldbg_session.h | 33 -- elenasrc3/ldbg/vs/Resource.rc | 60 ---- elenasrc3/ldbg/vs/ldbg.vcxproj | 195 ----------- elenasrc3/ldbg/vs/resource.h | 29 -- elenasrc3/ldbg/windows/ldbg.cpp | 32 -- elenasrc3/tools/asmc/asmconst.h | 2 +- elenasrc3/tools/asmc/ppc64assembler.cpp | 19 + elenasrc3/tools/asmc/ppc64assembler.h | 1 + elenasrc3/tools/sg/sg.cpp | 4 +- elenasrc3/tools/sg/sgconst.h | 6 +- examples60/console/build.bat | 89 ----- examples60/console/build.script | 69 ---- examples60/console/build64.bat | 44 --- examples60/console/build_64.script | 69 ---- .../datetime.linux.prj} | 16 +- examples60/console/datetime/datetime.project | 0 examples60/console/goods/goods.l | 2 +- ...elloworld.project => helloworld.linux.prj} | 0 examples60/console/sum/realsum.project | 35 -- examples60/console/sum/sum.linux.prj | 71 ++++ examples60/examples60.linux.prjcol | 25 ++ examples60/examples60.prjcol | 48 +++ examples60/files/textdb/textdb.l | 2 +- examples60/files/textfile/textfile.l | 2 +- examples60/net/chat/server/server.l | 2 +- examples60/net/httpget/httpget.l | 56 +++ examples60/net/httpget/httpget.prj | 13 + examples60/rosetta/accumulator/accumulator.l | 2 +- examples60/rosetta/ackermann/ackermann.l | 4 +- examples60/rosetta/addfield/addfield.l | 4 +- examples60/rosetta/amb/amb.l | 12 +- examples60/rosetta/anagram/anagram.l | 6 +- examples60/rosetta/anonymrec/anonymrec.l | 8 +- examples60/rosetta/aplusb/aplusb.l | 4 +- .../rosetta/applycallback/applycallback.l | 2 +- .../rosetta/arithmeticint/arithmeticint.l | 16 +- examples60/rosetta/arithmeval/arithmeval.l | 6 +- examples60/rosetta/arithmmean/arithmmean.l | 2 +- examples60/rosetta/arrayconcat/arrayconcat.l | 2 +- examples60/rosetta/arraymode/arraymode.l | 2 +- examples60/rosetta/arrays/arrays.l | 6 +- .../associativearrays/associativearrays.l | 2 +- examples60/rosetta/bestshuffle/bestshuffle.l | 4 +- examples60/rosetta/binary/binary.l | 2 +- examples60/rosetta/bitwise/bitwise.l | 14 +- examples60/rosetta/brackets/brackets.l | 4 +- examples60/rosetta/build.bat | 289 ---------------- examples60/rosetta/build.script | 219 ------------ examples60/rosetta/build64.bat | 289 ---------------- examples60/rosetta/build64.script | 218 ------------ examples60/rosetta/bullscows/bullscows.l | 10 +- examples60/rosetta/caesar/caesar.l | 8 +- examples60/rosetta/calendar/calendar.l | 6 +- examples60/rosetta/charmatch/charmatch.l | 8 +- .../rosetta/combinations/combinations.l | 4 +- examples60/rosetta/complist/complist.l | 6 +- examples60/rosetta/doors/doors.l | 4 +- examples60/rosetta/dynamic_var/dynamic_var.l | 4 +- .../rosetta/evolutionary/evolutionary.l | 4 +- examples60/rosetta/firstclass/firstclass.l | 2 +- examples60/rosetta/gameoflife/gameoflife.l | 6 +- examples60/rosetta/gameoflife/view.l | 4 +- examples60/rosetta/knutalg/knutalg.l | 2 +- .../rosetta/loop_multiple_arrays/loopma.l | 8 +- examples60/rosetta/manboy/manboy.l | 2 +- examples60/rosetta/median/median.l | 6 +- examples60/rosetta/ninetynine/ninetynine.l | 2 +- .../reverse_words_in_string/reverse_words.l | 4 +- examples60/rosetta/smavg/smavg.l | 10 +- .../rosetta/string_append/string_append.l | 2 +- examples60/rosetta/string_case/string_case.l | 6 +- .../string_comparison/string_comparision.l | 14 +- .../string_concatenation.l | 6 +- .../string_interpolation.l | 2 +- .../rosetta/string_matching/string_matching.l | 26 +- .../rosetta/string_prepend/string_prepend.l | 6 +- examples60/rosetta/tokenizer/tokenizer.l | 2 +- examples60/rosetta/toppergroup/toppergroup.l | 8 +- examples60/rosetta/treeview/treeview.l | 2 +- .../rosetta/trigonometric/trigonometric.l | 32 +- examples60/rosetta/truncprime/truncprime.l | 6 +- examples60/rosetta/twelvestats/twelvestats.l | 10 +- examples60/rosetta/twentyfour/twentyfour.l | 20 +- examples60/rosetta/wireworld/wireworld.l | 6 +- examples60/rosetta/ycombinator/ycombinator.l | 4 +- .../zeckendorf_arithm/zeckendorf_arithm.l | 24 +- examples60/rosetta/zhangsuen/zhangsuen.l | 8 +- examples60/rosetta60.linux.prjcol | 60 ++++ examples60/rosetta60.prjcol | 60 ++++ examples60/scripts/build.bat | 42 --- examples60/scripts/calc/parser.l | 2 +- examples60/scripts/interpreter/interpreter.l | 20 +- examples60/scripts/js/main.l | 4 +- examples60/scripts/ls/main.l | 2 +- examples60/threads/async/sample1.l | 12 +- examples60/threads/tasks/sample1.l | 4 +- src60/extensions/app.l | 6 +- src60/extensions/extensions.linux.prj | 2 +- src60/extensions/extensions.prj | 3 +- src60/extensions/routines/enumerating.l | 6 +- src60/extensions/runtime/package.l | 26 ++ src60/extensions/runtime/systemmonitor.l | 20 +- src60/ltests/engine.l | 4 +- src60/net/http/common.l | 18 +- src60/net/http/httpclient.l | 35 +- src60/net/http/httpheaders.l | 35 +- src60/net/http/httpresponse.l | 150 +++++++- src60/net/win32_listener.l | 7 +- src60/system/app.l | 2 +- src60/system/culture/common.l | 5 +- src60/system/culture/win_locale.l | 8 +- .../system/dynamic/expressions/expressions.l | 2 +- src60/system/io/memorystream.l | 21 +- src60/system/net/networkstream.l | 31 +- src60/system/net/win_sockets.l | 145 +++----- src60/system/system.linux.prj | 2 +- src60/system/system.prj | 2 +- src60/system/text/textbuffer.l | 2 +- src60/system/threading/blockinglists.l | 4 +- src60/system/threading/tasks.l | 5 + tests60/sandbox/sandbox.l | 11 +- tests60/sandbox2/sandbox2.l | 14 +- tests60/script_tests/basic.l | 2 +- tests60/script_tests/main.l | 4 +- tests60/system_tests/basic.l | 325 ++++++++++-------- tests60/system_tests/main.l | 4 +- 285 files changed, 3495 insertions(+), 3785 deletions(-) delete mode 100644 elenasrc3/dpa/dpa_common.h delete mode 100644 elenasrc3/dpa/dpa_queue.h delete mode 100644 elenasrc3/dpa/dpa_session.cpp delete mode 100644 elenasrc3/dpa/dpa_session.h delete mode 100644 elenasrc3/dpa/dpa_stream.cpp delete mode 100644 elenasrc3/dpa/dpa_stream.h create mode 100644 elenasrc3/ide/windows/icons/closeAll_l.bmp create mode 100644 elenasrc3/ide/windows/icons/closeFile_l.bmp create mode 100644 elenasrc3/ide/windows/icons/copy_l.bmp create mode 100644 elenasrc3/ide/windows/icons/cut_l.bmp create mode 100644 elenasrc3/ide/windows/icons/goto_l.bmp create mode 100644 elenasrc3/ide/windows/icons/newFile_l.bmp create mode 100644 elenasrc3/ide/windows/icons/openFile_l.bmp create mode 100644 elenasrc3/ide/windows/icons/paste_l.bmp create mode 100644 elenasrc3/ide/windows/icons/redo_l.bmp create mode 100644 elenasrc3/ide/windows/icons/run_l.bmp create mode 100644 elenasrc3/ide/windows/icons/saveAll_l.bmp create mode 100644 elenasrc3/ide/windows/icons/saveFile_l.bmp create mode 100644 elenasrc3/ide/windows/icons/stepinto_l.bmp create mode 100644 elenasrc3/ide/windows/icons/stepover_l.bmp create mode 100644 elenasrc3/ide/windows/icons/stop_l.bmp create mode 100644 elenasrc3/ide/windows/icons/undo_l.bmp delete mode 100644 elenasrc3/ldbg/ldbg_common.h delete mode 100644 elenasrc3/ldbg/ldbg_const.h delete mode 100644 elenasrc3/ldbg/ldbg_session.cpp delete mode 100644 elenasrc3/ldbg/ldbg_session.h delete mode 100644 elenasrc3/ldbg/vs/Resource.rc delete mode 100644 elenasrc3/ldbg/vs/ldbg.vcxproj delete mode 100644 elenasrc3/ldbg/vs/resource.h delete mode 100644 elenasrc3/ldbg/windows/ldbg.cpp delete mode 100644 examples60/console/build.bat delete mode 100755 examples60/console/build.script delete mode 100644 examples60/console/build64.bat delete mode 100755 examples60/console/build_64.script rename examples60/console/{sum/intsum.project => datetime/datetime.linux.prj} (55%) delete mode 100644 examples60/console/datetime/datetime.project rename examples60/console/helloworld/{helloworld.project => helloworld.linux.prj} (100%) delete mode 100644 examples60/console/sum/realsum.project create mode 100644 examples60/console/sum/sum.linux.prj create mode 100644 examples60/examples60.linux.prjcol create mode 100644 examples60/examples60.prjcol create mode 100644 examples60/net/httpget/httpget.l create mode 100644 examples60/net/httpget/httpget.prj delete mode 100644 examples60/rosetta/build.bat delete mode 100755 examples60/rosetta/build.script delete mode 100644 examples60/rosetta/build64.bat delete mode 100755 examples60/rosetta/build64.script create mode 100644 examples60/rosetta60.linux.prjcol create mode 100644 examples60/rosetta60.prjcol delete mode 100644 examples60/scripts/build.bat create mode 100644 src60/extensions/runtime/package.l diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 5852a2e312..1f436103b7 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -67,7 +67,7 @@ jobs: shell: cmd run: build\rebuild_lib60_${{matrix.platform}}.bat - - name: Prepare Artifact + - name: Prepare Release shell: cmd run: build\create_package_${{matrix.platform}}.bat @@ -81,4 +81,3 @@ jobs: prerelease: true files: | ./build/*.zip - diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index a8a53db014..cc13a8dcb5 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -19,7 +19,7 @@ env: # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix BUILD_CONFIGURATION: Release - BUILD_TAG: 6.6.3 + BUILD_TAG: 6.6.4 permissions: write-all @@ -35,7 +35,7 @@ jobs: steps: - uses: actions/checkout@v4 with: - ref: iteration38 + ref: iteration39 - name: Add MSBuild to PATH uses: microsoft/setup-msbuild@v2 @@ -84,4 +84,3 @@ jobs: prerelease: true files: | ./build/*.zip - diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f4f6695ec..e42925492f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ -## ELENA 6.6.0 +## ELENA 6.7.0 - ELENA - [ADDED] user defined type alias + - [ADDED] supporting auto field - ELC - [ADDED] new option "-xj" to turn on jump alignment @@ -23,6 +24,18 @@ - [FIXED] #704 : Porting to FreeBSD/PowerPC64 - [FIXED] aarch64 extopen / extclose opcode - [FIXED] #283 : unboxing duplicate object + - [ADDED] CORE_MATH_TABLE core table + - [ADDED] ppc64le : fexp + - [ADDED] aarch64 : fexp + - [ADDED] ppc64le : fln + - [ADDED] aarch64 : fln + - [FIXED] #283 : unboxing duplicate object + - [FIXED] default built-in variable inside the constructor + - [FIXED] GC routine in MTA + - [FIXED] using inside using in async / yield method + - [FIXED] string interpolation with character codes + - [FIXED] ppc64le : fiadd, fisub, fimul, fidiv opcodes + - [ADDED] project collection : support sub folders - API - [ADDED] net'http'HttpClient, net'http'Uri @@ -30,12 +43,35 @@ - [ADDED] system'net'NetworkStream - [ADDED] system'net'Socket : poll[3] - [ADDED] net'TcpListener : prop:Pending + - [ADDED] forms'Combobox + - [ADDED] net'HttpClient + - [FIXED] system'threading'Task - raise an exception if the task was completed before + - [FIXED] BlockingQueue implementation + +- SM + - [ADDED] supporting $regex rules + +- Scripts + - [ADDED] xforms : supporting RadioButton, Panel, Edit, Combobox - SAMPLES - [ADDED] console regex sample + - [ADDED] net : httpget sample + - [FIXED] ppc64le : pi sample - IDE - [FIXED]debugger : step over multi-select statement + - [ADDED] Linux - open a file + - [FIXED] #716 : applying highlight setting changes immediately + - [FIXED] #716 : highlight setting os on by default + - [FIXED] fix syntax highlighting with character constants + - [FIXED] #717 : The setting to change code editor font size doesn't work + - [FIXED] #715 : There is no options available to change the code editor font + - [FIXED] displaying short struct field + - [ADDED] #721 : Dragging files into the IDE to open doesn't work + - [ADDED] #723 : include path to approot temporally inside IDE + - [ADDED] #722 : [IDE] Scrolling experience + - [ADDED] #725 : [IDE] large toolbar buttons - Tools - [ADDED][LDOC] static methods are in the separate category diff --git a/VERSION b/VERSION index 3eae443131..a45cc0adf0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.6.2 \ No newline at end of file +6.6.3 \ No newline at end of file diff --git a/asm/ppc64le/core60.asm b/asm/ppc64le/core60.asm index 88c766e309..60af35e357 100644 --- a/asm/ppc64le/core60.asm +++ b/asm/ppc64le/core60.asm @@ -1005,7 +1005,7 @@ end // ; fiadd inline %070h - lfd f18, 0(r3) + lfiwax f18, r3 fcfid f18, f18 lfd f17, 0(r15) fadd f17, f17, f18 @@ -1016,7 +1016,7 @@ end // ; fsub inline %071h - lfd f18, 0(r3) + lfiwax f18, r3 fcfid f18, f18 lfd f17, 0(r15) fsub f17, f18, f17 @@ -1024,10 +1024,10 @@ inline %071h end -// ; fmul +// ; fimul inline %072h - lfd f18, 0(r3) + lfiwax f18, r3 fcfid f18, f18 lfd f17, 0(r15) fmul f17, f17, f18 @@ -1035,13 +1035,13 @@ inline %072h end -// ; fdiv +// ; fidiv inline %073h - lfd f18, 0(r3) + lfiwax f18, r3 fcfid f18, f18 lfd f17, 0(r15) - fdiv f17, f18, f17 + fdiv f17, f17, f18 stfd f17, 0(r15) end diff --git a/build/aarch64/build_package_arm64.script b/build/aarch64/build_package_arm64.script index 92a7376352..672ab45748 100755 --- a/build/aarch64/build_package_arm64.script +++ b/build/aarch64/build_package_arm64.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.2.aarch64-linux +RELEASE=elena-6.6.3.aarch64-linux mkdir -p ../lib60_64 mkdir -p /usr/share/elena @@ -145,21 +145,7 @@ fi mkdir -p ./$RELEASE/usr/bin/ mkdir -p ./$RELEASE/usr/elena-lang - mkdir -p ./$RELEASE/usr/elena-lang/examples60/console/helloworld/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/console/sum/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/console/words/ - - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/accumulator/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/ackermann/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/addfield/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/anonymrec/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/aplusb/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/applycallback/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmeticint/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmeval/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmmean/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arrayconcat/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arraymode/ + mkdir -p ./$RELEASE/usr/elena-lang/examples60/ echo copying configuration diff --git a/build/aarch64/control b/build/aarch64/control index 76ec1e5ad4..8dd0f0bfc3 100644 --- a/build/aarch64/control +++ b/build/aarch64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.2 +Version: 6.6.3 Architecture: aarch64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/amd64/build_package_amd64.script b/build/amd64/build_package_amd64.script index 0caaeae1d6..3907389338 100755 --- a/build/amd64/build_package_amd64.script +++ b/build/amd64/build_package_amd64.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.2.amd64-linux +RELEASE=elena-6.6.3.amd64-linux mkdir -p ../../lib60_64 mkdir -p /usr/share/elena @@ -157,21 +157,7 @@ fi mkdir -p ./$RELEASE/usr/bin/ mkdir -p ./$RELEASE/usr/elena-lang - mkdir -p ./$RELEASE/usr/elena-lang/examples60/console/helloworld/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/console/sum/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/console/words/ - - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/accumulator/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/ackermann/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/addfield/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/anonymrec/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/aplusb/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/applycallback/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmeticint/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmeval/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmmean/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arrayconcat/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arraymode/ + mkdir -p ./$RELEASE/usr/elena-lang/examples60/ echo copying configuration diff --git a/build/amd64/control b/build/amd64/control index 6ef35ce178..1af39e3b70 100644 --- a/build/amd64/control +++ b/build/amd64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.2 +Version: 6.6.3 Architecture: amd64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/create_package_x64.bat b/build/create_package_x64.bat index 6874fbd8f4..458b31341e 100644 --- a/build/create_package_x64.bat +++ b/build/create_package_x64.bat @@ -9,46 +9,6 @@ md %~dp0\x64\bin\scripts md %~dp0\x64\bin\amd64 md %~dp0\x64\doc md %~dp0\x64\examples60 -md %~dp0\x64\examples60\console -md %~dp0\x64\examples60\console\helloworld -md %~dp0\x64\examples60\console\sum -md %~dp0\x64\examples60\console\words -md %~dp0\x64\examples60\console\binary -md %~dp0\x64\examples60\console\bsort -md %~dp0\x64\examples60\console\datetime -md %~dp0\x64\examples60\console\goods -md %~dp0\x64\examples60\console\replace -md %~dp0\x64\examples60\rosetta\accumulator -md %~dp0\x64\examples60\rosetta\ackermann -md %~dp0\x64\examples60\rosetta\addfield -md %~dp0\x64\examples60\rosetta\anonymrec -md %~dp0\x64\examples60\rosetta\aplusb -md %~dp0\x64\examples60\rosetta\applycallback -md %~dp0\x64\examples60\rosetta\arithmeticint -md %~dp0\x64\examples60\rosetta\arithmeval -md %~dp0\x64\examples60\rosetta\arithmmean -md %~dp0\x64\examples60\rosetta\arrayconcat -md %~dp0\x64\examples60\rosetta\arraymode -md %~dp0\x64\examples60\rosetta\arrays -md %~dp0\x64\examples60\rosetta\associativearrays -md %~dp0\x64\examples60\rosetta\bestshuffle -md %~dp0\x64\examples60\rosetta\binary -md %~dp0\x64\examples60\rosetta\bitwise -md %~dp0\x64\examples60\rosetta\brackets -md %~dp0\x64\examples60\rosetta\bullscows -md %~dp0\x64\examples60\rosetta\caesar -md %~dp0\x64\examples60\rosetta\calendar -md %~dp0\x64\examples60\rosetta\charmatch -md %~dp0\x64\examples60\rosetta\combinations -md %~dp0\x64\examples60\rosetta\doors -md %~dp0\x64\examples60\rosetta\evolutionary -md %~dp0\x64\examples60\rosetta\firstclass -md %~dp0\x64\examples60\rosetta\loop_multiple_arrays -md %~dp0\x64\examples60\rosetta\median -md %~dp0\x64\examples60\rosetta\ninetynine -md %~dp0\x64\examples60\rosetta\reverse_words_in_string -md %~dp0\x64\examples60\rosetta\smavg -md %~dp0\x64\examples60\rosetta\string_append copy %~dp0\..\bin\asm64-cli.exe %~dp0\x64\bin copy %~dp0\..\bin\elena64-cli.exe %~dp0\x64\bin @@ -76,41 +36,9 @@ copy %~dp0\..\readme.md %~dp0\x64\ copy %~dp0\..\CHANGELOG.md %~dp0\x64\ copy %~dp0\..\VERSION %~dp0\x64\ -md %~dp0\x64\src60\system -xcopy %~dp0\..\src60\system\*.l %~dp0\x64\src60\system /s -xcopy %~dp0\..\src60\system\*.prj %~dp0\x64\src60\system /s - -md %~dp0\x64\src60\extensions -xcopy %~dp0\..\src60\extensions\*.l %~dp0\x64\src60\extensions /s -xcopy %~dp0\..\src60\extensions\*.prj %~dp0\x64\src60\extensions /s - -md %~dp0\x64\src60\algorithms -xcopy %~dp0\..\src60\algorithms\*.l %~dp0\x64\src60\algorithms /s -xcopy %~dp0\..\src60\algorithms\*.prj %~dp0\x64\src60\algorithms /s - -md %~dp0\x64\src60\cellular -xcopy %~dp0\..\src60\cellular\*.l %~dp0\x64\src60\cellular /s -xcopy %~dp0\..\src60\cellular\*.prj %~dp0\x64\src60\cellular /s - -md %~dp0\x64\src60\sqlite -xcopy %~dp0\..\src60\sqlite\*.l %~dp0\x64\src60\sqlite /s -xcopy %~dp0\..\src60\sqlite\*.prj %~dp0\x64\src60\sqlite /s - -md %~dp0\x64\src60\forms -xcopy %~dp0\..\src60\forms\*.l %~dp0\x64\src60\forms /s -xcopy %~dp0\..\src60\forms\*.prj %~dp0\x64\src60\forms /s - -md %~dp0\x64\src60\xforms -xcopy %~dp0\..\src60\xforms\*.l %~dp0\x64\src60\xforms /s -xcopy %~dp0\..\src60\xforms\*.prj %~dp0\x64\src60\xforms /s - -md %~dp0\x64\src60\net -xcopy %~dp0\..\src60\net\*.l %~dp0\x64\src60\net /s -xcopy %~dp0\..\src60\net\*.prj %~dp0\x64\src60\net /s - -md %~dp0\x64\src60\ltests -xcopy %~dp0\..\src60\ltests\*.l %~dp0\x64\src60\ltests /s -xcopy %~dp0\..\src60\ltests\*.prj %~dp0\x64\src60\ltests /s +md %~dp0\x64\src60 +xcopy %~dp0\..\src60\*.l %~dp0\x64\src60\ /s +xcopy %~dp0\..\src60\*.prj %~dp0\x64\src60\ /s copy %~dp0\..\src60\elena_api.prjcol %~dp0\x64\src60\ @@ -154,54 +82,14 @@ if %ERRORLEVEL% EQU -2 GOTO CompilerError if %ERRORLEVEL% EQU -2 GOTO CompilerError @echo on -copy %~dp0\..\examples60\console\helloworld\*.l %~dp0\x64\examples60\console\helloworld -copy %~dp0\..\examples60\console\helloworld\*.prj %~dp0\x64\examples60\console\helloworld - -copy %~dp0\..\examples60\console\sum\*.l %~dp0\x64\examples60\console\sum -copy %~dp0\..\examples60\console\sum\*.prj %~dp0\x64\examples60\console\sum - -copy %~dp0\..\examples60\console\words\*.l %~dp0\x64\examples60\console\words -copy %~dp0\..\examples60\console\binary\*.l %~dp0\x64\examples60\console\binary -copy %~dp0\..\examples60\console\bsort\*.l %~dp0\x64\examples60\console\bsort -copy %~dp0\..\examples60\console\datetime\*.l %~dp0\x64\examples60\console\datetime -copy %~dp0\..\examples60\console\datetime\*.prj %~dp0\x64\examples60\console\datetime -copy %~dp0\..\examples60\console\goods\*.l %~dp0\x64\examples60\console\goods -copy %~dp0\..\examples60\console\goods\*.txt %~dp0\x64\examples60\console\goods -copy %~dp0\..\examples60\console\replace\*.l %~dp0\x64\examples60\console\replace - -copy %~dp0\..\examples60\rosetta\accumulator\*.l %~dp0\x64\examples60\rosetta\accumulator -copy %~dp0\..\examples60\rosetta\ackermann\*.l %~dp0\x64\examples60\rosetta\ackermann -copy %~dp0\..\examples60\rosetta\addfield\*.l %~dp0\x64\examples60\rosetta\addfield -copy %~dp0\..\examples60\rosetta\anonymrec\*.l %~dp0\x64\examples60\rosetta\anonymrec -copy %~dp0\..\examples60\rosetta\aplusb\*.l %~dp0\x64\examples60\rosetta\aplusb -copy %~dp0\..\examples60\rosetta\applycallback\*.l %~dp0\x64\examples60\rosetta\applycallback -copy %~dp0\..\examples60\rosetta\arithmeticint\*.l %~dp0\x64\examples60\rosetta\arithmeticint -copy %~dp0\..\examples60\rosetta\arithmeval\*.l %~dp0\x64\examples60\rosetta\arithmeval -copy %~dp0\..\examples60\rosetta\arithmmean\*.l %~dp0\x64\examples60\rosetta\arithmmean -copy %~dp0\..\examples60\rosetta\arrayconcat\*.l %~dp0\x64\examples60\rosetta\arrayconcat -copy %~dp0\..\examples60\rosetta\arraymode\*.l %~dp0\x64\examples60\rosetta\arraymode -copy %~dp0\..\examples60\rosetta\arrays\*.l %~dp0\x64\examples60\rosetta\arrays - -copy %~dp0\..\examples60\rosetta\associativearrays\*.l %~dp0\x64\examples60\rosetta\associativearrays -copy %~dp0\..\examples60\rosetta\bestshuffle\*.l %~dp0\x64\examples60\rosetta\bestshuffle -copy %~dp0\..\examples60\rosetta\binary\*.l %~dp0\x64\examples60\rosetta\binary -copy %~dp0\..\examples60\rosetta\bitwise\*.l %~dp0\x64\examples60\rosetta\bitwise -copy %~dp0\..\examples60\rosetta\brackets\*.l %~dp0\x64\examples60\rosetta\brackets -copy %~dp0\..\examples60\rosetta\bullscows\*.l %~dp0\x64\examples60\rosetta\bullscows -copy %~dp0\..\examples60\rosetta\caesar\*.l %~dp0\x64\examples60\rosetta\caesar -copy %~dp0\..\examples60\rosetta\calendar\*.l %~dp0\x64\examples60\rosetta\calendar -copy %~dp0\..\examples60\rosetta\charmatch\*.l %~dp0\x64\examples60\rosetta\charmatch -copy %~dp0\..\examples60\rosetta\combinations\*.l %~dp0\x64\examples60\rosetta\combinations -copy %~dp0\..\examples60\rosetta\doors\*.l %~dp0\x64\examples60\rosetta\doors -copy %~dp0\..\examples60\rosetta\evolutionary\*.l %~dp0\x64\examples60\rosetta\evolutionary -copy %~dp0\..\examples60\rosetta\firstclass\*.l %~dp0\x64\examples60\rosetta\firstclass -copy %~dp0\..\examples60\rosetta\loop_multiple_arrays\*.l %~dp0\x64\examples60\rosetta\loop_multiple_arrays -copy %~dp0\..\examples60\rosetta\median\*.l %~dp0\x64\examples60\rosetta\median -copy %~dp0\..\examples60\rosetta\ninetynine\*.l %~dp0\x64\examples60\rosetta\ninetynine -copy %~dp0\..\examples60\rosetta\reverse_words_in_string\*.l %~dp0\x64\examples60\rosetta\reverse_words_in_string -copy %~dp0\..\examples60\rosetta\smavg\*.l %~dp0\x64\examples60\rosetta\smavg -copy %~dp0\..\examples60\rosetta\string_append\*.l %~dp0\x64\examples60\rosetta\string_append -copy %~dp0\..\examples60\rosetta\twentyfour\*.l %~dp0\x64\examples60\rosetta\twentyfour +xcopy %~dp0\..\examples60\*.l %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.prj %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.txt %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.bmp %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.es %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.js %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.ls %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.xs %~dp0\x64\examples60\ /s goto:eof ::ERRORS diff --git a/build/create_package_x86.bat b/build/create_package_x86.bat index 9f16033ad3..08bd69e19e 100644 --- a/build/create_package_x86.bat +++ b/build/create_package_x86.bat @@ -9,75 +9,6 @@ md %~dp0\x86\bin\scripts md %~dp0\x86\bin\x32 md %~dp0\x86\doc md %~dp0\x86\examples60 -md %~dp0\x86\examples60\console -md %~dp0\x86\examples60\console\helloworld -md %~dp0\x86\examples60\console\sum -md %~dp0\x86\examples60\console\words -md %~dp0\x86\examples60\console\binary -md %~dp0\x86\examples60\console\bsort -md %~dp0\x86\examples60\console\datetime -md %~dp0\x86\examples60\console\goods -md %~dp0\x86\examples60\console\replace -md %~dp0\x86\examples60\console\pi -md %~dp0\x86\examples60\console\matrix -md %~dp0\x86\examples60\console\random -md %~dp0\x86\examples60\files -md %~dp0\x86\examples60\files\textdb -md %~dp0\x86\examples60\files\textfile -md %~dp0\x86\examples60\scripts\calc -md %~dp0\x86\examples60\scripts\interpreter -md %~dp0\x86\examples60\scripts\js -md %~dp0\x86\examples60\scripts\ls -md %~dp0\x86\examples60\rosetta\accumulator -md %~dp0\x86\examples60\rosetta\ackermann -md %~dp0\x86\examples60\rosetta\addfield -md %~dp0\x86\examples60\rosetta\anonymrec -md %~dp0\x86\examples60\rosetta\aplusb -md %~dp0\x86\examples60\rosetta\applycallback -md %~dp0\x86\examples60\rosetta\arithmeticint -md %~dp0\x86\examples60\rosetta\arithmeval -md %~dp0\x86\examples60\rosetta\arithmmean -md %~dp0\x86\examples60\rosetta\arrayconcat -md %~dp0\x86\examples60\rosetta\arraymode -md %~dp0\x86\examples60\rosetta\arrays -md %~dp0\x86\examples60\rosetta\associativearrays -md %~dp0\x86\examples60\rosetta\bestshuffle -md %~dp0\x86\examples60\rosetta\binary -md %~dp0\x86\examples60\rosetta\bitwise -md %~dp0\x86\examples60\rosetta\brackets -md %~dp0\x86\examples60\rosetta\bullscows -md %~dp0\x86\examples60\rosetta\caesar -md %~dp0\x86\examples60\rosetta\calendar -md %~dp0\x86\examples60\rosetta\charmatch -md %~dp0\x86\examples60\rosetta\combinations -md %~dp0\x86\examples60\rosetta\doors -md %~dp0\x86\examples60\rosetta\evolutionary -md %~dp0\x86\examples60\rosetta\firstclass -md %~dp0\x86\examples60\rosetta\loop_multiple_arrays -md %~dp0\x86\examples60\rosetta\median -md %~dp0\x86\examples60\rosetta\ninetynine -md %~dp0\x86\examples60\rosetta\reverse_words_in_string -md %~dp0\x86\examples60\rosetta\smavg -md %~dp0\x86\examples60\rosetta\string_append - -md %~dp0\x86\examples60\gui\c_a_g -md %~dp0\x86\examples60\gui\c_a_g\formulas -md %~dp0\x86\examples60\gui\c_a_g\formulas\Circulo -md %~dp0\x86\examples60\gui\c_a_g\formulas\Paralelogramos -md %~dp0\x86\examples60\gui\c_a_g\formulas\Trapezio -md %~dp0\x86\examples60\gui\c_a_g\formulas\Triangulos - -md %~dp0\x86\examples60\gui\agenda -md %~dp0\x86\examples60\gui\graphs -md %~dp0\x86\examples60\gui\helloworld - -md %~dp0\x86\examples60\db -md %~dp0\x86\examples60\db\sqlite - -md %~dp0\x86\examples60\threads -md %~dp0\x86\examples60\threads\async -md %~dp0\x86\examples60\threads\tasks -md %~dp0\x86\examples60\threads\threadpool copy %~dp0\..\bin\asm-cli.exe %~dp0\x86\bin copy %~dp0\..\bin\elena-cli.exe %~dp0\x86\bin @@ -111,41 +42,9 @@ copy %~dp0\..\readme.md %~dp0\x86\ copy %~dp0\..\CHANGELOG.md %~dp0\x86\ copy %~dp0\..\VERSION %~dp0\x86\ -md %~dp0\x86\src60\system -xcopy %~dp0\..\src60\system\*.l %~dp0\x86\src60\system /s -xcopy %~dp0\..\src60\system\*.prj %~dp0\x86\src60\system /s - -md %~dp0\x86\src60\extensions -xcopy %~dp0\..\src60\extensions\*.l %~dp0\x86\src60\extensions /s -xcopy %~dp0\..\src60\extensions\*.prj %~dp0\x86\src60\extensions /s - -md %~dp0\x86\src60\algorithms -xcopy %~dp0\..\src60\algorithms\*.l %~dp0\x86\src60\algorithms /s -xcopy %~dp0\..\src60\algorithms\*.prj %~dp0\x86\src60\algorithms /s - -md %~dp0\x86\src60\cellular -xcopy %~dp0\..\src60\cellular\*.l %~dp0\x86\src60\cellular /s -xcopy %~dp0\..\src60\cellular\*.prj %~dp0\x86\src60\cellular /s - -md %~dp0\x86\src60\sqlite -xcopy %~dp0\..\src60\sqlite\*.l %~dp0\x86\src60\sqlite /s -xcopy %~dp0\..\src60\sqlite\*.prj %~dp0\x86\src60\sqlite /s - -md %~dp0\x86\src60\forms -xcopy %~dp0\..\src60\forms\*.l %~dp0\x86\src60\forms /s -xcopy %~dp0\..\src60\forms\*.prj %~dp0\x86\src60\forms /s - -md %~dp0\x86\src60\xforms -xcopy %~dp0\..\src60\xforms\*.l %~dp0\x86\src60\xforms /s -xcopy %~dp0\..\src60\xforms\*.prj %~dp0\x86\src60\xforms /s - -md %~dp0\x86\src60\ltests -xcopy %~dp0\..\src60\ltests\*.l %~dp0\x86\src60\ltests /s -xcopy %~dp0\..\src60\ltests\*.prj %~dp0\x86\src60\ltests /s - -md %~dp0\x86\src60\net -xcopy %~dp0\..\src60\net\*.l %~dp0\x86\src60\net /s -xcopy %~dp0\..\src60\net\*.prj %~dp0\x86\src60\net /s +md %~dp0\x86\src60 +xcopy %~dp0\..\src60\*.l %~dp0\x86\src60\ /s +xcopy %~dp0\..\src60\*.prj %~dp0\x86\src60\ /s copy %~dp0\..\src60\elena_api.prjcol %~dp0\x86\src60\ @@ -204,106 +103,14 @@ if %ERRORLEVEL% EQU -2 GOTO CompilerError if %ERRORLEVEL% EQU -2 GOTO CompilerError @echo on -copy %~dp0\..\examples60\console\helloworld\*.l %~dp0\x86\examples60\console\helloworld -copy %~dp0\..\examples60\console\helloworld\*.prj %~dp0\x86\examples60\console\helloworld - -copy %~dp0\..\examples60\console\sum\*.l %~dp0\x86\examples60\console\sum -copy %~dp0\..\examples60\console\sum\*.prj %~dp0\x86\examples60\console\sum - -copy %~dp0\..\examples60\console\words\*.l %~dp0\x86\examples60\console\words -copy %~dp0\..\examples60\console\binary\*.l %~dp0\x86\examples60\console\binary -copy %~dp0\..\examples60\console\bsort\*.l %~dp0\x86\examples60\console\bsort -copy %~dp0\..\examples60\console\datetime\*.l %~dp0\x86\examples60\console\datetime -copy %~dp0\..\examples60\console\datetime\*.prj %~dp0\x86\examples60\console\datetime -copy %~dp0\..\examples60\console\goods\*.l %~dp0\x86\examples60\console\goods -copy %~dp0\..\examples60\console\goods\*.txt %~dp0\x86\examples60\console\goods -copy %~dp0\..\examples60\console\replace\*.l %~dp0\x86\examples60\console\replace -copy %~dp0\..\examples60\console\pi\*.l %~dp0\x86\examples60\console\pi -copy %~dp0\..\examples60\console\matrix\*.l %~dp0\x86\examples60\console\matrix -copy %~dp0\..\examples60\console\matrix\*.prj %~dp0\x86\examples60\console\matrix -copy %~dp0\..\examples60\console\random\*.l %~dp0\x86\examples60\console\random - -copy %~dp0\..\examples60\scripts\calc\*.l %~dp0\x86\examples60\scripts\calc -copy %~dp0\..\examples60\scripts\calc\*.es %~dp0\x86\examples60\scripts\calc -copy %~dp0\..\examples60\scripts\calc\*.prj %~dp0\x86\examples60\scripts\calc - -copy %~dp0\..\examples60\scripts\interpreter\*.l %~dp0\x86\examples60\scripts\interpreter -copy %~dp0\..\examples60\scripts\interpreter\*.es %~dp0\x86\examples60\scripts\interpreter -copy %~dp0\..\examples60\scripts\interpreter\*.prj %~dp0\x86\examples60\scripts\interpreter -copy %~dp0\..\examples60\scripts\interpreter\*.txt %~dp0\x86\examples60\scripts\interpreter - -copy %~dp0\..\examples60\scripts\js\*.l %~dp0\x86\examples60\scripts\js -copy %~dp0\..\examples60\scripts\js\*.js %~dp0\x86\examples60\scripts\js -copy %~dp0\..\examples60\scripts\js\*.prj %~dp0\x86\examples60\scripts\js - -copy %~dp0\..\examples60\scripts\ls\*.l %~dp0\x86\examples60\scripts\ls -copy %~dp0\..\examples60\scripts\ls\*.ls %~dp0\x86\examples60\scripts\ls -copy %~dp0\..\examples60\scripts\ls\*.prj %~dp0\x86\examples60\scripts\ls - -copy %~dp0\..\examples60\rosetta\accumulator\*.l %~dp0\x86\examples60\rosetta\accumulator -copy %~dp0\..\examples60\rosetta\ackermann\*.l %~dp0\x86\examples60\rosetta\ackermann -copy %~dp0\..\examples60\rosetta\addfield\*.l %~dp0\x86\examples60\rosetta\addfield -copy %~dp0\..\examples60\rosetta\anonymrec\*.l %~dp0\x86\examples60\rosetta\anonymrec -copy %~dp0\..\examples60\rosetta\aplusb\*.l %~dp0\x86\examples60\rosetta\aplusb -copy %~dp0\..\examples60\rosetta\applycallback\*.l %~dp0\x86\examples60\rosetta\applycallback -copy %~dp0\..\examples60\rosetta\arithmeticint\*.l %~dp0\x86\examples60\rosetta\arithmeticint -copy %~dp0\..\examples60\rosetta\arithmeval\*.l %~dp0\x86\examples60\rosetta\arithmeval -copy %~dp0\..\examples60\rosetta\arithmmean\*.l %~dp0\x86\examples60\rosetta\arithmmean -copy %~dp0\..\examples60\rosetta\arrayconcat\*.l %~dp0\x86\examples60\rosetta\arrayconcat -copy %~dp0\..\examples60\rosetta\arraymode\*.l %~dp0\x86\examples60\rosetta\arraymode -copy %~dp0\..\examples60\rosetta\arrays\*.l %~dp0\x86\examples60\rosetta\arrays - -copy %~dp0\..\examples60\rosetta\associativearrays\*.l %~dp0\x86\examples60\rosetta\associativearrays -copy %~dp0\..\examples60\rosetta\bestshuffle\*.l %~dp0\x86\examples60\rosetta\bestshuffle -copy %~dp0\..\examples60\rosetta\binary\*.l %~dp0\x86\examples60\rosetta\binary -copy %~dp0\..\examples60\rosetta\bitwise\*.l %~dp0\x86\examples60\rosetta\bitwise -copy %~dp0\..\examples60\rosetta\brackets\*.l %~dp0\x86\examples60\rosetta\brackets -copy %~dp0\..\examples60\rosetta\bullscows\*.l %~dp0\x86\examples60\rosetta\bullscows -copy %~dp0\..\examples60\rosetta\caesar\*.l %~dp0\x86\examples60\rosetta\caesar -copy %~dp0\..\examples60\rosetta\calendar\*.l %~dp0\x86\examples60\rosetta\calendar -copy %~dp0\..\examples60\rosetta\charmatch\*.l %~dp0\x86\examples60\rosetta\charmatch -copy %~dp0\..\examples60\rosetta\combinations\*.l %~dp0\x86\examples60\rosetta\combinations -copy %~dp0\..\examples60\rosetta\doors\*.l %~dp0\x86\examples60\rosetta\doors -copy %~dp0\..\examples60\rosetta\evolutionary\*.l %~dp0\x86\examples60\rosetta\evolutionary -copy %~dp0\..\examples60\rosetta\firstclass\*.l %~dp0\x86\examples60\rosetta\firstclass -copy %~dp0\..\examples60\rosetta\loop_multiple_arrays\*.l %~dp0\x86\examples60\rosetta\loop_multiple_arrays -copy %~dp0\..\examples60\rosetta\median\*.l %~dp0\x86\examples60\rosetta\median -copy %~dp0\..\examples60\rosetta\ninetynine\*.l %~dp0\x86\examples60\rosetta\ninetynine -copy %~dp0\..\examples60\rosetta\reverse_words_in_string\*.l %~dp0\x86\examples60\rosetta\reverse_words_in_string -copy %~dp0\..\examples60\rosetta\smavg\*.l %~dp0\x86\examples60\rosetta\smavg -copy %~dp0\..\examples60\rosetta\string_append\*.l %~dp0\x86\examples60\rosetta\string_append -copy %~dp0\..\examples60\rosetta\twentyfour\*.l %~dp0\x86\examples60\rosetta\twentyfour - -copy %~dp0\..\examples60\gui\c_a_g\*.l %~dp0\x86\examples60\gui\c_a_g -copy %~dp0\..\examples60\gui\c_a_g\*.prj %~dp0\x86\examples60\gui\c_a_g - -copy %~dp0\..\examples60\gui\c_a_g\formulas\Circulo\*.bmp %~dp0\x86\examples60\gui\c_a_g\formulas\Circulo -copy %~dp0\..\examples60\gui\c_a_g\formulas\Paralelogramos\*.bmp %~dp0\x86\examples60\gui\c_a_g\formulas\Paralelogramos -copy %~dp0\..\examples60\gui\c_a_g\formulas\Trapezio\*.bmp %~dp0\x86\examples60\gui\c_a_g\formulas\Trapezio -copy %~dp0\..\examples60\gui\c_a_g\formulas\Triangulos\*.bmp %~dp0\x86\examples60\gui\c_a_g\formulas\Triangulos - -copy %~dp0\..\examples60\gui\agenda\*.l %~dp0\x86\examples60\gui\agenda -copy %~dp0\..\examples60\gui\agenda\*.prj %~dp0\x86\examples60\gui\agenda - -copy %~dp0\..\examples60\gui\graphs\*.l %~dp0\x86\examples60\gui\graphs -copy %~dp0\..\examples60\gui\graphs\*.prj %~dp0\x86\examples60\gui\graphs - -copy %~dp0\..\examples60\gui\helloworld\*.l %~dp0\x86\examples60\gui\helloworld -copy %~dp0\..\examples60\gui\helloworld\*.prj %~dp0\x86\examples60\gui\helloworld -copy %~dp0\..\examples60\gui\helloworld\*.xs %~dp0\x86\examples60\gui\helloworld - -copy %~dp0\..\examples60\db\sqlite\*.l %~dp0\x86\examples60\db\sqlite -copy %~dp0\..\examples60\db\sqlite\*.prj %~dp0\x86\examples60\db\sqlite - -copy %~dp0\..\examples60\files\textdb\*.l %~dp0\x86\examples60\files\textdb -copy %~dp0\..\examples60\files\textdb\*.prj %~dp0\x86\examples60\files\textdb -copy %~dp0\..\examples60\files\textdb\*.txt %~dp0\x86\examples60\files\textdb - -copy %~dp0\..\examples60\files\textfile\*.l %~dp0\x86\examples60\files\textfile -copy %~dp0\..\examples60\files\textfile\*.txt %~dp0\x86\examples60\files\textfile - -xcopy %~dp0\..\examples60\threads\*.l %~dp0\x86\examples60\threads /s -xcopy %~dp0\..\examples60\threads\*.prj %~dp0\x86\examples60\threads /s +xcopy %~dp0\..\examples60\*.l %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.prj %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.txt %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.bmp %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.es %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.js %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.ls %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.xs %~dp0\x86\examples60\ /s goto:eof ::ERRORS diff --git a/build/elena_inno.iss b/build/elena_inno.iss index 66ef664798..2ddc96780f 100644 --- a/build/elena_inno.iss +++ b/build/elena_inno.iss @@ -7,7 +7,7 @@ ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{3CAA69D3-0F98-44B1-A73E-E864BA51D5BD} AppName=ELENA Programming Language -AppVersion=6.6.2 +AppVersion=6.6.3 ;AppVerName=ELENA Programming Language 6.6.0 AppPublisher=Alexey Rakov AppPublisherURL=http://github.com/ELENA-LANG/elena-lang @@ -18,7 +18,7 @@ DefaultGroupName=ELENA Programming Language AllowNoIcons=yes LicenseFile=..\doc\license InfoAfterFile=..\CHANGELOG.md -OutputBaseFilename=elena-lang-6.6.2.x86-win-setup +OutputBaseFilename=elena-lang-6.6.3.x86-win-setup Compression=lzma SolidCompression=yes ChangesEnvironment=yes diff --git a/build/i386/build_package_i386.script b/build/i386/build_package_i386.script index 2aa893271a..45150cc9e4 100755 --- a/build/i386/build_package_i386.script +++ b/build/i386/build_package_i386.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.2.i386-linux +RELEASE=elena-6.6.3.i386-linux mkdir -p ../lib60 mkdir -p /usr/share/elena @@ -159,17 +159,7 @@ echo compiling lib60 files mkdir -p ./$RELEASE/usr/bin/ mkdir -p ./$RELEASE/usr/elena-lang - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/accumulator/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/ackermann/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/addfield/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/anonymrec/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/aplusb/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/applycallback/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmeticint/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmeval/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmmean/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arrayconcat/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arraymode/ + mkdir -p ./$RELEASE/usr/elena-lang/examples60 echo copying configuration diff --git a/build/i386/control b/build/i386/control index e8744dca25..df5785ced6 100644 --- a/build/i386/control +++ b/build/i386/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.2 +Version: 6.6.3 Architecture: i386 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/ppc64le/build_package_ppc64le.script b/build/ppc64le/build_package_ppc64le.script index c807419d4a..539c09be10 100755 --- a/build/ppc64le/build_package_ppc64le.script +++ b/build/ppc64le/build_package_ppc64le.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.2.ppc64le-linux +RELEASE=elena-6.6.3.ppc64le-linux mkdir -p ../lib60_64 mkdir -p /usr/share/elena @@ -145,21 +145,7 @@ fi mkdir -p ./$RELEASE/usr/bin/ mkdir -p ./$RELEASE/usr/elena-lang - mkdir -p ./$RELEASE/usr/elena-lang/examples60/console/helloworld/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/console/sum/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/console/words/ - - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/accumulator/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/ackermann/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/addfield/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/anonymrec/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/aplusb/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/applycallback/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmeticint/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmeval/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arithmmean/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arrayconcat/ - mkdir -p ./$RELEASE/usr/elena-lang/examples60/rosetta/arraymode/ + mkdir -p ./$RELEASE/usr/elena-lang/examples60/ echo copying configuration diff --git a/build/ppc64le/control b/build/ppc64le/control index 3f0a0e7cc7..47fb1f0279 100644 --- a/build/ppc64le/control +++ b/build/ppc64le/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.2 +Version: 6.6.3 Architecture: ppc64le Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/doc/api/extensions-routines-summary.html b/doc/api/extensions-routines-summary.html index e406e793fb..28db068cfe 100644 --- a/doc/api/extensions-routines-summary.html +++ b/doc/api/extensions-routines-summary.html @@ -89,11 +89,11 @@

-printingLn +PrintingLn
-public singleton printingLn
+public singleton PrintingLn @@ -128,6 +128,26 @@

  • +Symbol Summary +
    + + + + + + + + +
    Symbol nameDescription
    +printingLn + +
    +printingLn
    +
    +
  • +
  • + +
    Extended Class Summary
    diff --git a/doc/api/extensions-routines.html b/doc/api/extensions-routines.html index 7bfe8b451f..90bc22a3da 100644 --- a/doc/api/extensions-routines.html +++ b/doc/api/extensions-routines.html @@ -602,20 +602,20 @@

    Method Summary


    - +
    extensions'routines'
    -

    printingLn

    +

    PrintingLn



    -public singleton printingLn
    +public singleton PrintingLn
      @@ -624,7 +624,7 @@

      printingLn

      • -extensions'routines'printingLn
      • +extensions'routines'PrintingLn
    @@ -1025,6 +1025,43 @@

    Method Summary


    + + + +
    +
    +extensions'routines'
    +

    printingLn

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      +
    + + + + + + +
    Modifier and TypeName
    + +public   +printingLn +
    +
  • + + +
    + diff --git a/doc/api/forms-summary.html b/doc/api/forms-summary.html index 70e431099f..196227e314 100644 --- a/doc/api/forms-summary.html +++ b/doc/api/forms-summary.html @@ -116,6 +116,15 @@

    +Combobox + + +
    +public class Combobox
    + + + + Edit @@ -123,7 +132,7 @@

    public class Edit - + Frame @@ -132,7 +141,7 @@

    public class Frame - + IControl @@ -141,7 +150,7 @@

    abstract public class IControl - + Imagebox @@ -150,7 +159,7 @@

    public class Imagebox - + ImageList @@ -159,7 +168,7 @@

    public class ImageList - + Label @@ -168,7 +177,7 @@

    public class Label - + messageDialog @@ -177,7 +186,7 @@

    public singleton messageDialog - + OpenFileDialog @@ -186,7 +195,7 @@

    public class OpenFileDialog - + Paintbox @@ -195,7 +204,7 @@

    public class Paintbox - + Panel @@ -204,7 +213,7 @@

    public class Panel - + RadioButton @@ -213,7 +222,7 @@

    public class RadioButton - + RadioButtonGroup @@ -222,7 +231,7 @@

    public class RadioButtonGroup - + SaveFileDialog @@ -231,7 +240,7 @@

    public class SaveFileDialog - + SDIDialog @@ -240,7 +249,7 @@

    public class SDIDialog - + SDIForm @@ -249,7 +258,7 @@

    public class SDIForm - + StaticLabel diff --git a/doc/api/forms.html b/doc/api/forms.html index 4279395b3e..b3cef8153d 100644 --- a/doc/api/forms.html +++ b/doc/api/forms.html @@ -1774,6 +1774,170 @@

    Method Summary


    + + + +
    +
    +forms'
    +

    Combobox

    +
    +
    +
    +
    +
    +
    +public class Combobox
    +
    +
    + + + + +
      +
    • +

      Constructor Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +Combobox +new() + +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + +
      Modifier and TypeMethod
      + +internal   +createHandle() + +
      +
    • +
    +
    +
    diff --git a/doc/api/system-culture-summary.html b/doc/api/system-culture-summary.html index f44fc850bc..70c550ce7c 100644 --- a/doc/api/system-culture-summary.html +++ b/doc/api/system-culture-summary.html @@ -44,6 +44,15 @@

    +ILocale + + +
    +abstract public class ILocale
    + + + + Locale diff --git a/doc/api/system-culture.html b/doc/api/system-culture.html index 9f7364b88c..56cf0159b6 100644 --- a/doc/api/system-culture.html +++ b/doc/api/system-culture.html @@ -23,6 +23,82 @@ + + + +
    +
    +system'culture'
    +

    ILocale

    +
    +
    +
    +
    +
    +
    +abstract public class ILocale
    +
    +
    + + + +
    +
    @@ -45,7 +121,7 @@

    Locale

  • @@ -570,7 +605,7 @@

    Extension Summary

    -Task +Task<system'IntNumber> writeAsync(system'ByteNumber[] dump, IntNumber length) @@ -579,6 +614,33 @@

    Extension Summary

    +Task + +writeAsync(String s) + + + + + + +Task<system'String> + +readAsStringAsync() + + + + + + +Task<system'IntNumber> + +readAsync(MemoryBuffer buffer, IntNumber length) + + + + + + get property  BoolValue isDataAvailable() @@ -739,12 +801,46 @@

    Property Summary

    +get  ShortNumber + +Family() + + + + + +set   + +Family(ShortNumber val) + + + + + + +set   + +Ip4_address(String ip) + + + + + + set   -ip_address(String ip) +Port(ShortNumber value) + + + +get  ShortNumber + +Port() + +
  • @@ -826,6 +922,27 @@

    Constructor Summary

    + +
      +
    • +

      Static Method Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +Socket +connect(String host, ShortNumber port) + +
      +
    • +
    • @@ -889,7 +1006,7 @@

      Method Summary

      -bind(UnsafePointer sockAddrPtr, IntNumber nameLen) +open(SOCKADDR_IN sockAddr) @@ -898,55 +1015,37 @@

      Method Summary

      -listen(IntNumber backLog) +bind(UnsafePointer sockAddrPtr, IntNumber nameLen) -BoolValue + -tryOpen(UnsafePointer ptr, IntNumber len) +listen(IntNumber backLog) - +BoolValue -connect(String ip_address, IntNumber port) +tryOpen(UnsafePointer ptr, IntNumber len) -Task - -connectAsync(String ip_address, IntNumber port) - - - - - - IntNumber send(system'ByteNumber[] buffer) - - - -Task<system'IntNumber> - -sendAsync(system'ByteNumber[] buffer) - - - @@ -959,30 +1058,12 @@

      Method Summary

      -Task<system'IntNumber> - -sendAsync(system'ByteNumber[] buffer, IntNumber length, IntNumber flags) - - - - - - IntNumber receive(system'ByteNumber[] buffer, IntNumber maxLength, IntNumber flags) - - - -Task<system'IntNumber> - -receiveAsync(system'ByteNumber[] buffer, IntNumber maxLength, IntNumber flags) - - - @@ -995,22 +1076,13 @@

      Method Summary

      -Task<system'net'Socket> - -acceptAsync() - - - - - - shutdown(IntNumber how) - + IntNumber @@ -1019,7 +1091,7 @@

      Method Summary

      - + @@ -1028,7 +1100,7 @@

      Method Summary

      - + BoolValue @@ -1037,7 +1109,7 @@

      Method Summary

      - + IntNumber @@ -1046,7 +1118,7 @@

      Method Summary

      - + BoolValue @@ -1055,7 +1127,7 @@

      Method Summary

      - + diff --git a/doc/api/system-text.html b/doc/api/system-text.html index 421eb85b26..63d9d93637 100644 --- a/doc/api/system-text.html +++ b/doc/api/system-text.html @@ -243,7 +243,7 @@

      Method Summary

      -insert(index, o) +write(o) @@ -252,7 +252,7 @@

      Method Summary

      -write(CharValue ch) +insert(index, o) @@ -261,7 +261,7 @@

      Method Summary

      -write(String s) +write(CharValue ch) @@ -270,7 +270,7 @@

      Method Summary

      -wide(o) +write(String s) diff --git a/doc/api/system-winforms-summary.html b/doc/api/system-winforms-summary.html index b0fc1623e2..e46eb39b1d 100644 --- a/doc/api/system-winforms-summary.html +++ b/doc/api/system-winforms-summary.html @@ -280,6 +280,33 @@

      +CBS_DROPDOWN + + +
      +CBS_DROPDOWN
      + + + + +CBS_DROPDOWNLIST + + +
      +CBS_DROPDOWNLIST
      + + + + +ComboboxClass + + +
      +ComboboxClass
      + + + + CS_HREDRAW @@ -287,7 +314,7 @@

      CS_HREDRAW - + CS_VREDRAW @@ -296,7 +323,7 @@

      CS_VREDRAW - + CurrentInstance @@ -305,7 +332,7 @@

      CurrentInstance - + CW_USEDEFAULT @@ -314,7 +341,7 @@

      CW_USEDEFAULT - + DS_CENTER @@ -323,7 +350,7 @@

      DS_CENTER - + EditClass @@ -332,7 +359,7 @@

      EditClass - + EN_CHANGE @@ -341,7 +368,7 @@

      EN_CHANGE - + EX_SDI_OVERLAPPEDWINDOW @@ -350,7 +377,7 @@

      EX_SDI_OVERLAPPEDWINDOW - + GWL_USERDATA @@ -359,7 +386,7 @@

      GWL_USERDATA - + HTCLIENT @@ -368,7 +395,7 @@

      HTCLIENT - + IDC_ARROW @@ -377,7 +404,7 @@

      IDC_ARROW - + IDNO @@ -386,7 +413,7 @@

      IDNO - + IDOK @@ -395,7 +422,7 @@

      IDOK - + IDRETRY @@ -404,7 +431,7 @@

      IDRETRY - + IDTRYAGAIN @@ -413,7 +440,7 @@

      IDTRYAGAIN - + IDYES @@ -422,7 +449,7 @@

      IDYES - + MB_ABORTRETRYIGNORE @@ -431,7 +458,7 @@

      MB_ABORTRETRYIGNORE - + MB_CANCELTRYCONTINUE @@ -440,7 +467,7 @@

      MB_CANCELTRYCONTINUE - + MB_HELP @@ -449,7 +476,7 @@

      MB_HELP - + MB_ICONASTERISK @@ -458,7 +485,7 @@

      MB_ICONASTERISK - + MB_ICONERROR @@ -467,7 +494,7 @@

      MB_ICONERROR - + MB_ICONEXCLAMATION @@ -476,7 +503,7 @@

      MB_ICONEXCLAMATION - + MB_ICONHAND @@ -485,7 +512,7 @@

      MB_ICONHAND - + MB_ICONINFORMATION @@ -494,7 +521,7 @@

      MB_ICONINFORMATION - + MB_ICONQUESTION @@ -503,7 +530,7 @@

      MB_ICONQUESTION - + MB_ICONSTOP @@ -512,7 +539,7 @@

      MB_ICONSTOP - + MB_ICONWARNING @@ -521,7 +548,7 @@

      MB_ICONWARNING - + MB_OK @@ -530,7 +557,7 @@

      MB_OK - + MB_OKCANCEL @@ -539,7 +566,7 @@

      MB_OKCANCEL - + MB_RETRYCANCEL @@ -548,7 +575,7 @@

      MB_RETRYCANCEL - + MB_YESNO @@ -557,7 +584,7 @@

      MB_YESNO - + MB_YESNOCANCEL @@ -566,7 +593,7 @@

      MB_YESNOCANCEL - + MF_POPUP @@ -575,7 +602,7 @@

      MF_POPUP - + MF_STRING @@ -584,7 +611,7 @@

      MF_STRING - + OFN_EXPLORER @@ -593,7 +620,7 @@

      OFN_EXPLORER - + OFN_HIDEREADONLY @@ -602,7 +629,7 @@

      OFN_HIDEREADONLY - + OFN_LONGNAMES @@ -611,7 +638,7 @@

      OFN_LONGNAMES - + OFN_PATHMUSTEXIST @@ -620,7 +647,7 @@

      OFN_PATHMUSTEXIST - + PaintboxClass @@ -629,7 +656,7 @@

      PaintboxClass - + PanelClass @@ -638,7 +665,7 @@

      PanelClass - + program @@ -647,7 +674,7 @@

      program - + SDIWindowClass @@ -656,7 +683,7 @@

      SDIWindowClass - + SS_SIMPLE @@ -665,7 +692,7 @@

      SS_SIMPLE - + StaticClass @@ -674,7 +701,7 @@

      StaticClass - + SWP_NOMOVE @@ -683,7 +710,7 @@

      SWP_NOMOVE - + SWP_NOSIZE @@ -692,7 +719,7 @@

      SWP_NOSIZE - + WM_CLOSE @@ -701,7 +728,7 @@

      WM_CLOSE - + WM_DESTROY @@ -710,7 +737,7 @@

      WM_DESTROY - + WM_GETTEXT @@ -719,7 +746,7 @@

      WM_GETTEXT - + WM_GETTEXTLENGTH @@ -728,7 +755,7 @@

      WM_GETTEXTLENGTH - + WM_PAINT @@ -737,7 +764,7 @@

      WM_PAINT - + WM_SETTEXT @@ -746,7 +773,7 @@

      WM_SETTEXT - + WS_BORDER @@ -755,7 +782,7 @@

      WS_BORDER - + WS_CHILD @@ -764,7 +791,7 @@

      WS_CHILD - + WS_CLIPSIBLINGS @@ -773,7 +800,7 @@

      WS_CLIPSIBLINGS - + WS_DIALOGWINDOW @@ -782,7 +809,7 @@

      WS_DIALOGWINDOW - + WS_DLGFRAME @@ -791,7 +818,7 @@

      WS_DLGFRAME - + WS_ELENAWINDOW @@ -800,7 +827,7 @@

      WS_ELENAWINDOW - + WS_EX_CLIENTEDGE @@ -809,7 +836,7 @@

      WS_EX_CLIENTEDGE - + WS_EX_CONTROLPARENT @@ -818,7 +845,7 @@

      WS_EX_CONTROLPARENT - + WS_EX_DLGMODALFRAME @@ -827,7 +854,7 @@

      WS_EX_DLGMODALFRAME - + WS_EX_NOPARENTNOTIFY @@ -836,7 +863,7 @@

      WS_EX_NOPARENTNOTIFY - + WS_EX_OVERLAPPEDWINDOW @@ -845,7 +872,7 @@

      WS_EX_OVERLAPPEDWINDOW - + WS_EX_TRANSPARENT @@ -854,7 +881,7 @@

      WS_EX_TRANSPARENT - + WS_HSCROLL @@ -863,7 +890,7 @@

      WS_HSCROLL - + WS_OVERLAPPEDWINDOW @@ -872,7 +899,7 @@

      WS_OVERLAPPEDWINDOW - + WS_POPUPWINDOW @@ -881,7 +908,7 @@

      WS_POPUPWINDOW - + WS_TABSTOP @@ -890,7 +917,7 @@

      WS_TABSTOP - + WS_VISIBLE @@ -899,7 +926,7 @@

      WS_VISIBLE - + WS_VSCROLL diff --git a/doc/api/system-winforms.html b/doc/api/system-winforms.html index d1c1ec0f58..3a8b93e2e1 100644 --- a/doc/api/system-winforms.html +++ b/doc/api/system-winforms.html @@ -2061,6 +2061,117 @@

      Symbol Summary


      + + + +
      +
      +system'winforms'
      +

      CBS_DROPDOWN

      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
        +
      • +

        Symbol Summary

        + + + + + + + +
        Modifier and TypeName
        + +public  IntNumber +CBS_DROPDOWN +
        +
      • +
      +
      +
      +
      + + + +
      +
      +system'winforms'
      +

      CBS_DROPDOWNLIST

      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
        +
      • +

        Symbol Summary

        + + + + + + + +
        Modifier and TypeName
        + +public  IntNumber +CBS_DROPDOWNLIST +
        +
      • +
      +
      +
      +
      + + + +
      +
      +system'winforms'
      +

      ComboboxClass

      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
        +
      • +

        Symbol Summary

        + + + + + + + +
        Modifier and TypeName
        + +public  WideString +ComboboxClass +
        +
      • +
      +
      +
      +
      diff --git a/doc/api/system.html b/doc/api/system.html index e940794353..3cf3c053c0 100644 --- a/doc/api/system.html +++ b/doc/api/system.html @@ -19173,7 +19173,7 @@

      Property Summary

      -get  IntNumber +get  UnsafePointer
      Value() @@ -19181,12 +19181,30 @@

      Property Summary

      +set  IntNumber + +Value(ref IntNumber arg1) + + + + + + set  RealNumber Value(ref RealNumber arg1) + + + +set  LongNumber + +Value(ref LongNumber arg1) + + + @@ -19265,9 +19283,27 @@

      Method Summary

      +LongNumber + +getLongValue() + + + + + + +String + +getStringUnsafe() + + + + + + -copyTo(system'ByteNumber[] target, IntNumber len) +copyToUnsafe(Object ptr, IntNumber length) @@ -19276,6 +19312,15 @@

      Method Summary

      +copyTo(system'ByteNumber[] target, IntNumber len) + + + + + + + + copyTo(system'ByteNumber[] target, IntNumber index, IntNumber len) diff --git a/doc/contributors b/doc/contributors index 08a9d05de4..8357ad8f9b 100644 --- a/doc/contributors +++ b/doc/contributors @@ -1,4 +1,5 @@ Aleksey Rakov (creator) Alexandre Bencz (examples : agenda, c_a_g, sqlite_test ..., lib : sqllite, ... and a lot of bug reports, work on asm2binx) Raymond Filiatreault / FPULIB21a (float numer routines) +Httplib : Copyright (c) 2025 Yuji Hirose. All rights reserved. Yair Bybabayov (elenavm, elc) \ No newline at end of file diff --git a/doc/features b/doc/features index 5334167efe..85161915f8 100644 --- a/doc/features +++ b/doc/features @@ -89,7 +89,7 @@ public program() String interpolation ---------------------------------------------------------------------------- - var s := var s := $"a_{ 1 }_b_{ 2 }_c"; + var s := $"a_{ 1 }_b_{ 2 }_c"; ---------------------------------------------------------------------------- user-defined literals @@ -216,3 +216,26 @@ public program() console.printLine(variable); } } + +---------------------------------------------------------------------------- + Auto fields +---------------------------------------------------------------------------- + +---------------------------------------------------------------------------- + Private fields +---------------------------------------------------------------------------- + +---------------------------------------------------------------------------- + Module info +---------------------------------------------------------------------------- + +import extensions; +import extensions'runtime; + +public program() +{ + var o := new MyObject(); + Console.printLine("MyObject info:", o.getFullPackageInfo()); +} + + \ No newline at end of file diff --git a/doc/readme.txt b/doc/readme.txt index 461412c61a..30195596fc 100644 --- a/doc/readme.txt +++ b/doc/readme.txt @@ -1,5 +1,5 @@ - ELENA Language Project V. 6.0 - (C)2005-2024 By Alex Rakov + ELENA Language Project V. 6.6 + (C)2005-2026 By Alex Rakov The project includes ELENA documentation, standard library source code, samples, command-line compiler, IDE. diff --git a/doc/tech/bytecode60.txt b/doc/tech/bytecode60.txt index 0e13c81fec..b46eab4164 100644 --- a/doc/tech/bytecode60.txt +++ b/doc/tech/bytecode60.txt @@ -391,6 +391,14 @@ ELENA byte codes (or ecodes) fisub - double:[acc] -= int:[sp[0]] + fladd - double:[acc] += long:[sp[0]] + + fldiv - double:[acc] /= long:[sp[0]] + + flmul - double:[acc] *= long:[sp[0]] + + flsub - double:[acc] -= long:[sp[0]] + fmul dp:disp, n - temp : n << sp[0]; [dp[disp]] *= temp; n = 8 diff --git a/doc/todo.txt b/doc/todo.txt index 9ff643e3d6..f394edddc5 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -5,50 +5,55 @@ In development: [development] ### EPIC: elena 6.7 ### - === Iteration 38 (05.04) === + === Iteration 39 (18.4) === -------------------------------------- dev: - - upndown (connector - interaction) + - support fladd, flsub, fldiv, flmul (throu special prefix??) + - #34 : https get (Mbed TLS - https://github.com/Mbed-TLS/mbedtls/blob/development/programs/ssl/ssl_client1.c), + - MTA support for Linux - #496 - #622 - - #34 : http client (http get, https get (https://github.com/HISONA/https_client), post, put, patch, delete, head, options, trace), web api - - MTA support for Linux - #708 : compile the project (elc, og, sg, asm, ecv), create Linker - - implement ExtensionMessage.equal - ide: - - linux - select tab, save, close - - fix syntax highlighting (see system'net:win_common.l) - - ide : windows + - unit tests for try-catch / try-catch-finally / try-finally + - upndown (connector - interaction) gen: - lpad / elt : declare an extension, parse it and apply to the input + ide: + - ide : windows + - syntax highlighting + - #184 : linux - save, close, ... + - async method - auto watch : self and some variables are not displayed maint: - - pi samples for ppc64, aarch64 + - github actions : `set-output` command is deprecated - test all x86-64 examples - unit tests : bt optimization - - warn if typecasting method returns itself, it leads to infinite call - - test binary file reader / writer + - arrange action for i386 / amd64 linux release + api: + - implement ExtensionMessage.equal - api : add descriptions - - api refactoring : all symbols must start with a capital letter (e.g. printingLn) + - api refactoring : main program entry to be called - Program port: - - chat sample - - rosetta code : moving to 6.5 + - pi samples for aarch64 + - x86-64 : httpget, threading samples + - rosetta code : moving to 6.6 (test, use Console) - x86-64 : mta - test net examples for mta - test all x86-64 examples (net) - - pi samples for ppc64, aarch64 - tools: - - #658 : connect with ldbg from VSCode + tools: + - vs #2 : elena.tmLanguage.json + - #658 : connect with ldbg from VSCode : launch exe, implement built-in debugger prom: bi-posting weekly -------------------------------------- -------------------------------------- -------------------------------------- - === Iteration 39 === + === Iteration 40 === -------------------------------------- dev: + - #34 : http client : support redirects, post, put, patch, delete, head, options, trace), web api gen: maint: - - review pi performance (must < 6) port: + - chat sample prom: -------------------------------------- -------------------------------------- @@ -56,18 +61,19 @@ In development: ### EPIC: elena 6.8 ### - === Iteration 40 === + === Iteration 41 === -------------------------------------- dev: gen: maint: + - review pi performance (must < 6) port: prom: -------------------------------------- -------------------------------------- -------------------------------------- - === Iteration 41 === + === Iteration 42 === -------------------------------------- dev: gen: diff --git a/elenasrc3/common/tree.h b/elenasrc3/common/tree.h index 8db4071b0e..3fa5479698 100644 --- a/elenasrc3/common/tree.h +++ b/elenasrc3/common/tree.h @@ -108,6 +108,7 @@ namespace elena_lang NodeRecord nw; nw.next = INVALID_POS; + nw.child = INVALID_POS; nw.key = key; nw.arg = arg; @@ -595,7 +596,6 @@ namespace elena_lang pos_t _current; Stack _bookmarks; - pos_t _pendingBookmarks; void updateBookmarks(Stack& bookmarks, pos_t oldPos, pos_t newPos) { @@ -609,11 +609,10 @@ namespace elena_lang { NodeArg arg(argument, strArgRef); - pos_t prev = _tree->readPrevious(position); - if (prev != INVALID_REF) { - _current = _tree->injectSibling(prev, type, arg); + if (position != INVALID_REF) { + _current = _tree->injectSibling(position, type, arg); } - else _current = _tree->injectChild(position, type, arg); + else _current = _tree->injectChild(_current, type, arg); updateBookmarks(_bookmarks, position, _current); } @@ -621,16 +620,15 @@ namespace elena_lang public: pos_t newBookmark() { - _pendingBookmarks++; + Node lastNode = CurrentNode().lastChild(); - return _bookmarks.count() + _pendingBookmarks; + _bookmarks.push(lastNode._position); + + return _bookmarks.count(); } void removeBookmark() { - if (_pendingBookmarks > 0) { - _pendingBookmarks--; - } - else _bookmarks.pop(); + _bookmarks.pop(); } void newNode(Key key, ref_t arg) @@ -705,7 +703,6 @@ namespace elena_lang _tree->clear(); _current = INVALID_POS; _bookmarks.clear(); - _pendingBookmarks = 0; } Writer(Tree& tree) @@ -713,14 +710,12 @@ namespace elena_lang { this->_tree = &tree; this->_current = INVALID_POS; - this->_pendingBookmarks = 0; } Writer(Node& node) : _bookmarks(INVALID_POS) { this->_tree = node._tree; this->_current = node._position; - this->_pendingBookmarks = 0; } }; diff --git a/elenasrc3/common/ustring.cpp b/elenasrc3/common/ustring.cpp index f8faf6baab..2ea36635e4 100644 --- a/elenasrc3/common/ustring.cpp +++ b/elenasrc3/common/ustring.cpp @@ -3,7 +3,7 @@ // // This file contains String classes implementations // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov // (C)1994-2004, Unicode, Inc. //--------------------------------------------------------------------------- diff --git a/elenasrc3/common/ustring.h b/elenasrc3/common/ustring.h index 79e4756fc2..db92390da8 100644 --- a/elenasrc3/common/ustring.h +++ b/elenasrc3/common/ustring.h @@ -3,7 +3,7 @@ // // This header contains UTF8 String classes declarations // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef USTRING_H @@ -600,6 +600,13 @@ namespace elena_lang } public: + bool allocate(size_t size) + { + create(size); + + return _string != nullptr; + } + T& operator[](size_t index) { return *(_string + index); @@ -700,7 +707,10 @@ namespace elena_lang copy(value, getlength(value)); } - + virtual ~DynamicString() + { + freestr(_string); + } }; typedef DynamicString DynamicUStr; diff --git a/elenasrc3/dpa/dpa_common.h b/elenasrc3/dpa/dpa_common.h deleted file mode 100644 index 4a43fa1f67..0000000000 --- a/elenasrc3/dpa/dpa_common.h +++ /dev/null @@ -1,17 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA Debugger Adapater -// -// This file contains the common DPA declarations -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#ifndef DPA_COMMON_H -#define DPA_COMMON_H - -namespace dpa -{ - -} - -#endif \ No newline at end of file diff --git a/elenasrc3/dpa/dpa_queue.h b/elenasrc3/dpa/dpa_queue.h deleted file mode 100644 index b0c655eda7..0000000000 --- a/elenasrc3/dpa/dpa_queue.h +++ /dev/null @@ -1,67 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA Debugger Adapater -// -// This file contains the DPA queue declarations -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#ifndef DPA_QUEUE_H -#define DPA_QUEUE_H - -#include -#include -#include -#include - -namespace dpa -{ - // --- ContentReader --- - template - class ThreadQueue - { - bool _closed = false; - std::queue _queue; - std::condition_variable _cv; - std::mutex _mutex; - - public: - void close(); - - void put(const T& in); - std::optional take(); - }; - - template - void ThreadQueue :: close() - { - std::unique_lock lock(_mutex); - _closed = true; - _cv.notify_all(); - } - - template - void ThreadQueue :: put(const T& in) - { - std::unique_lock lock(_mutex); - auto notify = _queue.size() == 0 && !_closed; - _queue.push(in); - if (notify) - _cv.notify_all(); - } - - template - std::optional ThreadQueue :: take() - { - std::unique_lock lock(_mutex); - _cv.wait(lock, [&] { return _queue.size() > 0 || _closed; }); - if (_queue.size() == 0) { - return std::optional(); - } - auto out = std::move(_queue.front()); - _queue.pop(); - return std::optional(std::move(out)); - } -} - -#endif \ No newline at end of file diff --git a/elenasrc3/dpa/dpa_session.cpp b/elenasrc3/dpa/dpa_session.cpp deleted file mode 100644 index 1acfdf2138..0000000000 --- a/elenasrc3/dpa/dpa_session.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA Debugger Adapater -// -// This file contains the DPA Session implementations -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#include "dpa_session.h" - -using namespace dpa; - -Session :: Session() -{ - -} - -Session :: ~Session() -{ - _inbox.close(); - if (_recvThread.joinable()) { - _recvThread.join(); - } - if (_dispatchThread.joinable()) { - _dispatchThread.join(); - } - _reader.close(); -} - -void Session :: connect() -{ - _reader = ContentReader(); -} - -Payload Session :: getPayload() -{ - return {}; -} - -void Session :: start(const ClosedHandler& onClose) -{ - _recvThread = std::thread([this/*, onClose*/] { - while (_reader.isOpen()) { - if (auto payload = getPayload()) { - _inbox.put(std::move(payload)); - } - } - //if (onClose) { - // onClose(); - //} - }); - - _dispatchThread = std::thread([this] { - while (auto payload = _inbox.take()) { - payload.value()(); - } - }); - -} \ No newline at end of file diff --git a/elenasrc3/dpa/dpa_session.h b/elenasrc3/dpa/dpa_session.h deleted file mode 100644 index 4c0dd35d1f..0000000000 --- a/elenasrc3/dpa/dpa_session.h +++ /dev/null @@ -1,51 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA Debugger Adapater -// -// This file contains the DPA Session declarations -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#ifndef DPA_SESSION_H -#define DPA_SESSION_H - -#include -#include - -#include "dpa_stream.h" -#include "dpa_queue.h" - -namespace dpa -{ - using Payload = std::function; - using PayloadQueue = ThreadQueue; - - using ClosedHandler = std::function; - - //using RequestHandler = - // std::function; - - // --- Session --- - class Session - { - ContentReader _reader; - PayloadQueue _inbox; - - std::thread _recvThread; - std::thread _dispatchThread; - - Payload getPayload(); - - public: - //virtual void registerHandler(const TypeInfo* typeinfo, - // const RequestHandler& handler); - - void connect(); - void start(const ClosedHandler& onClose = {}); - - Session(); - virtual ~Session(); - }; -} - -#endif \ No newline at end of file diff --git a/elenasrc3/dpa/dpa_stream.cpp b/elenasrc3/dpa/dpa_stream.cpp deleted file mode 100644 index 7401e3459f..0000000000 --- a/elenasrc3/dpa/dpa_stream.cpp +++ /dev/null @@ -1,26 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA Debugger Adapater -// -// This file contains the DPA I/O class implementations -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#include "dpa_stream.h" - -using namespace dpa; - -ContentReader :: ~ContentReader() -{ - -} - -bool ContentReader :: isOpen() -{ - return false; -} - -void ContentReader :: close() -{ - -} diff --git a/elenasrc3/dpa/dpa_stream.h b/elenasrc3/dpa/dpa_stream.h deleted file mode 100644 index 99e7dc97fa..0000000000 --- a/elenasrc3/dpa/dpa_stream.h +++ /dev/null @@ -1,31 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA Debugger Adapater -// -// This file contains the DPA I/O class declarations -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#ifndef DPA_STREAM_H -#define DPA_STREAM_H - -namespace dpa -{ - //using RequestHandler = - // std::function; - - // --- ContentReader --- - class ContentReader - { - - public: - bool isOpen(); - - void close(); - - ContentReader() = default; - virtual ~ContentReader(); - }; -} - -#endif \ No newline at end of file diff --git a/elenasrc3/elc/clicommon.h b/elenasrc3/elc/clicommon.h index fb0a72c2b1..72f9c5cd15 100644 --- a/elenasrc3/elc/clicommon.h +++ b/elenasrc3/elc/clicommon.h @@ -304,6 +304,7 @@ class ModuleScopeBase : public SectionScopeBase int ptrSize; bool tapeOptMode; + bool reusingTemplates; Map cachedSizes; Map cachedClassReferences; @@ -354,6 +355,8 @@ class ModuleScopeBase : public SectionScopeBase virtual Visibility retrieveVisibility(ref_t reference) = 0; + virtual void flush() = 0; + ModuleScopeBase(ModuleBase* module, ModuleBase* debugModule, pos_t stackAlingment, @@ -392,50 +395,51 @@ class ModuleScopeBase : public SectionScopeBase enum class ExpressionAttribute : pos64_t { - None = 0x00000000000, - Meta = 0x00000000001, - NestedNs = 0x00000000002, - Forward = 0x00000000004, - Weak = 0x00000000008, - NoTypeAllowed = 0x00000000010, - Intern = 0x00000000020, - Parameter = 0x00000000040, - NewVariable = 0x00000000080, - Local = 0x00000000100, - NewOp = 0x00000000200, - StrongResolved = 0x00000000400, - RootSymbol = 0x00000000800, - Root = 0x00000001000, - CastOp = 0x00000002000, - IgnoreDuplicate = 0x00000004000, - RefOp = 0x00000008000, - NoPrimitives = 0x00000010000, - MssgLiteral = 0x00000020000, - MssgNameLiteral = 0x00000040000, - Extern = 0x00000080000, - Member = 0x00000100000, - ProbeMode = 0x00000200000, - AllowPrivateCall = 0x00000400000, - InitializerScope = 0x00000800000, - NestedDecl = 0x00001000000, - ConstantExpr = 0x00002000000, - Variadic = 0x00004000000, - WithVariadicArg = 0x00008000000, - RetrievingType = 0x00010000000, - RetValExpected = 0x00020000000, - CheckShortCircle = 0x00040000000, - LookaheadExprMode = 0x00080000000, - Class = 0x00100000000, - Nillable = 0x00200000000, - AllowGenericSignature= 0x00400000000, - OutRefOp = 0x01000000000, - WithVariadicArgCast = 0x02008000000, - DistributedForward = 0x04000000000, - DynamicObject = 0x08000000000, - Superior = 0x10000000000, - Lookahead = 0x20000000000, - NoDebugInfo = 0x40000000000, - NoExtension = 0x80000000000, + None = 0x000000000000, + Meta = 0x000000000001, + NestedNs = 0x000000000002, + Forward = 0x000000000004, + Weak = 0x000000000008, + NoTypeAllowed = 0x000000000010, + Intern = 0x000000000020, + Parameter = 0x000000000040, + NewVariable = 0x000000000080, + Local = 0x000000000100, + NewOp = 0x000000000200, + StrongResolved = 0x000000000400, + RootSymbol = 0x000000000800, + Root = 0x000000001000, + CastOp = 0x000000002000, + IgnoreDuplicate = 0x000000004000, + RefOp = 0x000000008000, + NoPrimitives = 0x000000010000, + MssgLiteral = 0x000000020000, + MssgNameLiteral = 0x000000040000, + Extern = 0x000000080000, + Member = 0x000000100000, + ProbeMode = 0x000000200000, + AllowPrivateCall = 0x000000400000, + InitializerScope = 0x000000800000, + NestedDecl = 0x000001000000, + ConstantExpr = 0x000002000000, + Variadic = 0x000004000000, + WithVariadicArg = 0x000008000000, + RetrievingType = 0x000010000000, + RetValExpected = 0x000020000000, + CheckShortCircle = 0x000040000000, + LookaheadExprMode = 0x000080000000, + Class = 0x000100000000, + Nillable = 0x000200000000, + AllowGenericSignature= 0x000400000000, + OutRefOp = 0x001000000000, + WithVariadicArgCast = 0x002008000000, + DistributedForward = 0x004000000000, + DynamicObject = 0x008000000000, + Superior = 0x010000000000, + Lookahead = 0x020000000000, + NoDebugInfo = 0x040000000000, + NoExtension = 0x080000000000, + TryMode = 0x100000000000, }; struct ExpressionAttributes @@ -500,6 +504,7 @@ struct FieldAttributes bool overrideMode; bool autogenerated; bool privateOne; + bool isAuto; }; // --- CompilerBase --- diff --git a/elenasrc3/elc/cliconst.h b/elenasrc3/elc/cliconst.h index a03b045369..699fe8f92a 100644 --- a/elenasrc3/elc/cliconst.h +++ b/elenasrc3/elc/cliconst.h @@ -13,7 +13,7 @@ namespace elena_lang { - #define ELC_REVISION_NUMBER 0x0084 + #define ELC_REVISION_NUMBER 0x00A0 #if defined _M_IX86 || _M_X64 diff --git a/elenasrc3/elc/compiler.cpp b/elenasrc3/elc/compiler.cpp index b2a725ef2b..0bef008dde 100644 --- a/elenasrc3/elc/compiler.cpp +++ b/elenasrc3/elc/compiler.cpp @@ -58,6 +58,16 @@ MethodHint operator | (const ref_t& l, const MethodHint& r) // } //} +//inline void testNodes(BuildNode node) +//{ +// BuildNode current = node.firstChild(); +// while (current != BuildKey::None) { +// testNodes(current); +// +// current = current.nextNode(); +// } +//} + #ifdef FULL_OUTOUT_INFO inline void printTree(PresenterBase* presenter, SyntaxNode node) @@ -1204,6 +1214,26 @@ Compiler::ClassScope::ClassScope(Scope* ns, ref_t reference, Visibility visibili withStaticConstructor = false; } +bool Compiler::ClassScope :: resolveAutoType(ObjectInfo& targetInfo, TypeInfo typeInfo, int size, int extra) +{ + if (targetInfo.kind == ObjectKind::Field) { + for (auto it = info.fields.start(); !it.eof(); ++it) { + if ((*it).offset == (int)targetInfo.reference) { + if ((*it).typeInfo.typeRef == V_AUTO) { + (*it).typeInfo.typeRef = typeInfo.typeRef; + (*it).typeInfo.elementRef = typeInfo.elementRef; + + targetInfo.typeInfo = typeInfo; + + return true; + } + } + } + } + + return Scope::resolveAutoType(targetInfo, typeInfo, size, extra); +} + inline ObjectInfo mapClassInfoField(ClassInfo& info, ustr_t identifier, ExpressionAttribute attr, bool ignoreFields) { auto fieldInfo = info.fields.get(identifier); @@ -1486,7 +1516,7 @@ void Compiler::MethodScope::markAsAssigned(ObjectInfo object) // --- Compiler::CodeScope --- Compiler::CodeScope::CodeScope(MethodScope* parent) - : Scope(parent), locals({}), localNodes({}) + : Scope(parent), locals({}), localNodes({}), flowMode(CodeFlowMode::Normal) { allocated1 = reserved1 = 0; allocated2 = reserved2 = 0; @@ -1494,7 +1524,7 @@ Compiler::CodeScope::CodeScope(MethodScope* parent) } Compiler::CodeScope::CodeScope(CodeScope* parent) - : Scope(parent), locals({}), localNodes({}) + : Scope(parent), locals({}), localNodes({}), flowMode(CodeFlowMode::Normal) { reserved1 = allocated1 = parent->allocated1; reserved2 = allocated2 = parent->allocated2; @@ -1701,6 +1731,29 @@ void Compiler::ExprScope::syncStack() } } +void Compiler::ExprScope :: commitTempStack(int& prevAllocated1, int& prevAllocated2) +{ + CodeScope* codeScope = Scope::getScope(*this, Scope::ScopeLevel::Code); + if (codeScope != nullptr) { + prevAllocated1 = codeScope->allocated1; + prevAllocated2 = codeScope->allocated2; + + if (codeScope->reserved1 > codeScope->allocated1) + codeScope->allocated1 = codeScope->reserved1; + + if (codeScope->reserved2 > codeScope->allocated2) + codeScope->allocated2 = codeScope->reserved2; + } +} + +void Compiler::ExprScope :: freeTempStack(int prevAllocated1, int prevAllocated2) +{ + CodeScope* codeScope = Scope::getScope(*this, Scope::ScopeLevel::Code); + if (codeScope != nullptr) { + codeScope->allocated1 = prevAllocated1; + codeScope->allocated2 = prevAllocated2; + } +} // --- Compiler::InlineClassScope --- Compiler::InlineClassScope::InlineClassScope(ExprScope* owner, ref_t reference) @@ -1775,11 +1828,11 @@ Compiler::InlineClassScope::Outer Compiler::InlineClassScope::mapParent() ExprScope* exprScope = Scope::getScope(*parent, ScopeLevel::Expr); if (exprScope) { parentVar.outerObject = exprScope->mapSelf(); + + outers.add(PARENT_VAR, parentVar); + mapNewField(info.fields, PARENT_VAR, FieldInfo{ (int)parentVar.reference, parentVar.outerObject.typeInfo }); } else parentVar = mapOwner(); - - outers.add(PARENT_VAR, parentVar); - mapNewField(info.fields, PARENT_VAR, FieldInfo{ (int)parentVar.reference, parentVar.outerObject.typeInfo }); } return parentVar; @@ -1893,7 +1946,7 @@ bool Compiler::InlineClassScope::markAsPresaved(ObjectInfo object) // --- Compiler::StatemachineClassScope --- Compiler::StatemachineClassScope::StatemachineClassScope(ExprScope* owner, ref_t reference, bool asyncMode) - : InlineClassScope(owner, reference), contextSize(0), typeRef(0), resultRef(0), asyncMode(asyncMode) + : InlineClassScope(owner, reference), contextSize(0), typeRef(0), resultRef(0), asyncMode(asyncMode), localMappings(-1) { } @@ -3333,7 +3386,10 @@ bool Compiler::generateClassField(ClassScope& scope, FieldAttributes& attrs, ust return false; SizeInfo sizeInfo = {}; - if (typeInfo.isPrimitive()) { + if (typeInfo.typeRef == V_AUTO) { + + } + else if (typeInfo.isPrimitive()) { if (!sizeHint) { return false; } @@ -4042,6 +4098,7 @@ void Compiler :: declareIteratorMessage(MethodScope& scope, SyntaxNode node) scope.info.outputRef = scope.moduleScope->branchingInfo.typeRef; scope.info.hints |= (ref_t)MethodHint::Yieldable; + scope.nestedMode = true; } void Compiler :: declareMethod(MethodScope& methodScope, SyntaxNode node, bool abstractMode, @@ -5820,6 +5877,9 @@ void Compiler::declareFieldAttributes(ClassScope& scope, SyntaxNode node, FieldA if (attrs.typeInfo.isPrimitive()) { bool valid = true; switch (attrs.typeInfo.typeRef) { + case V_AUTO: + valid = !test(scope.info.header.flags, elStructure); + break; case V_INTBINARY: switch (attrs.size) { case 1: @@ -5997,23 +6057,29 @@ int Compiler::resolveArraySize(Scope& scope, SyntaxNode node) Interpreter interpreter(scope.moduleScope, _logic); ObjectInfo retVal = evalExpression(interpreter, scope, node); switch (retVal.kind) { - case ObjectKind::IntLiteral: - return retVal.extra; - break; - default: - scope.raiseError(errInvalidOperation, node); - return 0; + case ObjectKind::IntLiteral: + return retVal.extra; + break; + default: + scope.raiseError(errInvalidOperation, node); + return 0; } } -bool Compiler::declareYieldVariable(Scope& scope, ustr_t name, TypeInfo typeInfo) +void Compiler :: markYieldVariable(Scope& scope, ref_t localOffset) { - ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class); + StatemachineClassScope* smScope = Scope::getScope(scope, Scope::ScopeLevel::Statemachine); - FieldAttributes attrs = { typeInfo }; + IdentifierString tmpName("#"); + tmpName.appendHex(localOffset); - // NOTE : should return false to indicate that it is not a variable - return !generateClassField(*classScope, attrs, name, 0, typeInfo, false); + FieldAttributes attrs = { }; + bool valid = generateClassField(*smScope, attrs, *tmpName, 0, {}, false); + assert(valid); + + auto fieldInfo = smScope->mapField(*tmpName, ExpressionAttribute::None); + + smScope->localMappings.add(localOffset, fieldInfo.reference); } bool Compiler::declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeInfo, bool ignoreDuplicate) @@ -6038,12 +6104,12 @@ bool Compiler::declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeI if (ignoreDuplicate) { auto var = codeScope->mapIdentifier(*identifier, false, EAttr::None); switch (var.kind) { - case ObjectKind::Local: - case ObjectKind::LocalAddress: - // exit if the variable with this names does exist - return false; - default: - break; + case ObjectKind::Local: + case ObjectKind::LocalAddress: + // exit if the variable with this names does exist + return false; + default: + break; } } @@ -6089,11 +6155,13 @@ bool Compiler::declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeI else if (size != 0) { scope.raiseError(errInvalidOperation, terminal); } - else if (methodScope && methodScope->isYieldable()) { - // NOTE : yieildable method is a special case when the referece variable is declared as a special class field - return declareYieldVariable(scope, *identifier, typeInfo); + else { + variable.reference = codeScope->newLocal(); + if (methodScope && methodScope->isYieldable()) { + // NOTE : yieildable method is a special case when the referece variable is declared as a special class field + markYieldVariable(scope, variable.reference); + } } - else variable.reference = codeScope->newLocal(); if (exprScope) exprScope->syncStack(); @@ -6345,11 +6413,15 @@ ObjectInfo Compiler::mapClassSymbol(Scope& scope, ref_t classRef) retVal.typeInfo = { classClassRef }; + MethodScope* methodScope = Scope::getScope(scope, Scope::ScopeLevel::Method); ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class); if (classScope != nullptr && (classScope->reference == retVal.typeInfo.typeRef)) { retVal.kind = ObjectKind::ClassSelf; } + else if (methodScope != nullptr && methodScope->constructorMode && classClassRef == retVal.typeInfo.typeRef) { + retVal.kind = ObjectKind::ClassSelf; + } return retVal; } @@ -7015,6 +7087,15 @@ ObjectInfo Compiler::defineTerminalInfo(Scope& scope, SyntaxNode node, TypeInfo retVal = scope.mapIdentifier(node.identifier(), node.key == SyntaxKey::reference, attrs | ExpressionAttribute::Local); + if (retVal.kind == ObjectKind::Unknown) { + MethodScope* methodScope = Scope::getScope(scope, Scope::ScopeLevel::Method); + if (methodScope && methodScope->isYieldable()) { + // HOTFIX : it is a iterator method + retVal = scope.mapIdentifier(node.identifier(), node.key == SyntaxKey::reference, + attrs); + } + } + if (_trackingUnassigned && terminalAttrs.outRefOp) { scope.markAsAssigned(retVal); } @@ -7849,6 +7930,25 @@ ObjectInfo Compiler :: mapConstructorTarget(MethodScope& scope) return { ObjectKind::ConstructorSelf, classSymbol.typeInfo, scope.selfLocal, classSymbol.reference }; } +void Compiler :: injectLocalLoadingForYieldMethod(BuildTreeWriter& writer, ClassScope* classScope, CodeScope& codeScope) +{ + StatemachineClassScope* smScope = Scope::getScope(*classScope, Scope::ScopeLevel::Statemachine); + + BuildTree tmp; + BuildTreeWriter tmpWriter(tmp); + tmpWriter.newNode(BuildKey::Root); + + Expression expression(this, codeScope, tmpWriter); + for (auto local_it = smScope->localMappings.start(); !local_it.eof(); ++local_it) { + bool dummy = false; + expression.compileAssigningOp({ ObjectKind::Local, (ref_t)local_it.key() }, { ObjectKind::Field, (ref_t)*local_it }, dummy); + } + + tmpWriter.closeNode(); + + BuildTree::injectChildren(writer, tmp.readRoot()); +} + void Compiler :: compileMethodCode(BuildTreeWriter& writer, ClassScope* classScope, MethodScope& scope, CodeScope& codeScope, SyntaxNode node, bool newFrame) { @@ -7875,10 +7975,14 @@ void Compiler :: compileMethodCode(BuildTreeWriter& writer, ClassScope* classSco // reserve the place for the next step int offset = allocateLocalAddress(codeScope, sizeof(addr_t), false); + // mark the place to inject the local loading + writer.newBookmark(); + ObjectInfo contextField = smScope->mapContextField(); expression.writeObjectInfo(contextField); writer.appendNode(BuildKey::LoadingStackDump); + writer.appendNode(BuildKey::YieldDispatch, offset); } if (scope.isGeneric()) { @@ -7933,6 +8037,10 @@ void Compiler :: compileMethodCode(BuildTreeWriter& writer, ClassScope* classSco } if (scope.isYieldable()) { + // we have to inject the variable loading code here + injectLocalLoadingForYieldMethod(writer, classScope, codeScope); + writer.removeBookmark(); + Expression expression(this, codeScope, writer); expression.writeObjectInfo({ ObjectKind::Singleton, { scope.moduleScope->branchingInfo.typeRef }, scope.moduleScope->branchingInfo.falseRef }); @@ -8734,7 +8842,19 @@ ref_t Compiler :: declareAsyncStatemachine(StatemachineClassScope& scope, Syntax void Compiler :: compileAsyncMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node) { + // create a async method + beginMethod(writer, scope, node, BuildKey::Method, _withDebugInfo); + + // new stack frame + writer.appendNode(BuildKey::OpenFrame); + CodeScope codeScope(&scope); + + // stack should contains current self reference + // the original message should be restored if it is a generic method + scope.selfLocal = codeScope.newLocal(); + writer.appendNode(BuildKey::Assigning, scope.selfLocal); + Expression expression(this, codeScope, writer); // declare a state machine enumerator @@ -8746,21 +8866,9 @@ void Compiler :: compileAsyncMethod(BuildTreeWriter& writer, MethodScope& scope, while (buildNode != BuildKey::Root) buildNode = buildNode.parentNode(); - scope.selfLocal = codeScope.newLocal(); - BuildTreeWriter nestedWriter(buildNode); compileStatemachineClass(nestedWriter, smScope, node, baseRef); - // create a async method - beginMethod(writer, scope, node, BuildKey::Method, _withDebugInfo); - - // new stack frame - writer.appendNode(BuildKey::OpenFrame); - - // stack should contains current self reference - // the original message should be restored if it is a generic method - writer.appendNode(BuildKey::Assigning, scope.selfLocal); - // create a state machine enumerator int preservedContext = 0; expression.compileNestedInitializing(smScope, nestedRef, preservedContext, nullptr); @@ -8807,6 +8915,7 @@ void Compiler :: compileAsyncMethod(BuildTreeWriter& writer, MethodScope& scope, expression.compileConverting(node, retVal, scope.info.outputRef, scope.checkHint(MethodHint::Stacksafe)); + expression.scope.syncStack(); codeScope.syncStack(&scope); writer.appendNode(BuildKey::CloseFrame); @@ -8816,7 +8925,18 @@ void Compiler :: compileAsyncMethod(BuildTreeWriter& writer, MethodScope& scope, void Compiler :: compileYieldMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node) { + beginMethod(writer, scope, node, BuildKey::Method, _withDebugInfo); + + // new stack frame + writer.appendNode(BuildKey::OpenFrame); + CodeScope codeScope(&scope); + + // stack should contains current self reference + // the original message should be restored if it is a generic method + scope.selfLocal = codeScope.newLocal(); + writer.appendNode(BuildKey::Assigning, scope.selfLocal); + Expression expression(this, codeScope, writer); // create yield state machine @@ -8832,11 +8952,6 @@ void Compiler :: compileYieldMethod(BuildTreeWriter& writer, MethodScope& scope, compileStatemachineClass(nestedWriter, smScope, node, resolveStateMachine(scope, scope.moduleScope->buildins.yielditTemplateReference, smScope.typeRef)); - beginMethod(writer, scope, node, BuildKey::Method, _withDebugInfo); - - // new stack frame - writer.appendNode(BuildKey::OpenFrame); - ObjectInfo retVal = { ObjectKind::Object, { nestedRef }, 0 }; int preservedContext = 0; @@ -9748,8 +9863,7 @@ void Compiler :: compileNestedClass(BuildTreeWriter& writer, ClassScope& scope, bool withConstructors = false; bool withDefaultConstructor = false; - bool yieldMethodNotAllowed = true; - declareVMT(scope, node, withConstructors, withDefaultConstructor, yieldMethodNotAllowed, true, false); + declareVMT(scope, node, withConstructors, withDefaultConstructor, true, true, false); if (withConstructors) scope.raiseError(errIllegalConstructor, node); @@ -11109,9 +11223,8 @@ void Compiler::Class::declare(SyntaxNode node) bool withConstructors = false; bool withDefConstructor = false; - bool yieldMethodNotAllowed = !test(declaredFlags, elStateless); compiler->declareVMT(scope, node, withConstructors, withDefConstructor, - yieldMethodNotAllowed, false, test(declaredFlags, elTemplatebased)); + false, false, test(declaredFlags, elTemplatebased)); // NOTE : generateClassDeclaration should be called for the proper class before a class class one // due to dynamic array implementation (auto-generated default constructor should be removed) @@ -12216,9 +12329,17 @@ ObjectInfo Compiler::Expression :: compileAsyncOperation(SyntaxNode node, ref_t if (nillableOp) scope.raiseWarning(WARNING_LEVEL_1, wrnReturningNillable, node); + // saving local variables + for (auto local_it = smScope->localMappings.start(); !local_it.eof(); ++local_it) { + bool dummy = false; + compileAssigningOp({ ObjectKind::Field, (ref_t)*local_it }, { ObjectKind::Local, (ref_t)local_it.key() }, dummy); + } + writeObjectInfo(contextField, node); writer->appendNode(BuildKey::SavingStackDump); + writer->appendNode(BuildKey::ExcludeTry); // exclide the current try blocks before exiting an iteration method + // returning true writeObjectInfo({ ObjectKind::Singleton, { scope.moduleScope->branchingInfo.typeRef }, scope.moduleScope->branchingInfo.trueRef }); @@ -12227,6 +12348,8 @@ ObjectInfo Compiler::Expression :: compileAsyncOperation(SyntaxNode node, ref_t writer->closeNode(); writer->closeNode(); + writer->appendNode(BuildKey::IncludeTry); // include the current try blocks again + if (valueExpected) { // to ingnore the compatibility errors, replace Task with Task type, if applicable if (compiler->_logic->isCompatible(*scope.moduleScope, currentField.typeInfo, exprVal.typeInfo, false)) @@ -12246,6 +12369,9 @@ void Compiler::Expression :: compileYieldOperation(SyntaxNode node) if (!methodScope->isYieldable()) scope.raiseError(errInvalidOperation, node); + if (scope.checkFlowMode(CodeFlowMode::TryCatch)) + scope.raiseError(errIllegalOperation, node); + ObjectInfo contextField = smScope->mapContextField(); ObjectInfo currentField = smScope->mapCurrentField(); @@ -12264,6 +12390,12 @@ void Compiler::Expression :: compileYieldOperation(SyntaxNode node) writeObjectInfo(contextField, node); writer->appendNode(BuildKey::SavingStackDump); + // saving local variables + for (auto local_it = smScope->localMappings.start(); !local_it.eof(); ++local_it) { + bool dummy = false; + compileAssigningOp({ ObjectKind::Field, (ref_t)*local_it }, { ObjectKind::Local, (ref_t)local_it.key() }, dummy); + } + // returning true writeObjectInfo({ ObjectKind::Singleton, { scope.moduleScope->branchingInfo.typeRef }, scope.moduleScope->branchingInfo.trueRef }); @@ -12625,7 +12757,7 @@ ObjectInfo Compiler::Expression::compileCatchOperation(SyntaxNode node) writer->appendNode(BuildKey::Index, scope.newTempLocal()); writer->newNode(BuildKey::Tape); - compile(opNode, 0, EAttr::None, nullptr); + compile(opNode, 0, EAttr::TryMode, nullptr); writer->closeNode(); writer->newNode(BuildKey::Tape); @@ -12633,13 +12765,20 @@ ObjectInfo Compiler::Expression::compileCatchOperation(SyntaxNode node) catchNode.firstChild().firstChild(), false); writer->closeNode(); + scope.syncStack(); + if (finallyNode != SyntaxKey::None) { if (finallyNode.existChild(SyntaxKey::ClosureBlock)) finallyNode = finallyNode.findChild(SyntaxKey::ClosureBlock); + int prevAllocated1, prevAllocated2; + scope.commitTempStack(prevAllocated1, prevAllocated2); // HOTFIX : to prevent overwritting temporal variables + writer->newNode(BuildKey::Tape); compile(finallyNode, 0, EAttr::None, nullptr); writer->closeNode(); + + scope.freeTempStack(prevAllocated1, prevAllocated2); } writer->closeNode(); @@ -12662,9 +12801,15 @@ ObjectInfo Compiler::Expression::compileFinalOperation(SyntaxNode node) writer->appendNode(BuildKey::Index, index1); writer->newNode(BuildKey::Tape); - compile(opNode, 0, EAttr::None, nullptr); + compile(opNode, 0, EAttr::TryMode, nullptr); writer->closeNode(); + scope.syncStack(); + + int prevAllocated1, prevAllocated2; + if (finallyNode != SyntaxKey::None) + scope.commitTempStack(prevAllocated1, prevAllocated2); // HOTFIX : to prevent overwritting temporal variables + if (finallyNode.existChild(SyntaxKey::ClosureBlock)) finallyNode = finallyNode.findChild(SyntaxKey::ClosureBlock); @@ -12672,6 +12817,9 @@ ObjectInfo Compiler::Expression::compileFinalOperation(SyntaxNode node) compile(finallyNode, 0, EAttr::None, nullptr); writer->closeNode(); + if (finallyNode != SyntaxKey::None) + scope.freeTempStack(prevAllocated1, prevAllocated2); + writer->closeNode(); return {}; @@ -12684,35 +12832,35 @@ ObjectInfo Compiler::Expression::compileAltOperation(SyntaxNode node) ObjectInfo target = {}; SyntaxNode current = node.firstChild(); switch (current.key) { - case SyntaxKey::MessageOperation: - case SyntaxKey::PropertyOperation: - { - SyntaxNode objNode = current.firstChild(); + case SyntaxKey::MessageOperation: + case SyntaxKey::PropertyOperation: + { + SyntaxNode objNode = current.firstChild(); - target = compileObject(objNode, EAttr::Parameter, nullptr); + target = compileObject(objNode, EAttr::Parameter, nullptr); - writer->newNode(BuildKey::AltOp, ehLocal.argument); + writer->newNode(BuildKey::AltOp, ehLocal.argument); - writer->newNode(BuildKey::Tape); - compileMessageOperationR(target, objNode.nextNode(), current == SyntaxKey::PropertyOperation); - writer->closeNode(); - break; - } - case SyntaxKey::CodeBlock: - case SyntaxKey::Object: - { - writer->newNode(BuildKey::AltOp, ehLocal.argument); + writer->newNode(BuildKey::Tape); + compileMessageOperationR(target, objNode.nextNode(), current == SyntaxKey::PropertyOperation); + writer->closeNode(); + break; + } + case SyntaxKey::CodeBlock: + case SyntaxKey::Object: + { + writer->newNode(BuildKey::AltOp, ehLocal.argument); - writer->newNode(BuildKey::Tape); - compile(current, 0, EAttr::Parameter, nullptr); - writer->closeNode(); + writer->newNode(BuildKey::Tape); + compile(current, 0, EAttr::Parameter, nullptr); + writer->closeNode(); - target = { ObjectKind::Nil }; - break; - } - default: - scope.raiseError(errInvalidOperation, node); - break; + target = { ObjectKind::Nil }; + break; + } + default: + scope.raiseError(errInvalidOperation, node); + break; } writer->newNode(BuildKey::Tape); @@ -12878,17 +13026,38 @@ ObjectInfo Compiler::Expression::compileClosure(SyntaxNode node, ref_t targetRef return compileNested(helper.scope, mode, updatedOuterArgs); } +inline CodeFlowMode defineTryMode(SyntaxNode node) +{ + SyntaxNode parent = node.parentNode(); + while (parent != SyntaxKey::None) { + if (parent.key == SyntaxKey::CatchOperation || parent.key == SyntaxKey::FinalOperation) { + return CodeFlowMode::TryCatch; + } + else if (parent.key == SyntaxKey::AltOperation) { + return CodeFlowMode::TryCatch; + } + parent = parent.parentNode(); + } + + return CodeFlowMode::Normal; +} + ObjectInfo Compiler::Expression::compileSubCode(SyntaxNode node, ExpressionAttribute mode, bool withoutNewScope) { bool retValExpected = EAttrs::testAndExclude(mode, EAttr::RetValExpected); bool withoutDebugInfo = EAttrs::testAndExclude(mode, EAttr::NoDebugInfo); + bool tryMode = EAttrs::testAndExclude(mode, EAttr::TryMode); scope.syncStack(); CodeScope* parentCodeScope = Scope::getScope(scope, Scope::ScopeLevel::Code); ObjectInfo retVal = {}; - if (!withoutNewScope) { + if (!withoutNewScope || tryMode) { CodeScope codeScope(parentCodeScope); + if (tryMode) { + codeScope.flowMode = defineTryMode(node); + } + retVal = compiler->compileCode(*writer, codeScope, node, retValExpected, withoutDebugInfo); codeScope.syncStack(parentCodeScope); @@ -14485,7 +14654,7 @@ ObjectInfo Compiler::Expression::compileWeakOperation(SyntaxNode node, ref_t* ar retVal = tempRetVal; } else retVal = compileMessageCall(node, loperand, context, { context.weakMessage }, - messageArguments, EAttr::NoExtension, updatedOuterArgs); + messageArguments, EAttr::NoExtension | EAttr::CheckShortCircle, updatedOuterArgs); return retVal; } @@ -15451,7 +15620,7 @@ bool Compiler::Expression::resolveAutoType(ObjectInfo source, ObjectInfo& target int size = 0; int extra = 0; - if (compiler->_logic->isEmbeddableStruct(*scope.moduleScope, sourceInfo)) { + if (compiler->_logic->isEmbeddableStruct(*scope.moduleScope, sourceInfo) && target.kind == ObjectKind::Local) { // Bad luck : it is a auto structure, we have to reallocate the variable size = align(compiler->_logic->defineStructSize(*scope.moduleScope, sourceInfo.typeRef).size, scope.moduleScope->rawStackAlingment); diff --git a/elenasrc3/elc/compiler.h b/elenasrc3/elc/compiler.h index 099c59cfdf..b8c259abc0 100644 --- a/elenasrc3/elc/compiler.h +++ b/elenasrc3/elc/compiler.h @@ -135,6 +135,13 @@ namespace elena_lang Illegal = 2 }; + enum class CodeFlowMode + { + Normal = 0, + TryCatch = 1, + Alt = 2 + }; + struct ObjectInfo { ObjectKind kind; @@ -467,6 +474,14 @@ namespace elena_lang else return false; } + virtual bool checkFlowMode(CodeFlowMode mode) + { + if (parent) { + return parent->checkFlowMode(mode); + } + else return false; + } + template static T* getScope(Scope& scope, ScopeLevel level) { T* targetScope = (T*)scope.getScope(level); @@ -699,6 +714,8 @@ namespace elena_lang return test(info.header.flags, elAbstract); } + bool resolveAutoType(ObjectInfo& info, TypeInfo typeInfo, int size, int extra) override; + ObjectInfo mapMember(ustr_t identifier) override; virtual ObjectInfo mapField(ustr_t identifier, ExpressionAttribute attr); @@ -858,6 +875,11 @@ namespace elena_lang else return Scope::resolveAutoOutput(typeInfo); } + bool checkFlowMode(CodeFlowMode) override + { + return false; + } + MethodScope(ClassScope* classScope); }; @@ -874,6 +896,8 @@ namespace elena_lang bool withRetStatement; + CodeFlowMode flowMode; + Scope* getScope(ScopeLevel level) override { if (level == ScopeLevel::Code) { @@ -971,6 +995,14 @@ namespace elena_lang locals.add(local, Parameter(level, typeInfo, size, unassigned)); } + bool checkFlowMode(CodeFlowMode mode) override + { + if (flowMode == mode) { + return true; + } + else return Scope::checkFlowMode(mode); + } + void syncStack(MethodScope* methodScope); void syncStack(CodeScope* parentScope); @@ -1059,6 +1091,8 @@ namespace elena_lang } void syncStack(); + void commitTempStack(int& prevAllocated1, int& prevAllocated2); + void freeTempStack(int prevAllocated1, int prevAllocated2); ExprScope(SourceScope* parent); ExprScope(CodeScope* parent); @@ -1082,9 +1116,9 @@ namespace elena_lang ref_t expectedRef; - Outer mapParent(); - Outer mapOwner(); - Outer mapSelf(); + virtual Outer mapParent(); + virtual Outer mapOwner(); + virtual Outer mapSelf(); ObjectInfo mapMember(ustr_t identifier) override; @@ -1100,16 +1134,25 @@ namespace elena_lang bool markAsPresaved(ObjectInfo object); + bool checkFlowMode(CodeFlowMode) override + { + return false; + } + InlineClassScope(ExprScope* owner, ref_t reference); }; struct StatemachineClassScope : InlineClassScope { + typedef Map LocalFieldMapping; + pos_t contextSize; ref_t typeRef; ref_t resultRef; bool asyncMode; + LocalFieldMapping localMappings; + ObjectInfo mapContextField() { return { ObjectKind::Field }; @@ -1121,7 +1164,17 @@ namespace elena_lang if (level == ScopeLevel::Statemachine) { return this; } - else return Scope::getScope(level); + else return InlineClassScope::getScope(level); + } + + Outer mapParent() override + { + return mapSelf(); + } + + Outer mapOwner() override + { + return mapSelf(); } StatemachineClassScope(ExprScope* owner, ref_t reference, bool asyncMode); @@ -1636,6 +1689,8 @@ namespace elena_lang bool importPropertyTemplate(Scope& scope, SyntaxNode node, ustr_t postfix, SyntaxNode target); void importCode(Scope& scope, SyntaxNode node, SyntaxNode& importNode); + void injectLocalLoadingForYieldMethod(BuildTreeWriter& writer, ClassScope* classScope, CodeScope& codeScope); + void readFieldAttributes(ClassScope& scope, SyntaxNode node, FieldAttributes& attrs, bool declarationMode); static int allocateLocalAddress(Scope& scope, int size, bool binaryArray); @@ -1707,7 +1762,8 @@ namespace elena_lang void generateClassDeclaration(ClassScope& scope, SyntaxNode node, ref_t declaredFlags); bool declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeInfo, bool ignoreDuplicate); - bool declareYieldVariable(Scope& scope, ustr_t name, TypeInfo typeInfo); + + void markYieldVariable(Scope& scope, ref_t localOffset); void declareClassParent(ref_t parentRef, ClassScope& scope, SyntaxNode node); diff --git a/elenasrc3/elc/compilerlogic.cpp b/elenasrc3/elc/compilerlogic.cpp index 15831faf87..379ff83f64 100644 --- a/elenasrc3/elc/compilerlogic.cpp +++ b/elenasrc3/elc/compilerlogic.cpp @@ -920,6 +920,10 @@ bool CompilerLogic :: validateFieldAttribute(ref_t attribute, FieldAttributes& a case V_PRIVATE: attrs.privateOne = true; break; + case V_AUTO: + attrs.typeInfo = { V_AUTO }; + attrs.isAuto = true; + break; default: return false; } diff --git a/elenasrc3/elc/compiling.cpp b/elenasrc3/elc/compiling.cpp index 6c54df8c21..a5e09e3f31 100644 --- a/elenasrc3/elc/compiling.cpp +++ b/elenasrc3/elc/compiling.cpp @@ -234,6 +234,10 @@ ref_t CompilingProcess::TemplateGenerator :: generateTemplateName(ModuleScopeBas } name.replaceAll('\'', '@', 0); + // !! temporal + if ((*name).findStr("Task#1&system@Int") != NOTFOUND_POS) + alreadyDeclared |= false; + return moduleScope.mapTemplateIdentifier(*name, visibility, alreadyDeclared, false); } @@ -525,6 +529,8 @@ void CompilingProcess :: generateModule(ModuleScopeBase& moduleScope, BuildTree& // saving a module _presenter->print(ELC_SAVING_MODULE, moduleScope.module->name()); + moduleScope.flush(); + _libraryProvider.saveModule(moduleScope.module); _libraryProvider.saveDebugModule(moduleScope.debugModule); } @@ -818,6 +824,9 @@ int CompilingProcess :: build(Project& project, configurateParser(project.getSyntaxVersion()); configurate(project); + if (project.Namespace().empty()) + throw InternalError(errMissingNamespace); + PlatformType targetType = project.TargetType(); // Project Greetings diff --git a/elenasrc3/elc/errors.h b/elenasrc3/elc/errors.h index b88d6d21f4..92a3a5f39d 100644 --- a/elenasrc3/elc/errors.h +++ b/elenasrc3/elc/errors.h @@ -3,7 +3,7 @@ // // This file contains the ELENA Compiler error messages // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ERRORS_H @@ -117,6 +117,7 @@ namespace elena_lang constexpr auto errMsgFatalLinkerError = "\nFatal linker error\n"; constexpr auto errMsgNotImplemented = "\nNot implemented error\n"; constexpr auto errMsgCorruptedVMT = "\nVMT structure is corrupt\n"; + constexpr auto errMsgMissingNamespace = "\nInvalid project structure - missing namespace\n"; constexpr auto errMssgFailedMemoryAllocation = "\nnFatal error: cannot allocate the memory\n"; diff --git a/elenasrc3/elc/messages.h b/elenasrc3/elc/messages.h index b1623477a5..46ad4b85f2 100644 --- a/elenasrc3/elc/messages.h +++ b/elenasrc3/elc/messages.h @@ -10,7 +10,7 @@ namespace elena_lang { - constexpr auto MessageLength = 103; + constexpr auto MessageLength = 104; const Pair Messages[MessageLength] = { {errDuplicatedSymbol, errMsgDuplicatedSymbol}, @@ -115,6 +115,7 @@ namespace elena_lang {wrnAssigningNillable, wrnMssgAssigningNillable}, {wrnReturningNillable, wrnMssgReturningNillable}, {errFailedMemoryAllocation, errMssgFailedMemoryAllocation}, + {errMissingNamespace , errMsgMissingNamespace }, }; } diff --git a/elenasrc3/elc/modulescope.cpp b/elenasrc3/elc/modulescope.cpp index 124cde87b9..7b8d815e08 100644 --- a/elenasrc3/elc/modulescope.cpp +++ b/elenasrc3/elc/modulescope.cpp @@ -70,7 +70,8 @@ ref_t ModuleScope :: mapTemplateIdentifier(ustr_t templateName, Visibility visib IdentifierString forwardName(TEMPLATE_PREFIX_NS, templateName); if (!declarationMode) { - if (forwardResolver->resolveForward(templateName).empty()) { + ustr_t resolved = forwardResolver->resolveForward(templateName); + if (resolved.empty()) { ReferenceName fullName(module->name()); fullName.combine(templateName); @@ -80,7 +81,16 @@ ref_t ModuleScope :: mapTemplateIdentifier(ustr_t templateName, Visibility visib alreadyDeclared = false; } - else alreadyDeclared = true; + else { + alreadyDeclared = true; + if (!reusedTemplates.exist(templateName)) { + auto info = loader->retrieveReferenceInfo(resolved, forwardResolver); + if (info.module != module) { + // the reference to reused template must be saved as well + reusedTemplates.add(templateName, resolved.clone()); + } + } + } } return module->mapReference(*forwardName); @@ -377,9 +387,6 @@ bool ModuleScope :: includeNamespace(IdentifierList& importedNs, ustr_t name, bo if (value == nullptr) { importedNs.add(name.clone()); - if (sectionInfo.module != module) - saveListMember(IMPORTS_SECTION, sectionInfo.module->name()); - return true; } else duplicateInclusion = true; @@ -403,3 +410,18 @@ Visibility ModuleScope :: retrieveVisibility(ref_t reference) return CompilerLogic::getVisibility(referenceName); } + +void ModuleScope :: flush() +{ + MemoryBase* section = module->mapSection( + module->mapReference(TEMPLATE_MAPPING, false) | mskMetaInfo, + false); + + MemoryWriter metaWriter(section); + + reusedTemplates.forEach(&metaWriter, [](StreamWriter* writer, ustr_t key, ustr_t value) + { + writer->writeString(key); + writer->writeString(value); + }); +} diff --git a/elenasrc3/elc/modulescope.h b/elenasrc3/elc/modulescope.h index 06692bdcfe..fedea357ec 100644 --- a/elenasrc3/elc/modulescope.h +++ b/elenasrc3/elc/modulescope.h @@ -3,7 +3,7 @@ // // This file contains Module scope class declaration. // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef MODULESCOPE_H @@ -22,6 +22,8 @@ class ModuleScope : public ModuleScopeBase LibraryLoaderBase* loader; ForwardResolverBase* forwardResolver; + Forwards reusedTemplates; + void saveListMember(ustr_t name, ustr_t memberName); public: @@ -80,6 +82,8 @@ class ModuleScope : public ModuleScopeBase Visibility retrieveVisibility(ref_t reference) override; + void flush() override; + ModuleScope(LibraryLoaderBase* loader, ForwardResolverBase* forwardResolver, ModuleBase* module, @@ -91,7 +95,7 @@ class ModuleScope : public ModuleScopeBase int ptrSize, int moduleHint) : ModuleScopeBase(module, debugModule, stackAlingment, rawStackAlingment, ehTableEntrySize, - minimalArgList, ptrSize, false) + minimalArgList, ptrSize, false), reusedTemplates(nullptr) { this->loader = loader; this->forwardResolver = forwardResolver; diff --git a/elenasrc3/elc/project.cpp b/elenasrc3/elc/project.cpp index 119fe863ee..8af43d90e9 100644 --- a/elenasrc3/elc/project.cpp +++ b/elenasrc3/elc/project.cpp @@ -153,6 +153,7 @@ void Project :: loadSourceFiles(ConfigFile& config, ConfigFile::Node& configRoot ConfigFile::Collection modules; if (config.select(configRoot, MODULE_CATEGORY, modules)) { for (auto m_it = modules.start(); !m_it.eof(); ++m_it) { + ConfigFile::Node moduleNode = *m_it; if (!moduleNode.readAttribute("name", subNs)) { @@ -497,6 +498,18 @@ void Project :: loadProfileList(ConfigFile& config) // --- ProjectCollection --- +inline void loadModuleCollection(path_t collectionPath, ConfigFile::Collection& modules, XmlProjectBase::Paths& paths) +{ + DynamicString pathStr; + for (auto it = modules.start(); !it.eof(); ++it) { + ConfigFile::Node node = *it; + node.readContent(pathStr); + + PathString fullPath(collectionPath, pathStr.str()); + paths.add((*fullPath).clone()); + } +} + bool ProjectCollection :: load(path_t path) { PathString collectionPath; @@ -504,18 +517,22 @@ bool ProjectCollection :: load(path_t path) ConfigFile config; if (config.load(path, _encoding)) { - DynamicString pathStr; - ConfigFile::Collection modules; if (config.select(COLLECTION_CATEGORY, modules)) { - for (auto it = modules.start(); !it.eof(); ++it) { - ConfigFile::Node node = *it; - node.readContent(pathStr); - - PathString fullPath(*collectionPath, pathStr.str()); - paths.add((*fullPath).clone()); + loadModuleCollection(*collectionPath, modules, paths); + } + else { + ConfigFile::Collection collections; + if (config.select(COLLECTIONS_CATEGORY, collections)) { + for (auto it = collections.start(); !it.eof(); ++it) { + ConfigFile::Collection subModules; + if (config.select(*it, "*", subModules)) { + loadModuleCollection(*collectionPath, subModules, paths); + } + } } } + return true; } return false; diff --git a/elenasrc3/elc/source.cpp b/elenasrc3/elc/source.cpp index 53ef8d3b45..71a45053f7 100644 --- a/elenasrc3/elc/source.cpp +++ b/elenasrc3/elc/source.cpp @@ -3,7 +3,7 @@ // // This file contains ELENA Source Reader class implementation. // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -12,7 +12,7 @@ using namespace elena_lang; -const char* source_dfa[40] = +const char* source_dfa[42] = { ".????????BB??B??????????????????BdFIRCDLQQDbDVQHEEEEEEEEEEDDDDYc`CCCCCCCCCCCCCCCCCCCCCCCCCCDeQDC?CCCCCCCCCCCCCCCCCCCCCCCCCCDDDDC", "*********BB*********************B***********************************************************************************************", @@ -34,7 +34,7 @@ const char* source_dfa[40] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAAAAAAAAAAAASSSSSSSSSSAAAAAAARRRRRRRRRRRRRRRRRRRRRRRRRRAAAAAARRRRRRRRRRRRRRRRRRRRRRRRRRAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFATAAAAAAAAAAASSSSSSSSSSAAAAAAASSSSSSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAA", "????????????????????????????????????????????????UUUUUUUUUU??????????????????????????????????????????????????????????????????????", - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAGAAAAAAAAAAAUUUUUUUUUUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFATAAAAAAAAAAAUUUUUUUUUUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "---------------------------------------------Q---------------Q------------------------------------------------------------------", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!EEEEEEEEEE!!!D!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", @@ -53,7 +53,9 @@ const char* source_dfa[40] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "ffffffffffffffffffffffffffffffffffhffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffgffff", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAAA", - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "????????????????????????????????????????????????jjjjjjjjjj??????????????????????????????????????????????????????????????????????", + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAiAAAAAAAAAAAjjjjjjjjjjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" }; // --- SourceReader --- @@ -90,39 +92,57 @@ ustr_t SourceReader :: copyQuote(char* token, size_t length, List& dynamicStrings) +ustr_t SourceReader :: copyInterpolQuote(char* token, size_t length, bool nextInterpolToken, List& dynamicStrings) { pos_t start = _startPosition; - if (_line[start] == '$' || _line[start] == '{') + + bool startingWithChar = false; + if (nextInterpolToken && _line[start] == '"' && _line[start + 1] == '$') { + startingWithChar = true; + start++; + } + else if (_line[start] == '$' || _line[start] == '{') start++; size_t tokenLen = _position - start; - if (_line[start] != '"') + if (_line[start] != '"' && !startingWithChar) tokenLen++; if (tokenLen > length) { char* str = StrFactory::allocate(tokenLen + 1, DEFAULT_STR); - ::copyInterpolQuote(str, _line, start, tokenLen); + ::copyInterpolQuote(str, _line, start, tokenLen, startingWithChar); dynamicStrings.add(str); return str; } - else return ::copyInterpolQuote(token, _line, start, tokenLen); + else return ::copyInterpolQuote(token, _line, start, tokenLen, startingWithChar); } SourceInfo SourceReader :: read(char* line, size_t length, List& dynamicStrings) @@ -154,18 +174,19 @@ SourceInfo SourceReader :: read(char* line, size_t length, List& case dfaCharacter: info.symbol = copyQuote(line, length, dynamicStrings); break; - case dfaAltQuote:; - _startState = dfaStart; - - info.symbol = copyInterpolQuote(line, length, dynamicStrings); + case dfaAltQuote2: + case dfaAltQuote: + info.symbol = copyInterpolQuote(line, length, _startState == dfaNextInterpol, dynamicStrings); info.state = dfaStartInterpol; + + _startState = dfaStart; break; case dfaStartInterpol: _interpolating = true; - _bracketLevel = 1; - _startState = dfaStart; + _bracketLevel = 1; + info.symbol = copyInterpolQuote(line, length, _startState == dfaNextInterpol, dynamicStrings); - info.symbol = copyInterpolQuote(line, length, dynamicStrings); + _startState = dfaStart; break; default: info.symbol = copyToken(line, length); diff --git a/elenasrc3/elc/source.h b/elenasrc3/elc/source.h index d0d766e5ab..6836a8dd7b 100644 --- a/elenasrc3/elc/source.h +++ b/elenasrc3/elc/source.h @@ -3,7 +3,7 @@ // // This header contains ELENA Source Reader class declaration. // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef SOURCE_H @@ -40,7 +40,7 @@ namespace elena_lang ustr_t copyToken(char* token, size_t length); ustr_t copyQuote(char* token, size_t length, List& dynamicStrings); - ustr_t copyInterpolQuote(char* token, size_t length, List& dynamicStrings); + ustr_t copyInterpolQuote(char* token, size_t length, bool nextInterpolToken, List& dynamicStrings); bool IsOperator(char state) { diff --git a/elenasrc3/elc/windows/elc.cpp b/elenasrc3/elc/windows/elc.cpp index 90c4aa2ff1..d1240207bc 100644 --- a/elenasrc3/elc/windows/elc.cpp +++ b/elenasrc3/elc/windows/elc.cpp @@ -6,6 +6,8 @@ // (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- +//#define TIME_RECORDING 1 + #include #include "elena.h" @@ -27,6 +29,8 @@ #include "constants.h" #include "windows/presenter.h" +#include + using namespace elena_lang; #ifdef _M_IX86 @@ -257,15 +261,30 @@ int main() int argc; wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc); +#ifdef TIME_RECORDING + clock_t start, finish; + start = clock(); +#endif + + int retVal = 0; if (argc < 2) { Presenter::getInstance().printLine(ELC_HELP_INFO); return -2; } else if (argv[argc - 1][0] != '-' && PathUtil::checkExtension(argv[argc - 1], "prjcol")) { - return compileProjectCollection(argc, argv, argv[argc - 1], + retVal = compileProjectCollection(argc, argv, argv[argc - 1], *appPath, errorProcessor, process); } - else return compileProject(argc, argv, *appPath, errorProcessor, process); + else retVal = compileProject(argc, argv, *appPath, errorProcessor, process); + +#ifdef TIME_RECORDING + finish = clock(); + + double duration = (double)(finish - start) / CLOCKS_PER_SEC; + printf("The compilation took %2.3f seconds\n", duration); +#endif + + return retVal; } catch (CLIException) { diff --git a/elenasrc3/elena-tests/tests_common.h b/elenasrc3/elena-tests/tests_common.h index f52d54f144..7b1facf0f1 100644 --- a/elenasrc3/elena-tests/tests_common.h +++ b/elenasrc3/elena-tests/tests_common.h @@ -139,6 +139,10 @@ namespace elena_lang Visibility retrieveVisibility(ref_t reference) override; + void flush() override + { + } + TestModuleScope(bool tapeOptMode); }; diff --git a/elenasrc3/elenart/rtcommon.h b/elenasrc3/elenart/rtcommon.h index d258a76808..171503ebbc 100644 --- a/elenasrc3/elenart/rtcommon.h +++ b/elenasrc3/elenart/rtcommon.h @@ -3,7 +3,7 @@ // // This file contains the compiler common interfaces & types // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef RTCOMMON_H @@ -14,7 +14,7 @@ namespace elena_lang { -#define ELENART_REVISION_NUMBER 0x000A +#define ELENART_REVISION_NUMBER 0x000B } diff --git a/elenasrc3/elenasm/regex.h b/elenasrc3/elenasm/regex.h index 3c2ed37efd..3bae314181 100644 --- a/elenasrc3/elenasm/regex.h +++ b/elenasrc3/elenasm/regex.h @@ -394,6 +394,8 @@ namespace elena_lang if (state == dfaQuote) { return RegEx::isMatched(token, state); } + + return false; } void saveTo(ScriptEngineReaderBase& scriptReader, ScriptEngineCFParser* parser, ref_t ptr, ScriptEngineLog& log) override; diff --git a/elenasrc3/elenasrc3.sln b/elenasrc3/elenasrc3.sln index 8914e77f06..beee2c961e 100644 --- a/elenasrc3/elenasrc3.sln +++ b/elenasrc3/elenasrc3.sln @@ -34,8 +34,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "elt", "tools\elt\vs\elt.vcx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "elena-tests", "elena-tests\elena-tests.vcxproj", "{89A68A7E-1CB6-45CB-9B02-8183FF59284A}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ldbg", "ldbg\vs\ldbg.vcxproj", "{60FE12CF-0DA9-4266-9C0F-F544DB115020}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 diff --git a/elenasrc3/elenavm/windows/dllmain.cpp b/elenasrc3/elenavm/windows/dllmain.cpp index 7521a22109..e843ee58f0 100644 --- a/elenasrc3/elenavm/windows/dllmain.cpp +++ b/elenasrc3/elenavm/windows/dllmain.cpp @@ -115,6 +115,9 @@ void printError(int errCode) case errFailedMemoryAllocation: printf("ELENAVM: cannot reserve the memory"); break; + case errCommandSetAbsent: + printf("ELENAVM: cannot initialize core"); + break; default: printf("ELENAVM: Unknown error %d\n", errCode); break; diff --git a/elenasrc3/engine/bcwriter.cpp b/elenasrc3/engine/bcwriter.cpp index d68af81b9c..9a595170a2 100644 --- a/elenasrc3/engine/bcwriter.cpp +++ b/elenasrc3/engine/bcwriter.cpp @@ -3,7 +3,7 @@ // // This file contains ELENA byte code compiler class implementation. // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -3071,51 +3071,70 @@ void ByteCodeWriter :: saveLoop(CommandTape& tape, BuildNode node, TapeScope& ta tape.releaseLabel(); } -void ByteCodeWriter :: saveCatching(CommandTape& tape, BuildNode node, TapeScope& tapeScope, - ReferenceMap& paths, bool tapeOptMode) +void ByteCodeWriter :: openTryBlock(CommandTape& tape, TryContextInfo& tryInfo, bool virtualMode) { - int retLabel = tape.newLabel(); // declare ret-end-label - tape.newLabel(); // declare end-label - tape.newLabel(); // declare alternative-label + if (!virtualMode) { + tryInfo.retLabel = tape.newLabel(); // declare ret-end-label + tryInfo.endLabel = tape.newLabel(); // declare end-label + tryInfo.altLabel = tape.newLabel(); // declare alternative-label + } + else { + tryInfo.retLabel = tape.renewLabel(tryInfo.retLabel); // declare ret-end-label + tryInfo.endLabel = tape.renewLabel(tryInfo.endLabel); // declare end-label + tryInfo.altLabel = tape.renewLabel(tryInfo.altLabel); // declare alternative-label + } - tape.write(ByteCode::XHookDPR, node.arg.value, PseudoArg::CurrentLabel, mskLabelRef); + tape.write(ByteCode::XHookDPR, tryInfo.ptr, tryInfo.altLabel, mskLabelRef); - retLabel = tape.exchangeFirstsLabel(retLabel); + tryInfo.retLabel = tape.exchangeFirstsLabel(tryInfo.retLabel); +} - BuildNode tryNode = node.findChild(BuildKey::Tape); - BuildNode catchNode = tryNode.nextNode(BuildKey::Tape); - BuildNode finallyNode = catchNode.nextNode(BuildKey::Tape); - BuildNode index = node.findChild(BuildKey::Index); - saveTape(tape, tryNode, tapeScope, paths, tapeOptMode, false); +// NOTE : closing is true for the actual try-catch end, and false - for try_exclude +void ByteCodeWriter :: closeTryBlock(CommandTape& tape, TryContextInfo& tryInfo, bool virtualMode, + TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode) +{ + BuildNode finallyNode = tryInfo.catchMode ? tryInfo.catchNode.nextNode(BuildKey::Tape) : tryInfo.catchNode; // unhook tape.write(ByteCode::Unhook); + if (!tryInfo.catchMode) { + // for try-finally statement, the finnaly code must be called here + if (!virtualMode && finallyNode != BuildKey::None) { + tape.write(ByteCode::StoreFI, tryInfo.index); + saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); + tape.write(ByteCode::PeekFI, tryInfo.index); + } + } + // jump - tape.write(ByteCode::Jump, PseudoArg::PreviousLabel); + tape.write(ByteCode::Jump, tryInfo.endLabel); // === exit redirect block === // restore the original ret label and return the overridden one - retLabel = tape.exchangeFirstsLabel(retLabel); + tryInfo.retLabel = tape.exchangeFirstsLabel(tryInfo.retLabel); // ret-end-label: - tape.setPredefinedLabel(retLabel); + tape.setPredefinedLabel(tryInfo.retLabel); // unhook tape.write(ByteCode::Unhook); // finally-block - if (finallyNode != BuildKey::None) { - tape.write(ByteCode::StoreFI, index.arg.value); + if (finallyNode != BuildKey::None) { + tape.write(ByteCode::StoreFI, tryInfo.index); saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); - tape.write(ByteCode::PeekFI, index.arg.value); + tape.write(ByteCode::PeekFI, tryInfo.index); } tape.write(ByteCode::Jump, PseudoArg::FirstLabel); // =========================== // catchLabel: - tape.setLabel(); + if (virtualMode) { + tape.setPredefinedLabel(tryInfo.altLabel); + } + else tape.setLabel(); // tstflg elMessage // jeq labSkip @@ -3133,106 +3152,143 @@ void ByteCodeWriter :: saveCatching(CommandTape& tape, BuildNode node, TapeScope tape.setLabel(); tape.write(ByteCode::Unhook); - saveTape(tape, catchNode, tapeScope, paths, tapeOptMode, false); + if (tryInfo.catchMode) { + saveTape(tape, tryInfo.catchNode, tapeScope, paths, tapeOptMode, false); - // eos: - tape.setLabel(); - tape.releaseLabel(); // release ret-end-label + // eos: + if (virtualMode) { + tape.setPredefinedLabel(tryInfo.endLabel); + } + else { + tape.setLabel(); + tape.releaseLabel(); // release ret-end-label + } - // finally-block - if (finallyNode != BuildKey::None) { - tape.write(ByteCode::StoreFI, index.arg.value); - saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); - tape.write(ByteCode::PeekFI, index.arg.value); + // finally-block + if (finallyNode != BuildKey::None) { + tape.write(ByteCode::StoreFI, tryInfo.index); + saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); + tape.write(ByteCode::PeekFI, tryInfo.index); + } + + if (virtualMode) + tape.write(ByteCode::Jump, PseudoArg::FirstLabel); + } + else { + // finally-block + if (finallyNode != BuildKey::None) { + // store fp:index + // + // peek fp:index + + tape.write(ByteCode::StoreFI, tryInfo.index); + saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); + tape.write(ByteCode::PeekFI, tryInfo.index); + } + + // throw + tape.write(ByteCode::Throw); + + // eos: + if (virtualMode) { + tape.setPredefinedLabel(tryInfo.endLabel); + } + else { + tape.setLabel(); + tape.releaseLabel(); // release ret-end-label + } } } -void ByteCodeWriter :: saveFinally(CommandTape& tape, BuildNode node, TapeScope& tapeScope, - ReferenceMap& paths, bool tapeOptMode) +void ByteCodeWriter::includeTryBlocks(CommandTape& tape, TapeScope& tapeScope) { - int retLabel = tape.newLabel(); // declare ret-end-label - tape.newLabel(); // declare end-label - tape.newLabel(); // declare alternative-label + if (tapeScope.tryContexts.count() == 1) { + auto info = tapeScope.tryContexts.pop(); - tape.write(ByteCode::XHookDPR, node.arg.value, PseudoArg::CurrentLabel, mskLabelRef); + openTryBlock(tape, info, true); - retLabel = tape.exchangeFirstsLabel(retLabel); + tapeScope.tryContexts.push(info); + } + else if (tapeScope.tryContexts.count() > 1) { + TryContexts temp({ }); + while (tapeScope.tryContexts.count() > 0) { + temp.push(tapeScope.tryContexts.pop()); + } + while (temp.count() > 0) { + auto info = temp.pop(); - BuildNode tryNode = node.findChild(BuildKey::Tape); - BuildNode finallyNode = tryNode.nextNode(BuildKey::Tape); - BuildNode index = node.findChild(BuildKey::Index); + openTryBlock(tape, info, true); - saveTape(tape, tryNode, tapeScope, paths, tapeOptMode, false); + tapeScope.tryContexts.push(info); + } + } +} - // unhook - tape.write(ByteCode::Unhook); +void ByteCodeWriter :: excludeTryBlocks(CommandTape& tape, + TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode) +{ + if (tapeScope.tryContexts.count() == 1) { + auto info = tapeScope.tryContexts.pop(); - if (finallyNode != BuildKey::None) { - tape.write(ByteCode::StoreFI, index.arg.value); - saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); - tape.write(ByteCode::PeekFI, index.arg.value); + closeTryBlock(tape, info, true, tapeScope, paths, tapeOptMode); + + tapeScope.tryContexts.push(info); } + else if (tapeScope.tryContexts.count() > 1) { + TryContexts temp({}); + while (temp.count() > 0) { + auto info = tapeScope.tryContexts.pop(); - // jump - tape.write(ByteCode::Jump, PseudoArg::PreviousLabel); + closeTryBlock(tape, info, true, tapeScope, paths, tapeOptMode); - // === exit redirect block === - // restore the original ret label and return the overridden one - retLabel = tape.exchangeFirstsLabel(retLabel); + temp.push(info); + } + while (temp.count() > 0) { + tapeScope.tryContexts.push(temp.pop()); + } + } +} - // ret-end-label: - tape.setPredefinedLabel(retLabel); +void ByteCodeWriter :: saveCatching(CommandTape& tape, BuildNode node, TapeScope& tapeScope, + ReferenceMap& paths, bool tapeOptMode) +{ + BuildNode tryNode = node.findChild(BuildKey::Tape); - // unhook - tape.write(ByteCode::Unhook); + TryContextInfo blockInfo = { true }; + blockInfo.catchNode = tryNode.nextNode(BuildKey::Tape); + blockInfo.index = node.findChild(BuildKey::Index).arg.value; + blockInfo.ptr = node.arg.value; - // finally-block - if (finallyNode != BuildKey::None) { - tape.write(ByteCode::StoreFI, index.arg.value); - saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); - tape.write(ByteCode::PeekFI, index.arg.value); - } + openTryBlock(tape, blockInfo, false); - tape.write(ByteCode::Jump, PseudoArg::FirstLabel); - // =========================== + tapeScope.tryContexts.push(blockInfo); - // catchLabel: - tape.setLabel(); + saveTape(tape, tryNode, tapeScope, paths, tapeOptMode, false); - // tstflg elMessage - // jeq labSkip - // load - // peeksi 0 - // callvi 0 - // labSkip: - // unhook + blockInfo = tapeScope.tryContexts.pop(); - tape.newLabel(); - tape.write(ByteCode::TstFlag, elMessage); - tape.write(ByteCode::Jeq, PseudoArg::CurrentLabel); - tape.write(ByteCode::Load); - tape.write(ByteCode::PeekSI); - tape.write(ByteCode::CallVI); - tape.setLabel(); - tape.write(ByteCode::Unhook); + closeTryBlock(tape, blockInfo, false, tapeScope, paths, tapeOptMode); +} - // finally-block - if (finallyNode != BuildKey::None) { - // store fp:index - // - // peek fp:index +void ByteCodeWriter :: saveFinally(CommandTape& tape, BuildNode node, TapeScope& tapeScope, + ReferenceMap& paths, bool tapeOptMode) +{ + BuildNode tryNode = node.findChild(BuildKey::Tape); - tape.write(ByteCode::StoreFI, index.arg.value); - saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); - tape.write(ByteCode::PeekFI, index.arg.value); - } + TryContextInfo blockInfo = { false }; + blockInfo.catchNode = tryNode.nextNode(BuildKey::Tape); + blockInfo.index = node.findChild(BuildKey::Index).arg.value; + blockInfo.ptr = node.arg.value; - // throw - tape.write(ByteCode::Throw); + openTryBlock(tape, blockInfo, false); - // eos: - tape.setLabel(); - tape.releaseLabel(); // release ret-end-label + tapeScope.tryContexts.push(blockInfo); + + saveTape(tape, tryNode, tapeScope, paths, tapeOptMode, false); + + blockInfo = tapeScope.tryContexts.pop(); + + closeTryBlock(tape, blockInfo, false, tapeScope, paths, tapeOptMode); } void ByteCodeWriter :: saveSwitchOption(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode) @@ -3574,6 +3630,12 @@ void ByteCodeWriter :: saveTape(CommandTape& tape, BuildNode node, TapeScope& ta case BuildKey::TernaryOp: saveTernaryOp(tape, current, tapeScope, paths, tapeOptMode); break; + case BuildKey::ExcludeTry: + excludeTryBlocks(tape, tapeScope, paths, tapeOptMode); + break; + case BuildKey::IncludeTry: + includeTryBlocks(tape, tapeScope); + break; case BuildKey::Path: case BuildKey::InplaceCall: // ignore special nodes diff --git a/elenasrc3/engine/bcwriter.h b/elenasrc3/engine/bcwriter.h index 8f82dc0767..f60ce269e6 100644 --- a/elenasrc3/engine/bcwriter.h +++ b/elenasrc3/engine/bcwriter.h @@ -3,7 +3,7 @@ // // This file contains ELENA byte code writer class. // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef BCWRITER_H @@ -18,6 +18,28 @@ namespace elena_lang class ByteCodeWriter { public: + struct TryContextInfo + { + bool catchMode; + int index; + int retLabel; + int endLabel; + int altLabel; + ref_t ptr; + BuildNode catchNode; + + TryContextInfo() + : TryContextInfo(false) + { + + } + TryContextInfo(bool catchMode) + : catchMode(catchMode), index(0), retLabel(0), endLabel(0), altLabel(0), ptr(0) + { + + } + }; + struct Scope { MemoryWriter* vmt; @@ -34,6 +56,7 @@ namespace elena_lang typedef Stack> LoopLabels; typedef CachedList IndexedMessages; + typedef Stack TryContexts; struct TapeScope { @@ -46,9 +69,11 @@ namespace elena_lang bool threadFriendly; LoopLabels loopLabels; + TryContexts tryContexts; TapeScope(Scope* scope, int reserved, int reservedN, bool classMode, bool threadFriendly) - : scope(scope), reserved(reserved), reservedN(reservedN), classMode(classMode), threadFriendly(threadFriendly), loopLabels({}) + : scope(scope), reserved(reserved), reservedN(reservedN), classMode(classMode), + threadFriendly(threadFriendly), loopLabels({}), tryContexts({}) { } @@ -91,6 +116,14 @@ namespace elena_lang void importTree(CommandTape& tape, BuildNode node, Scope& scope); + void openTryBlock(CommandTape& tape, TryContextInfo& tryInfo, bool virtualMode); + void closeTryBlock(CommandTape& tape, TryContextInfo& tryInfo, bool virtualMode, + TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode); + + void includeTryBlocks(CommandTape& tape, TapeScope& tapeScope); + void excludeTryBlocks(CommandTape& tape, + TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode); + void saveTape(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode, bool loopMode = false); void saveBranching(CommandTape& tape, BuildNode node, TapeScope& tapeScope, diff --git a/elenasrc3/engine/buildtree.h b/elenasrc3/engine/buildtree.h index 41a89c0388..c6f4ad6ab1 100644 --- a/elenasrc3/engine/buildtree.h +++ b/elenasrc3/engine/buildtree.h @@ -3,7 +3,7 @@ // // This file contains ELENA Engine Byte code Build Tree classes // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef BUILDTREE_H @@ -190,6 +190,8 @@ namespace elena_lang YieldDispatch = 0x00A4, TernaryOp = 0x00A5, NilRefBranchOp = 0x00A6, + ExcludeTry = 0x00A7, + IncludeTry = 0x00A8, VariableInfo = 0x00B0, Variable = 0x00B1, @@ -324,6 +326,23 @@ namespace elena_lang writer.closeNode(); } + static void injectChildren(Tree::Writer& writer, Tree::Node node) + { + auto current = node.firstChild(); + while (current != BuildKey::None) { + if (current.arg.strArgPosition != INVALID_POS) { + writer.inject(current.key, current.identifier()); + } + else writer.inject(current.key, current.arg.reference); + + copyNode(writer, current); + + writer.closeNode(); + + current = current.nextNode(); + } + } + static void loadBuildKeyMap(BuildKeyMap& map) { map.add("breakpoint", BuildKey::Breakpoint); diff --git a/elenasrc3/engine/bytecode.cpp b/elenasrc3/engine/bytecode.cpp index 363c82bcfd..9dbae48500 100644 --- a/elenasrc3/engine/bytecode.cpp +++ b/elenasrc3/engine/bytecode.cpp @@ -3,7 +3,7 @@ // // This file contains common ELENA byte code classes and constants // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //------------------------------------------------------------------------------ #include "bytecode.h" @@ -678,6 +678,11 @@ void CommandTape::write(ByteCode code, arg_t arg1, PseudoArg arg2, ref_t mask) write(code, arg1, resolvePseudoArg(arg2) | mask); } +void CommandTape :: write(ByteCode code, arg_t arg1, int arg2, ref_t mask) +{ + write(code, arg1, arg2 | mask); +} + void CommandTape :: write(ByteCode code, arg_t arg1, arg_t arg2) { ByteCommand command(code, arg1, arg2); diff --git a/elenasrc3/engine/bytecode.h b/elenasrc3/engine/bytecode.h index 44c57a04f1..c4fb0a395d 100644 --- a/elenasrc3/engine/bytecode.h +++ b/elenasrc3/engine/bytecode.h @@ -306,6 +306,20 @@ namespace elena_lang return labelSeed; } + int renewLabel(int oldLabel) + { + labelSeed++; + + for (auto it = labels.start(); !it.eof(); ++it) { + if (*it == oldLabel) { + *it = labelSeed; + break; + } + } + + return labelSeed; + } + void setLabel(bool persist = false) { if (persist) { @@ -341,6 +355,7 @@ namespace elena_lang void write(ByteCode code, PseudoArg arg); void write(ByteCode code, arg_t arg1, PseudoArg arg2); void write(ByteCode code, arg_t arg1, PseudoArg arg2, ref_t mask); + void write(ByteCode code, arg_t arg1, int arg2, ref_t mask); void import(ModuleBase* sourceModule, MemoryBase* source, bool withHeader, ModuleBase * targetModule); diff --git a/elenasrc3/engine/elena.h b/elenasrc3/engine/elena.h index 46c054b90e..164390a195 100644 --- a/elenasrc3/engine/elena.h +++ b/elenasrc3/engine/elena.h @@ -3,7 +3,7 @@ // // This file contains the common ELENA Compiler Engine templates, // classes, structures, functions and constants -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ELENA_H @@ -121,15 +121,16 @@ namespace elena_lang typedef Pair ExtensionInfo; // --- Maps --- - typedef Map ReferenceMap; - typedef Map ActionMap; - typedef Map AddressMap; - typedef Map ExtensionMap; - typedef Map ExtensionTemplateMap; - typedef Map ResolvedMap; - typedef Map FieldAddressMap; - - // --- Maps --- + typedef Map ReferenceMap; + typedef Map ActionMap; + typedef Map AddressMap; + typedef Map ExtensionMap; + typedef Map ExtensionTemplateMap; + typedef Map ResolvedMap; + typedef Map FieldAddressMap; + typedef MemoryMap Forwards; + + // --- Lists --- typedef List IdentifierList; // --- Tuples --- diff --git a/elenasrc3/engine/elenaconst.h b/elenasrc3/engine/elenaconst.h index 1f195e657f..1b08509dfb 100644 --- a/elenasrc3/engine/elenaconst.h +++ b/elenasrc3/engine/elenaconst.h @@ -3,7 +3,7 @@ // // This file contains the common ELENA Compiler Engine templates, // classes, structures, functions and constants -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ELENACONST_H @@ -38,7 +38,7 @@ namespace elena_lang // --- ELENA Module structure constants --- constexpr auto ELENA_SIGNITURE = "ELENA."; // the stand alone image constexpr auto ELENA_VM_SIGNITURE = "VM.ELENA."; // the stand alone image - constexpr auto MODULE_SIGNATURE = "ELENA.0605"; // the module version + constexpr auto MODULE_SIGNATURE = "ELENA.0606"; // the module version constexpr auto DEBUG_MODULE_SIGNATURE = "ED.06"; // --- ELENA core module names --- @@ -50,10 +50,10 @@ namespace elena_lang // --- ELENA special sections --- constexpr auto NAMESPACES_SECTION = "$namespaces"; - constexpr auto IMPORTS_SECTION = "$import"; constexpr auto EXTENSION_SECTION = "#extensions"; constexpr auto INITIALIZER_SECTION = "#initializer"; constexpr auto PACKAGE_SECTION = "#package"; + constexpr auto TEMPLATE_MAPPING = "#templates"; constexpr auto WEAK_POSTFIX = "#weak"; constexpr auto ENUM_POSTFIX = "#enum"; @@ -359,6 +359,7 @@ namespace elena_lang constexpr ref_t mskPackageRef = 0x27000000u; constexpr ref_t mskDistrTypeListRef = 0x28000000u; constexpr ref_t mskTLSVariable = 0x29000000u; + constexpr ref_t mskMetaInfo = 0x2A000000u; // --- Image reference types --- constexpr ref_t mskCodeRef = 0x01000000u; diff --git a/elenasrc3/engine/gcroutines.cpp b/elenasrc3/engine/gcroutines.cpp index 3782b55a58..b5b45eccd5 100644 --- a/elenasrc3/engine/gcroutines.cpp +++ b/elenasrc3/engine/gcroutines.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: GC System Routines // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -12,6 +12,8 @@ using namespace elena_lang; #if _M_IX86 || __i386__ +constexpr int LOCK_FLAG = 0x01000000; + constexpr int elObjectOffset = elObjectOffset32; constexpr int gcCollectedMask = 0x80000000; @@ -34,6 +36,8 @@ typedef ObjectPage32 ObjectPage; #else +constexpr size_t LOCK_FLAG = 0x00000000; + constexpr int elObjectOffset = elObjectOffset64; constexpr int gcCollectedMask = 0x80000000; @@ -180,53 +184,49 @@ inline void CollectMG2YGRoots(GCTable* table, ObjectPage* &shadowPtr) if (card) { if (testanyLong(card, 0xFFULL)) { wb_root.stack_ptr_addr = mg_current + elObjectOffset; - wb_root.size = getSize(wb_root.stack_ptr_addr); + wb_root.size = getSize(wb_root.stack_ptr_addr) & ~LOCK_FLAG; YGCollect(&wb_root, table->gc_yg_start, table->gc_yg_end, shadowPtr, nullptr); } if (testanyLong(card, 0xFF00ULL)) { wb_root.stack_ptr_addr = mg_current + page_size + elObjectOffset; - wb_root.size = getSize(wb_root.stack_ptr_addr); + wb_root.size = getSize(wb_root.stack_ptr_addr) & ~LOCK_FLAG; YGCollect(&wb_root, table->gc_yg_start, table->gc_yg_end, shadowPtr, nullptr); } if (testanyLong(card, 0xFF0000ULL)) { wb_root.stack_ptr_addr = mg_current + (page_size << 1) + elObjectOffset; - wb_root.size = getSize(wb_root.stack_ptr_addr); + wb_root.size = getSize(wb_root.stack_ptr_addr) & ~LOCK_FLAG; YGCollect(&wb_root, table->gc_yg_start, table->gc_yg_end, shadowPtr, nullptr); } if (testanyLong(card, 0xFF000000ULL)) { wb_root.stack_ptr_addr = mg_current + (page_size * 3) + elObjectOffset; - wb_root.size = getSize(wb_root.stack_ptr_addr); + wb_root.size = getSize(wb_root.stack_ptr_addr) & ~LOCK_FLAG; YGCollect(&wb_root, table->gc_yg_start, table->gc_yg_end, shadowPtr, nullptr); } if (testanyLong(card, 0xFF00000000ULL)) { wb_root.stack_ptr_addr = mg_current + (page_size << 2) + elObjectOffset; - wb_root.size = getSize(wb_root.stack_ptr_addr); + wb_root.size = getSize(wb_root.stack_ptr_addr) & ~LOCK_FLAG; YGCollect(&wb_root, table->gc_yg_start, table->gc_yg_end, shadowPtr, nullptr); } if (testanyLong(card, 0xFF0000000000ULL)) { wb_root.stack_ptr_addr = mg_current + ((page_size << 2) + page_size) + elObjectOffset; - wb_root.size = getSize(wb_root.stack_ptr_addr); + wb_root.size = getSize(wb_root.stack_ptr_addr) & ~LOCK_FLAG; YGCollect(&wb_root, table->gc_yg_start, table->gc_yg_end, shadowPtr, nullptr); } if (testanyLong(card, 0xFF000000000000ULL)) { wb_root.stack_ptr_addr = mg_current + (page_size * 6) + elObjectOffset; - wb_root.size = getSize(wb_root.stack_ptr_addr); + wb_root.size = getSize(wb_root.stack_ptr_addr) & ~LOCK_FLAG; YGCollect(&wb_root, table->gc_yg_start, table->gc_yg_end, shadowPtr, nullptr); } if (testanyLong(card, 0xFF00000000000000ULL)) { wb_root.stack_ptr_addr = mg_current + (page_size * 7) + elObjectOffset; - wb_root.size = getSize(wb_root.stack_ptr_addr); - - // !! temporal trace code - if (wb_root.size > 0x10000) - wb_root.size = wb_root.size; + wb_root.size = getSize(wb_root.stack_ptr_addr) & ~LOCK_FLAG; YGCollect(&wb_root, table->gc_yg_start, table->gc_yg_end, shadowPtr, nullptr); } @@ -264,7 +264,7 @@ inline void CollectPermYGRoots(GCTable* table, ObjectPage*& shadowPtr) void MGCollect(GCRoot* root, size_t start, size_t end) { size_t* ptr = (size_t*)root->stack_ptr; - size_t size = root->size; + size_t size = root->size & ~LOCK_FLAG; GCRoot current; @@ -294,7 +294,7 @@ void MGCollect(GCRoot* root, size_t start, size_t end) inline void FixObject(GCTable* table, GCRoot* roots, size_t start, size_t end) { uintptr_t* ptr = (uintptr_t*)roots->stack_ptr; - size_t size = roots->size; + size_t size = roots->size & ~LOCK_FLAG; GCRoot current; @@ -415,7 +415,7 @@ inline void FullCollect(GCTable* table, GCRoot* roots) memset((void*)table->gc_mg_wbar, 0, size); } -void* SystemRoutineProvider :: GCRoutine(GCTable* table, GCRoot* roots, size_t size, bool fullMode) +void* SystemRoutineProvider::GCRoutine(GCTable* table, GCRoot* roots, size_t size, bool fullMode) { //printf("GCRoutine %llx,%llx\n", (long long)roots, (long long)size); diff --git a/elenasrc3/engine/langcommon.h b/elenasrc3/engine/langcommon.h index 30161b1e9a..4cdb4a67e8 100644 --- a/elenasrc3/engine/langcommon.h +++ b/elenasrc3/engine/langcommon.h @@ -436,6 +436,7 @@ namespace elena_lang constexpr auto errFatalError = -1; constexpr auto errFatalLinker = -2; constexpr auto errCorruptedVMT = -4; + constexpr auto errMissingNamespace = -5; // --- Project warning levels constexpr int WARNING_LEVEL_1 = 1; @@ -744,6 +745,7 @@ namespace elena_lang constexpr auto PLATFORM_CATEGORY = "configuration/platform"; constexpr auto COLLECTION_CATEGORY = "configuration/collection/*"; + constexpr auto COLLECTIONS_CATEGORY = "configuration/collections/*"; constexpr auto TEMPLATE_CATEGORY = "templates/*"; constexpr auto PRIMITIVE_CATEGORY = "primitives/*"; diff --git a/elenasrc3/engine/libman.cpp b/elenasrc3/engine/libman.cpp index a98ef62bd8..5599794374 100644 --- a/elenasrc3/engine/libman.cpp +++ b/elenasrc3/engine/libman.cpp @@ -3,14 +3,14 @@ // // This file contains the base class implementing ELENA LibraryManager. // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" // ------------------------------------------------------- #include "libman.h" -#include +//#include #include "module.h" #include "langcommon.h" @@ -43,6 +43,7 @@ LibraryProvider :: LibraryProvider() _binaries(nullptr), _modules(nullptr), _debugModules(nullptr), + _templates(nullptr), _listeners(nullptr) { } @@ -111,6 +112,11 @@ ModuleBase* LibraryProvider :: loadModule(ustr_t name, LoadResult& result, bool } else _modules.add(name, module); + // load resolved template mapping if available + ref_t mappingRef = module->mapReference(TEMPLATE_MAPPING, true); + if (mappingRef) + loadTemplateForwards(module, mappingRef); + onModuleLoad(module); } else result = LoadResult::Successful; @@ -249,57 +255,19 @@ ModuleBase* LibraryProvider :: resolveWeakModule(ustr_t weakName, ref_t& referen return nullptr; } -ModuleBase* LibraryProvider :: resolveIndirectWeakModule(ustr_t weakName, ref_t& reference, bool silentMode) +void LibraryProvider :: loadTemplateForwards(ModuleBase* module, ref_t reference) { - IdentifierString relativeName(TEMPLATE_PREFIX_NS, weakName); - - for (auto it = _modules.start(); !it.eof(); ++it) { - // try to resolve it once again - IdentifierString properName("'", weakName); - - reference = (*it)->mapReference(*properName, true); - if (reference) - return *it; + IdentifierString forward; + IdentifierString resolved; - // if not - load imported modules - if ((*it)->mapReference(*relativeName, true)) { - // get list of nested namespaces - IdentifierString nsSectionName("'", NAMESPACES_SECTION); - auto nsSection = (*it)->mapSection((*it)->mapReference(*nsSectionName, true) | mskLiteralListRef, true); - if (nsSection) { - MemoryReader nsReader(nsSection); - while (!nsReader.eof()) { - IdentifierString nsProperName("'"); - nsReader.appendString(nsProperName); - nsProperName.append("'"); - nsProperName.append(weakName.str()); - - reference = (*it)->mapReference(*nsProperName, true); - if (reference) { - assert(false); // NOTE : the template must be declared in the root namespace - - return *it; - } - } - } + MemoryReader reader(module->mapSection(reference | mskMetaInfo, true), 0); + while (!reader.eof()) { + reader.readString(forward); + reader.readString(resolved); - // get list of imported modules - IdentifierString importSectionName("'", IMPORTS_SECTION); - auto importSection = (*it)->mapSection((*it)->mapReference(*importSectionName, true) | mskLiteralListRef, true); - if (importSection) { - MemoryReader importReader(importSection); - while (!importReader.eof()) { - IdentifierString moduleName; - importReader.readString(moduleName); - - LoadResult tempResult; - loadModule(*moduleName, tempResult, true); - } - } - } + if (!_templates.exist(*forward)) + _templates.add(*forward, (*resolved).clone()); } - - return nullptr; } void LibraryProvider :: addCorePath(path_t path) @@ -342,12 +310,13 @@ ModuleInfo LibraryProvider :: getWeakModule(ustr_t weakReferenceName, bool silen { ModuleInfo retVal; - retVal.module = resolveWeakModule(weakReferenceName, retVal.reference, true); - if (retVal.module == nullptr) { - // Bad luck : try to resolve it indirectly - retVal.module = resolveIndirectWeakModule(weakReferenceName, retVal.reference, silentMode); + ustr_t resolved = _templates.get(weakReferenceName); + if (!resolved.empty()) { + return getModule({ resolved }, silentMode); } + retVal.module = resolveWeakModule(weakReferenceName, retVal.reference, true); + return retVal; } @@ -498,6 +467,7 @@ ReferenceInfo LibraryProvider :: retrieveReferenceInfo(ustr_t referenceName, For ModuleBase* LibraryProvider :: createModule(ustr_t name) { + assert(!name.empty()); assert(!_modules.exist(name)); auto module = new Module(name); diff --git a/elenasrc3/engine/libman.h b/elenasrc3/engine/libman.h index b6092c5a41..d84a8fe9ca 100644 --- a/elenasrc3/engine/libman.h +++ b/elenasrc3/engine/libman.h @@ -3,7 +3,7 @@ // // This header contains the declaration of the base class implementing // ELENA JIT Loader. -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef LIBMAN_H @@ -25,6 +25,7 @@ namespace elena_lang PathMap _binaryPaths, _packagePaths; ModuleMap _binaries, _modules, _debugModules; + Forwards _templates; Listeners _listeners; @@ -40,7 +41,8 @@ namespace elena_lang ModuleBase* resolveModule(ustr_t referenceName, ref_t& reference, bool silentMode, bool debugModule); ModuleBase* resolveWeakModule(ustr_t referenceName, ref_t& reference, bool silentMode); - ModuleBase* resolveIndirectWeakModule(ustr_t referenceName, ref_t& reference, bool silentMode); + + void loadTemplateForwards(ModuleBase* module, ref_t reference); public: enum class ModuleRequestResult diff --git a/elenasrc3/engine/textparser.h b/elenasrc3/engine/textparser.h index 5f21b9b4a4..bca6167114 100644 --- a/elenasrc3/engine/textparser.h +++ b/elenasrc3/engine/textparser.h @@ -3,7 +3,7 @@ // // This header contains ELENA Source Reader class declaration. // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef TEXTPARSER_H @@ -43,6 +43,7 @@ namespace elena_lang constexpr char dfaStartInterpol = 'g'; constexpr char dfaNextInterpol = 'f'; constexpr char dfaAltQuote = 'h'; + constexpr char dfaAltQuote2 = 'j'; constexpr char dfaPrivate = 'N'; constexpr char dfaLong = '?'; diff --git a/elenasrc3/engine/xmlprojectbase.h b/elenasrc3/engine/xmlprojectbase.h index 186cb9eb53..8d27edff12 100644 --- a/elenasrc3/engine/xmlprojectbase.h +++ b/elenasrc3/engine/xmlprojectbase.h @@ -23,7 +23,6 @@ namespace elena_lang typedef Tree ProjectTree; typedef Tree::Node ProjectNode; typedef List Paths; - typedef MemoryMap Forwards; class ModuleIterator; diff --git a/elenasrc3/gui/controller.cpp b/elenasrc3/gui/controller.cpp index fef5a32d37..23d145f0a1 100644 --- a/elenasrc3/gui/controller.cpp +++ b/elenasrc3/gui/controller.cpp @@ -13,7 +13,7 @@ using namespace elena_lang; void TextViewController :: newDocument(TextViewModelBase* model, ustr_t name, bool included) { - Text* text = new Text(_settings.eolMode); + Text* text = new Text(model->settings.eolMode); text->create(); model->addDocumentView(name, text, nullptr, included); @@ -22,7 +22,7 @@ void TextViewController :: newDocument(TextViewModelBase* model, ustr_t name, bo bool TextViewController :: openDocument(TextViewModelBase* model, ustr_t name, path_t path, FileEncoding encoding, bool included) { - Text* text = new Text(_settings.eolMode); + Text* text = new Text(model->settings.eolMode); if (!text->load(path, encoding, false)) return false; @@ -69,15 +69,15 @@ void TextViewController :: indent(TextViewModelBase* model) DocumentChangeStatus status = {}; auto docView = model->DocView(); - if (_settings.tabUsing) { + if (model->settings.tabUsing) { docView->tabbing(status, '\t', 1, true); } else { if (!docView->hasSelection()) { - int shift = calcTabShift(docView->getCaret().x, _settings.tabSize); + int shift = calcTabShift(docView->getCaret().x, model->settings.tabSize); docView->insertChar(status, ' ', shift); } - else docView->tabbing(status, ' ', _settings.tabSize, true); + else docView->tabbing(status, ' ', model->settings.tabSize, true); } notifyTextModelChange(model, status); @@ -88,11 +88,11 @@ void TextViewController :: outdent(TextViewModelBase* model) DocumentChangeStatus status = {}; auto docView = model->DocView(); - if (_settings.tabUsing) { + if (model->settings.tabUsing) { docView->tabbing(status, '\t', 1, false); } else { - docView->tabbing(status, ' ', _settings.tabSize, false); + docView->tabbing(status, ' ', model->settings.tabSize, false); } notifyTextModelChange(model, status); @@ -324,7 +324,7 @@ void TextViewController :: moveCaretDown(TextViewModelBase* model, bool kbShift, auto docView = model->DocView(); if (kbCtrl) { - docView->moveFrameDown(status); + docView->moveFrameDown(status, model->scrollOffset); } else docView->moveDown(status, kbShift); @@ -403,7 +403,7 @@ void TextViewController :: moveCaretUp(TextViewModelBase* model, bool kbShift, b if (!kbCtrl) { docView->moveUp(status, kbShift); } - else docView->moveFrameUp(status); + else docView->moveFrameUp(status, model->scrollOffset); notifyTextModelChange(model, status); } diff --git a/elenasrc3/gui/controller.h b/elenasrc3/gui/controller.h index dd687d9c3a..c66a24008e 100644 --- a/elenasrc3/gui/controller.h +++ b/elenasrc3/gui/controller.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // GUI Controller header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef CONTOLLER_H @@ -21,6 +21,13 @@ namespace elena_lang virtual bool saveFile(path_t ext, PathString& path) = 0; }; + // --- FontDialogBase --- + class FontDialogBase + { + public: + virtual bool selectFont(FontInfo& fontInfo) = 0; + }; + // --- MessageDialogBase --- class MessageDialogBase { @@ -88,19 +95,10 @@ namespace elena_lang virtual SelectResult selectWindow() = 0; }; - // --- TextViewSettings --- - struct TextViewSettings - { - EOLMode eolMode; - bool tabUsing; - int tabSize; - }; - // --- TextViewController --- class TextViewController : public TextViewControllerBase { - protected: - TextViewSettings _settings; + protected: NotifierBase* _notifier; //void onTextChanged(TextViewModelBase* model, DocumentView* view); @@ -170,9 +168,8 @@ namespace elena_lang void goToLine(TextViewModelBase* model, int row); - TextViewController(TextViewSettings& settings) + TextViewController() { - _settings = settings; _notifier = nullptr; } }; diff --git a/elenasrc3/gui/document.cpp b/elenasrc3/gui/document.cpp index a836c370bd..92c70a3381 100644 --- a/elenasrc3/gui/document.cpp +++ b/elenasrc3/gui/document.cpp @@ -252,6 +252,8 @@ bool DocumentView::LexicalReader :: readNext(TextWriter& writer, pos_t l // --- DocumentView --- +int DocumentView::VerticalScrollOffset = 1; + DocumentView :: DocumentView(Text* text, TextFormatterBase* formatter) : _undoBuffer(UNDO_BUFFER_SIZE), _formatter(text, formatter, &_markers), @@ -398,7 +400,7 @@ void DocumentView :: setCaret(int column, int row, bool selecting, DocumentChang frame.y = caret.y; } else if (frame.y + _size.y - 1 <= caret.y) { - frame.y = caret.y - _size.y + 3; + frame.y = caret.y - _size.y + 2 + VerticalScrollOffset; } if (_frame.getCaret() != frame) { @@ -590,9 +592,9 @@ void DocumentView :: moveRightToken(DocumentChangeStatus& changeStatus, bool sel setCaret(_caret.getCaret(), selecting, changeStatus); } -void DocumentView :: moveFrameUp(DocumentChangeStatus& changeStatus) +void DocumentView :: moveFrameUp(DocumentChangeStatus& changeStatus, int frameOffset) { - vscroll(changeStatus, -1); + vscroll(changeStatus, -frameOffset); if (changeStatus.frameChanged) { if (_frame.row() + _size.y - 2 <= _caret.row()) { setCaret(_caret.column(), _frame.row() + _size.y - 3, false, changeStatus); @@ -600,9 +602,9 @@ void DocumentView :: moveFrameUp(DocumentChangeStatus& changeStatus) } } -void DocumentView :: moveFrameDown(DocumentChangeStatus& changeStatus) +void DocumentView :: moveFrameDown(DocumentChangeStatus& changeStatus, int frameOffset) { - vscroll(changeStatus, 1); + vscroll(changeStatus, frameOffset); if (changeStatus.frameChanged) { if (_caret.row() < _frame.row()) { setCaret(_caret.column(), _frame.row(), false, changeStatus); @@ -642,9 +644,9 @@ void DocumentView :: movePageDown(DocumentChangeStatus& changeStatus, bool selec setCaret(_caret.column(), _text->getRowCount() - 1, selecting, changeStatus); } else { - vscroll(changeStatus, _size.y); + vscroll(changeStatus, _size.y - 1); if (changeStatus.frameChanged) - setCaret(_caret.column(), _caret.row() + _size.y, selecting, changeStatus); + setCaret(_caret.column(), _caret.row() + _size.y - 1, selecting, changeStatus); } } @@ -657,9 +659,9 @@ void DocumentView :: movePageUp(DocumentChangeStatus& changeStatus, bool selecti setCaret(_caret.column(), 0, selecting, changeStatus); } else { - vscroll(changeStatus, -_size.y); + vscroll(changeStatus, -_size.y + 1); if (changeStatus.frameChanged) - setCaret(_caret.column(), _caret.row() - _size.y, selecting, changeStatus); + setCaret(_caret.column(), _caret.row() - _size.y + 1, selecting, changeStatus); } } diff --git a/elenasrc3/gui/document.h b/elenasrc3/gui/document.h index 68122ab22e..b3ea5ab011 100644 --- a/elenasrc3/gui/document.h +++ b/elenasrc3/gui/document.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // DocumentView class header -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef DOCUMENT_H @@ -161,6 +161,8 @@ namespace elena_lang class DocumentView : public TextWatcherBase { public: + static int VerticalScrollOffset; + struct LexicalReader : ReaderInfo { Rectangle region; @@ -338,10 +340,10 @@ namespace elena_lang void moveEnd(DocumentChangeStatus& changeStatus, bool selecting); void moveLast(DocumentChangeStatus& changeStatus, bool selecting); - void moveFrameDown(DocumentChangeStatus& changeStatus); + void moveFrameDown(DocumentChangeStatus& changeStatus, int frameOffset); void moveDown(DocumentChangeStatus& changeStatus, bool selecting); - void moveFrameUp(DocumentChangeStatus& changeStatus); + void moveFrameUp(DocumentChangeStatus& changeStatus, int frameOffset); void moveUp(DocumentChangeStatus& changeStatus, bool selecting); void moveLeftToken(DocumentChangeStatus& changeStatus, bool selecting); diff --git a/elenasrc3/gui/gtklinux/gtktabbar.cpp b/elenasrc3/gui/gtklinux/gtktabbar.cpp index 98def95b2c..aa9290b16c 100644 --- a/elenasrc3/gui/gtklinux/gtktabbar.cpp +++ b/elenasrc3/gui/gtklinux/gtktabbar.cpp @@ -37,6 +37,15 @@ Gtk::Widget* TabBar :: getCurrentControl() return list[0]; } +void TabBar :: selectTab(int index) +{ + set_current_page(index); +} + +void TabBar :: onTabChange(int page_num) +{ +} + /*Gtk::Widget* TabBar :: getTabControl(int index) const { if (index == -1) diff --git a/elenasrc3/gui/gtklinux/gtktabbar.h b/elenasrc3/gui/gtklinux/gtktabbar.h index 1635b002ca..03cbe3b730 100644 --- a/elenasrc3/gui/gtklinux/gtktabbar.h +++ b/elenasrc3/gui/gtklinux/gtktabbar.h @@ -14,9 +14,26 @@ namespace elena_lang // --- TabBar --- class TabBar : public Gtk::Notebook { + protected: + void on_switch_page(Widget* page, guint page_num) override + { + Gtk::Notebook::on_switch_page(page, page_num); + + onTabChange(page_num); + } + public: + virtual void onTabChange(int page_num); + void addTab(const char* name, Gtk::Widget* control); + void selectTab(int index); + + int getCurrentTabIndex() + { + return get_current_page(); + } + Gtk::Widget* getCurrentControl(); TabBar(); diff --git a/elenasrc3/gui/guieditor.h b/elenasrc3/gui/guieditor.h index 13be89244b..ec395fc5cf 100644 --- a/elenasrc3/gui/guieditor.h +++ b/elenasrc3/gui/guieditor.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // GUI common editor header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef GUIEDITOR_H @@ -74,6 +74,30 @@ namespace elena_lang } }; + // --- FontInfo --- + struct FontInfo + { + TextString name; + int size; + + FontInfo(ustr_t name, int size) + : name(name), size(size) + { + } + FontInfo(int size) + : size(size) + { + } + }; + + // --- TextViewSettings --- + struct TextViewSettings + { + EOLMode eolMode; + bool tabUsing; + int tabSize; + }; + // --- TextViewBase --- class TextViewModelBase { @@ -81,11 +105,14 @@ namespace elena_lang DocumentView* _currentView; public: - bool lineNumbersVisible; - bool highlightSyntax; - bool empty; - int fontSize; - int schemeIndex; + TextViewSettings settings; + + bool lineNumbersVisible; + bool highlightSyntax; + bool empty; + FontInfo fontInfo; + int schemeIndex; + int scrollOffset; DocumentView* DocView() { @@ -124,14 +151,21 @@ namespace elena_lang _currentView->refresh(changeStatus); } - TextViewModelBase() + void refreshSettings() + { + DocumentView::VerticalScrollOffset = scrollOffset; + Text::TabSize = settings.tabSize; + } + + TextViewModelBase(TextViewSettings settings) + : fontInfo(10), settings(settings) { this->_currentView = nullptr; this->lineNumbersVisible = true; // !! temporal hard-coded this->empty = true; - this->fontSize = 10; this->schemeIndex = 0; - this->highlightSyntax = false; + this->highlightSyntax = true; + this->scrollOffset = 1; } }; diff --git a/elenasrc3/gui/view.cpp b/elenasrc3/gui/view.cpp index d9a5446841..2a103e8188 100644 --- a/elenasrc3/gui/view.cpp +++ b/elenasrc3/gui/view.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // IDE View class body File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "view.h" @@ -13,8 +13,8 @@ using namespace elena_lang; // --- TextViewModel --- -TextViewModel :: TextViewModel() : - TextViewModelBase(), +TextViewModel :: TextViewModel(TextViewSettings settings) : + TextViewModelBase(settings), _documents(nullptr), _listeners(nullptr), _docListeners(nullptr) diff --git a/elenasrc3/gui/view.h b/elenasrc3/gui/view.h index 3bf89b8a1c..b9ec9b2705 100644 --- a/elenasrc3/gui/view.h +++ b/elenasrc3/gui/view.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // IDE View class header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef VIEW_H @@ -115,7 +115,7 @@ namespace elena_lang } } - TextViewModel(); + TextViewModel(TextViewSettings settings); virtual ~TextViewModel() = default; }; diff --git a/elenasrc3/gui/windows/wincanvas.cpp b/elenasrc3/gui/windows/wincanvas.cpp index 66d63d497c..9abf9c5c30 100644 --- a/elenasrc3/gui/windows/wincanvas.cpp +++ b/elenasrc3/gui/windows/wincanvas.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA Win32 Common header // Win32 graphic tools body -// (C)2021, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "wincanvas.h" @@ -15,13 +15,12 @@ Font :: Font() fontID = nullptr; characterSet = /*IDE_CHARSET_DEFAULT*/0; size = 8; - fontName = nullptr; bold = italic = false; } Font :: Font(wstr_t faceName, int characterSet, int size, bool bold, bool italic) { - this->fontName = faceName; + this->fontName.copy(faceName); this->characterSet = characterSet; this->size = size; this->bold = bold; @@ -30,6 +29,16 @@ Font :: Font(wstr_t faceName, int characterSet, int size, bool bold, bool italic this->fontID = nullptr; } +int Font :: toSize(HDC handler, int lfHeight) +{ + return MulDiv(-lfHeight, 72, GetDeviceCaps(handler, LOGPIXELSY)); +} + +int Font :: fromSize(HDC handler, int size) +{ + return -MulDiv(size, ::GetDeviceCaps(handler, LOGPIXELSY), 72); +} + void Font :: create(HDC handler) { LOGFONT lf; @@ -41,7 +50,7 @@ void Font :: create(HDC handler) lf.lfCharSet = (BYTE)(characterSet); size_t length = LF_FACESIZE; - StrConvertor::copy(lf.lfFaceName, fontName, fontName.length(), length); + StrConvertor::copy(lf.lfFaceName, fontName.str(), fontName.length(), length); lf.lfFaceName[length] = 0; fontID = ::CreateFontIndirect(&lf); @@ -62,7 +71,7 @@ Font* FontFactory :: createFont(wstr_t fontName, int size, int characterSet, boo for (auto it = _cache.start(); !it.eof(); ++it) { Font* font = *it; - if (font->fontName.compare(fontName) && font->size == size && + if ((*font->fontName).compare(fontName) && font->size == size && font->characterSet == characterSet && font->bold == bold && font->italic == italic) { return font; diff --git a/elenasrc3/gui/windows/wincanvas.h b/elenasrc3/gui/windows/wincanvas.h index 89d7cd6f3c..fa13ed5b19 100644 --- a/elenasrc3/gui/windows/wincanvas.h +++ b/elenasrc3/gui/windows/wincanvas.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA Win32 Common header // Win32 graphic tools header -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef CANVAS_H @@ -14,8 +14,11 @@ namespace elena_lang // --- Font --- struct Font : public FontBase { - wstr_t fontName; - HFONT fontID; + TextString fontName; + HFONT fontID; + + static int toSize(HDC handler, int value); + static int fromSize(HDC handler, int value); void create(HDC handler); void release(); diff --git a/elenasrc3/gui/windows/wincommon.cpp b/elenasrc3/gui/windows/wincommon.cpp index ff132f0d8f..9895deede0 100644 --- a/elenasrc3/gui/windows/wincommon.cpp +++ b/elenasrc3/gui/windows/wincommon.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // WinAPI Common Body File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "wincommon.h" @@ -30,9 +30,9 @@ DateTime DateTime::getFileTime(const wchar_t* path) // --- ControlBase --- -HWND ControlBase :: create(HINSTANCE instance, wstr_t className, ControlBase* owner) +HWND ControlBase :: create(HINSTANCE instance, wstr_t className, ControlBase* owner, int dwExStyles) { - _handle = ::CreateWindowW(className.str(), _title.str(), WS_OVERLAPPEDWINDOW, + _handle = ::CreateWindowExW(dwExStyles, className.str(), _title.str(), WS_OVERLAPPEDWINDOW, _rect.topLeft.x, _rect.topLeft.y, _rect.width(), _rect.height(), owner ? owner->handle() : nullptr, nullptr, instance, this); return _handle; diff --git a/elenasrc3/gui/windows/wincommon.h b/elenasrc3/gui/windows/wincommon.h index 8944cc6333..c1750ef65f 100644 --- a/elenasrc3/gui/windows/wincommon.h +++ b/elenasrc3/gui/windows/wincommon.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // WinAPI Common Header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef WINCOMMON_H @@ -174,7 +174,7 @@ namespace elena_lang virtual void onSelChanged() {} virtual void onDoubleClick(NMHDR* hdr) {} - virtual HWND create(HINSTANCE instance, wstr_t className, ControlBase* owner); + virtual HWND create(HINSTANCE instance, wstr_t className, ControlBase* owner, int dwExStyles); virtual wchar_t* getValue() { return nullptr; } virtual void clearValue() {} diff --git a/elenasrc3/gui/windows/winsdi.cpp b/elenasrc3/gui/windows/winsdi.cpp index 9d69efb434..22f8a9f322 100644 --- a/elenasrc3/gui/windows/winsdi.cpp +++ b/elenasrc3/gui/windows/winsdi.cpp @@ -442,6 +442,9 @@ LRESULT SDIWindow :: proceed(UINT message, WPARAM wParam, LPARAM lParam) } case WM_ERASEBKGND: return paintBackground(); + case WM_DROPFILES: + onDropFiles((HDROP)wParam); + break; //case WM_PAINT: // break; //case WM_CTLCOLORLISTBOX: diff --git a/elenasrc3/gui/windows/winsdi.h b/elenasrc3/gui/windows/winsdi.h index b555f07f32..66f836564e 100644 --- a/elenasrc3/gui/windows/winsdi.h +++ b/elenasrc3/gui/windows/winsdi.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // WinAPI SDI Window Header File -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef WINSDI_H @@ -131,6 +131,8 @@ namespace elena_lang virtual void onNotify(NMHDR* hdr); bool onSetCursor() override; + virtual void onDropFiles(HDROP hDrop) {} + LRESULT proceed(UINT message, WPARAM wParam, LPARAM lParam) override; void setBackgroundColor(Color color); diff --git a/elenasrc3/gui/windows/winsplitter.cpp b/elenasrc3/gui/windows/winsplitter.cpp index 8157418238..4966393a39 100644 --- a/elenasrc3/gui/windows/winsplitter.cpp +++ b/elenasrc3/gui/windows/winsplitter.cpp @@ -56,10 +56,10 @@ void Splitter :: registerSplitterWindow(HINSTANCE hInstance, wstr_t className, b CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS); } -HWND Splitter :: create(HINSTANCE instance, wstr_t className, ControlBase* owner) +HWND Splitter :: create(HINSTANCE instance, wstr_t className, ControlBase* owner, int dwExStyles) { _handle = ::CreateWindowEx( - 0, className, _title, + dwExStyles, className, _title, WS_CHILD, CW_USEDEFAULT, 0, 4, 4, owner->handle(), nullptr, instance, (LPVOID)this); diff --git a/elenasrc3/gui/windows/winsplitter.h b/elenasrc3/gui/windows/winsplitter.h index 74e8a3ea72..ebce1d2958 100644 --- a/elenasrc3/gui/windows/winsplitter.h +++ b/elenasrc3/gui/windows/winsplitter.h @@ -40,7 +40,7 @@ namespace elena_lang EventInvoker _layoutEventInvoker; - HWND create(HINSTANCE instance, wstr_t className, ControlBase* owner) override; + HWND create(HINSTANCE instance, wstr_t className, ControlBase* owner, int dwExStyles = 0) override; bool visible() override; diff --git a/elenasrc3/gui/windows/wintextview.cpp b/elenasrc3/gui/windows/wintextview.cpp index a0f62eebe3..f9862d0b99 100644 --- a/elenasrc3/gui/windows/wintextview.cpp +++ b/elenasrc3/gui/windows/wintextview.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // WinAPI TextView Control Body File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "wintextview.h" @@ -70,10 +70,10 @@ void TextViewWindow :: registerTextViewWindow(HINSTANCE hInstance, wstr_t classN WindowBase::registerClass(hInstance, WindowBase::WndProc, className, nullptr, nullptr, nullptr, CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS); } -HWND TextViewWindow :: create(HINSTANCE instance, wstr_t className, ControlBase* owner) +HWND TextViewWindow :: create(HINSTANCE instance, wstr_t className, ControlBase* owner, int dwExStyles) { _handle = ::CreateWindowEx( - WS_EX_CLIENTEDGE, className, _title, + dwExStyles | WS_EX_CLIENTEDGE, className, _title, WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_CLIPCHILDREN | WS_EX_RTLREADING, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, owner->handle(), nullptr, instance, (LPVOID)this); @@ -496,7 +496,7 @@ void TextViewWindow :: onMouseWheel(short wheelDelta, bool kbCtrl) DocumentChangeStatus status = {}; auto docView = _model->DocView(); - int offset = (wheelDelta > 0) ? -1 : 1; + int offset = (wheelDelta > 0) ? -_model->scrollOffset : _model->scrollOffset; if (kbCtrl) { offset *= docView->getSize().y; } diff --git a/elenasrc3/gui/windows/wintextview.h b/elenasrc3/gui/windows/wintextview.h index f3da417e55..63f1e0cf6f 100644 --- a/elenasrc3/gui/windows/wintextview.h +++ b/elenasrc3/gui/windows/wintextview.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // WinAPI TextView Control Header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef WINTEXTVIEW_H @@ -159,7 +159,7 @@ namespace elena_lang static void registerTextViewWindow(HINSTANCE hInstance, wstr_t className); - HWND create(HINSTANCE instance, wstr_t className, ControlBase* owner) override; + HWND create(HINSTANCE instance, wstr_t className, ControlBase* owner, int dwExStyles) override; LRESULT proceed(UINT message, WPARAM wParam, LPARAM lParam) override; diff --git a/elenasrc3/gui/windows/wintoolbar.cpp b/elenasrc3/gui/windows/wintoolbar.cpp index dfc661cef2..ee40546152 100644 --- a/elenasrc3/gui/windows/wintoolbar.cpp +++ b/elenasrc3/gui/windows/wintoolbar.cpp @@ -16,40 +16,58 @@ ToolBar :: ToolBar(int iconSize) : ControlBase(_T("Toolbar"), 0, 0, 800, iconSize + 11) { _iconSize = iconSize; + _hImageList = 0; +} + +ToolBar::~ToolBar() +{ + if (_hImageList) + ImageList_Destroy(_hImageList); } HWND ToolBar :: createControl(HINSTANCE instance, ControlBase* owner, ToolBarButton* buttons, size_t counter) { - _handle = ::CreateWindowEx( - WS_EX_PALETTEWINDOW, TOOLBARCLASSNAME, _title, - WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_TOP | BTNS_AUTOSIZE, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, owner->handle(), nullptr, instance, (LPVOID)this); + _handle = CreateWindowEx(WS_EX_PALETTEWINDOW, TOOLBARCLASSNAME, _title, + WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_WRAPABLE | TBSTYLE_FLAT | CCS_TOP, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, + owner->handle(), nullptr, instance, (LPVOID)this); + + SendMessage(_handle, CCM_SETVERSION, (WPARAM)6, 0); ::SendMessage(_handle, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + ::SendMessage(_handle, TB_SETBITMAPSIZE, 0, MAKELPARAM(_iconSize, _iconSize)); + + _hImageList = ImageList_Create(_iconSize, _iconSize, // Dimensions of individual bitmaps. + ILC_COLOR24 | ILC_MASK, // Ensures transparent background. + 2, 0); + + COLORREF crMask = RGB(255, 0, 255); - //::SendMessage(_self, TB_LOADIMAGES, IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL); - TBADDBITMAP bitmap = { instance, 0 }; TBBUTTON* tbButtons = new TBBUTTON[counter]; - for (size_t i = 0; i < counter; i++) { + int imageListId = 0; + for (size_t i = 0; i < counter/*2*/; i++) { tbButtons[i].idCommand = buttons[i].command; tbButtons[i].fsState = TBSTATE_ENABLED; tbButtons[i].dwData = 0; tbButtons[i].iString = 0; if (buttons[i].command != 0) { - bitmap.nID = buttons[i].iconId; - tbButtons[i].iBitmap = (int)::SendMessage(_handle, TB_ADDBITMAP, 1, (LPARAM)&bitmap); + tbButtons[i].iBitmap = imageListId++; + tbButtons[i].fsStyle = TBSTYLE_BUTTON; - tbButtons[i].fsStyle = BTNS_BUTTON; + HBITMAP hBitmap = (HBITMAP)LoadImage(instance, MAKEINTRESOURCE(buttons[i].iconId), IMAGE_BITMAP, _iconSize, _iconSize, NULL); + + //ImageList_Add(_hImageList, hBitmap, NULL); + ImageList_AddMasked(_hImageList, hBitmap, crMask); } else { tbButtons[i].iBitmap = 0; tbButtons[i].fsStyle = BTNS_SEP; } } - ::SendMessage(_handle, TB_SETBUTTONSIZE, 0, MAKELONG(_iconSize, _iconSize)); - ::SendMessage(_handle, TB_ADDBUTTONS, (WPARAM)counter, (LPARAM)tbButtons); + + ::SendMessage(_handle, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)_hImageList); + ::SendMessage(_handle, TB_ADDBUTTONS, counter, (LPARAM)tbButtons); ::SendMessage(_handle, TB_AUTOSIZE, 0, 0); delete[] tbButtons; diff --git a/elenasrc3/gui/windows/wintoolbar.h b/elenasrc3/gui/windows/wintoolbar.h index 9012d8c0ee..ba70bb25fb 100644 --- a/elenasrc3/gui/windows/wintoolbar.h +++ b/elenasrc3/gui/windows/wintoolbar.h @@ -21,7 +21,8 @@ struct ToolBarButton class ToolBar : public ControlBase { - int _iconSize; + int _iconSize; + HIMAGELIST _hImageList; public: HWND createControl(HINSTANCE instance, ControlBase* owner, @@ -30,6 +31,7 @@ class ToolBar : public ControlBase void enableItemById(int id, bool doEnable); ToolBar(int iconSize); + virtual ~ToolBar(); }; } diff --git a/elenasrc3/ide/debugcontroller.cpp b/elenasrc3/ide/debugcontroller.cpp index 0fd5986233..fb085c95fa 100644 --- a/elenasrc3/ide/debugcontroller.cpp +++ b/elenasrc3/ide/debugcontroller.cpp @@ -3,7 +3,7 @@ // // This file contains implematioon of the DebugController class and // its helpers -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -499,7 +499,7 @@ DebugLineInfo* DebugInfoProvider :: seekClassInfo(addr_t address, IdentifierStri DebugController :: DebugController(DebugProcessBase* process, ProjectModel* model, SourceViewModel* sourceModel, DebugSourceController* sourceController) - : _provider(model) + : _provider(model), _startUpSettings({}) { _started = false; _process = process; @@ -508,12 +508,11 @@ DebugController :: DebugController(DebugProcessBase* process, ProjectModel* mode _model = model; _currentPath = nullptr; _sourceController = sourceController; - _witExplicitConsole = false; } void DebugController :: debugThread() { - if (!_process->startProgram(_debuggee.str(), _arguments.str(), _witExplicitConsole)) { + if (!_process->startProgram(_debuggee.str(), _arguments.str(), *_model->paths.appPath, _startUpSettings)) { //HOTFIX : to inform the listening thread _process->resetEvent(DEBUG_ACTIVE); @@ -843,12 +842,12 @@ void DebugController :: clearBreakpoints() } -bool DebugController :: start(path_t programPath, path_t arguments, bool debugMode, bool witExplicitConsole) +bool DebugController :: start(path_t programPath, path_t arguments, bool debugMode, StartUpSettings startUpSettings) { _currentModule.clear(); _debuggee.copy(programPath); _arguments.copy(arguments); - _witExplicitConsole = witExplicitConsole; + _startUpSettings = startUpSettings; if (debugMode) { addr_t entryPoint = _process->findEntryPoint(programPath); @@ -1110,6 +1109,17 @@ void* DebugController :: readByteLocal(ContextBrowserBase* watch, void* parent, else return nullptr; } +void* DebugController :: readShortLocal(ContextBrowserBase* watch, void* parent, addr_t address, ustr_t name, int level) +{ + if (level > 0) { + unsigned int value = _process->getWORD(address); + + WatchContext context = { parent, address }; + return watch->addOrUpdateDWORD(&context, name, value); + } + else return nullptr; +} + void* DebugController :: readLongLocal(ContextBrowserBase* watch, void* parent, addr_t address, ustr_t name, int level) { if (level > 0) { @@ -1156,6 +1166,9 @@ void* DebugController :: readFieldValue(ContextBrowserBase* watch, void* parent, if (size == 4) { return readUIntLocal(watch, parent, address, name, level); } + else if (size == 2) { + return readShortLocal(watch, parent, address, name, level); + } else if (size == 1) { return readByteLocal(watch, parent, address, name, level); } diff --git a/elenasrc3/ide/debugcontroller.h b/elenasrc3/ide/debugcontroller.h index 5eb08f08ae..af7a7540da 100644 --- a/elenasrc3/ide/debugcontroller.h +++ b/elenasrc3/ide/debugcontroller.h @@ -2,7 +2,7 @@ // E L E N A P r o j e c t: ELENA Engine // // This file contains the DebugController class and its helpers header -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef DEBUGCONTROLLER_H @@ -224,7 +224,7 @@ namespace elena_lang bool _running; PathString _debuggee; PathString _arguments; - bool _witExplicitConsole; + StartUpSettings _startUpSettings; DebugProcessBase* _process; DebugInfoProvider _provider; @@ -257,6 +257,7 @@ namespace elena_lang void* readObject(ContextBrowserBase* watch, void* parent, addr_t address, ustr_t name, int level, ustr_t className = nullptr, addr_t vmtAddress = 0); void* readFieldValue(ContextBrowserBase* watch, void* parent, addr_t address, ustr_t name, int level, int size, ustr_t className = nullptr); void* readByteLocal(ContextBrowserBase* watch, void* parent, addr_t address, ustr_t name, int level); + void* readShortLocal(ContextBrowserBase* watch, void* parent, addr_t address, ustr_t name, int level); void* readIntLocal(ContextBrowserBase* watch, void* parent, addr_t address, ustr_t name, int level); void* readUIntLocal(ContextBrowserBase* watch, void* parent, addr_t address, ustr_t name, int level); void* readLongLocal(ContextBrowserBase* watch, void* parent, addr_t address, ustr_t name, int level); @@ -274,7 +275,7 @@ namespace elena_lang return _started; } - bool start(path_t programPath, path_t arguments, bool debugMode, bool witExplicitConsole); + bool start(path_t programPath, path_t arguments, bool debugMode, StartUpSettings startUpSettings); void clearBreakpoints(); diff --git a/elenasrc3/ide/editframe.cpp b/elenasrc3/ide/editframe.cpp index 64b0212d68..2a05bd1f19 100644 --- a/elenasrc3/ide/editframe.cpp +++ b/elenasrc3/ide/editframe.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // SourceViewModel implementation File -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "editframe.h" @@ -10,8 +10,8 @@ using namespace elena_lang; // --- SourceViewModel --- -SourceViewModel :: SourceViewModel() - : TextViewModel() +SourceViewModel :: SourceViewModel(TextViewSettings settings) + : TextViewModel(settings) { } diff --git a/elenasrc3/ide/editframe.h b/elenasrc3/ide/editframe.h index 4539e2d478..caf4b8f077 100644 --- a/elenasrc3/ide/editframe.h +++ b/elenasrc3/ide/editframe.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // SourceViewModel header File -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef EDITFRAME_H @@ -26,7 +26,7 @@ namespace elena_lang void clearDocumentView() override; - SourceViewModel(); + SourceViewModel(TextViewSettings settings); }; } diff --git a/elenasrc3/ide/gtklinux/factory.cpp b/elenasrc3/ide/gtklinux/factory.cpp index facd3322af..c055bc8803 100644 --- a/elenasrc3/ide/gtklinux/factory.cpp +++ b/elenasrc3/ide/gtklinux/factory.cpp @@ -79,6 +79,9 @@ void IDEBroadcaster :: sendMessage(EventBase* event) case EVENT_TEXTVIEW_MODEL_CHANGED: textview_changed.emit(*(TextViewModelEvent*)event); break; + case EVENT_TEXTFRAME_SELECTION_CHANGED: + textframe_changed.emit(*(SelectionEvent*)event); + break; default: break; } @@ -107,16 +110,16 @@ Gtk::Widget* IDEFactory :: createTextControl() // update font size for (int j = 0; j < STYLE_MAX; j++) { - defaultStyles[j].size = viewModel->fontSize; - classicStyles[j].size = viewModel->fontSize; - darkStyles[j].size = viewModel->fontSize; + defaultStyles[j].size = viewModel->fontInfo.size; + classicStyles[j].size = viewModel->fontInfo.size; + darkStyles[j].size = viewModel->fontInfo.size; } // initialize view styles reloadStyles(viewModel); //TextViewWindow* view = new TextViewWindow(/*_model->viewModel(), &_styles*//*, &_controller->sourceController*/); - IDETextViewFrame* frame = new IDETextViewFrame(_model->viewModel(), &_controller->sourceController, &_styles); + IDETextViewFrame* frame = new IDETextViewFrame(_model->viewModel(), &_controller->sourceController, &_styles, &_broadcaster); _broadcaster.textview_changed.connect(sigc::mem_fun(*frame, &IDETextViewFrame::on_text_model_change)); @@ -138,7 +141,19 @@ Gtk::Widget* IDEFactory :: createTextControl() void IDEFactory :: reloadStyles(TextViewModelBase* viewModel) { - _styles.assign(STYLE_MAX + 1, _schemes[viewModel->schemeIndex], viewModel->fontSize + 5, 20, &_fontFactory); + // update font size + for (int j = 0; j <= STYLE_MAX; j++) { + defaultStyles[j].size = viewModel->fontInfo.size; + defaultStyles[j].faceName = *viewModel->fontInfo.name; + + classicStyles[j].size = viewModel->fontInfo.size; + classicStyles[j].faceName = *viewModel->fontInfo.name; + + darkStyles[j].size = viewModel->fontInfo.size; + darkStyles[j].faceName = *viewModel->fontInfo.name; + } + + _styles.assign(STYLE_MAX + 1, _schemes[viewModel->schemeIndex], viewModel->fontInfo.size + 5, 20, &_fontFactory); } void IDEFactory :: styleControl(GUIControlBase* control) @@ -160,6 +175,7 @@ GUIControlBase* IDEFactory :: createMainWindow(NotifierBase* notifier, ProcessBa ideWindow->setLayout(textIndex, -1, -1, -1, -1); _broadcaster.textview_changed.connect(sigc::mem_fun(*ideWindow, >KIDEWindow::on_text_model_change)); + _broadcaster.textframe_changed.connect(sigc::mem_fun(*ideWindow, >KIDEWindow::on_textframe_change)); return new WindowWrapper(ideWindow); } diff --git a/elenasrc3/ide/gtklinux/factory.h b/elenasrc3/ide/gtklinux/factory.h index e17de9163f..79546715ec 100644 --- a/elenasrc3/ide/gtklinux/factory.h +++ b/elenasrc3/ide/gtklinux/factory.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // IDE windows factory -// (C)2024, by Aleksey Rakov +// (C)2024-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef FACTORY_H @@ -18,12 +18,14 @@ namespace elena_lang { typedef sigc::signal type_textview_changed; + typedef sigc::signal type_textframe_changed; // --- IDEBroadcaster --- class IDEBroadcaster : public BroadcasterBase { public: - type_textview_changed textview_changed; + type_textview_changed textview_changed; + type_textframe_changed textframe_changed; void sendMessage(EventBase* event) override; diff --git a/elenasrc3/ide/gtklinux/gtkide.cpp b/elenasrc3/ide/gtklinux/gtkide.cpp index ff227e747d..899e33721c 100644 --- a/elenasrc3/ide/gtklinux/gtkide.cpp +++ b/elenasrc3/ide/gtklinux/gtkide.cpp @@ -251,6 +251,11 @@ void GTKIDEWindow :: on_text_model_change(TextViewModelEvent event) // } } +void GTKIDEWindow :: on_textframe_change(SelectionEvent event) +{ + _controller->onDocSelection(_model, event.Index()); +} + void GTKIDEWindow :: onDocumentUpdate(DocumentChangeStatus changeStatus) { } diff --git a/elenasrc3/ide/gtklinux/gtkide.h b/elenasrc3/ide/gtklinux/gtkide.h index b80752a095..e6e654f079 100644 --- a/elenasrc3/ide/gtklinux/gtkide.h +++ b/elenasrc3/ide/gtklinux/gtkide.h @@ -272,6 +272,7 @@ class GTKIDEWindow : public SDIWindow public: void on_text_model_change(TextViewModelEvent event); + void on_textframe_change(SelectionEvent event); GTKIDEWindow(/*const char* caption, */IDEController* controller, IDEModel* model); }; diff --git a/elenasrc3/ide/gtklinux/gtkidetextview.cpp b/elenasrc3/ide/gtklinux/gtkidetextview.cpp index c566964dd6..ef084f3550 100644 --- a/elenasrc3/ide/gtklinux/gtkidetextview.cpp +++ b/elenasrc3/ide/gtklinux/gtkidetextview.cpp @@ -10,14 +10,22 @@ using namespace elena_lang; // --- IDETextViewFrame --- -IDETextViewFrame :: IDETextViewFrame(TextViewModel* model, TextViewControllerBase* controller, ViewStyles* styles) +IDETextViewFrame :: IDETextViewFrame(TextViewModel* model, TextViewControllerBase* controller, ViewStyles* styles, +BroadcasterBase* eventBroadcaster) : TextViewFrame(model, controller, styles) { - + _eventBroadcaster = eventBroadcaster; } void IDETextViewFrame :: on_text_model_change(TextViewModelEvent event) { + if (test(event.status, STATUS_FRAME_CHANGED)) { + int docIndex = _model->getCurrentIndex(); + if (docIndex > 0) { + selectTab(docIndex - 1); + } + } + auto client = getCurrentTextView(); if (client) client->onDocumentUpdate(event.changeStatus); @@ -28,6 +36,7 @@ void IDETextViewFrame :: on_text_model_change(TextViewModelEvent event) //grab_focus(); } + // if (_model->sourceViewModel.isAssigned()) { //_children[_model->ideScheme.textFrameId]->show(); //_children[_model->ideScheme.textFrameId]->setFocus(); @@ -35,3 +44,24 @@ void IDETextViewFrame :: on_text_model_change(TextViewModelEvent event) //else _children[_model->ideScheme.textFrameId]->hide(); //} } + +void IDETextViewFrame :: onTabChange(int page_num) +{ + int index = getCurrentTabIndex(); + if (index >= 0) { + _model->selectDocumentView(index + 1); + + SelectionEvent event(EVENT_TEXTFRAME_SELECTION_CHANGED, index); + _eventBroadcaster->sendMessage(&event); + + //((TextView*)_child)->setDocument(_model->currentDoc); + //_child->show(); + + //refreshDocument(); + } + //else if (getTabCount() == 0) { + //_child->hide(); + //_notSelected = true; + //_model->currentDoc = NULL; + //} +} diff --git a/elenasrc3/ide/gtklinux/gtkidetextview.h b/elenasrc3/ide/gtklinux/gtkidetextview.h index 9461f0af98..394b89aada 100644 --- a/elenasrc3/ide/gtklinux/gtkidetextview.h +++ b/elenasrc3/ide/gtklinux/gtkidetextview.h @@ -15,10 +15,15 @@ namespace elena_lang class IDETextViewFrame : public TextViewFrame { + BroadcasterBase* _eventBroadcaster; + +protected: + void onTabChange(int page_num) override; + public: void on_text_model_change(TextViewModelEvent event); - IDETextViewFrame(TextViewModel* model, TextViewControllerBase* controller, ViewStyles* styles); + IDETextViewFrame(TextViewModel* model, TextViewControllerBase* controller, ViewStyles* styles, BroadcasterBase* eventBroadcaster); }; } // _GUI_ diff --git a/elenasrc3/ide/idecommon.h b/elenasrc3/ide/idecommon.h index 29440554d2..fab74e14cc 100644 --- a/elenasrc3/ide/idecommon.h +++ b/elenasrc3/ide/idecommon.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // IDE common classes header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef IDECOMMON_H @@ -251,12 +251,18 @@ namespace elena_lang addr_t address; }; + struct StartUpSettings + { + bool withExplicitConsole; + bool includeAppPath2Paths; // applicable only for Windows + }; + // --- DebugProcessBase --- class DebugProcessBase { public: virtual bool startThread(DebugControllerBase* controller) = 0; - virtual bool startProgram(path_t exePath, path_t cmdLine, bool withExplicitConsole) = 0; + virtual bool startProgram(path_t exePath, path_t cmdLine, path_t appPath, StartUpSettings& startUpSettings) = 0; virtual void activate() = 0; virtual void run() = 0; @@ -342,6 +348,7 @@ namespace elena_lang struct GUISettinngs { bool withTabAboverscore; + bool withLargeToolbar; }; // --- GUIFactory --- diff --git a/elenasrc3/ide/idecontroller.cpp b/elenasrc3/ide/idecontroller.cpp index 6ecea0f230..4a2f838396 100644 --- a/elenasrc3/ide/idecontroller.cpp +++ b/elenasrc3/ide/idecontroller.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // IDE Controller implementation File -// (C)2005-2024, by Aleksey Rakov +// (C)2005-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifdef _MSC_VER @@ -76,6 +76,11 @@ inline void saveSetting(ConfigFile& config, ustr_t xpath, int value) config.appendSetting(xpath, number.str()); } +inline void saveSetting(ConfigFile& config, ustr_t xpath, ustr_t value) +{ + config.appendSetting(xpath, value.str()); +} + inline void removeSetting(ConfigFile& config, ustr_t xpath) { config.removeSetting(xpath); @@ -295,17 +300,17 @@ bool ProjectController :: startDebugger(ProjectModel& model, DebugActionResult& commandLine.append(arguments); bool withPersistentConsole = model.withPersistentConsole && (model.singleSourceProject || (*model.profile).endsWith("console")); + bool includeAppPath2Paths = model.includeAppPath2PathsTemporally; bool debugMode = model.getDebugMode(); if (debugMode) { - if (!_debugController.start(exePath.str(), commandLine.str(), debugMode, withPersistentConsole)) { + if (!_debugController.start(exePath.str(), commandLine.str(), debugMode, { withPersistentConsole, includeAppPath2Paths })) { result.noDebugFile = true; return false; } - } else { - if (!_debugController.start(exePath.str(), commandLine.str(), false, withPersistentConsole)) { + if (!_debugController.start(exePath.str(), commandLine.str(), false, { withPersistentConsole, includeAppPath2Paths })) { //notifyCompletion(NOTIFY_DEBUGGER_RESULT, ERROR_RUN_NEED_RECOMPILE); return false; @@ -1039,26 +1044,45 @@ void IDEController :: loadSystemConfig(IDEModel* model, path_t path, ustr_t type } } -bool IDEController :: loadConfig(IDEModel* model, path_t path) +bool IDEController :: loadConfig(IDEModel* model, path_t path, GUISettinngs& guiSettings) { model->projectModel.paths.configPath.copy(path); ConfigFile config; if (config.load(path, FileEncoding::UTF8)) { model->appMaximized = loadSetting(config, MAXIMIZED_SETTINGS, -1) != 0; - model->sourceViewModel.fontSize = loadSetting(config, FONTSIZE_SETTINGS, 12); model->sourceViewModel.schemeIndex = loadSetting(config, SCHEME_SETTINGS, 1); model->projectModel.withPersistentConsole = loadSetting(config, PERSISTENT_CONSOLE_SETTINGS, -1) != 0; +#ifdef _MSC_VER + model->projectModel.includeAppPath2PathsTemporally = loadSetting(config, INCLIDE_PATH2ENV_SETTINGS, 0) != 0; +#endif model->rememberLastPath = loadSetting(config, LASTPATH_SETTINGS, -1) != 0; model->rememberLastProject = loadSetting(config, LASTPROJECT_SETTINGS, -1) != 0; model->sourceViewModel.highlightSyntax = loadSetting(config, HIGHLIGHTSYNTAX_SETTINGS, -1) != 0; model->sourceViewModel.lineNumbersVisible = loadSetting(config, LINENUMBERS_SETTINGS, -1) != 0; + model->sourceViewModel.scrollOffset = loadSetting(config, VSCROLL_SETTINGS, 1); + model->sourceViewModel.settings.tabSize = loadSetting(config, TABSIZE_SETTINGS, 3); model->projectModel.autoRecompile = loadSetting(config, AUTO_RECOMPILE_SETTING, -1) != 0; - model->autoSave = loadSetting(config, AUTO_SAVE_SETTING, -1) != 0; + model->autoSave = loadSetting(config, AUTO_SAVE_SETTING, -1) != 0; + + guiSettings.withLargeToolbar = loadSetting(config, LARGETOOLBAR_SETTINGS, -1) != 0; + guiSettings.withTabAboverscore = loadSetting(config, TABABOVESCORE_SETTINGS, -1) != 0; + + // load font size + int fontSize = loadSetting(config, FONTSIZE_SETTINGS, 12); + IdentifierString fontName; + loadSetting(config, FONTNAME_SETTINGS, fontName); + if (fontName.empty()) { + fontName.copy(DEFAULT_FONTNAME); + } + + model->sourceViewModel.fontInfo = { *fontName, fontSize }; loadRecentFiles(config, RECENTFILES_SETTINGS, model->projectModel.lastOpenFiles); loadRecentFiles(config, RECENTPROJECTS_SETTINGS, model->projectModel.lastOpenProjects); + model->sourceViewModel.refreshSettings(); + return true; } else { @@ -1066,21 +1090,33 @@ bool IDEController :: loadConfig(IDEModel* model, path_t path) } } -void IDEController :: saveConfig(IDEModel* model, path_t configPath) +void IDEController :: saveConfig(IDEModel* model, path_t configPath, GUISettinngs& guiSettings) { ConfigFile config(ROOT_NODE); saveSetting(config, MAXIMIZED_SETTINGS, model->appMaximized); - saveSetting(config, FONTSIZE_SETTINGS, model->sourceViewModel.fontSize); saveSetting(config, SCHEME_SETTINGS, model->sourceViewModel.schemeIndex); saveSetting(config, PERSISTENT_CONSOLE_SETTINGS, model->projectModel.withPersistentConsole); +#ifdef _MSC_VER + saveSetting(config, INCLIDE_PATH2ENV_SETTINGS, model->projectModel.includeAppPath2PathsTemporally); +#endif saveSetting(config, LASTPATH_SETTINGS, model->rememberLastPath); saveSetting(config, LASTPROJECT_SETTINGS, model->rememberLastProject); saveSetting(config, HIGHLIGHTSYNTAX_SETTINGS, model->sourceViewModel.highlightSyntax); saveSetting(config, LINENUMBERS_SETTINGS, model->sourceViewModel.lineNumbersVisible); + saveSetting(config, VSCROLL_SETTINGS, model->sourceViewModel.scrollOffset); + saveSetting(config, TABSIZE_SETTINGS, model->sourceViewModel.settings.tabSize); + saveSetting(config, AUTO_RECOMPILE_SETTING, model->projectModel.autoRecompile); saveSetting(config, AUTO_SAVE_SETTING, model->autoSave); + saveSetting(config, FONTSIZE_SETTINGS, model->sourceViewModel.fontInfo.size); + IdentifierString fontName(model->sourceViewModel.fontInfo.name.str()); + saveSetting(config, FONTNAME_SETTINGS, *fontName); + + saveSetting(config, LARGETOOLBAR_SETTINGS, guiSettings.withLargeToolbar); + saveSetting(config, TABABOVESCORE_SETTINGS, guiSettings.withTabAboverscore); + saveRecentFiles(config, RECENTFILE_SETTINGS, model->projectModel.lastOpenFiles); saveRecentFiles(config, RECENTPROJECTS_SETTINGS, model->projectModel.lastOpenProjects); @@ -1846,11 +1882,11 @@ void IDEController :: onDebuggerStep(IDEModel* model) model->running = false; } -void IDEController :: onIDEStop(IDEModel* model) +void IDEController :: onIDEStop(IDEModel* model, GUISettinngs& guiSettings) { PathString path(*model->projectModel.paths.configPath); - saveConfig(model, *path); + saveConfig(model, *path, guiSettings); } void IDEController :: toggleBreakpoint(IDEModel* model, int row) @@ -1964,14 +2000,22 @@ void IDEController :: doOutdent(IDEModel* model) void IDEController :: doConfigureEditorSettings(EditorSettingsBase& editorDialog, IDEModel* model) { int prevSchemeIndex = model->viewModel()->schemeIndex; + bool prevHighlightSyntax = model->viewModel()->highlightSyntax; if(editorDialog.showModal()) { - if (prevSchemeIndex != model->viewModel()->schemeIndex) { + if (prevSchemeIndex != model->viewModel()->schemeIndex || prevHighlightSyntax != model->viewModel()->highlightSyntax) { notifyOnModelChange(STATUS_FRAME_CHANGED | STATUS_COLORSCHEME_CHANGED); } } } +void IDEController :: doConfigureFontSettings(FontDialogBase& editorDialog, IDEModel* model) +{ + if (editorDialog.selectFont(model->viewModel()->fontInfo)) { + notifyOnModelChange(STATUS_FRAME_CHANGED | STATUS_COLORSCHEME_CHANGED); + } +} + void IDEController :: doConfigureIDESettings(IDESettingsBase& ideDialog, IDEModel* model) { if (ideDialog.showModal()) { diff --git a/elenasrc3/ide/idecontroller.h b/elenasrc3/ide/idecontroller.h index dc17d1173c..851e2d1369 100644 --- a/elenasrc3/ide/idecontroller.h +++ b/elenasrc3/ide/idecontroller.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // IDE Controller header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef IDECONTROLLER_H @@ -27,8 +27,8 @@ namespace elena_lang void saveSource(TextViewModelBase* model, ustr_t name); - SourceViewController(TextViewSettings& settings) - : TextViewController(settings) + SourceViewController() + : TextViewController() { } }; @@ -191,8 +191,8 @@ namespace elena_lang void loadSystemConfig(IDEModel* model, path_t configPath, ustr_t typeXPath, ustr_t platformXPath); - bool loadConfig(IDEModel* model, path_t configPath); - void saveConfig(IDEModel* model, path_t configPath); + bool loadConfig(IDEModel* model, path_t configPath, GUISettinngs& guiSettings); + void saveConfig(IDEModel* model, path_t configPath, GUISettinngs& guiSettings); void setNotifier(NotifierBase* notifier) { @@ -248,6 +248,7 @@ namespace elena_lang void doIndent(IDEModel* model); void doOutdent(IDEModel* model); + void doConfigureFontSettings(FontDialogBase& editorDialog, IDEModel* model); void doConfigureEditorSettings(EditorSettingsBase& editorDialog, IDEModel* model); void doConfigureIDESettings(IDESettingsBase& editorDialog, IDEModel* model); void doConfigureDebuggerSettings(DebuggerSettingsBase& editorDialog, IDEModel* model); @@ -272,7 +273,7 @@ namespace elena_lang void onDebuggerNoSource(MessageDialogBase& mssgDialog, IDEModel* model); void onDocSelection(IDEModel* model, int index); - void onIDEStop(IDEModel* model); + void onIDEStop(IDEModel* model, GUISettinngs& guiSettings); void doInclude(IDEModel* model); void doExclude(IDEModel* model); @@ -286,9 +287,9 @@ namespace elena_lang void autoSave(FileDialogBase& dialog, FileDialogBase& projectDialog, IDEModel* model); IDEController(ProcessBase* outputProcess, ProcessBase* vmConsoleProcess, DebugProcessBase* process, - IDEModel* model, TextViewSettings& textViewSettings, PlatformType platform, PathHelperBase* pathHelper, CompareFileDateTime comparer + IDEModel* model, PlatformType platform, PathHelperBase* pathHelper, CompareFileDateTime comparer ) : - sourceController(textViewSettings), + sourceController(), projectController(outputProcess, vmConsoleProcess, process, &model->projectModel, &model->sourceViewModel, this, platform, pathHelper, comparer) { diff --git a/elenasrc3/ide/ideproject.cpp b/elenasrc3/ide/ideproject.cpp index 356b2e86b0..b86c95e780 100644 --- a/elenasrc3/ide/ideproject.cpp +++ b/elenasrc3/ide/ideproject.cpp @@ -20,6 +20,7 @@ ProjectModel :: ProjectModel(IDEStatus* status) this->status = status; this->withPersistentConsole = false; + this->includeAppPath2PathsTemporally = false; this->autoRecompile = false; this->empty = true; diff --git a/elenasrc3/ide/ideproject.h b/elenasrc3/ide/ideproject.h index 727ec92072..9d84332621 100644 --- a/elenasrc3/ide/ideproject.h +++ b/elenasrc3/ide/ideproject.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // IDE Project Model header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef PROJECT_H @@ -12,18 +12,38 @@ namespace elena_lang { +#ifdef _MSC_VER + +#define DEFAULT_FONTNAME "Courier New" + +#elif __GNUG__ + +#define DEFAULT_FONTNAME "Monospace" + +#endif + + constexpr auto ROOT_NODE = "configuration"; constexpr auto MAXIMIZED_SETTINGS = "configuration/settings/maximized"; constexpr auto LASTPATH_SETTINGS = "configuration/settings/last_path"; constexpr auto LASTPROJECT_SETTINGS = "configuration/settings/last_project"; constexpr auto FONTSIZE_SETTINGS = "configuration/settings/font_size"; + constexpr auto FONTNAME_SETTINGS = "configuration/settings/font_name"; constexpr auto SCHEME_SETTINGS = "configuration/settings/scheme"; constexpr auto HIGHLIGHTSYNTAX_SETTINGS = "configuration/settings/highlight"; constexpr auto PERSISTENT_CONSOLE_SETTINGS = "configuration/settings/persist_output"; + constexpr auto VSCROLL_SETTINGS = "configuration/settings/vscroll"; + constexpr auto TABSIZE_SETTINGS = "configuration/settings/tabsize"; +#ifdef _MSC_VER + constexpr auto INCLIDE_PATH2ENV_SETTINGS = "configuration/settings/include_path_2_env"; +#endif constexpr auto LINENUMBERS_SETTINGS = "configuration/settings/line_number"; constexpr auto AUTO_RECOMPILE_SETTING = "configuration/settings/autocomp"; constexpr auto AUTO_SAVE_SETTING = "configuration/settings/autosave"; + constexpr auto LARGETOOLBAR_SETTINGS = "configuration/startup/largetoolbar"; + constexpr auto TABABOVESCORE_SETTINGS = "configuration/startup/tababovescore"; + constexpr auto RECENTFILES_SETTINGS = "configuration/recent_files/*"; constexpr auto RECENTFILE_SETTINGS = "configuration/recent_files/path"; constexpr auto RECENTPROJECTS_SETTINGS = "configuration/recent_projects/path"; @@ -58,6 +78,7 @@ namespace elena_lang ReferencePathMap referencePaths; bool withPersistentConsole; + bool includeAppPath2PathsTemporally; bool singleSourceProject; bool autoRecompile; diff --git a/elenasrc3/ide/ideversion.h b/elenasrc3/ide/ideversion.h index 62ed0a82af..df3abe291c 100644 --- a/elenasrc3/ide/ideversion.h +++ b/elenasrc3/ide/ideversion.h @@ -1,2 +1,2 @@ -#define IDE_REVISION_NUMBER 21 +#define IDE_REVISION_NUMBER 31 diff --git a/elenasrc3/ide/ideview.h b/elenasrc3/ide/ideview.h index 877dffe934..282ed81451 100644 --- a/elenasrc3/ide/ideview.h +++ b/elenasrc3/ide/ideview.h @@ -76,8 +76,8 @@ class IDEModel void changeStatus(IDEStatus status); - IDEModel() - : projectModel(&status) + IDEModel(TextViewSettings settings) + : sourceViewModel(settings), projectModel(&status) { status = IDEStatus::Empty; running = false; diff --git a/elenasrc3/ide/sourceformatter.cpp b/elenasrc3/ide/sourceformatter.cpp index d029c7de6b..2b4d6ec8d7 100644 --- a/elenasrc3/ide/sourceformatter.cpp +++ b/elenasrc3/ide/sourceformatter.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // ELENA Document formatter implementations -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "sourceformatter.h" @@ -25,16 +25,17 @@ const text_c lexComment = 'j'; const text_c lexComment2 = 'n'; const text_c lexDigit = 'p'; const text_c lexQuote = 's'; +const text_c lexChar = 'u'; const text_c* lexDFA[] = { - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeqaaaaaeeeeeeehooooooooooeeeeeeabbbbbbbbbbbbbbbbbbbbbbbbbbaaaababbbbbbbbbbbbbbbbbbbbbbbbbbfefab"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeqataaaeeeeeeehooooooooooeeeeeeabbbbbbbbbbbbbbbbbbbbbbbbbbaaaababbbbbbbbbbbbbbbbbbbbbbbbbbfefab"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceaaaaaaeeeeeeeaaaaaaaaaaaeeeeeeabbbbbbbbbbbbbbbbbbbbbbbbbbaaaababbbbbbbbbbbbbbbbbbbbbbbbbbaeaab"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceaaaaaaeeeeeeeaaaaaaaaaaaeeeeeeaddddddddddddddddddddddddddaaaadaddddddddddddddddddddddddddaeaad"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeeeeeeeaaaaaaaaaaaeeeeeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaafffffffaaaaaaaaaaaffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaa"), _T("gggggggggggggggggggggggggggggggggfggggggfffffffgggggggggggffffffgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggfffgg"), - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqataaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakaaaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), _T("jiiiiiiiiijiijiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), @@ -45,8 +46,10 @@ const text_c* lexDFA[] = _T("ppppppppppppppppppppppppppppppppppppppppppppppppoooooooooopppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaafffffffaaaaaaaaaaaffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaa"), _T("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqrqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"), - _T("ssssssssssssssssssssssssssssssssssqsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"), + _T("ssssssssssssssssssssssssssssssssssqstsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaafffffffaaaaaaaaaaaffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaa"), + _T("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuquuuuuuuuuuuuuttttttttttuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), }; pos_t defineStyle(text_c state, pos_t style) @@ -65,6 +68,7 @@ pos_t defineStyle(text_c state, pos_t style) case lexDigit: return STYLE_NUMBER; case lexQuote: + case lexChar: return STYLE_STRING; default: return INVALID_POS; diff --git a/elenasrc3/ide/windows/Resource.h b/elenasrc3/ide/windows/Resource.h index 4850a6ec91..8169753621 100644 --- a/elenasrc3/ide/windows/Resource.h +++ b/elenasrc3/ide/windows/Resource.h @@ -38,6 +38,24 @@ #define IDR_GOTO 216 #define IDR_FILETREE 217 +#define IDR_FILENEW_L 218 +#define IDR_FILEOPEN_L 219 +#define IDR_FILESAVE_L 220 +#define IDR_SAVEALL_L 221 +#define IDR_CLOSEFILE_L 222 +#define IDR_CLOSEALL_L 223 +#define IDR_CUT_L 224 +#define IDR_COPY_L 225 +#define IDR_PASTE_L 226 +#define IDR_UNDO_L 227 +#define IDR_REDO_L 228 +#define IDR_RUN_L 229 +#define IDR_STOP_L 230 +#define IDR_STEPINTO_L 231 +#define IDR_STEPOVER_L 232 +#define IDR_GOTO_L 233 +#define IDR_FILETREE_L 234 + #define IDM_FILE_NEW 401 #define IDM_FILE_OPEN 402 #define IDM_FILE_EXIT 403 @@ -171,7 +189,6 @@ #define IDD_EDITOR_SETTINGS 1700 #define IDC_EDITOR_LINENUMBERFLAG 1701 #define IDC_EDITOR_COLORSCHEME 1702 -#define IDC_EDITOR_FONTSIZE 1703 #define IDC_EDITOR_USETAB 1704 #define IDC_EDITOR_TABSIZE 1705 #define IDC_EDITOR_HIGHLIGHSYNTAXFLAG 1706 @@ -186,9 +203,12 @@ #define IDC_DEBUGGER_LIBPATH 1715 #define IDC_IDE_AUTORECOMPILE 1716 #define IDC_IDE_AUTOSAVE 1717 +#define IDC_IDE_INCLUDE_APPPATH 1718 +#define IDC_EDITOR_SCROLLOFFSET 1719 #define IDM_EDITOR_OPTIONS 1750 #define IDM_IDE_OPTIONS 1751 +#define IDM_EDITOR_FONT_OPTIONS 1752 #ifndef IDC_STATIC #define IDC_STATIC -1 diff --git a/elenasrc3/ide/windows/elide.rc b/elenasrc3/ide/windows/elide.rc index f8648677a6426bd1fb8b54ac8b68207e049842c4..98a4b752b1de8e40886eca2576101acb5d48d4df 100644 GIT binary patch delta 822 zcmYLHO=}ZT6umaqnU_h1R7s_#n#7NVS}`%HiC9WP)6_yqrkOM?h{TdQS{Rd{DI&OV zp`jI}g)8pexv?nO_c!Rur3h}^)r}inc-~|t;W6_b_uO;dJ@>x1-$uH>Mm|mITvS4$ zMDw&tbz0*0T8dAp`jI+E{S!Q^hJ0T1xf*h#B}L_ZRUIHXq4J@sx~ML61soD2__v62 zPW06xY>A=T2XWlVkMN%b-BTKCkWDRmO!p{{lTEUU=s;~*yR0;5i#kp`!h8N>9#b^H zYtvH)nFt!-n^c7>w|cEj>(K2$*>R?=P>Bju_Hcftx%F!mu!hLZzAI57$>^(1k8V-Z z)seT9$r$MD1-w4&2V}qEYhgD0I^PXWu^t>^swh(pH&viB%t^bqEkIN1_OVc49Q^az zeR%BPtCQUm`tpUa2|G5v2Es8a0%}r+<0q0FN{uT;2$ZPG`Sj^tE@c^S!bL}cyI|c77Oz%EkT)VR@@2nffywDh wTxPZKm+zxWx5(u0ufyR*v}q1zRxo$@V)DQZ{=0hz@ZQ4FpOIt+#kWSV#>?#T`PEX?K%29p!}Bqs|@RGJ(#!GhV6 m!D#aQ2>rviewModel(); - // update font size - for (int j = 0; j < STYLE_MAX; j++) { - defaultStyles[j].size = viewModel->fontSize; - classicStyles[j].size = viewModel->fontSize; - darkStyles[j].size = viewModel->fontSize; - } - // initialize view styles reloadStyles(viewModel); @@ -252,7 +268,7 @@ ControlPair IDEFactory :: createTextControl(WindowBase* owner, NotifierBase* not notifier->notify(&event); }); - view->create(_instance, szTextView, owner); + view->create(_instance, szTextView, owner, 0); frame->createControl(_instance, owner); return { frame, view }; @@ -260,7 +276,19 @@ ControlPair IDEFactory :: createTextControl(WindowBase* owner, NotifierBase* not void IDEFactory :: reloadStyles(TextViewModelBase* viewModel) { - _styles.assign(STYLE_MAX + 1, _schemes[viewModel->schemeIndex], viewModel->fontSize + 5, 20, &_fontFactory); + // update font size + for (int j = 0; j <= STYLE_MAX; j++) { + defaultStyles[j].size = viewModel->fontInfo.size; + defaultStyles[j].faceName = *viewModel->fontInfo.name; + + classicStyles[j].size = viewModel->fontInfo.size; + classicStyles[j].faceName = *viewModel->fontInfo.name; + + darkStyles[j].size = viewModel->fontInfo.size; + darkStyles[j].faceName = *viewModel->fontInfo.name; + } + + _styles.assign(STYLE_MAX + 1, _schemes[viewModel->schemeIndex], viewModel->fontInfo.size + 5, 20, &_fontFactory); } void IDEFactory :: styleControl(GUIControlBase* control) @@ -404,11 +432,11 @@ GUIControlBase* IDEFactory :: createEditorContextMenu(ControlBase* owner) return menu; } -GUIControlBase* IDEFactory :: createToolbar(ControlBase* owner) +GUIControlBase* IDEFactory :: createToolbar(ControlBase* owner, bool largeMode) { - ToolBar* toolBar = new ToolBar(16); + ToolBar* toolBar = new ToolBar(largeMode ? 32 : 16); - toolBar->createControl(_instance, owner, AppToolBarButtons, AppToolBarButtonNumber); + toolBar->createControl(_instance, owner, largeMode ? AppToolBarButtonsLarge : AppToolBarButtons, AppToolBarButtonNumber); toolBar->show(); return toolBar; @@ -476,7 +504,7 @@ GUIControlBase* IDEFactory :: createMainWindow(NotifierBase* notifier, ProcessBa int editIndex = counter++; SDIWindow* sdi = new IDEWindow(szTitle, _controller, _model, _instance, this); - sdi->create(_instance, szSDI, nullptr); + sdi->create(_instance, szSDI, nullptr, WS_EX_ACCEPTFILES); VerticalBox* vb = new VerticalBox(false, 1); @@ -495,7 +523,7 @@ GUIControlBase* IDEFactory :: createMainWindow(NotifierBase* notifier, ProcessBa children[menu] = createMenu(sdi); children[debugContextMenu] = createDebugContextMenu(sdi); children[vmConsoleControl] = createVmConsoleControl((ControlBase*)children[tabBar], vmConsoleProcess); - children[toolBarControl] = createToolbar(sdi); + children[toolBarControl] = createToolbar(sdi, _settings.withLargeToolbar); children[contextEditor] = createEditorContextMenu(sdi); children[editIndex] = textCtrls.value2; diff --git a/elenasrc3/ide/windows/factory.h b/elenasrc3/ide/windows/factory.h index 3276e8d7da..6c0775c310 100644 --- a/elenasrc3/ide/windows/factory.h +++ b/elenasrc3/ide/windows/factory.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // IDE windows factory -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef FACTORY_H @@ -47,7 +47,7 @@ namespace elena_lang GUIControlBase* createMenu(ControlBase* owner); GUIControlBase* createDebugContextMenu(ControlBase* owner); GUIControlBase* createEditorContextMenu(ControlBase* owner); - GUIControlBase* createToolbar(ControlBase* owner); + GUIControlBase* createToolbar(ControlBase* owner, bool largeMode); void initializeScheme(int frameTextIndex, int tabBar, int compilerOutput, int errorList, int projectView, int contextBrowser, int menu, int statusBar, int debugContextMenu, diff --git a/elenasrc3/ide/windows/icons/closeAll.bmp b/elenasrc3/ide/windows/icons/closeAll.bmp index ca23d93f0fb8a88e77fb6a42073c14b81bb48c1f..68ed8d4ddf5523c1f37762df73a71589055089b5 100644 GIT binary patch literal 822 zcmaiyA#cMl5QT5*9|)RC114>Mpi*hzq>{qYz(K>(!oa}L!a_q!Lxq8criFol-m`Ce zisUIh#iz^pyBFU%&0)8ZY&-aOtm=2Y$TsH%`){whG$Ha`SP0?%XZ`I_pPV!f{&Eck zn-XASwgk8L+C1buNgGhLETQZ$49Y{Z9p>sB#o$RL$nX=CbUmmX41NHwFl-C} literal 1334 zcmeH@Eo_5O6opT_Hf4-ubd2n$TN&NY+Z3)zZRL`g$yp>4Sz9rIY^Jc4l~0mXA(2Qd z5=o}sF1)QwwSMVM4!rZelgs5!U&me4HSPdUbkcv+f+9gnzUpUnCVB20o);htL)dQ| z!GeQxj<3%Ttk-MU?-AWah@uF#8zYWmJbMX}B*DZ_k)|o&W|%KCWLXB=&#_qL$nzZV z3t(12CryF^MNz;FOZdwY0WVROC1nKkN;3g_F7UDtSS12H6%b;(FpYL*cJzCxa$%9!)O7`t>NB!4ixx9_eL z3CSOx3?FZf&5dUr>Tha|x2(Z{HJ&Ur-1wSWs?p?$s)qcyrK??4ZFh~|VTe(-8eU_6 Qpd7Y=(*{v+ie}RTf6mj{IAC~vl}4$(w>}q?zzA3 zJOA^Y@7`sr7d*j4Z2{Uh@PFms|1{=V^kBF@JAwY`0K?SZ+xUFGKp>FGWJaU0t*s3m zTnYqyiICsKHE=RjdA;>$VaKve_NkRTCaHo+;ytsfYH^li|5;;6bz8lNYZh0>;iCir zCDT?am1?zG@LOA3(a~x(T8%~~SN~b3%P%o*I0S02d%Vm(Ka=HUzI8ImMrJve@RjtlT;+jttz-E5m>O!eTBFe* zW|2q)FBKIPrKP1cH8l>0gYs2oZ&rcfgUsfngXV?D+%M+(AK4#f_C=UIL1wpy+1kx) zFg})|e0@8+BvVYW2sOsn>2xNO343ZV7|@4{YuBz}72RE3lwT)ztvo1u?He{Z-=0$z zNxMPT6_YhZB)KTErf7IkfhXaRbJ`Z;!d`sW`uC+<})$zY*2*vO4IwR^_Y1~!g=+tPcwh~1b|w>(?<#Yso% z1>cdIB(Ihnt|Z$olV$mL-^yuEI;7k3qw)Lm7VI6)q{rilQ#%&zME-!=!?LEI3%Qgd z;*WC_Ymb{V3wsWiy0VL1TMHb^k6MzlbsO@u`6Z^C0xP!lVfn#8@Q&Ntq_CVS6sH`j zS(M%|Z>MZ-YSWx;+}u=d@gC*o6ULL5%_tzKQ8-`Vm|{S z6XH(}aPOx{7wi;%v{#h=i}rj)kASnIM#+f9+}k6O!>YV!@g zS)z7Y>^{^eomPuVJ2ieJ5($r5FcJzxLc=8Fj|6?;zz}|fgt5S3|DeI3hxk+A10D

      bULvdNP)ZE-Q8BJ72_Qp9dst(sF@Opq^_>+fqXy^6@sCw7K_Cwwlqj6fPQs# zb!BBG>I~)p3q!rdILIjY6Zv>{yxJopBX|WMHXL(2h+E(wPOKg2U0z;({rdH*SFe_p zmB9r(Vp{>nEg0Yrwcx&KIjZk59br=C0?k4glRU3m) z34AOBIzw=@?d|PKr4nmFz*riV10YD%46h+^(9|)RC117CMP^mPq(te;cu+XryFfee`Ffhubx+=i!xt4j4bst9yT;U8oc0-`}`%foPhhZQGWAB>H)GR@5krqF(?* zU|mVwp!e-ui;b>^T1_W)llln{&-Tk!S4RTPFF_^c^+RhAVhqX76?SQU@mZ+)Ja?l# z^{x`GzPV#(P)YsSHXa@Mk7C7=adkr4{bfNVGdYW_MAlX!D`$~NBuf<%iNqq2 z$hZ4wS30r(pf@@1-5=+^`{0Jz`{V?5OxnPZGG!+Lr&~kVZuQD@QV;|P!w^vv0kasG z$GH9=ea6^qHnb6C?>eb5o2KDRGK4O)>Q{WLXBdIaWaqKg^NmIdK8Y zE3gg=6h#4eC9o`^kfwf#vMk|#Rq%oeepI2VDym^nxRwmoiebKH2vdeAV_>XN9Do1e zL+_Y3b2`rAIE(-O0lBa4;#?9XMV3`(8+!NVuGhZWvt+$I-S#BThGA%$_)2y6;@N9mAmo}y7lF> diff --git a/elenasrc3/ide/windows/icons/closeFile_l.bmp b/elenasrc3/ide/windows/icons/closeFile_l.bmp new file mode 100644 index 0000000000000000000000000000000000000000..03dc8d6c929b9327e90294a6177936ca73e98022 GIT binary patch literal 2102 zcmaiz4Nz276vzKZK{PW>(LR(UKQV0+F*HQvThc{AKvn@=1aT3Sb;81O0!K}voIu6! z6C^7f2^rB^Qju&h`j9pyTM+{R*_B;kMUhqa?RMYlb7q<6^m}u5&%M8M_THU&$3N7w zKWun90B$UEeG-Hxg6%(ro@TIGt>B+=vl`*%e-o1e+AxWIkDPJ|qdhd3IJ*%WKkY<# zk{&Us2Dk;ZK&vXmh;e`5t7DxgRdr)ZP#bO=IrNw;kf#~Ya`GUCj;hAi9a@y1xesF( zhsb0-nojJ)pyB6GebIytR)4+pOAHvK!shHY=sP$_SG1%4SRSkv4i5cJz(4c~y1P02 zQfq=_t`=8{cf!g&LZ3dzG0X3F=nW5Hyko}s-%N0yr^V&3zkt>J08^(`L9c&+rsf{F z`&`1NZ8xDV`W)6rJ*cc~$JP3Km?*h`Pj(w|u^=0khuv^-`2nX--@+)D3jBItJ1h_G zV#4?ejP<&P3wyW1V(P+K)eVdtqr%9^wfK3@W>|WRsM?hQ%l!_V$=L);w*eJ9Ho|hR z9p7ia56fL0%D1P1>uSUCt?R+vX+_EAb>NK6IQnr4xXv5+=A&eA9gQgZAPL;<>nPZe z0M2j?2iD8M>91n%x@F+n|3O|#49vIw#!iI{X5D4vu8Kx!QV5PFh2lbP8X7AO;$PK% zRDYI&y-{8`zIp)~%6FqA-XEvli$=@2LTGC%p}lwpEtQ8*o+8DTxzlhYJ{UiK7>8!I z*L=PdH-0KX^Vx%_*svIR5i@akSs+fWk3dJmU+nky;rhuuoLm!%-HT>mPqa5m6N1^9 zYtd2vC%W5PQJuXSC2~J(o9~W-r9R9Dp)x}bbwLKZ&n~DBWw7;fwjY4~i@lH=?unu$ zv+-@*9DK+64zoNv)B}n6GI*DG!`#{mv(W&vfe#(~?|igEnpg~}q69Ur&d?nxM8ldy zXcV!~B+8(XM?w=Di8@&r>LR763kyM=G!Sa3FVulEq4u2)=Ue3nVPi0wMOBfXZ6IQ6 z{m`H*N0U#N%^zVke56m80SmNHx;~z(XU^1|8mk$zp2-LfAT=oh7f5BSglWQjUCeK73i;=l@8320~vdiIOV# zwX{wIS}XVzS|b9b2tJusi$KYOUquQLXqDhsQj!R?Qt%0sC;}x2KAu*HK=FcKPI3`w zx!~hynFtgo_!x>6fno%|gqDgxO9UTHG7%_R@KLl_1d0-T1VxHK5rPk=MIunR;1^Pu z2((b}^Ju;u(ohLw;_EIi4PL<41k+qQLY``;{_isHNB(w5Bmsdze7Dz-z7EXKB5yk+ zlG)@lhiM{TN9L!~+jdAKo-=6XJ50af!TTxnrXB2RZ%rk4qG=wEydO^!?BH+iHi>ml zcC>ldUavoYwJ~gO?6}8%R4>o;%S5k@reOnZ{UdsLn|@{Jz+v?2NdEj6dNJ5(2)#Je k(Q)7~=i$8XjZ^;t&#{wP!SjxTdP{!Y*TJUQM?bdu59h*uX8-^I literal 0 HcmV?d00001 diff --git a/elenasrc3/ide/windows/icons/copy.bmp b/elenasrc3/ide/windows/icons/copy.bmp index 3ca261d3fb5a18a8770872a8dd3a25065c9ab1b1..ae6b2baa0a5f2d51a33523c36a895cd4d3bd2eb5 100644 GIT binary patch literal 822 zcmZ{iA#cMl5QSas4-8fN1Cv%*QfV}NBrr5EFfi0Gu&}hSFwj!bK|@1R!$8CA*=Ji> z(pmQDjQcxG(Vi^T>-ggm~@-$wqbG)SeK_r0yIxWwXPd zsy!|L4C<>rue&pFZ?$)JaR$law6}!KmpqOxJW4`gn2D#cMHSm)w_84yWPYeOX6+=C zeo~Hpj0%2+N=KgEa6UM(nDFGz!IyP$lBzKhXgGD%Dp z2mb$K+mYQwagI@H29#kkqeJFxLNDzv`LW-iIC@PAK zBr3}Yu_9q9BR>@NK``utf>LHg7E+sgD>Ex*w!3$|?p)i6$p3KWo_l}io;&}US-jdE z1tE6?;N)3CZxDI`U+)w3W$^p`2wd;)Uq#1*aVGxojU;i+ec_$JJ9yH8c!}9LUZL=_;n4{M|VN*`3$|g6MEN2 zG}qq3{Zo6L3sK0z1`p<6El^ucpqYF=YFa5g@wP#BB z8J|#dvY7Yz0MD`A(D`}QM|R@&!6Im^9hLicK=Zx9jeP~sI$xuF&o*eEUg7ett37>=nBTMjSNOhY!&6?pHrwQoY&M!9xb&4y z(^XNr;L_JLN>fGC1ed;2$>j>QpX_o`s^HR>ot&!3F1YlSLUF1nMR4gWnH&y7e}{vT z1(&`ODM=M23NC$3p{c59ir~`MB#Mt0{o}b3gantqM$?#(#>R~sKVhQa(${d~?_(b^ za#XCq7U^rKkq@&)#{{uO`ieC2!BIncu|@i_8Wk}}VvCtCSzzW%ax-6&oB5L5%$MY5 Pz9cu=vKo9z{@3w0!ACT7 literal 0 HcmV?d00001 diff --git a/elenasrc3/ide/windows/icons/cut.bmp b/elenasrc3/ide/windows/icons/cut.bmp index e0b34d8d27784454d4f39c11d0f44b86530fa877..03486f17fcdef1eab29df41ba01298c4b0646ddb 100644 GIT binary patch literal 822 zcma)&A#cMl5QQ`C4-8HF1C#a(DvcUi8Zj&lEG!HSGz<(i3^Y7x$j~q_v@o!ApY5t@ znO8yRRT2XpZ zT96>T%jKZ8qyoDbX7fO%K6s_m<6&V1u1&TzUa>Rn*d(6^G9lSgHyN5Sx+6D;HUX<8 zzdoc^dlzg+iE)yCj*bxknPth(C6a_)_~&^N*N7kfB^Qup7=at+JVoC(8|2%R3>N=W z^iN7;=0zg literal 1334 zcmeH_t#86m6vYn<>`?;ypfCbrV-vtgDi)HGC6FbRBr`~CB@$VStVCifE1$dx>d7Z7 zYb%jRc1!u#{)X|AU+=l+-20L?b-wKa4#&;|Jys7#awuj&E-Qy;s+n-*LI(@TwFgQG zJg8s^8Ti<2Hc+7t3Rlo_#dVFC)`%#;RtF#%LQ#lVhj6A6Ggrc$OAtvUTEdwS`-BNI zoiQ%)3^OO5BP=|EwoiGCz;mvs9~9z z@!ILMgxL|bZq_%t%~7@56)&Bv@0y}E%ni+6BkP~7_cyzIH?rDUFB+C*m&f`0V=F|h zS<4S@&TT5b#!r6?V^A9ZHjKe-v2R>fjJ^=X%H>MqQHXlsvSCzswvO|HQ98?msGmlE E015-e8UO$Q diff --git a/elenasrc3/ide/windows/icons/cut_l.bmp b/elenasrc3/ide/windows/icons/cut_l.bmp new file mode 100644 index 0000000000000000000000000000000000000000..773a9f06b614b31f0bd764207cb6d258ec93998f GIT binary patch literal 2102 zcmb7C3slop9RB8|5;Lu=l@(@I2tm?IEFY+(SQcs~W*JGQf=}K|o=)B*zM_#qfrs)Y5g0@ zfj%Vqdf`aKPSl^RL48#T2Jf`tK(Ifu!iBU)38g}TWYRgi!qMA)na)-~5*h+YSO^*} z{EkcKs-WoUK!z{~SN`}78IfVgi;sr<))i>fDx?GokS~shhR$khyo#p!b5P!sAullw zEe)5TQ4SzSEW)uA5#${Wr2CO5@J3PUUZ@pvs0aI?Ca<%-4egifXzy)^1AHKBZiITE z2kQPFoXnP>T(S@Sva66aT|=CoCrS_Phg#lExPyD$UGQG(jDN5H31!bMB>4NF_jWVX zeVtJEcA}=F7-x#IFd(~zSYHoR98F+oW1Bws+D zAI&|agJ`ZM?L&MQK|t6{o;!J7gb32!G`A795<&?(wVXQZX$BE?5PS%M1Q+Ui&~&4G z3r#>H z6UI(7>@)6Ywf@YJGQG$C->RvuJo}TrDygil)${waT3TFq>U6nIq@O-@ra)TFEtE=6 zkUUwYEtHh~SixAOw2D)Z7U;zBA{s>{I$j{<Gq4%SMr+%epBp+lqjW8a9a7*s;}8MtG`|8NFc0lXr%^ zci(&8X4(hC3Kr&;=5HAsD{D*hw+)KOYg2eUlh+N-8*iHPrc5Kng0q$KW)l;h9en!c7o}19AmWUm?t@sv9V8$8_zXN9^)$Fk3TWY L7&T03h2HrOq3`C* literal 0 HcmV?d00001 diff --git a/elenasrc3/ide/windows/icons/goto.bmp b/elenasrc3/ide/windows/icons/goto.bmp index 36ddaa04222576e42ffdcaa5354512c03ecd9232..32c08cc8237da36f30a4da09588e6d214e021c51 100644 GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C7H0s;tBOG|M1XLNHEf6W78Z?AU3wi3{rU4nmxCdE1oQ>&tOc9b41GPicW153Y1gIXD H6ivkecU1zp literal 1334 zcmeH{Aq;~s5Jf-9mLQR{xY?N{*h!L^NyH2iiNqj~$Vu!Z5=nwWR#sv=S2;1ku4NF$ zvSb1`E_uECch@#)E8nu`xX@HBwP0yNhULK8vc5hM}EF~teR2}F@X78l4egRHNR zEGG)wd5N}d7nV1eWd_c-$1Lak!%Uh#8YX?1BxoPbBGamFn;Et9k-Ax!!>Q diff --git a/elenasrc3/ide/windows/icons/goto_l.bmp b/elenasrc3/ide/windows/icons/goto_l.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6a98f2f01bf60ac5f7afc79c5ba3008a7cf8b49f GIT binary patch literal 2102 zcmb`GX;)KM6oy~!bwq8XsEi2#8A1Y>1W1?+5Htc&6aj11C>23eoY7QeP!ttyD^=Ut zQmsP;g3N|N!~qAe%c;XB{Q-XVAEfU^KwVP%p*>l9t#kK&_Pd9yV_ssIg5hJB0H}CV zj+h%p0`!j^x3L>sE*GR9$^~G*8H(`Sc-@X2B1_RznfNy!iO~a3kUb0XmBrzhG>uM z@N15NUrP-9TVk>DK?%}Yvw*zBjoLp#UZgj2O9_Nn090)d)LE{x$=%UC_3Vy=#(r0 zx;`tmKdFS*sQ}Iv%{cwn6A>VpQ?ewedo9@gdo|{sQ?srSO8S&t^P%iEAyBfOWQ5*G z!?r)F5M6I#ZUO>(lW8dk>P`UR8b6Jf!S2Xat%6aQKZv$s- zw^yYmobRJ3MN zaEE5P#!$a%7J15Q%`zeV)YCN6_eq% zj}OAmhp=COtF{&{rxPa3f(;6k@dedEk3J;f1uS@tJh+0l!j)bPSIK$uUF4sVSCdaB zpG$rd`3mx9$TyMiCV!9oGx9IVzanoUZzEquzK(n!`4{A0ljkc;r5(bn*4e4UF4sV7yjQf z@Go-W-H!ue*`1F9qND2e#{kjcD7}^R&jjO+n*MLz0mSzYyuy#d6H3a>kBp%7HzZ?Z`!=&-AeW^_w8p~ zW{C`pnx|bF7oU=1UYTLd&R(9A`}wNXYiw)Rc`>eWpD*)N21aRhM3Pg?<_zmH3CUaW z*|5G^9gA$8VgG!jMFqy*R{er_S)6zh@dPoig@eaAiKe{D zSJuf=w}{A5!4dSH!^cye082Z8T}0%V65wyeqtdNwg()x=;9*|s78s78`D*`KwOJ#; zcSiFK{?Qgk(kjOwJVh*NJt31JoTX=#$R;#=Z8)E{z^MJ;{oF@Lsq=S(V iPZg!qFbw|t`Xs@`!;B9HzArhMz;49CAKg0}ME(HI(2i9A literal 1334 zcmeH_p>Kmg6o-GXu9U4~q!}Aqxl8IcS<|F;a>>kOZ6y+kMIw>4NFpIz2%oEcaOn=~i{(z?0m(W#3y&>g&m~+E2=H}p6#*!}$b@16EowJm| z^#_X^qx|aDdcGgk^VLGv?|%Dp&KS2x&i*=Mjx)*&T@OxY9dS)rd#-3h8KVhPH QEp)ga=Td3oCq!2J29Lb&lK=n! diff --git a/elenasrc3/ide/windows/icons/newFile_l.bmp b/elenasrc3/ide/windows/icons/newFile_l.bmp new file mode 100644 index 0000000000000000000000000000000000000000..78a1e3098996fbc1abbef90c91973216923fea8b GIT binary patch literal 2102 zcmb`FYfMvT7{~ul#~f~*H!4TOx}Wkj4B6C)WV;=E#*nH!t& zntH)B!LpKRG_Fp(G1!_cGrMKrg%3LBK#QWbC{kI)DxA~32VM)IubUtIHUE>R&+k3& z<(!i-KQSCVB!&U8tkUxkxM2Mt6s!;k1fcwGRomgNsX$BBS738q`Oy8v341xwnmh%S_~Zab1T_~09T9{#@9fUp94Pc*EjWl`SYC>D)uWY<0nY@8BjUn`^v2fyR+clpM^VDv!OH0M#}1Zm>n!`GrYA0&_%64_rgLHf3Xq`j*p>kT!p+bYw%v& zTI3b1gRy))Oy`PV_aB8xcMRSIl~`gs&el1BFwZIEOghcJ(eI%Bx*C?hYk-&^V2yJ^ z`+gI&i>hE>cr|#E!jrjpe2%1SphR%a;NWLmsQ#b%PlDe%kHpO5eh$qQL36k_(QFZ9 z;y#PAMNk&^nKVlTWpbZEGeuAa_ePo_f{fg!QMw39<35$tA}E#n6dECdQn*j1=^`kZ z`)GPc1VwW{jgmyrH0~2AMg%2tpFnSmpakwC=`9fy$^BFsD}ttSA5T+6P(1gO=}i$d znR^4pi68^_6KRqNn#g@Dy&-~PxqppbAHalOxYtqC0HVk0W5&HYp8Js@pMT^i?dUPD taIG2|;)e|%5utgkRWFA4m((v032N1#5dT8>;6AN-E`+e>`|1BK{{@ z(yr62XDd2?_x$Ya-?xvIjxE+V%%^2OR4-buu>bmO(+X8pJKFU8uYi5(0LhYvD2|JI zRmTFgB#p|aym4&&&T*3L;t$!fG%P2UBTG%PCke9R2iO;2tKD6y2EZN`I|W&rdW^Bg@n2}tXJ?!lJOUqgTDZu6;qA? literal 1334 zcmeIwy>HV%7zXgyCB+S2s#PTgrG|bG(b5wrrcEg{k!%)lF2xWy^{yaQ8L`5Cc_rdF?QPz9NJnPIIE?3+CA{; z4OKJima2J5b&+D75-(=7TrNqK8Obsy#jQE%dI9%Pk`^V+I42`Oa>}ZTI2Zx4qByT9 zuWG7l5H)5s4KhK4T+pR8hXNLGFDNbr<+UKK1R016NjD2gX({QBOPoo}L8F%n?*^er zX@!}hsMZui3RAchn(p8aq%egUWRTk~(IJO9EWl_mxFZebhPX0RX+r{(WejOBz>BO| z?f%i@H~1g_f!)1-vg^8gaWo!}MpswE^Yfp+>%P4X(Y}BCdU5vU7y7#-3`0A(yg0Lc z-}dnI^!@9d?KeJc>`x|1l0;2npE(EDC&wQ?vq=+w;2b35@h5*B<{T!YarDCpdc9t^ z+XWluyx_40fELfj2&+}de-m|9<=M%B@uvNJy9g2pmPr^n)xgJ_Wz25hf=mfpP_4Bn@PVNSgKJ9tAx7!Ngb*saGJt5QGp@ zIA$7yq0lpT0do~l%T+*G9u8$iBmzZU9|Yu4GcnIDAf{4{AZo$pC@2bMBE%4m=&Cq` z9EnDtAq>a{;;l(gR>m+k8^~e43LAZGT+jUZ3Pe<^5mqH2yh=qsV_6F1bq&Gc_F&ZG z!3a4_I?4R=PQ+IwBC1jarDZn4Dr31;h430RB5LCiS+@{T^$A#bauqVqa-*9S7-XJS zvT(wKJW@CAfvUa-3f&B(G^{}+-ydGBLPSj**Cs+}T88}g5(H=iku~hXEQ<|+yMnR) zR2m}1cUb2mN_o|8u$%jG z;|SMwu^t=QNp_Hi&L*sD)S$lqBs9m;q3>uyGuLR&4Z_YGnNBw{huqLgbV2KIAw%S# z3+d#2jU|9qfkghN^}C?CG>&eU2U%Q~KH$P;k&LJHO<z&x z+tD)SMoPOAIh_u;S+9#6C&$PkvY+hZetO7m@;uo^+Q?4kD|d{enf0aG#}QxGgVqT* zbnKbB!H$!xN8NY{C!7=5!?Vocd_&JDl>DZe*q4+xC$#N@uuA7_M+0MOYY*0SkD!iq zG%$A|*9i4?)N-EII*2;%ckTHRR6AWz)pnzW@6KdjggQGcLoU<|jG>S{TWuSL*5*WN z%K)s*8*8;AIJX8T_?>9kmsOp^{5CJ5g5N<{ZZ+>t2SQ3(fc^fwi==@p^@kttqMvvd z_xfX!KbROVC(FovyaUDl2q+7JzjPOQu@5qSz#pOIHzM@V&A3jyi^aT)JE-mQ<2{^* z>kmajv3n+*|A(!@^cavA3O{U_78m-x2BGV_UXz5^3Ck3|@00bOZ|!EY`7q(N@hLek zT#^jJ#nWGR8_LScj3VgtS-;up)xSFa=}~=gacOC(L4?m~GF=yZ}(vbKo{gpXKK&By05e2|UXbvm7x zKsY6qeEQ4>DJi}_`J5RaGJ$Z+#I77a@!oPG#Ru8?KJ}w!u`xAo*1l!6E?BrIL6e?d zzpbdK;qAtEn%=E;3RMQS#(emVX^)BePO&*&kJ#F&1F#5Uc}}5HtVK_Y&*M8KS+8J0 zQftIC^sxWlG_qc_WlKiJe>}$hn## zdbCmvFJ`{9G3(`QA;-Hvji`%AdGS zW9l!L;XNK;kfy>sTp-Ji51`GKVm zdJS@8?~rCnrAl?DdR|=U+_`tfOOb0Ivts7NhF%+O(Qd;xIFly&I$I0Fycx*zg}pv;K=#oG{5u>Q## zKNR4%l#O4?Kqavl_Io|Tw*itA8;(3GXFr90=Nnpi$r8RsNNhJ}z*BGwU*Laj7)!@c zyk+IZ_U0@O+xvj8I^ko=#(R{pRMH8`e)J7B75rNkKBnM`l^5tX#@>)A(F>7R9YZk- z{34AXC##^&lyHuX1K#nZ`yp-kAiNcx4#0hjU6jT9ASJWhjk5|9gbh9o4G5j92fpno guN_P-ss&c_1YvWoqzMb-(2)23`ySDI9c*{(8;5%)tN;K2 literal 1334 zcmeH_uW#Ex9K~PMWT{$3+2;NJrOs-mB}%PSm6D|cTO3qNX{9JG2n`H0G&M9dG&M8~ zj1**e@Sv&TK|}AIThKpYpilbvec$^Yxs&b1xP@BdCh(Kf%SReGepoaftp4hm2+v05 zI}jxEmk@zwja|6G;c$SUi%7GDh&_nJgG_zoM5X~ffZB&pS%mMK82xRGOHX@3Phk5A z9I^~jtiu$g)a=L}Wxhw0W{7qfs+<%VoKRpH2_$=glw?A1M+)6bEMtkaCXo@YF@2v#jB;&VBP6^W3tmi!S$!U)+{)Gag%3 z*X`@A%l*xiMb|Y=^Q&vVJ~5o>ROec+j@yQFeLbCayPeMI>5G$g+qnC4S!*~m^i|%@ i@2*yh#p=qQztQ=}C*%F<_ICBo_VOc~F71TsTXmD~G zlo*+Z+?mfWnHOKMaX8PRu&i>B*{O-Bu zo;f>bLEw1k1e$bQO^S-MJgq#XV+q&OSO`7W@54m2LE#t&Opo*ZcF+`TILj#rI+F`cx?V8@}QDQk|QO3jVt@#|Cz; z6=mHLDzoCidYe(g_n{&q2F%q2KYj*6e(J*4ytgbZ60GM8N>jqYx=&-9EflQtH(7bfpyk8^fbTbTLH+Ur1YwP@(Ws%sK_M*$5Tre#2*38#VH2lM%|- zy*V#NXC19KLhFQIBm7#*H9~8JUnP7Ftu{hA!e+9IH{SF;K0$BIU+}iBP3FL7o_+557hZhH*Uz@R{EE;f^MemP{K%t^J^qBR zfAXoPN3_X2W9D6V-*fMMvwXS#fl+NTPY<{RX0M-k2_4|$Crr~D?i7qP`}kXKy)7VM z>g}UU)jIC*`fIPde!|2XCQTk?lAr&LH{CpC?ENPF-!bl*QO0TG@m?*etH!wcVs-iP EKldOkW&i*H literal 0 HcmV?d00001 diff --git a/elenasrc3/ide/windows/icons/redo.bmp b/elenasrc3/ide/windows/icons/redo.bmp index 454e6741da63b9c0ae3dcb3459353fe38d14dd48..da8d61911b3d79a81611e5ab4d6055e6c37d7432 100644 GIT binary patch literal 822 zcmbtRp>72s5Txl3R5i6vH0jA_UUK&2OKOlugLmI2-V(5rk^wt7s6kWd+j|OZbvNxZ}I*L0&fpfQc&AlAYm-K*oB0 zooY@b2e=m|+WvHS5mC9#12ACIddL}rGX2E2@iv3W7S5>z%-@vYPGEFneqRFoyZ2DB z)!um!SI-xB1&{&I!Hg1giW0s`d>2whnj0i0?B-C1Uz#y0)M|A}_4%!lYAjo{FQVj8 cz!d;{GOAyP+}&1k+BxY@hZp?)!}uSA9~iuE6bJCXQnA{!TAHfFwrE>X8l=)RCU$f*>B7j$$jHdb$jHcgBO@b;6C)#E z$G(HsIP@cU$&dHm|1Ker+kUTGsMh)dSWwsh)xc%F(Wp!HT7(Zb~u_9>;vRi4QL& znGc`K2@BvSBqbTi0|ZHkASHQ-Fo_Tp5keAWF`|N$G2)z2WrztY6C`*74TY}JRHu&b}NRpL_qKwCKlh2Q`Hc?eop@h#% zS=Uvm^CgO+Akh4zYTC^UKUlAO!%!A~1J&Vio>%EiHw>vda6RI|N;OSG?p<}elJvj> sP5*eO$S`zWdaeRhH|s!}^SQm64e$EBo;)~tEyaV^YWMh99=ns~2fKy6X8-^I diff --git a/elenasrc3/ide/windows/icons/redo_l.bmp b/elenasrc3/ide/windows/icons/redo_l.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d6f57458e5778f9b1becbbb5a190cef7bbace175 GIT binary patch literal 3126 zcmdUw?N1xY9ml!%eSNAbMORgqs&9Iys)gv9%Qcsfq$0jMN*>IUd9n?*!QizGw%5B} zuOIOG+4vDZvVOL)jh|v0$3P(1#uy4D5Ryy(nCsHqNhc9=Na>4q^qtY@w=Wh?m*z7`SWx?xz0U4Nd1?RkyAwzG_FWw@bcghpx3l z?SF>a{{;W#bGYM=;*KlqPd}#q=CETnwHF&5VSZ!%@c2GJ}#Brz}&4V`G%) zXn$mc93CczhRDG|aiBtH(3ABX#U{CyqR->yu5O0437C1}fbAPJ5{n8Wc2dU|TI z0C3kt!Yu@@$&ZIa1(}Va%5M9?x|&aYNAD&7*tn)H5piyf;FkQh9XTlw1f0U2S1k( zd{Qeun4PDmxs#aX!&kopet!$R`(D1GZ0F`7R*^4!j$->J{h>{FU{N%+#O5#yKyP@g%lYu8 z`TmWCyI-2_e5t*CUEO&d>%6YMb0*c-*U&Gn0#~mvKKVP`b)N59!;!LzQx@?y#ORLN zaA-3gI+VNmxlM%e1Q=ds4)|z&wo$Ta=%KN{$JqNo+xtM%cP4E=p&r%aZ>8P$zZ`STv#G7(@db&SEqlVd{IBHB<+$pas<#8mPj)c>( z>^#qD6_Gx{rd9=l=Tc=;k2M$6yCy|l$197eu}OM>4JQ;!rBJK6mx<42(eWZ5s;bNf zF3W*Ov%3IqD}hxI$cW@C>dO!=9>dMTv?5Ph)4E;++%E!}rdhOw5`0N%{^E(3{5tyt zW|Vno{T)B3ZCWnLhiosuWfmh`->jL6r9Y?;!Biy)Wm(?`0PbIvZSf15fFg^V= zt4iphnB1OqT`+8ZO)uD#%6E09jzeSKA9tycoa>es|92%6ffy z+?!ic#?_;qi7wm29`^t@DstvMtt>P(t8_;#-_z?~xE!a^#nYJOB~DmC8w#K(oXl`p z2@WeZGZCH|!x8nHMpe^ZJ@$+sbCEu z1U{2Vw&#h&(7Kvi5sxJ&sR6b)BJ*VZ=lMiLU$@OS4cI?Th9kTA*kw6!+g>j%ejjzd zO}YM+a=%TuPh;*^5zk4`a~$#<2c5@$`%9nw#AiM6NOv%5hE2xDCU8KLG{2Wm1Pyho zw1E*1zG7deJv5t-J&xBA=iB5NpV0RS_nWxqRrnp>bsTWM^gB=dwi7Q>C-_r+0V*rV zH>}uN@%`IjVxwd=EwY254YjtTa7bVht4-l+5^G zibhG%={YvADw?gpGphn-7MM)(3H}A-pMS!)qn2kbRYgbKZb1R!~$TD23h7GyQZY@qsUEl$su z7C&Fx0@e}*u?1NTG8-s+uO|qo`1#hJYb{Q~W)fRjSy@w2S&76Vk(EuVkS9;po;*2O z-d&;GFgR3S^7Z}SyX&QCZn>U6L)Y8_ekj>z8fcdbjk4*d%0#-daopHot^?+MgZVRX zg82*T3uIXa9xTBl#R_@+3m$I>7x~tOAb9LS>^$UqA3_sA90Eup3`5Ehh($ diff --git a/elenasrc3/ide/windows/icons/run_l.bmp b/elenasrc3/ide/windows/icons/run_l.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5f60444751701f495291fe0f82ff35c5a7be8140 GIT binary patch literal 2102 zcma)*|4&m_7{(v7CEK4dlP%ePShi(ZXLLH}76(o{LXasE=@751mWqs&Qfo(Q?P{&H zHi#9m%9quyW2LQ#tahx{T3I!CMMTCFu^@tOi0=EQvZtU770B+*n|tqhKIeJQIXBOu zWs+wxc1fNFUgXZB7dU z>|dwIfKQc6#)_^wD>~~e=&UiL@p3KNs@R9~#5y~I zWpdQZ(>Z4~dm9nAYtd@gpw*^E%&J0+&ofRlq8#@XX2LB<=~YH9$!HL@6eDUbM#Nl% zh^Y`!s~Yi26U&HZZ650LrR=Y#mzsJJ!aT3AQHd6V0xfz4LVQN;Iz+4*o=q0K`AgX+ zi@K6~m$S%mPKa|Gi?dNLEP-A+hs+B0r5}5S$hPp``V?uXku8Ro=M}Z65aQmN)G}Bz z-r_#<(PCE7s|W#Q23)!1_#eU+4c95ap1FYE>70{~AbW-_Y6RHB%d-jFv>a1%ZBkSu zIe8kwRxO%T*>KaRg>1xLMt`n>nq$QRM9cMP)(P+mOA)OwAY#*@lH*>kKVsK&%!pW} z8J@fpcv&%rk^9SnGixEg7t>z@UCOKQ(!VBq5k`48Bs25b2K1je0(Z$e=A{6)FPy^2 zg;tz(?Z(&1ylhrr=vXa=PcttUc$vpY@;wm$9Wh^thahaJB|JQZ;?9A9HlRZ8Y5jokqYbGEPik_6jrgt#A z8k)aru01{-VV+%0BJ^$3G=P7PWQ?fZdu&SLuwdLHanPgT$dnde?hpj)xQEmqc+%pF zErzW-_K$m1Z>xI(*rzVtVleCwjFx1VLuU75#6FcuU8<*vV3h21RM*r#X0cIGP@pOq zH!)atIvh^>fyoxzbLHz51rJTE^pNhYoCIvok$s#?f+k~awpw=Dc1`+aD>Iho$Yi;4 z#e|9BbJI5Sgu}`u=_GPwx#K44Qq87Kn{^YixGE(zH9ce8WW7S6*s!*6W6^)IxN3e{ zN=oWOlQo%Zg>{ouQG9Riy!rFrA2V5=p83&=m06F-;+*@VbLY(?k&^ns(q+;QA5}&1 z<-4!kdu=XF7QDUiokj0HE{lJ?@b^D=@7*7L{iQb~Z$6=l;;oVAZ{PXl*WZ5sF3$QQ_AAiM53?%+Q9XxRZ;Bz@zUjCSdpONgG?1B>W=7_x#qiAjS ze%1yYJI#{^LgN2IO0q`R)HM{zNxGvaiWI(wWalySn32GPB00%| z4fhRq5^m_X$igiY$w{F#+G3gL+=q&M6huWk<~yi(hk}$10rDh3sYwH@vj83`l8{-5 zG>%ZD5z-{4#;CFwd6u9cC8?C&Q*6r=KFO3qSSgfMfubs@C8~xBbw%n5d0nF*^^t_P z`MtmDpS!%?;{UmY_}4reXPr*x?DPbO)|fwizrX+SG;C@A_Fen>;o|d`i=VRb=G?e? zeBeCF6CplyjcfC2I2;V*x!o3`JGXAk$$)+!<+Bi$V}CLnx0xY(ddHZ!mJTjWA$pEE zG4I@4?VY24FYW%RW!vVI-esI&duuWW?Y;!J?{mG1zu!##pM1q82?GU@#HMOZ7=?d#eWegd1 zlQ72EM8dFQS4pi+ZJO7vV$*dMD^?^G3#+wZ3@0LE9jOEn$%ee(DQzG&;hX2plic3t zo^$T+-rmgpsrO?(QttzjX|ypW4q^t)F9c^{gt@snSSuB<%}Y*WIhcwf%+eR?bt3Fz zFzT~lv^yd*Lf(i>2z8k-5>clS!yW^MJMr6h#*7xWfF|~ofx8;L8gIf zMs$JZ#jvWx2>BcsbZIf@)FM256QMvSLVgc|4u*UYM!MT@)2^YO8U*YXSWAT%?qtw! zYec`bfmmIzDh0H66N08%QVkd-pVsT(*HxldTLGq|kk)G8YgVDVsgzg>&}VLd_ksf6 zdO5o4i_le9gdvX&L1P^{Yb5Bb7Q=H|gh4m;^12W(UqHZA4?l^KbE$SUJXHd8RPoVK zSqMjSHG;t){DxZeMx>{G6y>8=Qwet&5A7;0DIaDN-9ab>pH2;*wu*QJv@Q?bjVicG za^O^C!zs^#UZ;b%Nd+&>cQup}BOi<`m-eZELzWJQbT90ZG-#Td;Hi<3r0A%Yf|2H+ z^RyIg!W6U#cA=rZ4(=);+?4{flNf0>?N!B`J!4t_-3n`b*hWfcHC~uyh za!R?Rd^nYPaF*o3QIZRXA_oq6HZ0;yv@3H-Idl%$C@-P^wABj6Vu8hMhRJAz(V&N+ zwG}#T3$!g7Xf@3+RViSXWx_7aKwCtTbeM!0R4)TcsTg)EgMii z%`oR~f+=SsOxf#U%3KR$1}QxehV(TU85x0L&qL6YiUftwr!0qXJG$c%i3kd@ z5OR?KGJXN1g*-?K^3hV5hRY|5VLM50`{WTClPZs3j=szE#_#lA1^a)+mlWPVC;kdg z{yjBzogy-^SX^Ihx0hYvEXJ5xtvvxs@Trk={d#{-?=}BV$~)mdDD(>j&NRH= z*w{qAFX}73baJEbE%;TnXV2E1oA-OJ-S7`8uiUzI`}UayU-gdq)TwvL|B)Kppa#a@ zhK7ExTJ+y4D?5H7;>Q{^4GjG9tBU-2upi_{6vf3yyE&ZozMh_Iet+QH&%t1yoMmHR z;x{A`>6^~0uA^VIe|^IJO~^Q%o;_WP!je;rnWjvqB;RqLl!#Q@WbRWw`!DMOA?cE!ffB5j>G?tBm zz5etwDJgOJhYpE$v1}BqaQlwL#JK!zJD=LlvN5nNPp(=W=O=I7x`kz9V2?kMkPzo@ z-n@Ae%f`UgJ(jd0&fk!M<>6vkQh51d-|4=kBIb4hLGB{P$=NMt3pvJ#0!A}dL%onat|+8DGFsx4E$;#q6?rARZc*WuFPbBmd9(5^ z)r0ua7?l`JxA;eXr%^Y1*@Yiz2d8Ct+!A_~{BO_l8h;1(O*~#K3r~@>Mmmn#Lcj3A zqkyBErZ{SwoXP$h9!C^6#v74E!=Q6+&++p}k(bxV+g#6)|Lh$Eb5ad>s944t1Pm*( WicA+^8O%Q~nvdPTkEV2@bMItM)NMt2R)s;vj z7KyB6=K^WFzhOJc@1FB1 z3lr=08i{L?8JQ#T=7_y7>csyh4$^=u7sv=(y2wHoITyK zgUz1~}smG&0e iNRs*fHjkxK<7St2UA{Jq-SgEq*OvT`M_kGyYT^{?l^L_W;^L@Ur_viEZ zK6kt4Ny`kFCKy-1WPxBYSq1T)B$z(F&;2+b^7==z<_rOFeL)l2W9+z@+X`rb8(Ejo zzQlp+^Dp2^Ts=-}H>10e1*bN9HEc>bIz&IgBX2?1*~4hFnbAr-klu`;buH+0GU)u7 zL5tOd0qI2y$u6U#fkv~%i2l_V@TY?!YXkZvZZhjPTscLdrO|-!6 z(W5u*JOV zr@jbX;s*32|3b1VxJ)WEXbXt*(YfptdR98&GAc=(0*waFMQ9{7PJJPqI?g1k$tTW* zL!FC`rFQ(4aE4?EBYm8tPXpO^sO4~|ILpuxYeU!a(`29AD`mtPuya;OaW(chy2xC+ zNehd`Ld=3?IWu4x1`I=kp=r=G1)8EjQD#tP&L*%L1?)u<*a}n79(@#@qIxnz2DjUV zv9U3Xj*en@co-g!2ZMuy=kys3Cz8HT*FzAS@CFhc&K$Zc6PD}RV zVa??nht}{KT#L1k^Ge9P6m)lYL#I*0B9Dee#(6O=FEZmQIfK105hkMnTD1z6j8L%B zAT);@L|YUC8|i5y{nSbYSjk+lDYMZORF1ZY8dym$RZ$_B#F@nYV8s5YjTK?U?!X!^^qzGl4q)2gZ}^RB!2XVuk*4pIDb zR~U_@yAN`FyK0BG{^QC@lj#$lfAFC~p)dAwZ=h^{x#7Tpk9hu0Uf$llTmH*S_PzU_ zPWL{~-^|HT$~V0w6u!NkJODR9y{oizw`LE|Uy`M#r@y>$W5K4)uM}>1^|hkn*WXYm zwr<_V^B1L3sZ1tYOHw&GIoWc#JU4Is`VAZMd7deeWM!>cLsHMll9Ng7`RwfMb#nO& zJWokYO-p-5B3UI~&83o(Nr$%0%HrB_%)2^W`g6OvFO5_$i(*6^VTC`1oZ! ze=;UUC|r2Agu>XkB|MLajPy|-6&20%(6BHcd{H>}8s`)g9PFciNXP;&7EGNt&qsaW z{D1kJfB;`Sa4ugz^YJHq@L98F^Za3de;@pjM<3()^!p$1!Dl>3zBc2U(}8d)AOj-%e(#)n zQ<5R#aP|0Q;mRNkpkjy#XyRD85XC_C#ArcQOpF$wdI$n~3eLvr3}iu|N{D)7K|E}N j>fu&H7(kcfF&|gJs(`3>ej@aI3ke>O(uhMe++jVU)OTV!Hv8e4^!CK!d&1a0zPYu&v6G0&;)HgW#A TmWfx)d}~a6)ZgJV{oUUI4wK*s diff --git a/elenasrc3/ide/windows/icons/stepinto_l.bmp b/elenasrc3/ide/windows/icons/stepinto_l.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ebed0e930ccbe61085f902654f1d68b72cfbb3db GIT binary patch literal 1654 zcmdT?Yfy|~6#lwO(SbyUk&qdeG5k|*WB7|< z#x3HP#Eji8+gCAbH=FpQF!MOyMx$N)G~>*i?>+DHJnwnWIq$b2T58GYO=`+8o)o$K za1+K#k8>Y)r!hZ4G3Q`_&vtJx#J`UZ{Kw=^D1L+?*H(PB9>&+nAJHcgp;P7yWyNap zHBgoZKvCw4zBD1e*sAfxMhA6qH3lz9F?hKQnwEX!QfM#9puH%?z=;H~sVNw7VDV0` zDKNkRBX7kp_0S`hKu7sB7fYd_bKUh(7`#yn?d5W+e--H-;)81&G#84Y zbGr=%^`+tJA%1jt(WzQ|w(o~B(i^WbrlTW|j}D0^ zly#f&wnc_cT006n33r1s!ke@#x}pQnS+odUb&=>g9E0wr6!e|TLl3Q;#fvdY^JCL@ zL3Jb!>?tvN&*ngNIt%P+G2z*Cr-u4VBYqp$v$;^6$%d*i9wT;d(JK<8hnv^Qbc!CG4I^jjCHQHktT5a$=(VTb-n%@JOQ5#06cJ810@6F`caam~7#5M>k zC)0y<^@k2O$fG6*2s_f)cytV_sN64?S54rViUS9$Yih?aiR4FERyK}>$j0)I0~Cl# zOGUr#4Pr^jK55C%R0bSvC3^~siVBPO8Z&xicTR3zetup-&hFm|MClpg%&e@;T^ZS; z-v|;ClafNRWE8J#y-VP9sZx*y2EsvhDsOj(Es znhW8If#PVUK~w?-Aq5-gGg^Cfn2a&l&3auSI}PEIbFLRMDJR#tvFuI+vT z27y5Bl6&vnz4oPP-r=!9-kbm@3RU;RQ?XEH&5Nnl7_r7+hN{Vjv>%wg&rmMn^bb;-JfX)4&}0^43;?>AUg zlMViKi(wchPJb}%z?XMm@d*U+d~YellKRD?lrM&m(i@}cq%%Yu433Q5*niFYz9Zss ajF4VSXE;zw_Xx?#fjPV>w0R)N_wfNAsNhEc diff --git a/elenasrc3/ide/windows/icons/stepover_l.bmp b/elenasrc3/ide/windows/icons/stepover_l.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f40346b0a3096282391b3270806da012b882a351 GIT binary patch literal 1774 zcmds2X;71A5dIRVm7suy(uyro0)l931qpa7f(Q2{v=RaV6eH!3mOy|?K|l}-%3%@k zst^v9pFRGxGc9z6cBYQN3?z_)P))-n{^FX>)BWU_I0L^s)1BGuW}j!@caL}G^9h<- z$Gnm$F2lHz=dh$4X8o%;`{Qi8sGa1q3Il2Q=3r@VqGnV=dVjljp$DoCQrq1O~JB zVBYc>w4zuH7WzSTT?pNs4Co(7iA&ln#pvyHipN45%c>9~)j~X%=VA1|6zUry3>6)x zd%dB^Wz~yt;)#Tqx6nf?jDe~m9QuwzjCGblSC;^Ff`t0`6;o_a{4VON8`EUfVhQ15 zsHj#A0u|XI%2(tF(3fP3KO-5;v9lMSgZgSX zw6%%Q)JveQI}2@HBE@LFiK%$W@1eKUL%R||TYmxSo5@gDMAGcWpovd}syq~$8Zr4v zP?v{MUKs74xb%P4Y7{fp15gHf;mK(R|Cr1{cPJiDqd3qVj0gLc|0m)n$jA`*t=UY+ z!$$=Lj~;idNoZ|rZ*OZ|6J{6=m&;j(~3Ra@E8Qn@Oy81&zuDs%z_RepAmfzA7~46j1`?R z!pV(`7box%7h~Z&BO*@=UdN-NKl#+nWHDxP@|1r-;A_1GdxnIb3iDpX4?7(>>T}H3 zXj;d8kNF%uVYgiLu8()Sd+hNPczK(0xu$#f?%RLB!~Ni)T`N~wIyrB1aoz5=gGaJ+ z$97kjZ6AJQxdJoHX1gu#y>GvDt1XFxgZ&4NTlkxeV1}`@+VqyS&D$()V`Kf!yH>{8 nEOXtP>&Dmr~m)} literal 246 zcmZ?r{l)+RWk5;;hy|dSk%0v)(EuhP1WXRX1IhpqLqh|E0+J6NJYYC*-~dnvB=H}N s8225Mvn@kymY1|gXPH6Laz0ObWpP5=M^ diff --git a/elenasrc3/ide/windows/icons/stop_l.bmp b/elenasrc3/ide/windows/icons/stop_l.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cdbf2c0b6da28b3dcbd458c2264e9f28920ad996 GIT binary patch literal 2102 zcmcgrZA_DA6g`p#YeN_zj1bmfQ!5ngI%HZ3@-;wa6cGg(aq7?*KiEt**oRy8!-Q-< z#?sBW4J62%QDlS>*AOI(AaTSv=Uyp-B38hHfCZs^xH+fo&eI}-`gePpo4!5g+;i`9 z``+aB207fvAOo~~Qq9By%n-z9&w|+}xLhtc`H4s#fHrxMA--+UuNg*M_9)ioIgqi- zft>tlWHZvXk0ExG9lF#3geLSrpEiiJtz*c2XBwOKP9k~B7*=H15xI64k!uDK#qZe6 zVHh(8sqcf@&;bMa9O@%dSuaWW*bo}m2Mt3VOHbAhjk6*osvQYAqX?x&LtJgNGT#c- zif*VGs;H|7)=MyC+NrTYWgxbqi+PO5t5E7Y5UguMkoFvNd#LZ??{)-*USdeR*Cg*T z2qm%L2;$l{1gKgOpgsp9?-)XVC4GV;golJc%_aDUv`}*a={p_lr5l0ji~M~N{>pRk z3vPj5&}pP{2AbGDYR|)uxNl$se1jUWX1fDX>BDe3oz%Bd+X5edGx;WRW4Ql7;LHgY zoXBg2!moy!X3l7UzM~i&bCM_L=9wSR2)S$UJIFb z1#}5kD13?g2)qU|`EiDs^J<4SwwqWTwZy!uAd^+`zi5XlvV(Q%sXIaZ7`$Ys5vaYu z8MV^Ckva9usUufOt{Prm6`b#R&ix|m2+mCIIPogJz?GaYXCBl{teQ0{h>M&`Vhy}o zJ$(Gk?7g1Rz`ADUS5jL}?-SJ3GRiqCp>5<{$ScUpk5NOOJ$rd^Ha@&Fb7kIUVj`y$ zE`B0XZX=xg5}qPLJohtf(DFHc^C;HsnBe<0ftevJ+WhnHY}x9v#J+MVs1hmZH4qdp5KZ} zPX2zW?2qS{+;Z^O1FfZp51%hPTl=h{KJUzqGmVACzZ5l@OwDJjo>H97`g!-BcR$Q8 z{JQvPiP>a2RW?uXV|7MG?pu5E_U0FUQGBT6Nlf2J!HmVBqa~H5Q*%lf z%TtA5u0_T7$7U;h`<*d9H8H_skte!fjnX4W9t$$RiZ;flq`C#Utl{pW=$V5#$p!Nc+sxjv)5CY>gj>cP z4>eQlBGP@+#B^RHYs;G+{<3w0#UgX4Czm;0`jydCxQCUMwb{c<3vE`5MOZwVay_wF zpD{yAo&8DoDR5h`hQVX8I_)tp_1?XqqM&X3A7SAcRzl(|EvcfezerxxP)>?AIn9{Z zC%n`d{?{T=!t(b6TCmMmBA3shC8=$6@!c^|gBBB$Q`7hUoJUKNrMK^vt$*OQ#WFZF ne8)cW6wRNV3$I@5y54>5hV^F8v#dZax6!}-O2_lr{|5aR#gMrS literal 0 HcmV?d00001 diff --git a/elenasrc3/ide/windows/icons/undo.bmp b/elenasrc3/ide/windows/icons/undo.bmp index 3ed55cec391a5707504234b3b3edf540ea7e00e7..7f2472b06c1d797c2c93afdf4b1ac16fb02b365d 100644 GIT binary patch literal 822 zcmb_Yt8T9*q9Kb-F04|)YpC#PAc%<5u08`4+^Wj5+Bp3%OjK7N>pV%8R z|BYV)Iy@5kpO6G2U<2U0>?zt7rEDuqvL=yHn$>_)mj;W)N{Wqdi_@P}v3zSqye?qE pqIsvjk>S|YH$I%kM>DA65~nrq_>iCq(0ZffkU1Wf)(ijL{{@Qr@;m?l literal 1334 zcmeH_y-&hW6vdAsf*(XwOwcBXUyYzuq0tJ#U^$yp&PY%NB4;SN~xH)z!tuN{X&M>G(bL0?hye(hI4f zi$UaKu~@*3CUD~kCK@rtH2TCRnZ{&J1T&dRYCNN#(NoDxYeE$sv&T#l`jkpM;loQv z>cb~9MHK-&8Ng3S8X!?Hjz9ghds0k9KkY)-h%c1fd8FBdr%jNQ)|2O!vf1tv8)NNhY`)g0vZ5)<2H&Lps z#`=bB+m>aSjosQCult7M*!F{EU6_Y8z1TO5o$7Y^z`Qkgi`+`d0O^FO~WiM3Jgdl*uGBQU(YEm}QJ@jQ8u^=K6ZP8yjyI8}JUc z!7H}$a*dbk-7KCAWNZ>BQAd-iRXTmh-;kH|z_bxEg^4ukOOJl%>MY;)``zz+=YIG8 z@CUyhx@sSQ=O01;{lELKhJFV|Z`&V!J2Z6J|I>aN`spUh^{Ouya%VU5)xyo)_gtwo zaeqFfjhHM62UgvCPqqPfyp8+!g3_>J-o=Iks$?lWVDO&PU?nV1X{R?R!)p^14}B@N zypaiR?gl+6AAmdQb?tauJ8o~v8`#|p=flZj3d8qmt>!y*tL^$$C92LY)8o9!ZQ_%_ zqMp> zQblyWU4O2Uzb%SzJ#Hx4cv+Z<358We-q9%zbZ}F}D=#uI0VU5N=h>ty%;i{fX*w}R zo7tjF28d%m!kA}b+Bw5=vkZ~ta5-^PqR=j`;$C51KA+*ROCr^g5$(HHPCaPPW$QVu zz4hh3!`NRj^iks}x^#-_dp6aPNm5tR_xLkO%J>#x#62>)IzsVK)$yfpWl-WeKc_6# zeraAk^R1n4*uVAwAzR;R>91S+tCs$X`4lx=NoY^3NLR;e!Hf!@mV-zMDj_sA?j5JN zsUV76C3igvaQNYR!dOHFc^S7Pm31^r$2P+;sysA^8qc7zgj14mOJa73$Jpag3mkfh ziUEkx9jOZSzswn|b%m>4t}B8)gjz(IL4{zkiXT>|gaqVHNsj}QkNp#meG`v-qYvDl-*+%dt}-< z4bmMerLOaL54w&0W~`9}5`0WX&amcEbW)s7-eyoX85AFbQlrbJRUe2+eUYp}eC)Ito56q-5!Y(9>BbNfA`ubOb9P7okQ}Rb1v~ zWLnJpUv0o*xEOyH(apLS#yv!891>R$xcyApLAbbNHcS~^8H1ec+k8PTLXEho>T=XJ zZ?ggGp+ZCv(bEDvY8Zkr$zofnc&>+=YGRoBsrfS!O1#6jy5ETH=c1kL9X4Rgg>6dW z%7rMGp5sf}O6{>lwZBY?(myhNLao0*cv6=()51JT zf(5<;RoAF`vHa}0UfNd9r`cm3B448<3E>uG91MmqF_aTQ zyCQaqPftPgT`oH(1iNrUqwSi_FIOFBUi2HcqPqkt9y!huMCEH)?*M*pKJ^Ubw0Kd7{DOFf_F zFk*t`%t{i^4Dd%=aY_d@JSBKF-Sf8ZkS{w9FFbn3sfAZ;zL0yFbc zF{VYUgU9}}R_q|P*wr(7u;Rk9`f6kCFB|r6y;ty{7jEmhbNLkf#q0n}U)gmpZ0fFA zd0>=*kgE!DQ6VoF9k~Bzwwr^*VOrKTkWYm49xQyR61`9epCbVLF3dTQvN|G0Tfk@m z2x)a84Hq-YQa&z+Yido+Y_EB?>w~|=0g3!!Vdcn!JU4(Ski#XA3wcwGG}W?(N`lKp z6+~2#i7$Z&OLEbkarun(ideWindow, ideModel.appMaximized, &startUpEvent); - ideController.onIDEStop(&ideModel); + ideController.onIDEStop(&ideModel, guiSettings); delete app; diff --git a/elenasrc3/ide/windows/win32debugprocess.cpp b/elenasrc3/ide/windows/win32debugprocess.cpp index 5fc202bc4d..10939be469 100644 --- a/elenasrc3/ide/windows/win32debugprocess.cpp +++ b/elenasrc3/ide/windows/win32debugprocess.cpp @@ -2,7 +2,7 @@ // E L E N A P r o j e c t: ELENA Engine // // This file contains the Win32 Debugger class and its helpers implementation -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -346,8 +346,19 @@ Win32DebugProcess :: Win32DebugProcess() needToFreeConsole = false; } -bool Win32DebugProcess :: startProcess(const wchar_t* exePath, const wchar_t* cmdLine, bool withExplicitConsole) +inline bool isIncluded(path_t paths, path_t path) { + pos_t length = path.length_pos(); + pos_t index = paths.findStr(path); + + return (index != NOTFOUND_POS && (paths[index + length] == ';' || paths[index + length] == 0 || paths[index + length] == '\\')); +} + +bool Win32DebugProcess :: startProcess(const wchar_t* exePath, const wchar_t* cmdLine, const wchar_t* appPath, + StartUpSettings& startUpSettings) +{ + DynamicString pathsEnv; + PROCESS_INFORMATION pi = { nullptr, nullptr, 0, 0 }; STARTUPINFO si; PathString currentPath; @@ -360,15 +371,32 @@ bool Win32DebugProcess :: startProcess(const wchar_t* exePath, const wchar_t* cm si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; - if (withExplicitConsole) { + if (startUpSettings.withExplicitConsole) { AllocConsole(); needToFreeConsole = true; } else flags |= CREATE_NEW_CONSOLE; + pos_t trimPos = INVALID_POS; + if (startUpSettings.includeAppPath2Paths) { + flags |= CREATE_UNICODE_ENVIRONMENT; + + pathsEnv.allocate(4096); + + int dwRet = GetEnvironmentVariable(_T("PATH"), (LPWSTR)pathsEnv.str(), 4096); + if (dwRet && !isIncluded(pathsEnv.str(), appPath)) { + trimPos = pathsEnv.length_pos(); + + if (!pathsEnv.empty() && pathsEnv[pathsEnv.length() - 1] != ';') + pathsEnv.append(';'); + pathsEnv.append(appPath); - if (!CreateProcess( + SetEnvironmentVariable(_T("PATH"), pathsEnv.str()); + } + } + + bool retVal = CreateProcess( exePath, (wchar_t*)cmdLine, nullptr, @@ -376,8 +404,16 @@ bool Win32DebugProcess :: startProcess(const wchar_t* exePath, const wchar_t* cm FALSE, flags, nullptr, - currentPath.str(), &si, &pi)) - { + currentPath.str(), &si, &pi); + + if (trimPos != NOTFOUND_POS) { + // rolling back changes to ENVIRONENT if required + pathsEnv.trim(trimPos); + + SetEnvironmentVariable(_T("PATH"), pathsEnv.str()); + } + + if (!retVal) { return false; } @@ -396,9 +432,9 @@ bool Win32DebugProcess :: startProcess(const wchar_t* exePath, const wchar_t* cm return true; } -bool Win32DebugProcess :: startProgram(path_t exePath, path_t cmdLine, bool withPersistentConsole) +bool Win32DebugProcess :: startProgram(path_t exePath, path_t cmdLine, path_t appPath, StartUpSettings& startUpSettings) { - if (startProcess(exePath.str(), cmdLine.str(), withPersistentConsole)) { + if (startProcess(exePath.str(), cmdLine.str(), appPath, startUpSettings)) { processEvent(INFINITE); return true; diff --git a/elenasrc3/ide/windows/win32debugprocess.h b/elenasrc3/ide/windows/win32debugprocess.h index 72ed22815b..f53c37e522 100644 --- a/elenasrc3/ide/windows/win32debugprocess.h +++ b/elenasrc3/ide/windows/win32debugprocess.h @@ -2,7 +2,7 @@ // E L E N A P r o j e c t: ELENA Engine // // This file contains the Win32 Debugger class and its helpers header -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef WIN32DEBUGPROCESS_H @@ -135,7 +135,8 @@ namespace elena_lang Win32DebugProcessException exception; - bool startProcess(const wchar_t* exePath, const wchar_t* cmdLine, bool withPersistentConsole); + bool startProcess(const wchar_t* exePath, const wchar_t* cmdLine, const wchar_t* appPath, + StartUpSettings& startUpSettings); void continueProcess(); void processEvent(DWORD timeout); @@ -194,7 +195,7 @@ namespace elena_lang bool findSignature(StreamReader& reader, char* signature, pos_t length) override; - bool startProgram(path_t exePath, path_t cmdLine, bool withPersistentConsole) override; + bool startProgram(path_t exePath, path_t cmdLine, path_t appPath, StartUpSettings& startUpSettings) override; bool proceed(int timeout) override; void run() override; diff --git a/elenasrc3/ide/windows/windialogs.cpp b/elenasrc3/ide/windows/windialogs.cpp index 52585196c0..4c055dd63c 100644 --- a/elenasrc3/ide/windows/windialogs.cpp +++ b/elenasrc3/ide/windows/windialogs.cpp @@ -1,12 +1,13 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // WinAPI: Static dialog implementations -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include #include "windialogs.h" +#include "windows/wincanvas.h" #include "Resource.h" #include "eng/messages.h" @@ -114,6 +115,40 @@ bool FileDialog :: saveFile(path_t ext, PathString& path) else return false; } +// --- FontDialog --- + +FontDialog :: FontDialog(HINSTANCE instance, WindowBase* owner) +{ + _owner = owner; + + // Initialize CHOOSEFONT + ZeroMemory(&_lf, sizeof(_lf)); + ZeroMemory(&_cf, sizeof(_cf)); + _cf.lStructSize = sizeof(_cf); + _cf.hwndOwner = owner->handle(); + _cf.lpLogFont = &_lf; + _cf.Flags = CF_SCREENFONTS; +} + +bool FontDialog :: selectFont(FontInfo& fontInfo) +{ + HDC hdc = ::GetDC(_owner->handle()); + + _lf.lfHeight = Font::fromSize(hdc, fontInfo.size); + StrUtil::move(_lf.lfFaceName, fontInfo.name.str(), fontInfo.name.length() + 1); + + _cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT | CF_TTONLY; + if (ChooseFont(&_cf) == TRUE) { + fontInfo.size = Font::toSize(hdc, _lf.lfHeight); + fontInfo.name.copy(_lf.lfFaceName); + + return true; + } + return false; +} + +// --- MessageDialog --- + MessageDialogBase::Answer MessageDialog :: question(text_str message, text_str param) { WideMessage wideMessage(message); @@ -446,15 +481,8 @@ void EditorSettings::onCreate() setCheckState(IDC_EDITOR_HIGHLIGHSYNTAXFLAG, _model->highlightSyntax); setCheckState(IDC_EDITOR_LINENUMBERFLAG, _model->lineNumbersVisible); - // populate font size combo box - String size; - for (int i = 8; i < 25; i++) { - size.appendInt(i); - addComboBoxItem(IDC_EDITOR_FONTSIZE, size.str()); - size.clear(); - } - - setComboBoxIndex(IDC_EDITOR_FONTSIZE, _model->fontSize - 8); + setIntText(IDC_EDITOR_TABSIZE, _model->settings.tabSize); + setIntText(IDC_EDITOR_SCROLLOFFSET, _model->scrollOffset); } void EditorSettings :: onOK() @@ -463,16 +491,21 @@ void EditorSettings :: onOK() if (index != -1) _model->schemeIndex = index; - int fontSize = getComboBoxIndex(IDC_EDITOR_COLORSCHEME) + 8; - if (_model->fontSize != fontSize) { - _model->fontSize = fontSize; - } - bool value = getCheckState(IDC_EDITOR_HIGHLIGHSYNTAXFLAG); if (_model->highlightSyntax != value) _model->setHighlightMode(value); _model->lineNumbersVisible = getCheckState(IDC_EDITOR_LINENUMBERFLAG); + + int intValue = getIntText(IDC_EDITOR_TABSIZE); + if (intValue > 0 && intValue < 100) + _model->settings.tabSize = intValue; + + intValue = getIntText(IDC_EDITOR_SCROLLOFFSET); + if (intValue > 0 && intValue < 100) + _model->scrollOffset = intValue; + + _model->refreshSettings(); } bool EditorSettings :: showModal() @@ -490,9 +523,12 @@ IDESettings :: IDESettings(HINSTANCE instance, WindowBase* owner, IDEModel* mode void IDESettings :: onCreate() { + loadFontList(); + setCheckState(IDC_IDE_REMEMBERPATH, _model->rememberLastPath); setCheckState(IDC_IDE_REMEMBERPROJECT, _model->rememberLastProject); setCheckState(IDC_IDE_PERSIST_CONSOLE, _model->projectModel.withPersistentConsole); + setCheckState(IDC_IDE_INCLUDE_APPPATH, _model->projectModel.includeAppPath2PathsTemporally); setCheckState(IDC_IDE_APPMAXIMIZED, _model->appMaximized); setCheckState(IDC_IDE_AUTORECOMPILE, _model->projectModel.autoRecompile); setCheckState(IDC_IDE_AUTOSAVE, _model->autoSave); @@ -504,6 +540,7 @@ void IDESettings :: onOK() _model->rememberLastProject = getCheckState(IDC_IDE_REMEMBERPROJECT); _model->appMaximized = getCheckState(IDC_IDE_APPMAXIMIZED); _model->projectModel.withPersistentConsole = getCheckState(IDC_IDE_PERSIST_CONSOLE); + _model->projectModel.includeAppPath2PathsTemporally = getCheckState(IDC_IDE_INCLUDE_APPPATH); _model->projectModel.autoRecompile = getCheckState(IDC_IDE_AUTORECOMPILE); _model->autoSave = getCheckState(IDC_IDE_AUTOSAVE); } @@ -513,6 +550,15 @@ bool IDESettings :: showModal() return show() == IDOK; } +void IDESettings :: loadFontList() +{ + //LOGFONT lf; + //memset(&lf, 0, sizeof(lf)); + //lf.lfCharSet = DEFAULT_CHARSET; + + //EnumFontFamiliesEx(screenDC, &lf, GetFontsCallback, NULL, 0) +} + // --- DebuggerSettings --- DebuggerSettings :: DebuggerSettings(HINSTANCE instance, WindowBase* owner, ProjectModel* model) diff --git a/elenasrc3/ide/windows/windialogs.h b/elenasrc3/ide/windows/windialogs.h index 988f38dfd7..da427f172e 100644 --- a/elenasrc3/ide/windows/windialogs.h +++ b/elenasrc3/ide/windows/windialogs.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // Win32: Static dialogs header -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef WINDIALOGS_H @@ -47,6 +47,20 @@ namespace elena_lang const wchar_t* initialDir = nullptr); }; + // --- FontDialog --- + class FontDialog : public FontDialogBase + { + WindowBase* _owner; + + CHOOSEFONT _cf; + LOGFONT _lf; + + public: + bool selectFont(FontInfo& fontInfo) override; + + FontDialog(HINSTANCE instance, WindowBase* owner); + }; + class MessageDialog : public MessageDialogBase { WindowBase* _owner; @@ -149,6 +163,8 @@ namespace elena_lang void onCreate() override; void onOK() override; + void loadFontList(); + public: bool showModal() override; diff --git a/elenasrc3/ide/windows/winide.cpp b/elenasrc3/ide/windows/winide.cpp index 3e0cf3871c..3195f5dcd7 100644 --- a/elenasrc3/ide/windows/winide.cpp +++ b/elenasrc3/ide/windows/winide.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // WinAPI IDE Window Implementation File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include @@ -264,6 +264,7 @@ IDEWindow :: IDEWindow(wstr_t title, IDEController* controller, IDEModel* model, _recentProjectList(controller, model, IDM_FILE_PROJECTS), aboutDialog(instance, this), editorSettingsDialog(instance, this, model->viewModel()), + fontSettingsDialog(instance, this), ideSettingsDialog(instance, this, model), debuggerSettingsDialog(instance, this, &model->projectModel), _docViewListener(nullptr) @@ -934,6 +935,9 @@ bool IDEWindow :: onCommand(int command) case IDM_EDITOR_OPTIONS: _controller->doConfigureEditorSettings(editorSettingsDialog, _model); break; + case IDM_EDITOR_FONT_OPTIONS: + _controller->doConfigureFontSettings(fontSettingsDialog, _model); + break; case IDM_IDE_OPTIONS: _controller->doConfigureIDESettings(ideSettingsDialog, _model); break; @@ -1039,9 +1043,9 @@ void IDEWindow :: onContextMenu(ContextMenuNMHDR* rec) ContextMenu* menu = static_cast(_children[_model->ideScheme.editorContextMenu]); - menu->enableMenuItemById(IDM_EDIT_CUT, rec->hasSelection); - menu->enableMenuItemById(IDM_EDIT_COPY, rec->hasSelection); - menu->enableMenuItemById(IDM_EDIT_PASTE, Clipboard::isAvailable()); + enableMenuItemById(IDM_EDIT_CUT, rec->hasSelection, true); + enableMenuItemById(IDM_EDIT_COPY, rec->hasSelection, true); + enableMenuItemById(IDM_EDIT_PASTE, Clipboard::isAvailable(), true); menu->show(_handle, p); } @@ -1131,6 +1135,7 @@ void IDEWindow :: onTextModelChange(TextViewModelNMHDR* rec) { if (test(rec->status, STATUS_COLORSCHEME_CHANGED)) { onColorSchemeChange(); + rec->docStatus.frameChanged = true; } onDocumentUpdate(rec->docStatus); @@ -1344,8 +1349,8 @@ void IDEWindow :: onDocumentUpdate(DocumentChangeStatus& changeStatus) bool isSelected = docInfo ? docInfo->hasSelection() : false; - menu->enableMenuItemById(IDM_EDIT_COPY, isSelected); - menu->enableMenuItemById(IDM_EDIT_CUT, isSelected); + enableMenuItemById(IDM_EDIT_COPY, isSelected, true); + enableMenuItemById(IDM_EDIT_CUT, isSelected, true); menu->enableMenuItemById(IDM_EDIT_COMMENT, isSelected); menu->enableMenuItemById(IDM_EDIT_UNCOMMENT, isSelected); menu->enableMenuItemById(IDM_EDIT_DELETE, isSelected); @@ -1353,8 +1358,8 @@ void IDEWindow :: onDocumentUpdate(DocumentChangeStatus& changeStatus) if (changeStatus.textChanged) { MenuBase* menu = dynamic_cast(_children[_model->ideScheme.menu]); - menu->enableMenuItemById(IDM_EDIT_UNDO, docInfo ? docInfo->canUndo() : false); - menu->enableMenuItemById(IDM_EDIT_REDO, docInfo ? docInfo->canRedo() : false); + enableMenuItemById(IDM_EDIT_UNDO, docInfo ? docInfo->canUndo() : false, true); + enableMenuItemById(IDM_EDIT_REDO, docInfo ? docInfo->canRedo() : false, true); } if (docInfo) { @@ -1459,3 +1464,24 @@ void IDEWindow :: onColorSchemeChange() refresh(); } + +void IDEWindow :: onDropFiles(HDROP hDrop) +{ + TCHAR szName[MAX_PATH]; + + int count = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH); + for (int i = 0; i < count; i++) + { + DragQueryFile(hDrop, i, szName, MAX_PATH); + + if(PathUtil::checkExtension(path_t(szName), "l")) { + _controller->doOpenFile(_model, path_t(szName)); + } + else if (PathUtil::checkExtension(path_t(szName), "prj")) { + _controller->doOpenProject(fileDialog, projectDialog, messageDialog, _model, path_t(szName)); + break; + } + } + + DragFinish(hDrop); +} diff --git a/elenasrc3/ide/windows/winide.h b/elenasrc3/ide/windows/winide.h index 7786668c9c..db4625e20a 100644 --- a/elenasrc3/ide/windows/winide.h +++ b/elenasrc3/ide/windows/winide.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // WinAPI IDE Window Header File -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef WINIDE_H @@ -127,6 +127,7 @@ namespace elena_lang EditorSettings editorSettingsDialog; IDESettings ideSettingsDialog; DebuggerSettings debuggerSettingsDialog; + FontDialog fontSettingsDialog; ViewFactoryBase* _viewFactory; @@ -185,7 +186,6 @@ namespace elena_lang void onProjectChange(bool empty); void onProjectRefresh(bool empty); - void onProjectViewSel(int index); void onColorSchemeChange(); @@ -244,6 +244,8 @@ namespace elena_lang void onDebuggerSourceNotFound(); void onDocumentUpdate(DocumentChangeStatus& changeStatus); + void onDropFiles(HDROP hDrop) override; + public: void populate(size_t counter, GUIControlBase** children) override; diff --git a/elenasrc3/ldbg/ldbg_common.h b/elenasrc3/ldbg/ldbg_common.h deleted file mode 100644 index ed7a820be3..0000000000 --- a/elenasrc3/ldbg/ldbg_common.h +++ /dev/null @@ -1,28 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA command-Line Debugger Adapter -// -// This file contains LDBG comment declaration -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#ifndef LDBG_COMMON -#define LDBG_COMMON - -#if defined(_MSC_VER) - -#include "windows\winevents.h" - -#else - -#endif - -namespace elena_lang -{ - constexpr auto LDBG_EVENT_COUNT = 1; - constexpr auto LDBF_CONFIGURED = 0; - - typedef EventManager DPAEventManager; -} - -#endif // LDBG_COMMON diff --git a/elenasrc3/ldbg/ldbg_const.h b/elenasrc3/ldbg/ldbg_const.h deleted file mode 100644 index 43d78ac60f..0000000000 --- a/elenasrc3/ldbg/ldbg_const.h +++ /dev/null @@ -1 +0,0 @@ -#define LDBG_REVISION_NUMBER 0x0002 diff --git a/elenasrc3/ldbg/ldbg_session.cpp b/elenasrc3/ldbg/ldbg_session.cpp deleted file mode 100644 index e6877fe69c..0000000000 --- a/elenasrc3/ldbg/ldbg_session.cpp +++ /dev/null @@ -1,51 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA command-Line Debugger Adapter -// -// This file contains DPA Session wrapper implementation -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#include "ldbg_session.h" -#include "common.h" - -using namespace elena_lang; - -// --- DPASessionWrapper --- - -DPASessionWrapper :: DPASessionWrapper() -{ - _events.init(-1); -} - -DPASessionWrapper :: ~DPASessionWrapper() -{ - freeobj(_session); -} - -void DPASessionWrapper :: prepare() -{ - _session = new dpa::Session(); - - // The ConfigurationDone request is made by the client once all configuration - // requests have been made. - - //session->registerHandler([&](const dap::ConfigurationDoneRequest&) { - // configured.fire(); - // return dap::ConfigurationDoneResponse(); - // }); - -} - -void DPASessionWrapper :: bind() -{ - _session->connect(); -} - -void DPASessionWrapper :: run() -{ - _session->start(); - - // Wait for the ConfigurationDone request to be made. - _events.waitForEvent(LDBF_CONFIGURED); -} diff --git a/elenasrc3/ldbg/ldbg_session.h b/elenasrc3/ldbg/ldbg_session.h deleted file mode 100644 index 8a8015d619..0000000000 --- a/elenasrc3/ldbg/ldbg_session.h +++ /dev/null @@ -1,33 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA command-Line Debugger Adapter -// -// This file contains DPA Session wrapper declaration -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#ifndef LDBG_SESSION_H -#define LDBG_SESSION_H - -#include "dpa_session.h" -#include "ldbg_common.h" - -namespace elena_lang -{ - class DPASessionWrapper - { - DPAEventManager _events; - - dpa::Session* _session; - - public: - void prepare(); - void bind(); - void run(); - - DPASessionWrapper(); - virtual ~DPASessionWrapper(); - }; -} - -#endif \ No newline at end of file diff --git a/elenasrc3/ldbg/vs/Resource.rc b/elenasrc3/ldbg/vs/Resource.rc deleted file mode 100644 index fcf4fce297..0000000000 --- a/elenasrc3/ldbg/vs/Resource.rc +++ /dev/null @@ -1,60 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) -LANGUAGE 7, 1 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION ENGINE_MAJOR_VERSION,ENGINE_MINOR_VERSION,LDBG_REVISION_NUMBER,0 - PRODUCTVERSION ENGINE_MAJOR_VERSION,ENGINE_MINOR_VERSION,0,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x0L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040004b0" - BEGIN - VALUE "CompanyName", "ELENA Programming Language by Alex Rakov" - VALUE "FileDescription", "ELENA debugger adapter" - VALUE "FileVersion", VER_FILE_VERSION_STR "\0" - VALUE "InternalName", "TODO: " - VALUE "LegalCopyright", "Copyright (C) 2024" - VALUE "OriginalFilename", "elc" - VALUE "ProductName", "ELENA Programming Language" - VALUE "ProductVersion", VER_PRODUCT_VERSION_STR "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x400, 1200 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/elenasrc3/ldbg/vs/ldbg.vcxproj b/elenasrc3/ldbg/vs/ldbg.vcxproj deleted file mode 100644 index e953b5af02..0000000000 --- a/elenasrc3/ldbg/vs/ldbg.vcxproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {60FE12CF-0DA9-4266-9C0F-F544DB115020} - ConsoleApplication1 - 10.0 - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - ..\..\..\bin\ - ..\..\temp\ldbg\ - elena-dpa - - - false - ..\..\..\bin\ - ..\..\temp\ldbg\ - elena-dpa - - - true - ..\..\..\bin\ - ..\..\temp\ldbg64\ - elena64-dpa - - - false - ..\..\..\bin\ - ..\..\temp\ldbg64\ - elena64-dpa - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\common;..\..\engine;..\..\dpa;..\windows;..;%(AdditionalIncludeDirectories) - stdcpp17 - - - Console - true - - - ..;..\..\engine - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\common;..\..\engine;..\..\dpa;..\windows;..;%(AdditionalIncludeDirectories) - stdcpp17 - - - Console - true - true - true - - - ..;..\..\engine - - - - - Level3 - true - _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\common;..\..\engine;..\..\dpa;..\windows;..;%(AdditionalIncludeDirectories) - stdcpp17 - - - Console - true - - - ..;..\..\engine - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\common;..\..\engine;..\..\dpa;..\windows;..;%(AdditionalIncludeDirectories) - stdcpp17 - - - Console - true - true - true - - - ..;..\..\engine - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/elenasrc3/ldbg/vs/resource.h b/elenasrc3/ldbg/vs/resource.h deleted file mode 100644 index 8dc044e928..0000000000 --- a/elenasrc3/ldbg/vs/resource.h +++ /dev/null @@ -1,29 +0,0 @@ -#include "elenaconst.h" -#include "ldbg_const.h" - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Resource.rc - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif - -#define STRINGIZE2(s) #s -#define STRINGIZE(s) STRINGIZE2(s) - -#define VER_FILE_VERSION_STR STRINGIZE(ENGINE_MAJOR_VERSION) \ - "." STRINGIZE(ENGINE_MINOR_VERSION) \ - "." STRINGIZE(LDBG_REVISION_NUMBER) \ - ".0" - -#define VER_PRODUCT_VERSION_STR STRINGIZE(ENGINE_MAJOR_VERSION) \ - "." STRINGIZE(ENGINE_MINOR_VERSION) \ - ".0.0" diff --git a/elenasrc3/ldbg/windows/ldbg.cpp b/elenasrc3/ldbg/windows/ldbg.cpp deleted file mode 100644 index 417e692c09..0000000000 --- a/elenasrc3/ldbg/windows/ldbg.cpp +++ /dev/null @@ -1,32 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA command-Line Debugger Adapter -// -// This file contains the main body of the win32 / win64 -// ELENA Debugger Adapter -// -// (C)2024, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#include "ldbg_session.h" -#include "common.h" - -using namespace elena_lang; - -int main() -{ - printf("Starting\n"); - - int n = 0; - while (true) - { - n++; - } - - DPASessionWrapper session; - - session.prepare(); - session.bind(); - session.run(); - - return 0; -} \ No newline at end of file diff --git a/elenasrc3/tools/asmc/asmconst.h b/elenasrc3/tools/asmc/asmconst.h index a1545d57d6..34b5d5b2e4 100644 --- a/elenasrc3/tools/asmc/asmconst.h +++ b/elenasrc3/tools/asmc/asmconst.h @@ -12,7 +12,7 @@ namespace elena_lang { - #define ASM_REVISION_NUMBER 0x000B + #define ASM_REVISION_NUMBER 0x000D constexpr auto N_ARGUMENT1 = "__n_1"; constexpr auto N_ARGUMENT2 = "__n_2"; diff --git a/elenasrc3/tools/asmc/ppc64assembler.cpp b/elenasrc3/tools/asmc/ppc64assembler.cpp index 1c977a15fb..b127cd0bb3 100644 --- a/elenasrc3/tools/asmc/ppc64assembler.cpp +++ b/elenasrc3/tools/asmc/ppc64assembler.cpp @@ -1352,6 +1352,22 @@ void PPC64Assembler :: compileLFD(ScriptToken& tokenInfo, MemoryWriter& writer) else throw SyntaxError(ASM_INVALID_COMMAND, tokenInfo.lineInfo); } +void PPC64Assembler :: compileLFIWAX(ScriptToken& tokenInfo, MemoryWriter& writer) +{ + PPCOperand frt = readRegister(tokenInfo, ASM_INVALID_SOURCE); + + checkComma(tokenInfo); + + int d = 0; + PPCOperand rb = readRegister(tokenInfo, ASM_INVALID_SOURCE); + + if (frt.isFPR() && rb.isGPR()) { + writer.writeDWord(PPCHelper::makeXCommand(31, frt.type, PPCOperandType::None, rb.type, 855, 0)); + } + else throw SyntaxError(ASM_INVALID_COMMAND, tokenInfo.lineInfo); +} + + void PPC64Assembler :: compileLHZ(ScriptToken& tokenInfo, MemoryWriter& writer) { PPCOperand rs = readRegister(tokenInfo, ASM_INVALID_SOURCE); @@ -2128,6 +2144,9 @@ bool PPC64Assembler :: compileLOpCode(ScriptToken& tokenInfo, MemoryWriter& writ else if (tokenInfo.compare("lfd")) { compileLFD(tokenInfo, writer); } + else if (tokenInfo.compare("lfiwax")) { + compileLFIWAX(tokenInfo, writer); + } else if (tokenInfo.compare("lha")) { compileLHA(tokenInfo, writer); } diff --git a/elenasrc3/tools/asmc/ppc64assembler.h b/elenasrc3/tools/asmc/ppc64assembler.h index 52c864e1c1..b86dde0676 100644 --- a/elenasrc3/tools/asmc/ppc64assembler.h +++ b/elenasrc3/tools/asmc/ppc64assembler.h @@ -113,6 +113,7 @@ namespace elena_lang void compileORI(ScriptToken& tokenInfo, MemoryWriter& writer); void compileLBZ(ScriptToken& tokenInfo, MemoryWriter& writer); void compileLFD(ScriptToken& tokenInfo, MemoryWriter& writer); + void compileLFIWAX(ScriptToken& tokenInfo, MemoryWriter& writer); void compileLHZ(ScriptToken& tokenInfo, MemoryWriter& writer); void compileLHA(ScriptToken& tokenInfo, MemoryWriter& writer); void compileLWZ(ScriptToken& tokenInfo, MemoryWriter& writer); diff --git a/elenasrc3/tools/sg/sg.cpp b/elenasrc3/tools/sg/sg.cpp index 3797dd97af..69a17005c0 100644 --- a/elenasrc3/tools/sg/sg.cpp +++ b/elenasrc3/tools/sg/sg.cpp @@ -1,14 +1,13 @@ //--------------------------------------------------------------------------- // E L E N A p r o j e c t // Command line syntax generator main file -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "sgconst.h" #include "elena.h" #include "scriptreader.h" #include "parsertable.h" -#include "tree.h" using namespace elena_lang; @@ -24,7 +23,6 @@ constexpr auto DEFAULT_ENCODING = FileEncoding::UTF8; #endif -typedef Tree SyntaxTempTree; typedef Map Coordinates; parse_key_t lastKey = 0; diff --git a/elenasrc3/tools/sg/sgconst.h b/elenasrc3/tools/sg/sgconst.h index 9044ee45a5..243e8ac90b 100644 --- a/elenasrc3/tools/sg/sgconst.h +++ b/elenasrc3/tools/sg/sgconst.h @@ -3,7 +3,7 @@ // // This file contains the compiler common interfaces & types // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef CLICONST @@ -12,9 +12,9 @@ namespace elena_lang { - #define SG_REVISION_NUMBER 0x0003 + #define SG_REVISION_NUMBER 0x0004 - constexpr auto SG_GREETING = "ELENA command line syntax generator %d.%d.%d (C)2005-2024 by Aleksey Rakov\n"; + constexpr auto SG_GREETING = "ELENA command line syntax generator %d.%d.%d (C)2005-2025 by Aleksey Rakov\n"; constexpr auto SG_HELP = "sg-cli [-cp]\n"; diff --git a/examples60/console/build.bat b/examples60/console/build.bat deleted file mode 100644 index 38dc676912..0000000000 --- a/examples60/console/build.bat +++ /dev/null @@ -1,89 +0,0 @@ -..\..\bin\elena-cli helloworld\helloworld.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -lintsum sum\sum.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -lrealsum sum\sum.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pwords words.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pbinary binary.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pbsort bsort.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pgoods goods.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pcollatz collatz.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli datetime\datetime.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli matrix\matrix.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ppi pi.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ppi2 pi2.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -prandom random.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -preplace replace.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli trans\translit.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli regex\regex.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -@echo off -goto:eof -@echo on - -:CompilerError -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on diff --git a/examples60/console/build.script b/examples60/console/build.script deleted file mode 100755 index cf8cad7137..0000000000 --- a/examples60/console/build.script +++ /dev/null @@ -1,69 +0,0 @@ - ../../bin/elena-cli helloworld/helloworld.project - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli sum/intsum.project - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli sum/realsum.project - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pwords words.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pbinary binary.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pbsort bsort.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pgoods goods.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi diff --git a/examples60/console/build64.bat b/examples60/console/build64.bat deleted file mode 100644 index 389505b1d5..0000000000 --- a/examples60/console/build64.bat +++ /dev/null @@ -1,44 +0,0 @@ -..\..\bin\elena64-cli helloworld\helloworld.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -lintsum sum\sum.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -lrealsum sum\sum.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pwords words.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pbinary binary.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pbsort bsort.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pgoods goods.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -@echo off -goto:eof -@echo on - -:CompilerError -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on diff --git a/examples60/console/build_64.script b/examples60/console/build_64.script deleted file mode 100755 index 513141cd85..0000000000 --- a/examples60/console/build_64.script +++ /dev/null @@ -1,69 +0,0 @@ - ../../bin/elena64-cli helloworld/helloworld.project - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli sum/intsum.project - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli sum/realsum.project - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pwords words.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pbinary binary.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pbsort bsort.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pgoods goods.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi diff --git a/examples60/console/sum/intsum.project b/examples60/console/datetime/datetime.linux.prj similarity index 55% rename from examples60/console/sum/intsum.project rename to examples60/console/datetime/datetime.linux.prj index afbff69c11..431ce7a1e5 100644 --- a/examples60/console/sum/intsum.project +++ b/examples60/console/datetime/datetime.linux.prj @@ -1,35 +1,35 @@ - intsum + datetime - intsum64 + datetime64 - intsum64 + datetime64 - intsum64 + datetime64 - sum + datetime - sum.l + control.l - sum'IntSamplePrompt - extensions'Integer + extensions'ProgramLoop + datetime'Control \ No newline at end of file diff --git a/examples60/console/datetime/datetime.project b/examples60/console/datetime/datetime.project deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples60/console/goods/goods.l b/examples60/console/goods/goods.l index 35c8eb6984..08501a0047 100644 --- a/examples60/console/goods/goods.l +++ b/examples60/console/goods/goods.l @@ -88,7 +88,7 @@ public program() } }; - list.forEach(printingLn); + list.forEach(PrintingLn); Console.readChar() } diff --git a/examples60/console/helloworld/helloworld.project b/examples60/console/helloworld/helloworld.linux.prj similarity index 100% rename from examples60/console/helloworld/helloworld.project rename to examples60/console/helloworld/helloworld.linux.prj diff --git a/examples60/console/sum/realsum.project b/examples60/console/sum/realsum.project deleted file mode 100644 index c5fe4b90e2..0000000000 --- a/examples60/console/sum/realsum.project +++ /dev/null @@ -1,35 +0,0 @@ - - - - realsum - - - - - realsum64 - - - - - realsum64 - - - - - realsum64 - - - - sum - - - - - sum.l - - - - sum'RealSamplePrompt - extensions'Real - - \ No newline at end of file diff --git a/examples60/console/sum/sum.linux.prj b/examples60/console/sum/sum.linux.prj new file mode 100644 index 0000000000..c587181898 --- /dev/null +++ b/examples60/console/sum/sum.linux.prj @@ -0,0 +1,71 @@ + + + + + intsum + + + + + realsum + + + + + + + intsum64 + + + + + realsum64 + + + + + + + intsum64 + + + + + realsum64 + + + + + + + intsum64 + + + + + realsum64 + + + + + sum + + + + + sum.l + + + + + sum'IntSamplePrompt + extensions'Integer + + + + + sum'RealSamplePrompt + extensions'Real + + + \ No newline at end of file diff --git a/examples60/examples60.linux.prjcol b/examples60/examples60.linux.prjcol new file mode 100644 index 0000000000..c0b18a7b94 --- /dev/null +++ b/examples60/examples60.linux.prjcol @@ -0,0 +1,25 @@ + + + + console/helloworld/helloworld.linux.prj + console/binary/binary.l + console/bsort/bsort.l + console/collatz/collatz.l + console/datetime/datetime.linux.prj + console/goods/goods.l + console/matrix/matrix.prj + console/pi/pi.l + console/pi2/pi2.l + console/random/random.l + console/regex/regex.prj + console/replace/replace.l + console/trans/translit.linux.prj + console/sum/sum.linux.prj + console/words/words.l + + + files/textdb/textdb.l + files/textfile/textfile.l + + + \ No newline at end of file diff --git a/examples60/examples60.prjcol b/examples60/examples60.prjcol new file mode 100644 index 0000000000..2ed034d8ce --- /dev/null +++ b/examples60/examples60.prjcol @@ -0,0 +1,48 @@ + + + + console\helloworld\helloworld.prj + console\binary\binary.l + console\bsort\bsort.l + console\collatz\collatz.l + console\datetime\datetime.prj + console\goods\goods.l + console\matrix\matrix.prj + console\pi\pi.l + console\pi2\pi2.l + console\random\random.l + console\regex\regex.prj + console\replace\replace.l + console\trans\translit.prj + console\sum\sum.prj + console\words\words.l + + + db\sqlite\sqlite_test.prj + + + files\textdb\textdb.l + files\textfile\textfile.l + + + gui\agenda\agenda.prj + gui\c_a_g\c_area_gui.prj + gui\graphs\graphs.prj + gui\helloworld\xforms_hellowindow.prj + + + net\httpget\httpget.prj + + + scripts\calc\calc.prj + scripts\interpreter\interpreter.l + scripts\js\jsinterpreter.prj + scripts\ls\lsinterpreter.prj + + + scripts\async\asyncsamples.prj + scripts\tasks\tasksamples.prj + scripts\threadpool\threadpoolsamples.prj + + + \ No newline at end of file diff --git a/examples60/files/textdb/textdb.l b/examples60/files/textdb/textdb.l index d86b8066a8..8304716bf6 100644 --- a/examples60/files/textdb/textdb.l +++ b/examples60/files/textdb/textdb.l @@ -109,7 +109,7 @@ public program() }; // print the list - db.forEach(printingLn); + db.forEach(PrintingLn); Console.readChar() } \ No newline at end of file diff --git a/examples60/files/textfile/textfile.l b/examples60/files/textfile/textfile.l index 550ddf5674..9abc9c10f3 100644 --- a/examples60/files/textfile/textfile.l +++ b/examples60/files/textfile/textfile.l @@ -7,7 +7,7 @@ public program() if (Program_arguments.Length == 1) { Console.writeLine("Please provide the path to the file to view"); AbortException.raise() }; - File.assign(Program_arguments[1]).forEachLine(printingLn); + File.assign(Program_arguments[1]).forEachLine(PrintingLn); Console.readChar() // wait for any key } \ No newline at end of file diff --git a/examples60/net/chat/server/server.l b/examples60/net/chat/server/server.l index 5adc91bcc6..6df188b06b 100644 --- a/examples60/net/chat/server/server.l +++ b/examples60/net/chat/server/server.l @@ -65,7 +65,7 @@ public sealed ChatServer }; } catch(Exception ex) { - console.writeLine(ex); + Console.writeLine(ex); }; ^ true diff --git a/examples60/net/httpget/httpget.l b/examples60/net/httpget/httpget.l new file mode 100644 index 0000000000..fee94910a1 --- /dev/null +++ b/examples60/net/httpget/httpget.l @@ -0,0 +1,56 @@ +/*namespace HttpClientStatus; + +class Program +{ + static async Task Main(string[] args) + { + using var client = new HttpClient(); + + var result = await client.GetAsync("http://webcode.me"); + Console.WriteLine(result.StatusCode); + } +} + +using var client = new HttpClient(); +var content = await client.GetStringAsync("http://webcode.me"); + +Console.WriteLine(content); + +var url = "http://webcode.me"; + +using var client = new HttpClient(); + +var msg = new HttpRequestMessage(HttpMethod.Get, url); +msg.Headers.Add("User-Agent", "C# Program"); +var res = await client.SendAsync(msg); + +var content = await res.Content.ReadAsStringAsync(); + +Console.WriteLine(content); + +*/ + +import net'http; +import system'threading; + +singleton Tester +{ + async Task browse() + { + using(HttpClient client := new HttpClient()) + { + client.Headers.add("User-agent", "MyUserAgent"); + + HttpResponse response := :await client.getAsync("http://www.google.com"); + + string content := :await response.readAsStringAsync(); + + Console.writeLine(content); + }; + } +} + +public program() +{ + Tester.browse().Result; +} diff --git a/examples60/net/httpget/httpget.prj b/examples60/net/httpget/httpget.prj new file mode 100644 index 0000000000..3f332c7d12 --- /dev/null +++ b/examples60/net/httpget/httpget.prj @@ -0,0 +1,13 @@ + + + + httpget.l + + + + httpget + + + httpget + + \ No newline at end of file diff --git a/examples60/rosetta/accumulator/accumulator.l b/examples60/rosetta/accumulator/accumulator.l index 576fbfca18..786178073d 100644 --- a/examples60/rosetta/accumulator/accumulator.l +++ b/examples60/rosetta/accumulator/accumulator.l @@ -24,5 +24,5 @@ public program() var y := accumulator(3); - console.write(x(2.3r)) + Console.write(x(2.3r)) } diff --git a/examples60/rosetta/ackermann/ackermann.l b/examples60/rosetta/ackermann/ackermann.l index dc27ca340c..fa72860641 100644 --- a/examples60/rosetta/ackermann/ackermann.l +++ b/examples60/rosetta/ackermann/ackermann.l @@ -34,9 +34,9 @@ public program() { for(int j := 0; j <= 5; j += 1) { - console.printLine("A(",i,",",j,")=",ackermann(i,j)) + Console.printLine("A(",i,",",j,")=",ackermann(i,j)) } }; - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/addfield/addfield.l b/examples60/rosetta/addfield/addfield.l index d9beda584a..c1edc9ea5a 100644 --- a/examples60/rosetta/addfield/addfield.l +++ b/examples60/rosetta/addfield/addfield.l @@ -19,7 +19,7 @@ public program() object.foo := "bar"; - console.printLine(object,".foo=",object.foo); + Console.printLine(object,".foo=",object.foo); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/amb/amb.l b/examples60/rosetta/amb/amb.l index ebc57682b0..957ea4cd9d 100644 --- a/examples60/rosetta/amb/amb.l +++ b/examples60/rosetta/amb/amb.l @@ -76,14 +76,14 @@ public program2() try { ambOperator.for(new object[]{1,2,4}, new object[]{4,5,6}).seek::(a,b => a * b == 8).do:: - (a,b){ console.printLine(a," * ",b," = 8") }; + (a,b){ Console.printLine(a," * ",b," = 8") }; } catch(Exception e) { - console.printLine("AMB is angry") + Console.printLine("AMB is angry") }; - console.readChar() + Console.readChar() } public program() @@ -97,12 +97,12 @@ public program() new object[]{"walked", "treaded", "grows"}, new object[]{"slowly", "quickly"}) .seek::(a,b,c,d => joinable(a,b) && joinable(b,c) && joinable(c,d) ) - .do::(a,b,c,d) { console.printLine(a," ",b," ",c," ",d) } + .do::(a,b,c,d) { Console.printLine(a," ",b," ",c," ",d) } } catch(Exception e) { - console.printLine("AMB is angry") + Console.printLine("AMB is angry") }; - console.readChar() + Console.readChar() } diff --git a/examples60/rosetta/anagram/anagram.l b/examples60/rosetta/anagram/anagram.l index 026d65006b..13a16cb8fe 100644 --- a/examples60/rosetta/anagram/anagram.l +++ b/examples60/rosetta/anagram/anagram.l @@ -35,13 +35,13 @@ public program() dictionary.Values .quickSort::(former,later => former.Item2.Length > later.Item2.Length ) .top(20) - .forEach::(pair){ console.printLine(pair.Item2) }; + .forEach::(pair){ Console.printLine(pair.Item2) }; var end := Now; var diff := end - start; - console.printLine("Time elapsed in msec:",diff.Milliseconds); + Console.printLine("Time elapsed in msec:",diff.Milliseconds); - console.readChar() + Console.readChar() } diff --git a/examples60/rosetta/anonymrec/anonymrec.l b/examples60/rosetta/anonymrec/anonymrec.l index c848521290..3ff9e9414d 100644 --- a/examples60/rosetta/anonymrec/anonymrec.l +++ b/examples60/rosetta/anonymrec/anonymrec.l @@ -23,16 +23,16 @@ public program() { for (int i := -1; i <= 10; i += 1) { - console.print("fib(",i,")="); + Console.print("fib(",i,")="); try { - console.printLine(fib(i)) + Console.printLine(fib(i)) } catch(Exception e) { - console.printLine("invalid") + Console.printLine("invalid") } }; - console.readChar() + Console.readChar() } diff --git a/examples60/rosetta/aplusb/aplusb.l b/examples60/rosetta/aplusb/aplusb.l index 10c12879b2..abad785ec7 100644 --- a/examples60/rosetta/aplusb/aplusb.l +++ b/examples60/rosetta/aplusb/aplusb.l @@ -19,7 +19,7 @@ import extensions; public program() { - console.printLine(console.readLine() + Console.printLine(Console.readLine() .split() .selectBy(mssgconst toInt[1]) .summarize()) @@ -30,5 +30,5 @@ public program_alt() var A := Integer.new(); var B := Integer.new(); - console.loadLine(A,B).printLine(A + B) + Console.loadLine(A,B).printLine(A + B) } \ No newline at end of file diff --git a/examples60/rosetta/applycallback/applycallback.l b/examples60/rosetta/applycallback/applycallback.l index d7989321bb..1ce8568a95 100644 --- a/examples60/rosetta/applycallback/applycallback.l +++ b/examples60/rosetta/applycallback/applycallback.l @@ -2,7 +2,7 @@ import system'routines; -PrintSecondPower(n){ console.writeLine(n * n) } +PrintSecondPower(n){ Console.writeLine(n * n) } public program() { diff --git a/examples60/rosetta/arithmeticint/arithmeticint.l b/examples60/rosetta/arithmeticint/arithmeticint.l index e797996ac4..78b298b154 100644 --- a/examples60/rosetta/arithmeticint/arithmeticint.l +++ b/examples60/rosetta/arithmeticint/arithmeticint.l @@ -8,13 +8,13 @@ import extensions; public program() { - var a := console.loadLineTo(new Integer()); - var b := console.loadLineTo(new Integer()); + var a := Console.loadLineTo(new Integer()); + var b := Console.loadLineTo(new Integer()); - console.printLine(a," + ",b," = ",a + b); - console.printLine(a," - ",b," = ",a - b); - console.printLine(a," * ",b," = ",a * b); - console.printLine(a," / ",b," = ",a / b); // truncates towards 0 - console.printLine(a," % ",b," = ",a.mod(b)); // matches sign of first operand - console.printLine(a," ^ ",b," = ",a ^ b); + Console.printLine(a," + ",b," = ",a + b); + Console.printLine(a," - ",b," = ",a - b); + Console.printLine(a," * ",b," = ",a * b); + Console.printLine(a," / ",b," = ",a / b); // truncates towards 0 + Console.printLine(a," % ",b," = ",a.mod(b)); // matches sign of first operand + Console.printLine(a," ^ ",b," = ",a ^ b); } diff --git a/examples60/rosetta/arithmeval/arithmeval.l b/examples60/rosetta/arithmeval/arithmeval.l index 1f4fe9e5e7..0985cf817d 100644 --- a/examples60/rosetta/arithmeval/arithmeval.l +++ b/examples60/rosetta/arithmeval/arithmeval.l @@ -349,15 +349,15 @@ public program() var text := new StringWriter(); var parser := new Parser(); - while (console.readLine().writeTo(text).Length > 0) + while (Console.readLine().writeTo(text).Length > 0) { try { - console.printLine("=",parser.run(text)) + Console.printLine("=",parser.run(text)) } catch(Exception e) { - console.writeLine("Invalid Expression") + Console.writeLine("Invalid Expression") }; text.clear() diff --git a/examples60/rosetta/arithmmean/arithmmean.l b/examples60/rosetta/arithmmean/arithmmean.l index c20a5834f7..0cb8f44419 100644 --- a/examples60/rosetta/arithmmean/arithmmean.l +++ b/examples60/rosetta/arithmmean/arithmmean.l @@ -27,7 +27,7 @@ extension op public program() { var array := new int[]{1, 2, 3, 4, 5, 6, 7, 8}; - console.printLine( + Console.printLine( "Arithmetic mean of {",array.asEnumerable(),"} is ", array.average()).readChar() } \ No newline at end of file diff --git a/examples60/rosetta/arrayconcat/arrayconcat.l b/examples60/rosetta/arrayconcat/arrayconcat.l index d39caa90b4..a4fac7f736 100644 --- a/examples60/rosetta/arrayconcat/arrayconcat.l +++ b/examples60/rosetta/arrayconcat/arrayconcat.l @@ -6,7 +6,7 @@ public program() var a := new int[]{1,2,3}; var b := new int[]{4,5}; - console.printLine( + Console.printLine( "(",a.asEnumerable(),") + (",b.asEnumerable(), ") = (",(a + b).asEnumerable(),")").readChar(); } \ No newline at end of file diff --git a/examples60/rosetta/arraymode/arraymode.l b/examples60/rosetta/arraymode/arraymode.l index 0872dc6f23..7734c2074c 100644 --- a/examples60/rosetta/arraymode/arraymode.l +++ b/examples60/rosetta/arraymode/arraymode.l @@ -33,7 +33,7 @@ public program() var array2 := new int[]{1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17}; var array3 := new object[]{1, "blue", 2, 7.5r, 5, "green", "red", 5, 2, "blue", "white"}; - console + Console .printLine("mode of (",array1.asEnumerable(),") is (",array1.Mode,")") .printLine("mode of (",array2.asEnumerable(),") is (",array2.Mode,")") .printLine("mode of (",array3.asEnumerable(),") is (",array3.Mode,")") diff --git a/examples60/rosetta/arrays/arrays.l b/examples60/rosetta/arrays/arrays.l index 9563a011f3..e8e2ff83dd 100644 --- a/examples60/rosetta/arrays/arrays.l +++ b/examples60/rosetta/arrays/arrays.l @@ -24,7 +24,7 @@ public program() dynamicArray[2] := 3; - console.writeLine(array[0]); - console.writeLine(stackAllocatedArray[1]); - console.writeLine(dynamicArray[2]); + Console.writeLine(array[0]); + Console.writeLine(stackAllocatedArray[1]); + Console.writeLine(dynamicArray[2]); } \ No newline at end of file diff --git a/examples60/rosetta/associativearrays/associativearrays.l b/examples60/rosetta/associativearrays/associativearrays.l index 4fac8530b8..347d1fab67 100644 --- a/examples60/rosetta/associativearrays/associativearrays.l +++ b/examples60/rosetta/associativearrays/associativearrays.l @@ -18,5 +18,5 @@ public program() // Enumerate map.forEach:: - (tuple){ console.printLine(tuple.Item1," : ",tuple.Item2) } + (tuple){ Console.printLine(tuple.Item1," : ",tuple.Item2) } } \ No newline at end of file diff --git a/examples60/rosetta/bestshuffle/bestshuffle.l b/examples60/rosetta/bestshuffle/bestshuffle.l index 7f14c8db30..24a56ede00 100644 --- a/examples60/rosetta/bestshuffle/bestshuffle.l +++ b/examples60/rosetta/bestshuffle/bestshuffle.l @@ -45,8 +45,8 @@ public program() { var shuffled_s := s.Shuffled; - console.printLine("The best shuffle of ",s," is ",shuffled_s,"(",shuffled_s.score(s),")") + Console.printLine("The best shuffle of ",s," is ",shuffled_s,"(",shuffled_s.score(s),")") }; - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/binary/binary.l b/examples60/rosetta/binary/binary.l index 325eae47f4..eac8e61c8c 100644 --- a/examples60/rosetta/binary/binary.l +++ b/examples60/rosetta/binary/binary.l @@ -9,6 +9,6 @@ public program() { new int[]{5,50,9000}.forEach::(n) { - console.printLine(n.toString(2)) + Console.printLine(n.toString(2)) } } \ No newline at end of file diff --git a/examples60/rosetta/bitwise/bitwise.l b/examples60/rosetta/bitwise/bitwise.l index 871b382d61..982cb3478f 100644 --- a/examples60/rosetta/bitwise/bitwise.l +++ b/examples60/rosetta/bitwise/bitwise.l @@ -6,16 +6,16 @@ extension testOp { bitwiseTest(y) { - console.printLine(self," and ",y," = ",self.band(y)); - console.printLine(self," or ",y," = ",self.bor(y)); - console.printLine(self," xor ",y," = ",self.bxor(y)); - console.printLine("not ",self," = ",self.BInverted); - console.printLine(self," shr ",y," = ",self.shiftRight(y)); - console.printLine(self," shl ",y," = ",self.shiftLeft(y)); + Console.printLine(self," and ",y," = ",self.band(y)); + Console.printLine(self," or ",y," = ",self.bor(y)); + Console.printLine(self," xor ",y," = ",self.bxor(y)); + Console.printLine("not ",self," = ",self.BInverted); + Console.printLine(self," shr ",y," = ",self.shiftRight(y)); + Console.printLine(self," shl ",y," = ",self.shiftLeft(y)); } } public program() { - console.loadLineTo(new Integer()).bitwiseTest(console.loadLineTo(new Integer())) + Console.loadLineTo(new Integer()).bitwiseTest(Console.loadLineTo(new Integer())) } \ No newline at end of file diff --git a/examples60/rosetta/brackets/brackets.l b/examples60/rosetta/brackets/brackets.l index 2fa5b23266..88c1798b72 100644 --- a/examples60/rosetta/brackets/brackets.l +++ b/examples60/rosetta/brackets/brackets.l @@ -47,8 +47,8 @@ public program() { var str := randomBrackets(len); - console.printLine("""",str,"""",str.isBalanced ? " is balanced" : " is not balanced") + Console.printLine("""",str,"""",str.isBalanced ? " is balanced" : " is not balanced") }; - console.readChar() + Console.readChar() } diff --git a/examples60/rosetta/build.bat b/examples60/rosetta/build.bat deleted file mode 100644 index cca2779f25..0000000000 --- a/examples60/rosetta/build.bat +++ /dev/null @@ -1,289 +0,0 @@ -..\..\bin\elena-cli -packermann ackermann.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -paccumulator accumulator.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -paddfield addfield.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pamb amb.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -panagram anagram.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -panonymrec anonymrec.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -paplusb aplusb.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -papplycallback applycallback.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -parithmeticint arithmeticint.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -parithmeval arithmeval.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -parithmmean arithmmean.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -parrayconcat arrayconcat.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -parraymode arraymode.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -passociativearrays associativearrays.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -parrays arrays.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pbestshuffle bestshuffle.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pbinary binary.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pbitwise bitwise.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pbrackets brackets.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pbullscows bullscows.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pcaesar caesar.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pcharmatch charmatch.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pcalendar calendar.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pcombinations combinations.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pcomplist complist.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pdoors doors.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pdynamic_var dynamic_var.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pevolutionary evolutionary.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pfirstclass firstclass.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli gameoflife\gameoflife.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pknutalg knutalg.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ploop_multiple_arrays loopma.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pmanboy manboy.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pmedian median.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pninetynine ninetynine.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -preverse_words_in_string reverse_words.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli simple_windowed_app\simple_windowed_app.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -psmavg smavg.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pstring_append string_append.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pstring_case string_case.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pstring_comparison string_comparision.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pstring_concatenation string_concatenation.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pstring_interpolation string_interpolation.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pstring_matching string_matching.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pstring_prepend string_prepend.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ptokenizer tokenizer.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ptoppergroup toppergroup.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ptreeview treeview.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ptrigonometric trigonometric.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ptruncprime truncprime.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ptwelvestats twelvestats.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -ptwentyfour twentyfour.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pwireworld wireworld.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pycombinator ycombinator.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pzeckendorf_arithm zeckendorf_arithm.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena-cli -pzhangsuen zhangsuen.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -@echo off -goto:eof -@echo on - -:CompilerError -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on diff --git a/examples60/rosetta/build.script b/examples60/rosetta/build.script deleted file mode 100755 index 39d58f4095..0000000000 --- a/examples60/rosetta/build.script +++ /dev/null @@ -1,219 +0,0 @@ - ../../bin/elena-cli -packermann ackermann.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -paccumulator accumulator.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -paddfield addfield.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -panonymrec anonymrec.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -paplusb aplusb.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -papplycallback applycallback.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -parithmeticint arithmeticint.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -parithmeval arithmeval.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -parithmmean arithmmean.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -parrayconcat arrayconcat.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -parraymode arraymode.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -parrays arrays.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -passociativearrays associativearrays.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pbestshuffle bestshuffle.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pbinary binary.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pbitwise bitwise.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pbrackets brackets.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pbullscows bullscows.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pcaesar caesar.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pcharmatch charmatch.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli -pcalendar calendar.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena-cli gameoflife/gameoflife.prj - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi diff --git a/examples60/rosetta/build64.bat b/examples60/rosetta/build64.bat deleted file mode 100644 index b7ff68d03d..0000000000 --- a/examples60/rosetta/build64.bat +++ /dev/null @@ -1,289 +0,0 @@ -..\..\bin\elena64-cli -packermann ackermann.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -paccumulator accumulator.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -paddfield addfield.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pamb amb.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -panagram anagram.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -panonymrec anonymrec.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -paplusb aplusb.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -papplycallback applycallback.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -parithmeticint arithmeticint.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -parithmeval arithmeval.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -parithmmean arithmmean.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -parrayconcat arrayconcat.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -parraymode arraymode.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -passociativearrays associativearrays.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -parrays arrays.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pbestshuffle bestshuffle.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pbinary binary.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pbitwise bitwise.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pbrackets brackets.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pbullscows bullscows.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pcaesar caesar.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pcharmatch charmatch.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pcalendar calendar.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pcombinations combinations.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pcomplist complist.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pdoors doors.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pdynamic_var dynamic_var.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pevolutionary evolutionary.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pfirstclass firstclass.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli gameoflife\gameoflife.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pknutalg knutalg.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -ploop_multiple_arrays loopma.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pmanboy manboy.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pmedian median.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pninetynine ninetynine.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -preverse_words_in_string reverse_words.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli simple_windowed_app\simple_windowed_app.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -psmavg smavg.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pstring_append string_append.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pstring_case string_case.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pstring_comparison string_comparision.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pstring_concatenation string_concatenation.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pstring_interpolation string_interpolation.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pstring_matching string_matching.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pstring_prepend string_prepend.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -ptokenizer tokenizer.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -ptoppergroup toppergroup.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -ptreeview treeview.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -ptrigonometric trigonometric.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -ptruncprime truncprime.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -ptwelvestats twelvestats.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -ptwentyfour twentyfour.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pwireworld wireworld.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pycombinator ycombinator.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pzeckendorf_arithm zeckendorf_arithm.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -..\..\bin\elena64-cli -pzhangsuen zhangsuen.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -@echo off -goto:eof -@echo on - -:CompilerError -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on diff --git a/examples60/rosetta/build64.script b/examples60/rosetta/build64.script deleted file mode 100755 index 3cbfbe4a5a..0000000000 --- a/examples60/rosetta/build64.script +++ /dev/null @@ -1,218 +0,0 @@ - ../../bin/elena64-cli -packermann ackermann.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -paccumulator accumulator.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -paddfield addfield.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -panonymrec anonymrec.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -paplusb aplusb.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -papplycallback applycallback.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -parithmeticint arithmeticint.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -parithmeval arithmeval.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -parithmmean arithmmean.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -parrayconcat arrayconcat.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -parrays arrays.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -parraymode arraymode.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -passociativearrays associativearrays.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pbestshuffle bestshuffle.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pbinary binary.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pbitwise bitwise.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - ../../bin/elena64-cli -pbrackets brackets.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pbullscows bullscows.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pcaesar caesar.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pcharmatch charmatch.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli -pcalendar calendar.l - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../bin/elena64-cli gameoflife/gameoflife.prj - ret=$? - if [ $ret -eq -2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi diff --git a/examples60/rosetta/bullscows/bullscows.l b/examples60/rosetta/bullscows/bullscows.l index 08240ef1d9..79f2d793ea 100644 --- a/examples60/rosetta/bullscows/bullscows.l +++ b/examples60/rosetta/bullscows/bullscows.l @@ -17,7 +17,7 @@ class GameMaster ask() { - var row := console.print("Your Guess #",_attempt," ?").readLine(); + var row := Console.print("Your Guess #",_attempt," ?").readLine(); ^ row.toArray() } @@ -68,12 +68,12 @@ class GameMaster }; bulls => - -1 { console.printLine("Not a valid guess."); ^ true } - 4 { console.printLine("Congratulations! You have won!"); ^ false } + -1 { Console.printLine("Not a valid guess."); ^ true } + 4 { Console.printLine("Congratulations! You have won!"); ^ false } ! { _attempt.append(1); - console.printLine("Your Score is ",bulls," bulls and ",cows," cows"); + Console.printLine("Your Score is ",bulls," bulls and ",cows," cows"); ^ true } @@ -88,5 +88,5 @@ public program() process.doWhile(); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/caesar/caesar.l b/examples60/rosetta/caesar/caesar.l index f47f569081..701f94ca1a 100644 --- a/examples60/rosetta/caesar/caesar.l +++ b/examples60/rosetta/caesar/caesar.l @@ -69,15 +69,15 @@ extension encryptOp public program() { - console.printLine("Original text :",TestText); + Console.printLine("Original text :",TestText); var encryptedText := TestText.encrypt(Key); - console.printLine("Encrypted text:",encryptedText); + Console.printLine("Encrypted text:",encryptedText); var decryptedText := encryptedText.decrypt(Key); - console.printLine("Decrypted text:",decryptedText); + Console.printLine("Decrypted text:",decryptedText); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/calendar/calendar.l b/examples60/rosetta/calendar/calendar.l index 0cdb6e0f97..f4caa532ad 100644 --- a/examples60/rosetta/calendar/calendar.l +++ b/examples60/rosetta/calendar/calendar.l @@ -157,9 +157,9 @@ class Calendar public program() { - var calender := Calendar.new(console.write("ENTER THE YEAR:").readLine().toInt()); + var calender := Calendar.new(Console.write("ENTER THE YEAR:").readLine().toInt()); - calender.printTo(console); + calender.printTo(Console); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/charmatch/charmatch.l b/examples60/rosetta/charmatch/charmatch.l index 69432576f4..a141206dbb 100644 --- a/examples60/rosetta/charmatch/charmatch.l +++ b/examples60/rosetta/charmatch/charmatch.l @@ -9,18 +9,18 @@ public program() if(s.startingWith("hel")) { - console.printLine(s," starts with hel") + Console.printLine(s," starts with hel") }; if(s.endingWith("llo")) { - console.printLine(s," ends with llo") + Console.printLine(s," ends with llo") }; if(s.containing("el")) { - console.printLine(s," contains el") + Console.printLine(s," contains el") }; - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/combinations/combinations.l b/examples60/rosetta/combinations/combinations.l index 241963b1aa..69f9a22c48 100644 --- a/examples60/rosetta/combinations/combinations.l +++ b/examples60/rosetta/combinations/combinations.l @@ -19,8 +19,8 @@ public program() var numbers := Numbers(N); Combinator.new(M, numbers).forEach::(row) { - console.printLine(row.toString()) + Console.printLine(row.toString()) }; - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/complist/complist.l b/examples60/rosetta/complist/complist.l index 4ee356a9cc..62df6e6c82 100644 --- a/examples60/rosetta/complist/complist.l +++ b/examples60/rosetta/complist/complist.l @@ -30,9 +30,9 @@ public program() { testCases.forEach::(list) { - console.printLine(list.asEnumerable()," all equal - ",list.isEqual()); - console.printLine(list.asEnumerable()," ascending - ",list.isAscending()) + Console.printLine(list.asEnumerable()," all equal - ",list.isEqual()); + Console.printLine(list.asEnumerable()," ascending - ",list.isAscending()) }; - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/doors/doors.l b/examples60/rosetta/doors/doors.l index 494ffb66e9..d90b894a89 100644 --- a/examples60/rosetta/doors/doors.l +++ b/examples60/rosetta/doors/doors.l @@ -14,8 +14,8 @@ public program() for(int i := 0; i < 100; i++) { - console.printLine("Door #",i + 1," :",Doors[i].iif("Open","Closed")) + Console.printLine("Door #",i + 1," :",Doors[i].iif("Open","Closed")) }; - console.readChar() + Console.readChar() } diff --git a/examples60/rosetta/dynamic_var/dynamic_var.l b/examples60/rosetta/dynamic_var/dynamic_var.l index c555d3e72a..63e15ed9f6 100644 --- a/examples60/rosetta/dynamic_var/dynamic_var.l +++ b/examples60/rosetta/dynamic_var/dynamic_var.l @@ -16,10 +16,10 @@ class TestClass function() { - auto prop := new MessageName(console.write("Enter the variable name:").readLine()); + auto prop := new MessageName(Console.write("Enter the variable name:").readLine()); (prop.setPropertyMessage())(variables,42); - console.printLine(prop.toPrintable(),"=",(prop.getPropertyMessage())(variables)).readChar() + Console.printLine(prop.toPrintable(),"=",(prop.getPropertyMessage())(variables)).readChar() } } diff --git a/examples60/rosetta/evolutionary/evolutionary.l b/examples60/rosetta/evolutionary/evolutionary.l index ea4735e902..eb60897d7d 100644 --- a/examples60/rosetta/evolutionary/evolutionary.l +++ b/examples60/rosetta/evolutionary/evolutionary.l @@ -67,10 +67,10 @@ public program() var attempt := new Integer(); EvoAlgorithm.new(Target,C).forEach::(current) { - console + Console .printPaddingLeft(10,"#",attempt.append(1)) .printLine(" ",current," fitness: ",current.fitnessOf(Target)) }; - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/firstclass/firstclass.l b/examples60/rosetta/firstclass/firstclass.l index 53e5a062c5..6590d0abab 100644 --- a/examples60/rosetta/firstclass/firstclass.l +++ b/examples60/rosetta/firstclass/firstclass.l @@ -21,5 +21,5 @@ public program() var gs := new object[]{ mssgconst arcsin[1], mssgconst arccos[1], (x => power(x, 1.0r / 3)) }; fs.zipBy(gs, (f,g => 0.5r.compose(f,g))) - .forEach(printingLn) + .forEach(PrintingLn) } \ No newline at end of file diff --git a/examples60/rosetta/gameoflife/gameoflife.l b/examples60/rosetta/gameoflife/gameoflife.l index 30b2f6cca7..92f4e13e5d 100644 --- a/examples60/rosetta/gameoflife/gameoflife.l +++ b/examples60/rosetta/gameoflife/gameoflife.l @@ -27,18 +27,18 @@ singleton gameOfLifeRuleSet : RuleSet playGame(Model model) { - console.clear(); + Console.clear(); model.OnUpdate := (Space sp){ sp.print() }; - until (console.KeyAvailable) + until (Console.KeyAvailable) { model.run(); threadControl.sleep(DELAY) }; - console.readChar() + Console.readChar() } //public test diff --git a/examples60/rosetta/gameoflife/view.l b/examples60/rosetta/gameoflife/view.l index 3266d4393d..141606b7c4 100644 --- a/examples60/rosetta/gameoflife/view.l +++ b/examples60/rosetta/gameoflife/view.l @@ -5,7 +5,7 @@ public extension presenterOp : Space { print() { - console.setCursorPosition(0, 0); + Console.setCursorPosition(0, 0); int columns := self.Columns; int rows := self.Rows; @@ -21,7 +21,7 @@ public extension presenterOp : Space line.write((cell == 0).iif(" ","o")); }; - console.writeLine(line.Value) + Console.writeLine(line.Value) } } } \ No newline at end of file diff --git a/examples60/rosetta/knutalg/knutalg.l b/examples60/rosetta/knutalg/knutalg.l index 54ab9df181..fce70034dc 100644 --- a/examples60/rosetta/knutalg/knutalg.l +++ b/examples60/rosetta/knutalg/knutalg.l @@ -48,5 +48,5 @@ public program() } }; - console.printLine(bin).readChar() + Console.printLine(bin).readChar() } \ No newline at end of file diff --git a/examples60/rosetta/loop_multiple_arrays/loopma.l b/examples60/rosetta/loop_multiple_arrays/loopma.l index 5d6d74d49f..91047fad57 100644 --- a/examples60/rosetta/loop_multiple_arrays/loopma.l +++ b/examples60/rosetta/loop_multiple_arrays/loopma.l @@ -11,10 +11,10 @@ public programUsingFor() for(int i := 0; i < a1.Length; i += 1) { - console.printLine(a1[i], a2[i], a3[i]) + Console.printLine(a1[i], a2[i], a3[i]) }; - console.readChar() + Console.readChar() } public programUsingZip() @@ -26,9 +26,9 @@ public programUsingZip() .zipBy(a3, (first,second => first + second.toString() )); zipped.forEach::(e) - { console.writeLine(e) }; + { Console.writeLine(e) }; - console.readChar() + Console.readChar() } // To build the program to use 'programUsingZip' symbol, just change diff --git a/examples60/rosetta/manboy/manboy.l b/examples60/rosetta/manboy/manboy.l index 75f6ffe5bb..2f74fc144a 100644 --- a/examples60/rosetta/manboy/manboy.l +++ b/examples60/rosetta/manboy/manboy.l @@ -20,6 +20,6 @@ public program() { for(int n := 0; n <= 14; n += 1) { - console.printLine(A(n,{ ^1 },{ ^-1 },{ ^-1 },{ ^1 },{ ^0 })) + Console.printLine(A(n,{ ^1 },{ ^-1 },{ ^-1 },{ ^1 },{ ^0 })) } } diff --git a/examples60/rosetta/median/median.l b/examples60/rosetta/median/median.l index c6f32b9636..abfa0a1ef8 100644 --- a/examples60/rosetta/median/median.l +++ b/examples60/rosetta/median/median.l @@ -33,8 +33,8 @@ public program() var a1 := new real[]{4.1r, 5.6r, 7.2r, 1.7r, 9.3r, 4.4r, 3.2r}; var a2 := new real[]{4.1r, 7.2r, 1.7r, 9.3r, 4.4r, 3.2r}; - console.printLine("median of (",a1.asEnumerable(),") is ",a1.Median); - console.printLine("median of (",a2.asEnumerable(),") is ",a2.Median); + Console.printLine("median of (",a1.asEnumerable(),") is ",a1.Median); + Console.printLine("median of (",a2.asEnumerable(),") is ",a2.Median); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/ninetynine/ninetynine.l b/examples60/rosetta/ninetynine/ninetynine.l index d8966f90d5..f5b5d55d54 100644 --- a/examples60/rosetta/ninetynine/ninetynine.l +++ b/examples60/rosetta/ninetynine/ninetynine.l @@ -31,5 +31,5 @@ public program() { var bottles := 99; - bottles.bottleEnumerator().forEach(printingLn) + bottles.bottleEnumerator().forEach(PrintingLn) } \ No newline at end of file diff --git a/examples60/rosetta/reverse_words_in_string/reverse_words.l b/examples60/rosetta/reverse_words_in_string/reverse_words.l index 3cdd97c5ba..e02bd84fd6 100644 --- a/examples60/rosetta/reverse_words_in_string/reverse_words.l +++ b/examples60/rosetta/reverse_words_in_string/reverse_words.l @@ -18,8 +18,8 @@ public program() { line.splitBy(" ").sequenceReverse().forEach::(word) { - console.print(word," ") + Console.print(word," ") }; - console.writeLine() + Console.writeLine() } } \ No newline at end of file diff --git a/examples60/rosetta/smavg/smavg.l b/examples60/rosetta/smavg/smavg.l index 8fdd4d0ad2..6690b427eb 100644 --- a/examples60/rosetta/smavg/smavg.l +++ b/examples60/rosetta/smavg/smavg.l @@ -43,14 +43,14 @@ public program() var SMA5 := SMA.new(5); for (int i := 1; i <= 5; i += 1) { - console.printPaddingRight(30, "sma3 + ", i, " = ", SMA3.append(i)); - console.printLine("sma5 + ", i, " = ", SMA5.append(i)) + Console.printPaddingRight(30, "sma3 + ", i, " = ", SMA3.append(i)); + Console.printLine("sma5 + ", i, " = ", SMA5.append(i)) }; for (int i := 5; i >= 1; i -= 1) { - console.printPaddingRight(30, "sma3 + ", i, " = ", SMA3.append(i)); - console.printLine("sma5 + ", i, " = ", SMA5.append(i)) + Console.printPaddingRight(30, "sma3 + ", i, " = ", SMA3.append(i)); + Console.printLine("sma5 + ", i, " = ", SMA5.append(i)) }; - console.readChar() + Console.readChar() } diff --git a/examples60/rosetta/string_append/string_append.l b/examples60/rosetta/string_append/string_append.l index 983141891c..847e36188d 100644 --- a/examples60/rosetta/string_append/string_append.l +++ b/examples60/rosetta/string_append/string_append.l @@ -5,5 +5,5 @@ public program() var s := StringWriter.load("Hello"); s.append(" World"); - console.writeLine(s).readChar() + Console.writeLine(s).readChar() } \ No newline at end of file diff --git a/examples60/rosetta/string_case/string_case.l b/examples60/rosetta/string_case/string_case.l index 7d4e95d1b6..6a91bdd4e2 100644 --- a/examples60/rosetta/string_case/string_case.l +++ b/examples60/rosetta/string_case/string_case.l @@ -4,7 +4,7 @@ public program() { string s1 := "alphaBETA"; - console.writeLine(s1.toLower(currentLocale)); - console.writeLine(s1.toUpper(currentLocale)); - console.readChar() + Console.writeLine(s1.toLower(currentLocale)); + Console.writeLine(s1.toUpper(currentLocale)); + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/string_comparison/string_comparision.l b/examples60/rosetta/string_comparison/string_comparision.l index 085d41ce4d..5237041d6a 100644 --- a/examples60/rosetta/string_comparison/string_comparision.l +++ b/examples60/rosetta/string_comparison/string_comparision.l @@ -2,12 +2,12 @@ import extensions; compareStrings = (val1,val2) { - if (val1 == val2) { console.printLine("The strings ",val1," and ",val2," are equal") }; - if (val1 != val2) { console.printLine("The strings ",val1," and ",val2," are not equal") }; - if (val1 > val2) { console.printLine("The string ",val1," is lexically after than ",val2) }; - if (val1 < val2) { console.printLine("The string ",val1," is lexically before than ",val2) }; - if (val1 >= val2) { console.printLine("The string ",val1," is not lexically before than ",val2) }; - if (val1 <= val2) { console.printLine("The string ",val1," is not lexically after than ",val2) } + if (val1 == val2) { Console.printLine("The strings ",val1," and ",val2," are equal") }; + if (val1 != val2) { Console.printLine("The strings ",val1," and ",val2," are not equal") }; + if (val1 > val2) { Console.printLine("The string ",val1," is lexically after than ",val2) }; + if (val1 < val2) { Console.printLine("The string ",val1," is lexically before than ",val2) }; + if (val1 >= val2) { Console.printLine("The string ",val1," is not lexically before than ",val2) }; + if (val1 <= val2) { Console.printLine("The string ",val1," is not lexically after than ",val2) } }; public program() @@ -16,5 +16,5 @@ public program() var s2 := "that"; compareStrings(s1,s2); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/string_concatenation/string_concatenation.l b/examples60/rosetta/string_concatenation/string_concatenation.l index 8fb8fa839f..fd57a62553 100644 --- a/examples60/rosetta/string_concatenation/string_concatenation.l +++ b/examples60/rosetta/string_concatenation/string_concatenation.l @@ -3,7 +3,7 @@ public program() var s := "Hello"; var s2 := s + " literal"; - console.writeLine(s); - console.writeLine(s2); - console.readChar() + Console.writeLine(s); + Console.writeLine(s2); + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/string_interpolation/string_interpolation.l b/examples60/rosetta/string_interpolation/string_interpolation.l index 1becf668ea..ffabf51004 100644 --- a/examples60/rosetta/string_interpolation/string_interpolation.l +++ b/examples60/rosetta/string_interpolation/string_interpolation.l @@ -3,5 +3,5 @@ import extensions; public program() { var s := "little"; - console.printLineFormatted("Mary had a {0} lamb.",s).readChar() + Console.printLineFormatted("Mary had a {0} lamb.",s).readChar() } \ No newline at end of file diff --git a/examples60/rosetta/string_matching/string_matching.l b/examples60/rosetta/string_matching/string_matching.l index dad8958eb2..c5d7353da4 100644 --- a/examples60/rosetta/string_matching/string_matching.l +++ b/examples60/rosetta/string_matching/string_matching.l @@ -4,21 +4,21 @@ public program() { var s := "abcd"; - console.printLine(s," starts with ab: ",s.startingWith("ab")); - console.printLine(s," starts with cd: ",s.startingWith("cd")); + Console.printLine(s," starts with ab: ",s.startingWith("ab")); + Console.printLine(s," starts with cd: ",s.startingWith("cd")); - console.printLine(s," ends with ab: ",s.endingWith("ab")); - console.printLine(s," ends with cd: ",s.endingWith("cd")); + Console.printLine(s," ends with ab: ",s.endingWith("ab")); + Console.printLine(s," ends with cd: ",s.endingWith("cd")); - console.printLine(s," contains ab: ",s.containing("ab")); - console.printLine(s," contains bc: ",s.containing("bc")); - console.printLine(s," contains cd: ",s.containing("cd")); - console.printLine(s," contains az: ",s.containing("az")); + Console.printLine(s," contains ab: ",s.containing("ab")); + Console.printLine(s," contains bc: ",s.containing("bc")); + Console.printLine(s," contains cd: ",s.containing("cd")); + Console.printLine(s," contains az: ",s.containing("az")); - console.printLine(s," index of az: ",s.indexOf(0, "az")); - console.printLine(s," index of cd: ",s.indexOf(0, "cd")); - console.printLine(s," index of bc: ",s.indexOf(0, "bc")); - console.printLine(s," index of ab: ",s.indexOf(0, "ab")); + Console.printLine(s," index of az: ",s.indexOf(0, "az")); + Console.printLine(s," index of cd: ",s.indexOf(0, "cd")); + Console.printLine(s," index of bc: ",s.indexOf(0, "bc")); + Console.printLine(s," index of ab: ",s.indexOf(0, "ab")); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/string_prepend/string_prepend.l b/examples60/rosetta/string_prepend/string_prepend.l index 873f65a210..ff8b6554d0 100644 --- a/examples60/rosetta/string_prepend/string_prepend.l +++ b/examples60/rosetta/string_prepend/string_prepend.l @@ -5,11 +5,11 @@ public program() { var s := "World"; s := "Hello " + s; - console.writeLine(s); + Console.writeLine(s); // Alternative way var s2 := StringWriter.load("World"); s2.insert(0, "Hello "); - console.writeLine(s2); - console.readChar() + Console.writeLine(s2); + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/tokenizer/tokenizer.l b/examples60/rosetta/tokenizer/tokenizer.l index 5fb43dcfcb..bd6e9cfd8c 100644 --- a/examples60/rosetta/tokenizer/tokenizer.l +++ b/examples60/rosetta/tokenizer/tokenizer.l @@ -7,6 +7,6 @@ public program() string.splitBy(",").forEach::(s) { - console.print(s,".") + Console.print(s,".") } } \ No newline at end of file diff --git a/examples60/rosetta/toppergroup/toppergroup.l b/examples60/rosetta/toppergroup/toppergroup.l index e5e2b80d42..d3ba2c782e 100644 --- a/examples60/rosetta/toppergroup/toppergroup.l +++ b/examples60/rosetta/toppergroup/toppergroup.l @@ -54,12 +54,12 @@ public program() employees.topNPerDepartment(2).forEach::(info) { - console.printLine("Department: ",info.Department); + Console.printLine("Department: ",info.Department); - info.Employees.forEach(printingLn); + info.Employees.forEach(PrintingLn); - console.writeLine("---------------------------------------------") + Console.writeLine("---------------------------------------------") }; - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/treeview/treeview.l b/examples60/rosetta/treeview/treeview.l index e40f22d2ac..33df1a5b29 100644 --- a/examples60/rosetta/treeview/treeview.l +++ b/examples60/rosetta/treeview/treeview.l @@ -62,5 +62,5 @@ public program() Node.new("e") }); - console.writeTree(tree).readChar() + Console.writeTree(tree).readChar() } diff --git a/examples60/rosetta/trigonometric/trigonometric.l b/examples60/rosetta/trigonometric/trigonometric.l index 99436a8e32..f50c6c471f 100644 --- a/examples60/rosetta/trigonometric/trigonometric.l +++ b/examples60/rosetta/trigonometric/trigonometric.l @@ -3,22 +3,22 @@ import extensions; public program() { - console.printLine("Radians:"); - console.printLine("sin(π/3) = ",(Pi_value/3).sin()); - console.printLine("cos(π/3) = ",(Pi_value/3).cos()); - console.printLine("tan(π/3) = ",(Pi_value/3).tan()); - console.printLine("arcsin(1/2) = ",0.5r.arcsin()); - console.printLine("arccos(1/2) = ",0.5r.arccos()); - console.printLine("arctan(1/2) = ",0.5r.arctan()); - console.printLine(); + Console.printLine("Radians:"); + Console.printLine("sin(π/3) = ",(Pi_value/3).sin()); + Console.printLine("cos(π/3) = ",(Pi_value/3).cos()); + Console.printLine("tan(π/3) = ",(Pi_value/3).tan()); + Console.printLine("arcsin(1/2) = ",0.5r.arcsin()); + Console.printLine("arccos(1/2) = ",0.5r.arccos()); + Console.printLine("arctan(1/2) = ",0.5r.arctan()); + Console.printLine(); - console.printLine("Degrees:"); - console.printLine("sin(60º) = ",60.0r.Radian.sin()); - console.printLine("cos(60º) = ",60.0r.Radian.cos()); - console.printLine("tan(60º) = ",60.0r.Radian.tan()); - console.printLine("arcsin(1/2) = ",0.5r.arcsin().Degree,"º"); - console.printLine("arccos(1/2) = ",0.5r.arccos().Degree,"º"); - console.printLine("arctan(1/2) = ",0.5r.arctan().Degree,"º"); + Console.printLine("Degrees:"); + Console.printLine("sin(60º) = ",60.0r.Radian.sin()); + Console.printLine("cos(60º) = ",60.0r.Radian.cos()); + Console.printLine("tan(60º) = ",60.0r.Radian.tan()); + Console.printLine("arcsin(1/2) = ",0.5r.arcsin().Degree,"º"); + Console.printLine("arccos(1/2) = ",0.5r.arccos().Degree,"º"); + Console.printLine("arctan(1/2) = ",0.5r.arctan().Degree,"º"); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/truncprime/truncprime.l b/examples60/rosetta/truncprime/truncprime.l index aead36488c..b133385eb9 100644 --- a/examples60/rosetta/truncprime/truncprime.l +++ b/examples60/rosetta/truncprime/truncprime.l @@ -87,8 +87,8 @@ public program() n := n - 1 }; - console.printLine("Largest truncable left is ",max_lt); - console.printLine("Largest truncable right is ",max_rt); + Console.printLine("Largest truncable left is ",max_lt); + Console.printLine("Largest truncable right is ",max_rt); - console.readChar() + Console.readChar() } diff --git a/examples60/rosetta/twelvestats/twelvestats.l b/examples60/rosetta/twelvestats/twelvestats.l index a7024c0c3d..e99e2cb220 100644 --- a/examples60/rosetta/twelvestats/twelvestats.l +++ b/examples60/rosetta/twelvestats/twelvestats.l @@ -43,7 +43,7 @@ puzzle = new Func1[] public program() { - console.writeLine(); + Console.writeLine(); for(int n := 0; n < 2.power(12); n += 1) { @@ -53,10 +53,10 @@ public program() var counts := bits.zipBy(results, (b,r => b.xor(r).toBit() )).summarize(); counts => - 0 { console.printLine("Total hit :",results.printSolution(bits)) } - 1 { console.printLine("Near miss :",results.printSolution(bits)) } - 12 { console.printLine("Total miss:",results.printSolution(bits)) }; + 0 { Console.printLine("Total hit :",results.printSolution(bits)) } + 1 { Console.printLine("Near miss :",results.printSolution(bits)) } + 12 { Console.printLine("Total miss:",results.printSolution(bits)) }; }; - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta/twentyfour/twentyfour.l b/examples60/rosetta/twentyfour/twentyfour.l index e380e0a076..ecc5be6bf7 100644 --- a/examples60/rosetta/twentyfour/twentyfour.l +++ b/examples60/rosetta/twentyfour/twentyfour.l @@ -121,7 +121,7 @@ class TwentyFourGame help() { - console + Console .printLine("------------------------------- Instructions ------------------------------") .printLine("Four digits will be displayed.") .printLine("Enter an equation using all of those four digits that evaluates to 24") @@ -137,9 +137,9 @@ class TwentyFourGame prompt() { - theNumbers.forEach::(n){ console.print(n," ") }; + theNumbers.forEach::(n){ Console.print(n," ") }; - console.print(": ") + Console.print(": ") } resolve(expr) @@ -150,18 +150,18 @@ class TwentyFourGame tree.readLeaves(leaves); ifnot (leaves.ascendant().sequenceEqual(theNumbers.ascendant())) - { console.printLine("Invalid input. Enter an equation using all of those four digits. Try again."); ^ self }; + { Console.printLine("Invalid input. Enter an equation using all of those four digits. Try again."); ^ self }; var result := tree.Value; if (result == 24) { - console.printLine("Good work. ",expr,"=",result); + Console.printLine("Good work. ",expr,"=",result); self.newPuzzle() } else { - console.printLine("Incorrect. ",expr,"=",result) + Console.printLine("Incorrect. ",expr,"=",result) } } } @@ -178,7 +178,7 @@ extension gameOp { if (expr == "") { - console.printLine("Skipping this puzzle"); self.newPuzzle() + Console.printLine("Skipping this puzzle"); self.newPuzzle() } else { @@ -188,8 +188,8 @@ extension gameOp } catch(Exception e) { - console.printLine(e) - //console.printLine:"An error occurred. Check your input and try again." + Console.printLine(e) + //Console.printLine:"An error occurred. Check your input and try again." } }; @@ -204,5 +204,5 @@ public program() { var game := new TwentyFourGame().help(); - while (game.prompt().playRound(console.readLine())) {} + while (game.prompt().playRound(Console.readLine())) {} } \ No newline at end of file diff --git a/examples60/rosetta/wireworld/wireworld.l b/examples60/rosetta/wireworld/wireworld.l index 2424352146..8fd1d35cbd 100644 --- a/examples60/rosetta/wireworld/wireworld.l +++ b/examples60/rosetta/wireworld/wireworld.l @@ -121,13 +121,13 @@ sealed class Model electronHead { label := headLabel } electronTail { label := tailLabel }; - console.write(label); + Console.write(label); j := j + 1 }; i := i + 1; - console.writeLine() + Console.writeLine() } } } @@ -137,7 +137,7 @@ public program() Model model := Model.load(sample,10,30); for(int i := 0; i < 10; i += 1) { - console.printLineFormatted("Iteration {0}",i); + Console.printLineFormatted("Iteration {0}",i); model.print().run() } } \ No newline at end of file diff --git a/examples60/rosetta/ycombinator/ycombinator.l b/examples60/rosetta/ycombinator/ycombinator.l index 678fbfbf9a..095040f1dd 100644 --- a/examples60/rosetta/ycombinator/ycombinator.l +++ b/examples60/rosetta/ycombinator/ycombinator.l @@ -11,6 +11,6 @@ public program() var fib := YCombinator.fix::(f => (i => (i <= 1) ? i : (f(i-1) + f(i-2)) )); var fact := YCombinator.fix::(f => (i => (i == 0) ? 1 : (f(i-1) * i) )); - console.printLine("fib(10)=",fib(10)); - console.printLine("fact(10)=",fact(10)); + Console.printLine("fib(10)=",fib(10)); + Console.printLine("fact(10)=",fact(10)); } \ No newline at end of file diff --git a/examples60/rosetta/zeckendorf_arithm/zeckendorf_arithm.l b/examples60/rosetta/zeckendorf_arithm/zeckendorf_arithm.l index 15f1322293..85b81d5655 100644 --- a/examples60/rosetta/zeckendorf_arithm/zeckendorf_arithm.l +++ b/examples60/rosetta/zeckendorf_arithm/zeckendorf_arithm.l @@ -229,33 +229,33 @@ sealed struct ZeckendorfNumber public program() { - console.printLine("Addition:"); + Console.printLine("Addition:"); var n := 10n; n += 10n; - console.printLine(n); + Console.printLine(n); n += 10n; - console.printLine(n); + Console.printLine(n); n += 1001n; - console.printLine(n); + Console.printLine(n); n += 1000n; - console.printLine(n); + Console.printLine(n); n += 10101n; - console.printLine(n); + Console.printLine(n); - console.printLine("Subtraction:"); + Console.printLine("Subtraction:"); n := 1000n; n -= 101n; - console.printLine(n); + Console.printLine(n); n := 10101010n; n -= 1010101n; - console.printLine(n); + Console.printLine(n); - console.printLine("Multiplication:"); + Console.printLine("Multiplication:"); n := 1001n; n *= 101n; - console.printLine(n); + Console.printLine(n); n := 101010n; n += 101n; - console.printLine(n) + Console.printLine(n) } diff --git a/examples60/rosetta/zhangsuen/zhangsuen.l b/examples60/rosetta/zhangsuen/zhangsuen.l index e8fb9bdb00..996d007dbc 100644 --- a/examples60/rosetta/zhangsuen/zhangsuen.l +++ b/examples60/rosetta/zhangsuen/zhangsuen.l @@ -136,12 +136,12 @@ extension zhangsuenOp : Matrix { var it := self.enumerator(); - it.forEach::(ch){ console.print(ch," ") }; + it.forEach::(ch){ Console.print(ch," ") }; while (it.next()) { - console.writeLine(); + Console.writeLine(); - it.forEach::(ch){ console.print(ch," ") } + it.forEach::(ch){ Console.print(ch," ") } } } } @@ -162,5 +162,5 @@ public program() grid.print(); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/rosetta60.linux.prjcol b/examples60/rosetta60.linux.prjcol new file mode 100644 index 0000000000..c43bf6a9af --- /dev/null +++ b/examples60/rosetta60.linux.prjcol @@ -0,0 +1,60 @@ + + + rosetta/accumulator/accumulator.l + rosetta/ackermann/ackermann.l + rosetta/addfield/addfield.l + rosetta/amb/amb.l + rosetta/anagram/anagram.l + rosetta/anonymrec/anonymrec.l + rosetta/aplusb/aplusb.l + rosetta/applycallback/applycallback.l + rosetta/arithmeticint/arithmeticint.l + rosetta/arithmeval/arithmeval.l + rosetta/arithmmean/arithmmean.l + rosetta/arrayconcat/arrayconcat.l + rosetta/arraymode/arraymode.l + rosetta/arrays/arrays.l + rosetta/associativearrays/associativearrays.l + rosetta/bestshuffle/bestshuffle.l + rosetta/binary/binary.l + rosetta/bitwise/bitwise.l + rosetta/brackets/brackets.l + rosetta/bullscows/bullscows.l + rosetta/caesar/caesar.l + rosetta/calendar/calendar.l + rosetta/charmatch/charmatch.l + rosetta/combinations/combinations.l + rosetta/complist/complist.l + rosetta/doors/doors.l + rosetta/dynamic_var/dynamic_var.l + rosetta/evolutionary/evolutionary.l + rosetta/firstclass/firstclass.l + rosetta/gameoflife/gameoflife.prj + rosetta/knutalg/knutalg.l + rosetta/loop_multiple_arrays/loopma.l + rosetta/manboy/manboy.l + rosetta/median/median.l + rosetta/ninetynine/ninetynine.l + rosetta/reverse_words_in_string/reverse_words.l + rosetta/simple_windowed_app/simple_windowed_app.prj + rosetta/smavg/smavg.l + rosetta/string_append/string_append.l + rosetta/string_case/string_case.l + rosetta/string_comparison/string_comparision.l + rosetta/string_concatenation/string_concatenation.l + rosetta/string_interpolation/string_interpolation.l + rosetta/string_matching/string_matching.l + rosetta/string_prepend/string_prepend.l + rosetta/tokenizer/tokenizer.l + rosetta/toppergroup/toppergroup.l + rosetta/treeview/treeview.l + rosetta/trigonometric/trigonometric.l + rosetta/truncprime/truncprime.l + rosetta/twelvestats/twelvestats.l + rosetta/twentyfour/twentyfour.l + rosetta/wireworld/wireworld.l + rosetta/ycombinator/ycombinator.l + rosetta/zeckendorf_arithm/zeckendorf_arithm.l + rosetta/zhangsuen/zhangsuen.l + + \ No newline at end of file diff --git a/examples60/rosetta60.prjcol b/examples60/rosetta60.prjcol new file mode 100644 index 0000000000..db61bc1a26 --- /dev/null +++ b/examples60/rosetta60.prjcol @@ -0,0 +1,60 @@ + + + rosetta\accumulator\accumulator.l + rosetta\ackermann\ackermann.l + rosetta\addfield\addfield.l + rosetta\amb\amb.l + rosetta\anagram\anagram.l + rosetta\anonymrec\anonymrec.l + rosetta\aplusb\aplusb.l + rosetta\applycallback\applycallback.l + rosetta\arithmeticint\arithmeticint.l + rosetta\arithmeval\arithmeval.l + rosetta\arithmmean\arithmmean.l + rosetta\arrayconcat\arrayconcat.l + rosetta\arraymode\arraymode.l + rosetta\arrays\arrays.l + rosetta\associativearrays\associativearrays.l + rosetta\bestshuffle\bestshuffle.l + rosetta\binary\binary.l + rosetta\bitwise\bitwise.l + rosetta\brackets\brackets.l + rosetta\bullscows\bullscows.l + rosetta\caesar\caesar.l + rosetta\calendar\calendar.l + rosetta\charmatch\charmatch.l + rosetta\combinations\combinations.l + rosetta\complist\complist.l + rosetta\doors\doors.l + rosetta\dynamic_var\dynamic_var.l + rosetta\evolutionary\evolutionary.l + rosetta\firstclass\firstclass.l + rosetta\gameoflife\gameoflife.prj + rosetta\knutalg\knutalg.l + rosetta\loop_multiple_arrays\loopma.l + rosetta\manboy\manboy.l + rosetta\median\median.l + rosetta\ninetynine\ninetynine.l + rosetta\reverse_words_in_string\reverse_words.l + rosetta\simple_windowed_app\simple_windowed_app.prj + rosetta\smavg\smavg.l + rosetta\string_append\string_append.l + rosetta\string_case\string_case.l + rosetta\string_comparison\string_comparision.l + rosetta\string_concatenation\string_concatenation.l + rosetta\string_interpolation\string_interpolation.l + rosetta\string_matching\string_matching.l + rosetta\string_prepend\string_prepend.l + rosetta\tokenizer\tokenizer.l + rosetta\toppergroup\toppergroup.l + rosetta\treeview\treeview.l + rosetta\trigonometric\trigonometric.l + rosetta\truncprime\truncprime.l + rosetta\twelvestats\twelvestats.l + rosetta\twentyfour\twentyfour.l + rosetta\wireworld\wireworld.l + rosetta\ycombinator\ycombinator.l + rosetta\zeckendorf_arithm\zeckendorf_arithm.l + rosetta\zhangsuen\zhangsuen.l + + \ No newline at end of file diff --git a/examples60/scripts/build.bat b/examples60/scripts/build.bat deleted file mode 100644 index dedeb066df..0000000000 --- a/examples60/scripts/build.bat +++ /dev/null @@ -1,42 +0,0 @@ -cd calc -..\..\..\bin\elena-cli calc.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError2 -@echo on -cd .. - -..\..\bin\elena-cli -pinterpreter interpreter.l -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -cd js -..\..\..\bin\elena-cli jsinterpreter.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError2 -@echo on -cd .. - -cd ls -..\..\..\bin\elena-cli lsinterpreter.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError2 -@echo on -cd .. - -@echo off -goto:eof -@echo on - -:CompilerError -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on - -:CompilerError2 -cd .. -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on diff --git a/examples60/scripts/calc/parser.l b/examples60/scripts/calc/parser.l index ba559dbc85..516118eabb 100644 --- a/examples60/scripts/calc/parser.l +++ b/examples60/scripts/calc/parser.l @@ -342,7 +342,7 @@ extension parserOp } catch(Exception e) { - console.printLine(e); + Console.printLine(e); stateMachine.invalidate() }; diff --git a/examples60/scripts/interpreter/interpreter.l b/examples60/scripts/interpreter/interpreter.l index 2ccfca811d..3dc71106f3 100644 --- a/examples60/scripts/interpreter/interpreter.l +++ b/examples60/scripts/interpreter/interpreter.l @@ -58,7 +58,7 @@ class TapeAssembler Expression.Variable("ptr"), Expression.MessageCall( new Message("readChar[1]"), - Expression.Constant(console) + Expression.Constant(Console) ) ) ) @@ -69,7 +69,7 @@ class TapeAssembler _tape.append( Expression.MessageCall( new Message("write[2]"), - Expression.Constant(console), + Expression.Constant(Console), Expression.MessageCall( new Message("at[2]"), Expression.Variable("tape"), @@ -243,14 +243,14 @@ public solution0() "ptr", Expression.Constant(0) ), - // tape[ptr] := console.readChar() + // tape[ptr] := Console.readChar() Expression.MessageCall( new Message("setAt[3]"), Expression.Variable("tape"), Expression.Variable("ptr"), Expression.MessageCall( new Message("readChar[1]"), - Expression.Constant(console) + Expression.Constant(Console) ) ), // while (tape[ptr]!=0) { @@ -265,24 +265,24 @@ public solution0() Expression.Constant($0) ), Expression.CodeBlock( - // console.write(tape[ptr]) + // Console.write(tape[ptr]) Expression.MessageCall( new Message("write[2]"), - Expression.Constant(console), + Expression.Constant(Console), Expression.MessageCall( new Message("at[2]"), Expression.Variable("tape"), Expression.Variable("ptr") ) ), - // tape[ptr] := console readChar + // tape[ptr] := Console readChar Expression.MessageCall( new Message("setAt[3]"), Expression.Variable("tape"), Expression.Variable("ptr"), Expression.MessageCall( new Message("readChar[1]"), - Expression.Constant(console) + Expression.Constant(Console) ) ) ) @@ -342,7 +342,7 @@ public solution4(string path) var bfProgram := TapeCGenerator.load(bfAssemblyProgram).compile(); - console.writeLine(bfProgram) + Console.writeLine(bfProgram) } public program() @@ -351,7 +351,7 @@ public program() if (program_arguments.Length == 1) { - console.write("Please provide the path to the file to interpret"); AbortException.raise() + Console.write("Please provide the path to the file to interpret"); AbortException.raise() } else if (program_arguments.Length == 3) { solution := program_arguments[2].toInt(); diff --git a/examples60/scripts/js/main.l b/examples60/scripts/js/main.l index 5693eaa881..8b84768cad 100644 --- a/examples60/scripts/js/main.l +++ b/examples60/scripts/js/main.l @@ -4,7 +4,7 @@ import extensions'scripting; //public live_program() //{ // if (program_arguments.Length == 1) -// { console.printLine("Please provide the path to the file to interpret"); AbortException.raise() }; +// { Console.printLine("Please provide the path to the file to interpret"); AbortException.raise() }; // // try // { @@ -14,7 +14,7 @@ import extensions'scripting; // } // catch(Exception e) // { -// console.printLine:e +// Console.printLine:e // } //} diff --git a/examples60/scripts/ls/main.l b/examples60/scripts/ls/main.l index c5e281104d..fa08753a31 100644 --- a/examples60/scripts/ls/main.l +++ b/examples60/scripts/ls/main.l @@ -5,7 +5,7 @@ import system'dynamic'expressions; public program() { if (program_arguments.Length == 1) - { console.printLine("Please provide the path to the file to interpret"); AbortException.raise() }; + { Console.printLine("Please provide the path to the file to interpret"); AbortException.raise() }; lscript.interpretPath(program_arguments[1]); } \ No newline at end of file diff --git a/examples60/threads/async/sample1.l b/examples60/threads/async/sample1.l index c04a42bb5c..9e6521f3cd 100644 --- a/examples60/threads/async/sample1.l +++ b/examples60/threads/async/sample1.l @@ -5,22 +5,22 @@ class Sample1 async static Task wait() { :await Task.sleep(10000); - console.writeLine("10 Seconds wait Completed\n"); + Console.writeLine("10 Seconds wait Completed\n"); } async static Task someMethod() { - console.writeLine("Some Method Started......"); + Console.writeLine("Some Method Started......"); :await wait(); - console.writeLine("Some Method End"); + Console.writeLine("Some Method End"); } static run() { - console.writeLine("Main Method Started......"); + Console.writeLine("Main Method Started......"); someMethod(); - console.writeLine("Main Method End"); - console.readChar(); + Console.writeLine("Main Method End"); + Console.readChar(); } } diff --git a/examples60/threads/tasks/sample1.l b/examples60/threads/tasks/sample1.l index 7a8803ba3a..17a13f3139 100644 --- a/examples60/threads/tasks/sample1.l +++ b/examples60/threads/tasks/sample1.l @@ -20,7 +20,7 @@ public sample1() Task.waitAll(tasks.Value); - list.Snapshot.forEach(printingLn); + list.Snapshot.forEach(PrintingLn); - console.writeLine("Main thread exits") + Console.writeLine("Main thread exits") } \ No newline at end of file diff --git a/src60/extensions/app.l b/src60/extensions/app.l index fd506083b4..780d9bc65a 100644 --- a/src60/extensions/app.l +++ b/src60/extensions/app.l @@ -19,15 +19,15 @@ class ProgramLoopImpl function() { // if grettings is not defined - do nothing - console.printLine(_control.greeting() ?? EmptyString); + Console.printLine(_control.greeting() ?? EmptyString); var prompt := _control.Prompt ?? EmptyString; while (_active) { - console.write(prompt); + Console.write(prompt); - console.printLine(_control.proceed(console.readLine())) + Console.printLine(_control.proceed(Console.readLine())) } } } diff --git a/src60/extensions/extensions.linux.prj b/src60/extensions/extensions.linux.prj index 95b70441dd..5987b8586b 100644 --- a/src60/extensions/extensions.linux.prj +++ b/src60/extensions/extensions.linux.prj @@ -25,7 +25,7 @@ ELENA Extension Library - 6.5.0 + 6.6.0 Alex Rakov diff --git a/src60/extensions/extensions.prj b/src60/extensions/extensions.prj index 4630c56273..6fc4138a06 100644 --- a/src60/extensions/extensions.prj +++ b/src60/extensions/extensions.prj @@ -15,7 +15,7 @@ ELENA Extension Library - 6.5.0 + 6.6.1 Alex Rakov @@ -58,6 +58,7 @@ runtime\systemmonitor.l + runtime\package.l \ No newline at end of file diff --git a/src60/extensions/routines/enumerating.l b/src60/extensions/routines/enumerating.l index da127b9d3a..7df9047a89 100644 --- a/src60/extensions/routines/enumerating.l +++ b/src60/extensions/routines/enumerating.l @@ -70,9 +70,11 @@ public extension fileExOp : File = f.run(ReaderEnumerator.new(self)); } -// --- printingLn --- +// --- PrintingLn --- -public symbol printingLn = (line){ console.printLine(line) }; +public symbol PrintingLn = (line){ Console.printLine(line) }; + +public symbol printingLn = PrintingLn; // !! for backword compatibility // --- func1Op --- diff --git a/src60/extensions/runtime/package.l b/src60/extensions/runtime/package.l new file mode 100644 index 0000000000..71c2d69416 --- /dev/null +++ b/src60/extensions/runtime/package.l @@ -0,0 +1,26 @@ +import extensions; +import system'text; +import system'runtime; + +public extension packageOp +{ + string getFullPackageInfo() + { + auto package := self.Package(); + auto output := new StringBuilder(); + + if ((package.Namespace ?? string.MinValue).Length != 0) + output.print("Namespace: ", package.Namespace).print(NewLineConstant); + + if ((package.Name ?? string.MinValue).Length != 0) + output.print("Name: ", package.Name).print(NewLineConstant); + + if ((package.Version ?? string.MinValue).Length != 0) + output.print("Name: ", package.Version).print(NewLineConstant); + + if ((package.Author ?? string.MinValue).Length != 0) + output.print("Author: ", package.Author).print(NewLineConstant); + + ^ output.Value + } +} \ No newline at end of file diff --git a/src60/extensions/runtime/systemmonitor.l b/src60/extensions/runtime/systemmonitor.l index 46027b273e..39c1ca4fd4 100644 --- a/src60/extensions/runtime/systemmonitor.l +++ b/src60/extensions/runtime/systemmonitor.l @@ -7,16 +7,16 @@ public singleton SystemMonitor { GCStatistics statistics := GCManager.calcStatistics(); - console.printLine("=== Memory usage statistics ==="); - console.printLine("yg allocated: ", statistics.ygInfo.allocated.toString(10)); - console.printLine("yg free: ", statistics.ygInfo.free.toString(10)); - console.printLine("mg allocated: ", statistics.mgInfo.allocated.toString(10)); - console.printLine("mg free: ", statistics.mgInfo.free.toString(10)); - console.printLine("perm allocated: ", statistics.permInfo.allocated.toString(10)); - console.printLine("perm free: ", statistics.permInfo.free.toString(10)); - console.printLine("minor collections: ", statistics.minorCollections.toString(10)); - console.printLine("major collections: ", statistics.majorCollections.toString(10)); - console.printLine("==============================="); + Console.printLine("=== Memory usage statistics ==="); + Console.printLine("yg allocated: ", statistics.ygInfo.allocated.toString(10)); + Console.printLine("yg free: ", statistics.ygInfo.free.toString(10)); + Console.printLine("mg allocated: ", statistics.mgInfo.allocated.toString(10)); + Console.printLine("mg free: ", statistics.mgInfo.free.toString(10)); + Console.printLine("perm allocated: ", statistics.permInfo.allocated.toString(10)); + Console.printLine("perm free: ", statistics.permInfo.free.toString(10)); + Console.printLine("minor collections: ", statistics.minorCollections.toString(10)); + Console.printLine("major collections: ", statistics.majorCollections.toString(10)); + Console.printLine("==============================="); } } diff --git a/src60/ltests/engine.l b/src60/ltests/engine.l index 0bb0452fed..97b467626d 100644 --- a/src60/ltests/engine.l +++ b/src60/ltests/engine.l @@ -6,9 +6,9 @@ public singleton Engine foreach(var test; in collection) { - console.write(test.TestName).write(":"); + Console.write(test.TestName).write(":"); test(); - console.writeLine(); + Console.writeLine(); } } } \ No newline at end of file diff --git a/src60/net/http/common.l b/src60/net/http/common.l index f359e0672d..75c82c8b13 100644 --- a/src60/net/http/common.l +++ b/src60/net/http/common.l @@ -1,13 +1,18 @@ import system'text'parsing; import system'net; +public class HttpException : Exception +{ + constructor new(string s) + <= super new(s); +} + internal static RegEx UrlRegEx = new RegEx("^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]((\.|-+)?[0-9a-zA-Z])*(:(0-9)*)?(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_=]*)?$"); public sealed class Uri { string _scheme; string _host; - string _ip; string _port; string _path; string _query; @@ -23,9 +28,6 @@ public sealed class Uri get string Host() = _host; - get string IP() - = _query; - get string PortValue() = _port ?? String.MinValue; @@ -68,7 +70,10 @@ public sealed class Uri _host := url.Substring(index, portIndex - index); _port := url.Substring(portIndex + 1, end - portIndex - 1); } - else _host := url.Substring(index, end - index); + else { + _host := url.Substring(index, end - index); + _port := "80" + }; index := end + 1; @@ -86,9 +91,6 @@ public sealed class Uri _query := url.Substring(index, len - index); }; - hostent h := hostent.load(_host); - _ip := h.IP; - ^ true; } diff --git a/src60/net/http/httpclient.l b/src60/net/http/httpclient.l index 55c414aced..d78ddaa2ec 100644 --- a/src60/net/http/httpclient.l +++ b/src60/net/http/httpclient.l @@ -6,7 +6,7 @@ public class HttpClient HttpHeaders _headers; Socket _socket; - constructor new() + constructor() { _headers := new HttpHeaders(); } @@ -14,31 +14,36 @@ public class HttpClient HttpHeaders Headers = _headers; - async Task getAsync(Uri uri) - { - /* Create TCP socket */ - _socket := new Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + Task getAsync(string url) + = getAsync(Uri.parse(url)); - /* Set remote->sin_addr.s_addr */ - SOCKADDR_IN remote := default; - - remote.Ip_address := uri.IP; - remote.Port := uri.Port; + private Task openAsync(Uri uri) + = ::Task.run({ ^ Socket.connect(uri.Host, uri.Port) }); + async Task getAsync(Uri uri) + { /* Connect */ - _socket.open(remote); + _socket := :await openAsync(uri); /* Send headers to server */ NetworkStream stream := new NetworkStream(_socket); - :await stream.writeAsync(_headers.Value); + string host := uri.Host; + string headers := _headers.Value; + string request := $"GET / HTTP/1.1"$13$10"Host:{host}"$13$10"Connection:close"$13$10"{headers}"$13$10; + + :await stream.writeAsync(request); + + HttpResponse response := HttpResponse.assign(stream); + + :await response.readHeader(); - ^ HttpResponse.assign(stream); - + ^ response; } close() { - _socket.close() + if:not:nil(_socket) + _socket.close() } } \ No newline at end of file diff --git a/src60/net/http/httpheaders.l b/src60/net/http/httpheaders.l index d8869a0730..a9edb08433 100644 --- a/src60/net/http/httpheaders.l +++ b/src60/net/http/httpheaders.l @@ -1,23 +1,42 @@ import system'text; +import system'collections; public class HttpHeaders { - StringBuilder content; + List> _headers; constructor() { - content := new StringBuilder(); + _headers := new List>(); } add(string name, string content) { - content - .append(name) - .append(":") - .append(content) - .append($13$10); + _headers.append(new Tuple(name, content)); + } + + string at(string key) + { + foreach(auto p; in _headers) { + if (p.Item1 == key) { + ^ p.Item2 + } + }; + + ^ String.MinValue } get string Value() - => content; + { + auto content := new StringBuilder(); + foreach(auto p; in _headers) { + content + .write(p.Item1) + .write(":") + .write(p.Item2) + .write($13$10); + }; + + ^ content.Value + } } \ No newline at end of file diff --git a/src60/net/http/httpresponse.l b/src60/net/http/httpresponse.l index ee530ab9c2..4506910359 100644 --- a/src60/net/http/httpresponse.l +++ b/src60/net/http/httpresponse.l @@ -1,17 +1,163 @@ +import system'io; import system'net; +import system'text; import system'threading; +import system'routines; +import system'culture; +import extensions; public class HttpResponse { NetworkStream _stream; + MemoryBuffer _buffer; + + HttpHeaders _headers; + + string _protocol; + int _statusCode; + string _statusText; + + private int seekEOL(byte[] buffer, int start, int length) + { + for (int i := start; i < length; i++) { + if (buffer[i] ==13) { + if (i + 1 < length){ + if (buffer[i + 1] == 10) { + ^ i + 2; + } + } + } + }; + + ^ 0 + } + + private int seekHeaderContent(byte[] buffer, int start, int length) + { + for (int i := 0; i < length; i++) { + if (buffer[start + i] == 58) { + ^ start + i + 1; + } + }; + + ^ start + length + } + + private int seekHeaderEnd() + { + byte[] buffer := _buffer.Content; + + int length := _buffer.Length; + int eol := seekEOL(buffer, 0, length); + if (eol > 0 && length - eol > 2) { + if (buffer[eol]==13 && buffer[eol+1]==10) { + ^ eol + 2; + }; + + int start := eol; + while (start < length) { + eol := seekEOL(buffer, start, length - start); + if (eol > 0 && length - eol > 2) { + if (buffer[eol]==13 && buffer[eol+1]==10) { + ^ eol + 2; + }; + + start := eol; + } + else :break; + } + }; + + ^ 0 + } internal constructor assign(NetworkStream stream) { - _stream := stream + _stream := stream; + _buffer := MemoryBuffer.allocate(); + + _headers := new HttpHeaders(); } - async Task ReadAsStringAsync() + async internal Task readHeader() { + int eoh := 0; + int received := :await _stream.readAsync(_buffer, 512); + while (received > 0) { + eoh := seekHeaderEnd(); + if (eoh > 0) + :break; + + received := :await _stream.readAsync(_buffer, 512); + }; + + byte[] buffer := _buffer.Content; + int length := _buffer.Length; + + int index := 0; + // status + int eol := seekEOL(buffer, 0, length); + var line := UTF8Encoding.toString(index, eol - index - 2, buffer); + + var elements := line.split(); + _protocol := elements[0]; + _statusCode := elements[1].toInt(); + _statusText := elements[2]; + + index := eol; + + while (index < eoh) { + int next := seekEOL(buffer, index, length); + if (next - index == 2) + :break; + + int headerContent := seekHeaderContent(buffer, index, next - index - 2); + string key := UTF8Encoding.toString(index, headerContent - index - 1, buffer).trimRight(); + if (buffer[headerContent + 1] == 32) + headerContent++; + + string value := UTF8Encoding.toString(headerContent + 1, next - headerContent - 3, buffer); + + _headers.add(key, value); + + index := next; + } + } + + async Task readAsStringAsync() + { + int received := :await _stream.readAsync(_buffer, 512); + while (received > 0) { + received := :await _stream.readAsync(_buffer, 512); + }; + + byte[] buffer := _buffer.Content; + int length := _buffer.Length; + int eoh := seekHeaderEnd(); + if (eoh == 0) + HttpException.raise("Invalid response"); + + if (_headers["Transfer-Encoding"]=="chunked") { + int current := eoh; + auto output := MemoryBuffer.allocate(); + while (current < length) { + int eol := seekEOL(buffer, current, length); + string chunkStr := UTF8Encoding.toString(current, eol - current - 2, buffer); + int chunkSize := chunkStr.toUpper().toInt(16); + + if (chunkSize == 0) + :break; + + output.write(eol, chunkSize, buffer); + + current := eol + chunkSize + 2; + }; + + ^ UTF8Encoding.toString(0, output.Length, output.Content); + } + else { + ^ UTF8Encoding.toString(eoh, length - eoh, _buffer.Content); + } } } \ No newline at end of file diff --git a/src60/net/win32_listener.l b/src60/net/win32_listener.l index d8d9e6e5cd..b47f21cef7 100644 --- a/src60/net/win32_listener.l +++ b/src60/net/win32_listener.l @@ -60,9 +60,12 @@ public class TcpListener ^ socket } + private Task listenAsync() + = ::Task.run({ ^ _listenSocket.accept(); }); + async Task acceptSocketAsync() { - Socket socket := :await _listenSocket.acceptAsync(); + Socket socket := :await listenAsync(); if:not(socket.isInvalid) { if (_noDelayMode) @@ -86,7 +89,7 @@ public class TcpListener async Task acceptTcpClientAsync() { - Socket socket := :await _listenSocket.acceptAsync(); + Socket socket := :await listenAsync(); if:not(socket.isInvalid) { if (_noDelayMode) diff --git a/src60/system/app.l b/src60/system/app.l index 663bbe4d4d..ba370b28f5 100644 --- a/src60/system/app.l +++ b/src60/system/app.l @@ -38,7 +38,7 @@ entry() { startUpEvents.handlingError(err); - console.writeLine(err); + Console.writeLine(err); extern ExitLA(-1); } diff --git a/src60/system/culture/common.l b/src60/system/culture/common.l index 57b798a7c5..544f9d1ac0 100644 --- a/src60/system/culture/common.l +++ b/src60/system/culture/common.l @@ -1,6 +1,6 @@ namespace culture { - interface ILocale + public interface ILocale { abstract string toUppercase(string s); abstract wide toUppercase(wide s); @@ -37,4 +37,5 @@ namespace culture wide toLower() = currentLocale.toLowercase(self); - }} \ No newline at end of file + } +} \ No newline at end of file diff --git a/src60/system/culture/win_locale.l b/src60/system/culture/win_locale.l index dee28d7c4e..45444c1d98 100644 --- a/src60/system/culture/win_locale.l +++ b/src60/system/culture/win_locale.l @@ -20,10 +20,10 @@ namespace culture _name := nil } - get static Current() + get static ILocale Current() = Locale.new(emptyWideString); - get static Invariant() + get static ILocale Invariant() = new Locale(); private strToUpper(short[] src, int length, short[] dest, ref int destLength) @@ -127,7 +127,7 @@ namespace culture } } - public static Locale invariantLocale = Locale.Invariant; + public static ILocale invariantLocale = Locale.Invariant; - public static Locale currentLocale = Locale.Current; + public static ILocale currentLocale = Locale.Current; } \ No newline at end of file diff --git a/src60/system/dynamic/expressions/expressions.l b/src60/system/dynamic/expressions/expressions.l index cd7167618e..6e7f722039 100644 --- a/src60/system/dynamic/expressions/expressions.l +++ b/src60/system/dynamic/expressions/expressions.l @@ -1965,7 +1965,7 @@ namespace expressions function(Exception err) { - console.writeLine(err); + Console.writeLine(err); } } } diff --git a/src60/system/io/memorystream.l b/src60/system/io/memorystream.l index 16c74cf959..161461e695 100644 --- a/src60/system/io/memorystream.l +++ b/src60/system/io/memorystream.l @@ -20,6 +20,9 @@ namespace io _used := 0; } + get byte[] Content + = _buffer; + get byte[] Value() { int used := _used.Value; @@ -50,30 +53,33 @@ namespace io private writeInternal(int index, int length, byte[] array) { - byte temp[64]; + byte temp[1024]; int n := index; int len := length; - int temp_len := 64; + int temp_len := 1024; int used := _used.Value; while (len > 0) { - if(len < 64) + if(len < 1024) { temp_len := len } else { - temp_len := 64 + temp_len := 1024 }; Array.copy(temp, array, n, temp_len); Array.copyTo(_buffer, temp, used, temp_len); - + + used += temp_len; n := n + temp_len; len := len - temp_len - } + }; + + _used.append(length) } write(int index, int length, byte[] array) @@ -81,9 +87,6 @@ namespace io int used := _used.Value; int capacity := _capacity.Value; - if(used < index) - { OutOfRangeException.raise() }; - if(capacity < used + length) { self.reserve(length) }; diff --git a/src60/system/net/networkstream.l b/src60/system/net/networkstream.l index 8ba1fc3bcc..e70a9fd0f4 100644 --- a/src60/system/net/networkstream.l +++ b/src60/system/net/networkstream.l @@ -7,11 +7,13 @@ public class NetworkStream : Stream { Socket _socket; bool _ownStream; + byte[] _buffer; constructor(Socket socket) { _socket := socket; _ownStream := false; + _buffer := new byte[](512); } constructor assign(Socket socket, bool socketStream) @@ -56,14 +58,36 @@ public class NetworkStream : Stream } indexed internal Task readAsync(byte[] dump, int length) - = _socket.receiveAsync(dump, length, 0); + = ::Task.run({ ^ _socket.receive(dump, length, 0) }); indexed internal Task writeAsync(byte[] dump, int length) - = _socket.sendAsync(dump, length, 0); + = ::Task.run({ ^ _socket.send(dump, length, 0) }); indexed internal bool isDataAvailable = _socket.available() != 0; + indexed async internal Task readAsync(MemoryBuffer buffer, int length) + { + int total_received := 0; + int total := length; + while (total > 0) { + int size := 512; + if (size > length) + size := length; + + int received := :await readAsync(_buffer, size); + if (received > 0) { + total_received += received; + total -= received; + + buffer.write(0, received, _buffer); + } + else :break; + }; + + ^ total_received; + } + indexed async internal Task writeAsync(string s) { byte tmp[1024]; @@ -123,6 +147,9 @@ public extension AsyncStreamExtension : NetworkStream Task readAsStringAsync() = self.readAsStringAsync(); + Task readAsync(MemoryBuffer buffer, int length) + = self.readAsync(buffer, length); + // async Task writeAsync(string s) // { // byte tmp[1024]; diff --git a/src60/system/net/win_sockets.l b/src60/system/net/win_sockets.l index 76986fea53..798cb026f4 100644 --- a/src60/system/net/win_sockets.l +++ b/src60/system/net/win_sockets.l @@ -79,47 +79,6 @@ public sealed struct IN_ADDR } } -// --- hostent --- -public sealed struct hostent -{ - pointer h_name; - pointer h_aliases; - short h_addrtype; - short h_length; - pointer h_addr_list; - - static hostent load(string host) - { - hostent tmp := default; - - pointer ptr := extern WS2_32.gethostbyname(host); - - ptr.copyToUnsafe(tmp, $size tmp); - - ^ tmp - } - - get string IP() - { - if (h_addrtype == AF_INET) { - pointer addr := h_addr_list.Value; - pointer paddr_in := addr.Value; - - IN_ADDR addr_in := default; - addr_in.Value := paddr_in.getLongValue(); - - pointer pip := extern WS2_32.inet_ntoa(addr_in); - - ^ pip.getStringUnsafe(); - } - else { - SocketException.new("gethostbyname failed").raise() - }; - - ^ nil; - } -} - // --- SOCKADDR_IN --- public sealed packed SOCKADDR_IN @@ -142,28 +101,31 @@ public sealed packed SOCKADDR_IN } } - set Ip_address(string ip) + set Ip4_address(string ip) { family := AF_INET; - int retVal := extern WS2_32.inet_pton(AF_INET, ip, sin_addr); + IN_ADDR in_addr := default; + int retVal := extern WS2_32.inet_pton(AF_INET, ip, /*sin_addr*/in_addr); if (retVal < 0) { SocketException.new("Can't set remote->sin_addr.s_addr", retVal).raise(); } else if (retVal == 0) { SocketException.new("Not a valid IP", retVal).raise(); - } + }; + + sin_addr := in_addr; } set Port(short value) { - port := extern WS2_32.htons(value); + port := /*extern WS2_32.htons(value)*/value; } get short Port() { - short val := extern WS2_32.ntohs(port); + short val := /*extern WS2_32.ntohs(*/port/*)*/; ^ val } @@ -249,6 +211,48 @@ public sealed const struct Socket { handle _handle; + static Socket connect(string host, short port) + { + Socket socket := default; + + //resolve server address and port + AddrInfo addrinfo := default; + + // set address info + addrinfo.ai_family := AF_UNSPEC; + addrinfo.ai_socktype := SOCK_STREAM; + addrinfo.ai_protocol := IPPROTO_TCP; + + AddrInfoReader reader := new AddrInfoReader(host, port.toPrintable(), addrinfo); + while (reader.Available) + { + reader.read(addrinfo); + + int ai_family := addrinfo.ai_family; + int ai_socktype := addrinfo.ai_socktype; + int ai_protocol := addrinfo.ai_protocol; + int ai_addrlen := addrinfo.ai_addrlen; + pointer ai_addrptr := addrinfo.ai_addr; + + socket := new Socket(ai_family, ai_socktype, ai_protocol); + + if (socket.tryOpen(ai_addrptr, ai_addrlen)) + { + reader.close(); + + ^ socket + }; + + reader.next() + }; + + reader.close(); + + SocketException.raise($"Unable to open {host}"); + + ^ socket + } + constructor(handle handle) { _handle := handle @@ -315,23 +319,6 @@ public sealed const struct Socket ^ (SOCKET_ERROR != retVal) } - connect(string ip_address, int port) - { - SOCKADDR_IN addr := SOCKADDR_IN.Default; - addr.Port := port; - addr.Family := system'net'AF_INET; - addr.Ip_address := ip_address; - - pointer ptr := addr; - int retVal := extern WS2_32.connect(_handle, ptr, SOCKADDR_IN_SIZE); - - if (retVal == SOCKET_ERROR) - { SocketException.new("Error at socket").raise() } - } - - Task connectAsync(string ip_address, int port) - = Task.run({ connect(ip_address, port); }); - int send(byte[] buffer) { int len := buffer.Length; @@ -339,14 +326,6 @@ public sealed const struct Socket ^ self.send(buffer, len, 0); } - Task sendAsync(byte[] buffer) - = ::Task.run( - { - int written := send(buffer); - - ^ written - }); - int send(byte[] buffer, int length, int flags) { int retVal := extern WS2_32.send(_handle, buffer, length, flags); @@ -357,14 +336,6 @@ public sealed const struct Socket ^ retVal } - Task sendAsync(byte[] buffer, int length, int flags) - = ::Task.run( - { - int sent := send(buffer, length, flags); - - ^ sent - }); - int receive(byte[] buffer, int maxLength, int flags) { int retVal := extern WS2_32.recv(_handle,buffer,maxLength,flags); @@ -379,14 +350,6 @@ public sealed const struct Socket ^ retVal } - Task receiveAsync(byte[] buffer, int maxLength, int flags) - = ::Task.run( - { - int received := receive(buffer, maxLength, flags); - - ^ received - }); - Socket accept() { handle socket := extern WS2_32.accept(_handle, 0, 0); @@ -394,14 +357,6 @@ public sealed const struct Socket ^ socket } - Task acceptAsync() - = ::Task.run( - { - handle socket := extern WS2_32.accept(_handle, 0, 0); - - ^ new Socket(socket) - }); - shutdown(int how) { int retVal := extern WS2_32.shutdown(_handle, how); diff --git a/src60/system/system.linux.prj b/src60/system/system.linux.prj index 550fad335e..621b735eeb 100644 --- a/src60/system/system.linux.prj +++ b/src60/system/system.linux.prj @@ -50,7 +50,7 @@ ELENA Standard Library - 6.6.0 + 6.6.1 Aleksey Rakov diff --git a/src60/system/system.prj b/src60/system/system.prj index 9e5f3159a3..1f855d765c 100644 --- a/src60/system/system.prj +++ b/src60/system/system.prj @@ -18,7 +18,7 @@ ELENA Standard Library - 6.6.0 + 6.6.1 Aleksey Rakov diff --git a/src60/system/text/textbuffer.l b/src60/system/text/textbuffer.l index fefbeabe00..3ae5675207 100644 --- a/src60/system/text/textbuffer.l +++ b/src60/system/text/textbuffer.l @@ -506,7 +506,7 @@ namespace text _length.append(counter) } - wide(o) + write(o) <= write(o.toPrintable()); insert(int index, char ch) diff --git a/src60/system/threading/blockinglists.l b/src60/system/threading/blockinglists.l index 3983b09e43..aa6e047b55 100644 --- a/src60/system/threading/blockinglists.l +++ b/src60/system/threading/blockinglists.l @@ -13,9 +13,9 @@ public sealed class BlockingQueue push(T value) { - _semaphore.release(); - _list.push(value); + + _semaphore.release(); } T pop() diff --git a/src60/system/threading/tasks.l b/src60/system/threading/tasks.l index dda0d858c5..6090216f28 100644 --- a/src60/system/threading/tasks.l +++ b/src60/system/threading/tasks.l @@ -84,6 +84,11 @@ public class Task sealed wait() { if (_completed) { + if:not:nil (_exception) + { + _exception.raise() + }; + ^ self }; diff --git a/tests60/sandbox/sandbox.l b/tests60/sandbox/sandbox.l index 78169e0623..77b77b1341 100644 --- a/tests60/sandbox/sandbox.l +++ b/tests60/sandbox/sandbox.l @@ -2,10 +2,13 @@ import extensions; public program() { - real r := 1.0; + int i := 1; - real z := r.exp(); - console.printLine(z); + real a := -1.0/*.power(i)*/; - console.printLine(z.ln()); + //Console.printLine(a); + //Console.printLine(b); + //Console.printLine(c); + //Console.printLine(d); + Console.printLine(a / (i*2/*+1*/) /** 4*/); } \ No newline at end of file diff --git a/tests60/sandbox2/sandbox2.l b/tests60/sandbox2/sandbox2.l index 9dcf84808b..e2e2bd45c1 100644 --- a/tests60/sandbox2/sandbox2.l +++ b/tests60/sandbox2/sandbox2.l @@ -12,7 +12,7 @@ public program() int n := 1; while (true) { lock(sync) { - console.writeLine("Line from thread 1 : " + n.toPrintable()); + Console.writeLine("Line from thread 1 : " + n.toPrintable()); n++; }; if (n == 50000) @@ -21,7 +21,7 @@ public program() } catch(Exception ex) { - console.writeLine(ex); + Console.writeLine(ex); } }); @@ -30,13 +30,13 @@ public program() int n := 1000; while (true) { lock(sync) { - console.writeLine("Line from thread 2 : " + n.toPrintable()); + Console.writeLine("Line from thread 2 : " + n.toPrintable()); n++; } } }); - console.readChar() + Console.readChar() } /*public program() @@ -47,11 +47,11 @@ public program() { var s := list.pop(); - console.printLine("Thread says ",s); + Console.printLine("Thread says ",s); }); - console.printLineConcurrent("Send a message to a thread"); - var msg := console.readLine(); + Console.printLineConcurrent("Send a message to a thread"); + var msg := Console.readLine(); list.push(msg); diff --git a/tests60/script_tests/basic.l b/tests60/script_tests/basic.l index 25b8a44585..0ab279a1f0 100644 --- a/tests60/script_tests/basic.l +++ b/tests60/script_tests/basic.l @@ -8,5 +8,5 @@ public evalTest() : testCase() Assert.ifEqual(ret, "Hello World"); - console.write("."); + Console.write("."); } diff --git a/tests60/script_tests/main.l b/tests60/script_tests/main.l index 7c624ecebc..c4c2b34d5a 100644 --- a/tests60/script_tests/main.l +++ b/tests60/script_tests/main.l @@ -2,9 +2,9 @@ import ltests; public program() { - console.writeLine("--- ELENA 6 Script Functional Tests ---"); + Console.writeLine("--- ELENA 6 Script Functional Tests ---"); Engine.run(); - console.writeLine("--- Passed ---") + Console.writeLine("--- Passed ---") } \ No newline at end of file diff --git a/tests60/system_tests/basic.l b/tests60/system_tests/basic.l index 50ca86802e..d4cdea3b29 100644 --- a/tests60/system_tests/basic.l +++ b/tests60/system_tests/basic.l @@ -28,24 +28,24 @@ public controlTest() : testCase() Assert.ifTrue(b1); Assert.ifTrue(b2); - console.write("."); + Console.write("."); bool b3 := true; Assert.ifEqual(b3 ? 2.0 : 3.0, 2.0); - console.write(".") + Console.write(".") } public objectTest() : testCase() { - console.write("objectTest:"); + Console.write("objectTest:"); var a := 1; var b := "abc"; Assert.ifTrue(a.equalReference(a) && a.equalReference(b).Inverted); - console.write(".") + Console.write(".") } // --- BooleanTest --- @@ -62,7 +62,7 @@ public booleanTest() : testCase() Assert.ifFalse(b2 != b2); Assert.ifTrue(b1 != b2); - console.write(".") + Console.write(".") } // --- intTests --- @@ -76,7 +76,7 @@ public intTests() : testCase() Assert.ifTrue(2 + 3 * 4 == 14); Assert.ifTrue(n + m * k == 14); - console.write("."); + Console.write("."); Assert.ifFalse(n == m); Assert.ifTrue(n == n); Assert.ifTrue(n < m); @@ -89,7 +89,7 @@ public intTests() : testCase() Assert.ifFalse(m < l); Assert.ifTrue(m >= l); Assert.ifTrue(m <= l); - console.write("."); + Console.write("."); int m2 := 10; int k2 := -2; @@ -98,7 +98,7 @@ public intTests() : testCase() Assert.ifFalse(k2 > m2); Assert.ifTrue(m2 > k2); Assert.ifFalse(k2 < l2); - console.write("."); + Console.write("."); int i := 1; i += 2; @@ -106,7 +106,7 @@ public intTests() : testCase() i *= 2; i /= 2; Assert.ifTrue(i == 1); - console.write("."); + Console.write("."); } public uintTests() : testCase() @@ -120,13 +120,13 @@ public uintTests() : testCase() Assert.ifFalse(m < l); // 081000000H < 10 Assert.ifTrue(l < m); // 10 < 081000000H Assert.ifTrue(n > m); // 08FFFFFFFH > 081000000H - console.write("."); + Console.write("."); m := 80000000H; n := 10H; k := m / n; Assert.ifTrue(k == 8000000H); - console.write("."); + Console.write("."); } @@ -146,7 +146,7 @@ public longTests() : testCase() long in64 := in32; Assert.ifTrue(n64 == 23456l); Assert.ifTrue(in64 == -23458l); - console.write("."); + Console.write("."); long n := 2l; long m := 3l; @@ -154,12 +154,12 @@ public longTests() : testCase() Assert.ifTrue(2l + 3l * 4l == 14l); Assert.ifTrue(n + m * k == 14l); - console.write("."); + Console.write("."); n := 2000000l; m := 500000l; Assert.ifTrue(n * m == 1000000000000l); - console.write("."); + Console.write("."); n := 12345678l; m := 12345679l; @@ -175,7 +175,7 @@ public longTests() : testCase() Assert.ifFalse(m == n); Assert.ifTrue(m > n); Assert.ifFalse(m < n); - console.write("."); + Console.write("."); long l := 2l; l2 := -2l; @@ -187,7 +187,7 @@ public longTests() : testCase() Assert.ifTrue(l > l2); Assert.ifTrue(l2 < l); Assert.ifFalse(l2 > l); - console.write("."); + Console.write("."); n := 2; int n2 := -2; @@ -201,7 +201,7 @@ public longTests() : testCase() Assert.ifFalse(l < n); // ; false Assert.ifTrue(l2 < n); // ; true Assert.ifFalse(l2 < n2); // ; false - console.write("."); + Console.write("."); long i := 0l; i += 3l; @@ -209,13 +209,13 @@ public longTests() : testCase() i *= 2l; i /= 2l; Assert.ifTrue(i == 1l); - console.write("."); + Console.write("."); var tester := (long l, long control1, long control2) { long r1 := -l; long r2 := -r1; Assert.ifTrue(r1 == control1); Assert.ifTrue(r2 == control2); }; tester(-1l,1l,-1l); tester(-5000000000l,5000000000l,-5000000000l); - console.write("."); + Console.write("."); } // --- realTests --- @@ -225,14 +225,14 @@ public realTests() : testCase() real r := 2.89787; Assert.ifFalse(r == 2.8); Assert.ifTrue(r == 2.89787); - console.write("."); + Console.write("."); real n := 2.0; real m := 3.0; real k := 4.0; Assert.ifTrue(n + m * k == 14.0); - console.write("."); + Console.write("."); real i := 1.0; i += 2.1; @@ -240,7 +240,7 @@ public realTests() : testCase() i *= 2.0; i /= 2.0; Assert.ifTrue(i == 1.0); - console.write("."); + Console.write("."); Assert.ifFalse(n == m); Assert.ifTrue(n != m); @@ -252,16 +252,16 @@ public realTests() : testCase() Assert.ifTrue(n <= n); Assert.ifTrue(n < m); Assert.ifTrue(m > n); - console.write("."); + Console.write("."); int rounded := r.RoundedInt; Assert.ifTrue(rounded == 3); - console.write("."); + Console.write("."); real negr := -2.3; real absr := negr.Absolute; Assert.ifTrue(absr == 2.3); - console.write("."); + Console.write("."); } // --- gcTests --- @@ -272,7 +272,7 @@ public gcTests() : testCase() { new IntNumber(); }; - console.write("."); + Console.write("."); } // --- stringTests --- @@ -283,7 +283,7 @@ public stringTests() : testCase() Assert.ifTrue("ba" > "ab"); Assert.ifTrue("ab" < "abc"); Assert.ifTrue("abc" + "de" == "abcde"); - console.write("."); + Console.write("."); Assert.ifTrue("abcd".indexOf(0, "bc")==1); Assert.ifTrue("abcd".indexOf(2, "bc")==-1); @@ -292,27 +292,27 @@ public stringTests() : testCase() Assert.ifTrue("abecd".delete(2,1) == "abcd"); Assert.ifTrue("abcd".Substring(1,2) == "bc"); Assert.ifTrue("abc"[1] == "b"); - console.write("."); + Console.write("."); Assert.ifFailed({ "abc"[-1] }); Assert.ifFailed({ "abc"[4] }); - console.write("."); + Console.write("."); string s := "abc"; Assert.ifTrue(s == "abc"); - console.write("."); + Console.write("."); string s2 := "de"; var s3 := s + s2; Assert.ifTrue(s3 == "abcde"); - console.write("."); + Console.write("."); Assert.ifTrue("s1" < "s2"); Assert.ifTrue("s2" < "s2"); Assert.ifFalse("s2" < "s1"); - console.write("."); + Console.write("."); } // --- wideTests --- @@ -334,23 +334,23 @@ public wideTests() : testCase() Assert.ifFailed({ "abc"w[-1] }); Assert.ifFailed({ "abc"w[4] }); - console.write("."); + Console.write("."); wide s := "abc"w; Assert.ifTrue(s == "abc"w); - console.write("."); + Console.write("."); wide s2 := "de"w; var s3 := s + s2; Assert.ifTrue(s3 == "abcde"w); - console.write("."); + Console.write("."); Assert.ifTrue("s1"w < "s2"w); Assert.ifTrue("s2"w < "s2"w); Assert.ifFalse("s2"w < "s1"w); - console.write("."); + Console.write("."); } // --- shortTests --- @@ -359,7 +359,7 @@ public shortTests() : testCase() { short w := 1234; Assert.ifTrue(w == 1234); - console.write("."); + Console.write("."); short n := 2; short m := 3; @@ -367,7 +367,7 @@ public shortTests() : testCase() short l := 3; Assert.ifTrue(n + m * k == 14); - console.write("."); + Console.write("."); } // --- ushortTests --- @@ -376,7 +376,7 @@ public ushortTests() : testCase() { short w := 1234; Assert.ifTrue(w == 1234); - console.write("."); + Console.write("."); ushort n := 2; ushort m := 3; @@ -392,10 +392,10 @@ public ushortTests() : testCase() Assert.ifTrue(n == n); Assert.ifFalse(n == m); - console.write("."); + Console.write("."); Assert.ifTrue(n + m * k == 14); - console.write("."); + Console.write("."); } // --- conversionTests --- @@ -405,17 +405,17 @@ public conversionTests() : testCase() var n := "23".toInt(); var sn := n.toString(); Assert.ifTrue(sn == "23"); - console.write("."); + Console.write("."); Assert.ifTrue("1234567890123456".toLong() == 1234567890123456l); Assert.ifTrue("-123".toInt() == -123); Assert.ifTrue("-1234567890123456".toLong() == -1234567890123456l); - console.write("."); + Console.write("."); Assert.ifTrue("23".toReal() == 23.0); Assert.ifTrue("123.456789".toReal() == 123.456789); Assert.ifTrue("-123.456789".toReal() == -123.456789); - console.write("."); + Console.write("."); Assert.ifTrue(-2l.toInt() == -2); Assert.ifTrue(-2.toLong() == -2l); @@ -425,18 +425,18 @@ public conversionTests() : testCase() Assert.ifTrue(-2.0.toLong() == -2l); Assert.ifTrue(-2l.toReal() == -2.0); - console.write("."); + Console.write("."); int n2 := 1234; short w := n2; Assert.ifTrue(w == 1234); - console.write("."); + Console.write("."); string s := n2.toString(); Assert.ifTrue(s == "1234"); - console.write("."); + Console.write("."); int n3 := s.toInt(); Assert.ifTrue(n3 == n2); - console.write("."); + Console.write("."); } // --- assignTests --- @@ -464,7 +464,7 @@ public assignTests() : testCase() var o := new AssignTestClass(2,"test"); o.test(2,"test"); - console.write("."); + Console.write("."); } // --- boxingTests --- @@ -561,24 +561,24 @@ public boxingTests() : testCase() // --- boxing read-only struct // 1a. passing directly BoxingProber.check(n); - console.write("."); + Console.write("."); // 1b. weak passing directly var o := BoxingProber; o.check(n); - console.write("."); + Console.write("."); // --- boxing / unboxing variable struct BoxingStruct st := default; BoxingProber.set(st); st.test(3,4); - console.write("."); + Console.write("."); BoxingStruct st2; var p := BoxingProber; p.set(st2); st2.test(3,4); - console.write("."); + Console.write("."); BoxingFixedArrayStruct x := new BoxingFixedArrayStruct(); byte b := 2; @@ -587,20 +587,20 @@ public boxingTests() : testCase() x.test(0,1); x.test(1,b); - console.write("."); + Console.write("."); var xint := new XInteger(2); var nint := cast int(xint); Assert.ifTrue(nint.instanceOf(IntNumber)); - console.write("."); + Console.write("."); int n2 := 2; int m2 := 2; Assert.ifTrue(n2.check(m2)); - console.write("."); + Console.write("."); } // --- byRefTests --- @@ -624,26 +624,26 @@ public byRefTests() : testCase() ByRefProber.set(ref n); Assert.ifTrue(n == 123); - console.write("."); + Console.write("."); int m := 0; var o := ByRefProber; o.set(ref m); Assert.ifTrue(m == 123); - console.write("."); + Console.write("."); string s := "none"; ByRefProber.set(ref s); Assert.ifTrue(s == "hello"); - console.write("."); + Console.write("."); string s2 := "none"; o.set(ref s2); Assert.ifTrue(s2 == "hello"); - console.write("."); + Console.write("."); } // --- inlineAssignmentTests --- @@ -680,10 +680,10 @@ public inlineAssignmentTests() : testCase() { var b := new InlineAssignTesterBase(); b.validate(); - console.write("."); + Console.write("."); var c := new InlineAssignTesterChild(); c.validate(); - console.write("."); + Console.write("."); var child := new InlineAssignTester2Base { this x := 1; @@ -693,7 +693,7 @@ public inlineAssignmentTests() : testCase() }; child.validate(); - console.write("."); + Console.write("."); } class DispatchType @@ -740,13 +740,13 @@ public singleDispatchTest() : testCase() Assert.ifTrue(weakDispatcher.check(arg1) == 1); Assert.ifTrue(weakDispatcher.check(arg2) == 2); - console.write("."); + Console.write("."); auto dispatcher := new SingleDispatcher(); Assert.ifTrue(dispatcher.check(arg1) == 1); Assert.ifTrue(dispatcher.check(arg2) == 2); - console.write("."); + Console.write("."); } @@ -792,11 +792,11 @@ public variadicTest() : testCase() tester.test2("hello",3,3); tester.validate(); - console.write("."); + Console.write("."); Assert.ifTrue(tester.sum(1,2,3)==6); Assert.ifTrue(tester.passAndSum(1,2,3)==6); - console.write("."); + Console.write("."); // compile-time auto tester2 := new VariadicTester(); @@ -804,12 +804,12 @@ public variadicTest() : testCase() tester2.test1(1,3,3); tester2.test2("hello",3,3); tester2.validate(); - console.write("."); + Console.write("."); Assert.ifTrue(tester.sum(1,2,3)==6); Assert.ifTrue(tester.passAndSum(1,2,3)==6); - console.write(".") + Console.write(".") } // --- dynamicLoadTests --- @@ -827,7 +827,7 @@ public dynamicLoadTests() : testCase() Assert.ifTrue(o.instanceOf(DynamicallyLoadedClass)); - console.write("."); + Console.write("."); } interface ITest @@ -864,7 +864,7 @@ public interfaceTests() : testCase() int n := i.Index; Assert.ifTrue(n == 2); - console.write("."); + Console.write("."); } singleton VariadicFunctionDispatchTester @@ -901,7 +901,7 @@ public vardispatcherTest() : testCase() Assert.ifTrue(r1 == 6); var r2 := VariadicDispatchTester.product(1,2,3,4); Assert.ifTrue(r2 == 24); - console.write("."); + Console.write("."); var o := VariadicFunctionDispatchTester; var o2 := VariadicDispatchTester; @@ -910,7 +910,7 @@ public vardispatcherTest() : testCase() var r4 := o2.product(1,2,3,4); Assert.ifTrue(r4 == 24); - console.write("."); + Console.write("."); } // --- mssgDispatchTest --- @@ -930,7 +930,7 @@ public mssgDispatchTest() : testCase() Assert.ifTrue(r == 3); - console.write(".") + Console.write(".") } // --- MultySelectTest --- @@ -944,7 +944,7 @@ public multySelectTest() : testCase() 2 : { Assert.ifTrue(n==2); } 3 : { Assert.ifTrue(n==3); }; - console.write(".") + Console.write(".") } // --- stringEnumerationTest --- @@ -959,7 +959,7 @@ public stringEnumerationTest() : testCase() Assert.ifTrue(s == "321"); - console.write(".") + Console.write(".") } // --- TextBufferTest --- @@ -974,7 +974,7 @@ public textBufferTest() : testCase() Assert.ifTrue(buffer.Value == "abc"); - console.write("."); + Console.write("."); } // --- LoopTest --- @@ -1016,13 +1016,13 @@ public loopTest() : testCase() Assert.ifTrue(sum == 0); - console.write("."); + Console.write("."); var counter := new LoopTester(); while(counter.next()) {}; counter.assert(); - console.write(".") + Console.write(".") } // --- Action Test --- @@ -1044,7 +1044,7 @@ public actionTest() : testCase() var r2 := ActionTester.testStrong((int x, int y => x + y), 2, 3); Assert.ifTrue(r2 == 5); - console.write("."); + Console.write("."); } // --- ArrayTest --- @@ -1064,7 +1064,7 @@ public arrayTest() : testCase() Assert.ifFailed({ "abc"[-1] }); Assert.ifFailed({ "abc"[4] }); - console.write(".") + Console.write(".") } // --- ExceptionTest --- @@ -1104,7 +1104,7 @@ public exceptionTest() : testCase() bool raised := false; ExecTester.break() \\ on::(e){ raised := true }; Assert.ifTrue(raised); - console.write("."); + Console.write("."); bool passed := false; try @@ -1123,7 +1123,7 @@ public exceptionTest() : testCase() } }; Assert.ifTrue(passed); - console.write("."); + Console.write("."); bool passed2 := false; try @@ -1134,7 +1134,7 @@ public exceptionTest() : testCase() } catch(MyException e) { - console.writeLine("!!Wrong handler"); + Console.writeLine("!!Wrong handler"); Assert.ifTrue(false) } } @@ -1144,7 +1144,44 @@ public exceptionTest() : testCase() }; Assert.ifTrue(passed2); - console.write(".") + Console.write(".") +} + +// -- tryFinallyTest --- + +public tryFinallyTest() : testCase() +{ + var passed := false; + var passed2 := false; + Assert.ifFailed( + { + var o := new Object(); + try + { + o.fail() + } + finally + { + passed := true + } + }); + Assert.ifTrue(passed); + Console.write("."); + + Assert.ifNotFailed( + { + var o := new Object(); + try + { + o.toPrintable() + } + finally + { + passed2 := true + } + }); + Assert.ifTrue(passed); + Console.write("."); } // --- nestedFieldsTest -- @@ -1179,7 +1216,7 @@ public nestedFieldsTest() : testCase() Assert.ifEqual(n.getParentField(), 2); Assert.ifEqual(n.getParentParentField(), 3); - console.write(".") + Console.write(".") } public shortCircuitBooleanOperation() : testCase() @@ -1189,7 +1226,7 @@ public shortCircuitBooleanOperation() : testCase() Assert.ifFalse(b); - console.write(".") + Console.write(".") } class NestedTester @@ -1217,7 +1254,7 @@ public nestedTest() : testCase() tester.validate(); - console.write(".") + Console.write(".") } // --- nestetNestedTest() --- @@ -1249,7 +1286,7 @@ public nestetNestedTest() : testCase() tester.validate(); - console.write(".") + Console.write(".") } public ifExpressionTest() : testCase() @@ -1282,7 +1319,7 @@ public ifExpressionTest() : testCase() Assert.ifTrue(o.eval(1,2)); Assert.ifFalse(o.eval(1,1)); - console.write(".") + Console.write(".") } public loopExpressionTest() : testCase() @@ -1335,7 +1372,7 @@ public loopExpressionTest() : testCase() Assert.ifEqual(o.eval(4), 8); Assert.ifEqual(o.eval(0), 0); - console.write(".") + Console.write(".") } A; @@ -1374,11 +1411,11 @@ public nilDispatcherTest() : testCase() d.testMe(1, b) \ back(nil); d.validate(1); - console.write("."); + Console.write("."); d.testMe(1, nil) \ back(nil); d.validate(1); - console.write("."); + Console.write("."); d2.testMe(1, a) \ back(nil); d2.validate(1); @@ -1389,14 +1426,14 @@ public nilDispatcherTest() : testCase() d2.testMe(1, nil) \ back(nil); d2.validate(1); - console.write(".") + Console.write(".") } public duplicateBoxing() : testCase() { var t := 0; int t2 := 0; - console.then( + Console.then( { Assert.ifTrue(t == 0); Assert.ifTrue(t2 == 0); @@ -1411,18 +1448,18 @@ public duplicateBoxing() : testCase() t := 2; t2 += 1; }); - console.write("."); + Console.write("."); Assert.ifTrue(t == 2); Assert.ifTrue(t2 == 2); - console.write("."); + Console.write("."); var mode := -1; var value := false; value ? { mode := 0 } ! { mode := 1 }; Assert.ifTrue(mode == 1); - console.write("."); + Console.write("."); mode := -1; value := true; @@ -1430,7 +1467,7 @@ public duplicateBoxing() : testCase() Assert.ifTrue(mode == 0); - console.write(".") + Console.write(".") } public extension etOp @@ -1454,7 +1491,7 @@ public templateExtensionTest() : testCase() auto a := new A(); Assert.testExtension(a); - console.write(".") + Console.write(".") } public stackSafeExtensions() : testCase() @@ -1475,14 +1512,14 @@ public stackSafeExtensions() : testCase() Assert.ifTrue(r3 == 1); Assert.ifTrue(r4 == 1); - console.write(".") + Console.write(".") } public genericTest() : testCase() { var r := cast int(nilValue); Assert.ifTrue(r == nil); - console.write(".") + Console.write(".") } @@ -1510,7 +1547,7 @@ public outerFieldAssigningTest() : testCase() tester.apply(2); tester.test(2); - console.write("."); + Console.write("."); } // --- methodNotFoundTest --- @@ -1530,7 +1567,7 @@ public methodNotFoundTest() : testCase() Assert.ifTrue(f); - console.write("."); + Console.write("."); } // --- methodNotFoundTest --- @@ -1550,7 +1587,7 @@ public nilReferenceTest() : testCase() Assert.ifTrue(f); - console.write("."); + Console.write("."); } // --- structTest --- @@ -1598,19 +1635,19 @@ public structTest() : testCase() Assert.ifTrue(xy.x == 2); Assert.ifTrue(xy.y == 3); - console.write("."); + Console.write("."); StructTest.testMe(xy2); Assert.ifTrue(xy2.x == 1); Assert.ifTrue(xy2.y == 2); - console.write("."); + Console.write("."); StructTest.testMe2(xy2); Assert.ifTrue(xy2.x == 3); Assert.ifTrue(xy2.y == 4); - console.write("."); + Console.write("."); } singleton LookaheadHelper @@ -1636,7 +1673,7 @@ public lookaheadTests() : testCase() Assert.ifTrue(r == 3); Assert.ifTrue(r2 == 4); - console.write("."); + Console.write("."); } struct IncTestStruct @@ -1664,7 +1701,7 @@ public incTest() : testCase() struct.act(); struct.assert(); - console.write("."); + Console.write("."); } @@ -1684,26 +1721,26 @@ public multiValTest() : testCase() Assert.ifTrue(t.Item1 == 3); Assert.ifTrue(t.Item2 == "abc"); - console.write("."); + Console.write("."); auto t2 := MultiValGetter.getMultiVal(); Assert.ifTrue(t2.Item1 == "Alex"); Assert.ifTrue(t2.Item2 == 13); - console.write("."); + Console.write("."); var i1, i2 := MultiValGetter.getMultiVal(); Assert.ifTrue(i1 == "Alex"); Assert.ifTrue(i2 == 13); - console.write("."); + Console.write("."); (string x1, int x2) := MultiValGetter.getMultiVal(); Assert.ifTrue(x1 == "Alex"); Assert.ifTrue(x2 == 13); - console.write("."); + Console.write("."); } // -- defaultTest -- @@ -1748,7 +1785,7 @@ public defaultTest() : testCase() Assert.ifEqual(b, new DefaultB()); Assert.ifEqual(c, DefaultC.load(0)); - console.write("."); + Console.write("."); } // -- retValTests -- @@ -1770,7 +1807,7 @@ public retValTests() : testCase() Assert.ifInstanceOf(a.eval(), RetValA); Assert.ifInstanceOf(a.extendEval(), RetValA); - console.write("."); + Console.write("."); } static variableToBeLoaded = new Variable(1); @@ -1782,7 +1819,7 @@ public preloadedTests() : testCase() { Assert.ifEqual(variableToBeLoaded, 4); - console.write("."); + Console.write("."); } // --- staticFieldAssigningOpTests --- @@ -1806,7 +1843,7 @@ public staticFieldAssigningOpTests() : testCase() StaticFieldAssigningOpHelper.inc(); Assert.ifEqual(StaticFieldAssigningOpHelper.get(), 2); - console.write("."); + Console.write("."); } public RealArrayOpTests() : testCase() @@ -1819,7 +1856,7 @@ public RealArrayOpTests() : testCase() Assert.ifEqual(r.Length, 3); Assert.ifEqual(r[1], 2.3); - console.write("."); + Console.write("."); } public ShortArrayOpTests() : testCase() @@ -1832,7 +1869,7 @@ public ShortArrayOpTests() : testCase() Assert.ifEqual(r.Length, 3); Assert.ifEqual(r[1], 2); - console.write("."); + Console.write("."); } public ByteArrayOpTests() : testCase() @@ -1845,7 +1882,7 @@ public ByteArrayOpTests() : testCase() Assert.ifEqual(r.Length, 3); Assert.ifEqual(r[1], 2); - console.write("."); + Console.write("."); } public ArrayAssignOperation() : testCase() @@ -1867,7 +1904,7 @@ public ArrayAssignOperation() : testCase() Assert.ifEqual(temp[2], 6); Assert.ifEqual(temp[3], 2); - console.write("."); + Console.write("."); } VT_B; @@ -1898,7 +1935,7 @@ public variadicTypecastingTests() : testCase() Assert.ifEqual(VT_E.loadAndTypecast(b,c), "system_tests'$private'VT_B,system_tests'$private'VT_B"); - console.write("."); + Console.write("."); } II_A; @@ -1928,7 +1965,7 @@ public interfaceImplTests() : testCase() var r := i.retrieve(); Assert.ifTrue(r is::II_A); - console.write("."); + Console.write("."); } interface IDecoratorA @@ -1981,7 +2018,7 @@ public decoratorTest() : testCase() Assert.ifEqual((decA as::IDecoratorA).giveMe(), 5); - console.write("."); + Console.write("."); } class ifNilOperatorHelper @@ -1999,10 +2036,10 @@ public ifNilOperatorTest() : testCase() var b := nil; Assert.ifEqual(a?.get(), 2); Assert.ifEqual(a?.Value, 3); - console.write("."); + Console.write("."); Assert.ifNil(b?.get()); Assert.ifNil(b?.Value); - console.write("."); + Console.write("."); } // --- enumTest --- @@ -2019,7 +2056,7 @@ public enumTest() : testCase() Assert.ifEqual(red.toPrintable(), "Red"); Assert.ifEqual(green.toPrintable(), "Green"); - console.write("."); + Console.write("."); } // --- passingNilArg --- @@ -2064,14 +2101,14 @@ singleton NilArgTester public passingNilArg() : testCase() { NilArgTester.runWeak(); - console.write("."); + Console.write("."); NilArgTester.runStrong(); - console.write("."); + Console.write("."); Assert.ifFailed({ NilArgTester.runWeak() }); - console.write("."); + Console.write("."); Assert.ifFailed({ NilArgTester.runStrong() }); - console.write("."); + Console.write("."); } public stringInterpolation() : testCase() @@ -2079,12 +2116,12 @@ public stringInterpolation() : testCase() var s := $"a_{ 1 }_b_{ 2 }_c"; Assert.ifEqual(s,"a_1_b_2_c"); - console.write("."); + Console.write("."); var s2 := $"{ 3 }_b_{ 4 }_c"; Assert.ifEqual(s2,"3_b_4_c"); - console.write("."); + Console.write("."); } // --- iteratorMethodTest --- @@ -2113,7 +2150,7 @@ public iteratorMethodTest() : testCase() Assert.ifTrue(e.next()); Assert.ifTrue(*e == 7); Assert.ifFalse(e.next()); - console.write("."); + Console.write("."); } public isNilOperatorTest() : testCase() @@ -2123,15 +2160,15 @@ public isNilOperatorTest() : testCase() var r := a ?? b; Assert.ifTrue(r == 2); - console.write("."); + Console.write("."); Assert.ifNotFailed({ var a := new A(); var b := nil; var r := a ?? b.test() }); Assert.ifFailed({ var a := nil; var b := nil; var r := a ?? b.test() }); - console.write("."); + Console.write("."); string s := nil; Assert.ifEqual(s ?? String.MinValue, EmptyString); - console.write("."); + Console.write("."); } namespace IndexedTest @@ -2175,7 +2212,7 @@ public indexedTests() : testCase() IndexedTest'A a := new IndexedTest'A(); Assert.ifEqual(a.foo(), "from A"); Assert.ifEqual(weak a.foo(), "from A"); - console.write("."); + Console.write("."); IndexedTest'A b := new IndexedTest'B(); Assert.ifEqual(b.foo(), "from B"); @@ -2184,7 +2221,7 @@ public indexedTests() : testCase() IndexedTest'A c := new IndexedTest'C(); Assert.ifEqual(c.foo(), "from A"); Assert.ifEqual(weak c.foo(), "from A"); - console.write("."); + Console.write("."); Assert.ifEqual(a.foo("Hello"), "from A with Hello"); Assert.ifEqual(weak a.foo("Hello2"), "from A with Hello2"); @@ -2192,7 +2229,7 @@ public indexedTests() : testCase() Assert.ifEqual(weak b.foo("Hello"), "from B with Hello"); Assert.ifEqual(c.foo("Hello2"), "from A with Hello2"); Assert.ifEqual(weak c.foo("Hello2"), "from A with Hello2"); - console.write("."); + Console.write("."); Assert.ifEqual(a.fooInternal("Hello"), "from A with hidden Hello"); Assert.ifEqual(b.fooInternal("Hello"), "from B with hidden Hello"); @@ -2201,7 +2238,7 @@ public indexedTests() : testCase() Assert.ifFailed({weak a.fooInternal("Hello")}); Assert.ifFailed({weak b.fooInternal("Hello")}); Assert.ifFailed({weak c.fooInternal("Hello")}); - console.write("."); + Console.write("."); } @@ -2227,7 +2264,7 @@ public sealedMethodDispatcher() : testCase() var c := new sealedMethodDispatcherTest'C(); Assert.ifNotFailed({ weak b.continueWith(c); }); - console.write("."); + Console.write("."); } public objectOpTests() : testCase() @@ -2237,7 +2274,7 @@ public objectOpTests() : testCase() string name := a.__getClassName(); Assert.ifEqual(name, "system_tests'$private'A"); - console.write("."); + Console.write("."); } namespace variadicBoxingTestset diff --git a/tests60/system_tests/main.l b/tests60/system_tests/main.l index 830a5cc753..965568fe79 100644 --- a/tests60/system_tests/main.l +++ b/tests60/system_tests/main.l @@ -2,9 +2,9 @@ import ltests; public program() { - console.writeLine("--- ELENA 6 API Functional Tests ---"); + Console.writeLine("--- ELENA 6 API Functional Tests ---"); Engine.run(); - console.writeLine("--- Passed ---") + Console.writeLine("--- Passed ---") } \ No newline at end of file From d37003d05842e4fcfdc3725c900ce206ac04ffd2 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Fri, 11 Apr 2025 11:33:50 +0200 Subject: [PATCH 35/53] Update README.md --- README.md | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bebda041e8..1f119a81a1 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ ELENA is a general-purpose language with late binding. It is multi-paradigm, com - Returning Multiple Values - Support of variadic methods - Support of yieldable methods + - Concurrent programming - Closures - Mixins - Type interfaces / conversions @@ -47,15 +48,16 @@ ELENA is a general-purpose language with late binding. It is multi-paradigm, com - **macOS** : arm64 (a64) -## Source Download and Compilation +## Installing ELENA from source To acquire the source code clone the git repository: git clone https://github.com/ELENA-LANG/elena-lang.git + cd elena-lang ### Windows: -The compiler code is implemented in C++ and does not require external dependencies. You just need Visual Studio 2019. +The compiler code is implemented in C++ and does not require external dependencies. You just need Visual Studio 2019 / 2022. You have to add a path to _BIN_ folder to the system environment *PATH* or copy elenavm.dll and elenart.dll to _Windows\System32_ folder. @@ -63,6 +65,115 @@ To build the compiler and API under VS2019 / VS2022 you have to go to the root f recompile60.bat +### Linux: + +To compile the code in Linux you have to install GCC tool set + + sudo apt-get install gcc-multilib g++-multilib + +Then you have to run the compilation: + +#### For x86 + +For Linux x86 (i386): + + make all_i386 + +After this you can either install it globally: + + cd scripts/i386 + sudo ./build_package_i386.script + +or locally + + cd scripts/i386 + sudo ./local_build_package_i386.script + +*Note : in this case you have to copy libelenart60.so into /usr/lib/elena or modify the configuration file bin/templates/lnx_console60.config and provide the correct path:* + + + + /usr/lib/elena/libelenart60.so

      system'net'
      -

      NetworkStream

      +

      INetSocket



      -public class NetworkStream
      +abstract public class INetSocket
      - -
        -
      • -

        Field Summary

        - - - - - - - - - - - - - - - - - -
        Modifier and TypeField
        - -Socket -_socket -
        - -BoolValue -_ownStream -
        - -system'ByteNumber[] -_buffer -
        -
      • +system'net'INetSocket
      - - @@ -466,26 +400,9 @@

      Property Summary

      -get  IntNumber - -Length() - - - - - -get  IntNumber - -Index() - - - - - -set   +get abstract  BoolValue
      -Index(IntNumber retVal) - +AvailableToRead() @@ -503,102 +420,9 @@

      Method Summary

      -IntNumber - -read(system'ByteNumber[] dump, IntNumber length) - - - - - - -IntNumber - -write(system'ByteNumber[] dump, IntNumber length) - - - - - - - - -close() - - - - - - -internal private  Task<system'IntNumber> - -readAsync(system'ByteNumber[] dump, IntNumber length) - - - - - - -internal private  Task<system'IntNumber> - -writeAsync(system'ByteNumber[] dump, IntNumber length) - - - - - - -internal private  BoolValue - -isDataAvailable() - - - - - - -internal private  Task<system'IntNumber> - -readAsync(MemoryBuffer buffer, IntNumber length) - - - - - - -internal private  Task - -writeAsync(String s) - - - - - - -internal private  Task<system'String> - -readAsStringAsync() - - - - -
    • -
    - -
    - +
    system'net'
    -

    SelectMode

    +

    INetSocketFactory



    -public class SelectMode
    +abstract public class INetSocketFactory
      @@ -673,25 +498,35 @@

      SelectMode

      • -system'net'SelectMode
      • +system'net'INetSocketFactory
    - +
    - +
    system'net'
    -

    SOCKADDR_IN

    +

    NativeSocket



    -public class SOCKADDR_IN
    +public class NativeSocket
      @@ -721,7 +556,7 @@

      SOCKADDR_IN

      • -system'net'SOCKADDR_IN
      • +system'net'NativeSocket
    @@ -737,53 +572,80 @@

    Field Summary

    -ShortNumber +Handle
    -family +_handle - - - -ShortNumber - -port - + + + + + - +
    • -

      Static Property Summary

      +

      Static Method Summary

      - + +NativeSocket + +
      Modifier and TypeStatic PropertyConstructor / Static Method
      -get  SOCKADDR_IN -Default() +connect(String host, ShortNumber port) + +
      +
    • +
    + +
      +
    • +

      Static Property Summary

      + + + + + + + +
      Modifier and TypeStatic Property
      + +get  NativeSocket +Default()
      @@ -801,44 +663,165 @@

      Property Summary

      -get  ShortNumber +get  BoolValue -Family() +isInvalid() + + + +
    • +
    + +
    - +
    system'net'
    -

    Socket

    +

    NativeSocketFactory



    -public class Socket
    +public class NativeSocketFactory
    +
    • -

      Field Summary

      +

      Constructor Summary

      - + +NativeSocketFactory
      Modifier and TypeFieldConstructor / Static Method
      -Handle -_handle +create() +
    - + - +
    +
    + + + +
    +
    +system'net'
    +

    NetSocket

    +
    +
    +
    +
    +
    +
    +public class NetSocket
    +
    +
    + + - + +
    +
    + + + +
    +
    +system'net'
    +

    NetworkStream

    +
    +
    +
    +
    +
    +
    +public class NetworkStream
    +
    +
    + + + + + + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get  IntNumber +Length() +
      + +get  IntNumber +Index() +
      + +set   +Index(IntNumber retVal) + +
      +
    • +
    + + + + +
    +
    + + + +
    +
    +system'net'
    +

    SelectMode

    +
    +
    +
    +
    +
    +
    +public class SelectMode
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + +
      Modifier and TypeField
      + +IntNumber +_value +
      +
    • +
    +
    +
    + + + +
    +
    +system'net'
    +

    SOCKADDR_IN

    +
    +
    +
    +
    +
    +
    +public class SOCKADDR_IN
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeField
      + +ShortNumber +family +
      + +ShortNumber +port +
      + +IN_ADDR +sin_addr +
      + -close() +sin_zero +
      +
    • +
    + +
      +
    • +

      Static Property Summary

      + + + + + + + + + +
      Modifier and TypeStatic Property
      + +get  SOCKADDR_IN +Default() +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get  ShortNumber +Family() +
      + +set   +Family(ShortNumber val) + +
      + +set   +Ip4_address(String ip) + +
      + +set   +Port(ShortNumber value)
      + +get  ShortNumber +Port() +
    diff --git a/doc/features b/doc/features index 85161915f8..3eb6df7b42 100644 --- a/doc/features +++ b/doc/features @@ -238,4 +238,40 @@ public program() Console.printLine("MyObject info:", o.getFullPackageInfo()); } - \ No newline at end of file +---------------------------------------------------------------------------- + Async program entry +---------------------------------------------------------------------------- + +import system'threading; +import extensions'threading; + +async public program() +{ + Task t1 := Task.run({ Console.printLineConcurrent("Enjoy") }); + Task t2 := Task.run({ Console.printLineConcurrent("Rosetta") }); + Task t3 := Task.run({ Console.printLineConcurrent("Code") }); + + :await Task.whenAllArgs(t1, t2, t3); +} + +---------------------------------------------------------------------------- + Evaluating a script without compilation +---------------------------------------------------------------------------- + +import extensions; +import extensions'scripting; + +public program() +{ + Console.print("Evaluating:"); + + var t := new ScriptEngine() + .loadScript("[[ #grammar build ]]") + .loadPath("~\scripts\grammar60.es") + .loadPath("~\scripts\lscript60.es"); + + var o := t.buildScript("import extensions; public program() { Console.printLine(""Hello "", ""World"") }"); + + o.eval(); +} + diff --git a/doc/tech/bytecode60.txt b/doc/tech/bytecode60.txt index b46eab4164..7e2ee28735 100644 --- a/doc/tech/bytecode60.txt +++ b/doc/tech/bytecode60.txt @@ -193,6 +193,9 @@ ELENA byte codes (or ecodes) has to immediately follow close opcode; has to be paired with attach opcode + dfree - sp -= index ; reserve and fill with zeros; + new sp value is aligned to 2 in x86-64 mode + free i - sp -= i ; release the stack; new sp value is aligned to 2 in x86-64 mode diff --git a/doc/todo.txt b/doc/todo.txt index f394edddc5..274a750777 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -5,56 +5,47 @@ In development: [development] ### EPIC: elena 6.7 ### - === Iteration 39 (18.4) === + === Iteration 40 (4.05) === -------------------------------------- dev: - - support fladd, flsub, fldiv, flmul (throu special prefix??) - - #34 : https get (Mbed TLS - https://github.com/Mbed-TLS/mbedtls/blob/development/programs/ssl/ssl_client1.c), - - MTA support for Linux - - #496 - - #622 - - #708 : compile the project (elc, og, sg, asm, ecv), create Linker - - unit tests for try-catch / try-catch-finally / try-finally - - upndown (connector - interaction) + - MTA support for Linux + - upndown (connector - interaction) + - support :sizeof + - #708 : compile the project (elc, og, sg, asm, ecv), compile library, compile executable, test executable + - #620 : backlog + - #34 : http client : support redirects, post, put, patch, delete, head, options, trace), web api + - MTA support for Linux (fix simple program - access to TLS) + - support fladd, flsub, fldiv, flmul (throu special prefix??) + - conditional compiling + - #622 : api backlog + - #731 gen: - - lpad / elt : declare an extension, parse it and apply to the input + - lpad / elt : declare an extension, parse it and apply to the input ide: - - ide : windows - - syntax highlighting - - #184 : linux - save, close, ... - - async method - auto watch : self and some variables are not displayed + - auto indent + - #184 : linux - open project, new project, save project, save all, close project ... + - syntax highlighting + - async method - auto watch : self and some variables are not displayed maint: - - github actions : `set-output` command is deprecated - - test all x86-64 examples - - unit tests : bt optimization - - arrange action for i386 / amd64 linux release + - remove old scripts from build folder + - optimization : pi (used classes byte code) + - test all x86-64 examples + - github actions : `set-output` command is deprecated + - API - review / description + - Actions : create a release archive api: - - implement ExtensionMessage.equal - - api : add descriptions - - api refactoring : main program entry to be called - Program - port: - - pi samples for aarch64 - - x86-64 : httpget, threading samples - - rosetta code : moving to 6.6 (test, use Console) - - x86-64 : mta - test net examples for mta - - test all x86-64 examples (net) + - api refactoring : main program entry to be called - Program tools: - - vs #2 : elena.tmLanguage.json - - #658 : connect with ldbg from VSCode : launch exe, implement built-in debugger - prom: bi-posting weekly - -------------------------------------- - -------------------------------------- - -------------------------------------- - - === Iteration 40 === - -------------------------------------- - dev: - - #34 : http client : support redirects, post, put, patch, delete, head, options, trace), web api - gen: - maint: + - #658 : debug elena program in VSCode : new thread event, loading source info, step over source + - vs #2 : elena.tmLanguage.json port: - - chat sample - prom: + - x86-64 : net, threading samples + - rosetta code : moving to 6.6 (test, use Console) + - chat sample + samples: + - rosetta code : Comma quibbling, Program termination, Parallel calculations + prom: + - bi-posting weekly -------------------------------------- -------------------------------------- -------------------------------------- @@ -66,7 +57,7 @@ In development: dev: gen: maint: - - review pi performance (must < 6) + - review pi performance (must < 6) : realOp.power[3] byte code port: prom: -------------------------------------- diff --git a/elenasrc3/common/common.h b/elenasrc3/common/common.h index c035292e05..1d7cf7fb4e 100644 --- a/elenasrc3/common/common.h +++ b/elenasrc3/common/common.h @@ -86,12 +86,12 @@ namespace elena_lang #endif - constexpr pos_t INVALID_POS = -1; - constexpr ref_t INVALID_REF = -1; + constexpr pos_t INVALID_POS = (pos_t)-1; + constexpr ref_t INVALID_REF = (ref_t)-1; constexpr ref_t MAX_OFFSET = 0x7FFFFFFF; constexpr ref_t MID_OFFSET = 0x3FFFFFFF; - constexpr addr_t INVALID_ADDR = -1; - constexpr size_t INVALID_SIZE = -1; + constexpr addr_t INVALID_ADDR = (addr_t)-1; + constexpr size_t INVALID_SIZE = (size_t)-1; } @@ -111,10 +111,10 @@ namespace elena_lang // --- ExceptionBase --- class ExceptionBase {}; - class AbortError : ExceptionBase {}; + class AbortError : public ExceptionBase {}; // --- InternalError --- - struct InternalError : ExceptionBase + struct InternalError : public ExceptionBase { int messageCode; int arg; diff --git a/elenasrc3/common/lists.h b/elenasrc3/common/lists.h index 28941c7851..e45ba3cf16 100644 --- a/elenasrc3/common/lists.h +++ b/elenasrc3/common/lists.h @@ -15,6 +15,11 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Waddress" +#elif _MSC_VER + +#pragma warning( push ) +#pragma warning( disable:4127 ) + #endif namespace elena_lang @@ -1761,7 +1766,7 @@ namespace elena_lang { if (_top) { pos_t currentOffset = _top; - pos_t previousOffset = -1; + pos_t previousOffset = INVALID_POS; while (currentOffset) { Item* current = (Item*)_buffer.get(currentOffset); @@ -2842,6 +2847,7 @@ namespace elena_lang CachedMemoryMapIterator() { this->_cachedMap = nullptr; + this->_index = 0; } }; friend class CachedMemoryMapIterator; @@ -3659,6 +3665,10 @@ DISABLE_WARNING_POP #pragma GCC diagnostic pop +#elif _MSC_VER + +#pragma warning( pop ) + #endif #endif diff --git a/elenasrc3/common/streams.h b/elenasrc3/common/streams.h index f5101adf4b..262ba641ee 100644 --- a/elenasrc3/common/streams.h +++ b/elenasrc3/common/streams.h @@ -309,6 +309,10 @@ namespace elena_lang { return write(&value, 2); } + bool writeShort(short value) + { + return write(&value, 2); + } bool writeByte(unsigned char value) { return write(&value, 1); diff --git a/elenasrc3/common/tree.h b/elenasrc3/common/tree.h index 3fa5479698..1a12f8ab8f 100644 --- a/elenasrc3/common/tree.h +++ b/elenasrc3/common/tree.h @@ -9,6 +9,13 @@ #ifndef TREE_H #define TREE_H +#ifdef _MSC_VER + +#pragma warning( push ) +#pragma warning( disable : 4458 ) + +#endif + namespace elena_lang { // --- Tree --- @@ -822,17 +829,23 @@ namespace elena_lang return counter; } - static void serialize(Node& node, void(*encoder)(TextWriter&, Key, ustr_t, int, void*), TextWriter& writer, void* arg) + static void serialize(int level, Node& node, void(*encoder)(int level, TextWriter&, Key, ustr_t, int, void*), TextWriter& writer, void* arg, List* filters) { - encoder(writer, node.key, node.identifier(), node.arg.value, arg); + encoder(level, writer, node.key, node.identifier(), node.arg.value, arg); Node current = node.firstChild(); while (current != defKey) { - serialize(current, encoder, writer, arg); + if (filters && filters->template retrieveIndex(current.key, [](Key arg, Key current) + { + return current == arg; + }) == -1) + { + serialize(level + 1, current, encoder, writer, arg, filters); + } current = current.nextNode(); } - encoder(writer, defKey, nullptr, 0, nullptr); + encoder(level, writer, defKey, nullptr, 0, nullptr); } static void deserialize(Node root, bool(*reader)(Key&, IdentifierString&, int&, void*), void* arg) @@ -856,4 +869,10 @@ namespace elena_lang }; } +#ifdef _MSC_VER + +#pragma warning( pop ) + +#endif + #endif diff --git a/elenasrc3/common/ustring.cpp b/elenasrc3/common/ustring.cpp index 2ea36635e4..234810513d 100644 --- a/elenasrc3/common/ustring.cpp +++ b/elenasrc3/common/ustring.cpp @@ -1067,7 +1067,7 @@ char* StrFactory :: reallocate(char* s, size_t size) #ifdef _MSC_VER -void StrUtil :: move(wchar_t* s1, const wchar_t* s2, size_t length) +void StrUtil :: move(wide_c* s1, const wide_c* s2, size_t length) { memmove(s1, s2, length << 1); } diff --git a/elenasrc3/common/ustring.h b/elenasrc3/common/ustring.h index db92390da8..060c69980e 100644 --- a/elenasrc3/common/ustring.h +++ b/elenasrc3/common/ustring.h @@ -415,6 +415,55 @@ namespace elena_lang return true; } + static bool ulongToStr(unsigned long long n, T* s, int radix, size_t maxLength) + { + unsigned long long rem = 0; + size_t pos = 0; + size_t start = 0; + + do + { + if (pos >= maxLength) + return false; + + rem = n % radix; + n /= radix; + switch (rem) { + case 10: + s[pos++] = 'a'; + break; + case 11: + s[pos++] = 'b'; + break; + case 12: + s[pos++] = 'c'; + break; + case 13: + s[pos++] = 'd'; + break; + case 14: + s[pos++] = 'e'; + break; + case 15: + s[pos++] = 'f'; + break; + default: + if (rem < 10) { + s[pos++] = (T)(rem + 0x30); + } + } + } while (n != 0); + + s[pos] = 0; + pos--; + while (start < pos) { + T tmp = s[start]; + s[start++] = s[pos]; + s[pos--] = tmp; + } + + return true; + } void appendHex(int n) { @@ -425,6 +474,15 @@ namespace elena_lang StrUtil::upper(_string + pos); } + void appendLongHex(long long n) + { + size_t pos = getlength(_string); + + ulongToStr(n, _string + pos, 16, size - pos); + + StrUtil::upper(_string + pos); + } + void appendDouble(double value) { size_t pos = getlength(_string); @@ -556,7 +614,7 @@ namespace elena_lang return StrConvertor::toInt(_string, radix); } - int toUInt(int radix = 10) const + unsigned int toUInt(int radix = 10) const { return StrConvertor::toUInt(_string, radix); } diff --git a/elenasrc3/common/vs/lcommon.vcxproj b/elenasrc3/common/vs/lcommon.vcxproj new file mode 100644 index 0000000000..68732e197a --- /dev/null +++ b/elenasrc3/common/vs/lcommon.vcxproj @@ -0,0 +1,188 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF} + lcommon + 10.0 + + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + ..\..\..\bin\ + + + ..\..\..\bin\ + + + ..\..\..\bin\ + + + ..\..\..\bin\ + + + $(ProjectName)64 + + + $(ProjectName)64 + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + true + + ..;%(AdditionalIncludeDirectories) + + + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + true + + ..;%(AdditionalIncludeDirectories) + + + + + true + true + true + + + + + Level3 + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + true + + ..;%(AdditionalIncludeDirectories) + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + ..;%(AdditionalIncludeDirectories) + + true + + + + + true + true + true + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + \ No newline at end of file diff --git a/elenasrc3/elc/clicommon.h b/elenasrc3/elc/clicommon.h index 72f9c5cd15..e652625247 100644 --- a/elenasrc3/elc/clicommon.h +++ b/elenasrc3/elc/clicommon.h @@ -266,6 +266,7 @@ struct SizeInfo { int size; bool readOnly; + bool numeric; }; // --- ExternalType --- @@ -304,7 +305,6 @@ class ModuleScopeBase : public SectionScopeBase int ptrSize; bool tapeOptMode; - bool reusingTemplates; Map cachedSizes; Map cachedClassReferences; @@ -431,6 +431,7 @@ enum class ExpressionAttribute : pos64_t Class = 0x000100000000, Nillable = 0x000200000000, AllowGenericSignature= 0x000400000000, + AsyncOp = 0x000800000000, OutRefOp = 0x001000000000, WithVariadicArgCast = 0x002008000000, DistributedForward = 0x004000000000, @@ -788,7 +789,8 @@ enum class VirtualType : int None = 0, Multimethod, ByRefHandler, - AbstractByRefHandler + AbstractByRefHandler, + AsyncInvoker }; struct VirtualMethod diff --git a/elenasrc3/elc/cliconst.h b/elenasrc3/elc/cliconst.h index 699fe8f92a..9c467021cf 100644 --- a/elenasrc3/elc/cliconst.h +++ b/elenasrc3/elc/cliconst.h @@ -13,7 +13,7 @@ namespace elena_lang { - #define ELC_REVISION_NUMBER 0x00A0 + #define ELC_REVISION_NUMBER 0x00B0 #if defined _M_IX86 || _M_X64 @@ -45,18 +45,20 @@ namespace elena_lang constexpr auto ELC_COMPILING_TEMPLATE = "\nCompiling %s"; constexpr auto ELC_SAVING_MODULE = "\nsaving %s\n"; + constexpr auto ELC_MODULE_TARGET_PATH = "\ntarget path is %s\n"; constexpr auto ELC_COMPILING_PROJECT = "\nCompiling Project %s\n\n"; constexpr auto ELC_PROFILE_WARNING = "\nWARNING - Please select one of available profiles:%s\n"; constexpr auto ELC_PRJ_COLLECTION_WARNING = "\nWARNING - The project collection must be the last argument:%s\n"; - constexpr auto ELC_HELP_INFO = "elena-cli {-key} {source-file+ | project-file}\nkeys:\n -el{5 | 6} - specifying grammar compatibility\n -f{fwd=reference} - add a forward\n -l{profile name} - selecct a profile\n -m - turning on address mapping output\n -o{0 | 1 | 2} - set the optimization level\n -p - set the base path\n -r - clean the compilation output\n -s{ stackReserv:n } - set the linker option - stack reserved\n -t{ template name } - load the project template\n -v - turn on a verbose output mode\n - w{ 0 | 1 | 2 | 3 } - set the minimal warnings level to X = { 0 | 1 | 2 | 3 }\n -xb[-] - turn on / off a conditional boxing\n -xe[-] - turn on / off a compile-time expression evaluation\n -xj[-] - turn on / off jump alignment\n -xm[-] - turn on / off auto loading module extension list\n -xp[-] - turn on / off generation of the parameter meta info\n -xs[-] - turn on / off strict type enforcing"; + constexpr auto ELC_HELP_INFO = "elena-cli {-key} {source-file+ | project-file}\nkeys:\n -el{5 | 6} - specifying grammar compatibility\n -f{fwd=reference} - add a forward\n -l{profile name} - select a profile\n -m - turning on address mapping output\n -o{0 | 1 | 2} - set the optimization level\n -p - set the base path\n -r - clean the compilation output\n -s{ stackReserv:n } - set the linker option - stack reserved\n -t{ template name } - load the project template\n -v - turn on a verbose output mode\n - w{ 0 | 1 | 2 | 3 } - set the minimal warnings level to X = { 0 | 1 | 2 | 3 }\n -xb[-] - turn on / off a conditional boxing\n -xe[-] - turn on / off a compile-time expression evaluation\n -xj[-] - turn on / off jump alignment\n -xm[-] - turn on / off auto loading module extension list\n -xp[-] - turn on / off generation of the parameter meta info\n -xs[-] - turn on / off strict type enforcing"; constexpr auto SYNTAX50_FILE = "syntax50.dat"; constexpr auto SYNTAX60_FILE = "syntax60.dat"; constexpr auto BC_RULES_FILE = "bc_rules60.dat"; constexpr auto BT_RULES_FILE = "bt_rules60.dat"; + constexpr auto BT_XRULES_FILE = "bt_xrules60.dat"; constexpr auto VA_ALIGNMENT = 0x08; diff --git a/elenasrc3/elc/codeblocks/elc_amd64.mak b/elenasrc3/elc/codeblocks/elc_amd64.mak index c0654f50ba..4d97991f52 100644 --- a/elenasrc3/elc/codeblocks/elc_amd64.mak +++ b/elenasrc3/elc/codeblocks/elc_amd64.mak @@ -28,7 +28,7 @@ OBJDIR_RELEASE = ../../temp/elena64-cli DEP_RELEASE = OUT_RELEASE = ../../../bin/elena64-cli -OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker32.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker32.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o $(OBJDIR_RELEASE)/__/__/engine/serializer.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o all: release @@ -109,6 +109,12 @@ $(OBJDIR_RELEASE)/__/__/engine/bytecode.o: ../../engine/bytecode.cpp $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o: ../../engine/xmlprojectbase.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/xmlprojectbase.cpp -o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o +$(OBJDIR_RELEASE)/__/__/engine/serializer.o: ../../engine/serializer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/serializer.cpp -o $(OBJDIR_RELEASE)/__/__/engine/serializer.o + +$(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o: ../../engine/linux/presenter.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/presenter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o diff --git a/elenasrc3/elc/codeblocks/elc_arm64.mak b/elenasrc3/elc/codeblocks/elc_arm64.mak index 75d0e8200d..86b9b296c4 100644 --- a/elenasrc3/elc/codeblocks/elc_arm64.mak +++ b/elenasrc3/elc/codeblocks/elc_arm64.mak @@ -28,7 +28,7 @@ OBJDIR_RELEASE = ../../temp/elena64-cli DEP_RELEASE = OUT_RELEASE = ../../../bin/elena64-cli -OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/arm64compiler.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elfarmimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/linux/elfarmlinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/arm64compiler.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elfarmimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/linux/elfarmlinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o $(OBJDIR_RELEASE)/__/__/engine/serializer.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o all: release @@ -103,6 +103,12 @@ $(OBJDIR_RELEASE)/__/__/engine/bytecode.o: ../../engine/bytecode.cpp $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o: ../../engine/xmlprojectbase.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/xmlprojectbase.cpp -o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o +$(OBJDIR_RELEASE)/__/__/engine/serializer.o: ../../engine/serializer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/serializer.cpp -o $(OBJDIR_RELEASE)/__/__/engine/serializer.o + +$(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o: ../../engine/linux/presenter.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/presenter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o diff --git a/elenasrc3/elc/codeblocks/elc_i386.mak b/elenasrc3/elc/codeblocks/elc_i386.mak index 7fc4d678d6..e6b3b8fb5b 100644 --- a/elenasrc3/elc/codeblocks/elc_i386.mak +++ b/elenasrc3/elc/codeblocks/elc_i386.mak @@ -28,7 +28,7 @@ OBJDIR_RELEASE = ../../temp/elena-cli DEP_RELEASE = OUT_RELEASE = ../../../bin/elena-cli -OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker32.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker32.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o $(OBJDIR_RELEASE)/__/__/engine/serializer.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o all: release @@ -112,6 +112,12 @@ $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o: ../../engine/xmlprojectbase.cpp $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o: ../../engine/linux/presenter.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/presenter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o +$(OBJDIR_RELEASE)/__/__/engine/serializer.o: ../../engine/serializer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/serializer.cpp -o $(OBJDIR_RELEASE)/__/__/engine/serializer.o + +$(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + $(OBJDIR_RELEASE)/__/codeimage.o: ../codeimage.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../codeimage.cpp -o $(OBJDIR_RELEASE)/__/codeimage.o diff --git a/elenasrc3/elc/codeblocks/elc_linux_x86.cbp b/elenasrc3/elc/codeblocks/elc_linux_x86.cbp index 45935abd1a..d2d99df926 100644 --- a/elenasrc3/elc/codeblocks/elc_linux_x86.cbp +++ b/elenasrc3/elc/codeblocks/elc_linux_x86.cbp @@ -108,8 +108,12 @@ + + + + diff --git a/elenasrc3/elc/codeblocks/elc_mac_arm64.mak b/elenasrc3/elc/codeblocks/elc_mac_arm64.mak index 890e1c7ff6..b8230b2dd0 100644 --- a/elenasrc3/elc/codeblocks/elc_mac_arm64.mak +++ b/elenasrc3/elc/codeblocks/elc_mac_arm64.mak @@ -28,7 +28,7 @@ OBJDIR_RELEASE = ../../temp/elena64-cli DEP_RELEASE = OUT_RELEASE = ../../../bin/elena64-cli -OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/arm64compiler.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/macos/elc.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/arm64compiler.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/macos/elc.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/__/engine/serializer.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o all: release @@ -103,6 +103,12 @@ $(OBJDIR_RELEASE)/__/__/engine/bytecode.o: ../../engine/bytecode.cpp $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o: ../../engine/xmlprojectbase.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/xmlprojectbase.cpp -o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o +$(OBJDIR_RELEASE)/__/__/engine/serializer.o: ../../engine/serializer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/serializer.cpp -o $(OBJDIR_RELEASE)/__/__/engine/serializer.o + +$(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + $(OBJDIR_RELEASE)/__/codeimage.o: ../codeimage.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../codeimage.cpp -o $(OBJDIR_RELEASE)/__/codeimage.o diff --git a/elenasrc3/elc/codeblocks/elc_ppc64le.mak b/elenasrc3/elc/codeblocks/elc_ppc64le.mak index 1c8cbb0918..919af108fe 100644 --- a/elenasrc3/elc/codeblocks/elc_ppc64le.mak +++ b/elenasrc3/elc/codeblocks/elc_ppc64le.mak @@ -28,7 +28,7 @@ OBJDIR_RELEASE = ../../temp/elena64-cli DEP_RELEASE = OUT_RELEASE = ../../../bin/elena64-cli -OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/ppc64compiler.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elfppcimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/linux/elfppclinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/ppc64compiler.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elfppcimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/linux/elfppclinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o $(OBJDIR_RELEASE)/__/__/engine/serializer.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o all: release @@ -100,6 +100,12 @@ $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o: ../../engine/syntaxtree.cpp $(OBJDIR_RELEASE)/__/__/engine/bytecode.o: ../../engine/bytecode.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o +$(OBJDIR_RELEASE)/__/__/engine/serializer.o: ../../engine/serializer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/serializer.cpp -o $(OBJDIR_RELEASE)/__/__/engine/serializer.o + +$(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o: ../../engine/linux/presenter.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/presenter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o diff --git a/elenasrc3/elc/codeimage.cpp b/elenasrc3/elc/codeimage.cpp index 819aea189c..1a2ba89886 100644 --- a/elenasrc3/elc/codeimage.cpp +++ b/elenasrc3/elc/codeimage.cpp @@ -23,14 +23,14 @@ AddressMap::Iterator TargetImage :: externals() } TargetImage :: TargetImage(PlatformType systemTarget, ForwardResolverBase* resolver, LibraryLoaderBase* loader, - JITCompilerBase* (*jitCompilerFactory)(LibraryLoaderBase*, PlatformType), + JITCompilerBase* (*jitCompilerFactory)(PlatformType), TargetImageInfo imageInfo, AddressMapperBase* addressMapper) { _systemTarget = systemTarget; _tlsVariable = INVALID_ADDR; _stackReserved = imageInfo.coreSettings.stackReserved; - JITCompilerBase* compiler = jitCompilerFactory(loader, imageInfo.type); + JITCompilerBase* compiler = jitCompilerFactory(imageInfo.type); JITLinkerSettings settings = { diff --git a/elenasrc3/elc/codeimage.h b/elenasrc3/elc/codeimage.h index a045cfcee7..b57f0a1500 100644 --- a/elenasrc3/elc/codeimage.h +++ b/elenasrc3/elc/codeimage.h @@ -74,7 +74,7 @@ namespace elena_lang void generateAutoSymbol(ModuleBase* module, MemoryDump& tapeSymbol, bool withExtFrame); TargetImage(PlatformType systemTarget, ForwardResolverBase* resolver, LibraryLoaderBase* loader, - JITCompilerBase* (*jitCompilerFactory)(LibraryLoaderBase*, PlatformType), + JITCompilerBase* (*jitCompilerFactory)(PlatformType), TargetImageInfo imageInfo, AddressMapperBase* addressMapper); }; } diff --git a/elenasrc3/elc/compiler.cpp b/elenasrc3/elc/compiler.cpp index 0bef008dde..469c281217 100644 --- a/elenasrc3/elc/compiler.cpp +++ b/elenasrc3/elc/compiler.cpp @@ -15,12 +15,6 @@ #include "bytecode.h" -#ifdef FULL_OUTOUT_INFO - -#include "serializer.h" - -#endif - using namespace elena_lang; typedef ExpressionAttribute EAttr; @@ -68,26 +62,6 @@ MethodHint operator | (const ref_t& l, const MethodHint& r) // } //} -#ifdef FULL_OUTOUT_INFO - -inline void printTree(PresenterBase* presenter, SyntaxNode node) -{ - DynamicUStr target; - - SyntaxTreeSerializer::save(node, target); - - presenter->print(target.str()); -} - -#endif // FULL_OUTOUT_INFO - -//inline void storeNode(BuildNode node) -//{ -// DynamicUStr target; -// -// BuildTreeSerializer::save(node, target); -//} - inline bool isSelfCall(ObjectInfo target) { switch (target.kind) { @@ -306,8 +280,6 @@ inline bool isSingleObject(ObjectKind kind) default: return isConstant(kind); } - - return false; } inline bool areConstants(ArgumentsInfo& args) @@ -2666,6 +2638,19 @@ inline TypeInfo retrieveTypeInfo(SyntaxNode node) return { reference, 0, attributes == V_NILLABLE }; } +mssg_t Compiler :: overwriteAsAsyncFunction(Scope& scope, mssg_t weakMessage) +{ + pos_t argCount = 0; + ref_t dummyRef, flags = 0; + decodeMessage(weakMessage, dummyRef, argCount, flags); + ref_t signRef = 0; + scope.module->resolveAction(dummyRef, signRef); + + ref_t actionRef = scope.module->mapAction(ASYNC_INVOKE_MESSAGE, signRef, false); + + return encodeMessage(actionRef, argCount, flags); +} + void Compiler::addTypeInfo(Scope& scope, SyntaxNode node, SyntaxKey key, TypeInfo typeInfo) { SyntaxNode info = node.appendChild(key); @@ -3019,10 +3004,13 @@ void Compiler :: declareVirtualMethods(SyntaxNode classNode, SyntaxKey methodTyp auto methodInfo = *it; switch (methodInfo.type) { case VirtualType::ByRefHandler: - declareByRefHandler(classNode, methodType, targetRef, info, methodInfo.message, false); + declareByRefHandler(info, methodInfo.message, false); break; case VirtualType::AbstractByRefHandler: - declareByRefHandler(classNode, methodType, targetRef, info, methodInfo.message, true); + declareByRefHandler(info, methodInfo.message, true); + break; + case VirtualType::AsyncInvoker: + declareAsyncInvoker(info, methodInfo.message); break; default: break; @@ -3030,19 +3018,16 @@ void Compiler :: declareVirtualMethods(SyntaxNode classNode, SyntaxKey methodTyp } } -void Compiler :: declareByRefHandler(SyntaxNode classNode, SyntaxKey methodType, - ref_t targetRef, ClassInfo& info, mssg_t message, bool abstractOne) +void Compiler :: declareInvoker(ClassInfo& info, mssg_t targetMssg, MethodInfo& methodInfo, bool abstractOne, ref_t newHints) { - MethodInfo methodInfo = info.methods.get(message); - - assert(methodInfo.byRefHandler != 0); - MethodInfo handlerInfo = {}; - auto m_it = info.methods.getIt(methodInfo.byRefHandler); + auto m_it = info.methods.getIt(targetMssg); bool found = !m_it.eof(); if (found) handlerInfo = *m_it; + handlerInfo.hints |= newHints; + handlerInfo.hints &= ~(ref_t)MethodHint::Mask; handlerInfo.hints |= (ref_t)MethodHint::Autogenerated; if (MethodInfo::checkVisibility(methodInfo, MethodHint::Private)) { @@ -3070,10 +3055,27 @@ void Compiler :: declareByRefHandler(SyntaxNode classNode, SyntaxKey methodType, handlerInfo.hints |= (ref_t)MethodHint::Stacksafe; if (found) { - auto it = info.methods.getIt(methodInfo.byRefHandler); + auto it = info.methods.getIt(targetMssg); (*it).hints = handlerInfo.hints; } - else info.methods.add(methodInfo.byRefHandler, handlerInfo); + else info.methods.add(targetMssg, handlerInfo); +} + +void Compiler :: declareByRefHandler(ClassInfo& info, mssg_t message, bool abstractOne) +{ + MethodInfo methodInfo = info.methods.get(message); + + assert(methodInfo.byRefHandler != 0); + + declareInvoker(info, methodInfo.byRefHandler, methodInfo, abstractOne, 0); +} + +void Compiler :: declareAsyncInvoker(ClassInfo& info, mssg_t asyncFunction) +{ + MethodInfo methodInfo = {}; + methodInfo.hints |= (ref_t)MethodHint::Async; + + declareInvoker(info, asyncFunction, methodInfo, false, (ref_t)MethodHint::Async); } mssg_t Compiler :: defineOutRefMethod(ClassScope& scope, SyntaxNode node, bool isExtension) @@ -3196,6 +3198,24 @@ void Compiler :: generateMethodDeclarations(ClassScope& scope, SyntaxNode node, } } } + if (test(hints, (ref_t)MethodHint::Async) && test(current.arg.reference, FUNCTION_MESSAGE) + && current.findChild(SyntaxKey::Target).arg.reference == 0) + { + // if it is an generic async function - generate invoker + mssg_t invoker = overwriteAsAsyncFunction(scope, current.arg.reference); + + current.appendChild(SyntaxKey::AsyncInvoker, invoker); + + implicitMultimethods.add({ invoker, VirtualType::AsyncInvoker, 0 }); + + // remove the initial async attribute + SyntaxNode hintNode = current.findChild(SyntaxKey::Hints); + if (hintNode != SyntaxKey::None) { + hintNode.setArgumentReference(hintNode.arg.reference & ~(ref_t)MethodHint::Async); + } + + ref_t hints = current.findChild(SyntaxKey::Hints).arg.value; + } } current = current.nextNode(); } @@ -3229,7 +3249,7 @@ void Compiler :: generateMethodDeclarations(ClassScope& scope, SyntaxNode node, } } - //COMPILER MAGIC : if byref handler is declared - the compiler must declare the virtual multi method + //COMPILER MAGIC : if byref handler / async invoker is declared - the compiler must declare the virtual multi method if (implicitMultimethods.count() > 0) { declareVirtualMethods(node, methodKey, scope, scope.reference, scope.info, implicitMultimethods); } @@ -3252,6 +3272,12 @@ void Compiler::generateClassDeclaration(ClassScope& scope, SyntaxNode node, ref_ // generate fields generateClassFields(scope, node, SyntaxTree::countChild(node, SyntaxKey::Field) == 1); + + if (test(declaredFlags, elTemplatebased)) { + ref_t templateRef = node.findChild(SyntaxKey::SourceRef).arg.reference; + if (templateRef) + scope.addAttribute(ClassAttribute::SourceTemplateRef, templateRef); + } } injectVirtualCode(node, scope, closed); @@ -3458,7 +3484,11 @@ bool Compiler::generateClassField(ClassScope& scope, FieldAttributes& attrs, ust // padding if (!test(flags, elPacked)) { - scope.info.size += _logic->definePadding(*scope.moduleScope, scope.info.size, sizeInfo.size); + if (sizeInfo.size == 8 && !sizeInfo.numeric) { + // HOTFIX : align the complex structure as 4/8 alignment (depending on the platform) + scope.info.size += _logic->definePadding(*scope.moduleScope, scope.info.size, scope.moduleScope->ptrSize); + } + else scope.info.size += _logic->definePadding(*scope.moduleScope, scope.info.size, attrs.fieldArray ? sizeInfo.size / attrs.size : sizeInfo.size); } offset = scope.info.size; @@ -3971,9 +4001,12 @@ void Compiler :: declareVMTMessage(MethodScope& scope, SyntaxNode node, bool wit unnamedMessage = false; flags |= FUNCTION_MESSAGE; - if (MethodInfo::checkVisibility(scope.info, MethodHint::Internal)) + if (MethodInfo::checkVisibility(scope.info, MethodHint::Internal)) { + if (_verbose) { + _errorProcessor->info(infoInternalDefConstructor, *actionStr); + } scope.raiseError(errIllegalConstructor, node); - + } } else if (scope.checkHint(MethodHint::Generic) && scope.checkHint(MethodHint::Generic)) { if (signatureLen > 0 || !unnamedMessage || scope.checkHint(MethodHint::Function)) @@ -5186,11 +5219,6 @@ void Compiler::declareTemplate(TemplateScope& scope, SyntaxNode& node) saveTemplate(scope, node); -#ifdef FULL_OUTOUT_INFO - _presenter->print("\nSyntax tree:\n"); - printTree(_presenter, node); -#endif - node.setKey(SyntaxKey::Idle); } @@ -7575,32 +7603,32 @@ bool Compiler::compileSymbolConstant(SymbolScope& scope, ObjectInfo retVal) ref_t constRef = generateConstant(scope, retVal, scope.reference, false); if (constRef) { switch (retVal.kind) { - case ObjectKind::Singleton: - scope.info.symbolType = SymbolType::Singleton; - scope.info.valueRef = retVal.reference; + case ObjectKind::Singleton: + scope.info.symbolType = SymbolType::Singleton; + scope.info.valueRef = retVal.reference; - break; - case ObjectKind::StringLiteral: - case ObjectKind::WideStringLiteral: - case ObjectKind::Float64Literal: - scope.info.symbolType = SymbolType::Constant; - scope.info.valueRef = constRef; - break; - case ObjectKind::IntLiteral: - scope.info.symbolType = SymbolType::Constant; - scope.info.valueRef = constRef; - break; - case ObjectKind::Constant: - scope.info.symbolType = SymbolType::Constant; - scope.info.valueRef = retVal.reference; - break; - case ObjectKind::ConstArray: - scope.info.symbolType = SymbolType::ConstantArray; - scope.info.valueRef = retVal.reference; - break; - default: - assert(false); - break; + break; + case ObjectKind::StringLiteral: + case ObjectKind::WideStringLiteral: + case ObjectKind::Float64Literal: + scope.info.symbolType = SymbolType::Constant; + scope.info.valueRef = constRef; + break; + case ObjectKind::IntLiteral: + scope.info.symbolType = SymbolType::Constant; + scope.info.valueRef = constRef; + break; + case ObjectKind::Constant: + scope.info.symbolType = SymbolType::Constant; + scope.info.valueRef = retVal.reference; + break; + case ObjectKind::ConstArray: + scope.info.symbolType = SymbolType::ConstantArray; + scope.info.valueRef = retVal.reference; + break; + default: + assert(false); + break; } scope.info.typeRef = resolveStrongType(scope, retVal.typeInfo); @@ -7749,70 +7777,70 @@ void Compiler :: addVariableInfo(BuildNode node, Scope& scope, ustr_t name, Para { V_INT8 }, { localInfo.typeInfo.elementRef }, false)) { BuildNode varNode = node.appendChild(BuildKey::ByteArrayAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (_logic->isCompatible(*moduleScope, { V_UINT8 }, { localInfo.typeInfo.elementRef }, false)) { BuildNode varNode = node.appendChild(BuildKey::ByteArrayAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (_logic->isCompatible(*moduleScope, { V_INT16 }, { localInfo.typeInfo.elementRef }, false)) { BuildNode varNode = node.appendChild(BuildKey::ShortArrayAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (_logic->isCompatible(*moduleScope, { V_INT32 }, { localInfo.typeInfo.elementRef }, false)) { BuildNode varNode = node.appendChild(BuildKey::IntArrayAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } } else if (localInfo.typeInfo.typeRef == moduleScope->buildins.intReference) { BuildNode varNode = node.appendChild(BuildKey::IntVariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (localInfo.typeInfo.typeRef == moduleScope->buildins.uintReference) { BuildNode varNode = node.appendChild(BuildKey::UIntVariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (localInfo.typeInfo.typeRef == moduleScope->buildins.int8Reference) { BuildNode varNode = node.appendChild(BuildKey::IntVariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (localInfo.typeInfo.typeRef == moduleScope->buildins.uint8Reference) { BuildNode varNode = node.appendChild(BuildKey::IntVariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (localInfo.typeInfo.typeRef == moduleScope->buildins.shortReference) { BuildNode varNode = node.appendChild(BuildKey::IntVariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (localInfo.typeInfo.typeRef == moduleScope->buildins.longReference) { BuildNode varNode = node.appendChild(BuildKey::LongVariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (localInfo.typeInfo.typeRef == moduleScope->buildins.realReference) { BuildNode varNode = node.appendChild(BuildKey::RealVariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (_logic->isCompatible(*moduleScope, { V_INT32 }, { localInfo.typeInfo.typeRef }, false)) { BuildNode varNode = node.appendChild(BuildKey::IntVariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else if (_logic->isCompatible(*moduleScope, { V_INT64 }, { localInfo.typeInfo.typeRef }, false)) { BuildNode varNode = node.appendChild(BuildKey::LongVariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } else { BuildNode varNode = node.appendChild(BuildKey::VariableAddress, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); ustr_t className = moduleScope->module->resolveReference(localInfo.typeInfo.typeRef); if (isWeakReference(className)) { @@ -7826,7 +7854,7 @@ void Compiler :: addVariableInfo(BuildNode node, Scope& scope, ustr_t name, Para } else { BuildNode varNode = node.appendChild(BuildKey::Variable, name); - varNode.appendChild(BuildKey::Index, localInfo.offset); + varNode.appendChild(BuildKey::StackIndex, localInfo.offset); } } @@ -8651,6 +8679,47 @@ void Compiler::compileByRefHandlerInvoker(BuildTreeWriter& writer, MethodScope& writer.appendNode(BuildKey::CloseFrame); } +void Compiler :: compileAsyncInvoker(BuildTreeWriter& writer, MethodScope& methodScope, CodeScope& codeScope, mssg_t asyncFunction) +{ + writer.appendNode(BuildKey::OpenFrame); + + // stack should contains current self reference + // the original message should be restored if it is a generic method + methodScope.selfLocal = codeScope.newLocal(); + writer.appendNode(BuildKey::Assigning, methodScope.selfLocal); + + // calling the byref handler + Expression expression(this, codeScope, writer); + ArgumentsInfo arguments; + + ObjectInfo target = methodScope.mapSelf(); + MessageCallContext context = { asyncFunction, 0 }; + MessageResolution resolution = { true, asyncFunction }; + + for (auto it = methodScope.parameters.start(); !it.eof(); ++it) { + arguments.add(methodScope.mapParameter(it.key(), EAttr::None)); + } + + context.implicitSignatureRef = getSignature(codeScope.module, asyncFunction); + _logic->setSignatureStacksafe(*codeScope.moduleScope, context.implicitSignatureRef, resolution.stackSafeAttr); + + ObjectInfo retVal = expression.compileMessageCall({}, target, context, resolution, + arguments, EAttr::AllowPrivateCall, nullptr); + + mssg_t resultMessage = encodeMessage(codeScope.module->mapAction(RESULT_MESSAGE, 0, false), + 1, PROPERTY_MESSAGE); + + arguments.clear(); + arguments.add(retVal); + context = { resultMessage, 0 }; + expression.compileMessageCall({}, retVal, context, resultMessage, + arguments, EAttr::None, nullptr); + + expression.scope.syncStack(); + + writer.appendNode(BuildKey::CloseFrame); +} + void Compiler::writeMessageInfo(BuildTreeWriter& writer, MethodScope& scope) { IdentifierString methodName; @@ -8706,7 +8775,7 @@ void Compiler :: writeParameterDebugInfo(BuildTreeWriter& writer, Scope& scope, } else writer.newNode(BuildKey::Parameter, name); - writer.appendNode(BuildKey::Index, index); + writer.appendNode(BuildKey::StackIndex, index); writer.closeNode(); } @@ -8744,26 +8813,44 @@ void Compiler::writeMethodDebugInfo(BuildTreeWriter& writer, MethodScope& scope) writer.closeNode(); } -void Compiler::compileMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node) +void Compiler :: compileMethodInvoker(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node) { - ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class); - - SyntaxNode current = node.firstChild(SyntaxKey::MemberMask); - CodeScope codeScope(&scope); - if (scope.info.byRefHandler && !scope.checkHint(MethodHint::InterfaceDispatcher)) { + if (scope.info.byRefHandler) { compileByRefHandler(writer, scope, node, scope.info.byRefHandler); beginMethod(writer, scope, node, BuildKey::Method, false); compileByRefHandlerInvoker(writer, scope, codeScope, scope.info.byRefHandler, scope.info.outputRef); codeScope.syncStack(&scope); endMethod(writer, scope); + } + else if (node.existChild(SyntaxKey::AsyncInvoker)) { + mssg_t asyncFunction = node.findChild(SyntaxKey::AsyncInvoker).arg.reference; + ref_t outputRef = scope.info.outputRef; - // NOTE : normal byrefhandler has an alternative implementation - // overriding the normal routine - return; + mssg_t functionInvoker = scope.message; + scope.message = asyncFunction; + scope.info.outputRef = scope.moduleScope->buildins.taskReference; + compileAsyncMethod(writer, scope, node); + scope.message = functionInvoker; + scope.info.outputRef = outputRef; + + beginMethod(writer, scope, node, BuildKey::Method, false); + compileAsyncInvoker(writer, scope, codeScope, asyncFunction); + codeScope.syncStack(&scope); + endMethod(writer, scope); } + else assert(false); // should never reach this point +} + +void Compiler::compileMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node) +{ + ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class); + + SyntaxNode current = node.firstChild(SyntaxKey::MemberMask); + + CodeScope codeScope(&scope); beginMethod(writer, scope, node, BuildKey::Method, _withDebugInfo); @@ -9237,7 +9324,7 @@ void Compiler::compileConstructor(BuildTreeWriter& writer, MethodScope& scope, // NOTE : the named constructor should be polymorphic, depending on the message target writer.appendNode(BuildKey::Local, -1); writer.newNode(BuildKey::CallOp, defConstrMssg); - writer.appendNode(BuildKey::Index, 1); // built-in constructor entry should be the second entry in VMT + writer.appendNode(BuildKey::VMTIndex, 1); // built-in constructor entry should be the second entry in VMT writer.closeNode(); } } @@ -9487,7 +9574,7 @@ void Compiler::compileDispatcherMethod(BuildTreeWriter& writer, MethodScope& sco // change incoming message to variadic multi-method writer.newNode(BuildKey::LoadingSubject, encodeMessage(getAction(scope.moduleScope->buildins.dispatch_message), argCount, mask)); - writer.appendNode(BuildKey::Index, scope.messageLocalAddress); + writer.appendNode(BuildKey::StackAddress, scope.messageLocalAddress); if (mixedDispatcher) writer.appendNode(BuildKey::Special, -1); writer.closeNode(); @@ -9700,24 +9787,9 @@ void Compiler :: compileClassVMT(BuildTreeWriter& writer, ClassScope& classClass switch (current.key) { case SyntaxKey::StaticMethod: { - MethodScope methodScope(&classClassScope); - initializeMethod(classClassScope, methodScope, current); - - #ifdef FULL_OUTOUT_INFO - IdentifierString messageName; - ByteCodeUtil::resolveMessageName(messageName, scope.module, methodScope.message); - - _errorProcessor->info(infoCurrentMethod, *messageName); - #endif // FULL_OUTOUT_INFO - - if (methodScope.isYieldable()) { - compileYieldMethod(writer, methodScope, current); - } - else if (methodScope.checkHint(MethodHint::Async)) { - compileAsyncMethod(writer, methodScope, current); - } - else compileMethod(writer, methodScope, current); + Method method(this, classClassScope); + method.compile(writer, current); break; } default: @@ -11203,11 +11275,6 @@ bool Compiler::Class::isParentDeclared(SyntaxNode node) void Compiler::Class::declare(SyntaxNode node) { -#ifdef FULL_OUTOUT_INFO - compiler->_presenter->print("\nSyntax tree:\n"); - printTree(compiler->_presenter, node); -#endif - bool extensionDeclaration = isExtensionDeclaration(node); resolveClassPostfixes(node, extensionDeclaration); @@ -11427,6 +11494,18 @@ Compiler::Method::Method(Compiler* compiler, ClassScope& classScope) { } +bool Compiler::Method :: isMethodInvoker(SyntaxNode current) +{ + if (scope.info.byRefHandler && !scope.checkHint(MethodHint::InterfaceDispatcher)) { + return true; + } + else if (test(current.arg.reference, FUNCTION_MESSAGE) && current.existChild(SyntaxKey::AsyncInvoker)) { + return true; + } + + return false; +} + void Compiler::Method::compile(BuildTreeWriter& writer, SyntaxNode current) { ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class); @@ -11460,6 +11539,9 @@ void Compiler::Method::compile(BuildTreeWriter& writer, SyntaxNode current) else if (scope.checkHint(MethodHint::Async)) { compiler->compileAsyncMethod(writer, scope, current); } + else if (isMethodInvoker(current)) { + compiler->compileMethodInvoker(writer, scope, current); + } // if it is a normal method else compiler->compileMethod(writer, scope, current); } @@ -12084,6 +12166,20 @@ ObjectInfo Compiler::Expression :: compileMessageOperationR(SyntaxNode node, Syn if (source.mode != TargetMode::Weak) { resolvedMessage = compiler->_logic->resolveSingleDispatch(*scope.moduleScope, compiler->retrieveType(scope, source), callContext.weakMessage, isSelfCall(source), resolvedNillableArgs); + + if (test(callContext.weakMessage, FUNCTION_MESSAGE) && EAttrs::testAndExclude(attrs, EAttr::AsyncOp) && resolvedMessage) { + ref_t functionRef = compiler->retrieveType(scope, source); + + // check if the async function exists + mssg_t asyncMessage = compiler->overwriteAsAsyncFunction(scope, resolvedMessage); + + CheckMethodResult dummy = {}; + if (compiler->_logic->checkMethod(*scope.moduleScope, functionRef, asyncMessage, dummy)) { + callContext.weakMessage = asyncMessage; + resolvedMessage = asyncMessage; + } + } + if (!resolvedMessage && !ignoreVariadics) { ref_t variadicMssg = resolveVariadicMessage(scope, callContext.weakMessage); @@ -12320,7 +12416,7 @@ ObjectInfo Compiler::Expression :: compileAsyncOperation(SyntaxNode node, ref_t writer->newNode(BuildKey::YieldingOp, -scope.moduleScope->ptrSize); writer->newNode(BuildKey::Tape); - ObjectInfo exprVal = compile(node.firstChild(), retMode ? targetRef: currentField.typeInfo.typeRef, EAttr::None, nullptr); + ObjectInfo exprVal = compile(node.firstChild(), retMode ? targetRef: currentField.typeInfo.typeRef, EAttr::AsyncOp, nullptr); bool nillableOp = false; if (!compileAssigningOp(currentField, exprVal, nillableOp)) @@ -12497,8 +12593,8 @@ ObjectInfo Compiler::Expression::compileAssignOperation(SyntaxNode node, int ope writer->appendNode(BuildKey::SavingInStack, 0); } - writer->newNode(op, operatorId); - writer->appendNode(BuildKey::Index, loperand.argument); + writer->newNode(op, loperand.argument); + writer->appendNode(BuildKey::OperatorId, operatorId); writer->closeNode(); unboxArguments({}, &updatedOuterArgs); @@ -12754,7 +12850,7 @@ ObjectInfo Compiler::Expression::compileCatchOperation(SyntaxNode node) writer->newNode(BuildKey::CatchOp, ehLocal.argument); if (finallyNode != SyntaxKey::None) - writer->appendNode(BuildKey::Index, scope.newTempLocal()); + writer->appendNode(BuildKey::StackIndex, scope.newTempLocal()); writer->newNode(BuildKey::Tape); compile(opNode, 0, EAttr::TryMode, nullptr); @@ -12798,7 +12894,7 @@ ObjectInfo Compiler::Expression::compileFinalOperation(SyntaxNode node) opNode = opNode.findChild(SyntaxKey::ClosureBlock); writer->newNode(BuildKey::FinalOp, ehLocal.argument); - writer->appendNode(BuildKey::Index, index1); + writer->appendNode(BuildKey::StackIndex, index1); writer->newNode(BuildKey::Tape); compile(opNode, 0, EAttr::TryMode, nullptr); @@ -12806,7 +12902,7 @@ ObjectInfo Compiler::Expression::compileFinalOperation(SyntaxNode node) scope.syncStack(); - int prevAllocated1, prevAllocated2; + int prevAllocated1 = 0, prevAllocated2 = 0; if (finallyNode != SyntaxKey::None) scope.commitTempStack(prevAllocated1, prevAllocated2); // HOTFIX : to prevent overwritting temporal variables @@ -13202,7 +13298,7 @@ ObjectInfo Compiler::Expression::compileCollection(SyntaxNode node, ExpressionAt for (size_t i = 0; i < arguments.count(); i++) { writeObjectInfo(arguments[i], node); writer->newNode(BuildKey::CopyingItem, -sizeInfo.size); - writer->appendNode(BuildKey::Index, (pos_t)i); + writer->appendNode(BuildKey::Value, (pos_t)i); writer->closeNode(); } @@ -15009,7 +15105,9 @@ ObjectInfo Compiler::Expression::compileTernaryOperands(SyntaxNode rnode, Syntax { writer->newNode(BuildKey::Tape); - ObjectInfo lexpr = compile(rnode, 0, EAttr::RetValExpected, nullptr); + EAttr mode = (withoutDebugInfo ? EAttr::NoDebugInfo : EAttr::None) | EAttr::RetValExpected; + + ObjectInfo lexpr = compile(rnode, 0, mode, nullptr); writeObjectInfo(lexpr); @@ -15019,7 +15117,7 @@ ObjectInfo Compiler::Expression::compileTernaryOperands(SyntaxNode rnode, Syntax // NOTE : it should immediately follow if-block writer->newNode(BuildKey::Tape); - ObjectInfo rexpr = compile(r2node, 0, EAttr::RetValExpected, nullptr); + ObjectInfo rexpr = compile(r2node, 0, mode, nullptr); writeObjectInfo(rexpr, r2node); @@ -15259,12 +15357,13 @@ ObjectInfo Compiler::Expression::compileOperation(SyntaxNode node, ArgumentsInfo if (ioperand.kind != ObjectKind::Unknown) writeObjectInfo(ioperand); - writer->newNode(op, operatorId); - - // check if the operation requires an extra arguments if (needToAlloc) { - writer->appendNode(BuildKey::Index, retVal.argument); + // NOTE : for allowing build tree tranformation, the target must be an operation argument + writer->newNode(op, retVal.argument); } + else writer->newNode(op, operatorId); + + writer->appendNode(BuildKey::OperatorId, operatorId); // HOTFIX : please provide the operator id for all operation, to make sure all operations can be correctly saved switch (op) { case BuildKey::BinaryArraySOp: @@ -15557,13 +15656,13 @@ void Compiler::Expression::writeMessageArguments(ObjectInfo& target, if (argType == ArgumentListType::VariadicArgListWithTypecasting || argType == ArgumentListType::VariadicArgList) { counter--; - ObjectInfo lenLocal = declareTempLocal(scope.moduleScope->buildins.intReference, false); + lenLocal = declareTempLocal(scope.moduleScope->buildins.intReference, false); // get length writeObjectInfo(arguments[counter]); writer->appendNode(BuildKey::SavingInStack); - writer->newNode(BuildKey::VArgSOp, LEN_OPERATOR_ID); - writer->appendNode(BuildKey::Index, lenLocal.argument); + writer->newNode(BuildKey::VArgSOp, lenLocal.argument); + writer->appendNode(BuildKey::OperatorId, LEN_OPERATOR_ID); writer->closeNode(); if (argType == ArgumentListType::VariadicArgListWithTypecasting && arguments[counter].typeInfo.elementRef != scope.moduleScope->buildins.superReference) { @@ -15572,7 +15671,7 @@ void Compiler::Expression::writeMessageArguments(ObjectInfo& target, mssg_t typecastMssg = mapTypecasting(scope.module, arguments[counter].typeInfo.elementRef); writer->newNode(BuildKey::UnboxAndCallMessage, arguments[counter].argument); - writer->appendNode(BuildKey::Index, counter); + writer->appendNode(BuildKey::Value, counter); writer->appendNode(BuildKey::Length, lenLocal.reference); writer->appendNode(BuildKey::TempVar, tempLocal.reference); writer->appendNode(BuildKey::Message, typecastMssg); @@ -15581,7 +15680,7 @@ void Compiler::Expression::writeMessageArguments(ObjectInfo& target, else { writer->appendNode(BuildKey::LoadingIndex, lenLocal.argument); writer->newNode(BuildKey::UnboxMessage, arguments[counter].argument); - writer->appendNode(BuildKey::Index, counter); + writer->appendNode(BuildKey::Value, counter); writer->closeNode(); } } @@ -15886,8 +15985,8 @@ ObjectInfo Compiler::Expression::boxArgumentInPlace(ObjectInfo info, ref_t targe writeObjectInfo(info); writer->appendNode(BuildKey::SavingInStack, 0); - writer->newNode(BuildKey::BinaryArraySOp, LEN_OPERATOR_ID); - writer->appendNode(BuildKey::Index, lenLocal.argument); + writer->newNode(BuildKey::BinaryArraySOp, lenLocal.argument); + writer->appendNode(BuildKey::OperatorId, LEN_OPERATOR_ID); writer->appendNode(BuildKey::Size, elementSize); writer->closeNode(); @@ -15916,8 +16015,8 @@ ObjectInfo Compiler::Expression::boxArgumentInPlace(ObjectInfo info, ref_t targe writeObjectInfo(info, info.kind == ObjectKind::DistributedTypeList); writer->appendNode(BuildKey::SavingInStack, 0); - writer->newNode(BuildKey::ObjArraySOp, LEN_OPERATOR_ID); - writer->appendNode(BuildKey::Index, lenLocal.argument); + writer->newNode(BuildKey::ObjArraySOp, lenLocal.argument); + writer->appendNode(BuildKey::OperatorId, LEN_OPERATOR_ID); writer->closeNode(); // allocate the object @@ -16021,8 +16120,8 @@ ObjectInfo Compiler::Expression :: boxVariadicArgument(ObjectInfo info) // get length writeObjectInfo(info); writer->appendNode(BuildKey::SavingInStack); - writer->newNode(BuildKey::VArgSOp, LEN_OPERATOR_ID); - writer->appendNode(BuildKey::Index, lenLocal.argument); + writer->newNode(BuildKey::VArgSOp, lenLocal.argument); + writer->appendNode(BuildKey::OperatorId, LEN_OPERATOR_ID); writer->closeNode(); // create a dynamic array diff --git a/elenasrc3/elc/compiler.h b/elenasrc3/elc/compiler.h index b8c259abc0..6634d09e7b 100644 --- a/elenasrc3/elc/compiler.h +++ b/elenasrc3/elc/compiler.h @@ -441,11 +441,11 @@ namespace elena_lang else return {}; } - virtual ObjectInfo mapMember(ustr_t identifier) + virtual ObjectInfo mapMember(ustr_t) { return {}; } - virtual ObjectInfo mapGlobal(ustr_t globalReference) + virtual ObjectInfo mapGlobal(ustr_t) { return {}; } @@ -1357,6 +1357,8 @@ namespace elena_lang MethodScope scope; + bool isMethodInvoker(SyntaxNode current); + void compileConstructor(BuildTreeWriter& writer, SyntaxNode current, ClassScope& classClassScope); public: @@ -1605,6 +1607,8 @@ namespace elena_lang bool _withDebugInfo; bool _strictTypeEnforcing; + mssg_t overwriteAsAsyncFunction(Scope& scope, mssg_t weakMessage); + void addTypeInfo(Scope& scope, SyntaxNode node, SyntaxKey key, TypeInfo typeInfo); void importExtensions(NamespaceScope& ns, ustr_t importedNs); @@ -1783,8 +1787,9 @@ namespace elena_lang void declareSymbolMetaInfo(SymbolScope& scope, SyntaxNode node); - void declareByRefHandler(SyntaxNode classNode, SyntaxKey methodType, - ref_t targetRef, ClassInfo& info, mssg_t message, bool abstractOne); + void declareInvoker(ClassInfo& info, mssg_t targetMssg, MethodInfo& methodInfo, bool abstractOne, ref_t newHints); + void declareByRefHandler(ClassInfo& info, mssg_t message, bool abstractOne); + void declareAsyncInvoker(ClassInfo& info, mssg_t asyncFunction); void declareMetaInfo(Scope& scope, SyntaxNode node); void declareMethodMetaInfo(MethodScope& scope, SyntaxNode node); @@ -1874,6 +1879,7 @@ namespace elena_lang void compileConstructorDispatchCode(BuildTreeWriter& writer, CodeScope& codeScope, ClassScope& classClassScope, SyntaxNode node); void compileByRefHandlerInvoker(BuildTreeWriter& writer, MethodScope& scope, CodeScope& codeScope, mssg_t handler, ref_t targetRef); + void compileAsyncInvoker(BuildTreeWriter& writer, MethodScope& methodScope, CodeScope& codeScope, mssg_t asyncFunction); void compileRedirectDispatcher(BuildTreeWriter& writer, MethodScope& scope, CodeScope& codeScope, SyntaxNode node, bool withGenerics); @@ -1912,6 +1918,7 @@ namespace elena_lang void compileIteratorMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node); void compileExpressionMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node); void compileAbstractMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node, bool abstractMode); + void compileMethodInvoker(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node); void compileMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node); void compileYieldMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node); void compileAsyncMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node); diff --git a/elenasrc3/elc/compilerlogic.cpp b/elenasrc3/elc/compilerlogic.cpp index 379ff83f64..37472c043f 100644 --- a/elenasrc3/elc/compilerlogic.cpp +++ b/elenasrc3/elc/compilerlogic.cpp @@ -1360,6 +1360,13 @@ bool CompilerLogic :: isEmbeddableStruct(ClassInfo& info) && !test(info.header.flags, elDynamicRole); } +bool CompilerLogic :: isNumericData(ClassInfo& info) +{ + int dataMask = info.header.flags & elDebugMask; + + return dataMask == elDebugDWORD || dataMask == elDebugQWORD || dataMask == elDebugFLOAT64; +} + bool CompilerLogic :: isEmbeddable(ModuleScopeBase& scope, TypeInfo typeInfo) { if (typeInfo.nillable) @@ -1884,10 +1891,11 @@ bool CompilerLogic :: defineClassInfo(ModuleScopeBase& scope, ClassInfo& info, r SizeInfo CompilerLogic :: defineStructSize(ClassInfo& info) { - SizeInfo sizeInfo = { 0, test(info.header.flags, elReadOnlyRole) }; + SizeInfo sizeInfo = { 0, test(info.header.flags, elReadOnlyRole), false }; if (isEmbeddableStruct(info)) { sizeInfo.size = info.size; + sizeInfo.numeric = isNumericData(info); return sizeInfo; } @@ -2909,7 +2917,7 @@ ref_t CompilerLogic :: resolveExtensionTemplateByTemplateArgs(ModuleScopeBase& s String tmp; tmp.copy(pattern + argLenPos + 1, i - argLenPos - 3); - if(argumentLen != tmp.toInt()) + if(argumentLen != tmp.toUInt()) return 0; } else return 0; diff --git a/elenasrc3/elc/compilerlogic.h b/elenasrc3/elc/compilerlogic.h index 14f52d0d7d..363ad624a3 100644 --- a/elenasrc3/elc/compilerlogic.h +++ b/elenasrc3/elc/compilerlogic.h @@ -26,6 +26,8 @@ namespace elena_lang bool withCustomDispatcher; int nillableArgs; mssg_t byRefHandler; + + CheckMethodResult() = default; }; struct TypeAttributes @@ -122,6 +124,8 @@ namespace elena_lang bool isReadOnly(ClassInfo& info); bool withVariadicsMethods(ClassInfo& info); + bool isNumericData(ClassInfo& info); + bool isDynamic(ClassInfo& info); bool isEmbeddableArray(ClassInfo& info); bool isEmbeddableArray(ModuleScopeBase& scope, ref_t reference); diff --git a/elenasrc3/elc/compiling.cpp b/elenasrc3/elc/compiling.cpp index a5e09e3f31..3b3bb8aaed 100644 --- a/elenasrc3/elc/compiling.cpp +++ b/elenasrc3/elc/compiling.cpp @@ -15,6 +15,7 @@ #include "modulescope.h" #include "bcwriter.h" #include "separser.h" +#include "serializer.h" using namespace elena_lang; @@ -302,7 +303,7 @@ ref_t CompilingProcess::TemplateGenerator :: generateClassTemplate(ModuleScopeBa writer.newNode(SyntaxKey::Namespace); _processor.generateClassTemplate(&moduleScope, generatedReference, writer, - sectionInfo.section, parameters); + sectionInfo.section, parameters, templateRef); writer.closeNode(); writer.closeNode(); @@ -326,12 +327,13 @@ CompilingProcess :: CompilingProcess(path_t appPath, path_t exeExtension, PresenterBase* presenter, ErrorProcessor* errorProcessor, pos_t codeAlignment, JITSettings defaultCoreSettings, - JITCompilerBase* (*compilerFactory)(LibraryLoaderBase*, PlatformType) + JITCompilerBase* (*compilerFactory)(PlatformType) ) : _appPath(appPath), _templateGenerator(this), _forwards(nullptr), - _parser(nullptr) + _parser(nullptr), + _traceMode(false) { _exeExtension = exeExtension; _modulePrologName = modulePrologName; @@ -362,6 +364,12 @@ CompilingProcess :: CompilingProcess(path_t appPath, path_t exeExtension, _btRules.load(btRuleReader, btRuleReader.length()); } + PathString btXRulesPath(appPath, BT_XRULES_FILE); + FileReader btXRuleReader(*btXRulesPath, FileRBMode, FileEncoding::Raw, false); + if (btRuleReader.isOpen()) { + _btXRules.load(btXRuleReader, btXRuleReader.length()); + } + _verbose = false; } @@ -428,6 +436,8 @@ void CompilingProcess :: parseFileUserDefinedGrammar(SyntaxWriterBase* syntaxWri parser.parse(path, derivationTree); syntaxWriter->saveTree(derivationTree); + + parser.clearStack(); } catch (ParserError& e) { @@ -444,8 +454,12 @@ void CompilingProcess :: parseFile(path_t projectPath, { // save the path to the current source path_t sourceRelativePath = (*file_it).str(); - if (!projectPath.empty()) + if (!projectPath.empty()) { + if (!sourceRelativePath.startsWith(projectPath)) + _errorProcessor->raisePathError(errInvalidFile, sourceRelativePath); + sourceRelativePath += projectPath.length() + 1; + } _presenter->printPathLine(ELC_PARSING_FILE, sourceRelativePath); @@ -519,6 +533,8 @@ void CompilingProcess :: generateModule(ModuleScopeBase& moduleScope, BuildTree& ByteCodeWriter bcWriter(&_libraryProvider, true); if (_btRules.length() > 0) bcWriter.loadBuildTreeRules(&_btRules); + if (_btXRules.length() > 0) + bcWriter.loadBuildTreeXRules(&_btXRules); if (_bcRules.length() > 0) bcWriter.loadByteCodeRules(&_bcRules); @@ -533,12 +549,96 @@ void CompilingProcess :: generateModule(ModuleScopeBase& moduleScope, BuildTree& _libraryProvider.saveModule(moduleScope.module); _libraryProvider.saveDebugModule(moduleScope.debugModule); + + if (_verbose) { + PathString path; + _libraryProvider.retrievePath(moduleScope.module, path); + _presenter->printPath(ELC_MODULE_TARGET_PATH, *path); + } + } +} + +inline void printTree(PresenterBase* presenter, SyntaxNode node, List* filters) +{ + DynamicUStr target; + + SyntaxTreeSerializer::save(node, target, filters); + + presenter->print(target.str()); +} + +inline void printTree(PresenterBase* presenter, BuildNode node, List* filters) +{ + DynamicUStr target; + + BuildTreeSerializer::save(node, target, filters); + + presenter->print(target.str()); +} + +void CompilingProcess :: printSyntaxTree(SyntaxTree& syntaxTree) +{ + List filters(SyntaxKey::None); + if (!_verbose) { + filters.add(SyntaxKey::Column); + filters.add(SyntaxKey::Row); + filters.add(SyntaxKey::SourcePath); + filters.add(SyntaxKey::InlineTemplate); + } + + _presenter->print("\nSyntax Tree:"); + printTree(_presenter, syntaxTree.readRoot(), &filters); +} + +void CompilingProcess :: printBuildTree(ModuleBase* module, BuildTree& buildTree) +{ + List filters(BuildKey::None); + if (!_verbose) { + filters.add(BuildKey::Path); + filters.add(BuildKey::Breakpoint); + filters.add(BuildKey::VirtualBreakpoint); + filters.add(BuildKey::EOPBreakpoint); + filters.add(BuildKey::ClassName); + filters.add(BuildKey::MethodName); + filters.add(BuildKey::VariableInfo); + filters.add(BuildKey::ArgumentsInfo); + filters.add(BuildKey::OpenStatement); + filters.add(BuildKey::EndStatement); + } + + _presenter->print("\nBuild Tree:"); + + BuildNode node = buildTree.readRoot(); + BuildNode current = node.firstChild(); + while (current != BuildKey::None) { + switch (current.key) { + case BuildKey::Symbol: + _presenter->print("\n@symbol %s", module->resolveReference(current.arg.reference)); + + printTree(_presenter, current, &filters); + break; + case BuildKey::Class: + _presenter->print("\n@class %s", module->resolveReference(current.arg.reference)); + + printTree(_presenter, current, &filters); + break; + default: + // to make compiler happy + break; + } + + current = current.nextNode(); } } bool CompilingProcess :: buildSyntaxTree(ModuleScopeBase& moduleScope, SyntaxTree* syntaxTree, bool templateMode, ExtensionMap* outerExtensionList) { + // print the incoming syntax tree if required + if (_traceMode) { + printSyntaxTree(*syntaxTree); + } + // generating build tree BuildTree buildTree; bool retVal = compileModule(moduleScope, *syntaxTree, buildTree, outerExtensionList); @@ -546,6 +646,11 @@ bool CompilingProcess :: buildSyntaxTree(ModuleScopeBase& moduleScope, SyntaxTre // generating byte code generateModule(moduleScope, buildTree, !templateMode); + // print the outcome bui tree if required + if (_traceMode) { + printBuildTree(moduleScope.module, buildTree); + } + return retVal; } @@ -670,6 +775,8 @@ void CompilingProcess :: compile(ProjectBase& project, _errorProcessor->raiseInternalError(errParserNotInitialized); } + _traceMode = project.BoolSetting(ProjectOption::TracingMode); + // load the environment ProjectEnvironment env; project.initEnvironment(env); @@ -714,7 +821,7 @@ void CompilingProcess :: compile(ProjectBase& project, void CompilingProcess :: link(Project& project, LinkerBase& linker, bool withTLS) { // ignore link operation for trace mode - if (project.BoolSetting(ProjectOption::TracingMode)) + if (_traceMode) return; PlatformType uiType = project.UITargetType(); @@ -759,10 +866,10 @@ void CompilingProcess :: link(Project& project, LinkerBase& linker, bool withTLS freeobj(addressMapper); } -void CompilingProcess :: greeting() +void CompilingProcess :: greeting(PresenterBase* presenter) { // Greetings - _presenter->print(ELC_GREETING, ENGINE_MAJOR_VERSION, ENGINE_MINOR_VERSION, ELC_REVISION_NUMBER); + presenter->print(ELC_GREETING, ENGINE_MAJOR_VERSION, ENGINE_MINOR_VERSION, ELC_REVISION_NUMBER); } void CompilingProcess :: cleanUp(ProjectBase& project) diff --git a/elenasrc3/elc/compiling.h b/elenasrc3/elc/compiling.h index 5ab42ac70f..6372aec705 100644 --- a/elenasrc3/elc/compiling.h +++ b/elenasrc3/elc/compiling.h @@ -83,17 +83,22 @@ namespace elena_lang pos_t _codeAlignment; JITSettings _defaultCoreSettings; - JITCompilerBase*(*_jitCompilerFactory)(LibraryLoaderBase*, PlatformType); + JITCompilerBase*(*_jitCompilerFactory)(PlatformType); TemplateGenerator _templateGenerator; MemoryDump _bcRules; MemoryDump _btRules; + MemoryDump _btXRules; bool _verbose; + bool _traceMode; IdentifierList _forwards; + void printSyntaxTree(SyntaxTree& syntaxTree); + void printBuildTree(ModuleBase* module, BuildTree& buildTree); + bool buildSyntaxTree(ModuleScopeBase& moduleScope, SyntaxTree* syntaxTree, bool templateMode, ExtensionMap* outerExtensionList); @@ -140,7 +145,8 @@ namespace elena_lang _forwards.add(f.clone()); } - void greeting(); + static void greeting(PresenterBase* presenter); + int build(Project& project, LinkerBase& linker, pos_t defaultStackAlignment, @@ -161,7 +167,7 @@ namespace elena_lang PresenterBase* presenter, ErrorProcessor* errorProcessor, pos_t codeAlignment, JITSettings defaultCoreSettings, - JITCompilerBase* (*compilerFactory)(LibraryLoaderBase*, PlatformType)); + JITCompilerBase* (*compilerFactory)(PlatformType)); virtual ~CompilingProcess() { diff --git a/elenasrc3/elc/derivation.cpp b/elenasrc3/elc/derivation.cpp index 43cadb3e8d..2aea3c54a2 100644 --- a/elenasrc3/elc/derivation.cpp +++ b/elenasrc3/elc/derivation.cpp @@ -1327,7 +1327,7 @@ inline void copyFunctionAttributes(SyntaxTreeWriter& writer, SyntaxNode node) current.setKey(SyntaxKey::Idle); break; case SyntaxKey::Attribute: - if (current.arg.reference == V_FUNCTION) { + if (current.arg.reference == V_FUNCTION || current.arg.reference == V_ASYNC) { // copy the function attribute SyntaxTree::copyNodeSafe(writer, current, true); current.setKey(SyntaxKey::Idle); @@ -2344,7 +2344,7 @@ void TemplateProssesor :: copyModuleInfo(SyntaxTreeWriter& writer, SyntaxNode no } void TemplateProssesor :: generateTemplate(SyntaxTreeWriter& writer, TemplateScope& scope, - MemoryBase* templateBody, bool importModuleInfo) + MemoryBase* templateBody, bool importModuleInfo, ref_t templateRef) { SyntaxTree templateTree; templateTree.load(templateBody); @@ -2358,7 +2358,8 @@ void TemplateProssesor :: generateTemplate(SyntaxTreeWriter& writer, TemplateSco writer.newNode(SyntaxKey::Class, INVALID_REF); writer.appendNode(SyntaxKey::Attribute, V_TEMPLATEBASED); - writer.appendNode(SyntaxKey::Name, scope.moduleScope->mapFullReference(fullName, true)); + writer.appendNode(SyntaxKey::SourceRef, templateRef); + writer.appendNode(SyntaxKey::Name, scope.moduleScope->mapFullReference(fullName, true)); } SyntaxNode current = rootNode.firstChild(); @@ -2392,10 +2393,10 @@ void TemplateProssesor :: generateTemplate(SyntaxTreeWriter& writer, TemplateSco } void TemplateProssesor :: generateClassTemplate(ModuleScopeBase* moduleScope, ref_t classRef, - SyntaxTreeWriter& writer, MemoryBase* sectionBody, List& args) + SyntaxTreeWriter& writer, MemoryBase* sectionBody, List& args, ref_t templateRef) { TemplateScope templateScope(Type::Class, moduleScope, classRef); loadArguments(templateScope, &args); - generateTemplate(writer, templateScope, sectionBody, true); + generateTemplate(writer, templateScope, sectionBody, true, templateRef); } diff --git a/elenasrc3/elc/derivation.h b/elenasrc3/elc/derivation.h index fcf46643ec..43887e055a 100644 --- a/elenasrc3/elc/derivation.h +++ b/elenasrc3/elc/derivation.h @@ -323,7 +323,7 @@ namespace elena_lang void generate(SyntaxTreeWriter& writer, TemplateScope& scope, MemoryBase* templateSection); void generateTemplate(SyntaxTreeWriter& writer, TemplateScope& scope, - MemoryBase* templateBody, bool importModuleInfo); + MemoryBase* templateBody, bool importModuleInfo, ref_t templateRef); void importTemplate(Type type, MemoryBase* templateSection, SyntaxNode target, List* arguments, List* parameters); @@ -341,7 +341,7 @@ namespace elena_lang void importTextblock(MemoryBase* templateSection, SyntaxNode target); void generateClassTemplate(ModuleScopeBase* moduleScope, ref_t classRef, SyntaxTreeWriter& writer, - MemoryBase* sectionBody, List& args); + MemoryBase* sectionBody, List& args, ref_t templateRef); TemplateProssesor() = default; }; diff --git a/elenasrc3/elc/errors.h b/elenasrc3/elc/errors.h index 92a3a5f39d..0a08bf8507 100644 --- a/elenasrc3/elc/errors.h +++ b/elenasrc3/elc/errors.h @@ -130,6 +130,7 @@ namespace elena_lang constexpr auto infoMsgTargetClass = "info 707: target class: %s\n"; constexpr auto infoMsgScopeMethod = "info 708: in the method: %s\n"; constexpr auto infoMssgExptectedType = "\ninfo 709: the expected type is %s, but the actual type is %s\n"; + constexpr auto infoMsgInternalDefConstructor = "\ninfo 710: default constructor cannot be internal\n"; } // _ELENA_ diff --git a/elenasrc3/elc/linux/elc.cpp b/elenasrc3/elc/linux/elc.cpp index 68a51910f9..b788b9c440 100644 --- a/elenasrc3/elc/linux/elc.cpp +++ b/elenasrc3/elc/linux/elc.cpp @@ -136,7 +136,7 @@ class Presenter : public LinuxConsolePresenter ~Presenter() = default; }; -JITCompilerBase* createJITCompiler(LibraryLoaderBase* loader, PlatformType platform) +JITCompilerBase* createJITCompiler(PlatformType platform) { switch (platform) { #if defined(__i386__) || defined(__x86_64__) @@ -168,7 +168,8 @@ void handleOption(char* arg, IdentifierString& profile, Project& project, Compil { IdentifierString configName(arg + 2); - project.loadConfigByName(dataPath, *configName, true); + if(!project.loadConfigByName(dataPath, *configName, true)) + errorProcessor.info(wrnInvalidConfig, *configName);; break; } case 'p': @@ -185,10 +186,15 @@ void handleOption(char* arg, IdentifierString& profile, Project& project, Compil } int compileProject(int argc, char** argv, path_t dataPath, ErrorProcessor& errorProcessor, - CompilingProcess& process) + path_t basePath = nullptr, ustr_t defaultProfile = nullptr) { bool cleanMode = false; + JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_STACKRESERV, 1, true, true }; + CompilingProcess process(dataPath, nullptr, "", "", "", + &Presenter::getInstance(), &errorProcessor, + VA_ALIGNMENT, defaultCoreSettings, createJITCompiler); + Project project(dataPath, CURRENT_PLATFORM, &Presenter::getInstance()); LinuxLinker linker(&errorProcessor, &LinuxImageFormatter::getInstance(&project)); @@ -202,7 +208,7 @@ int compileProject(int argc, char** argv, path_t dataPath, ErrorProcessor& error PathString configPath(dataPath, PathHelper::retrieveFilePath(defaultConfigPath)); project.loadConfig(*configPath, nullptr, false); - IdentifierString profile; + IdentifierString profile(defaultProfile); for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { handleOption(argv[i], profile, project, process, @@ -233,10 +239,13 @@ int compileProject(int argc, char** argv, path_t dataPath, ErrorProcessor& error else { FileNameString fileName(argv[i]); - project.addSource(*fileName, argv[i], nullptr, nullptr); + project.addSource(*fileName, argv[i], nullptr, nullptr, true); } } + if (!basePath.empty()) + project.setBasePath(basePath); + if (cleanMode) { return process.clean(project); } @@ -252,7 +261,7 @@ int compileProject(int argc, char** argv, path_t dataPath, ErrorProcessor& error } int compileProjectCollection(int argc, char** argv, path_t path, path_t dataPath, - ErrorProcessor& errorProcessor, CompilingProcess& process) + ErrorProcessor& errorProcessor) { Presenter* presenter = &Presenter::getInstance(); @@ -265,16 +274,18 @@ int compileProjectCollection(int argc, char** argv, path_t path, path_t dataPath return ERROR_RET_CODE; } - for (auto it = collection.paths.start(); !it.eof(); ++it) { + for (auto it = collection.projectSpecs.start(); !it.eof(); ++it) { + auto spec = *it; + size_t destLen = FILENAME_MAX; char projectPath[FILENAME_MAX]; - StrConvertor::copy(projectPath, (*it).str(), (*it).length(), destLen); + StrConvertor::copy(projectPath, spec->path.str(), spec->path.length(), destLen); projectPath[destLen] = 0; argv[argc - 1] = projectPath; presenter->printPath(ELC_COMPILING_PROJECT, projectPath); - int result = compileProject(argc, argv, dataPath, errorProcessor, process); + int result = compileProject(argc, argv, dataPath, errorProcessor, spec->basePath, spec->profile); if (result == ERROR_RET_CODE) { return ERROR_RET_CODE; } @@ -294,13 +305,9 @@ int main(int argc, char* argv[]) { PathString dataPath(PathHelper::retrievePath(dataFileList, 3, DATA_PATH)); - JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_STACKRESERV, 1, true, true }; ErrorProcessor errorProcessor(&Presenter::getInstance()); - CompilingProcess process(*dataPath, nullptr, "", "", "", - &Presenter::getInstance(), &errorProcessor, - VA_ALIGNMENT, defaultCoreSettings, createJITCompiler); - process.greeting(); + CompilingProcess::greeting(&Presenter::getInstance()); // Reading command-line arguments... if (argc < 2) { @@ -309,9 +316,9 @@ int main(int argc, char* argv[]) } else if (argv[argc - 1][0] != '-' && PathUtil::checkExtension(argv[argc - 1], "prjcol")) { return compileProjectCollection(argc, argv, argv[argc - 1], - *dataPath, errorProcessor, process); + *dataPath, errorProcessor); } - else return compileProject(argc, argv, *dataPath, errorProcessor, process); + else return compileProject(argc, argv, *dataPath, errorProcessor); } catch (CLIException) { diff --git a/elenasrc3/elc/linux/elfcommon.h b/elenasrc3/elc/linux/elfcommon.h index 5dfd2dfabb..76ec3a2a66 100644 --- a/elenasrc3/elc/linux/elfcommon.h +++ b/elenasrc3/elc/linux/elfcommon.h @@ -2,7 +2,7 @@ // E L E N A P r o j e c t: ELENA Compiler // // This header contains Common ELF types -// (C)2021, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ELFCOMMON_H @@ -16,6 +16,8 @@ namespace elena_lang constexpr auto elfDynamicOffset = 1; constexpr auto elfDynamicVAddress = 2; constexpr auto elfDynamicSize = 3; + constexpr auto elfTLSSize = 5; + } -#endif \ No newline at end of file +#endif diff --git a/elenasrc3/elc/linux/elfimage.cpp b/elenasrc3/elc/linux/elfimage.cpp index 6243320d1c..585eb52199 100644 --- a/elenasrc3/elc/linux/elfimage.cpp +++ b/elenasrc3/elc/linux/elfimage.cpp @@ -3,7 +3,7 @@ // // This file contains ELENA Executive ELF Image class implementation // supported platform: I386, AMD64 -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "clicommon.h" @@ -66,6 +66,7 @@ void ElfImageFormatter :: mapImage(ImageProviderBase& provider, AddressSpace& ma MemoryBase* import = provider.getImportSection(); MemoryBase* data = provider.getDataSection(); MemoryBase* stat = provider.getStatSection(); + MemoryBase* tls = provider.getTLSSection(); // === address space mapping === @@ -135,8 +136,18 @@ void ElfImageFormatter :: mapImage(ImageProviderBase& provider, AddressSpace& ma fileSize += align(data->length(), fileAlignment); sectionSize += align(data->length(), fileAlignment); + if (tls->length() > 0) { + map.tls = map.data + align(data->length(), fileAlignment); + map.dataSize += align(tls->length(), fileAlignment); + + sectionSize += align(tls->length(), fileAlignment); + fileSize += align(tls->length(), fileAlignment); + + map.stat = map.tls + tls->length(); + } + else map.stat = map.data + data->length(); + map.dataSize += stat->length(); - map.stat = map.data + data->length(); sectionSize += align(stat->length(), fileAlignment); @@ -146,6 +157,12 @@ void ElfImageFormatter :: mapImage(ImageProviderBase& provider, AddressSpace& ma sections.items.add(sections.headers.count(), { import, true }); sections.items.add(sections.headers.count(), { data, true }); + if (tls->length() > 0) { + map.dictionary.add(elfTLSSize, tls->length()); + + sections.items.add(sections.headers.count(), { tls, true }); + } + sectionOffset = align(sectionOffset + sectionSize, sectionAlignment); fileOffset = align(fileOffset + fileSize, fileAlignment); // NOTE : due to loader requirement, adjust offset diff --git a/elenasrc3/elc/linux/elflinker.cpp b/elenasrc3/elc/linux/elflinker.cpp index 4aff4f8808..7c8c7d31f3 100644 --- a/elenasrc3/elc/linux/elflinker.cpp +++ b/elenasrc3/elc/linux/elflinker.cpp @@ -3,7 +3,7 @@ // // This file contains ELENA Executive Linker class implementation // Supported platforms: Linux -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elflinker.h" @@ -19,7 +19,9 @@ using namespace elena_lang; unsigned short ElfLinker :: calcPHLength(ElfExecutableImage& image) { - return image.imageSections.headers.count() + 3; // sections + HDR + interpreter + dynamic + unsigned short def_ph_count = image.withTLS ? 4 : 3; + + return image.imageSections.headers.count() + def_ph_count; // sections + HDR + interpreter + dynamic } void ElfLinker :: writeSection(FileWriter* file, MemoryBase* section) @@ -106,6 +108,9 @@ void ElfLinker :: prepareElfImage(ImageProviderBase& provider, ElfExecutableImag image.sectionAlignment, image.fileAlignment, image.withDebugInfo); + + if (image.addressMap.tls > 0) + image.withTLS = true; } LinkResult ElfLinker :: run(ProjectBase& project, ImageProviderBase& provider, PlatformType, path_t) diff --git a/elenasrc3/elc/linux/elflinker.h b/elenasrc3/elc/linux/elflinker.h index 0558e64d56..5263fc6ecb 100644 --- a/elenasrc3/elc/linux/elflinker.h +++ b/elenasrc3/elc/linux/elflinker.h @@ -20,6 +20,7 @@ namespace elena_lang unsigned int fileAlignment; unsigned int flags; bool withDebugInfo; + bool withTLS; AddressSpace addressMap; @@ -31,7 +32,8 @@ namespace elena_lang this->fileAlignment = this->sectionAlignment = 0; this->flags = 0; this->withDebugInfo = withDebugInfo; - } + this->withTLS = false; + } }; // --- ElfLinker --- diff --git a/elenasrc3/elc/linux/elflinker32.cpp b/elenasrc3/elc/linux/elflinker32.cpp index 13e913cb2f..02e6e39268 100644 --- a/elenasrc3/elc/linux/elflinker32.cpp +++ b/elenasrc3/elc/linux/elflinker32.cpp @@ -3,7 +3,7 @@ // // This header contains ELENA Executive Linker class body // Supported platforms: Linux 32 -// (C)2021, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elflinker32.h" @@ -123,6 +123,19 @@ void Elf32Linker :: writePHTable(ElfExecutableImage& image, FileWriter* file, un ph_header.p_flags = PF_R + PF_W; ph_header.p_align = 8; file->write((char*)&ph_header, ELF_PH_SIZE); + + // TLS + if (image.withTLS) { + pos_t tlsSize = image.addressMap.dictionary.get(elfTLSSize); + + ph_header.p_type = PT_TLS; + ph_header.p_offset = offset; + ph_header.p_paddr = ph_header.p_vaddr = image.addressMap.imageBase + image.addressMap.tls; + ph_header.p_memsz = ph_header.p_filesz = tlsSize; + ph_header.p_flags = PF_R; + ph_header.p_align = 4; + file->write((char*)&ph_header, ELF_PH_SIZE); + } } void Elf32Linker :: writeInterpreter(FileWriter* file) diff --git a/elenasrc3/elc/macos/elc.cpp b/elenasrc3/elc/macos/elc.cpp index 8d31208b39..fe87d4960f 100644 --- a/elenasrc3/elc/macos/elc.cpp +++ b/elenasrc3/elc/macos/elc.cpp @@ -227,7 +227,7 @@ int main(int argc, char* argv[]) JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_STACKRESERV, 1, true, true }; ErrorProcessor errorProcessor(&Presenter::getInstance()); - CompilingProcess process(*dataPath, nullptr, "", "", "", + CompilingProcess process(*dataPath, "o", "", "", "", &Presenter::getInstance(), &errorProcessor, VA_ALIGNMENT, defaultCoreSettings, createJITCompiler); diff --git a/elenasrc3/elc/macos/machoarmlinker64.h b/elenasrc3/elc/macos/machoarmlinker64.h index 1e96073cd5..ac6ce7892a 100644 --- a/elenasrc3/elc/macos/machoarmlinker64.h +++ b/elenasrc3/elc/macos/machoarmlinker64.h @@ -17,6 +17,15 @@ namespace elena_lang class MachOARM64Linker : public MachOLinker64 { protected: + virtual CPUType getCPUType() + { + return CPUType::AARCH64; + } + + virtual CPUSubType getCPUSubType() + { + return CPUSubType::ARM_ALL; + } public: MachOARM64Linker(ErrorProcessorBase* errorProcessor) diff --git a/elenasrc3/elc/macos/machocommon.h b/elenasrc3/elc/macos/machocommon.h new file mode 100644 index 0000000000..c1669834d0 --- /dev/null +++ b/elenasrc3/elc/macos/machocommon.h @@ -0,0 +1,58 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains Common ELF types +// (C)2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef MACHOCOMMON_H +#define MACHOCOMMON_H + +namespace elena_lang +{ + constexpr auto SECTION_ALIGNMENT = 0x1000; + constexpr auto FILE_ALIGNMENT = 0x0010; + + constexpr unsigned long MH_MAGIC_64 = 0xFEEDFACF; + + constexpr unsigned long FILE_EXECUTABLE = 2; + + enum class CPUType : int32_t + { + None = 0, + AARCH64 = 0x1000000C; + }; + + enum class CPUSubType : int32_t + { + None = 0, + ARM_ALL = 0 + }; + + constexpr auto __PAGEZERO_SEGMENT = "__PAGEZERO"; + constexpr auto __TEXT_SEGMENT = "__TEXT"; + constexpr auto __DATA_SEGMENT = "__DATA"; + + constexpr int Flags_NoUndefs = 0x000001; + constexpr int Flags_DyldLink = 0x000004; + constexpr int Flags_TwoLevel = 0x000080; + + constexpr int Command_Segment_64 = 0x00000019; + + struct Command + { + uint32_t commandType; + + uint32_t commandSize; + }; + + typedef List Commands; + + typedef vm_prot_t int; + + constexpr int PROT_R = 1; + constexpr int PROT_W = 2; + constexpr int PROT_X = 4; +} + +#endif \ No newline at end of file diff --git a/elenasrc3/elc/macos/machoimage.cpp b/elenasrc3/elc/macos/machoimage.cpp index dbc7c5f4e6..444f26b479 100644 --- a/elenasrc3/elc/macos/machoimage.cpp +++ b/elenasrc3/elc/macos/machoimage.cpp @@ -15,8 +15,103 @@ using namespace elena_lang; // --- MachOImageFormatter --- -void MachOImageFormatter:: prepareImage(ImageProviderBase& provider, AddressSpace& map, ImageSections& sections, +void MachOImageFormatter :: mapImage(ImageProviderBase& provider, AddressSpace& map, ImageSections& sections, pos_t sectionAlignment, + pos_t fileAlignment/*, ElfData& elfData*/) +{ + pos_t fileOffset = 0, sectionOffset = 0; + pos_t sectionSize = 0, fileSize = 0; + + MemoryBase* text = provider.getTextSection(); + MemoryBase* rdata = provider.getRDataSection(); + MemoryBase* adata = provider.getADataSection(); + MemoryBase* mdata = provider.getMDataSection(); + MemoryBase* mbdata = provider.getMBDataSection(); + //MemoryBase* import = provider.getImportSection(); + MemoryBase* data = provider.getDataSection(); + MemoryBase* stat = provider.getStatSection(); + + // === address space mapping === + + sectionSize = map.headerSize; + sections.headers.add(ImageSectionHeader::get(__PAGEZERO_SEGMENT, 0, ImageSectionHeader::SectionType::Data, + sectionSize, 0)); + + // --- __TEXT (code & rdata & adata & mdata & mbdata & rdata) --- + sectionOffset = sectionSize; + + map.code = map.headerSize; // code section should always be first + map.codeSize = text->length(); + map.entryPoint += map.code; + + fileOffset += align(map.codeSize, fileAlignment); + + // adata & mdata & mbdata + map.dataSize = adata->length(); + map.adata = fileOffset; + + map.dataSize += mdata->length(); + map.mdata = map.adata + adata->length(); + + map.dataSize += mbdata->length(); + map.mbdata = map.mdata + mdata->length(); + + fileOffset += align(map.dataSize, fileAlignment); + + // rdata + map.dataSize += rdata->length(); + map.rdata = fileOffset; + + fileOffset += align(rdata->length(), fileAlignment); + sectionSize = fileSize = fileOfset; + + sections.headers.add(ImageSectionHeader::get(__TEXT_SEGMENT, map.code, ImageSectionHeader::SectionType::Text, + sectionSize, fileSize)); + + sections.items.add(sections.headers.count() + 1, { text, true }); + sections.items.add(sections.headers.count() + 1, { adata, false }); + sections.items.add(sections.headers.count() + 1, { mdata, false }); + sections.items.add(sections.headers.count() + 1, { mbdata, true }); + sections.items.add(sections.headers.count() + 1, { rdata, true }); + + // --- __DATA (data & stat) segment --- + sectionOffset = align(sectionOffset + sectionSize, sectionAlignment); + + map.dataSize += data->length(); + map.data = sectionOffset; + + map.dataSize += stat->length(); + map.stat = map.data + align(data->length(), fileAlignment); + + fileSize = 0; + sectionSize = align(stat->length(), fileAlignment) + align(data->length(), fileAlignment) + + sections.headers.add(ImageSectionHeader::get(__DATA_SEGMENT, map.data, ImageSectionHeader::SectionType::Data, + sectionSize, fileSize)); +} + +void MachOImageFormatter :: prepareImage(ImageProviderBase& provider, AddressSpace& map, ImageSections& sections, pos_t sectionAlignment, pos_t fileAlignment, bool withDebugInfo) { - // !! temporally stub + //MachOData data; + //fillElfData(provider, elfData, fileAlignment, map.importMapping); + + mapImage(provider, map, sections, sectionAlignment, fileAlignment/*, data*/); + + fixImage(provider, map, withDebugInfo); +} + +void MachOImageFormatter :: fixImage(ImageProviderBase& provider, AddressSpace& map, bool withDebugInfo) +{ + fixSection(provider.getTextSection(), map); + fixSection(provider.getRDataSection(), map); + fixSection(provider.getDataSection(), map); + fixSection(provider.getADataSection(), map); + fixSection(provider.getMDataSection(), map); + fixSection(provider.getMBDataSection(), map); + fixImportSection(provider.getImportSection(), map); + + // fix up debug info if enabled + if (withDebugInfo) { + fixSection(provider.getTargetDebugSection(), map); + } } diff --git a/elenasrc3/elc/macos/machoimage.h b/elenasrc3/elc/macos/machoimage.h index a42bdfb4e0..61158b752a 100644 --- a/elenasrc3/elc/macos/machoimage.h +++ b/elenasrc3/elc/macos/machoimage.h @@ -19,7 +19,7 @@ namespace elena_lang protected: ForwardResolverBase* _resolver; - //struct ElfData + //struct MachOData //{ // ReferenceMap functions; // LibraryList libraries; @@ -27,11 +27,11 @@ namespace elena_lang // pos_t dynamicOffset; // pos_t dynamicSize; - // ElfData() + //MachOData() // : functions(0), libraries(nullptr) - // { + //{ // dynamicOffset = dynamicSize = 0; - // } + // } //}; MachOImageFormatter(ForwardResolverBase* resolver) @@ -45,9 +45,9 @@ namespace elena_lang //virtual void fixSection(MemoryBase* section, AddressSpace& map) = 0; //virtual void fixImportSection(MemoryBase* section, AddressSpace& map) = 0; - //void mapImage(ImageProviderBase& provider, AddressSpace& map, ImageSections& sections, pos_t sectionAlignment, - // pos_t fileAlignment, ElfData& elfData); - //void fixImage(ImageProviderBase& provider, AddressSpace& map, bool withDebugInfo); + void mapImage(ImageProviderBase& provider, AddressSpace& map, ImageSections& sections, pos_t sectionAlignment, + pos_t fileAlignment/*, ElfData& elfData*/); + void fixImage(ImageProviderBase& provider, AddressSpace& map, bool withDebugInfo); public: void prepareImage(ImageProviderBase& provider, AddressSpace& map, ImageSections& sections, @@ -71,7 +71,6 @@ namespace elena_lang //void fillElfData(ImageProviderBase& provider, ElfData& elfData, pos_t fileAlignment, RelocationMap& importMapping) override; public: - }; } diff --git a/elenasrc3/elc/macos/macholinker.cpp b/elenasrc3/elc/macos/macholinker.cpp index cc5b3dee28..de84b347c1 100644 --- a/elenasrc3/elc/macos/macholinker.cpp +++ b/elenasrc3/elc/macos/macholinker.cpp @@ -10,8 +10,102 @@ using namespace elena_lang; -LinkResult MachOLinker :: run(ProjectBase& project, ImageProviderBase& provider, PlatformType, path_t) +void MachOLinker::writeSegments(ElfExecutableImage& image, FileWriter* file) { + for (auto it = image.imageSections.items.start(); !it.eof(); ++it) { + writeSection(file, (*it).section); + if ((*it).isAligned) + file->align(image.fileAlignment); + } + file->align(image.fileAlignment); +} + +bool MachOLinker :: createExecutable(MachOExecutableImage& image, path_t exePath) +{ + if (exePath.empty()) + _errorProcessor->raiseInternalError(errEmptyTarget); + + if (!PathUtil::recreatePath(/*nullptr, */exePath)) + return false; + + FileWriter executable(exePath, FileEncoding::Raw, false); + if (!executable.isOpen()) + return false; + + writeMachOHeader(image, &executable/*, ph_length */); + + // write commands + for (auto command_it = image.commands.start(); !command_it.eof(); ++command_it) { + Command* command = *command_it; + + file->write((char*)command, command->commandSize); + } + + // write sections + writeSegments(image, file); + + return true; +} + +void MachOLinker :: prepareCommands(MachOExecutableImage& image) +{ + pos_t fileOffset = 0; + for (auto it = image.addressMap.sections.headers.start(); !it.eof(); ++it) { + ImageSectionHeader header = *it; + + Command* command = createSegmentCommand(header, fileOffset); + image.commands.add(command); + + image.totalCommandSize += command->commandSize; + } +} + +void MachOLinker :: prepareMachOImage(MachOExecutableImage& image) +{ + image.flags |= Flags_NoUndefs; + //image.flags |= Flags_DyldLink; + //image.flags |= Flags_TwoLevel; + + NoUndefs, DyldLink, TwoLevel, PIE + + if (!image.sectionAlignment) + image.sectionAlignment = SECTION_ALIGNMENT; + + if (!image.fileAlignment) + image.fileAlignment = FILE_ALIGNMENT; + + image.addressMap.headerSize = SECTION_ALIGNMENT; + + _imageFormatter->prepareImage(provider, image.addressMap, image.imageSections, + image.sectionAlignment, + image.fileAlignment, + image.withDebugInfo); + + prepareCommands(image); +} + +LinkResult MachOLinker :: run(ProjectBase& project, ImageProviderBase& provider, PlatformType, path_t exeExtension) +{ + MachOExecutableImage image(withDebugMode); + + prepareMachOImage(/*provider, */image/*, calcHeaderSize()*/); + + PathString exePath(project.PathSetting(ProjectOption::TargetPath)); + exePath.changeExtension(exeExtension); + + if (!createExecutable(image, *exePath)) { + _errorProcessor->raisePathError(errCannotCreate, project.PathSetting(ProjectOption::TargetPath)); + } + + //if (withDebugMode) { + // PathString debugFilePath(*exePath); + // debugFilePath.changeExtension("dn"); + + // if (!createDebugFile(provider, image, *debugFilePath)) { + // _errorProcessor->raisePathError(errCannotCreate, *debugFilePath); + // } + //} + // !! temporal stub return {}; } \ No newline at end of file diff --git a/elenasrc3/elc/macos/macholinker.h b/elenasrc3/elc/macos/macholinker.h index f6a3cd1398..cc55408115 100644 --- a/elenasrc3/elc/macos/macholinker.h +++ b/elenasrc3/elc/macos/macholinker.h @@ -10,19 +10,60 @@ #define MACHOLINKER_H #include "clicommon.h" +#include "machocommon.h" namespace elena_lang { + struct Mach0ExecutableImage + { + unsigned int sectionAlignment; + unsigned int fileAlignment; + bool withDebugInfo; + int flags; + + AddressSpace addressMap; + + ImageSections imageSections; + + int totalCommandSize; + Commands commands; + + ElfExecutableImage(bool withDebugInfo) + : imageSections({}) + { + this->fileAlignment = this->sectionAlignment = 0; + this->flags = 0; + this->withDebugInfo = withDebugInfo; + this->totalCommandSize = 0; + } + }; + // --- ElfLinker --- class MachOLinker : public LinkerBase { protected: + ImageFormatter* _imageFormatter; + + virtual unsigned long getMagicNumber() = 0; + + virtual CPUType getCPUType() = 0; + virtual CPUSubType getCPUSubType() = 0; + + virtual Command* createSegmentCommand(ImageSectionHeader& header, pos_t& fileOffset) = 0; + + virtual void prepareMachOImage(MachOExecutableImage& image); + virtual void prepareCommands(MachOExecutableImage& image); + + virtual void writeMachOHeader(MachOExecutableImage& image, FileWriter* file) = 0; + virtual void writeSegments(ElfExecutableImage& image, FileWriter* file); + + bool createExecutable(MachOExecutableImage image, path_t exePath); public: LinkResult run(ProjectBase& project, ImageProviderBase& code, PlatformType uiType, path_t exeExtension) override; - MachOLinker(ErrorProcessorBase* errorProcessor/*, ImageFormatter* imageFormatter*/) + MachOLinker(ErrorProcessorBase* errorProcessor, ImageFormatter* imageFormatter) : LinkerBase(errorProcessor) { _imageFormatter = imageFormatter; diff --git a/elenasrc3/elc/macos/macholinker64.cpp b/elenasrc3/elc/macos/macholinker64.cpp index 4e9e44af8d..8f7fb5dda6 100644 --- a/elenasrc3/elc/macos/macholinker64.cpp +++ b/elenasrc3/elc/macos/macholinker64.cpp @@ -9,3 +9,51 @@ #include "macholinker64.h" using namespace elena_lang; + +// --- MachOLinker64 --- + +void MachOLinker64 :: writeMachOHeader(MachOExecutableImage& image, FileWriter* file) +{ + MachOHeader_64 header = {}; + + header.magic = getMagicNumber(); + header.cputype = getCPUType(); + header.cpusubtype = getCPUSubType(); + header.filetype = FILE_EXECUTABLE; + header.ncmds = image.commands.count_pos(); + header.sizeofcmds = image.totalCommandSize; + header.flags = image.flags; + + file->write((char*)&header, sizeof(MachOHeader_64)); +} + +Command* MachOLinker64 :: createSegmentCommand(ImageSectionHeader& header, pos_t& fileOffset) +{ + auto command = new SegmentCommand_64(); + + command->commandType = Command_Segment_64; + command->commandSize = sizeof(SegmentCommand_64); + strncpy(command->segname, header.name.str(), header.name.length() + 1); + command->vmaddr = header.vaddress; + command->vmsize = header.memorySize; + command->fileoff = fileOffset; + command->filesize = fileSize; + switch (header.type) { + case SectionType::Text: + command->intprot = command->maxprot = PROT_X | PROT_R; + break; + case SectionType::Data: + case SectionType::UninitializedData: + command->intprot = command->maxprot = PROT_R | PROT_W; + break; + case SectionType::RData: + command->intprot = command->maxprot = PROT_R; + break; + } + command->nsects = 0; + command->flags = 0; + + fileOffset += command->filesize; + + return command; +} diff --git a/elenasrc3/elc/macos/macholinker64.h b/elenasrc3/elc/macos/macholinker64.h index 6ee74b6e59..87221e7566 100644 --- a/elenasrc3/elc/macos/macholinker64.h +++ b/elenasrc3/elc/macos/macholinker64.h @@ -13,10 +13,58 @@ namespace elena_lang { - // --- ElfLinker --- + struct MachOHeader_64 + { + uint32_t magic; + + CPUType cputype; + + CPUSubType cpusubtype; + + uint32_t filetype; + + uint32_t ncmds; + + uint32_t sizeofcmds; + + uint32_t flags; + + uint32_t reserved; + }; + + struct SegmentCommand_64 : public Command + { + char segname[16]; /* segment name */ + + uint64_t vmaddr; /* memory address of this segment */ + + uint64_t vmsize; /* memory size of this segment */ + + uint64_t fileoff; /* file offset of this segment */ + + uint64_t filesize; /* amount to map from the file */ + + vm_prot_t maxprot; /* maximum VM protection */ + + vm_prot_t initprot; /* initial VM protection */ + + uint32_t nsects; /* number of sections in segment */ + + uint32_t flags; /* flags */ + }; + + // --- MachOLinker64 --- class MachOLinker64 : public MachOLinker { protected: + unsigned long getMagicNumber() override + { + return MH_MAGIC_64; + } + + Command* createSegmentCommand(ImageSectionHeader& header, pos_t& fileOffset) override; + + void writeMachOHeader(MachOExecutableImage& image, FileWriter* file) override; public: MachOLinker64(ErrorProcessorBase* errorProcessor/*, ImageFormatter* imageFormatter*/) diff --git a/elenasrc3/elc/messages.h b/elenasrc3/elc/messages.h index 46ad4b85f2..3275bd2a2b 100644 --- a/elenasrc3/elc/messages.h +++ b/elenasrc3/elc/messages.h @@ -116,6 +116,7 @@ namespace elena_lang {wrnReturningNillable, wrnMssgReturningNillable}, {errFailedMemoryAllocation, errMssgFailedMemoryAllocation}, {errMissingNamespace , errMsgMissingNamespace }, + { infoInternalDefConstructor , infoMsgInternalDefConstructor }, }; } diff --git a/elenasrc3/elc/project.cpp b/elenasrc3/elc/project.cpp index 8af43d90e9..7265a80832 100644 --- a/elenasrc3/elc/project.cpp +++ b/elenasrc3/elc/project.cpp @@ -95,9 +95,9 @@ PlatformType Project :: ThreadModeType() return _platform & PlatformType::ThreadMask; } -void Project :: addSource(ustr_t ns, path_t path, ustr_t target, ustr_t hints) +void Project :: addSource(ustr_t ns, path_t path, ustr_t target, ustr_t hints, bool singleFileMode) { - if (!_loaded && _projectName.empty()) + if (singleFileMode && _projectName.empty()) _projectName.copy(ns); ProjectNode files = _root.findChild(ProjectOption::Files); @@ -175,7 +175,7 @@ void Project :: loadSourceFiles(ConfigFile& config, ConfigFile::Node& configRoot node.readContent(path); PathString filePath(path.str()); - addSource(*ns, *filePath, target.str(), hints.str()); + addSource(*ns, *filePath, target.str(), hints.str(), false); } } } @@ -498,15 +498,38 @@ void Project :: loadProfileList(ConfigFile& config) // --- ProjectCollection --- -inline void loadModuleCollection(path_t collectionPath, ConfigFile::Collection& modules, XmlProjectBase::Paths& paths) +inline void loadModuleCollection(path_t collectionPath, ConfigFile::Collection& modules, + ProjectCollection::ProjectSpecs& projectSpecs) { DynamicString pathStr; + DynamicString basePathStr; + DynamicString profileStr; for (auto it = modules.start(); !it.eof(); ++it) { ConfigFile::Node node = *it; node.readContent(pathStr); - PathString fullPath(collectionPath, pathStr.str()); - paths.add((*fullPath).clone()); + ProjectCollection::ProjectSpec* spec = new ProjectCollection::ProjectSpec(); + spec->path = nullptr; + spec->basePath = nullptr; + spec->profile = nullptr; + + if (node.readAttribute(BASE_PATH_ATTR, basePathStr)) { + PathString fullPath(collectionPath, basePathStr.str()); + spec->basePath = (*fullPath).clone(); + + fullPath.combine(pathStr.str()); + spec->path = (*fullPath).clone(); + } + else { + PathString fullPath(collectionPath, pathStr.str()); + spec->path = (*fullPath).clone(); + } + + if (node.readAttribute(PROFILE_ATTR, profileStr)) { + spec->profile = ustr_t(profileStr.str()).clone(); + } + + projectSpecs.add(spec); } } @@ -519,7 +542,7 @@ bool ProjectCollection :: load(path_t path) if (config.load(path, _encoding)) { ConfigFile::Collection modules; if (config.select(COLLECTION_CATEGORY, modules)) { - loadModuleCollection(*collectionPath, modules, paths); + loadModuleCollection(*collectionPath, modules, projectSpecs); } else { ConfigFile::Collection collections; @@ -527,7 +550,7 @@ bool ProjectCollection :: load(path_t path) for (auto it = collections.start(); !it.eof(); ++it) { ConfigFile::Collection subModules; if (config.select(*it, "*", subModules)) { - loadModuleCollection(*collectionPath, subModules, paths); + loadModuleCollection(*collectionPath, subModules, projectSpecs); } } } diff --git a/elenasrc3/elc/project.h b/elenasrc3/elc/project.h index e76c82b6c7..3ac992dd26 100644 --- a/elenasrc3/elc/project.h +++ b/elenasrc3/elc/project.h @@ -92,7 +92,7 @@ namespace elena_lang void forEachForward(void* arg, void(* feedback)(void* arg, ustr_t key, ustr_t value)) override; - void addSource(ustr_t ns, path_t path, ustr_t target, ustr_t hints); + void addSource(ustr_t ns, path_t path, ustr_t target, ustr_t hints, bool singleFileMode); bool loadConfigByName(path_t configPath, ustr_t name, bool markAsLoaded); @@ -122,12 +122,34 @@ namespace elena_lang FileEncoding _encoding; public: - XmlProjectBase::Paths paths; + struct ProjectSpec + { + path_t path; + path_t basePath; + ustr_t profile; + + ProjectSpec() + : path(nullptr), basePath(nullptr), profile(nullptr) + { + + } + virtual ~ProjectSpec() + { + freepath(path); + freepath(basePath); + freeUStr(profile); + } + + }; + + typedef List ProjectSpecs; + + ProjectSpecs projectSpecs; bool load(path_t path); ProjectCollection() - : paths(nullptr) + : projectSpecs(nullptr) { _encoding = FileEncoding::UTF8; } diff --git a/elenasrc3/elc/separser.cpp b/elenasrc3/elc/separser.cpp index add287494c..e9c94752f5 100644 --- a/elenasrc3/elc/separser.cpp +++ b/elenasrc3/elc/separser.cpp @@ -50,6 +50,7 @@ ScriptParser :: ScriptParser() _InterpretFile = (void* (__cdecl*)(const char*, int, bool))_library->loadFunction("InterpretFileSMLA"); _GetStatus = (size_t(__cdecl*)(char*, size_t))_library->loadFunction("GetStatusSMLA"); _Release = (void(__cdecl*)(void*))_library->loadFunction("ReleaseSMLA"); + _ClearStack = (void(__cdecl*)())_library->loadFunction("ClearStackSMLA"); #else @@ -59,6 +60,7 @@ ScriptParser :: ScriptParser() *(void **)(&_InterpretFile) = _library->loadFunction("InterpretFileSMLA"); *(void **)(&_GetStatus) = _library->loadFunction("GetStatusSMLA"); *(void **)(&_Release) = _library->loadFunction("ReleaseSMLA"); + *(void**)(&_ClearStack) = _library->loadFunction("ClearStackSMLA"); #endif } @@ -123,3 +125,8 @@ void ScriptParser :: parse(path_t filePath, SyntaxTree& tree) _Release(tape); } } + +void ScriptParser :: clearStack() +{ + _ClearStack(); +} diff --git a/elenasrc3/elc/separser.h b/elenasrc3/elc/separser.h index 241a16d684..89d8a5ca9c 100644 --- a/elenasrc3/elc/separser.h +++ b/elenasrc3/elc/separser.h @@ -3,7 +3,7 @@ // // This header contains ELENA Script Engine Parser class declaration. // -// (C)2023, by Aleksey Rakov +// (C)2023-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef SEPARSER_H @@ -25,12 +25,15 @@ namespace elena_lang void* (*_InterpretFile)(const char* path, int encoding, bool autoDetect); size_t(*_GetStatus)(char* error, size_t maxLength); void(*_Release)(void* tape); + void(*_ClearStack)(); public: bool setOption(ustr_t option, path_t projectPath); void parse(path_t filePath, SyntaxTree& tree); + void clearStack(); + ScriptParser(); }; diff --git a/elenasrc3/elc/windows/elc.cpp b/elenasrc3/elc/windows/elc.cpp index d1240207bc..fa6ad33e10 100644 --- a/elenasrc3/elc/windows/elc.cpp +++ b/elenasrc3/elc/windows/elc.cpp @@ -112,7 +112,7 @@ void getAppPath(PathString& appPath) appPath.lower(); } -JITCompilerBase* createJITCompiler(LibraryLoaderBase* loader, PlatformType platform) +JITCompilerBase* createJITCompiler(PlatformType platform) { switch (platform) { case PlatformType::Win_x86: @@ -147,10 +147,15 @@ void handleOption(wchar_t* arg, IdentifierString& profile, Project& project, Com } int compileProject(int argc, wchar_t** argv, path_t appPath, ErrorProcessor& errorProcessor, - CompilingProcess& process) + path_t basePath = nullptr, ustr_t defaultProfile = nullptr) { bool cleanMode = false; + JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_STACKRESERV, 1, true, true }; + CompilingProcess process(appPath, L"exe", L"", L"", L"", + &Presenter::getInstance(), &errorProcessor, + VA_ALIGNMENT, defaultCoreSettings, createJITCompiler); + Project project(appPath, CURRENT_PLATFORM, &Presenter::getInstance()); WinLinker linker(&errorProcessor, &WinImageFormatter::getInstance(&project)); @@ -158,7 +163,7 @@ int compileProject(int argc, wchar_t** argv, path_t appPath, ErrorProcessor& err PathString configPath(appPath, DEFAULT_CONFIG); project.loadConfig(*configPath, nullptr, false); - IdentifierString profile; + IdentifierString profile(defaultProfile); for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { handleOption(argv[i], profile, project, process, @@ -189,10 +194,13 @@ int compileProject(int argc, wchar_t** argv, path_t appPath, ErrorProcessor& err else { FileNameString fileName(argv[i]); IdentifierString ns(*fileName); - project.addSource(*ns, argv[i], nullptr, nullptr); + project.addSource(*ns, argv[i], nullptr, nullptr, true); } } + if (!basePath.empty()) + project.setBasePath(basePath); + if (cleanMode) { return process.clean(project); } @@ -208,7 +216,7 @@ int compileProject(int argc, wchar_t** argv, path_t appPath, ErrorProcessor& err } int compileProjectCollection(int argc, wchar_t** argv, path_t path, path_t appPath, - ErrorProcessor& errorProcessor, CompilingProcess& process) + ErrorProcessor& errorProcessor) { Presenter* presenter = &Presenter::getInstance(); @@ -221,16 +229,18 @@ int compileProjectCollection(int argc, wchar_t** argv, path_t path, path_t appPa return ERROR_RET_CODE; } - for (auto it = collection.paths.start(); !it.eof(); ++it) { + for (auto it = collection.projectSpecs.start(); !it.eof(); ++it) { + auto spec = *it; + size_t destLen = FILENAME_MAX; wchar_t projectPath[FILENAME_MAX]; - StrConvertor::copy(projectPath, (*it).str(), (*it).length(), destLen); + StrConvertor::copy(projectPath, spec->path.str(), spec->path.length(), destLen); projectPath[destLen] = 0; argv[argc - 1] = projectPath; presenter->printPath(ELC_COMPILING_PROJECT, projectPath); - int result = compileProject(argc, argv, appPath, errorProcessor, process); + int result = compileProject(argc, argv, appPath, errorProcessor, spec->basePath, spec->profile); if (result == ERROR_RET_CODE) { return ERROR_RET_CODE; } @@ -249,13 +259,9 @@ int main() PathString appPath; getAppPath(appPath); - JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_STACKRESERV, 1, true, true }; ErrorProcessor errorProcessor(&Presenter::getInstance()); - CompilingProcess process(*appPath, L"exe", L"", L"", L"", - &Presenter::getInstance(), &errorProcessor, - VA_ALIGNMENT, defaultCoreSettings, createJITCompiler); - process.greeting(); + CompilingProcess::greeting(&Presenter::getInstance()); // Reading command-line arguments... int argc; @@ -273,9 +279,9 @@ int main() } else if (argv[argc - 1][0] != '-' && PathUtil::checkExtension(argv[argc - 1], "prjcol")) { retVal = compileProjectCollection(argc, argv, argv[argc - 1], - *appPath, errorProcessor, process); + *appPath, errorProcessor); } - else retVal = compileProject(argc, argv, *appPath, errorProcessor, process); + else retVal = compileProject(argc, argv, *appPath, errorProcessor); #ifdef TIME_RECORDING finish = clock(); diff --git a/elenasrc3/elc/windows/ntlinker.cpp b/elenasrc3/elc/windows/ntlinker.cpp index 606858524d..8013ad016d 100644 --- a/elenasrc3/elc/windows/ntlinker.cpp +++ b/elenasrc3/elc/windows/ntlinker.cpp @@ -47,7 +47,7 @@ void WinNtLinker :: writeExecutableHeader(WinNtExecutableImage& image, FileWrite header.PointerToSymbolTable = 0; header.NumberOfSymbols = 0; header.Machine = image.machine; - header.SizeOfOptionalHeader = image.optionalHeaderSize; + header.SizeOfOptionalHeader = (WORD)image.optionalHeaderSize; executable.write(&header, IMAGE_SIZEOF_FILE_HEADER); } diff --git a/elenasrc3/elena-tests/bt_optimization.h b/elenasrc3/elena-tests/bt_optimization.h index f6268a0fdf..4da9d7e616 100644 --- a/elenasrc3/elena-tests/bt_optimization.h +++ b/elenasrc3/elena-tests/bt_optimization.h @@ -125,7 +125,7 @@ namespace elena_lang class VariadicRuntimeSingleDispatch : public MethodScenarioTest { protected: - SyntaxNode findTargetNode() override; + SyntaxNode findTargetNode(int scenario) override; void SetUp() override; }; @@ -152,7 +152,7 @@ namespace elena_lang void SetUp() override; public: - void runTest(bool withVariadic); + void runTest(bool withVariadic, int scenario = 0); }; class CallMethodWithoutTarget : public MethodCallTest @@ -190,7 +190,7 @@ namespace elena_lang void SetUp() override; public: - void runTest(); + void runTest(int scenario = 0); }; class Lambda_CallingPrivateMethod : public LambdaTest @@ -208,7 +208,7 @@ namespace elena_lang void SetUp() override; public: - void runTest(bool exceptionExpected = false); + void runTest(bool exceptionExpected = false, int scenario = 0); }; class NillableIntAssigning : public IntOperation diff --git a/elenasrc3/elena-tests/compile_tests.h b/elenasrc3/elena-tests/compile_tests.h index 6c7e6c2764..18d54cd1ec 100644 --- a/elenasrc3/elena-tests/compile_tests.h +++ b/elenasrc3/elena-tests/compile_tests.h @@ -43,6 +43,15 @@ namespace elena_lang protected: void SetUp() override; }; + + class ByRefHandlerTest : public MethodScenarioTest + { + protected: + BuildNode getExpectedOutput(BuildNode node, int scenario) override; + SyntaxNode findTargetNode(int scenario) override; + + void SetUp() override; + }; } #endif diff --git a/elenasrc3/elena-tests/constructor_tests.h b/elenasrc3/elena-tests/constructor_tests.h index 37265a8ebf..c102c86b9a 100644 --- a/elenasrc3/elena-tests/constructor_tests.h +++ b/elenasrc3/elena-tests/constructor_tests.h @@ -21,7 +21,7 @@ namespace elena_lang class CallPrivateConstructorDirectly : public MethodScenarioTest { protected: - SyntaxNode findTargetNode() override; + SyntaxNode findTargetNode(int scenario) override; void SetUp() override; }; diff --git a/elenasrc3/elena-tests/scenario_consts.h b/elenasrc3/elena-tests/scenario_consts.h index 9b5152db84..8a034a1474 100644 --- a/elenasrc3/elena-tests/scenario_consts.h +++ b/elenasrc3/elena-tests/scenario_consts.h @@ -17,3 +17,5 @@ constexpr auto S1_VariadicTemplates = " class (attribute -2147467263 ()attribute constexpr auto Tester_2Args = "class (attribute -2147467263 ()attribute -2147479546 () nameattr (identifier \"Tester\" ()) method (nameattr (identifier \"testArg2\" ()) parameter (nameattr (identifier \"arg1\" ())) parameter (nameattr (identifier \"arg2\" ())) code ()))"; constexpr auto IndexedClass_Scenario1 = "class (attribute -2147479545 ()nameattr 67 (identifier \"X\" ())method (type (identifier \"IntNumber\" ())nameattr (identifier \"calc\" ())parameter (type (identifier \"IntNumber\" ())nameattr (identifier \"arg\" ()))returning ())) class (attribute -2147479546 ()nameattr (identifier \"Y\" ())parent (type (identifier \"X\" ())))"; + +constexpr auto S_ByRefHandlerTest_Class = "class (attribute -2147479551 (identifier \"class\" ())nameattr (identifier \"A\" ()) method (type (identifier \"IntNumber\" ()) nameattr (identifier \"incSum\" ()) parameter (type (identifier \"IntNumber\" ()) nameattr (identifier \"arg1\" ()))returning (expression (add_operation (object (identifier \"arg1\" ())expression (object (integer \"1\" ())))))))"; diff --git a/elenasrc3/elena-tests/tests_bt.cpp b/elenasrc3/elena-tests/tests_bt.cpp index 8b360621c7..0d5b627e0f 100644 --- a/elenasrc3/elena-tests/tests_bt.cpp +++ b/elenasrc3/elena-tests/tests_bt.cpp @@ -3,6 +3,27 @@ using namespace elena_lang; +/* +* BTOptimization1_1 +* ------------- +* +* BTOptimization1_2 +* ----------------- +* +* BTOptimization1_3 +* ----------------* +* +* BTOptimization1_4 +* ----------------- +* +* BTOptimization2 +* --------------- +* +* BTOptimization4 +* --------------- +* +*/ + TEST_F(BTOptimization1_1, BuildTapeTest) { runBTTest(); diff --git a/elenasrc3/elena-tests/tests_bt_optimization.cpp b/elenasrc3/elena-tests/tests_bt_optimization.cpp index 4fd1984f70..04f62594b2 100644 --- a/elenasrc3/elena-tests/tests_bt_optimization.cpp +++ b/elenasrc3/elena-tests/tests_bt_optimization.cpp @@ -64,7 +64,7 @@ constexpr auto BuildTree1_1 = "byrefmark -8 () local_address -8 () saving_stack constexpr auto BuildTree1_2 = "byrefmark -8 () local_address -8 () saving_stack 1 () class_reference 4 () saving_stack () argument () direct_call_op 2434 (type 4 ()) local_address -8 () copying -4 (size 4 ())"; constexpr auto BuildTree1_4 = "byrefmark -8 () local_address -8 () saving_stack 2 () int_literal 2 (value 0 ()) saving_stack 1() class_reference 4 () saving_stack () argument () direct_call_op 3331 (type 4 ()) local_address -8 () copying -4 (size 4 ())"; constexpr auto BuildTree2 = "int_literal 2 (value 2 ()) copying -4 ( size 4 ())"; -constexpr auto BuildTree4 = "int_literal 2 (value 3 ())copying -4 (size 4 ())local_address -4 ()saving_stack ()int_literal 3 (value 2 ())saving_stack 1 ()intop 4 (index -12 ())local_address -12 ()copying -8 (size 4 ())"; +constexpr auto BuildTree4 = "int_literal 2 (value 3 ())copying -4 (size 4 ())local_address -4 ()saving_stack ()int_literal 3 (value 2 ())saving_stack 1 ()intop -12 (operator_id 4 ())local_address -12 ()copying -8 (size 4 ())"; constexpr auto OptimizedBuildTree1_1 = "local_address -4 () saving_stack 1 () class_reference 4 () saving_stack () argument () direct_call_op 2306 (type 4 ()) local_address -4 ()"; constexpr auto OptimizedBuildTree1_2 = "local_address -4 () saving_stack 1 () class_reference 4 () saving_stack () argument () direct_call_op 2434 (type 4 ()) local_address -4 ()"; @@ -72,7 +72,7 @@ constexpr auto OptimizedBuildTree1_4 = "local_address -4 () saving_stack 2 () in constexpr auto OptimizedBuildTree2 = "saving_int - 4 (size 4 ()value 2 ())"; constexpr auto OptimizedBuildTree4 = "saving_int -4 (size 4 ()value 3 ())local_address -4 ()copying -8 (size 4 ())addingint -8 (value 2 ())"; -constexpr auto BuildTree_VariadicSingleDispatch_1 = "tape(sealed_dispatching 11 (message 3138 ()) open_frame() assigning 1 () local_reference -2 () saving_stack() varg_sop 6 (index -4 ()) unbox_call_message -2 (index 1 () length -4 () temp_var -8 () message 1217 ()) local 1 () saving_stack() argument() direct_call_op 2626 (type 5 ()) loading_index() free_varstack() close_frame() exit()) reserved 3 ()reserved_n 8 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_1 = "tape(sealed_dispatching 11 (message 3138 ()) open_frame() assigning 1 () local_reference -2 () saving_stack() varg_sop -4 (operator_id 6 ()) unbox_call_message -2 (value 1 () length -4 () temp_var -8 () message 1217 ()) local 1 () saving_stack() argument() direct_call_op 2626 (type 5 ()) loading_index -4() free_varstack() close_frame() exit()) reserved 3 ()reserved_n 8 ())"; constexpr auto BuildTree_VariadicSingleDispatch_2 = "tape(open_frame() assigning 1 () class_reference 2 () direct_call_op 544 (type 10 ()) assigning 2 () class_reference 8 () direct_call_op 544 (type 15 ()) assigning 3 () local 2 () saving_stack() argument() call_op 1217 () assigning 4 () local 3 () saving_stack() argument() call_op 1217 () assigning 5 () terminator() saving_stack 3 () local 5 () saving_stack 2 () local 4 () saving_stack 1 () class_reference 5 () saving_stack() argument() direct_call_op 2626 (type 5 ()) local 1 () close_frame() exit()) reserved 9 ()"; constexpr auto BuildTree_VariadicSingleDispatch_4 = "tape (open_frame ()assigning 1 ()class_reference 8 ()direct_call_op 544 (type 16 ())assigning 2 ()class_reference 9 ()direct_call_op 544 (type 17 ())assigning 3 ()terminator ()saving_stack 3 ()local 3 ()saving_stack 2 ()local 2 ()saving_stack 1 ()class_reference 7 ()saving_stack ()argument ()direct_call_op 3650 (type 7 ())local 1 ()close_frame ()exit ())reserved 7 ())"; @@ -96,7 +96,7 @@ constexpr auto BuildTree1_1 = "byrefmark -24 () local_address -24 () saving_stac constexpr auto BuildTree1_2 = "byrefmark -24 () local_address -24 () saving_stack 1 () class_reference 4 () saving_stack () argument () direct_call_op 2434 (type 4 ()) local_address -24 () copying -8 (size 4 ())"; constexpr auto BuildTree1_4 = "byrefmark -24 () local_address -24 () saving_stack 2 () int_literal 2 (value 0 ()) saving_stack 1() class_reference 4 () saving_stack () argument () direct_call_op 3331 (type 4 ()) local_address -24 () copying -8 (size 4 ())"; constexpr auto BuildTree2 = "int_literal 2 (value 2 ()) copying -8 ( size 4 ())"; -constexpr auto BuildTree4 = "int_literal 2 (value 3 ())copying -8 (size 4 ())local_address -8 ()saving_stack ()int_literal 3 (value 2 ())saving_stack 1 ()intop 4 (index -40 ())local_address -40 ()copying -24 (size 4 ())"; +constexpr auto BuildTree4 = "int_literal 2 (value 3 ())copying -8 (size 4 ())local_address -8 ()saving_stack ()int_literal 3 (value 2 ())saving_stack 1 ()intop -40 (operator_id 4 ())local_address -40 ()copying -24 (size 4 ())"; constexpr auto OptimizedBuildTree1_1 = "local_address -8 () saving_stack 1 () class_reference 4 () saving_stack () argument () direct_call_op 2306 (type 4 ()) local_address -8 ()"; constexpr auto OptimizedBuildTree1_2 = "local_address -8 () saving_stack 1 () class_reference 4 () saving_stack () argument () direct_call_op 2434 (type 4 ()) local_address -8 ()"; @@ -104,7 +104,7 @@ constexpr auto OptimizedBuildTree1_4 = "local_address -8 () saving_stack 2 () in constexpr auto OptimizedBuildTree2 = "saving_int - 8 (size 4 ()value 2 ())"; constexpr auto OptimizedBuildTree4 = "saving_int -8 (size 4 ()value 3 ())local_address -8 ()copying -24 (size 4 ())addingint -24 (value 2 ())"; -constexpr auto BuildTree_VariadicSingleDispatch_1 = "tape(sealed_dispatching 11 (message 3138 ()) open_frame() assigning 1 () local_reference -2 () saving_stack() varg_sop 6 (index -8 ()) unbox_call_message -2 (index 1 () length -8 () temp_var -24 () message 1217 ()) local 1 () saving_stack() argument() direct_call_op 2626 (type 5 ()) loading_index() free_varstack() close_frame() exit()) reserved 4 ()reserved_n 32 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_1 = "tape(sealed_dispatching 11 (message 3138 ()) open_frame() assigning 1 () local_reference -2 () saving_stack() varg_sop -8 (operator_id 6 ()) unbox_call_message -2 (value 1 () length -8 () temp_var -24 () message 1217 ()) local 1 () saving_stack() argument() direct_call_op 2626 (type 5 ()) loading_index -8() free_varstack() close_frame() exit()) reserved 4 ()reserved_n 32 ())"; constexpr auto BuildTree_VariadicSingleDispatch_2 = "tape(open_frame() assigning 1 () class_reference 2 () direct_call_op 544 (type 10 ()) assigning 2 () class_reference 8 () direct_call_op 544 (type 15 ()) assigning 3 () local 2 () saving_stack() argument() call_op 1217 () assigning 4 () local 3 () saving_stack() argument() call_op 1217 () assigning 5 () terminator() saving_stack 3 () local 5 () saving_stack 2 () local 4 () saving_stack 1 () class_reference 5 () saving_stack() argument() direct_call_op 2626 (type 5 ()) local 1 () close_frame() exit()) reserved 10 ()"; constexpr auto BuildTree_VariadicSingleDispatch_4 = "tape (open_frame ()assigning 1 ()class_reference 8 ()direct_call_op 544 (type 16 ())assigning 2 ()class_reference 9 ()direct_call_op 544 (type 17 ())assigning 3 ()terminator ()saving_stack 3 ()local 3 ()saving_stack 2 ()local 2 ()saving_stack 1 ()class_reference 7 ()saving_stack ()argument ()direct_call_op 3650 (type 7 ())local 1 ()close_frame ()exit ())reserved 8 ())"; @@ -145,16 +145,16 @@ void BTOptimization :: SetUp() void BTOptimization :: runBTTest() { // Arrange - ByteCodeWriter::BuildTreeOptimizer buildTreeOptimizer; + ByteCodeWriter::BuildTreeAnalyzer buildTreeAnalyzer; MemoryReader reader(&btRules); - buildTreeOptimizer.load(reader); + buildTreeAnalyzer.load(reader); BuildTree output; BuildTreeWriter writer(output); BuildTree::copyNode(writer, buildNode, true); // Act - buildTreeOptimizer.proceed(output.readRoot()); + buildTreeAnalyzer.proceed(output.readRoot()); // Assess bool matched = BuildTree::compare(output.readRoot(), afterOptimization, true); @@ -373,7 +373,7 @@ void PrimitiveStructAlignment:: SetUp() // --- VariadicRuntimeSingleDispatch --- -SyntaxNode VariadicRuntimeSingleDispatch :: findTargetNode() +SyntaxNode VariadicRuntimeSingleDispatch :: findTargetNode(int) { return findAutoGenerated(findClassNode()); } @@ -386,7 +386,7 @@ void VariadicRuntimeSingleDispatch :: SetUp() BuildTreeSerializer::load(BuildTree_VariadicSingleDispatch_1, controlOutputNode); - argArrayRef = 0x80; + argArrayTemplateRef = 0x80; genericVargRef = 3; targetVargRef = 4; targetRef = 5; @@ -403,7 +403,7 @@ void VariadicCompiletimeSingleDispatch :: SetUp() BuildTreeSerializer::load(BuildTree_VariadicSingleDispatch_2, controlOutputNode); - argArrayRef = 0x80; + argArrayTemplateRef = 0x80; genericVargRef = 3; targetVargRef = 4; targetRef = 7; @@ -420,7 +420,7 @@ void VariadicCompiletimeSingleDispatch_WithDifferentArgs :: SetUp() BuildTreeSerializer::load(BuildTree_VariadicSingleDispatch_4, controlOutputNode); - argArrayRef = 0x80; + argArrayTemplateRef = 0x80; genericVargRef = 3; targetVargRef = 4; targetRef = 5; @@ -434,7 +434,7 @@ void MethodCallTest :: SetUp() ScenarioTest::SetUp(); } -void MethodCallTest :: runTest(bool withVariadic) +void MethodCallTest :: runTest(bool withVariadic, int scenario) { // Arrange ModuleScopeBase* moduleScope = env.createModuleScope(true); @@ -465,7 +465,7 @@ void MethodCallTest :: runTest(bool withVariadic) classHelper.load(); Compiler::Method methodHelper(classHelper); - SyntaxNode methodNode = findTargetNode(); + SyntaxNode methodNode = findTargetNode(scenario); if (methodNode != SyntaxKey::None) methodHelper.compile(writer, methodNode); @@ -553,7 +553,7 @@ void LambdaTest :: SetUp() controlOutputNode = buildTree.readRoot().appendChild(BuildKey::Idle); } -void LambdaTest :: runTest() +void LambdaTest :: runTest(int scenario) { // Arrange ModuleScopeBase* moduleScope = env.createModuleScope(true, true); @@ -581,7 +581,7 @@ void LambdaTest :: runTest() classHelper.load(); Compiler::Method methodHelper(classHelper); - SyntaxNode methodNode = findTargetNode(); + SyntaxNode methodNode = findTargetNode(scenario); if (methodNode != SyntaxKey::None) { writer.newNode(BuildKey::Root); writer.newNode(BuildKey::Class); @@ -620,7 +620,7 @@ void IntOperation :: SetUp() ScenarioTest::SetUp(); } -void IntOperation :: runTest(bool exceptionExpected) +void IntOperation :: runTest(bool exceptionExpected, int scenario) { // Arrange ModuleScopeBase* moduleScope = env.createModuleScope(true); @@ -647,7 +647,7 @@ void IntOperation :: runTest(bool exceptionExpected) classHelper.load(); Compiler::Method methodHelper(classHelper); - SyntaxNode methodNode = findTargetNode(); + SyntaxNode methodNode = findTargetNode(scenario); int catchedError = 0; if (methodNode != SyntaxKey::None) { try diff --git a/elenasrc3/elena-tests/tests_build.cpp b/elenasrc3/elena-tests/tests_build.cpp index 1418e7e565..37ebc3ccd4 100644 --- a/elenasrc3/elena-tests/tests_build.cpp +++ b/elenasrc3/elena-tests/tests_build.cpp @@ -1,3 +1,61 @@ +/* +* BTOptimization1_1 +* ------------- +* +* BTOptimization1_2 +* ----------------- +* +* BTOptimization1_3 +* ----------------* +* +* BTOptimization1_4 +* ----------------- +* +* BTOptimization2 +* --------------- +* +* BTOptimization4 +* --------------- +* +* StructAlignment +* --------------- +* +* PackedStructAlignment +* --------------------- +* +* VariadicRuntimeSingleDispatch +* ----------------------------- +* +* VariadicCompiletimeSingleDispatch +* --------------------------------- +* +* CallMethodWithoutTarget +* ----------------------- +* +* CallVariadocMethodWithoutTarget +* ------------------------------- +* +* CallMethodWithSignatureOfSuperClass +* ----------------------------------- +* +* CallMethodWithNil +* ----------------- +* +* VariadicCompiletimeSingleDispatch_WithDifferentArgs +* --------------------------------------------------- +* +* Lambda_CallingPrivateMethod +* --------------------------- +* +* IntAssigningNil +* --------------- +* +* NillableIntAssigning +* -------------------- +* +*/ + + #include "pch.h" // ------------------------------------------------ #include "bt_optimization.h" diff --git a/elenasrc3/elena-tests/tests_common.cpp b/elenasrc3/elena-tests/tests_common.cpp index 9e141d7d81..ad197e0367 100644 --- a/elenasrc3/elena-tests/tests_common.cpp +++ b/elenasrc3/elena-tests/tests_common.cpp @@ -2,7 +2,7 @@ // E L E N A P r o j e c t: ELENA Compiler // // This header contains ELENA Test Common implementation -// (C)2024, by Aleksey Rakov +// (C)2024-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "pch.h" @@ -392,7 +392,7 @@ void elena_lang::getAppPath(PathString& appPath) // --- ScenarioTest --- -SyntaxNode ScenarioTest::findTargetNode() +SyntaxNode ScenarioTest::findTargetNode(int) { return findClassNode().findChild(SyntaxKey::Method); } @@ -427,13 +427,25 @@ void CompileTest :: SetUp() // --- MethodScenarioTest --- -void MethodScenarioTest :: runTest(bool withProtectedConstructor, bool withAttributes) +void MethodScenarioTest :: runTest(bool withProtectedConstructor, bool withAttributes, int syntaxScenario, int buildScrenario) { // Arrange ModuleScopeBase* moduleScope = env.createModuleScope(true, withAttributes); moduleScope->buildins.superReference = 1; moduleScope->buildins.intReference = intNumberRef; - moduleScope->buildins.argArrayTemplateReference = argArrayRef; + + if (argArrayTemplateRef != INVALID_REF) { + moduleScope->buildins.argArrayTemplateReference = argArrayTemplateRef; + + env.setUpTemplateMockup(argArrayTemplateRef, 1, genericVargRef); + env.setUpTemplateMockup(argArrayTemplateRef, 2, targetVargRef); + } + if (byRefTemplateRef != INVALID_REF) { + moduleScope->buildins.wrapperTemplateReference = byRefTemplateRef; + + env.setUpTemplateMockup(byRefTemplateRef, intNumberRef, intByRefRef); + } + moduleScope->buildins.constructor_message = encodeMessage(moduleScope->module->mapAction(CONSTRUCTOR_MESSAGE, 0, false), 0, FUNCTION_MESSAGE); @@ -442,12 +454,11 @@ void MethodScenarioTest :: runTest(bool withProtectedConstructor, bool withAttri encodeMessage(moduleScope->module->mapAction(CONSTRUCTOR_MESSAGE2, 0, false), 0, FUNCTION_MESSAGE); - env.setUpTemplateMockup(argArrayRef, 1, genericVargRef); - env.setUpTemplateMockup(argArrayRef, 2, targetVargRef); Compiler* compiler = env.createCompiler(); BuildTree output; BuildTreeWriter writer(output); + writer.newNode(BuildKey::Root); Compiler::Namespace nsScope(compiler, moduleScope, TestErrorProcessor::getInstance(), nullptr, nullptr); // Act @@ -457,7 +468,7 @@ void MethodScenarioTest :: runTest(bool withProtectedConstructor, bool withAttri classHelper.load(); Compiler::Method methodHelper(classHelper); - SyntaxNode methodNode = findTargetNode(); + SyntaxNode methodNode = findTargetNode(syntaxScenario); if (methodNode == SyntaxKey::Method) { methodHelper.compile(writer, methodNode); } @@ -468,8 +479,11 @@ void MethodScenarioTest :: runTest(bool withProtectedConstructor, bool withAttri methodHelper.compileConstructor(writer, methodNode, classClassHelper); } + writer.closeNode(); + // Assess - bool matched = BuildTree::compare(output.readRoot(), controlOutputNode, true); + bool matched = BuildTree::compare(getExpectedOutput(output.readRoot().firstChild(), buildScrenario), + getExpectedOutput(controlOutputNode, buildScrenario), !checkTargetMessage); EXPECT_TRUE(matched); freeobj(compiler); diff --git a/elenasrc3/elena-tests/tests_common.h b/elenasrc3/elena-tests/tests_common.h index 7b1facf0f1..3db0d67d4a 100644 --- a/elenasrc3/elena-tests/tests_common.h +++ b/elenasrc3/elena-tests/tests_common.h @@ -178,6 +178,7 @@ namespace elena_lang { static TestTemplateProssesor instance; if (mapping) { + instance._mapping.clear(); for (auto it = mapping->start(); !it.eof(); ++it) { instance._mapping.add(it.key(), *it); } @@ -232,8 +233,13 @@ namespace elena_lang ref_t targetRef; + virtual BuildNode getExpectedOutput(BuildNode node, int) + { + return node; + } + virtual SyntaxNode findClassNode(); - virtual SyntaxNode findTargetNode(); + virtual SyntaxNode findTargetNode(int scenario); void SetUp() override; }; @@ -266,15 +272,31 @@ namespace elena_lang class MethodScenarioTest : public ScenarioTest { protected: + bool checkTargetMessage; + + ref_t argArrayTemplateRef; + ref_t byRefTemplateRef; + ref_t genericVargRef; ref_t targetVargRef; - ref_t argArrayRef; ref_t intNumberRef; + ref_t intByRefRef; SyntaxNode findAutoGenerated(SyntaxNode classNode); public: - void runTest(bool withProtectedConstructor = false, bool withAttributes = false); + void runTest(bool withProtectedConstructor = false, bool withAttributes = false, int syntaxScenario = 0, int buildScrenario = 0); + + MethodScenarioTest() + { + checkTargetMessage = false; + + argArrayTemplateRef = INVALID_REF; + byRefTemplateRef = INVALID_REF; + + genericVargRef = targetVargRef = intNumberRef = 0; + intByRefRef = 0; + } }; void getAppPath(PathString& appPath); diff --git a/elenasrc3/elena-tests/tests_compile.cpp b/elenasrc3/elena-tests/tests_compile.cpp index 2da7d41b0c..a773609089 100644 --- a/elenasrc3/elena-tests/tests_compile.cpp +++ b/elenasrc3/elena-tests/tests_compile.cpp @@ -1,3 +1,52 @@ +/* +* AccessPrivateFieldTest: +* ---------------------- +* +* AccessParentPrivateFieldTest: +* ----------------------------- +* +* CallingIndexedMethodTest: +* ------------------------- +* +* interface X +* { +* int calc(int arg) +* = arg + 2; +* } +* +* singleton Y : X {} +* { +* int ret := Y.calc(3); // Must be indexed call +* } +* +* DuplicateBoxingTest: +* -------------------- +* int x : = 2; +* Helper.testArg2({ ^ x }, { ^ x }); +* +* GeneratingByRefHandler +* ---------------------- +* check if ByRefHandler was properly generated +* +* class A +* { +* int incSum(int arg1) +* = arg1 + 1; +* } +* +* GeneratingByRefHandlerInvoker +* ----------------------------- +* check if ByRefHandlerInvoker was properly generated +* +* class A +* { +* int incSum(int arg1) +* = arg1 + 1; +* } +* +* +*/ + #include "pch.h" // ------------------------------------------------ #include "serializer.h" @@ -20,11 +69,16 @@ constexpr auto DuplicateBoxing_Scenario1 = "expression (code (expression (assign constexpr auto Build_CallingIndexedethodFromSealed_Scenario1 = "byrefmark -8 () local_address -8 () saving_stack 2() int_literal 2 (value 3 ())saving_stack 1 ()class_reference 5 ()saving_stack ()argument ()semi_direct_call_op 4355 (type 5 ()index_table_mode ())local_address -8 ()copying -4 (size 4 ())"; constexpr auto Build_DuplicateBoxing_Scenario1 = "int_literal 2 (value 2 ()) copying -4 (size 4 ())local_address -4 ()saving_stack ()create_struct 4 (type 2 ())copying_to_acc 1 (size 4 ())assigning 1 ()create_class 1 (type 6 ())assign_local_to_stack 1 ()set_imm_field ()assigning 2 ()create_class 1 (type 7 ())assign_local_to_stack 1 ()set_imm_field ()assigning 3 ()local 3 ()saving_stack 2 ()local 2 ()saving_stack 1 ()class_reference 3 ()saving_stack ()argument ()direct_call_op 2051 (type 3 ())"; + +constexpr auto Build_S_ByRefHandlerTest_Class = "class 4 (method 4867 (tape ( open_frame () assigning 1 () local -2 () saving_stack () int_literal 2 (value 1 ())saving_stack 1 ()intop -4 (operator_id 4 ())local_address -4 ()saving_stack ()local -3 ()copying_to_acc -3 (size 4 ()) going_to_eop ()close_frame ()exit ())reserved 3 ()reserved_n 4 ())method 3074 (tape (open_frame ()assigning 1 ()local_address -4 ()saving_stack 2 ()local -2 ()saving_stack 1 ()local 1 ()saving_stack ()argument ()semi_direct_call_op 4867 (type 4 ()index_table_mode ())local_address -4 ()saving_stack ()create_struct 4 (type 2 ())copying_to_acc 2 (size 4 ())assigning 2 ()local 2 ()close_frame ()exit ())reserved 5 ()reserved_n 4 ()))"; + #elif _M_X64 constexpr auto Build_CallingIndexedethodFromSealed_Scenario1 = "byrefmark -24 () local_address -24 () saving_stack 2() int_literal 2 (value 3 ())saving_stack 1 ()class_reference 5 ()saving_stack ()argument ()semi_direct_call_op 4355 (type 5 ()index_table_mode ())local_address -24 ()copying -8 (size 4 ())"; constexpr auto Build_DuplicateBoxing_Scenario1 = "int_literal 2 (value 2 ()) copying -8 (size 4 ())local_address -8 ()saving_stack ()create_struct 4 (type 2 ())copying_to_acc 1 (size 4 ())assigning 1 ()create_class 1 (type 6 ())assign_local_to_stack 1 ()set_imm_field ()assigning 2 ()create_class 1 (type 7 ())assign_local_to_stack 1 ()set_imm_field ()assigning 3 ()local 3 ()saving_stack 2 ()local 2 ()saving_stack 1 ()class_reference 3 ()saving_stack ()argument ()direct_call_op 2051 (type 3 ())"; +constexpr auto Build_S_ByRefHandlerTest_Class = "class 4 (method 4867 (tape ( open_frame () assigning 1 () local -2 () saving_stack () int_literal 2 (value 1 ())saving_stack 1 ()intop -8 (operator_id 4 ())local_address -8 ()saving_stack ()local -3 ()copying_to_acc -3 (size 4 ()) going_to_eop ()close_frame ()exit ())reserved 4 ()reserved_n 16 ())method 3074 (tape (open_frame ()assigning 1 ()local_address -8 ()saving_stack 2 ()local -2 ()saving_stack 1 ()local 1 ()saving_stack ()argument ()semi_direct_call_op 4867 (type 4 ()index_table_mode ())local_address -8 ()saving_stack ()create_struct 4 (type 2 ())copying_to_acc 2 (size 4 ())assigning 2 ()local 2 ()close_frame ()exit ())reserved 6 ()reserved_n 16 ()))"; + #endif // --- CompileScenarioTest --- @@ -104,19 +158,7 @@ TEST_F(AccessPrivateField, AccessParentPrivateFieldTest) // --- CallingIndexedethodFromSealed --- -/* -interface X -{ - int calc(int arg) - = arg + 2; -} -singleton Y : X {} - -{ - int ret := Y.calc(3); // Must be indexed call -} -*/ void CallingIndexedMethodFromSealed::SetUp() { ExprTest::SetUp(); @@ -133,10 +175,6 @@ TEST_F(CallingIndexedMethodFromSealed, CallingIndexedMethodTest) } // --- DuplicateBoxingTest --- -/* - int x : = 2; - Helper.testArg2({ ^ x }, { ^ x }); -*/ void DuplicateBoxingTest :: SetUp() { @@ -151,4 +189,71 @@ void DuplicateBoxingTest :: SetUp() TEST_F(DuplicateBoxingTest, DuplicateBoxingTest) { runBuildTest(true, false, 1); -} \ No newline at end of file +} + +// --- GeneratingByRefHandler --- + +void ByRefHandlerTest :: SetUp() +{ + checkTargetMessage = true; + byRefTemplateRef = 0x80; + + intNumberRef = 2; + intByRefRef = 3; + + targetRef = 4; + + MethodScenarioTest::SetUp(); + + LoadDeclarationScenario(S_DefaultNamespace_2, S_IntNumber, S_IntRefeference, S_ByRefHandlerTest_Class); + + BuildTreeSerializer::load(Build_S_ByRefHandlerTest_Class, controlOutputNode); +} + +BuildNode ByRefHandlerTest::getExpectedOutput(BuildNode node, int scenario) +{ + if (scenario <= 0) + return {}; + + BuildNode current = node != BuildKey::Method ? node.firstChild().firstChild() : node; + while (current != BuildKey::None) { + scenario--; + if (!scenario) + return current; + + current = current.nextNode(); + } + + return {}; +} + +SyntaxNode ByRefHandlerTest :: findTargetNode(int scenario) +{ + if (scenario <= 0) + return {}; + + SyntaxNode node = findClassNode(); + SyntaxNode current = node.firstChild(); + while (current != SyntaxKey::None) { + if (current == SyntaxKey::Method) { + scenario--; + if (!scenario) + return current; + } + current = current.nextNode(); + } + + return {}; +} + +TEST_F(ByRefHandlerTest, GeneratingByRefHandler) +{ + runTest(true, false, 1, 1); +} + +// --- GeneratingByRefHandlerInvoker --- + +TEST_F(ByRefHandlerTest, GeneratingByRefHandlerInvoker) +{ + runTest(true, false, 1, 2); +} diff --git a/elenasrc3/elena-tests/tests_constructor.cpp b/elenasrc3/elena-tests/tests_constructor.cpp index b291ad38ba..8934434fc6 100644 --- a/elenasrc3/elena-tests/tests_constructor.cpp +++ b/elenasrc3/elena-tests/tests_constructor.cpp @@ -1,3 +1,11 @@ +/* +* VariadicCompiletimeConstructorSingleDispatch: +* --------------------------------------------- +* +* CallPrivateConstructorDirectly: +* ------------------------------ +*/ + #include "pch.h" // ------------------------------------------------ #include "serializer.h" @@ -16,12 +24,12 @@ constexpr auto S_PrivateConstructorTest = "class (nameattr (identifier \"X\" ()) #ifdef _M_IX86 -constexpr auto BuildTree_VariadicSingleDispatch_3 = "tape(open_frame()assigning 1 ()local_reference - 2 ()saving_stack()varg_sop 6 (index - 4 ())unbox_call_message - 2 (index 1 ()length - 4 ()temp_var - 8 ()message 1729 ())class_reference 6 ()saving_stack()argument()direct_call_op 4162 (type 13 ())loading_index() free_varstack() going_to_eop() close_frame()exit())reserved 3 ()reserved_n 8 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_3 = "tape(open_frame()assigning 1 ()local_reference - 2 ()saving_stack()varg_sop -4 (operator_id 6 ())unbox_call_message - 2 (value 1 ()length - 4 ()temp_var - 8 ()message 1729 ())class_reference 6 ()saving_stack()argument()direct_call_op 4162 (type 13 ())loading_index -4() free_varstack() going_to_eop() close_frame()exit())reserved 3 ()reserved_n 8 ())"; constexpr auto BuildTree_PrivateConstructorTest = "tape(open_frame() direct_call_op 800(type 6()) assigning 1 ()local -2 ()saving_stack()create_struct 4 (type 2()) copying_to_acc 2 (size 4 ()) assigning 2() local 2() saving_stack () local 1() field_assign () local 1() close_frame()exit())reserved 3 ())"; #elif _M_X64 -constexpr auto BuildTree_VariadicSingleDispatch_3 = "tape(open_frame()assigning 1 ()local_reference -2 ()saving_stack()varg_sop 6 (index -8 ())unbox_call_message -2 (index 1 ()length -8 ()temp_var -24 ()message 1729 ())class_reference 6 ()saving_stack()argument()direct_call_op 4162 (type 13 ())loading_index() free_varstack() going_to_eop() close_frame()exit())reserved 4 ()reserved_n 32 ())"; +constexpr auto BuildTree_VariadicSingleDispatch_3 = "tape(open_frame()assigning 1 ()local_reference -2 ()saving_stack()varg_sop -8 (operator_id 6 ())unbox_call_message -2 (value 1 ()length -8 ()temp_var -24 ()message 1729 ())class_reference 6 ()saving_stack()argument()direct_call_op 4162 (type 13 ())loading_index -8() free_varstack() going_to_eop() close_frame()exit())reserved 4 ()reserved_n 32 ())"; constexpr auto BuildTree_PrivateConstructorTest = "tape(open_frame() direct_call_op 800(type 6()) assigning 1 ()local -2 ()saving_stack()create_struct 4 (type 2()) copying_to_acc 2 (size 4 ()) assigning 2() local 2() saving_stack () local 1() field_assign () local 1() close_frame()exit())reserved 4 ())"; #endif @@ -36,7 +44,8 @@ void VariadicCompiletimeConstructorSingleDispatch :: SetUp() BuildTreeSerializer::load(BuildTree_VariadicSingleDispatch_3, controlOutputNode); - argArrayRef = 0x80; + argArrayTemplateRef = 0x80; + genericVargRef = 3; targetVargRef = 4; targetRef = 5; @@ -57,7 +66,7 @@ void CallPrivateConstructorDirectly :: SetUp() targetRef = 3; } -SyntaxNode CallPrivateConstructorDirectly :: findTargetNode() +SyntaxNode CallPrivateConstructorDirectly :: findTargetNode(int) { return findClassNode().findChild(SyntaxKey::Constructor).nextNode(); } diff --git a/elenasrc3/elena-tests/tests_declare.cpp b/elenasrc3/elena-tests/tests_declare.cpp index b36c8e4939..983fd558f0 100644 --- a/elenasrc3/elena-tests/tests_declare.cpp +++ b/elenasrc3/elena-tests/tests_declare.cpp @@ -1,3 +1,13 @@ +/* +* TemplateArrayFixture: +* --------------------- +* +* NewTemplateArrayFixture: +* ----------------------- +* +*/ + + #include "pch.h" // ------------------------------------------------ #include "declaration.h" diff --git a/elenasrc3/elenart/elenartmachine.cpp b/elenasrc3/elenart/elenartmachine.cpp index 38cf57bb11..cdc56ce140 100644 --- a/elenasrc3/elenart/elenartmachine.cpp +++ b/elenasrc3/elenart/elenartmachine.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA RT Machine declaration // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -314,10 +314,10 @@ void ELENARTMachine :: Exit(int exitCode) __routineProvider.Exit(exitCode); } -void ELENARTMachine :: startSTA(SystemEnv* env, void* entry) +void ELENARTMachine :: startApp(SystemEnv* env, void* entry) { // setting up system - __routineProvider.InitSTA(env); + __routineProvider.InitApp(env); // executing the program execute(entry); diff --git a/elenasrc3/elenart/elenartmachine.h b/elenasrc3/elenart/elenartmachine.h index 4099711d44..93c2689965 100644 --- a/elenasrc3/elenart/elenartmachine.h +++ b/elenasrc3/elenart/elenartmachine.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA RT Machine declaration // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ELENARTMACHINE_H @@ -41,7 +41,7 @@ namespace elena_lang void Exit(int exitCode); public: - void startSTA(SystemEnv* env, void* entry); + void startApp(SystemEnv* env, void* entry); void startThread(SystemEnv* env, void* entryPoint, int index); void loadSubjectName(IdentifierString& actionName, ref_t subjectRef); diff --git a/elenasrc3/elenart/linux/elenart.h b/elenasrc3/elenart/linux/elenart.h index 9a0e99a75a..845f4a76bb 100644 --- a/elenasrc3/elenart/linux/elenart.h +++ b/elenasrc3/elenart/linux/elenart.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA RT Engine // Linux Shared Library Declaration -// (C)2022-2024, by Aleksey Rakov +// (C)2022-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ELENART_H_INCLUDED @@ -25,6 +25,7 @@ extern "C" { DLL_PUBLIC void InitializeSTLA(elena_lang::SystemEnv* env, elena_lang::SymbolList* entryList, void* criricalHandler); + DLL_PUBLIC void InitializeMTLA(elena_lang::SystemEnv* env, elena_lang::SymbolList* entryList, void* criricalHandler); DLL_PUBLIC void* CollectGCLA(void* roots, size_t size); DLL_PUBLIC size_t LoadMessageNameLA(size_t message, char* buffer, size_t length); DLL_PUBLIC size_t LoadCallStackLA(uintptr_t framePtr, uintptr_t* list, size_t length); diff --git a/elenasrc3/elenart/linux/main.cpp b/elenasrc3/elenart/linux/main.cpp index 28af2e6ab7..69abc560e1 100644 --- a/elenasrc3/elenart/linux/main.cpp +++ b/elenasrc3/elenart/linux/main.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA RT Engine // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -78,7 +78,26 @@ void InitializeSTLA(SystemEnv* env, SymbolList* entryList, void* criricalHandler __routineProvider.InitSTAExceptionHandling(env, criricalHandler); - machine->startSTA(env, entryList); + machine->startApp(env, entryList); +} + +void InitializeMTLA(SystemEnv* env, SymbolList* entryList, void* criricalHandler) +{ + systemEnv = env; + +#ifdef DEBUG_OUTPUT + printf("InitializeMTA.6 %llx,%llx,%llx\n", (long long)env, (long long)entryList, (long long)criricalHandler); + fflush(stdout); +#endif + + if (machine == nullptr) + init(); + + size_t index = machine->allocateThreadEntry(env); + __routineProvider.InitMTAExceptionHandling(env, index, criricalHandler); + __routineProvider.InitMTASignals(env, index); + + machine->startApp(env, entryList); } void* CollectGCLA(void* roots, size_t size) diff --git a/elenasrc3/elenart/rtcommon.h b/elenasrc3/elenart/rtcommon.h index 171503ebbc..0c95462fca 100644 --- a/elenasrc3/elenart/rtcommon.h +++ b/elenasrc3/elenart/rtcommon.h @@ -14,7 +14,7 @@ namespace elena_lang { -#define ELENART_REVISION_NUMBER 0x000B +#define ELENART_REVISION_NUMBER 0x000C } diff --git a/elenasrc3/elenart/vs/elenart.vcxproj b/elenasrc3/elenart/vs/elenart.vcxproj index 6d79150aaf..c55748efcd 100644 --- a/elenasrc3/elenart/vs/elenart.vcxproj +++ b/elenasrc3/elenart/vs/elenart.vcxproj @@ -100,7 +100,7 @@ true WIN32;_DEBUG;RT_EXPORTS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..\windows;..;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..\windows;..\..\lruntime;..;%(AdditionalIncludeDirectories) Windows @@ -119,7 +119,7 @@ true WIN32;NDEBUG;RT_EXPORTS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..\windows;..;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..\windows;..\..\lruntime;..;%(AdditionalIncludeDirectories) Windows @@ -138,7 +138,7 @@ true _DEBUG;RT_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..\windows;..;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..\windows;..\..\lruntime;..;%(AdditionalIncludeDirectories) Windows @@ -157,7 +157,7 @@ true NDEBUG;RT_EXPORTS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..\windows;..;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..\windows;..\..\lruntime;..;%(AdditionalIncludeDirectories) Windows @@ -171,12 +171,6 @@ - - - - - - @@ -184,18 +178,11 @@ - - - - - - - false false @@ -209,7 +196,6 @@ - false @@ -223,6 +209,14 @@ + + + {c7728dfb-e3b8-4ce0-bef5-f8369e6761ef} + + + {49f68d87-f240-4e39-922d-219ee1601240} + + diff --git a/elenasrc3/elenart/windows/dllmain.cpp b/elenasrc3/elenart/windows/dllmain.cpp index 9e5053c4cd..3a33aaf29c 100644 --- a/elenasrc3/elenart/windows/dllmain.cpp +++ b/elenasrc3/elenart/windows/dllmain.cpp @@ -72,7 +72,7 @@ EXTERN_DLL_EXPORT void InitializeSTLA(SystemEnv* env, void* entry, void* cririca __routineProvider.InitSTAExceptionHandling(env, criricalHandler); - machine->startSTA(env, entry); + machine->startApp(env, entry); } EXTERN_DLL_EXPORT void InitializeMTLA(SystemEnv* env, SymbolList* entry, void* criricalHandler) @@ -80,7 +80,7 @@ EXTERN_DLL_EXPORT void InitializeMTLA(SystemEnv* env, SymbolList* entry, void* c systemEnv = env; #ifdef DEBUG_OUTPUT - printf("InitializeSTA.6 %x,%x\n", (int)env, (int)criricalHandler); + printf("InitializeMTA.6 %x,%x\n", (int)env, (int)criricalHandler); fflush(stdout); #endif @@ -89,7 +89,7 @@ EXTERN_DLL_EXPORT void InitializeMTLA(SystemEnv* env, SymbolList* entry, void* c __routineProvider.InitMTAExceptionHandling(env, index, criricalHandler); __routineProvider.InitMTASignals(env, index); - machine->startSTA(env, entry); + machine->startApp(env, entry); } EXTERN_DLL_EXPORT void ExitLA(int retVal) diff --git a/elenasrc3/elenasm/linux/elenasm.h b/elenasrc3/elenasm/linux/elenasm.h index 02a39384a3..b7b3f5cd11 100644 --- a/elenasrc3/elenasm/linux/elenasm.h +++ b/elenasrc3/elenasm/linux/elenasm.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA SM Engine // Linux Shared Library Declaration -// (C)2022-2023, by Aleksey Rakov +// (C)2022-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ELENASM_H_INCLUDED @@ -36,6 +36,8 @@ extern "C" DLL_PUBLIC void ReleaseSMLA(void* tape); DLL_PUBLIC size_t GetStatusSMLA(char* buffer, size_t maxLength); + + DLL_PUBLIC void ClearStackSMLA(); } #endif // ELENASM_H_INCLUDED diff --git a/elenasrc3/elenasm/linux/main.cpp b/elenasrc3/elenasm/linux/main.cpp index c5166f26ea..09a1e4c9e7 100644 --- a/elenasrc3/elenasm/linux/main.cpp +++ b/elenasrc3/elenasm/linux/main.cpp @@ -101,3 +101,10 @@ size_t GetStatusSMLA(char* buffer, size_t maxLength) } else return 0; } + +void ClearStackSMLA() +{ + if (engine) { + engine->clearParserStack(); + } +} diff --git a/elenasrc3/elenasm/regex.h b/elenasrc3/elenasm/regex.h index 3bae314181..fb09663a7d 100644 --- a/elenasrc3/elenasm/regex.h +++ b/elenasrc3/elenasm/regex.h @@ -60,7 +60,7 @@ namespace elena_lang virtual int getMode() = 0; virtual PatternRule* gotoNext(Stack& parents) = 0; - virtual PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) = 0; + virtual PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) = 0; virtual ~PatternRule() = default; }; @@ -99,7 +99,7 @@ namespace elena_lang } LinkRule() - : _mode(0) + : _mode(0), nextRule(nullptr) { } }; @@ -131,7 +131,7 @@ namespace elena_lang PatternRule* child; public: - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { parents.push(this); PatternRule* next = child->makeStep(s, index, ch, parents); @@ -152,7 +152,7 @@ namespace elena_lang class OptionalRule : public NestedRule { public: - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { parents.push(this); PatternRule* next = child->makeStep(s, index, ch, parents); @@ -180,7 +180,7 @@ namespace elena_lang return this; } - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { parents.push(this); PatternRule* next = child->makeStep(s, index, ch, parents); @@ -203,7 +203,7 @@ namespace elena_lang class OrRule : public GroupRule { public: - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { parents.push(this); @@ -231,7 +231,7 @@ namespace elena_lang char chTill; public: - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { if (ch >= chFrom && ch <= chTill) { return gotoNext(parents); @@ -249,7 +249,7 @@ namespace elena_lang class AnyWordChar : public LinkRule { public: - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { if (PatternRule::isLetter(ch)) { return gotoNext(parents); @@ -269,7 +269,7 @@ namespace elena_lang class DigitChar : public LinkRule { public: - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { if (PatternRule::isDigit(ch)) { return gotoNext(parents); @@ -286,13 +286,13 @@ namespace elena_lang class AnyRule : public LinkRule { public: - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { if (ch == 10 || ch == 0) { return nullptr; } - if (index < s.length_int()) { + if (index < s.length()) { return gotoNext(parents); } @@ -310,7 +310,7 @@ namespace elena_lang char _ch; public: - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { if (_ch == ch) { return gotoNext(parents); @@ -334,7 +334,7 @@ namespace elena_lang throw AbortError(); } - PatternRule* makeStep(ustr_t s, int index, char ch, Stack& parents) override + PatternRule* makeStep(ustr_t s, size_t index, char ch, Stack& parents) override { return ch == 0 ? this : nullptr; } diff --git a/elenasrc3/elenasm/scriptmachine.h b/elenasrc3/elenasm/scriptmachine.h index e8108cdd02..4beb4465b8 100644 --- a/elenasrc3/elenasm/scriptmachine.h +++ b/elenasrc3/elenasm/scriptmachine.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA Script Engine // -// (C)2023, by Alexei Rakov +// (C)2023-2025, by Alexei Rakov //--------------------------------------------------------------------------- #ifndef SCRIPTMACHINE_H @@ -60,6 +60,11 @@ namespace elena_lang return _lastError.str(); } + void clearParserStack() + { + _parsers.clear(); + } + ScriptEngine(path_t rootPath); ~ScriptEngine() = default; }; diff --git a/elenasrc3/elenasm/smcommon.h b/elenasrc3/elenasm/smcommon.h index 6b0a437783..d6e2b28ad0 100644 --- a/elenasrc3/elenasm/smcommon.h +++ b/elenasrc3/elenasm/smcommon.h @@ -9,7 +9,7 @@ #ifndef RTCOMMON_H #define RTCOMMON_H -#define ELENASM_REVISION_NUMBER 0x0015 +#define ELENASM_REVISION_NUMBER 0x0016 namespace elena_lang { diff --git a/elenasrc3/elenasm/windows/dllmain.cpp b/elenasrc3/elenasm/windows/dllmain.cpp index 7d8eac35e4..53d73ab13b 100644 --- a/elenasrc3/elenasm/windows/dllmain.cpp +++ b/elenasrc3/elenasm/windows/dllmain.cpp @@ -92,6 +92,13 @@ EXTERN_DLL_EXPORT size_t GetStatusSMLA(char* buffer, size_t maxLength) else return 0; } +EXTERN_DLL_EXPORT void ClearStackSMLA() +{ + if (engine) { + engine->clearParserStack(); + } +} + BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved diff --git a/elenasrc3/elenasrc3.sln b/elenasrc3/elenasrc3.sln index beee2c961e..7d3c8958ca 100644 --- a/elenasrc3/elenasrc3.sln +++ b/elenasrc3/elenasrc3.sln @@ -34,6 +34,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "elt", "tools\elt\vs\elt.vcx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "elena-tests", "elena-tests\elena-tests.vcxproj", "{89A68A7E-1CB6-45CB-9B02-8183FF59284A}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ldebugger", "ldebugger\vs\ldebugger.vcxproj", "{ACC215C7-8CCF-4AD5-BE40-A107DEC72D4F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lcommon", "common\vs\lcommon.vcxproj", "{C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lruntime", "lruntime\vs\lruntime.vcxproj", "{49F68D87-F240-4E39-922D-219EE1601240}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -138,14 +144,30 @@ Global {89A68A7E-1CB6-45CB-9B02-8183FF59284A}.Release|x64.Build.0 = Release|x64 {89A68A7E-1CB6-45CB-9B02-8183FF59284A}.Release|x86.ActiveCfg = Release|Win32 {89A68A7E-1CB6-45CB-9B02-8183FF59284A}.Release|x86.Build.0 = Release|Win32 - {60FE12CF-0DA9-4266-9C0F-F544DB115020}.Debug|x64.ActiveCfg = Debug|x64 - {60FE12CF-0DA9-4266-9C0F-F544DB115020}.Debug|x64.Build.0 = Debug|x64 - {60FE12CF-0DA9-4266-9C0F-F544DB115020}.Debug|x86.ActiveCfg = Debug|Win32 - {60FE12CF-0DA9-4266-9C0F-F544DB115020}.Debug|x86.Build.0 = Debug|Win32 - {60FE12CF-0DA9-4266-9C0F-F544DB115020}.Release|x64.ActiveCfg = Release|x64 - {60FE12CF-0DA9-4266-9C0F-F544DB115020}.Release|x64.Build.0 = Release|x64 - {60FE12CF-0DA9-4266-9C0F-F544DB115020}.Release|x86.ActiveCfg = Release|Win32 - {60FE12CF-0DA9-4266-9C0F-F544DB115020}.Release|x86.Build.0 = Release|Win32 + {ACC215C7-8CCF-4AD5-BE40-A107DEC72D4F}.Debug|x64.ActiveCfg = Debug|x64 + {ACC215C7-8CCF-4AD5-BE40-A107DEC72D4F}.Debug|x64.Build.0 = Debug|x64 + {ACC215C7-8CCF-4AD5-BE40-A107DEC72D4F}.Debug|x86.ActiveCfg = Debug|Win32 + {ACC215C7-8CCF-4AD5-BE40-A107DEC72D4F}.Debug|x86.Build.0 = Debug|Win32 + {ACC215C7-8CCF-4AD5-BE40-A107DEC72D4F}.Release|x64.ActiveCfg = Release|x64 + {ACC215C7-8CCF-4AD5-BE40-A107DEC72D4F}.Release|x64.Build.0 = Release|x64 + {ACC215C7-8CCF-4AD5-BE40-A107DEC72D4F}.Release|x86.ActiveCfg = Release|Win32 + {ACC215C7-8CCF-4AD5-BE40-A107DEC72D4F}.Release|x86.Build.0 = Release|Win32 + {C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF}.Debug|x64.ActiveCfg = Debug|x64 + {C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF}.Debug|x64.Build.0 = Debug|x64 + {C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF}.Debug|x86.ActiveCfg = Debug|Win32 + {C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF}.Debug|x86.Build.0 = Debug|Win32 + {C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF}.Release|x64.ActiveCfg = Release|x64 + {C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF}.Release|x64.Build.0 = Release|x64 + {C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF}.Release|x86.ActiveCfg = Release|Win32 + {C7728DFB-E3B8-4CE0-BEF5-F8369E6761EF}.Release|x86.Build.0 = Release|Win32 + {49F68D87-F240-4E39-922D-219EE1601240}.Debug|x64.ActiveCfg = Debug|x64 + {49F68D87-F240-4E39-922D-219EE1601240}.Debug|x64.Build.0 = Debug|x64 + {49F68D87-F240-4E39-922D-219EE1601240}.Debug|x86.ActiveCfg = Debug|Win32 + {49F68D87-F240-4E39-922D-219EE1601240}.Debug|x86.Build.0 = Debug|Win32 + {49F68D87-F240-4E39-922D-219EE1601240}.Release|x64.ActiveCfg = Release|x64 + {49F68D87-F240-4E39-922D-219EE1601240}.Release|x64.Build.0 = Release|x64 + {49F68D87-F240-4E39-922D-219EE1601240}.Release|x86.ActiveCfg = Release|Win32 + {49F68D87-F240-4E39-922D-219EE1601240}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/elenasrc3/elenavm/elenavmmachine.cpp b/elenasrc3/elenavm/elenavmmachine.cpp index 5beef29669..052d7be233 100644 --- a/elenasrc3/elenavm/elenavmmachine.cpp +++ b/elenasrc3/elenavm/elenavmmachine.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA VM declaration // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov // (C)2021-2024, by ELENA-LANG Org //--------------------------------------------------------------------------- @@ -148,7 +148,7 @@ void ELENAVMMachine :: init(SystemEnv* exeEnv) _env = (SystemEnv*)_compiler->getSystemEnv(); // setting up system - __routineProvider.InitSTA(_env); + __routineProvider.InitApp(_env); _initialized = true; } diff --git a/elenasrc3/elenavm/vmcommon.h b/elenasrc3/elenavm/vmcommon.h index ce64608110..6ede04b980 100644 --- a/elenasrc3/elenavm/vmcommon.h +++ b/elenasrc3/elenavm/vmcommon.h @@ -3,17 +3,17 @@ // // This file contains the compiler common interfaces & types // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef VMCOMMON_H #define VMCOMMON_H -#define ELENAVM_REVISION_NUMBER 0x0009 +#define ELENAVM_REVISION_NUMBER 0x000A namespace elena_lang { - constexpr auto ELENAVM_GREETING = "ELENA VM %d.%d.%d (%s) (C)2022-2024 by Aleksey Rakov, ELENA-LANG Org"; + constexpr auto ELENAVM_GREETING = "ELENA VM %d.%d.%d (%s) (C)2022-2025 by Aleksey Rakov, ELENA-LANG Org"; constexpr auto ELENAVM_INITIALIZING = "Initializing..."; } diff --git a/elenasrc3/elenavm/vs/elenavm.vcxproj b/elenasrc3/elenavm/vs/elenavm.vcxproj index a0ce304bf7..b6fb2d891c 100644 --- a/elenasrc3/elenavm/vs/elenavm.vcxproj +++ b/elenasrc3/elenavm/vs/elenavm.vcxproj @@ -100,7 +100,7 @@ true WIN32;_DEBUG;RT_EXPORTS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..\windows;..;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..\..\lruntime;..\windows;..;%(AdditionalIncludeDirectories) Windows @@ -119,7 +119,7 @@ true WIN32;NDEBUG;RT_EXPORTS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..\windows;..;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..\..\lruntime;..\windows;..;%(AdditionalIncludeDirectories) Windows @@ -138,7 +138,7 @@ true _DEBUG;RT_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..\windows;..;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..\..\lruntime;..\windows;..;%(AdditionalIncludeDirectories) Windows @@ -157,7 +157,7 @@ true NDEBUG;RT_EXPORTS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..\windows;..;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..\..\lruntime;..\windows;..;%(AdditionalIncludeDirectories) Windows @@ -171,12 +171,7 @@ - - - - - @@ -189,7 +184,6 @@ - @@ -202,12 +196,6 @@ - - - - - - false false @@ -224,7 +212,6 @@ - @@ -255,6 +242,14 @@ + + + {c7728dfb-e3b8-4ce0-bef5-f8369e6761ef} + + + {49f68d87-f240-4e39-922d-219ee1601240} + + diff --git a/elenasrc3/engine/bcwriter.cpp b/elenasrc3/engine/bcwriter.cpp index 9a595170a2..9a2f6e2d35 100644 --- a/elenasrc3/engine/bcwriter.cpp +++ b/elenasrc3/engine/bcwriter.cpp @@ -117,7 +117,7 @@ void classReference(CommandTape& tape, BuildNode& node, TapeScope&) void sendOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) { - int vmtIndex = node.findChild(BuildKey::Index).arg.value; + int vmtIndex = node.findChild(BuildKey::VMTIndex).arg.value; bool variadicOp = (node.arg.reference & PREFIX_MESSAGE_MASK) == VARIADIC_MESSAGE; @@ -132,14 +132,14 @@ void sendOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) tape.write(ByteCode::CallVI, vmtIndex); } -void resendOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) -{ - if (node.arg.reference) - tape.write(ByteCode::MovM, node.arg.reference); - - int vmtIndex = node.findChild(BuildKey::Index).arg.value; - tape.write(ByteCode::CallVI, vmtIndex); -} +//void resendOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +//{ +// if (node.arg.reference) +// tape.write(ByteCode::MovM, node.arg.reference); +// +// int vmtIndex = node.findChild(BuildKey::VMTIndex).arg.value; +// tape.write(ByteCode::CallVI, vmtIndex); +//} void strongResendOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) { @@ -153,7 +153,7 @@ void redirectOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) if (node.arg.reference) tape.write(ByteCode::MovM, node.arg.reference); - int vmtIndex = node.findChild(BuildKey::Index).arg.value; + int vmtIndex = node.findChild(BuildKey::VMTIndex).arg.value; tape.write(ByteCode::JumpVI, vmtIndex); } @@ -197,7 +197,7 @@ void semiDirectCallOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) tape.write(ByteCode::VCallMR, node.arg.reference, targetRef | mskVMTRef); } -void exit(CommandTape& tape, BuildNode& node, TapeScope& scope) +void exit(CommandTape& tape, BuildNode&, TapeScope&) { tape.write(ByteCode::Quit); } @@ -295,7 +295,7 @@ void copyingToLocalArr(CommandTape& tape, BuildNode& node, TapeScope&) void assignToStack(CommandTape& tape, BuildNode& node, TapeScope&) { - int n = node.findChild(BuildKey::Index).arg.value; + int n = node.findChild(BuildKey::StackIndex).arg.value; tape.write(ByteCode::MovSIFI, n, node.arg.value); } @@ -379,22 +379,22 @@ void addVirtualBreakpoint(CommandTape& tape, BuildNode&, TapeScope& tapeScope) tape.write(ByteCode::Breakpoint); } -void intLiteral(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +void intLiteral(CommandTape& tape, BuildNode& node, TapeScope&) { tape.write(ByteCode::SetR, node.arg.reference | mskIntLiteralRef); } -void longLiteral(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +void longLiteral(CommandTape& tape, BuildNode& node, TapeScope&) { tape.write(ByteCode::SetR, node.arg.reference | mskLongLiteralRef); } -void realLiteral(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +void realLiteral(CommandTape& tape, BuildNode& node, TapeScope&) { tape.write(ByteCode::SetR, node.arg.reference | mskRealLiteralRef); } -void mssgLiteral(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +void mssgLiteral(CommandTape& tape, BuildNode& node, TapeScope&) { tape.write(ByteCode::SetR, node.arg.reference | mskMssgLiteralRef); } @@ -461,6 +461,16 @@ void savingNInStack(CommandTape& tape, BuildNode& node, TapeScope&) tape.write(ByteCode::SaveSI, node.arg.value); } +void load_long_index(CommandTape& tape, BuildNode& node, TapeScope&) +{ + tape.write(ByteCode::LLoadDP, node.arg.value); +} + +void save_long_index(CommandTape& tape, BuildNode& node, TapeScope&) +{ + tape.write(ByteCode::LSaveDP, node.arg.value); +} + void savingLInStack(CommandTape& tape, BuildNode& node, TapeScope&) { tape.write(ByteCode::LLoad); @@ -532,9 +542,10 @@ void genericDispatchOp(CommandTape& tape, BuildNode& node, TapeScope&) void intRealOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - if (!isAssignOp(node.arg.value)) { + if (!isAssignOp(operatorId)) { tape.write(ByteCode::PeekSI); tape.write(ByteCode::Load); tape.write(ByteCode::SetDP, targetOffset); @@ -542,7 +553,7 @@ void intRealOp(CommandTape& tape, BuildNode& node, TapeScope&) tape.write(ByteCode::XMovSISI, 0, 1); } - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: case ADD_ASSIGN_OPERATOR_ID: tape.write(ByteCode::FAddDPN, targetOffset, 8); @@ -567,9 +578,10 @@ void intRealOp(CommandTape& tape, BuildNode& node, TapeScope&) void intLongOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - if (!isAssignOp(node.arg.value)) { + if (!isAssignOp(operatorId)) { tape.write(ByteCode::PeekSI); tape.write(ByteCode::Load); tape.write(ByteCode::ConvL); @@ -577,7 +589,7 @@ void intLongOp(CommandTape& tape, BuildNode& node, TapeScope&) tape.write(ByteCode::XMovSISI, 0, 1); } - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: tape.write(ByteCode::IAddDPN, targetOffset, 8); break; @@ -604,18 +616,15 @@ void intLongOp(CommandTape& tape, BuildNode& node, TapeScope&) } } -void realIntOp(CommandTape& tape, BuildNode& node, TapeScope&) +void real_int_xop(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - if (!isAssignOp(node.arg.value)) { - tape.write(ByteCode::CopyDPN, targetOffset, 8); - tape.write(ByteCode::XMovSISI, 0, 1); - } tape.write(ByteCode::SetDP, targetOffset); - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: case ADD_ASSIGN_OPERATOR_ID: tape.write(ByteCode::FIAdd, 8); @@ -637,17 +646,32 @@ void realIntOp(CommandTape& tape, BuildNode& node, TapeScope&) } } +void real_int_op(CommandTape& tape, BuildNode& node, TapeScope& scope) +{ + // NOTE : sp[0] - loperand, sp[1] - roperand + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; + + if (!isAssignOp(operatorId)) { + tape.write(ByteCode::CopyDPN, targetOffset, 8); + tape.write(ByteCode::XMovSISI, 0, 1); + } + + real_int_xop(tape, node, scope); +} + void realOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - if (!isAssignOp(node.arg.value)) { + if (!isAssignOp(operatorId)) { tape.write(ByteCode::CopyDPN, targetOffset, 8); tape.write(ByteCode::XMovSISI, 0, 1); } - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: case ADD_ASSIGN_OPERATOR_ID: tape.write(ByteCode::FAddDPN, targetOffset, 8); @@ -672,14 +696,15 @@ void realOp(CommandTape& tape, BuildNode& node, TapeScope&) void intOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - if (!isAssignOp(node.arg.value)) { + if (!isAssignOp(operatorId)) { tape.write(ByteCode::CopyDPN, targetOffset, 4); tape.write(ByteCode::XMovSISI, 0, 1); } - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: case ADD_ASSIGN_OPERATOR_ID: tape.write(ByteCode::IAddDPN, targetOffset, 4); @@ -719,14 +744,15 @@ void intOp(CommandTape& tape, BuildNode& node, TapeScope&) void intOpWithConst(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; int sourceOffset = node.findChild(BuildKey::Source).arg.value; int value = node.findChild(BuildKey::Value).arg.value; // loaddpn tape.write(ByteCode::LoadDP, sourceOffset); - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: tape.write(ByteCode::AddN, value); break; @@ -759,14 +785,15 @@ void intOpWithConst(CommandTape& tape, BuildNode& node, TapeScope&) void uintOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - if (!isAssignOp(node.arg.value)) { + if (!isAssignOp(operatorId)) { tape.write(ByteCode::CopyDPN, targetOffset, 4); tape.write(ByteCode::XMovSISI, 0, 1); } - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: case ADD_ASSIGN_OPERATOR_ID: tape.write(ByteCode::IAddDPN, targetOffset, 4); @@ -805,8 +832,9 @@ void uintOp(CommandTape& tape, BuildNode& node, TapeScope&) void intSOp(CommandTape& tape, BuildNode& node, TapeScope&) { - int targetOffset = node.findChild(BuildKey::Index).arg.value; - switch (node.arg.value) { + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; + switch (operatorId) { case BNOT_OPERATOR_ID: tape.write(ByteCode::INotDPN, targetOffset, 4); break; @@ -830,14 +858,15 @@ void intSOp(CommandTape& tape, BuildNode& node, TapeScope&) void byteOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - if (!isAssignOp(node.arg.value)) { + if (!isAssignOp(operatorId)) { tape.write(ByteCode::CopyDPN, targetOffset, 1); tape.write(ByteCode::XMovSISI, 0, 1); } - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: case ADD_ASSIGN_OPERATOR_ID: tape.write(ByteCode::IAddDPN, targetOffset, 1); @@ -876,8 +905,10 @@ void byteOp(CommandTape& tape, BuildNode& node, TapeScope&) void byteSOp(CommandTape& tape, BuildNode& node, TapeScope&) { - int targetOffset = node.findChild(BuildKey::Index).arg.value; - switch (node.arg.value) { + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; + + switch (operatorId) { case BNOT_OPERATOR_ID: tape.write(ByteCode::INotDPN, targetOffset, 1); break; @@ -889,14 +920,15 @@ void byteSOp(CommandTape& tape, BuildNode& node, TapeScope&) void shortOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - if (!isAssignOp(node.arg.value)) { + if (!isAssignOp(operatorId)) { tape.write(ByteCode::CopyDPN, targetOffset, 2); tape.write(ByteCode::XMovSISI, 0, 1); } - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: case ADD_ASSIGN_OPERATOR_ID: tape.write(ByteCode::IAddDPN, targetOffset, 2); @@ -935,8 +967,10 @@ void shortOp(CommandTape& tape, BuildNode& node, TapeScope&) void shortSOp(CommandTape& tape, BuildNode& node, TapeScope&) { - int targetOffset = node.findChild(BuildKey::Index).arg.value; - switch (node.arg.value) { + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; + + switch (operatorId) { case BNOT_OPERATOR_ID: tape.write(ByteCode::INotDPN, targetOffset, 2); break; @@ -1226,14 +1260,15 @@ void shortCondOp(CommandTape& tape, BuildNode& node, TapeScope&) void longOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - if (!isAssignOp(node.arg.value)) { + if (!isAssignOp(operatorId)) { tape.write(ByteCode::CopyDPN, targetOffset, 8); tape.write(ByteCode::XMovSISI, 0, 1); } - switch (node.arg.value) { + switch (operatorId) { case ADD_OPERATOR_ID: case ADD_ASSIGN_OPERATOR_ID: tape.write(ByteCode::IAddDPN, targetOffset, 8); @@ -1272,8 +1307,10 @@ void longOp(CommandTape& tape, BuildNode& node, TapeScope&) void longSOp(CommandTape& tape, BuildNode& node, TapeScope&) { - int targetOffset = node.findChild(BuildKey::Index).arg.value; - switch (node.arg.value) { + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; + + switch (operatorId) { case BNOT_OPERATOR_ID: tape.write(ByteCode::INotDPN, targetOffset, 8); break; @@ -1360,9 +1397,10 @@ void longIntCondOp(CommandTape& tape, BuildNode& node, TapeScope&) void byteArraySOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - switch (node.arg.value) { + switch (operatorId) { case LEN_OPERATOR_ID: tape.write(ByteCode::PeekSI, 0); tape.write(ByteCode::NLen, 1); @@ -1376,9 +1414,10 @@ void byteArraySOp(CommandTape& tape, BuildNode& node, TapeScope&) void vargSOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - switch (node.arg.value) { + switch (operatorId) { case LEN_OPERATOR_ID: // nsave dp : tmp, -1 // labNext : @@ -1410,9 +1449,10 @@ void vargSOp(CommandTape& tape, BuildNode& node, TapeScope&) void shortArraySOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - switch (node.arg.value) { + switch (operatorId) { case LEN_OPERATOR_ID: tape.write(ByteCode::PeekSI, 0); tape.write(ByteCode::NLen, 2); @@ -1426,10 +1466,11 @@ void shortArraySOp(CommandTape& tape, BuildNode& node, TapeScope&) void bynaryArraySOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; int size = node.findChild(BuildKey::Size).arg.value; - switch (node.arg.value) { + switch (operatorId) { case LEN_OPERATOR_ID: tape.write(ByteCode::PeekSI, 0); tape.write(ByteCode::NLen, size); @@ -1443,9 +1484,10 @@ void bynaryArraySOp(CommandTape& tape, BuildNode& node, TapeScope&) void objArraySOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - switch (node.arg.value) { + switch (operatorId) { case LEN_OPERATOR_ID: tape.write(ByteCode::PeekSI, 0); tape.write(ByteCode::Len); @@ -1484,9 +1526,10 @@ void objArrayOp(CommandTape& tape, BuildNode& node, TapeScope&) void byteArrayOp(CommandTape& tape, BuildNode& node, TapeScope&) { - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - switch (node.arg.value) { + switch (operatorId) { case SET_INDEXER_OPERATOR_ID: // load // peek sp:1 @@ -1512,10 +1555,11 @@ void byteArrayOp(CommandTape& tape, BuildNode& node, TapeScope&) void binaryArrayOp(CommandTape& tape, BuildNode& node, TapeScope&) { - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; int size = node.findChild(BuildKey::Size).arg.value; - switch (node.arg.value) { + switch (operatorId) { case SET_INDEXER_OPERATOR_ID: // load // peek sp:1 @@ -1541,9 +1585,10 @@ void binaryArrayOp(CommandTape& tape, BuildNode& node, TapeScope&) void shortArrayOp(CommandTape& tape, BuildNode& node, TapeScope&) { - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - switch (node.arg.value) { + switch (operatorId) { case SET_INDEXER_OPERATOR_ID: // load // peek sp:1 @@ -1570,9 +1615,10 @@ void shortArrayOp(CommandTape& tape, BuildNode& node, TapeScope&) void intArraySOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - switch (node.arg.value) { + switch (operatorId) { case LEN_OPERATOR_ID: tape.write(ByteCode::PeekSI, 0); tape.write(ByteCode::NLen, 4); @@ -1585,9 +1631,10 @@ void intArraySOp(CommandTape& tape, BuildNode& node, TapeScope&) void intArrayOp(CommandTape& tape, BuildNode& node, TapeScope&) { - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; - switch (node.arg.value) { + switch (operatorId) { case SET_INDEXER_OPERATOR_ID: // load // peek sp:1 @@ -1613,7 +1660,7 @@ void intArrayOp(CommandTape& tape, BuildNode& node, TapeScope&) void copyingItem(CommandTape& tape, BuildNode& node, TapeScope&) { - int targetOffset = node.findChild(BuildKey::Index).arg.value; + int targetOffset = node.findChild(BuildKey::Value).arg.value; tape.write(ByteCode::MovN, targetOffset); tape.write(ByteCode::WriteN, node.arg.value); @@ -1848,7 +1895,7 @@ void incIndex(CommandTape& tape, BuildNode& node, TapeScope&) void unboxingMessage(CommandTape& tape, BuildNode& node, TapeScope&) { - int index = node.findChild(BuildKey::Index).arg.value; + int index = node.findChild(BuildKey::Value).arg.value; // add n:index // dalloc @@ -1885,7 +1932,7 @@ void unboxingMessage(CommandTape& tape, BuildNode& node, TapeScope&) void unboxingAndCallMessage(CommandTape& tape, BuildNode& node, TapeScope&) { - int index = node.findChild(BuildKey::Index).arg.value; + int index = node.findChild(BuildKey::Value).arg.value; int length = node.findChild(BuildKey::Length).arg.value; int temp = node.findChild(BuildKey::TempVar).arg.value; mssg_t message = node.findChild(BuildKey::Message).arg.value; @@ -1968,7 +2015,7 @@ void unboxingAndCallMessage(CommandTape& tape, BuildNode& node, TapeScope&) void loadingSubject(CommandTape& tape, BuildNode& node, TapeScope&) { - int index = node.findChild(BuildKey::Index).arg.value; + int index = node.findChild(BuildKey::StackAddress).arg.value; bool mixedMode = node.findChild(BuildKey::Special).arg.value != 0; if (mixedMode) { @@ -2025,8 +2072,7 @@ void threadVarAssigning(CommandTape& tape, BuildNode& node, TapeScope&) void freeStack(CommandTape& tape, BuildNode& node, TapeScope&) { - tape.write(ByteCode::Neg); - tape.write(ByteCode::DAlloc); + tape.write(ByteCode::DFree); } inline void savingInt(CommandTape& tape, BuildNode& node, TapeScope&) @@ -2127,7 +2173,7 @@ ByteCodeWriter::Saver commands[] = creatingStruct, intLiteral, stringLiteral, goingToEOP, getLocalAddress, copyingLocal, allocatingStack, freeingStack, savingNInStack, extCallOp, savingIndex, directCallOp, dispatchOp, intOp, byteArraySOp, copyingToAcc, - getArgument, nullptr, directResend, resendOp, xdispatchOp, boolSOp, intCondOp, charLiteral, + getArgument, nullptr, directResend, /*resendOp*/nullptr, xdispatchOp, boolSOp, intCondOp, charLiteral, assignSPField, getField, staticBegin, staticEnd, classOp, byteArrayOp, newArrayOp, swapSPField, mssgLiteral, accSwapSPField, redirectOp, shortArraySOp, wideLiteral, byteOp, shortOp, byteCondOp, @@ -2143,10 +2189,10 @@ ByteCodeWriter::Saver commands[] = uintOp, mssgNameLiteral, vargSOp, loadArgCount, incIndex, freeStack, fillOp, strongResendOp, copyingToAccExact, savingInt, addingInt, loadingAccToIndex, indexOp, savingIndexToAcc, continueOp, semiDirectCallOp, - intRealOp, realIntOp, copyingToLocalArr, loadingStackDump, savingStackDump, savingFloatIndex, intCopyingToAccField, intOpWithConst, + intRealOp, real_int_op, copyingToLocalArr, loadingStackDump, savingStackDump, savingFloatIndex, intCopyingToAccField, intOpWithConst, uint8CondOp, uint16CondOp, intLongOp, distrConstant, unboxingAndCallMessage, threadVarOp, threadVarAssigning, threadVarBegin, - threadVarEnd + threadVarEnd, load_long_index, save_long_index, real_int_xop }; inline bool duplicateBreakpoints(BuildNode lastNode) @@ -2262,7 +2308,7 @@ inline bool doubleAssigningByRefHandler(BuildNode lastNode) BuildNode prevCopyOp = getPrevious(opNode); // check if it is unboxing op - if (prevCopyOp.key != BuildKey::Copying || prevCopyOp.arg.reference != lastNode.arg.value) + if (prevCopyOp.key != BuildKey::Copying || prevCopyOp.arg.reference != lastNode.arg.reference) prevCopyOp = {}; // modify the tree to exclude double copying @@ -2305,8 +2351,9 @@ inline bool intOpWithConsts(BuildNode lastNode) BuildNode savingOp1 = getPrevious(intNode); BuildNode sourceNode = getPrevious(savingOp1); - int tempTarget = opNode.findChild(BuildKey::Index).arg.value; - switch (opNode.arg.value) { + int tempTarget = opNode.arg.value; + int operatorId = opNode.findChild(BuildKey::OperatorId).arg.value; + switch (operatorId) { case ADD_OPERATOR_ID: case SUB_OPERATOR_ID: savingOp1.setKey(BuildKey::Copying); @@ -2314,7 +2361,7 @@ inline bool intOpWithConsts(BuildNode lastNode) savingOp1.appendChild(BuildKey::Size, 4); intNode.setKey(BuildKey::AddingInt); intNode.setArgumentValue(tempTarget); - if (opNode.arg.value == SUB_OPERATOR_ID) { + if (operatorId == SUB_OPERATOR_ID) { // revert the value valueNode.setArgumentValue(-valueNode.arg.value); } @@ -2325,7 +2372,7 @@ inline bool intOpWithConsts(BuildNode lastNode) savingOp1.setKey(BuildKey::LoadingAccToIndex); savingOp1.setArgumentValue(0); intNode.setKey(BuildKey::IndexOp); - intNode.setArgumentValue(opNode.arg.value); + intNode.setArgumentValue(operatorId); savingOp2.setKey(BuildKey::SavingIndex); savingOp2.setArgumentValue(tempTarget); opNode.setKey(BuildKey::Idle); @@ -2335,9 +2382,10 @@ inline bool intOpWithConsts(BuildNode lastNode) case SHL_OPERATOR_ID: case SHR_OPERATOR_ID: setChild(intNode, BuildKey::Source, sourceNode.arg.value); - setChild(intNode, BuildKey::Index, tempTarget); + setChild(intNode, BuildKey::OperatorId, operatorId); + intNode.setKey(BuildKey::IntConstOp); - intNode.setArgumentValue(opNode.arg.value); + intNode.setArgumentValue(tempTarget); opNode.setKey(BuildKey::Idle); savingOp2.setKey(BuildKey::Idle); @@ -2398,14 +2446,15 @@ inline bool assignIntOpWithConsts(BuildNode lastNode) BuildNode intNode = getPrevious(savingOp); BuildNode valueNode = intNode.findChild(BuildKey::Value); - int tempTarget = opNode.findChild(BuildKey::Index).arg.value; + int tempTarget = opNode.arg.value; + int operatorId = opNode.findChild(BuildKey::OperatorId).arg.value; - switch (opNode.arg.value) { + switch (operatorId) { case ADD_ASSIGN_OPERATOR_ID: case SUB_ASSIGN_OPERATOR_ID: intNode.setKey(BuildKey::AddingInt); intNode.setArgumentValue(tempTarget); - if (opNode.arg.value == SUB_ASSIGN_OPERATOR_ID) { + if (operatorId == SUB_ASSIGN_OPERATOR_ID) { // revert the value valueNode.setArgumentValue(-valueNode.arg.value); } @@ -2579,9 +2628,8 @@ inline bool doubleAssigningIntRealOp(BuildNode lastNode) BuildNode copyingNode = lastNode; BuildNode tempNode = getPrevious(copyingNode); BuildNode opNode = getPrevious(tempNode); - BuildNode indexNode = opNode.findChild(BuildKey::Index); - if (tempNode.arg.value != indexNode.arg.value) + if (tempNode.arg.value != opNode.arg.value) return false; int copySize = copyingNode.findChild(BuildKey::Size).arg.value; @@ -2595,7 +2643,7 @@ inline bool doubleAssigningIntRealOp(BuildNode lastNode) break; } - indexNode.setArgumentValue(copyingNode.arg.value); + opNode.setArgumentValue(copyingNode.arg.value); tempNode.setKey(BuildKey::Idle); copyingNode.setKey(BuildKey::Idle); @@ -3256,7 +3304,7 @@ void ByteCodeWriter :: saveCatching(CommandTape& tape, BuildNode node, TapeScope TryContextInfo blockInfo = { true }; blockInfo.catchNode = tryNode.nextNode(BuildKey::Tape); - blockInfo.index = node.findChild(BuildKey::Index).arg.value; + blockInfo.index = node.findChild(BuildKey::StackIndex).arg.value; blockInfo.ptr = node.arg.value; openTryBlock(tape, blockInfo, false); @@ -3277,7 +3325,7 @@ void ByteCodeWriter :: saveFinally(CommandTape& tape, BuildNode node, TapeScope& TryContextInfo blockInfo = { false }; blockInfo.catchNode = tryNode.nextNode(BuildKey::Tape); - blockInfo.index = node.findChild(BuildKey::Index).arg.value; + blockInfo.index = node.findChild(BuildKey::StackIndex).arg.value; blockInfo.ptr = node.arg.value; openTryBlock(tape, blockInfo, false); @@ -3446,32 +3494,32 @@ void ByteCodeWriter :: saveVariableInfo(CommandTape& tape, BuildNode node, TapeS tape.write(ByteCode::NSaveDPN, current.arg.value + 4, current.findChild(BuildKey::Size).arg.value); break; case BuildKey::Variable: - saveDebugSymbol(DebugSymbol::Local, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::Local, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::VariableAddress: - saveDebugSymbol(DebugSymbol::LocalAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), + saveDebugSymbol(DebugSymbol::LocalAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope, current.findChild(BuildKey::ClassName).identifier()); break; case BuildKey::IntVariableAddress: - saveDebugSymbol(DebugSymbol::IntLocalAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::IntLocalAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::UIntVariableAddress: - saveDebugSymbol(DebugSymbol::UIntLocalAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::UIntLocalAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::ByteArrayAddress: - saveDebugSymbol(DebugSymbol::ByteArrayAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::ByteArrayAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::ShortArrayAddress: - saveDebugSymbol(DebugSymbol::ShortArrayAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::ShortArrayAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::IntArrayAddress: - saveDebugSymbol(DebugSymbol::IntArrayAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::IntArrayAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::LongVariableAddress: - saveDebugSymbol(DebugSymbol::LongLocalAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::LongLocalAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::RealVariableAddress: - saveDebugSymbol(DebugSymbol::RealLocalAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::RealLocalAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; default: break; @@ -3508,32 +3556,32 @@ void ByteCodeWriter :: saveArgumentsInfo(CommandTape& tape, BuildNode node, Tape while (current != BuildKey::None) { switch (current.key) { case BuildKey::Parameter: - saveParameterDebugSymbol(DebugSymbol::Parameter, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveParameterDebugSymbol(DebugSymbol::Parameter, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::IntParameterAddress: - saveParameterDebugSymbol(DebugSymbol::IntParameterAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveParameterDebugSymbol(DebugSymbol::IntParameterAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::LongParameterAddress: - saveParameterDebugSymbol(DebugSymbol::LongParameterAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveParameterDebugSymbol(DebugSymbol::LongParameterAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::RealParameterAddress: - saveParameterDebugSymbol(DebugSymbol::RealParameterAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveParameterDebugSymbol(DebugSymbol::RealParameterAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::ParameterAddress: - saveParameterDebugSymbol(DebugSymbol::ParameterAddress, current.findChild(BuildKey::Index).arg.value, current.identifier(), + saveParameterDebugSymbol(DebugSymbol::ParameterAddress, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope, current.findChild(BuildKey::ClassName).identifier()); break; case BuildKey::ByteArrayParameter: - saveDebugSymbol(DebugSymbol::ByteArrayParameter, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::ByteArrayParameter, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::ShortArrayParameter: - saveDebugSymbol(DebugSymbol::ShortArrayParameter, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::ShortArrayParameter, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::IntArrayParameter: - saveDebugSymbol(DebugSymbol::IntArrayParameter, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::IntArrayParameter, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; case BuildKey::RealArrayParameter: - saveDebugSymbol(DebugSymbol::RealArrayParameter, current.findChild(BuildKey::Index).arg.value, current.identifier(), tapeScope); + saveDebugSymbol(DebugSymbol::RealArrayParameter, current.findChild(BuildKey::StackIndex).arg.value, current.identifier(), tapeScope); break; default: break; @@ -3752,6 +3800,7 @@ inline bool isNested(BuildKey key) case BuildKey::SwitchOption: case BuildKey::ElseOption: case BuildKey::StackCondOp: + case BuildKey::TernaryOp: case BuildKey::Tape: return true; default: @@ -3762,7 +3811,8 @@ inline bool isNested(BuildKey key) void ByteCodeWriter :: saveProcedure(BuildNode node, Scope& scope, bool classMode, pos_t sourcePathRef, ReferenceMap& paths, bool tapeOptMode) { - _buildTreeOptimizer.proceed(node.findChild(BuildKey::Tape)); + _btAnalyzer.proceed(node.findChild(BuildKey::Tape)); + _btTransformer.proceed(node.findChild(BuildKey::Tape)); if (scope.moduleScope->debugModule) openMethodDebugInfo(scope, sourcePathRef); @@ -3975,33 +4025,35 @@ void ByteCodeWriter :: loadBuildTreeRules(MemoryDump* dump) { MemoryReader reader(dump); - _buildTreeOptimizer.load(reader); + _btAnalyzer.load(reader); } -void ByteCodeWriter :: loadByteCodeRules(MemoryDump* dump) +void ByteCodeWriter :: loadBuildTreeXRules(MemoryDump* dump) { MemoryReader reader(dump); - _bcTransformer.trie.load(&reader); - _bcTransformer.loaded = true; + _btTransformer.load(reader); } -// --- ByteCodeWriter::BuildTreeOptimizer --- - -ByteCodeWriter::BuildTreeOptimizer :: BuildTreeOptimizer() +void ByteCodeWriter :: loadByteCodeRules(MemoryDump* dump) { + MemoryReader reader(dump); + _bcTransformer.trie.load(&reader); + _bcTransformer.loaded = true; } -void ByteCodeWriter::BuildTreeOptimizer :: load(StreamReader& reader) +// --- ByteCodeWriter::BuildTreeTransformerBase --- + +void ByteCodeWriter::BuildTreeTransformerBase :: load(StreamReader& reader) { - _btTransformer.trie.load(&reader); - _btTransformer.loaded = true; + _btPatterns.trie.load(&reader); + _btPatterns.loaded = true; } -void ByteCodeWriter::BuildTreeOptimizer :: proceed(BuildNode node) +void ByteCodeWriter::BuildTreeTransformerBase :: proceed(BuildNode node) { - if (!_btTransformer.loaded) + if (!_btPatterns.loaded) return; bool applied = true; @@ -4012,7 +4064,7 @@ void ByteCodeWriter::BuildTreeOptimizer :: proceed(BuildNode node) } } -bool ByteCodeWriter::BuildTreeOptimizer :: matchTriePatterns(BuildNode node) +bool ByteCodeWriter::BuildTreeTransformerBase :: matchTriePatterns(BuildNode node) { BuildPatterns matchedOnes; BuildPatterns nextOnes; @@ -4021,6 +4073,7 @@ bool ByteCodeWriter::BuildTreeOptimizer :: matchTriePatterns(BuildNode node) BuildPatterns* followers = &nextOnes; bool reversed = false; + BuildNode previous = {}; BuildNode current = node.firstChild(); while (current != BuildKey::None) { if (isNested(current.key)) { @@ -4035,24 +4088,11 @@ bool ByteCodeWriter::BuildTreeOptimizer :: matchTriePatterns(BuildNode node) continue; } - matched->add({ &_btTransformer.trie }); + matched->add({ &_btPatterns.trie }); followers->clear(); - for (auto it = matched->start(); !it.eof(); ++it) { - auto pattern = *it; - - for (auto child_it = pattern.Children(); !child_it.eof(); ++child_it) { - auto currentPattern = child_it.Node(); - auto currentPatternValue = currentPattern.Value(); - - if (currentPatternValue.match(current)) { - if (currentPatternValue.patternId && transformers[currentPatternValue.patternId](current)) - return true; - - followers->add(currentPattern); - } - } - } + if (matchBuildKey(matched, followers, current, previous)) + return true; if (reversed) { reversed = false; @@ -4065,8 +4105,84 @@ bool ByteCodeWriter::BuildTreeOptimizer :: matchTriePatterns(BuildNode node) followers = &matchedOnes; } + previous = current; current = current.nextNode(); } + // check the remaining patterns + return matchBuildKey(matched, followers, current, previous); +} + +bool ByteCodeWriter::BuildTreeTransformerBase :: matchBuildKey(BuildPatterns* matched, BuildPatterns* followers, BuildNode current, BuildNode previous) +{ + for (auto it = matched->start(); !it.eof(); ++it) { + BuildPatternArg args = (*it).args; + auto pattern = (*it).node; + + for (auto child_it = pattern.Children(); !child_it.eof(); ++child_it) { + auto currentPattern = child_it.Node(); + auto currentPatternValue = currentPattern.Value(); + + if (currentPatternValue.match(current, args)) { + if (currentPatternValue.key == BuildKey::Match) { + if (transform(currentPattern, previous, args)) + return true; + } + + followers->add({ currentPattern, args }); + } + } + } + return false; } + +// --- ByteCodeWriter::BuildTreeAnalyzer --- + +bool ByteCodeWriter::BuildTreeAnalyzer :: transform(BuildCodeTrieNode matchNode, BuildNode current, BuildPatternArg&) +{ + auto matchNodeValue = matchNode.Value(); + int patternId = matchNodeValue.argValue; + if (matchNodeValue.key == BuildKey::Match && patternId) { + return transformers[patternId](current); + } + + return false; +} + +// --- ByteCodeWriter::BuildTreeOptimizer --- + +bool ByteCodeWriter::BuildTreeOptimizer :: transform(BuildCodeTrieNode matchNode, BuildNode current, BuildPatternArg& args) +{ + BuildCodeTrieNode replacement = matchNode.FirstChild(); + + BuildPattern pattern = replacement.Value(); + while (pattern.key != BuildKey::None) { + // skip meta commands (except label) + while (isNonOperational(current.key)) + current = current.prevNode(); + + switch (pattern.argType) { + case BuildPatternType::Set: + if (pattern.argValue == 1) { + current.setArgumentValue(args.arg1); + } + else current.setArgumentValue(args.arg2); + break; + case BuildPatternType::MatchArg: + current.setArgumentValue(pattern.argValue); + break; + default: + break; + } + + current.setKey(pattern.key); + + current = current.prevNode(); + + replacement = replacement.FirstChild(); + pattern = replacement.Value(); + } + + return true; +} diff --git a/elenasrc3/engine/bcwriter.h b/elenasrc3/engine/bcwriter.h index f60ce269e6..e50ac658ee 100644 --- a/elenasrc3/engine/bcwriter.h +++ b/elenasrc3/engine/bcwriter.h @@ -79,10 +79,14 @@ namespace elena_lang } }; - class BuildTreeOptimizer + class BuildTreeTransformerBase { - BuildTreeTransformer _btTransformer; + protected: + BuildTreeTransformer _btPatterns; + virtual bool transform(BuildCodeTrieNode matchNode, BuildNode current, BuildPatternArg& args) = 0; + + bool matchBuildKey(BuildPatterns* matched, BuildPatterns* followers, BuildNode current, BuildNode previous); bool matchTriePatterns(BuildNode node); public: @@ -90,21 +94,38 @@ namespace elena_lang void proceed(BuildNode node); - BuildTreeOptimizer(); + BuildTreeTransformerBase() = default; + }; + + class BuildTreeAnalyzer : public BuildTreeTransformerBase + { + bool transform(BuildCodeTrieNode matchNode, BuildNode current, BuildPatternArg& args) override; + + public: + BuildTreeAnalyzer() = default; + }; + + class BuildTreeOptimizer : public BuildTreeTransformerBase + { + bool transform(BuildCodeTrieNode matchNode, BuildNode current, BuildPatternArg& args) override; + + public: + BuildTreeOptimizer() = default; }; typedef void(*Saver)(CommandTape& tape, BuildNode& node, TapeScope& scope); typedef bool(*Transformer)(BuildNode lastNode); private: - BuildTreeOptimizer _buildTreeOptimizer; + BuildTreeAnalyzer _btAnalyzer; + BuildTreeOptimizer _btTransformer; ByteCodeTransformer _bcTransformer; - const Saver* _commands; - LibraryLoaderBase* _loader; + const Saver* _commands; + LibraryLoaderBase* _loader; - bool _threadFriendly; + bool _threadFriendly; pos_t savePath(BuildNode node, Scope& scope, ReferenceMap& paths); @@ -173,6 +194,7 @@ namespace elena_lang public: void loadBuildTreeRules(MemoryDump* dump); + void loadBuildTreeXRules(MemoryDump* dump); void loadByteCodeRules(MemoryDump* dump); void save(BuildTree& tree, SectionScopeBase* moduleScope, int minimalArgList, diff --git a/elenasrc3/engine/buildtree.h b/elenasrc3/engine/buildtree.h index c6f4ad6ab1..4dfa7fd69e 100644 --- a/elenasrc3/engine/buildtree.h +++ b/elenasrc3/engine/buildtree.h @@ -13,6 +13,13 @@ #include "tree.h" #include +#ifdef _MSC_VER + +#pragma warning( push ) +#pragma warning( disable : 4458 ) + +#endif + namespace elena_lang { enum class BuildKey @@ -62,7 +69,7 @@ namespace elena_lang Argument = 0x0020, BranchOp = 0x0021, StrongRedirectOp = 0x0022, - ResendOp = 0x0023, + //ResendOp = 0x0023, SealedDispatchingOp = 0x0024, BoolSOp = 0x0025, IntCondOp = 0x0026, @@ -164,8 +171,11 @@ namespace elena_lang ThreadVarAssigning = 0x0086, OpenThreadVar = 0x0087, CloseThreadVar = 0x0088, + LoadingLIndex = 0x0089, + SavingLIndex = 0x008A, + RealIntXOp = 0x008B, - MaxOperationalKey = 0x0088, + MaxOperationalKey = 0x008B, Import = 0x0090, DictionaryOp = 0x0091, @@ -224,7 +234,7 @@ namespace elena_lang Value = 0x8001, Reserved = 0x8002, // reserved managed ReservedN = 0x8003, // reserved unmanaged - Index = 0x8004, + VMTIndex = 0x8004, Type = 0x8005, Column = 0x8006, Row = 0x8007, @@ -242,7 +252,11 @@ namespace elena_lang Length = 0x8013, TempVar = 0x8014, IndexTableMode = 0x8015, + OperatorId = 0x8016, + StackIndex = 0x8017, + StackAddress = 0x8018, + Match = 0x8FFE, Idle = 0x8FFF, //MetaDictionary = 0x0022, @@ -407,13 +421,23 @@ namespace elena_lang map.add("column", BuildKey::Column); map.add("row", BuildKey::Row); map.add("message", BuildKey::Message); - map.add("index", BuildKey::Index); + map.add("vmt_index", BuildKey::VMTIndex); map.add("length", BuildKey::Length); map.add("temp_var", BuildKey::TempVar); map.add("message", BuildKey::Message); map.add("reserved", BuildKey::Reserved); map.add("reserved_n", BuildKey::ReservedN); map.add("index_table_mode", BuildKey::IndexTableMode); + map.add("class", BuildKey::Class); + map.add("method", BuildKey::Method); + map.add("symbol", BuildKey::Symbol); + map.add("param_address", BuildKey::ParameterAddress); + map.add("dispatch_op", BuildKey::DispatchingOp); + map.add("redirect_op", BuildKey::RedirectOp); + map.add("operator_id", BuildKey::OperatorId); + map.add("load_long_index", BuildKey::LoadingLIndex); + map.add("save_long_index", BuildKey::SavingLIndex); + map.add("real_int_xop", BuildKey::RealIntXOp); } }; @@ -423,58 +447,94 @@ namespace elena_lang constexpr int BuildKeyNoArg = INT_MAX; - // --- BuildKeyPattern --- - struct BuildKeyPattern + enum class BuildPatternType { - BuildKey type; + None = 0, + MatchArg, + Set, + Match + }; - int argument; - int patternId; + struct BuildPatternArg + { + int arg1; + int arg2; + }; + + // --- BuildPattern --- + struct BuildPattern + { + BuildKey key; + BuildPatternType argType; + int argValue; - bool operator ==(BuildKey type) const + bool operator ==(BuildKey key) const { - return (this->type == type); + return (this->key == key); } - bool operator !=(BuildKey type) const + bool operator !=(BuildKey key) const { - return (this->type != type); + return (this->key != key); } - bool operator ==(BuildKeyPattern pattern) + bool operator ==(BuildPattern pattern) { - return (type == pattern.type && argument == pattern.argument); + return (key == pattern.key && argType == pattern.argType && argValue == pattern.argValue); } - bool operator !=(BuildKeyPattern pattern) + bool operator !=(BuildPattern pattern) { return !(*this == pattern); } - bool match(BuildNode node) + bool match(BuildNode node, BuildPatternArg& args) { - return node.key == type && (argument == BuildKeyNoArg || node.arg.value == argument); + if (key != node.key) + return key == BuildKey::Match; + + switch (argType) { + case BuildPatternType::Set: + if (argValue == 1) { + args.arg1 = node.arg.value; + } + else args.arg2 = node.arg.value; + return true; + case BuildPatternType::Match: + return ((argValue == 1) ? args.arg1 : args.arg2) == node.arg.value; + case BuildPatternType::MatchArg: + return node.arg.value == argValue; + default: + return true; + } } + }; + + typedef MemoryTrieBuilder BuildCodeTrie; + typedef MemoryTrieNode BuildCodeTrieNode; + + struct BuildPatternContext + { + BuildCodeTrieNode node; + BuildPatternArg args; - BuildKeyPattern() - : type(BuildKey::None), argument(BuildKeyNoArg), patternId(0) + BuildPatternContext() = default; + BuildPatternContext(BuildCodeTrieNode node, BuildPatternArg args) + : node(node), args(args) { - } - BuildKeyPattern(BuildKey type) - : type(type), argument(BuildKeyNoArg), patternId(0) + BuildPatternContext(BuildCodeTrieNode node) + : node(node), args({}) { } }; - typedef MemoryTrieBuilder BuildCodeTrie; - typedef MemoryTrieNode BuildCodeTrieNode; - typedef CachedList BuildPatterns; + typedef CachedList BuildPatterns; // --- BuildTreeTransformer --- struct BuildTreeTransformer { - typedef MemoryTrie MemoryBuildCodeTrie; + typedef MemoryTrie MemoryBuildCodeTrie; MemoryBuildCodeTrie trie; bool loaded; @@ -489,4 +549,10 @@ namespace elena_lang } +#ifdef _MSC_VER + +#pragma warning( pop ) + +#endif + #endif diff --git a/elenasrc3/engine/bytecode.cpp b/elenasrc3/engine/bytecode.cpp index 9dbae48500..afa14b4414 100644 --- a/elenasrc3/engine/bytecode.cpp +++ b/elenasrc3/engine/bytecode.cpp @@ -23,7 +23,7 @@ const char* _fnOpcodes[256] = "coalesce", "not", "neg", "bread", "lsave", "fsave", "wread", "xjump", "bcopy", "wcopy", "xpeekeq", "trylock", "freelock", "parent", "xget", "xcall", - "xfsave", "altmode", "xnop", OPCODE_UNKNOWN, "xquit", OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, + "xfsave", "altmode", "xnop", OPCODE_UNKNOWN, "xquit", "dfree", OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, @@ -63,6 +63,23 @@ const char* _fnOpcodes[256] = "fillir", "xstore fp", "xdispatch", "dispatch mssg", "vcall mssg", "call mssg", "call extern", OPCODE_UNKNOWN }; +const ByteCode opNotUsingAcc[] = { + ByteCode::Nop, ByteCode::Breakpoint, ByteCode::SNop, ByteCode::MovEnv, ByteCode::Unhook, ByteCode::Exclude, ByteCode::Include, ByteCode::MovFrm, ByteCode::MLen, ByteCode::DAlloc, + ByteCode::ConvL, ByteCode::LNeg, ByteCode::Not, ByteCode::Neg, ByteCode::AltMode, ByteCode::XNop, ByteCode::XQuit, ByteCode::Shl, ByteCode::Shr, ByteCode::FAbsDP, + ByteCode::FSqrtDP, ByteCode::FExpDP, ByteCode::FLnDP, ByteCode::FSinDP, ByteCode::FCosDP, ByteCode::FArctanDP, ByteCode::FPiDP, ByteCode::XSwapSI, ByteCode::MovM, ByteCode::MovN, + ByteCode::LoadDP, ByteCode::XCmpDP, ByteCode::SubN, ByteCode::AddN, ByteCode::CloseN, ByteCode::AllocI, ByteCode::FreeI, ByteCode::AddN, ByteCode::CmpN, ByteCode::FTruncDP, + ByteCode::OrN, ByteCode::MulN, ByteCode::XAddDP, ByteCode::FRoundDP, ByteCode::SaveDP, ByteCode::SaveSI, ByteCode::XFlushSI, ByteCode::XRefreshSI, ByteCode::LSaveDP, ByteCode::LSaveSI, + ByteCode::LLoadDP, ByteCode::TstM, ByteCode::TstN, ByteCode::XCmpSI, ByteCode::ExtCloseN, ByteCode::LLoadSI, ByteCode::LoadSI, ByteCode::XLoadArgFI, ByteCode::FAddDPN, ByteCode::FSubDPN, + ByteCode::FMulDPN, ByteCode::FDivDPN, ByteCode::UDivDPN, ByteCode::XLabelDPR, ByteCode::IAndDPN, ByteCode::IOrDPN, ByteCode::IXorDPN, ByteCode::INotDPN, ByteCode::IShlDPN, ByteCode::IShrDPN, + ByteCode::XOpenIN, ByteCode::CopyDPN, ByteCode::IAddDPN, ByteCode::ISubDPN, ByteCode::IMulDPN, ByteCode::IDivDPN, ByteCode::NSaveDPN, ByteCode::XHookDPR, ByteCode::NAddDPN, ByteCode::DCopyDPN, + ByteCode::OpenIN, ByteCode::XStoreSIR, ByteCode::ExtOpenIN, ByteCode::MovSIFI, ByteCode::XMovSISI, ByteCode::XStoreFIR, ByteCode::CallExtR, ByteCode::DFree +}; + +const ByteCode opSetAcc[] = { + ByteCode::SetR, ByteCode::SetDP, ByteCode::PeekR, ByteCode::SetFP, ByteCode::CreateR, ByteCode::XSetFP, ByteCode::PeekFI, ByteCode::PeekSI, ByteCode::SetSP, + ByteCode::PeekTLS, ByteCode::XCreateR, ByteCode::SelGrRR, ByteCode::NewIR, ByteCode::NewNR, ByteCode::CreateNR, +}; + // --- Auxiliary --- void fixJumps(MemoryBase* code, int labelPosition, Map& jumps, int label) @@ -874,6 +891,40 @@ inline void skipImport(ByteCodeIterator& bc_it) ++bc_it; } +inline bool contains(const ByteCode* list, size_t len, ByteCode bc) +{ + for (size_t i = 0; i < len; i++) { + if (list[i] == bc) + return true; + } + + return false; +} + +inline bool isAccFree(ByteCodeIterator bc_it) +{ + while (bc_it.eof()) { + ByteCode bc = (*bc_it).code; + if (contains(opSetAcc, sizeof(opSetAcc) / sizeof(ByteCode), bc)) + return true; + + if (!contains(opNotUsingAcc, sizeof(opNotUsingAcc) / sizeof(ByteCode), bc)) + return false; + + ++bc_it; + } + + return true; +} + +inline bool endOfPattern(ByteCodePattern& currentPattern, ByteCodeIterator& bc_it) +{ + if (currentPattern.argType == ByteCodePatternType::IfAccFree) { + return isAccFree(bc_it); + } + return currentPattern.code == ByteCode::Match; +} + bool ByteCodeTransformer :: apply(CommandTape& commandTape) { ByteCodePatterns matchedOnes; @@ -905,7 +956,7 @@ bool ByteCodeTransformer :: apply(CommandTape& commandTape) auto currentPattern = currentPatternNode.Value(); if (currentPattern.match(bc_it, arg)) { - if (currentPattern.code == ByteCode::Match) { + if (endOfPattern(currentPattern, bc_it)) { transform(--bc_it, currentPatternNode.FirstChild(), arg); return true; diff --git a/elenasrc3/engine/bytecode.h b/elenasrc3/engine/bytecode.h index c4fb0a395d..ce862f250c 100644 --- a/elenasrc3/engine/bytecode.h +++ b/elenasrc3/engine/bytecode.h @@ -11,6 +11,13 @@ #include "elena.h" +#if _MSC_VER + +#pragma warning( push ) +#pragma warning( disable : 4458 ) + +#endif + namespace elena_lang { @@ -73,6 +80,7 @@ namespace elena_lang AltMode = 0x31, XNop = 0x32, XQuit = 0x34, + DFree = 0x35, FIAdd = 0x70, FISub = 0x71, @@ -508,7 +516,8 @@ namespace elena_lang None = 0, Set, Match, - MatchArg + MatchArg, + IfAccFree // NOTE : can be used only for ByteCode::Match }; struct PatternArg @@ -622,4 +631,10 @@ namespace elena_lang }; } +#ifdef _MSC_VER + +#pragma warning( pop ) + +#endif + #endif diff --git a/elenasrc3/engine/elena.h b/elenasrc3/engine/elena.h index 164390a195..000c422538 100644 --- a/elenasrc3/engine/elena.h +++ b/elenasrc3/engine/elena.h @@ -307,7 +307,7 @@ namespace elena_lang this->metaSection = nullptr; this->reference = 0; } - SectionInfo(MemoryBase* section, MemoryBase* mataSection) + SectionInfo(MemoryBase* section, MemoryBase* metaSection) { this->module = nullptr; this->section = section; @@ -1136,9 +1136,9 @@ namespace elena_lang // --- StaticFieldInfo --- struct StaticFieldInfo { - int offset; - TypeInfo typeInfo; - ref_t valueRef; + int offset = 0; + TypeInfo typeInfo = {}; + ref_t valueRef = 0; }; // --- ClassHeader --- diff --git a/elenasrc3/engine/elenaconst.h b/elenasrc3/engine/elenaconst.h index 1b08509dfb..c51f0e0b82 100644 --- a/elenasrc3/engine/elenaconst.h +++ b/elenasrc3/engine/elenaconst.h @@ -99,6 +99,7 @@ namespace elena_lang constexpr auto CONSTRUCTOR_MESSAGE2 = "#constructor2"; // protected constructor constexpr auto CAST_MESSAGE = "#cast"; constexpr auto INVOKE_MESSAGE = "#invoke"; + constexpr auto ASYNC_INVOKE_MESSAGE = "#async_invoke"; constexpr auto TRY_INVOKE_MESSAGE = "#try_invoke"; constexpr auto INIT_MESSAGE = "#init"; constexpr auto CLASS_INIT_MESSAGE = "#class_init"; @@ -122,7 +123,7 @@ namespace elena_lang constexpr auto NOT_MESSAGE = "Inverted"; constexpr auto NEGATE_MESSAGE = "Negative"; constexpr auto VALUE_MESSAGE = "Value"; - constexpr auto ITEM_MESSAGE = "Value"; + constexpr auto RESULT_MESSAGE = "Result"; constexpr auto DEFAULT_MESSAGE = "Default"; constexpr auto BNOT_MESSAGE = "BInverted"; constexpr auto NOTEQUAL_MESSAGE = "notequal"; @@ -310,6 +311,7 @@ namespace elena_lang ExtOverloadList = 0x90A, Initializer = 0x10B, YieldContextSize = 0x80C, + SourceTemplateRef = 0x10D, }; // === Reference constants ==== @@ -495,8 +497,8 @@ namespace elena_lang constexpr ref_t INV_ARG12_2 = 0x0000002Au; // predefined debug module sections - constexpr ref_t DEBUG_LINEINFO_ID = -1; - constexpr ref_t DEBUG_STRINGS_ID = -2; + constexpr ref_t DEBUG_LINEINFO_ID = (ref_t)-1; + constexpr ref_t DEBUG_STRINGS_ID = (ref_t)-2; // === ELENA Error codes === constexpr auto errNotImplemented = -3; diff --git a/elenasrc3/engine/elenamachine.cpp b/elenasrc3/engine/elenamachine.cpp index 638de5cf75..029768c006 100644 --- a/elenasrc3/engine/elenamachine.cpp +++ b/elenasrc3/engine/elenamachine.cpp @@ -70,7 +70,7 @@ uintptr_t ELENAMachine :: createPermVMT(SystemEnv* env, size_t size) uintptr_t addr = (uintptr_t)SystemRoutineProvider::GCRoutinePerm(env->gc_table, alignSize(size, gcPageSize)); ObjectPage* header = (ObjectPage*)(addr - elObjectOffset); - header->size = size; + header->size = (pos_t)size; header->vmtPtr = 0; return (uintptr_t)header + elObjectOffset; @@ -197,7 +197,7 @@ void SystemRoutineProvider :: InitMTAExceptionHandling(SystemEnv* env, size_t in InitCriticalStruct((uintptr_t)env->veh_handler); } -void SystemRoutineProvider :: Init(SystemEnv* env, SystemSettings settings) +void SystemRoutineProvider :: InitGC(SystemEnv* env, SystemSettings settings) { int page_mask = settings.page_mask; @@ -230,12 +230,12 @@ void SystemRoutineProvider :: Init(SystemEnv* env, SystemSettings settings) env->gc_table->gc_perm_end = env->gc_table->gc_perm_start; } -void SystemRoutineProvider :: InitSTA(SystemEnv* env) +void SystemRoutineProvider :: InitApp(SystemEnv* env) { SystemSettings settings; FillSettings(env, settings); - Init(env, settings); + InitGC(env, settings); } inline uintptr_t getContent(uintptr_t ptr) @@ -323,11 +323,11 @@ bool SystemRoutineProvider :: overrideClass(void* ptr, void* classPtr) return false; } -int SystemRoutineProvider :: GetFlags(void* classPtr) +pos_t SystemRoutineProvider :: GetFlags(void* classPtr) { VMTHeader* header = (VMTHeader*)((uintptr_t)classPtr - elVMTClassOffset); - return header->flags; + return (pos_t)header->flags; } size_t SystemRoutineProvider :: LoadMessages(MemoryBase* msection, void* classPtr, mssg_t* output, size_t skip, diff --git a/elenasrc3/engine/elenamachine.h b/elenasrc3/engine/elenamachine.h index 7d5b88996d..8dee51296c 100644 --- a/elenasrc3/engine/elenamachine.h +++ b/elenasrc3/engine/elenamachine.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA Machine common types // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ELENAMACHINE_H @@ -119,13 +119,13 @@ namespace elena_lang static size_t LoadCallStack(uintptr_t framePtr, uintptr_t* list, size_t length); - static void Init(SystemEnv* env, SystemSettings settings); + static void InitGC(SystemEnv* env, SystemSettings settings); static void InitSTAExceptionHandling(SystemEnv* env, void* criticalHandler); static void InitMTAExceptionHandling(SystemEnv* env, size_t index, void* criticalHandler); static void InitMTASignals(SystemEnv* env, size_t index); static void ClearMTASignals(SystemEnv* env, size_t index); static void InitCriticalStruct(uintptr_t criticalDispatcher); - static void InitSTA(SystemEnv* env); + static void InitApp(SystemEnv* env); static long long GenerateSeed(); static void InitRandomSeed(SeedStruct& seed, long long seedNumber); @@ -147,7 +147,7 @@ namespace elena_lang static size_t GetVMTLength(void* classPtr); static addr_t GetClass(void* ptr); static addr_t GetParent(void* classPtr); - static int GetFlags(void* classPtr); + static pos_t GetFlags(void* classPtr); static bool overrideClass(void* ptr, void* classPtr); static bool CheckMessage(MemoryBase* msection, void* classPtr, mssg_t message); diff --git a/elenasrc3/engine/gcroutines.cpp b/elenasrc3/engine/gcroutines.cpp index b5b45eccd5..11850e5f7c 100644 --- a/elenasrc3/engine/gcroutines.cpp +++ b/elenasrc3/engine/gcroutines.cpp @@ -553,7 +553,7 @@ void SystemRoutineProvider :: CalcGCStatistics(SystemEnv* systemEnv, GCStatistic auto table = systemEnv->gc_table; statistics->ygInfo.allocated = (unsigned int)(table->gc_yg_current - table->gc_yg_start); - statistics->ygInfo.free = (unsigned int)table->gc_yg_end - table->gc_yg_current; + statistics->ygInfo.free = (unsigned int)(table->gc_yg_end - table->gc_yg_current); statistics->mgInfo.allocated = (unsigned int)(table->gc_mg_current - table->gc_mg_start); statistics->mgInfo.free = (unsigned int)(table->gc_end - table->gc_mg_current); diff --git a/elenasrc3/engine/jitcompiler.cpp b/elenasrc3/engine/jitcompiler.cpp index 4adce0fa5a..e3c387acbe 100644 --- a/elenasrc3/engine/jitcompiler.cpp +++ b/elenasrc3/engine/jitcompiler.cpp @@ -27,7 +27,7 @@ CodeGenerator _codeGenerators[256] = loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, loadOp, - loadOp, compileAltMode, loadXNop, loadNop, loadOp, loadNop, loadNop, loadNop, + loadOp, compileAltMode, loadXNop, loadNop, loadOp, loadOp, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, @@ -90,7 +90,7 @@ constexpr ref_t coreFunctions[coreFunctionNumber] = }; // preloaded bc commands -constexpr size_t bcCommandNumber = 178; +constexpr size_t bcCommandNumber = 179; constexpr ByteCode bcCommands[bcCommandNumber] = { ByteCode::MovEnv, ByteCode::SetR, ByteCode::SetDP, ByteCode::CloseN, ByteCode::AllocI, @@ -128,7 +128,7 @@ constexpr ByteCode bcCommands[bcCommandNumber] = ByteCode::Shl, ByteCode::Shr, ByteCode::XLabelDPR, ByteCode::TryLock, ByteCode::FreeLock, ByteCode::XQuit, ByteCode::ExtCloseN, ByteCode::XCmpSI, ByteCode::LoadSI, ByteCode::XFSave, ByteCode::XSaveN, ByteCode::XSaveDispN, ByteCode::XStoreFIR, ByteCode::LNeg, ByteCode::Parent, - ByteCode::LLoadSI, ByteCode::PeekTLS, ByteCode::StoreTLS + ByteCode::LLoadSI, ByteCode::PeekTLS, ByteCode::StoreTLS, ByteCode::DFree }; void elena_lang :: writeCoreReference(JITCompilerScope* scope, ref_t reference, @@ -265,7 +265,7 @@ void elena_lang :: writeCoreReference(JITCompilerScope* scope, ref_t reference, } void elena_lang :: writeMDataReference(JITCompilerScope* scope, ref_t mask, - pos_t disp, void* code, ModuleBase* module) + pos_t disp, void* code, ModuleBase*) { // references should be already preloaded - except the import one switch (mask) { @@ -1480,7 +1480,7 @@ void elena_lang::loadStackIndexROp(JITCompilerScope* scope) break; case DISP32HI_2: if (scope->command.arg2 == -1) { - writer->writeWord((short)-1); + writer->writeShort((short)-1); } else if (scope->command.arg2) { scope->compiler->writeArgAddress(scope, scope->command.arg2, 0, mskDisp32Hi); @@ -1489,7 +1489,7 @@ void elena_lang::loadStackIndexROp(JITCompilerScope* scope) break; case DISP32LO_2: if (scope->command.arg2 == -1) { - writer->writeWord((short)-1); + writer->writeShort((short)-1); } else if (scope->command.arg2) { scope->compiler->writeArgAddress(scope, scope->command.arg2, 0, mskDisp32Lo); @@ -1498,7 +1498,7 @@ void elena_lang::loadStackIndexROp(JITCompilerScope* scope) break; case XDISP32HI_2: if (scope->command.arg2 == -1) { - writer->writeWord((short)-1); + writer->writeShort((short)-1); } else if (scope->command.arg2) { scope->compiler->writeArgAddress(scope, scope->command.arg2, 0, mskXDisp32Hi); @@ -1507,7 +1507,7 @@ void elena_lang::loadStackIndexROp(JITCompilerScope* scope) break; case XDISP32LO_2: if (scope->command.arg2 == -1) { - writer->writeWord((short)-1); + writer->writeShort((short)-1); } else if (scope->command.arg2) { scope->compiler->writeArgAddress(scope, scope->command.arg2, 0, mskXDisp32Lo); @@ -1517,7 +1517,7 @@ void elena_lang::loadStackIndexROp(JITCompilerScope* scope) case PTR32HI_2: { if (scope->command.arg2 == -1) { - writer->writeWord((short)-1); + writer->writeShort((short)-1); } else if (scope->command.arg2) { scope->compiler->writeArgAddress(scope, scope->command.arg2, 0, mskRef32Hi); @@ -1528,7 +1528,7 @@ void elena_lang::loadStackIndexROp(JITCompilerScope* scope) case PTR32LO_2: { if (scope->command.arg2 == -1) { - writer->writeWord((short)-1); + writer->writeShort((short)-1); } else if (scope->command.arg2) { scope->compiler->writeArgAddress(scope, scope->command.arg2, 0, mskRef32Lo); @@ -1678,7 +1678,7 @@ void elena_lang::loadIndexNOp(JITCompilerScope* scope) writer->writeDWord(scope->command.arg1 << scope->constants->indexPower); break; case INV_ARG16_1: - writer->writeWord(-(scope->command.arg1 << scope->constants->indexPower)); + writer->writeShort(-(scope->command.arg1 << scope->constants->indexPower)); break; case NARG_1: writer->writeDWord(scope->command.arg1); @@ -2354,7 +2354,7 @@ void elena_lang :: loadDispNOp(JITCompilerScope* scope) writer->writeDWord(scope->command.arg1); break; case ARG16_1: - writer->writeWord(scope->command.arg1); + writer->writeWord((unsigned short)scope->command.arg1); break; case ARG12_1: scope->compiler->writeImm12(writer, scope->command.arg1, 0); @@ -2409,7 +2409,7 @@ void elena_lang :: loadONOp(JITCompilerScope* scope) writer->writeDWord(scope->command.arg1); break; case ARG16_1: - writer->writeWord(scope->command.arg1); + writer->writeWord((unsigned short)scope->command.arg1); break; case ARG12_1: scope->compiler->writeImm12(writer, scope->command.arg1, 0); diff --git a/elenasrc3/engine/jitcompiler.h b/elenasrc3/engine/jitcompiler.h index 21b34efb09..592b8dae33 100644 --- a/elenasrc3/engine/jitcompiler.h +++ b/elenasrc3/engine/jitcompiler.h @@ -204,7 +204,7 @@ namespace elena_lang { switch (type) { case INV_ARG: - writer->writeWord(-value); + writer->writeShort(-value); break; default: writer->writeWord(value); diff --git a/elenasrc3/engine/langcommon.h b/elenasrc3/engine/langcommon.h index 4cdb4a67e8..c0e8a6fd43 100644 --- a/elenasrc3/engine/langcommon.h +++ b/elenasrc3/engine/langcommon.h @@ -427,6 +427,7 @@ namespace elena_lang constexpr auto infoTargetClass = 707; constexpr auto infoScopeMethod = 708; constexpr auto infoExptectedType = 709; + constexpr auto infoInternalDefConstructor = 710; constexpr auto errVMBroken = 800; constexpr auto errVMNotInitialized = 801; @@ -725,21 +726,21 @@ namespace elena_lang constexpr auto START_FORWARD = "$symbol_entry"; // --- Configuration xpaths --- - constexpr auto WIN_X86_KEY = "Win_x86"; - constexpr auto WIN_X86_64_KEY = "Win_x64"; - constexpr auto LINUX_X86_KEY = "Linux_I386"; - constexpr auto LINUX_X86_64_KEY = "Linux_AMD64"; - constexpr auto LINUX_PPC64le_KEY = "Linux_PPC64le"; - constexpr auto LINUX_ARM64_KEY = "Linux_ARM64"; - - constexpr auto MACOS_ARM64_KEY = "MacOS_ARM64"; - - constexpr auto LIBRARY_KEY = "Library"; - constexpr auto CONSOLE_KEY = "STA Console"; - constexpr auto GUI_KEY = "STA GUI"; - constexpr auto MT_CONSOLE_KEY = "MTA Console"; - constexpr auto VM_CONSOLE_KEY = "VM STA Console"; - constexpr auto VM_GUI_KEY = "VM STA GUI"; + constexpr auto WIN_X86_KEY = "Win_x86"; + constexpr auto WIN_X86_64_KEY = "Win_x64"; + constexpr auto LINUX_X86_KEY = "Linux_I386"; + constexpr auto LINUX_X86_64_KEY = "Linux_AMD64"; + constexpr auto LINUX_PPC64le_KEY = "Linux_PPC64le"; + constexpr auto LINUX_ARM64_KEY = "Linux_ARM64"; + + constexpr auto MACOS_ARM64_KEY = "MacOS_ARM64"; + + constexpr auto LIBRARY_KEY = "Library"; + constexpr auto CONSOLE_KEY = "STA Console"; + constexpr auto GUI_KEY = "STA GUI"; + constexpr auto MT_CONSOLE_KEY = "MTA Console"; + constexpr auto VM_CONSOLE_KEY = "VM STA Console"; + constexpr auto VM_GUI_KEY = "VM STA GUI"; constexpr auto CONFIG_ROOT = "configuration"; constexpr auto PLATFORM_CATEGORY = "configuration/platform"; @@ -747,6 +748,9 @@ namespace elena_lang constexpr auto COLLECTION_CATEGORY = "configuration/collection/*"; constexpr auto COLLECTIONS_CATEGORY = "configuration/collections/*"; + constexpr auto PROFILE_ATTR = "profile"; + constexpr auto BASE_PATH_ATTR = "base_path"; + constexpr auto TEMPLATE_CATEGORY = "templates/*"; constexpr auto PRIMITIVE_CATEGORY = "primitives/*"; constexpr auto LEXICAL_CATEGORY = "lexicals/*"; diff --git a/elenasrc3/engine/lbhelper.h b/elenasrc3/engine/lbhelper.h index 00fd04baab..454773fde5 100644 --- a/elenasrc3/engine/lbhelper.h +++ b/elenasrc3/engine/lbhelper.h @@ -24,7 +24,7 @@ namespace elena_lang JumpInfo() { - position = -1; + position = INVALID_POS; offset = 0; } JumpInfo(pos_t position) diff --git a/elenasrc3/engine/libman.cpp b/elenasrc3/engine/libman.cpp index 5599794374..42eeeb10db 100644 --- a/elenasrc3/engine/libman.cpp +++ b/elenasrc3/engine/libman.cpp @@ -486,6 +486,12 @@ ModuleBase* LibraryProvider :: createDebugModule(ustr_t name) return module; } +void LibraryProvider :: retrievePath(ModuleBase* module, PathString& path) +{ + ustr_t name = module->name(); + nameToPath(name, path, "nl"); +} + bool LibraryProvider :: saveModule(ModuleBase* module) { // resolving the module output path diff --git a/elenasrc3/engine/libman.h b/elenasrc3/engine/libman.h index d84a8fe9ca..8a7d05c28f 100644 --- a/elenasrc3/engine/libman.h +++ b/elenasrc3/engine/libman.h @@ -104,6 +104,8 @@ namespace elena_lang bool saveModule(ModuleBase* module); bool saveDebugModule(ModuleBase* module); + void retrievePath(ModuleBase* module, PathString& path); + ModuleBase* loadModule(ustr_t name); ModuleRequestResult loadModuleIfRequired(ustr_t name); diff --git a/elenasrc3/engine/serializer.cpp b/elenasrc3/engine/serializer.cpp index c71322b357..7af051c272 100644 --- a/elenasrc3/engine/serializer.cpp +++ b/elenasrc3/engine/serializer.cpp @@ -15,10 +15,10 @@ using namespace elena_lang; // --- SyntaxTreeReader --- -void syntaxTreeEncoder(TextWriter& writer, SyntaxKey key, ustr_t strArg, int arg, void* extraArg) +void syntaxTreeEncoder(int level, TextWriter& writer, SyntaxKey key, ustr_t strArg, int arg, void* extraArg) { if (key == SyntaxKey::None) { - writer.writeTextLine(")"); + writer.writeText(")"); return; } @@ -30,6 +30,11 @@ void syntaxTreeEncoder(TextWriter& writer, SyntaxKey key, ustr_t strArg, i return current == arg; }); + writer.writeTextLine(nullptr); + + for (int i = 0; i < level; i++) + writer.writeChar(' '); + if (keyName.empty()) { IdentifierString code; code.append('#'); @@ -53,17 +58,17 @@ void syntaxTreeEncoder(TextWriter& writer, SyntaxKey key, ustr_t strArg, i writer.writeChar(' '); } - writer.writeTextLine("("); + writer.writeText("("); } -void SyntaxTreeSerializer :: save(SyntaxNode node, DynamicUStr& target) +void SyntaxTreeSerializer :: save(SyntaxNode node, DynamicUStr& target, List* filters) { TokenMap list(SyntaxKey::None); SyntaxTree::loadTokens(list); DynamicUStrWriter writer(&target); - SyntaxTree::serialize(node, syntaxTreeEncoder, writer, &list); + SyntaxTree::serialize(0, node, syntaxTreeEncoder, writer, &list, filters); } struct LoadScope @@ -124,21 +129,26 @@ void SyntaxTreeSerializer :: load(ustr_t source, SyntaxNode& target) // --- BuildTreeSerializer --- -void buildTreeEncoder(TextWriter& writer, BuildKey key, ustr_t, int arg, void* extraArg) +void buildTreeEncoder(int level, TextWriter& writer, BuildKey key, ustr_t, int arg, void* extraArg) { if (key == BuildKey::None) { - writer.writeTextLine(")"); + writer.writeText(")"); return; } BuildKeyMap* map = static_cast(extraArg); - ustr_t keyName = map->retrieve(nullptr, key, [](BuildKey arg, ustr_t value, BuildKey current) + ustr_t keyName = map->retrieve(nullptr, key, [](BuildKey arg, ustr_t, BuildKey current) { return current == arg; }); + writer.writeTextLine(nullptr); + + for (int i = 0; i < level; i++) + writer.writeChar(' '); + if (keyName.empty()) { IdentifierString code; code.append('#'); @@ -156,17 +166,17 @@ void buildTreeEncoder(TextWriter& writer, BuildKey key, ustr_t, int arg, v writer.writeChar(' '); } - writer.writeTextLine("("); + writer.writeText("("); } -void BuildTreeSerializer :: save(BuildNode node, DynamicUStr& target) +void BuildTreeSerializer :: save(BuildNode node, DynamicUStr& target, List* filters) { BuildKeyMap map(BuildKey::None); BuildTree::loadBuildKeyMap(map); DynamicUStrWriter writer(&target); - BuildTree::serialize(node, buildTreeEncoder, writer, &map); + BuildTree::serialize(0, node, buildTreeEncoder, writer, &map, filters); } struct BuildLoadScope diff --git a/elenasrc3/engine/serializer.h b/elenasrc3/engine/serializer.h index acb5c42819..e150f9fdcf 100644 --- a/elenasrc3/engine/serializer.h +++ b/elenasrc3/engine/serializer.h @@ -3,7 +3,7 @@ // // This header contains ELENA Tree Serializer classes declaration. // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef SERIALIZER_H @@ -18,7 +18,7 @@ namespace elena_lang class BuildTreeSerializer { public: - static void save(BuildNode node, DynamicUStr& target); + static void save(BuildNode node, DynamicUStr& target, List* filters); static void load(ustr_t source, BuildNode& target); }; @@ -26,7 +26,7 @@ namespace elena_lang class SyntaxTreeSerializer { public: - static void save(SyntaxNode node, DynamicUStr& target); + static void save(SyntaxNode node, DynamicUStr& target, List* filters); static void load(ustr_t source, SyntaxNode& target); }; } diff --git a/elenasrc3/engine/syntaxtree.h b/elenasrc3/engine/syntaxtree.h index 6e97a63fc2..a153bca827 100644 --- a/elenasrc3/engine/syntaxtree.h +++ b/elenasrc3/engine/syntaxtree.h @@ -210,6 +210,8 @@ namespace elena_lang EnumArgParameter = 0x000114, NillableInfo = 0x000115, HasStaticConstructor = 0x000116, + AsyncInvoker = 0x000117, + SourceRef = 0x000118, Column = 0x000201, Row = 0x000202, diff --git a/elenasrc3/engine/x86_64compiler.cpp b/elenasrc3/engine/x86_64compiler.cpp index 53b523d752..18cede1a18 100644 --- a/elenasrc3/engine/x86_64compiler.cpp +++ b/elenasrc3/engine/x86_64compiler.cpp @@ -45,7 +45,7 @@ inline void x86_64FreeStack(int args, MemoryWriter* code) if (args < 0x80) { code->writeByte(0x48); code->writeWord(0xC483); - code->writeByte(args << 3); + code->writeByte((char)(args << 3)); } else { code->writeByte(0x48); @@ -171,12 +171,12 @@ void X86_64JITCompiler :: prepare( JITCompiler64::prepare(loader, imageProvider, helper, &lh, _settings, virtualMode); } -void X86_64JITCompiler :: writeImm9(MemoryWriter* writer, int value, int type) +void X86_64JITCompiler :: writeImm9(MemoryWriter* writer, int, int) { throw InternalError(errNotImplemented); } -void X86_64JITCompiler :: writeImm12(MemoryWriter* writer, int value, int type) +void X86_64JITCompiler :: writeImm12(MemoryWriter* writer, int, int) { throw InternalError(errNotImplemented); } diff --git a/elenasrc3/engine/x86_64compiler.h b/elenasrc3/engine/x86_64compiler.h index ee56433339..dc4aaee135 100644 --- a/elenasrc3/engine/x86_64compiler.h +++ b/elenasrc3/engine/x86_64compiler.h @@ -51,7 +51,7 @@ namespace elena_lang void writeImm12(MemoryWriter* writer, int value, int type) override; void alignCode(MemoryWriter& writer, pos_t alignment, bool isText) override; - void alignJumpAddress(MemoryWriter& writer) override + void alignJumpAddress(MemoryWriter&) override { // must be implemented } diff --git a/elenasrc3/engine/x86relocation.h b/elenasrc3/engine/x86relocation.h index 77271c40ef..f301c78825 100644 --- a/elenasrc3/engine/x86relocation.h +++ b/elenasrc3/engine/x86relocation.h @@ -105,7 +105,7 @@ inline void relocate64(pos_t pos, ref_t mask, ref_t reference, void* address, Ad } } -inline void relocateImport(pos_t pos, ref_t mask, ref_t reference, void* address, AddressSpace* space) +inline void relocateImport(pos_t, ref_t mask, ref_t reference, void* address, AddressSpace* space) { switch (mask) { case mskImportRef32: @@ -121,7 +121,7 @@ inline void relocateImport(pos_t pos, ref_t mask, ref_t reference, void* address } } -inline void relocateElfImport(pos_t pos, ref_t mask, ref_t reference, void* address, AddressSpace* space) +inline void relocateElfImport(pos_t, ref_t mask, ref_t reference, void* address, AddressSpace* space) { switch (mask) { case mskImportRef32: @@ -155,7 +155,7 @@ inline void relocateElfImport(pos_t pos, ref_t mask, ref_t reference, void* addr } } -inline void relocateElf64Import(pos_t pos, ref_t mask, ref_t reference, void* address, AddressSpace* space) +inline void relocateElf64Import(pos_t, ref_t mask, ref_t reference, void* address, AddressSpace* space) { switch (mask) { case mskImportRef64: diff --git a/elenasrc3/gui/controller.cpp b/elenasrc3/gui/controller.cpp index 23d145f0a1..e02d9ab90e 100644 --- a/elenasrc3/gui/controller.cpp +++ b/elenasrc3/gui/controller.cpp @@ -125,13 +125,13 @@ void TextViewController :: redo(TextViewModelBase* model) bool TextViewController :: copyToClipboard(TextViewModelBase* model, ClipboardBase* clipboard) { auto docView = model->DocView(); - if (docView->hasSelection()) { - if (clipboard->copyToClipboard(docView)) { - notifyOnClipboardOperation(clipboard); - return true; - } + if (clipboard->copyToClipboard(docView, docView->hasSelection())) { + notifyOnClipboardOperation(clipboard); + + return true; } + return false; } @@ -235,7 +235,10 @@ void TextViewController :: deleteText(TextViewModelBase* model) DocumentChangeStatus status = {}; auto docView = model->DocView(); if (!docView->isReadOnly()) { - docView->eraseSelection(status); + if (docView->hasSelection()) { + docView->eraseSelection(status); + } + else docView->eraseLine(status); } notifyTextModelChange(model, status); diff --git a/elenasrc3/gui/document.cpp b/elenasrc3/gui/document.cpp index 92c70a3381..a413c32771 100644 --- a/elenasrc3/gui/document.cpp +++ b/elenasrc3/gui/document.cpp @@ -845,14 +845,14 @@ void DocumentView :: insertNewLine(DocumentChangeStatus& changeStatus) status.rowDifference += (_text->getRowCount() - rowCount); } -void DocumentView :: insertLine(DocumentChangeStatus& changeStatus, const_text_t text, disp_t length) +void DocumentView :: insertLine(DocumentChangeStatus& changeStatus, const_text_t text, size_t length) { int rowCount = _text->getRowCount(); eraseSelection(changeStatus); _text->insertLine(_caret, text, length); - _caret.moveOn(length); + _caret.moveOn((disp_t)length); changeStatus.textChanged = true; setCaret(_caret.getCaret(), false, changeStatus); @@ -942,11 +942,15 @@ void DocumentView :: eraseLine(DocumentChangeStatus& changeStatus) { int rowCount = _text->getRowCount(); + Point caret = _caret.getCaret(true); + _caret.moveTo(0, _caret.row()); _text->eraseLine(_caret, _caret.length()); _text->eraseChar(_caret); + setCaret(caret.x, caret.y, false, changeStatus); + changeStatus.textChanged = true; changeStatus.caretChanged = true; @@ -970,7 +974,7 @@ void DocumentView :: duplicateLine(DocumentChangeStatus& changeStatus) _caret.moveTo(0, caret.y + 1); _text->insertNewLine(_caret); - _text->insertLine(_caret, buffer, length); + _text->insertLine(_caret, buffer, abs(length)); freestr(buffer); @@ -994,7 +998,7 @@ void DocumentView :: copyText(text_c* text, disp_t length) void DocumentView :: toLowercase(DocumentChangeStatus& changeStatus) { - disp_t selection = abs(_selection); + size_t selection = abs(_selection); if (selection > 0) { text_c* buffer = StrFactory::allocate(selection + 1, (text_str)nullptr); @@ -1022,7 +1026,7 @@ void DocumentView :: toLowercase(DocumentChangeStatus& changeStatus) void DocumentView :: toUppercase(DocumentChangeStatus& changeStatus) { - disp_t selection = abs(_selection); + size_t selection = abs(_selection); if (selection > 0) { text_c* buffer = StrFactory::allocate(selection + 1, (text_str)nullptr); @@ -1058,6 +1062,25 @@ void DocumentView :: copySelection(text_c* text) } } +void DocumentView :: copyCurrentLine(text_c* text) +{ + auto lineCaret = _caret; + lineCaret.moveTo(0, _caret.row()); + + auto nextLineCaret = lineCaret; + if (nextLineCaret.moveToNextBOL()) { + _text->copyTo(lineCaret, text, nextLineCaret.position() - lineCaret.position()); + } + else _text->copyTo(lineCaret, text, lineCaret.length()); +} + +disp_t DocumentView :: getCurrentLineLength() +{ + auto lineCaret = _caret; + + return lineCaret.length(); +} + void DocumentView :: undo(DocumentChangeStatus& changeStatus) { changeStatus.textChanged |= _undoBuffer.undo(_text, _caret); diff --git a/elenasrc3/gui/document.h b/elenasrc3/gui/document.h index b3ea5ab011..476497a77e 100644 --- a/elenasrc3/gui/document.h +++ b/elenasrc3/gui/document.h @@ -299,6 +299,7 @@ namespace elena_lang int getRowCount() const { return _text->getRowCount(); } int getMaxColumn() const { return _maxColumn; } disp_t getSelectionLength(); + disp_t getCurrentLineLength(); bool hasSelection() const { return (_selection != 0); } bool isReadOnly() { return status.readOnly; } @@ -358,6 +359,7 @@ namespace elena_lang void moveToFrame(DocumentChangeStatus& changeStatus, int column, int row, bool selecting); void copySelection(text_c* text); + void copyCurrentLine(text_c* text); void copyText(text_c* text, disp_t length); void insertChar(DocumentChangeStatus& changeStatus, text_c ch) @@ -366,7 +368,7 @@ namespace elena_lang } void insertChar(DocumentChangeStatus& changeStatus, text_c ch, size_t number); void insertNewLine(DocumentChangeStatus& changeStatus); - void insertLine(DocumentChangeStatus& changeStatus, const_text_t text, disp_t length); + void insertLine(DocumentChangeStatus& changeStatus, const_text_t text, size_t length); virtual void blockInserting(DocumentChangeStatus& changeStatus, const_text_t subs, size_t length); virtual void blockDeleting(DocumentChangeStatus& changeStatus, const_text_t subs, size_t length); diff --git a/elenasrc3/gui/gtklinux/gtktabbar.cpp b/elenasrc3/gui/gtklinux/gtktabbar.cpp index aa9290b16c..ceb50f2779 100644 --- a/elenasrc3/gui/gtklinux/gtktabbar.cpp +++ b/elenasrc3/gui/gtklinux/gtktabbar.cpp @@ -46,6 +46,11 @@ void TabBar :: onTabChange(int page_num) { } +void TabBar :: renameTab(int index, const char* title) +{ + set_tab_label_text(*get_nth_page(index), title); +} + /*Gtk::Widget* TabBar :: getTabControl(int index) const { if (index == -1) diff --git a/elenasrc3/gui/gtklinux/gtktabbar.h b/elenasrc3/gui/gtklinux/gtktabbar.h index 03cbe3b730..3defce1e4d 100644 --- a/elenasrc3/gui/gtklinux/gtktabbar.h +++ b/elenasrc3/gui/gtklinux/gtktabbar.h @@ -34,6 +34,8 @@ namespace elena_lang return get_current_page(); } + void renameTab(int index, const char* title); + Gtk::Widget* getCurrentControl(); TabBar(); diff --git a/elenasrc3/gui/guieditor.h b/elenasrc3/gui/guieditor.h index ec395fc5cf..194bac167d 100644 --- a/elenasrc3/gui/guieditor.h +++ b/elenasrc3/gui/guieditor.h @@ -36,7 +36,7 @@ namespace elena_lang class ClipboardBase { public: - virtual bool copyToClipboard(DocumentView* docView) = 0; + virtual bool copyToClipboard(DocumentView* docView, bool selectionMode) = 0; virtual void pasteFromClipboard(DocumentChangeStatus& status, DocumentView* docView) = 0; }; diff --git a/elenasrc3/gui/text.cpp b/elenasrc3/gui/text.cpp index db5c77242a..b783d56373 100644 --- a/elenasrc3/gui/text.cpp +++ b/elenasrc3/gui/text.cpp @@ -867,6 +867,8 @@ bool Text :: insertChar(TextBookmark& bookmark, text_c ch) return true; } + + bool Text :: insertNewLine(TextBookmark& bookmark) { validateBookmark(bookmark); @@ -921,6 +923,15 @@ bool Text :: eraseLine(TextBookmark& bookmark, size_t length) erase(bookmark, length, true); bookmark._length = NOTFOUND_POS; + + if (bookmark._offset >= (*bookmark._page).used) { + // HOTFIX : place the bookmark to the correct position + int col = bookmark._column; + int row = bookmark._row; + + bookmark.moveToClosestRow(row); + bookmark.moveTo(col, row); + } // bookmark.skipEmptyPages(); _rowCount = retrieveRowCount(); @@ -1292,7 +1303,9 @@ bool TextHistory :: undo(Text* text, TextBookmark& caret) #endif _locking = true; - caret.moveOn(position - caret.position()); + + disp_t disp = (int)position - (int)caret.position(); + caret.moveOn(disp); if (eraseMode) { // erase mode text->insertLine(caret, (text_t)line, length); @@ -1331,7 +1344,8 @@ bool TextHistory :: redo(Text* text, TextBookmark& caret) #endif _locking = true; - caret.moveOn(position - caret.position()); + disp_t disp = (int)position - (int)caret.position(); + caret.moveOn(disp); if (eraseMode) { // erase mode text->eraseLine(caret, length); diff --git a/elenasrc3/gui/windows/wintabbar.cpp b/elenasrc3/gui/windows/wintabbar.cpp index e739a1113f..08f1e5180a 100644 --- a/elenasrc3/gui/windows/wintabbar.cpp +++ b/elenasrc3/gui/windows/wintabbar.cpp @@ -317,4 +317,3 @@ void TabBar :: refresh() CustomTabBar::refresh(); } - diff --git a/elenasrc3/ide/gtklinux/gtkdialogs.cpp b/elenasrc3/ide/gtklinux/gtkdialogs.cpp index 0ae250431b..ce6f63632c 100644 --- a/elenasrc3/ide/gtklinux/gtkdialogs.cpp +++ b/elenasrc3/ide/gtklinux/gtkdialogs.cpp @@ -96,57 +96,76 @@ bool FileDialog :: openFiles(List& files) return true; } return false; +} + +bool FileDialog :: saveFile(path_t ext, PathString& path) +{ + Gtk::FileChooserDialog dialog(_caption, Gtk::FILE_CHOOSER_ACTION_SAVE); + dialog.set_transient_for(*_owner); + + if (!emptystr(_initialDir)) + dialog.set_current_folder (_initialDir); + + dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL); + dialog.add_button("_Save", Gtk::RESPONSE_OK); + + for (int i = 0; i < _filterCounter; i += 2) { + Glib::RefPtr filter_l = Gtk::FileFilter::create(); + + filter_l->set_name(_filter[i + 1]); + filter_l->add_pattern(_filter[i]); + dialog.add_filter(filter_l); + } + + int result = dialog.run(); + if (result == Gtk::RESPONSE_OK) { + std::string filename = dialog.get_filename(); + + path.copy(filename.c_str()); + return true; + } return false; } -bool FileDialog :: saveFile(path_t ext, PathString& path) +// --- MessageDialog --- + +int MessageDialog :: show(const char* message, Gtk::MessageType messageType, Gtk::ButtonsType buttonTypes, bool withCancel) { -// _struct.Flags = _defaultFlags | OFN_PATHMUSTEXIST; -// _struct.lpstrDefExt = ext; -// -// if (::GetSaveFileName(&_struct)) { -// path.copy(_fileName); -// -// return true; -// } - /*else */return false; + Gtk::MessageDialog dialog(message, false, messageType, buttonTypes, true); + dialog.set_transient_for(*_owner); + + if (withCancel) + dialog.add_button("Cancel", Gtk::ResponseType::RESPONSE_CANCEL); + + return dialog.run(); +} + +MessageDialogBase::Answer MessageDialog :: question(text_str message, text_str param) +{ + IdentifierString questionStr(message, param); + + return question(*questionStr); +} + +MessageDialogBase::Answer MessageDialog :: question(text_str message) +{ + int retVal = show(message, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true); + + if (retVal == Gtk::ResponseType::RESPONSE_YES) { + return Answer::Yes; + } + else if (retVal == Gtk::ResponseType::RESPONSE_CANCEL) { + return Answer::Cancel; + } + else return Answer::No; +} + +void MessageDialog :: info(text_str message) +{ + show(message, Gtk::MessageType::MESSAGE_INFO, Gtk::ButtonsType::BUTTONS_OK, false); } -//MessageDialogBase::Answer MessageDialog :: question(text_str message, text_str param) -//{ -// WideMessage wideMessage(message); -// wideMessage.append(param); -// -// int result = MsgBox::show(_owner->handle(), *wideMessage, MB_YESNOCANCEL | MB_ICONQUESTION); -// -// if (MsgBox::isYes(result)) { -// return Answer::Yes; -// } -// else if (MsgBox::isCancel(result)) { -// return Answer::Cancel; -// } -// else return Answer::No; -//} -// -//MessageDialogBase::Answer MessageDialog :: question(text_str message) -//{ -// int result = MsgBox::show(_owner->handle(), message, MB_YESNOCANCEL | MB_ICONQUESTION); -// -// if (MsgBox::isYes(result)) { -// return Answer::Yes; -// } -// else if (MsgBox::isCancel(result)) { -// return Answer::Cancel; -// } -// else return Answer::No; -//} -// -//void MessageDialog :: info(text_str message) -//{ -// ::MessageBox(_owner->handle(), message, APP_NAME, MB_OK | MB_ICONWARNING); -//} -// //// --- WinDialog --- // //BOOL CALLBACK WinDialog::DialogProc(HWND hWnd, size_t message, WPARAM wParam, LPARAM lParam) diff --git a/elenasrc3/ide/gtklinux/gtkdialogs.h b/elenasrc3/ide/gtklinux/gtkdialogs.h index 250d973c60..f98dbeb9af 100644 --- a/elenasrc3/ide/gtklinux/gtkdialogs.h +++ b/elenasrc3/ide/gtklinux/gtkdialogs.h @@ -53,23 +53,25 @@ namespace elena_lang FileDialog(Gtk::Window* owner, const char** filter, int filterCounter, const char* caption, const char* initialDir = nullptr); }; -// -// class MessageDialog : public MessageDialogBase -// { -// WindowBase* _owner; -// -// public: -// Answer question(text_str message, text_str param) override; -// Answer question(text_str message) override; -// -// void info(text_str message) override; -// -// MessageDialog(WindowBase* owner) -// { -// _owner = owner; -// } -// }; -// + + class MessageDialog : public MessageDialogBase + { + Gtk::Window* _owner; + + int show(const char* message, Gtk::MessageType messageType, Gtk::ButtonsType buttonTypes, bool withCancel); + + public: + Answer question(text_str message, text_str param) override; + Answer question(text_str message) override; + + void info(text_str message) override; + + MessageDialog(Gtk::Window* owner) + { + _owner = owner; + } + }; + // class WinDialog // { // protected: diff --git a/elenasrc3/ide/gtklinux/gtkide.cpp b/elenasrc3/ide/gtklinux/gtkide.cpp index 899e33721c..451a73b89c 100644 --- a/elenasrc3/ide/gtklinux/gtkide.cpp +++ b/elenasrc3/ide/gtklinux/gtkide.cpp @@ -134,10 +134,20 @@ const char* SOURCE_FILE_FILTER[] = "Any files" }; +const char* PROJECT_FILE_FILTER[] = +{ + "*.prj", + "ELENA project file", + "*", + "Any files" +}; + // --- GTKIDEWindow --- GTKIDEWindow :: GTKIDEWindow(IDEController* controller, IDEModel* model) - : fileDialog(this, SOURCE_FILE_FILTER, 4, OPEN_FILE_CAPTION, *model->projectModel.paths.lastPath) + : fileDialog(this, SOURCE_FILE_FILTER, 4, OPEN_FILE_CAPTION, *model->projectModel.paths.lastPath), + projectDialog(this, PROJECT_FILE_FILTER, 4, OPEN_PROJECT_CAPTION, *model->projectModel.paths.lastPath), + messageDialog(this) { _model = model; _controller = controller; diff --git a/elenasrc3/ide/gtklinux/gtkide.h b/elenasrc3/ide/gtklinux/gtkide.h index e6e654f079..a20e161c37 100644 --- a/elenasrc3/ide/gtklinux/gtkide.h +++ b/elenasrc3/ide/gtklinux/gtkide.h @@ -23,6 +23,8 @@ class GTKIDEWindow : public SDIWindow IDEController* _controller; FileDialog fileDialog; + FileDialog projectDialog; + MessageDialog messageDialog; void populateMenu(); @@ -33,7 +35,6 @@ class GTKIDEWindow : public SDIWindow } void on_menu_file_new_project() { - //_controller->doCreateProject(); } void on_menu_file_open_source() { @@ -43,7 +44,8 @@ class GTKIDEWindow : public SDIWindow } void on_menu_file_open_project() { - //_controller->doOpenProject(); + _controller->doOpenProject(fileDialog, projectDialog, messageDialog, _model); + //_recentProjectList.reload(); } void on_menu_file_quit() { @@ -51,11 +53,11 @@ class GTKIDEWindow : public SDIWindow } void on_menu_file_save() { - //_controller->doSave(false); + _controller->doSaveFile(fileDialog, _model, false, true); } void on_menu_file_saveas() { - //_controller->doSave(true); + _controller->doSaveFile(fileDialog, _model, true, true); } void on_menu_project_saveas() { @@ -67,7 +69,7 @@ class GTKIDEWindow : public SDIWindow } void on_menu_file_close() { - //_controller->doCloseFile(); + _controller->doCloseFile(fileDialog, messageDialog, _model); } void on_menu_file_closeall() { diff --git a/elenasrc3/ide/gtklinux/gtkidetextview.cpp b/elenasrc3/ide/gtklinux/gtkidetextview.cpp index ef084f3550..4957438ef8 100644 --- a/elenasrc3/ide/gtklinux/gtkidetextview.cpp +++ b/elenasrc3/ide/gtklinux/gtkidetextview.cpp @@ -17,6 +17,16 @@ BroadcasterBase* eventBroadcaster) _eventBroadcaster = eventBroadcaster; } +void IDETextViewFrame :: onDocumentModeChanged(int index, bool modifiedMode) +{ + IdentifierString title(_model->getDocumentName(index), modifiedMode ? "*" : ""); + + if (index == -1) + index = _model->getCurrentIndex(); + + renameTab(index - 1, *title); +} + void IDETextViewFrame :: on_text_model_change(TextViewModelEvent event) { if (test(event.status, STATUS_FRAME_CHANGED)) { @@ -26,6 +36,12 @@ void IDETextViewFrame :: on_text_model_change(TextViewModelEvent event) } } + if (event.changeStatus.modifiedChanged) { + auto docInfo = _model->DocView(); + + onDocumentModeChanged(-1, docInfo->isModified()); + } + auto client = getCurrentTextView(); if (client) client->onDocumentUpdate(event.changeStatus); diff --git a/elenasrc3/ide/gtklinux/gtkidetextview.h b/elenasrc3/ide/gtklinux/gtkidetextview.h index 394b89aada..14baaf4cb4 100644 --- a/elenasrc3/ide/gtklinux/gtkidetextview.h +++ b/elenasrc3/ide/gtklinux/gtkidetextview.h @@ -19,6 +19,7 @@ class IDETextViewFrame : public TextViewFrame protected: void onTabChange(int page_num) override; + void onDocumentModeChanged(int index, bool modifiedMode); public: void on_text_model_change(TextViewModelEvent event); diff --git a/elenasrc3/ide/gtklinux/main.cpp b/elenasrc3/ide/gtklinux/main.cpp index 3a40965883..9eb478d1e6 100644 --- a/elenasrc3/ide/gtklinux/main.cpp +++ b/elenasrc3/ide/gtklinux/main.cpp @@ -31,11 +31,12 @@ int main(int argc, char* argv[]) { Gtk::Main kit(argc, argv); - IDEModel ideModel; - GUISettinngs settings = { true }; TextViewSettings textViewSettings = { EOLMode::LF, false, 3 }; + + IDEModel ideModel(textViewSettings); + GUISettinngs settings = { true }; IDEController ideController(/*&outputProcess*/nullptr, /*&vmConsoleProcess*/nullptr, /*&debugProcess*/nullptr, &ideModel, - textViewSettings, CURRENT_PLATFORM, /*&pathHelper*/nullptr, /*compareFileModifiedTime*/nullptr); + CURRENT_PLATFORM, /*&pathHelper*/nullptr, /*compareFileModifiedTime*/nullptr); IDEFactory factory(&ideModel, &ideController, settings); GUIApp* app = factory.createApp(); diff --git a/elenasrc3/ide/idecommon.cpp b/elenasrc3/ide/idecommon.cpp index 3ee01f0505..92351733b7 100644 --- a/elenasrc3/ide/idecommon.cpp +++ b/elenasrc3/ide/idecommon.cpp @@ -159,7 +159,7 @@ void ContextBrowserBase :: populateQWORD(WatchContext* context, long long value) { String number; if (_model->hexadecimalMode) { - number.appendHex(value); + number.appendLongHex(value); number.append('h'); } else number.appendLong(value); diff --git a/elenasrc3/ide/idecommon.h b/elenasrc3/ide/idecommon.h index fab74e14cc..f073d45cc8 100644 --- a/elenasrc3/ide/idecommon.h +++ b/elenasrc3/ide/idecommon.h @@ -9,6 +9,7 @@ #include "elena.h" #include "guieditor.h" +//#include "ldbg_common.h" namespace elena_lang { @@ -244,19 +245,18 @@ namespace elena_lang virtual void debugThread() = 0; }; - // --- DebugProcessException --- - struct DebugProcessException - { - int code; - addr_t address; - }; - struct StartUpSettings { bool withExplicitConsole; bool includeAppPath2Paths; // applicable only for Windows }; + struct ExceptionInfo + { + int code; + addr_t address; + }; + // --- DebugProcessBase --- class DebugProcessBase { @@ -272,7 +272,7 @@ namespace elena_lang virtual void setStepMode() = 0; - virtual DebugProcessException* Exception() = 0; + virtual ExceptionInfo* Exception() = 0; virtual void resetException() = 0; virtual void initEvents() = 0; @@ -293,7 +293,7 @@ namespace elena_lang virtual addr_t getBaseAddress() = 0; virtual void* getState() = 0; - virtual addr_t getMemoryPtr(addr_t address) = 0; + //virtual addr_t getMemoryPtr(addr_t address) = 0; virtual addr_t getStackItem(int index, disp_t offset = 0) = 0; virtual addr_t getStackItemAddress(disp_t disp) = 0; diff --git a/elenasrc3/ide/ideversion.h b/elenasrc3/ide/ideversion.h index df3abe291c..9f785e85bc 100644 --- a/elenasrc3/ide/ideversion.h +++ b/elenasrc3/ide/ideversion.h @@ -1,2 +1,2 @@ -#define IDE_REVISION_NUMBER 31 +#define IDE_REVISION_NUMBER 37 diff --git a/elenasrc3/ide/sourceformatter.cpp b/elenasrc3/ide/sourceformatter.cpp index 2b4d6ec8d7..092f0396ab 100644 --- a/elenasrc3/ide/sourceformatter.cpp +++ b/elenasrc3/ide/sourceformatter.cpp @@ -29,26 +29,26 @@ const text_c lexChar = 'u'; const text_c* lexDFA[] = { - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeqataaaeeeeeeehooooooooooeeeeeeabbbbbbbbbbbbbbbbbbbbbbbbbbaaaababbbbbbbbbbbbbbbbbbbbbbbbbbfefab"), - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceaaaaaaeeeeeeeaaaaaaaaaaaeeeeeeabbbbbbbbbbbbbbbbbbbbbbbbbbaaaababbbbbbbbbbbbbbbbbbbbbbbbbbaeaab"), - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceaaaaaaeeeeeeeaaaaaaaaaaaeeeeeeaddddddddddddddddddddddddddaaaadaddddddddddddddddddddddddddaeaad"), - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeeeeeeeaaaaaaaaaaaeeeeeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaafffffffaaaaaaaaaaaffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaa"), - _T("gggggggggggggggggggggggggggggggggfggggggfffffffgggggggggggffffffgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggfffgg"), - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqataaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakaaaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeqataaaeeeeeeehooooooooooeeeeeeebbbbbbbbbbbbbbbbbbbbbbbbbbeaeebabbbbbbbbbbbbbbbbbbbbbbbbbbeeeab"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceaaaaaaeeeeeeeabbbbbbbbbbeeeeeeebbbbbbbbbbbbbbbbbbbbbbbbbbeaeebabbbbbbbbbbbbbbbbbbbbbbbbbbeeeab"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceaaaaaaeeeeeeeaddddddddddeeeeeeeddddddddddddddddddddddddddeaeedaddddddddddddddddddddddddddeeead"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeeeeeeeaaaaaaaaaaaeeeeeeebbbbbbbbbbbbbbbbbbbbbbbbbbeaeebabbbbbbbbbbbbbbbbbbbbbbbbbbaaaaa"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaafffffffaaaaaaaaaaafffffffaaaaaaaaaaaaaaaaaaaaaaaaaafaffaaaaaaaaaaaaaaaaaaaaaaaaaaaafffaa"), + _T("gggggggggggggggggggggggggggggggggfggggggfffffffgggggggggggfffffffggggggggggggggggggggggggggfgfgggggggggggggggggggggggggggggfffgg"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqataaaaaaaaaaaooooooooooaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaakaaaaigggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"), _T("jiiiiiiiiijiijiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), _T("kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkklkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"), _T("kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkmkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"), _T("nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - _T("ppppppppppppppppppppppppppppppppppppppppppppppppoooooooooopppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp"), - _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaafffffffaaaaaaaaaaaffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaa"), + _T("ppppppppppppppppppppppppppppppppppppppppppppppppoooooooooopppppppoooooopppppppppppppppppppppppppppppppppopppopppppoppppppppppppp"), + _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaafffffffaaaaaaaaaaaffffffaaaaaaaaaaaaaaaaaaaaaaaaaaafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaafffaa"), _T("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqrqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"), _T("ssssssssssssssssssssssssssssssssssqstsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaafffffffaaaaaaaaaaaffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaa"), - _T("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuquuuuuuuuuuuuuttttttttttuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu"), + _T("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuqutuuuuuuuuuuuttttttttttuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu"), _T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), }; diff --git a/elenasrc3/ide/vs/elide.vcxproj b/elenasrc3/ide/vs/elide.vcxproj index f23c486199..b08157eec1 100644 --- a/elenasrc3/ide/vs/elide.vcxproj +++ b/elenasrc3/ide/vs/elide.vcxproj @@ -100,12 +100,14 @@ true WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..;..\..\gui;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..;..\..\;..\..\gui;%(AdditionalIncludeDirectories) Windows true comctl32.lib shlwapi.lib %(AdditionalOptions) + lcommon.lib;ldebugger.lib;%(AdditionalDependencies) + ..\..\..\bin;%(AdditionalLibraryDirectories) true @@ -119,7 +121,7 @@ true WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..;..\..\engine;..;..\..\gui;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..;..\..;..\..\gui;%(AdditionalIncludeDirectories) Windows @@ -138,7 +140,7 @@ true _DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..;..\..\engine;..;..\..\gui;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..;..\..;..\..\gui;%(AdditionalIncludeDirectories) Windows @@ -157,7 +159,7 @@ true NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - ..\..\common;..\..\engine;..;..\..\engine;..;..\..\gui;%(AdditionalIncludeDirectories) + ..\..\common;..\..\engine;..;..\..;..\..\gui;%(AdditionalIncludeDirectories) Windows @@ -171,17 +173,10 @@ - - - - - - - @@ -218,21 +213,14 @@ - + - - - - - - - @@ -265,7 +253,7 @@ - + @@ -280,6 +268,14 @@ + + + {c7728dfb-e3b8-4ce0-bef5-f8369e6761ef} + + + {acc215c7-8ccf-4ad5-be40-a107dec72d4f} + + diff --git a/elenasrc3/ide/windows/factory.cpp b/elenasrc3/ide/windows/factory.cpp index 0e5eb50758..86addad4b2 100644 --- a/elenasrc3/ide/windows/factory.cpp +++ b/elenasrc3/ide/windows/factory.cpp @@ -187,6 +187,8 @@ inline void canonicalize(PathString& path) // --- IDEFactory --- +PathSettings IDEFactory::_pathSettings; + IDEFactory :: IDEFactory(HINSTANCE instance, IDEModel* ideModel, IDEController* controller, GUISettinngs settings) @@ -200,13 +202,6 @@ IDEFactory :: IDEFactory(HINSTANCE instance, IDEModel* ideModel, _model = ideModel; _controller = controller; - wchar_t appPath[MAX_PATH]; - ::GetModuleFileName(NULL, appPath, MAX_PATH); - ::PathRemoveFileSpec(appPath); - - _pathSettings.appPath.copy(appPath); - - _model->projectModel.paths.appPath.copy(*_pathSettings.appPath); _model->projectModel.paths.compilerPath.copy(CLI_PATH); _model->projectModel.paths.vmTerminalPath.copy(ELT_CLI_PATH); @@ -224,6 +219,17 @@ IDEFactory :: IDEFactory(HINSTANCE instance, IDEModel* ideModel, canonicalize(_model->projectModel.paths.libraryRoot); } +void IDEFactory :: initPathSettings(IDEModel* ideModel) +{ + wchar_t appPath[MAX_PATH]; + ::GetModuleFileName(NULL, appPath, MAX_PATH); + ::PathRemoveFileSpec(appPath); + + _pathSettings.appPath.copy(appPath); + + ideModel->projectModel.paths.appPath.copy(*_pathSettings.appPath); +} + void IDEFactory :: registerClasses() { // Initialize global strings diff --git a/elenasrc3/ide/windows/factory.h b/elenasrc3/ide/windows/factory.h index 6c0775c310..d3ba764780 100644 --- a/elenasrc3/ide/windows/factory.h +++ b/elenasrc3/ide/windows/factory.h @@ -22,16 +22,16 @@ namespace elena_lang class IDEFactory : public GUIFactoryBase, public ViewFactoryBase { protected: - FontFactory _fontFactory; - ViewStyles _styles; - StyleInfo* _schemes[3]; - GUISettinngs _settings; - PathSettings _pathSettings; + static PathSettings _pathSettings; - HINSTANCE _instance; + FontFactory _fontFactory; + ViewStyles _styles; + StyleInfo* _schemes[3]; + GUISettinngs _settings; + HINSTANCE _instance; - IDEModel* _model; - IDEController* _controller; + IDEModel* _model; + IDEController* _controller; void registerClasses(); @@ -54,6 +54,8 @@ namespace elena_lang int vmConsoleOutput, int toolBarControl, int contextEditor, int textIndex); public: + static void initPathSettings(IDEModel* ideModel); + void reloadStyles(TextViewModelBase* viewModel) override; void styleControl(GUIControlBase* control) override; diff --git a/elenasrc3/ide/windows/main.cpp b/elenasrc3/ide/windows/main.cpp index 863c22ec24..ccf7efbb6a 100644 --- a/elenasrc3/ide/windows/main.cpp +++ b/elenasrc3/ide/windows/main.cpp @@ -9,7 +9,7 @@ #include "ideview.h" #include "windows/wincommon.h" #include "windows/win32controller.h" -#include "windows/win32debugprocess.h" +#include "windows/win32debugadapter.h" #include "windows/windialogs.h" #include "text.h" @@ -58,7 +58,7 @@ bool compareFileModifiedTime(path_t sour, path_t dest) return sourceDT > moduleDT; } -typedef Win32DebugProcess DebugProcess; +typedef Win32DebugAdapter DebugProcess; // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); @@ -85,7 +85,9 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, DebugProcess debugProcess; IDEController ideController(&outputProcess, &vmConsoleProcess, &debugProcess, &ideModel, CURRENT_PLATFORM, &pathHelper, compareFileModifiedTime); - IDEFactory factory(hInstance, &ideModel, &ideController, guiSettings); + + // NOTE : it must be initialized before factory / controller + IDEFactory::initPathSettings(&ideModel); ideModel.sourceViewModel.refreshSettings(); @@ -97,6 +99,8 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, sysConfigPath.combine(_T("elc60.cfg")); ideController.loadSystemConfig(&ideModel, *sysConfigPath, TEMPLATE_XPATH, TARGET_XPATH); + IDEFactory factory(hInstance, &ideModel, &ideController, guiSettings); + GUIApp* app = factory.createApp(); GUIControlBase* ideWindow = factory.createMainWindow(app, &outputProcess, &vmConsoleProcess); diff --git a/elenasrc3/ide/windows/win32debugadapter.cpp b/elenasrc3/ide/windows/win32debugadapter.cpp new file mode 100644 index 0000000000..f7b493d217 --- /dev/null +++ b/elenasrc3/ide/windows/win32debugadapter.cpp @@ -0,0 +1,220 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Engine +// +// This file contains the Win32 Debugger adapter class implementation +// (C)2021-2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "common.h" +//--------------------------------------------------------------------------- +#include "windows/win32debugadapter.h" + +#ifdef _MSC_VER + +#include + +#endif + +#include "eng/messages.h" + +using namespace elena_lang; + +// --- main thread that is the debugger residing over a debuggee --- + +BOOL WINAPI debugEventThread(DebugControllerBase* controller) +{ + controller->debugThread(); + + ExitThread(TRUE); + + return TRUE; +} + +// --- Win32DebugProcess --- + +Win32DebugAdapter :: Win32DebugAdapter() + : _debugProcess(CONSOLE_OUTPUT_TEXT), _threadId(NULL) +{ +} + +bool Win32DebugAdapter :: startProgram(path_t exePath, path_t cmdLine, path_t appPath, StartUpSettings& startUpSettings) +{ + if (_debugProcess.startProcess(exePath.str(), cmdLine.str(), appPath.str(), + startUpSettings.includeAppPath2Paths, startUpSettings.withExplicitConsole)) + { + _debugProcess.processEvent(INFINITE); + + return true; + } + return false; +} + +bool Win32DebugAdapter :: startThread(DebugControllerBase* controller) +{ + HANDLE hThread = CreateThread(nullptr, 4096, + (LPTHREAD_START_ROUTINE)debugEventThread, + (LPVOID)controller, + 0, &_threadId); + + if (!hThread) { + return false; + } + else ::CloseHandle(hThread); + + return true; +} + +bool Win32DebugAdapter :: proceed(int timeout) +{ + _debugProcess.processEvent(timeout); + + return !_debugProcess.isTrapped(); +} + +void Win32DebugAdapter :: resetException() +{ + _exception.address = 0; + _exception.code = 0; + + _debugProcess.resetException(); +} + +void Win32DebugAdapter :: run() +{ + _debugProcess.continueProcess(); +} + +void Win32DebugAdapter :: activate() +{ + _debugProcess.activateWindow(); +} + +void Win32DebugAdapter :: stop() +{ + _debugProcess.stop(); +} + +void Win32DebugAdapter :: reset() +{ + _debugProcess.reset(); +} + +addr_t Win32DebugAdapter :: findEntryPoint(path_t programPath) +{ + return _debugProcess.findEntryPoint(programPath); +} + +bool Win32DebugAdapter :: isInitBreakpoint() +{ + return _debugProcess.isInitBreakpoint(); +} + +addr_t Win32DebugAdapter :: getBaseAddress() +{ + return _debugProcess.getBaseAddress(); +} + +bool Win32DebugAdapter :: findSignature(StreamReader& reader, char* signature, pos_t length) +{ + return _debugProcess.findSignature(reader, signature, length); +} + +void Win32DebugAdapter :: setBreakpoint(addr_t address, bool withStackLevelControl) +{ + _debugProcess.setBreakpoint(address, withStackLevelControl); +} + +void Win32DebugAdapter :: addBreakpoint(addr_t address) +{ + _debugProcess.addBreakpoint(address); +} + +void Win32DebugAdapter :: removeBreakpoint(addr_t address) +{ + _debugProcess.removeBreakpoint(address); +} + +void Win32DebugAdapter :: setStepMode() +{ + _debugProcess.setStepMode(); +} + +void Win32DebugAdapter :: addStep(addr_t address, void* state) +{ + _debugProcess.addStep(address, state); +} + +int Win32DebugAdapter :: getDataOffset() +{ + return sizeof(addr_t); +} + +void* Win32DebugAdapter :: getState() +{ + return _debugProcess.getState(); +} + +addr_t Win32DebugAdapter :: getClassVMT(addr_t address) +{ + return _debugProcess.getClassVMT(address); +} + +addr_t Win32DebugAdapter :: getStackItemAddress(disp_t disp) +{ + return _debugProcess.getStackItemAddress(disp); +} + +addr_t Win32DebugAdapter :: getStackItem(int index, disp_t offset) +{ + return _debugProcess.getStackItem(index, offset); +} + +unsigned short Win32DebugAdapter :: getWORD(addr_t address) +{ + return _debugProcess.getWORD(address); +} + +unsigned Win32DebugAdapter :: getDWORD(addr_t address) +{ + return _debugProcess.getDWORD(address); +} + +char Win32DebugAdapter :: getBYTE(addr_t address) +{ + return _debugProcess.getBYTE(address); +} + +unsigned long long Win32DebugAdapter :: getQWORD(addr_t address) +{ + return _debugProcess.getQWORD(address); +} + +double Win32DebugAdapter :: getFLOAT64(addr_t address) +{ + return _debugProcess.getFLOAT64(address); +} + +ref_t Win32DebugAdapter :: getClassFlags(addr_t vmtAddress) +{ + return _debugProcess.getClassFlags(vmtAddress); +} + +addr_t Win32DebugAdapter :: getField(addr_t address, int index) +{ + return _debugProcess.getField(address, index); +} + +addr_t Win32DebugAdapter :: getFieldAddress(addr_t address, disp_t disp) +{ + return _debugProcess.getFieldAddress(address, disp); +} + +size_t Win32DebugAdapter :: getArrayLength(addr_t address) +{ + return _debugProcess.getArrayLength(address); +} + +bool Win32DebugAdapter :: readDump(addr_t address, char* s, pos_t length) +{ + return _debugProcess.readDump(address, s, length); +} diff --git a/elenasrc3/ide/windows/win32debugadapter.h b/elenasrc3/ide/windows/win32debugadapter.h new file mode 100644 index 0000000000..64e2547d0b --- /dev/null +++ b/elenasrc3/ide/windows/win32debugadapter.h @@ -0,0 +1,139 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Engine +// +// This file contains the Win32 Debugger Adapter class header +// (C)2021-2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef WIN32DEBUGADAPTER_H +#define WIN32DEBUGADAPTER_H + +#include "idecommon.h" +#include "ldebugger/windows/win32debugprocess.h" +#include "windows/winevents.h" + +namespace elena_lang +{ + // --- DebugEventManager --- + typedef EventManager DebugEventManager; + + // --- Win32DebugAdapter --- + class Win32DebugAdapter : public DebugProcessBase + { + Win32DebugProcess _debugProcess; + DebugEventManager _events; + + ExceptionInfo _exception; + + DWORD _threadId; + + public: + void initEvents() override + { + _events.init(DEBUG_ACTIVE); + } + void setEvent(int event) override + { + _events.setEvent(event); + } + void resetEvent(int event) override + { + _events.resetEvent(event); + } + int waitForAnyEvent() override + { + return _events.waitForAnyEvent(); + } + bool waitForEvent(int event, int timeout) override + { + return _events.waitForEvent(event, timeout); + } + void clearEvents() override + { + _events.close(); + } + + void resetException() override; + + ExceptionInfo* Exception() override + { + auto debugException = _debugProcess.getException(); + if (debugException) { + _exception.address = debugException->address; + _exception.code = debugException->code; + + return &_exception; + } + + return nullptr; + } + + bool isStarted() override + { + return _debugProcess.isStarted(); + } + + bool isTrapped() override + { + return _debugProcess.isTrapped(); + } + + bool isInitBreakpoint() override; + + void initHook() override + { + _debugProcess.initHook(); + } + + addr_t findEntryPoint(path_t programPath) override; + + bool findSignature(StreamReader& reader, char* signature, pos_t length) override; + + bool startProgram(path_t exePath, path_t cmdLine, path_t appPath, StartUpSettings& startUpSettings) override; + + bool proceed(int timeout) override; + void run() override; + void stop() override; + void reset() override; + void activate() override; + + void setStepMode() override; + + bool startThread(DebugControllerBase* controller) override; + + int getDataOffset() override; + + addr_t getBaseAddress() override; + void* getState() override; + + ref_t getClassFlags(addr_t vmtAddress) override; + + addr_t getClassVMT(addr_t address) override; + addr_t getStackItem(int index, disp_t offset = 0) override; + addr_t getStackItemAddress(disp_t disp) override; + + addr_t getField(addr_t address, int index) override; + addr_t getFieldAddress(addr_t address, disp_t disp) override; + + //addr_t getMemoryPtr(addr_t address) override; + char getBYTE(addr_t address) override; + unsigned short getWORD(addr_t address) override; + unsigned getDWORD(addr_t address) override; + unsigned long long getQWORD(addr_t address) override; + double getFLOAT64(addr_t address) override; + + size_t getArrayLength(addr_t address) override; + + void setBreakpoint(addr_t address, bool withStackLevelControl) override; + void addBreakpoint(addr_t address) override; + void removeBreakpoint(addr_t address) override; + + void addStep(addr_t address, void* current) override; + + bool readDump(addr_t address, char* s, pos_t length); + + Win32DebugAdapter(); + }; +} + +#endif // WIN32DEBUGADAPTER_H diff --git a/elenasrc3/ide/windows/win32debugprocess.h b/elenasrc3/ide/windows/win32debugprocess.h deleted file mode 100644 index f53c37e522..0000000000 --- a/elenasrc3/ide/windows/win32debugprocess.h +++ /dev/null @@ -1,249 +0,0 @@ -//--------------------------------------------------------------------------- -// E L E N A P r o j e c t: ELENA Engine -// -// This file contains the Win32 Debugger class and its helpers header -// (C)2021-2025, by Aleksey Rakov -//--------------------------------------------------------------------------- - -#ifndef WIN32DEBUGPROCESS_H -#define WIN32DEBUGPROCESS_H - -#include "idecommon.h" -#include "windows/winevents.h" - -namespace elena_lang -{ - // --- DebugEventManager --- - typedef EventManager DebugEventManager; - - class Win32DebugProcess; - struct Win32BreakpointContext; - - // --- Win32ThreadBreakpoint --- - struct Win32ThreadBreakpoint - { - bool software; - bool hardware; - addr_t next; - addr_t stackLevel; - - void clearSoftware() - { - software = false; - next = 0; - } - - Win32ThreadBreakpoint() - { - hardware = software = false; - stackLevel = next = 0; - } - }; - - // --- Win32ThreadContext --- - struct Win32ThreadContext - { - friend class Win32DebugProcess; - friend struct Win32BreakpointContext; - - protected: - void* state; - HANDLE hProcess; - HANDLE hThread; - CONTEXT context; - - public: - Win32ThreadBreakpoint breakpoint; - - bool readDump(addr_t address, char* dump, size_t length); - void writeDump(addr_t address, char* dump, size_t length); - - void refresh(); - - void setTrapFlag(); - void resetTrapFlag(); - void setHardwareBreakpoint(addr_t breakpoint); - void clearHardwareBreakpoint(); - - unsigned char setSoftwareBreakpoint(addr_t breakpoint); - void clearSoftwareBreakpoint(addr_t breakpoint, unsigned char substitute); - - void setIP(addr_t address); - - Win32ThreadContext(HANDLE hProcess, HANDLE hThread); - }; - - // --- BreakpointContext --- - struct Win32BreakpointContext - { - Map breakpoints; - - void addBreakpoint(addr_t address, Win32ThreadContext* context, bool started); - void removeBreakpoint(addr_t address, Win32ThreadContext* context, bool started); - void setSoftwareBreakpoints(Win32ThreadContext* context); - void setHardwareBreakpoint(addr_t address, Win32ThreadContext* context, bool withStackLevelControl); - - bool processStep(Win32ThreadContext* context, bool stepMode); - bool processBreakpoint(Win32ThreadContext* context); - - void clear(); - - Win32BreakpointContext(); - }; - - // --- Win32DebugProcessException --- - struct Win32DebugProcessException : DebugProcessException - { - - }; - - // --- Win32DebugProcess --- - class Win32DebugProcess : public DebugProcessBase - { - typedef Map ThreadContextes; - typedef MemoryMap StepMap; - - class ConsoleHelper - { - public: - void printText(const char* s); - void waitForAnyKey(); - }; - - protected: - DebugEventManager _events; - Win32BreakpointContext _breakpoints; - ThreadContextes _threads; - Win32ThreadContext* _current; - - addr_t init_breakpoint; - addr_t minAddress, maxAddress; - addr_t baseAddress; - - DWORD threadId; - bool started; - bool trapped; - bool stepMode; - bool needToHandle; - bool needToFreeConsole; - - DWORD dwCurrentProcessId; - DWORD dwCurrentThreadId; - DWORD dwDebugeeProcessId; - - StepMap steps; - - Win32DebugProcessException exception; - - bool startProcess(const wchar_t* exePath, const wchar_t* cmdLine, const wchar_t* appPath, - StartUpSettings& startUpSettings); - - void continueProcess(); - void processEvent(DWORD timeout); - void processException(EXCEPTION_DEBUG_INFO* exception); - void processStep(); - void processEnd(); - - public: - void initEvents() override - { - _events.init(DEBUG_ACTIVE); - } - void setEvent(int event) override - { - _events.setEvent(event); - } - void resetEvent(int event) override - { - _events.resetEvent(event); - } - int waitForAnyEvent() override - { - return _events.waitForAnyEvent(); - } - bool waitForEvent(int event, int timeout) override - { - return _events.waitForEvent(event, timeout); - } - void clearEvents() override - { - _events.close(); - } - - void resetException() override; - - DebugProcessException* Exception() override - { - return exception.code == 0 ? nullptr : &exception; - } - - bool isStarted() override - { - return started; - } - - bool isTrapped() override - { - return trapped; - } - - bool isInitBreakpoint() override; - - void initHook() override { init_breakpoint = INVALID_ADDR; } - - addr_t findEntryPoint(path_t programPath) override; - - bool findSignature(StreamReader& reader, char* signature, pos_t length) override; - - bool startProgram(path_t exePath, path_t cmdLine, path_t appPath, StartUpSettings& startUpSettings) override; - - bool proceed(int timeout) override; - void run() override; - void stop() override; - void reset() override; - void activate() override; - - void setStepMode() override; - - bool startThread(DebugControllerBase* controller) override; - - int getDataOffset() override; - - addr_t getBaseAddress() override; - void* getState() override; - - ref_t getClassFlags(addr_t vmtAddress) override; - - addr_t getClassVMT(addr_t address) override; - addr_t getStackItem(int index, disp_t offset = 0) override; - addr_t getStackItemAddress(disp_t disp) override; - - addr_t getField(addr_t address, int index) override; - addr_t getFieldAddress(addr_t address, disp_t disp) override; - - addr_t getMemoryPtr(addr_t address) override; - char getBYTE(addr_t address) override; - unsigned short getWORD(addr_t address) override; - unsigned getDWORD(addr_t address) override; - unsigned long long getQWORD(addr_t address) override; - double getFLOAT64(addr_t address) override; - - size_t getArrayLength(addr_t address) override; - - void setBreakpoint(addr_t address, bool withStackLevelControl) override; - void addBreakpoint(addr_t address) override; - void removeBreakpoint(addr_t address) override; - - void addStep(addr_t address, void* current) override; - - bool readDump(addr_t address, char* s, pos_t length) override - { - return _current->readDump(address, s, length); - } - - Win32DebugProcess(); - }; - -} - -#endif diff --git a/elenasrc3/ide/windows/winide.cpp b/elenasrc3/ide/windows/winide.cpp index 3195f5dcd7..b76dfcbeac 100644 --- a/elenasrc3/ide/windows/winide.cpp +++ b/elenasrc3/ide/windows/winide.cpp @@ -67,15 +67,24 @@ void Clipboard :: freeBuffer(HGLOBAL buffer) ::GlobalUnlock(buffer); } -bool Clipboard :: copyToClipboard(DocumentView* docView) +bool Clipboard :: copyToClipboard(DocumentView* docView, bool selectionMode) { if (begin()) { clear(); - HGLOBAL buffer = createBuffer(docView->getSelectionLength()); - wchar_t* text = allocateBuffer(buffer); + HGLOBAL buffer = nullptr; + if (selectionMode) { + buffer = createBuffer(docView->getSelectionLength()); + wchar_t* text = allocateBuffer(buffer); + + docView->copySelection(text); + } + else { + buffer = createBuffer(docView->getCurrentLineLength() + 2); + wchar_t* text = allocateBuffer(buffer); - docView->copySelection(text); + docView->copyCurrentLine(text); + } freeBuffer(buffer); copy(buffer); @@ -178,7 +187,7 @@ void IDENotificationFormatter :: sendTextContextMenuEvent(ContextMenuEvent* even ContextMenuNMHDR nw = {}; nw.x = event->X(); - nw.y = event->X(); + nw.y = event->Y(); nw.hasSelection = event->HasSelection(); app->notify(EVENT_TEXT_CONTEXTMENU, (NMHDR*)&nw); @@ -305,6 +314,11 @@ void IDEWindow :: saveFile() _controller->doSaveFile(fileDialog, _model, false, true); } +void IDEWindow::saveFileAs() +{ + _controller->doSaveFile(fileDialog, _model, true, true); +} + void IDEWindow::saveAll() { _controller->doSaveAll(fileDialog, projectDialog, _model); @@ -720,6 +734,9 @@ bool IDEWindow :: onCommand(int command) case IDM_FILE_SAVE: saveFile(); break; + case IDM_FILE_SAVEAS: + saveFileAs(); + break; case IDM_FILE_SAVEALL: saveAll(); break; @@ -1043,8 +1060,6 @@ void IDEWindow :: onContextMenu(ContextMenuNMHDR* rec) ContextMenu* menu = static_cast(_children[_model->ideScheme.editorContextMenu]); - enableMenuItemById(IDM_EDIT_CUT, rec->hasSelection, true); - enableMenuItemById(IDM_EDIT_COPY, rec->hasSelection, true); enableMenuItemById(IDM_EDIT_PASTE, Clipboard::isAvailable(), true); menu->show(_handle, p); @@ -1187,16 +1202,13 @@ void IDEWindow :: onLayoutChange() enableMenuItemById(IDM_EDIT_UNDO, false, true); enableMenuItemById(IDM_EDIT_REDO, false, true); - enableMenuItemById(IDM_EDIT_CUT, false, true); - enableMenuItemById(IDM_EDIT_COPY, false, true); - enableMenuItemById(IDM_EDIT_PASTE, false, true); - enableMenuItemById(IDM_PROJECT_INCLUDE, false, false); enableMenuItemById(IDM_PROJECT_EXCLUDE, false, false); } - else { - enableMenuItemById(IDM_EDIT_PASTE, true, true); - } + + enableMenuItemById(IDM_EDIT_CUT, !empty, true); + enableMenuItemById(IDM_EDIT_COPY, !empty, true); + enableMenuItemById(IDM_EDIT_PASTE, !empty, true); enableMenuItemById(IDM_EDIT_DELETE, !empty, false); enableMenuItemById(IDM_EDIT_COMMENT, !empty, false); @@ -1349,8 +1361,6 @@ void IDEWindow :: onDocumentUpdate(DocumentChangeStatus& changeStatus) bool isSelected = docInfo ? docInfo->hasSelection() : false; - enableMenuItemById(IDM_EDIT_COPY, isSelected, true); - enableMenuItemById(IDM_EDIT_CUT, isSelected, true); menu->enableMenuItemById(IDM_EDIT_COMMENT, isSelected); menu->enableMenuItemById(IDM_EDIT_UNCOMMENT, isSelected); menu->enableMenuItemById(IDM_EDIT_DELETE, isSelected); diff --git a/elenasrc3/ide/windows/winide.h b/elenasrc3/ide/windows/winide.h index db4625e20a..91501a2d9a 100644 --- a/elenasrc3/ide/windows/winide.h +++ b/elenasrc3/ide/windows/winide.h @@ -75,7 +75,7 @@ namespace elena_lang public: static bool isAvailable(); - bool copyToClipboard(DocumentView* docView) override; + bool copyToClipboard(DocumentView* docView, bool selectionMode) override; void pasteFromClipboard(DocumentChangeStatus& status, DocumentView* docView) override; Clipboard(ControlBase* owner); @@ -202,6 +202,7 @@ namespace elena_lang void newFile(); void openFile(); void saveFile(); + void saveFileAs(); void saveAll(); void saveProject(); void closeFile(); diff --git a/elenasrc3/ldebugger/ldbg_common.h b/elenasrc3/ldebugger/ldbg_common.h new file mode 100644 index 0000000000..bb8f6a2651 --- /dev/null +++ b/elenasrc3/ldebugger/ldbg_common.h @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Engine +// +// This file contains the Win32 Debugger class header +// (C)2021-2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef LDBG_COMMON_H +#define LDBG_COMMON_H + +namespace elena_lang +{ + // --- DebugProcessException --- + struct DebugProcessException + { + int code; + addr_t address; + }; +} + +#endif // LDBG_COMMON_H \ No newline at end of file diff --git a/elenasrc3/ldebugger/vs/framework.h b/elenasrc3/ldebugger/vs/framework.h new file mode 100644 index 0000000000..3209b4abe5 --- /dev/null +++ b/elenasrc3/ldebugger/vs/framework.h @@ -0,0 +1,3 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers diff --git a/elenasrc3/ldebugger/vs/ldebugger.vcxproj b/elenasrc3/ldebugger/vs/ldebugger.vcxproj new file mode 100644 index 0000000000..d9cde9093d --- /dev/null +++ b/elenasrc3/ldebugger/vs/ldebugger.vcxproj @@ -0,0 +1,168 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {acc215c7-8ccf-4ad5-be40-a107dec72d4f} + ldebugger + 10.0 + + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + ..\..\..\bin\ + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + + ..;..\..\common;..\..;%(AdditionalIncludeDirectories) + + + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + ..;..\..\common;..\..;%(AdditionalIncludeDirectories) + + + + + true + true + true + + + + + Level3 + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + + ..;..\..\common;..\..;%(AdditionalIncludeDirectories) + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + ..;..\..\common;..\..;%(AdditionalIncludeDirectories) + + + + + true + true + true + + + + + + + + + + Create + Create + Create + Create + + + + + {c7728dfb-e3b8-4ce0-bef5-f8369e6761ef} + + + {49f68d87-f240-4e39-922d-219ee1601240} + + + + + + \ No newline at end of file diff --git a/elenasrc3/ide/windows/win32debugprocess.cpp b/elenasrc3/ldebugger/windows/win32debugprocess.cpp similarity index 76% rename from elenasrc3/ide/windows/win32debugprocess.cpp rename to elenasrc3/ldebugger/windows/win32debugprocess.cpp index 10939be469..a0ce28892c 100644 --- a/elenasrc3/ide/windows/win32debugprocess.cpp +++ b/elenasrc3/ldebugger/windows/win32debugprocess.cpp @@ -1,24 +1,16 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA Engine // -// This file contains the Win32 Debugger class and its helpers implementation +// This file contains the Win32 Debugger class implementation // (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- -#include "elena.h" -//--------------------------------------------------------------------------- -#include "windows/win32debugprocess.h" - -#include "core.h" -#include "windows/pehelper.h" - -#ifdef _MSC_VER - -#include - -#endif +#include "common.h" +// ------------------------------------------------------------------------- +#include "win32debugprocess.h" -#include "eng/messages.h" +#include "lruntime\windows\pehelper.h" +#include "engine\core.h" using namespace elena_lang; @@ -101,108 +93,6 @@ BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM lParam) else return TRUE; } -// --- main thread that is the debugger residing over a debuggee --- - -BOOL WINAPI debugEventThread(DebugControllerBase* controller) -{ - controller->debugThread(); - - ExitThread(TRUE); - - return TRUE; -} - -// --- Win32ThreadContext --- - -Win32ThreadContext :: Win32ThreadContext(HANDLE hProcess, HANDLE hThread) -{ - this->hProcess = hProcess; - this->hThread = hThread; - this->state = nullptr; -} - -bool Win32ThreadContext :: readDump(addr_t address, char* dump, size_t length) -{ - SIZE_T size = 0; - - ReadProcessMemory(hProcess, (void*)(address), dump, length, &size); - - return size != 0; -} - -void Win32ThreadContext :: writeDump(addr_t address, char* dump, size_t length) -{ - SIZE_T size = 0; - - WriteProcessMemory(hProcess, (void*)(address), dump, length, &size); -} - -void Win32ThreadContext :: refresh() -{ - context.ContextFlags = CONTEXT_FULL; - GetThreadContext(hThread, &context); - if (context.SegFs == 0) { // !! hotfix - context.SegFs = 0x38; - SetThreadContext(hThread, &context); - } -} - -unsigned char Win32ThreadContext :: setSoftwareBreakpoint(addr_t breakpoint) -{ - unsigned char code = 0; - unsigned char terminator = 0xCC; - - readDump(breakpoint, (char*)&code, 1); - writeDump(breakpoint, (char*)&terminator, 1); - - return code; -} - -void Win32ThreadContext :: clearSoftwareBreakpoint(addr_t breakpoint, unsigned char substitute) -{ - writeDump(breakpoint, (char*)&substitute, 1); -} - -void Win32ThreadContext :: setHardwareBreakpoint(addr_t breakpoint) -{ - context.ContextFlags = CONTEXT_DEBUG_REGISTERS; - context.Dr0 = breakpoint; - context.Dr7 = 0x000001; - SetThreadContext(hThread, &context); - this->breakpoint.hardware = true; -} - -void Win32ThreadContext :: clearHardwareBreakpoint() -{ - context.ContextFlags = CONTEXT_DEBUG_REGISTERS; - context.Dr0 = 0x0; - context.Dr7 = 0x0; - SetThreadContext(hThread, &context); - breakpoint.hardware = false; -} - -void Win32ThreadContext::resetTrapFlag() -{ - context.ContextFlags = CONTEXT_CONTROL; - context.EFlags &= ~0x100; - SetThreadContext(hThread, &context); -} - -void Win32ThreadContext::setTrapFlag() -{ - context.ContextFlags = CONTEXT_CONTROL; - context.EFlags |= 0x100; - SetThreadContext(hThread, &context); -} - -void Win32ThreadContext :: setIP(addr_t address) -{ - context.ContextFlags = CONTEXT_CONTROL; - GetThreadContext(hThread, &context); - ::setIP(context, address); - SetThreadContext(hThread, &context); -} - // --- Win32BreakpointContext --- Win32BreakpointContext :: Win32BreakpointContext() @@ -312,6 +202,98 @@ void Win32BreakpointContext :: clear() breakpoints.clear(); } +// --- Win32ThreadContext --- + +Win32ThreadContext :: Win32ThreadContext(HANDLE hProcess, HANDLE hThread) + : context({}) +{ + this->hProcess = hProcess; + this->hThread = hThread; + this->state = nullptr; +} + +void Win32ThreadContext :: refresh() +{ + context.ContextFlags = CONTEXT_FULL; + GetThreadContext(hThread, &context); + if (context.SegFs == 0) { // !! hotfix + context.SegFs = 0x38; + SetThreadContext(hThread, &context); + } +} + +bool Win32ThreadContext :: readDump(addr_t address, char* dump, size_t length) +{ + SIZE_T size = 0; + + ReadProcessMemory(hProcess, (void*)(address), dump, length, &size); + + return size != 0; +} + +void Win32ThreadContext :: writeDump(addr_t address, char* dump, size_t length) +{ + SIZE_T size = 0; + + WriteProcessMemory(hProcess, (void*)(address), dump, length, &size); +} + +unsigned char Win32ThreadContext :: setSoftwareBreakpoint(addr_t breakpoint) +{ + unsigned char code = 0; + unsigned char terminator = 0xCC; + + readDump(breakpoint, (char*)&code, 1); + writeDump(breakpoint, (char*)&terminator, 1); + + return code; +} + +void Win32ThreadContext :: clearSoftwareBreakpoint(addr_t breakpoint, unsigned char substitute) +{ + writeDump(breakpoint, (char*)&substitute, 1); +} + +void Win32ThreadContext :: setHardwareBreakpoint(addr_t breakpoint) +{ + context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + context.Dr0 = breakpoint; + context.Dr7 = 0x000001; + SetThreadContext(hThread, &context); + this->breakpoint.hardware = true; +} + +void Win32ThreadContext :: clearHardwareBreakpoint() +{ + context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + context.Dr0 = 0x0; + context.Dr7 = 0x0; + SetThreadContext(hThread, &context); + breakpoint.hardware = false; +} + +void Win32ThreadContext::resetTrapFlag() +{ + context.ContextFlags = CONTEXT_CONTROL; + context.EFlags &= ~0x100; + SetThreadContext(hThread, &context); +} + +void Win32ThreadContext::setTrapFlag() +{ + context.ContextFlags = CONTEXT_CONTROL; + context.EFlags |= 0x100; + SetThreadContext(hThread, &context); +} + +void Win32ThreadContext :: setIP(addr_t address) +{ + context.ContextFlags = CONTEXT_CONTROL; + GetThreadContext(hThread, &context); + ::setIP(context, address); + SetThreadContext(hThread, &context); +} + // --- Win32DebugProcess::ConsoleHelper --- void Win32DebugProcess::ConsoleHelper :: printText(const char* s) @@ -339,11 +321,39 @@ void Win32DebugProcess::ConsoleHelper :: waitForAnyKey() // --- Win32DebugProcess --- -Win32DebugProcess :: Win32DebugProcess() - : _threads(nullptr), steps(nullptr) +Win32DebugProcess :: Win32DebugProcess(const char* endingMessage) + : _threads(nullptr), _steps(nullptr), _exception({}) { + _needToFreeConsole = false; + _started = false; + + _endingMessage = endingMessage; + reset(); - needToFreeConsole = false; +} + +void Win32DebugProcess :: reset() +{ + _trapped = false; + _newThread = false; + + _threads.clear(); + _current = nullptr; + + _minAddress = INVALID_ADDR; + _maxAddress = 0; + _baseAddress = 0; + + _dwDebugeeProcessId = 0; + + _steps.clear(); + _breakpoints.clear(); + + _init_breakpoint = 0; + _stepMode = false; + _needToHandle = false; + + //_vmHook = 0; } inline bool isIncluded(path_t paths, path_t path) @@ -355,7 +365,7 @@ inline bool isIncluded(path_t paths, path_t path) } bool Win32DebugProcess :: startProcess(const wchar_t* exePath, const wchar_t* cmdLine, const wchar_t* appPath, - StartUpSettings& startUpSettings) + bool includeAppPath2Paths, bool withExplicitConsole) { DynamicString pathsEnv; @@ -371,28 +381,28 @@ bool Win32DebugProcess :: startProcess(const wchar_t* exePath, const wchar_t* cm si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; - if (startUpSettings.withExplicitConsole) { + if (withExplicitConsole) { AllocConsole(); - needToFreeConsole = true; + _needToFreeConsole = true; } else flags |= CREATE_NEW_CONSOLE; - pos_t trimPos = INVALID_POS; - if (startUpSettings.includeAppPath2Paths) { + size_t trimPos = NOTFOUND_POS; + if (includeAppPath2Paths) { flags |= CREATE_UNICODE_ENVIRONMENT; pathsEnv.allocate(4096); - int dwRet = GetEnvironmentVariable(_T("PATH"), (LPWSTR)pathsEnv.str(), 4096); + int dwRet = GetEnvironmentVariable(L"PATH", (LPWSTR)pathsEnv.str(), 4096); if (dwRet && !isIncluded(pathsEnv.str(), appPath)) { - trimPos = pathsEnv.length_pos(); + trimPos = pathsEnv.length(); if (!pathsEnv.empty() && pathsEnv[pathsEnv.length() - 1] != ';') pathsEnv.append(';'); pathsEnv.append(appPath); - SetEnvironmentVariable(_T("PATH"), pathsEnv.str()); + SetEnvironmentVariable(L"PATH", pathsEnv.str()); } } @@ -410,14 +420,14 @@ bool Win32DebugProcess :: startProcess(const wchar_t* exePath, const wchar_t* cm // rolling back changes to ENVIRONENT if required pathsEnv.trim(trimPos); - SetEnvironmentVariable(_T("PATH"), pathsEnv.str()); + SetEnvironmentVariable(L"PATH", pathsEnv.str()); } if (!retVal) { return false; } - dwDebugeeProcessId = pi.dwProcessId; + _dwDebugeeProcessId = pi.dwProcessId; if (pi.hProcess) CloseHandle(pi.hProcess); @@ -425,88 +435,40 @@ bool Win32DebugProcess :: startProcess(const wchar_t* exePath, const wchar_t* cm if (pi.hThread) CloseHandle(pi.hThread); - started = true; - //exception.code = 0; - needToHandle = false; - - return true; -} - -bool Win32DebugProcess :: startProgram(path_t exePath, path_t cmdLine, path_t appPath, StartUpSettings& startUpSettings) -{ - if (startProcess(exePath.str(), cmdLine.str(), appPath, startUpSettings)) { - processEvent(INFINITE); - - return true; - } - else return false; -} - -bool Win32DebugProcess :: startThread(DebugControllerBase* controller) -{ - HANDLE hThread = CreateThread(nullptr, 4096, - (LPTHREAD_START_ROUTINE)debugEventThread, - (LPVOID)controller, - 0, &threadId); - - if (!hThread) { - return false; - } - else ::CloseHandle(hThread); + _started = true; + _exception.code = 0; + _needToHandle = false; return true; } -void Win32DebugProcess :: continueProcess() -{ - int code = needToHandle ? DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE; - - ContinueDebugEvent(dwCurrentProcessId, dwCurrentThreadId, code); - - needToHandle = false; -} - -void Win32DebugProcess :: processEnd() -{ - _threads.clear(); - _current = nullptr; - started = false; - if (needToFreeConsole) { - ConsoleHelper console; - console.printText(CONSOLE_OUTPUT_TEXT); - console.waitForAnyKey(); - - FreeConsole(); - - needToFreeConsole = false; - } -} - void Win32DebugProcess :: processEvent(DWORD timeout) { DEBUG_EVENT event; - trapped = false; + _trapped = false; if (WaitForDebugEvent(&event, timeout)) { - dwCurrentThreadId = event.dwThreadId; - dwCurrentProcessId = event.dwProcessId; + _dwCurrentThreadId = event.dwThreadId; + _dwCurrentProcessId = event.dwProcessId; switch (event.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: _current = new Win32ThreadContext(event.u.CreateProcessInfo.hProcess, event.u.CreateProcessInfo.hThread); _current->refresh(); - _threads.add(dwCurrentThreadId, _current); + _threads.add(_dwCurrentThreadId, _current); - if (dwCurrentProcessId == dwDebugeeProcessId) { - baseAddress = (addr_t)event.u.CreateProcessInfo.lpBaseOfImage; + if (_dwCurrentProcessId == _dwDebugeeProcessId) { + _baseAddress = (addr_t)event.u.CreateProcessInfo.lpBaseOfImage; _breakpoints.setSoftwareBreakpoints(_current); } + _newThread = true; + ::CloseHandle(event.u.CreateProcessInfo.hFile); break; case EXIT_PROCESS_DEBUG_EVENT: - _current = _threads.get(dwCurrentThreadId); + _current = _threads.get(_dwCurrentThreadId); if (_current) { _current->refresh(); //exitCheckPoint = proceedCheckPoint(); @@ -517,7 +479,7 @@ void Win32DebugProcess :: processEvent(DWORD timeout) _current = new Win32ThreadContext((*_threads.start())->hProcess, event.u.CreateThread.hThread); _current->refresh(); - _threads.add(dwCurrentThreadId, _current); + _threads.add(_dwCurrentThreadId, _current); break; case EXIT_THREAD_DEBUG_EVENT: _threads.erase(event.dwThreadId); @@ -531,10 +493,10 @@ void Win32DebugProcess :: processEvent(DWORD timeout) case OUTPUT_DEBUG_STRING_EVENT: break; case RIP_EVENT: - started = false; + _started = false; break; case EXCEPTION_DEBUG_EVENT: - _current = _threads.get(dwCurrentThreadId); + _current = _threads.get(_dwCurrentThreadId); if (_current) { _current->refresh(); processException(&event.u.Exception); @@ -545,44 +507,60 @@ void Win32DebugProcess :: processEvent(DWORD timeout) } } +void Win32DebugProcess :: processEnd() +{ + _threads.clear(); + _current = nullptr; + _started = false; + if (_needToFreeConsole) { + ConsoleHelper console; + console.printText(_endingMessage); + console.waitForAnyKey(); + + FreeConsole(); + + _needToFreeConsole = false; + } +} + void Win32DebugProcess :: processException(EXCEPTION_DEBUG_INFO* exception) { switch (exception->ExceptionRecord.ExceptionCode) { case EXCEPTION_SINGLE_STEP: - if (_breakpoints.processStep(_current, stepMode)) + if (_breakpoints.processStep(_current, _stepMode)) break; // stop if it is VM Hook mode - if (init_breakpoint == INVALID_ADDR) { - init_breakpoint = getIP(_current->context); - trapped = true; + if (_init_breakpoint == INVALID_ADDR) { + _init_breakpoint = getIP(_current->context); + _trapped = true; } - else if (getIP(_current->context) >= minAddress && getIP(_current->context) <= maxAddress) { + else if (getIP(_current->context) >= _minAddress && getIP(_current->context) <= _maxAddress) { processStep(); } - if (!trapped) + if (!_trapped) _current->setTrapFlag(); break; case EXCEPTION_BREAKPOINT: if (_breakpoints.processBreakpoint(_current)) { - _current->state = steps.get(getIP(_current->context)); - trapped = true; - stepMode = false; + _current->state = _steps.get(getIP(_current->context)); + _trapped = true; + _stepMode = false; _current->setTrapFlag(); } - else if (init_breakpoint != 0 && init_breakpoint != INVALID_ADDR) { - trapped = true; - init_breakpoint = getIP(_current->context); + else if (_init_breakpoint != 0 && _init_breakpoint != INVALID_ADDR) { + _trapped = true; + _init_breakpoint = getIP(_current->context); } break; default: if (exception->dwFirstChance != 0) { - needToHandle = true; + _needToHandle = true; } else { - this->exception.code = exception->ExceptionRecord.ExceptionCode; - this->exception.address = (addr_t)exception->ExceptionRecord.ExceptionAddress; + this->_exception.code = exception->ExceptionRecord.ExceptionCode; + this->_exception.address = (addr_t)exception->ExceptionRecord.ExceptionAddress; TerminateProcess(_current->hProcess, 1); } break; @@ -591,100 +569,46 @@ void Win32DebugProcess :: processException(EXCEPTION_DEBUG_INFO* exception) void Win32DebugProcess :: processStep() { - _current->state = steps.get(getIP(_current->context)); + _current->state = _steps.get(getIP(_current->context)); if (_current->state != nullptr) { - trapped = true; - stepMode = false; + _trapped = true; + _stepMode = false; //proceedCheckPoint(); } } -bool Win32DebugProcess :: proceed(int timeout) +void Win32DebugProcess :: continueProcess() { - processEvent(timeout); + int code = _needToHandle ? DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE; - return !trapped; -} + ContinueDebugEvent(_dwCurrentProcessId, _dwCurrentThreadId, code); -void Win32DebugProcess :: resetException() -{ - exception.code = 0; + _needToHandle = false; } -void Win32DebugProcess :: run() +void Win32DebugProcess :: resetException() { - continueProcess(); + _exception.code = 0; } -void Win32DebugProcess :: activate() +void Win32DebugProcess :: activateWindow() { - if (started) { - EnumWindows(EnumThreadWndProc, dwCurrentThreadId); + if (_started) { + EnumWindows(EnumThreadWndProc, _dwCurrentThreadId); } } void Win32DebugProcess :: stop() { - if (!started) + if (!_started) return; - + if (_current) ::TerminateProcess(_current->hProcess, 1); - + continueProcess(); } -void Win32DebugProcess :: reset() -{ - trapped = false; - - _threads.clear(); - _current = nullptr; - - minAddress = INVALID_ADDR; - maxAddress = 0; - baseAddress = 0; - - dwDebugeeProcessId = 0; - - steps.clear(); - _breakpoints.clear(); - - init_breakpoint = 0; - stepMode = false; - needToHandle = false; - //exitCheckPoint = false; - - //_vmHook = 0; -} - -addr_t Win32DebugProcess :: findEntryPoint(path_t programPath) -{ - return PEHelper::findEntryPoint(programPath); -} - -bool Win32DebugProcess :: isInitBreakpoint() -{ - return _current ? init_breakpoint == getIP(_current->context) : false; -} - -addr_t Win32DebugProcess :: getBaseAddress() -{ - return baseAddress; -} - -bool Win32DebugProcess :: findSignature(StreamReader& reader, char* signature, pos_t length) -{ - size_t rdata = 0; - if (!PEHelper::seekSection(reader, ".rdata", rdata)) - return false; - - // load Executable image - _current->readDump(rdata + sizeof(addr_t), signature, length); - - return true; -} - void Win32DebugProcess :: setBreakpoint(addr_t address, bool withStackLevelControl) { _breakpoints.setHardwareBreakpoint(address, _current, withStackLevelControl); @@ -692,47 +616,54 @@ void Win32DebugProcess :: setBreakpoint(addr_t address, bool withStackLevelContr void Win32DebugProcess :: addBreakpoint(addr_t address) { - _breakpoints.addBreakpoint(address, _current, started); + _breakpoints.addBreakpoint(address, _current, _started); } void Win32DebugProcess :: removeBreakpoint(addr_t address) { - _breakpoints.removeBreakpoint(address, _current, started); + _breakpoints.removeBreakpoint(address, _current, _started); } void Win32DebugProcess :: setStepMode() { // !! temporal _current->clearHardwareBreakpoint(); - + _current->setTrapFlag(); - stepMode = true; + _stepMode = true; } void Win32DebugProcess :: addStep(addr_t address, void* state) { - steps.add(address, state); - if (address < minAddress) - minAddress = address; - - if (address > maxAddress) - maxAddress = address; + _steps.add(address, state); + if (address < _minAddress) + _minAddress = address; + + if (address > _maxAddress) + _maxAddress = address; } -int Win32DebugProcess :: getDataOffset() +addr_t Win32DebugProcess :: findEntryPoint(path_t programPath) { - return sizeof(addr_t); + return PEHelper::findEntryPoint(programPath); } -void* Win32DebugProcess :: getState() +bool Win32DebugProcess :: findSignature(StreamReader& reader, char* signature, pos_t length) { - return _current ? _current->state : nullptr; + size_t rdata = 0; + if (!PEHelper::seekSection(reader, ".rdata", rdata)) + return false; + + // load Executable image + _current->readDump(rdata + sizeof(addr_t), signature, length); + + return true; } addr_t Win32DebugProcess :: getClassVMT(addr_t address) { addr_t ptr = 0; - + if (_current->readDump(address - elObjectOffset, (char*)&ptr, sizeof(addr_t))) { return ptr; } @@ -752,38 +683,37 @@ addr_t Win32DebugProcess :: getStackItem(int index, disp_t offset) addr_t Win32DebugProcess :: getMemoryPtr(addr_t address) { addr_t retPtr = 0; - + if (_current->readDump(address, (char*)&retPtr, sizeof(addr_t))) { return retPtr; } else return 0; - } unsigned short Win32DebugProcess :: getWORD(addr_t address) { unsigned short word = 0; - + if (_current->readDump(address, (char*)&word, 2)) { return word; } else return 0; } -unsigned Win32DebugProcess::getDWORD(addr_t address) +unsigned Win32DebugProcess :: getDWORD(addr_t address) { unsigned int dword = 0; - + if (_current->readDump(address, (char*)&dword, 4)) { return dword; } else return 0; } -char Win32DebugProcess::getBYTE(addr_t address) +unsigned char Win32DebugProcess :: getBYTE(addr_t address) { - char b = 0; - + unsigned char b = 0; + if (_current->readDump(address, (char*)&b, 1)) { return b; } @@ -793,7 +723,7 @@ char Win32DebugProcess::getBYTE(addr_t address) unsigned long long Win32DebugProcess :: getQWORD(addr_t address) { unsigned long long qword = 0; - + if (_current->readDump(address, (char*)&qword, 8)) { return qword; } @@ -803,12 +733,11 @@ unsigned long long Win32DebugProcess :: getQWORD(addr_t address) double Win32DebugProcess :: getFLOAT64(addr_t address) { double number = 0; - + if (_current->readDump(address, (char*)&number, 8)) { return number; } else return 0; - } ref_t Win32DebugProcess :: getClassFlags(addr_t vmtAddress) @@ -818,13 +747,12 @@ ref_t Win32DebugProcess :: getClassFlags(addr_t vmtAddress) return flags; } else return 0; - } addr_t Win32DebugProcess :: getField(addr_t address, int index) { disp_t offset = index * sizeof(addr_t); - + return getMemoryPtr(address + offset); } @@ -842,3 +770,8 @@ size_t Win32DebugProcess :: getArrayLength(addr_t address) return 0; } + +bool Win32DebugProcess :: isInitBreakpoint() +{ + return _current ? _init_breakpoint == getIP(_current->context) : false; +} diff --git a/elenasrc3/ldebugger/windows/win32debugprocess.h b/elenasrc3/ldebugger/windows/win32debugprocess.h new file mode 100644 index 0000000000..fd6058f0e7 --- /dev/null +++ b/elenasrc3/ldebugger/windows/win32debugprocess.h @@ -0,0 +1,219 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Engine +// +// This file contains the Win32 Debugger class header +// (C)2021-2025, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef WIN32DEBUGPROCESS_H +#define WIN32DEBUGPROCESS_H + +#include + +#include "common/common.h" +#include "ldebugger/ldbg_common.h" + +namespace elena_lang +{ + // --- Win32DebugProcessException --- + struct Win32DebugProcessException : public DebugProcessException + { + }; + + // --- Win32ThreadBreakpoint --- + struct Win32ThreadBreakpoint + { + bool software; + bool hardware; + addr_t next; + addr_t stackLevel; + + void clearSoftware() + { + software = false; + next = 0; + } + + Win32ThreadBreakpoint() + { + hardware = software = false; + stackLevel = next = 0; + } + }; + + // --- Win32ThreadContext --- + struct Win32ThreadContext + { + friend class Win32DebugProcess; + friend struct Win32BreakpointContext; + + void* state; + HANDLE hProcess; + HANDLE hThread; + CONTEXT context; + + public: + Win32ThreadBreakpoint breakpoint; + + bool readDump(addr_t address, char* dump, size_t length); + void writeDump(addr_t address, char* dump, size_t length); + + void refresh(); + + void setTrapFlag(); + void resetTrapFlag(); + void setHardwareBreakpoint(addr_t breakpoint); + void clearHardwareBreakpoint(); + + unsigned char setSoftwareBreakpoint(addr_t breakpoint); + void clearSoftwareBreakpoint(addr_t breakpoint, unsigned char substitute); + + void setIP(addr_t address); + + Win32ThreadContext(HANDLE hProcess, HANDLE hThread); + }; + + // --- BreakpointContext --- + struct Win32BreakpointContext + { + Map breakpoints; + + void addBreakpoint(addr_t address, Win32ThreadContext* context, bool started); + void removeBreakpoint(addr_t address, Win32ThreadContext* context, bool started); + void setSoftwareBreakpoints(Win32ThreadContext* context); + void setHardwareBreakpoint(addr_t address, Win32ThreadContext* context, bool withStackLevelControl); + + bool processStep(Win32ThreadContext* context, bool stepMode); + bool processBreakpoint(Win32ThreadContext* context); + + void clear(); + + Win32BreakpointContext(); + }; + + class Win32DebugProcess + { + typedef Map ThreadContextes; + typedef MemoryMap StepMap; + + class ConsoleHelper + { + public: + void printText(const char* s); + void waitForAnyKey(); + }; + + const char* _endingMessage; + + bool _needToHandle; + bool _needToFreeConsole; + + bool _started; + bool _trapped; + bool _stepMode; + bool _newThread; + + DWORD _dwCurrentProcessId; + DWORD _dwCurrentThreadId; + DWORD _dwDebugeeProcessId; + + addr_t _init_breakpoint; + addr_t _minAddress, _maxAddress; + addr_t _baseAddress; + + Win32DebugProcessException _exception; + Win32ThreadContext* _current; + Win32BreakpointContext _breakpoints; + ThreadContextes _threads; + StepMap _steps; + + void processStep(); + void processException(EXCEPTION_DEBUG_INFO* exception); + void processEnd(); + + public: + bool isStarted() + { + return _started; + } + + bool isTrapped() + { + return _trapped; + } + + bool isNewThread() + { + bool retVal = _newThread; + _newThread = false; + + return _newThread; + } + + addr_t getBaseAddress() + { + return _baseAddress; + } + + void initHook() { _init_breakpoint = INVALID_ADDR; } + + addr_t findEntryPoint(path_t programPath); + bool findSignature(StreamReader& reader, char* signature, pos_t length); + + bool isInitBreakpoint(); + + void activateWindow(); + + void reset(); + void resetException(); + + void continueProcess(); + void processEvent(DWORD timeout); + + void setBreakpoint(addr_t address, bool withStackLevelControl); + void addBreakpoint(addr_t address); + void removeBreakpoint(addr_t address); + + void setStepMode(); + + void addStep(addr_t address, void* state); + + void* getState() + { + return _current ? _current->state : nullptr; + } + + Win32DebugProcessException* getException() + { + return _exception.code == 0 ? nullptr : &_exception; + } + + addr_t getClassVMT(addr_t address); + addr_t getStackItemAddress(disp_t disp); + addr_t getStackItem(int index, disp_t offset); + addr_t getMemoryPtr(addr_t address); + addr_t getField(addr_t address, int index); + addr_t getFieldAddress(addr_t address, disp_t disp); + + unsigned short getWORD(addr_t address); + unsigned getDWORD(addr_t address); + unsigned char getBYTE(addr_t address); + unsigned long long getQWORD(addr_t address); + double getFLOAT64(addr_t address); + ref_t getClassFlags(addr_t vmtAddress); + size_t getArrayLength(addr_t address); + + bool readDump(addr_t address, char* s, pos_t length) + { + return _current->readDump(address, s, length); + } + + bool startProcess(const wchar_t* exePath, const wchar_t* cmdLine, const wchar_t* appPath, + bool includeAppPath2Paths, bool withExplicitConsole); + void stop(); + + Win32DebugProcess(const char* endingMessage); + }; +} + +#endif \ No newline at end of file diff --git a/elenasrc3/lruntime/vs/lruntime.vcxproj b/elenasrc3/lruntime/vs/lruntime.vcxproj new file mode 100644 index 0000000000..55786422cd --- /dev/null +++ b/elenasrc3/lruntime/vs/lruntime.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {49F68D87-F240-4E39-922D-219EE1601240} + lruntime + 10.0 + + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + ..\..\..\bin\ + + + ..\..\..\bin\ + + + ..\..\..\bin\ + $(ProjectName)64 + + + ..\..\..\bin\ + $(ProjectName)64 + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + true + + ..;..\..\common;%(AdditionalIncludeDirectories) + + + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + ..;..\..\common;%(AdditionalIncludeDirectories) + + + + + true + true + true + + + + + Level3 + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + + ..;..\..\common;%(AdditionalIncludeDirectories) + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + ..;..\..\common;%(AdditionalIncludeDirectories) + + + + + true + true + true + + + + + + + + + + + {c7728dfb-e3b8-4ce0-bef5-f8369e6761ef} + + + + + + \ No newline at end of file diff --git a/elenasrc3/engine/windows/pehelper.cpp b/elenasrc3/lruntime/windows/pehelper.cpp similarity index 97% rename from elenasrc3/engine/windows/pehelper.cpp rename to elenasrc3/lruntime/windows/pehelper.cpp index a9ddeeb5bf..7da6f5a0b2 100644 --- a/elenasrc3/engine/windows/pehelper.cpp +++ b/elenasrc3/lruntime/windows/pehelper.cpp @@ -3,10 +3,10 @@ // // This file contains ELENA PEHelper implementation. // Supported platforms: x86 -// (C)2005-2021, by Aleksey Rakov +// (C)2005-2025, by Aleksey Rakov //--------------------------------------------------------------------------- -#include "elena.h" +#include "common.h" // -------------------------------------------------------------------------- #include "pehelper.h" #include diff --git a/elenasrc3/engine/windows/pehelper.h b/elenasrc3/lruntime/windows/pehelper.h similarity index 100% rename from elenasrc3/engine/windows/pehelper.h rename to elenasrc3/lruntime/windows/pehelper.h diff --git a/elenasrc3/tools/og/og.cpp b/elenasrc3/tools/og/og.cpp index 95dd78043f..3e98f1226a 100644 --- a/elenasrc3/tools/og/og.cpp +++ b/elenasrc3/tools/og/og.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A p r o j e c t // Command line syntax generator main file -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "buildtree.h" @@ -23,12 +23,18 @@ constexpr auto DEFAULT_ENCODING = FileEncoding::UTF8; #endif typedef MemoryTrieBuilder ByteCodeTrieBuilder; +typedef MemoryTrieBuilder BuildTrieBuilder; bool isMatchNode(ByteCodePattern pattern) { return pattern.code == ByteCode::Match; } +bool isMatchNode(BuildPattern pattern) +{ + return pattern.key == BuildKey::Match; +} + ByteCodePattern decodePattern(ScriptReader& reader, ScriptToken& token) { ByteCodePattern pattern = { ByteCode::None }; @@ -101,6 +107,51 @@ ByteCodePattern decodePattern(ScriptReader& reader, ScriptToken& token) return pattern; } +BuildPattern decodeBuildPattern(BuildKeyMap& dictionary, ScriptReader& reader, ScriptToken& token) +{ + BuildPattern pattern = { dictionary.get(token.token.str()) }; + + reader.read(token); + + if (pattern.key == BuildKey::None) + throw SyntaxError(OG_INVALID_OPCODE, token.lineInfo); + + if (token.compare("=")) { + reader.read(token); + + pattern.argValue = token.token.toInt(); + pattern.argType = BuildPatternType::MatchArg; + + reader.read(token); + } + else { + if (token.compare("$1")) { + pattern.argValue = 1; + pattern.argType = BuildPatternType::Set; + + reader.read(token); + } + else if (token.compare("$2")) { + pattern.argValue = 2; + pattern.argType = BuildPatternType::Set; + + reader.read(token); + } + else if (token.compare("#1")) { + pattern.argValue = 1; + pattern.argType = BuildPatternType::Match; + reader.read(token); + } + else if (token.compare("#2")) { + pattern.argValue = 2; + pattern.argType = BuildPatternType::Match; + reader.read(token); + } + } + + return pattern; +} + pos_t readTransformPart(pos_t position, ScriptReader& reader, ScriptToken& token, ByteCodeTrieBuilder& trie) { if (!token.compare(";")) { @@ -120,6 +171,25 @@ pos_t readTransformPart(pos_t position, ScriptReader& reader, ScriptToken& token return position; } +pos_t readBuildTransformPart(pos_t position, ScriptReader& reader, ScriptToken& token, BuildTrieBuilder& trie, BuildKeyMap& dictionary) +{ + if (!token.compare(";")) { + BuildPattern pattern = decodeBuildPattern(dictionary, reader, token); + + if (token.compare(",")) { + reader.read(token); + } + else if (!token.compare(";")) + throw SyntaxError(OG_INVALID_OPCODE, token.lineInfo); + + // should be saved in reverse order, to simplify transform algorithm + position = readBuildTransformPart(position, reader, token, trie, dictionary); + + return trie.add(position, pattern); + } + return position; +} + void parseOpcodeRule(ScriptReader& reader, ScriptToken& token, ByteCodeTrieBuilder& trie) { // save opcode pattern @@ -127,6 +197,7 @@ void parseOpcodeRule(ScriptReader& reader, ScriptToken& token, ByteCodeTrieBuild pos_t position = trie.add(0, pattern); + ByteCodePatternType matchArg = ByteCodePatternType::None; while (!token.compare("=>")) { if (token.compare(",")) { reader.read(token); @@ -134,17 +205,24 @@ void parseOpcodeRule(ScriptReader& reader, ScriptToken& token, ByteCodeTrieBuild else throw SyntaxError(OG_INVALID_OPCODE, token.lineInfo); position = trie.add(position, decodePattern(reader, token)); + + if (token.compare("$")) { + matchArg = ByteCodePatternType::IfAccFree; + reader.read(token); + if(!token.compare("=>")) + throw SyntaxError(OG_INVALID_OPCODE, token.lineInfo); + } } // save end state - position = trie.add(position, { ByteCode::Match }); + position = trie.add(position, { ByteCode::Match, matchArg }); // save replacement (should be saved in reverse order, to simplify transform algorithm) reader.read(token); readTransformPart(position, reader, token, trie); } -int parseRuleSet(FileEncoding encoding, path_t path) +int parseByteCodeRuleSet(FileEncoding encoding, path_t path) { ByteCodeTrieBuilder trie({ ByteCode::None }); @@ -182,56 +260,45 @@ int parseRuleSet(FileEncoding encoding, path_t path) return 0; } -BuildKeyPattern decodeBuildPattern(BuildKeyMap& dictionary, ScriptReader& reader, ScriptToken& token) +void parseBuildCodeRule(ScriptReader& reader, ScriptToken& token, BuildTrieBuilder& trie, BuildKeyMap& dictionary) { - BuildKeyPattern pattern = { dictionary.get(token.token.str())}; - if (pattern.type == BuildKey::None) - throw SyntaxError(OG_INVALID_OPCODE, token.lineInfo); - - reader.read(token); + // save opcode pattern + BuildPattern pattern = decodeBuildPattern(dictionary, reader, token); - if (token.compare("=")) { - reader.read(token); - pattern.argument = token.token.toInt(); - reader.read(token); - } + pos_t position = trie.add(0, pattern); - if (token.compare("=>")) { - reader.read(token); + while (!token.compare("=>")) { + if (token.compare(",")) { + reader.read(token); + } + else throw SyntaxError(OG_INVALID_OPCODE, token.lineInfo); - int patternId = token.token.toInt(); - if (!patternId) - throw SyntaxError(OG_INVALID_OPCODE, token.lineInfo); + position = trie.add(position, decodeBuildPattern(dictionary, reader, token)); + } - pattern.patternId = patternId; + reader.read(token); + if (token.state == dfaInteger) { + position = trie.add(position, { BuildKey::Match, BuildPatternType::None, token.token.toInt() }); reader.read(token); + if(!token.compare(";")) + throw SyntaxError(OG_INVALID_OPCODE, token.lineInfo); } - else if (token.compare(",")) { - reader.read(token); - } - else throw SyntaxError(OG_INVALID_OPCODE, token.lineInfo); + else { + // save end state + position = trie.add(position, { BuildKey::Match }); - return pattern; -} - -void parseBuildCodeRule(BuildCodeTrie& trie, BuildKeyMap& dictionary, ScriptReader& reader, ScriptToken& token) -{ - BuildKeyPattern pattern = decodeBuildPattern(dictionary, reader, token); - - pos_t position = trie.add(0, pattern); - - while (!token.compare(";")) { - position = trie.add(position, decodeBuildPattern(dictionary, reader, token)); + // save replacement (should be saved in reverse order, to simplify transform algorithm) + readBuildTransformPart(position, reader, token, trie, dictionary); } } -int parseSourceRules(FileEncoding encoding, path_t path) +int parseBuildKeyRules(FileEncoding encoding, path_t path) { BuildKeyMap dictionary({ BuildKey::None }); BuildTree::loadBuildKeyMap(dictionary); - BuildCodeTrie trie({ }); + BuildTrieBuilder trie({ }); TextFileReader source(path.str(), encoding, false); if (!source.isOpen()) { @@ -243,13 +310,17 @@ int parseSourceRules(FileEncoding encoding, path_t path) ScriptReader reader(4, &source); ScriptToken token; + // add root trie.addRoot({ BuildKey::Root }); // generate tree while (reader.read(token)) { - parseBuildCodeRule(trie, dictionary, reader, token); + parseBuildCodeRule(reader, token, trie, dictionary); } + // add suffix links + //trie.prepare(isMatchNode); + // save the result PathString outputFile(path); outputFile.changeExtension("dat"); @@ -271,11 +342,11 @@ int main(int argc, char* argv[]) { if (argc == 2) { PathString path(argv[1]); - retVal = parseRuleSet(DEFAULT_ENCODING, *path); + retVal = parseByteCodeRuleSet(DEFAULT_ENCODING, *path); } else if (argc == 3 && argv[1][0] == '-' && argv[1][1] == 's') { PathString path(argv[2]); - retVal = parseSourceRules(DEFAULT_ENCODING, *path); + retVal = parseBuildKeyRules(DEFAULT_ENCODING, *path); } else { printf(OG_HELP); diff --git a/elenasrc3/tools/og/ogconst.h b/elenasrc3/tools/og/ogconst.h index 9627bc23e7..b0992806b0 100644 --- a/elenasrc3/tools/og/ogconst.h +++ b/elenasrc3/tools/og/ogconst.h @@ -3,7 +3,7 @@ // // This file contains the compiler common interfaces & types // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef CLICONST @@ -11,9 +11,9 @@ namespace elena_lang { - #define SG_REVISION_NUMBER 0x0011 + #define SG_REVISION_NUMBER 0x0014 - constexpr auto OG_GREETING = "ELENA command line optimization rule set generator %d.%d.%d (C)2023-2024 by Aleksey Rakov\n"; + constexpr auto OG_GREETING = "ELENA command line optimization rule set generator %d.%d.%d (C)2023-2025 by Aleksey Rakov\n"; constexpr auto OG_HELP = "og-cli \n"; diff --git a/examples60/examples60.linux.prjcol b/examples60/examples60.linux.prjcol index c0b18a7b94..0d7af3c1a7 100644 --- a/examples60/examples60.linux.prjcol +++ b/examples60/examples60.linux.prjcol @@ -1,25 +1,26 @@ - console/helloworld/helloworld.linux.prj - console/binary/binary.l - console/bsort/bsort.l - console/collatz/collatz.l - console/datetime/datetime.linux.prj - console/goods/goods.l + console/helloworld/helloworld.prj + binary.l + bsort.l + collatz.l + console/datetime/datetime.prj + goods.l console/matrix/matrix.prj - console/pi/pi.l - console/pi2/pi2.l - console/random/random.l + pi.l + pi2.l + random.l console/regex/regex.prj - console/replace/replace.l - console/trans/translit.linux.prj - console/sum/sum.linux.prj - console/words/words.l + replace.l + console/trans/translit.prj + console/sum/sum.prj + console/sum/sum.prj + words.l - files/textdb/textdb.l - files/textfile/textfile.l + textdb.l + textfile.l \ No newline at end of file diff --git a/examples60/examples60.prjcol b/examples60/examples60.prjcol index 2ed034d8ce..6fc685e9f7 100644 --- a/examples60/examples60.prjcol +++ b/examples60/examples60.prjcol @@ -2,27 +2,28 @@ console\helloworld\helloworld.prj - console\binary\binary.l - console\bsort\bsort.l - console\collatz\collatz.l + binary.l + bsort.l + collatz.l console\datetime\datetime.prj - console\goods\goods.l + goods.l console\matrix\matrix.prj - console\pi\pi.l - console\pi2\pi2.l - console\random\random.l + pi.l + pi2.l + random.l console\regex\regex.prj - console\replace\replace.l + replace.l console\trans\translit.prj - console\sum\sum.prj - console\words\words.l + console\sum\sum.prj + console\sum\sum.prj + words.l db\sqlite\sqlite_test.prj - files\textdb\textdb.l - files\textfile\textfile.l + textdb.l + textfile.l gui\agenda\agenda.prj @@ -31,18 +32,19 @@ gui\helloworld\xforms_hellowindow.prj - net\httpget\httpget.prj + net\httpget\httpget.prj + net\httpget\httpget.prj scripts\calc\calc.prj - scripts\interpreter\interpreter.l + interpreter.l scripts\js\jsinterpreter.prj scripts\ls\lsinterpreter.prj - - scripts\async\asyncsamples.prj - scripts\tasks\tasksamples.prj - scripts\threadpool\threadpoolsamples.prj + + threads\async\asyncsamples.prj + threads\tasks\tasksamples.prj + threads\threadpool\threadpoolsamples.prj \ No newline at end of file diff --git a/examples60/net/chat/server/server.l b/examples60/net/chat/server/server.l index 6df188b06b..ee7056e826 100644 --- a/examples60/net/chat/server/server.l +++ b/examples60/net/chat/server/server.l @@ -111,7 +111,7 @@ public sealed ChatServer { lock (_lock) { - (client.Parameter as::ChatMember).write(data, length) + (client.Parameter as:ChatMember).write(data, length) } }; diff --git a/examples60/net/httpget/httpget.l b/examples60/net/httpget/httpget.l index fee94910a1..1e318b2ad4 100644 --- a/examples60/net/httpget/httpget.l +++ b/examples60/net/httpget/httpget.l @@ -1,47 +1,15 @@ -/*namespace HttpClientStatus; - -class Program -{ - static async Task Main(string[] args) - { - using var client = new HttpClient(); - - var result = await client.GetAsync("http://webcode.me"); - Console.WriteLine(result.StatusCode); - } -} - -using var client = new HttpClient(); -var content = await client.GetStringAsync("http://webcode.me"); - -Console.WriteLine(content); - -var url = "http://webcode.me"; - -using var client = new HttpClient(); - -var msg = new HttpRequestMessage(HttpMethod.Get, url); -msg.Headers.Add("User-Agent", "C# Program"); -var res = await client.SendAsync(msg); - -var content = await res.Content.ReadAsStringAsync(); - -Console.WriteLine(content); - -*/ - import net'http; import system'threading; singleton Tester { - async Task browse() + async Task browse(string url) { - using(HttpClient client := new HttpClient()) + using(HttpClient client := :await HttpClient.openAsync(url)) { client.Headers.add("User-agent", "MyUserAgent"); - HttpResponse response := :await client.getAsync("http://www.google.com"); + HttpResponse response := :await client.getAsync(); string content := :await response.readAsStringAsync(); @@ -52,5 +20,5 @@ singleton Tester public program() { - Tester.browse().Result; + Tester.browse("http://www.google.com").Result; } diff --git a/examples60/net/httpget/httpget.prj b/examples60/net/httpget/httpget.prj index 3f332c7d12..d6d4d457c4 100644 --- a/examples60/net/httpget/httpget.prj +++ b/examples60/net/httpget/httpget.prj @@ -1,11 +1,25 @@ - + + + httpget + + httpget.l - + + + + + httpsget + + + + httpsget.l + + + - httpget httpget diff --git a/examples60/net/httpget/httpsget.l b/examples60/net/httpget/httpsget.l new file mode 100644 index 0000000000..cbe7d87ce2 --- /dev/null +++ b/examples60/net/httpget/httpsget.l @@ -0,0 +1,25 @@ +import mbedtls'registration; +import net'http; +import system'threading; + +singleton Tester +{ + async Task browse(string url) + { + using(HttpClient client := :await HttpClient.openAsync(url)) + { + client.Headers.add("User-agent", "MyUserAgent"); + + HttpResponse response := :await client.getAsync(); + + string content := :await response.readAsStringAsync(); + + Console.writeLine(content); + }; + } +} + +public program() +{ + Tester.browse("https://www.google.com").Result; +} diff --git a/examples60/rosetta/ackermann/ackermann.l b/examples60/rosetta/ackermann/ackermann.l index fa72860641..8180091058 100644 --- a/examples60/rosetta/ackermann/ackermann.l +++ b/examples60/rosetta/ackermann/ackermann.l @@ -20,11 +20,11 @@ ackermann(m,n) }; m => - 0 { ^n + 1 } - ! { + 0 : { ^n + 1 } + ! : { n => - 0 { ^ackermann(m - 1,1) } - ! { ^ackermann(m - 1,ackermann(m,n-1)) } + 0 : { ^ackermann(m - 1,1) } + ! : { ^ackermann(m - 1,ackermann(m,n-1)) } } } diff --git a/examples60/rosetta/arithmeval/arithmeval.l b/examples60/rosetta/arithmeval/arithmeval.l index 0985cf817d..2680540eb8 100644 --- a/examples60/rosetta/arithmeval/arithmeval.l +++ b/examples60/rosetta/arithmeval/arithmeval.l @@ -112,10 +112,10 @@ singleton operatorState eval(ch) { ch => - $40 { // ( + $40 : { // ( ^ weak self.newBracket().gotoStarting() } - ! { + ! : { ^ weak self.newToken().append(ch).gotoToken() } } @@ -126,22 +126,22 @@ singleton tokenState eval(ch) { ch => - $41 { // ) + $41 : { // ) ^ weak self.closeBracket().gotoToken() } - $42 { // * + $42 : { // * ^ weak self.newProduct().gotoOperator() } - $43 { // + + $43 : { // + ^ weak self.newSummary().gotoOperator() } - $45 { // - + $45 : { // - ^ weak self.newDifference().gotoOperator() } - $47 { // / + $47 : { // / ^ weak self.newFraction().gotoOperator() } - ! { + ! : { ^ weak self.append(ch) } } @@ -152,13 +152,13 @@ singleton startState eval(ch) { ch => - $40 { // ( + $40 : { // ( ^ weak self.newBracket().gotoStarting() } - $45 { // - + $45 : { // - ^ weak self.newToken().append("0").newDifference().gotoOperator() } - ! { + ! : { ^ weak self.newToken().append(ch).gotoToken() } } diff --git a/examples60/rosetta/bullscows/bullscows.l b/examples60/rosetta/bullscows/bullscows.l index 79f2d793ea..2f3f0a6413 100644 --- a/examples60/rosetta/bullscows/bullscows.l +++ b/examples60/rosetta/bullscows/bullscows.l @@ -40,7 +40,7 @@ class GameMaster var number := ch.toString().toInt(); // check range - ifnot (number > 0 && number < 10) + if:not (number > 0 && number < 10) { InvalidArgumentException.raise() }; // check duplicates @@ -68,9 +68,9 @@ class GameMaster }; bulls => - -1 { Console.printLine("Not a valid guess."); ^ true } - 4 { Console.printLine("Congratulations! You have won!"); ^ false } - ! { + -1 : { Console.printLine("Not a valid guess."); ^ true } + 4 : { Console.printLine("Congratulations! You have won!"); ^ false } + ! : { _attempt.append(1); Console.printLine("Your Score is ",bulls," bulls and ",cows," cows"); diff --git a/examples60/rosetta/gameoflife/gameoflife.l b/examples60/rosetta/gameoflife/gameoflife.l index 92f4e13e5d..48924fc4fb 100644 --- a/examples60/rosetta/gameoflife/gameoflife.l +++ b/examples60/rosetta/gameoflife/gameoflife.l @@ -1,4 +1,4 @@ -import system'threading; +import extensions'threading; import cellular; const int DELAY = 50; diff --git a/examples60/rosetta/smavg/smavg.l b/examples60/rosetta/smavg/smavg.l index 6690b427eb..05c0a0c391 100644 --- a/examples60/rosetta/smavg/smavg.l +++ b/examples60/rosetta/smavg/smavg.l @@ -19,8 +19,8 @@ class SMA var count := theList.Length; count => - 0 { ^0.0r } - ! { + 0 : { ^0.0r } + ! : { if (count > thePeriod) { theList.removeAt(0); diff --git a/examples60/rosetta/truncprime/truncprime.l b/examples60/rosetta/truncprime/truncprime.l index b133385eb9..c8877aa9ed 100644 --- a/examples60/rosetta/truncprime/truncprime.l +++ b/examples60/rosetta/truncprime/truncprime.l @@ -33,7 +33,7 @@ extension mathOp while (n != 0) { - ifnot (n.isPrime()) + if:not (n.isPrime()) { ^ false }; n := n / 10 @@ -52,7 +52,7 @@ extension mathOp while (n != 0) { - ifnot (n.isPrime()) + if:not (n.isPrime()) { ^ false }; tens := tens / 10; diff --git a/examples60/rosetta/twelvestats/twelvestats.l b/examples60/rosetta/twelvestats/twelvestats.l index e99e2cb220..c755f1cb25 100644 --- a/examples60/rosetta/twelvestats/twelvestats.l +++ b/examples60/rosetta/twelvestats/twelvestats.l @@ -53,9 +53,9 @@ public program() var counts := bits.zipBy(results, (b,r => b.xor(r).toBit() )).summarize(); counts => - 0 { Console.printLine("Total hit :",results.printSolution(bits)) } - 1 { Console.printLine("Near miss :",results.printSolution(bits)) } - 12 { Console.printLine("Total miss:",results.printSolution(bits)) }; + 0 : { Console.printLine("Total hit :",results.printSolution(bits)) } + 1 : { Console.printLine("Near miss :",results.printSolution(bits)) } + 12: { Console.printLine("Total miss:",results.printSolution(bits)) }; }; Console.readChar() diff --git a/examples60/rosetta/twentyfour/twentyfour.l b/examples60/rosetta/twentyfour/twentyfour.l index ecc5be6bf7..1c8084f68b 100644 --- a/examples60/rosetta/twentyfour/twentyfour.l +++ b/examples60/rosetta/twentyfour/twentyfour.l @@ -18,13 +18,13 @@ class ExpressionTree var node := new DynamicStruct(); ch => - $43 { node.Level := level + 1; node.Operation := mssg add } // + - $45 { node.Level := level + 1; node.Operation := mssg subtract } // - - $42 { node.Level := level + 2; node.Operation := mssg multiply } // * - $47 { node.Level := level + 2; node.Operation := mssg divide } // / - $40 { level.append(10); ^ self } // ( - $41 { level.reduce(10); ^ self } // ) - ! { + $43 : { node.Level := level + 1; node.Operation := mssg add } // + + $45 : { node.Level := level + 1; node.Operation := mssg subtract } // - + $42 : { node.Level := level + 2; node.Operation := mssg multiply } // * + $47 : { node.Level := level + 2; node.Operation := mssg divide } // / + $40 : { level.append(10); ^ self } // ( + $41 : { level.reduce(10); ^ self } // ) + ! : { node.Leaf := ch.toString().toReal(); node.Level := level + 3 }; @@ -149,7 +149,7 @@ class TwentyFourGame var leaves := new ArrayList(); tree.readLeaves(leaves); - ifnot (leaves.ascendant().sequenceEqual(theNumbers.ascendant())) + if:not (leaves.ascendant().sequenceEqual(theNumbers.ascendant())) { Console.printLine("Invalid input. Enter an equation using all of those four digits. Try again."); ^ self }; var result := tree.Value; diff --git a/examples60/rosetta/wireworld/wireworld.l b/examples60/rosetta/wireworld/wireworld.l index 8fd1d35cbd..5f26ca7f3a 100644 --- a/examples60/rosetta/wireworld/wireworld.l +++ b/examples60/rosetta/wireworld/wireworld.l @@ -30,7 +30,7 @@ wireWorldRuleSet = new RuleSet int cell := s.at(x, y); cell => - conductor + conductor: { int number := s.LiveCell(x, y, electronHead); if (number == 1 || number == 2) @@ -42,15 +42,15 @@ wireWorldRuleSet = new RuleSet ^ conductor } } - electronHead + electronHead: { ^ electronTail } - electronTail + electronTail: { ^ conductor } - !{ + !:{ ^ cell } } @@ -62,7 +62,7 @@ sealed class Model constructor load(string stateString, int maxX, int maxY) { - var strings := stateString.splitBy(newLineConstant).selectBy::(s => s.toArray()).toArray(); + var strings := stateString.splitBy(NewLineConstant).selectBy::(s => s.toArray()).toArray(); theSpace := IntMatrixSpace.allocate(maxX, maxY, RuleSet { @@ -75,10 +75,10 @@ sealed class Model if (y < l.Length) { (l[y]) => - conductorLabel { retVal := conductor } - headLabel { retVal := electronHead } - tailLabel { retVal := electronTail } - emptyLabel { retVal := empty } + conductorLabel : { retVal := conductor } + headLabel : { retVal := electronHead } + tailLabel : { retVal := electronTail } + emptyLabel : { retVal := empty } } else { @@ -117,9 +117,9 @@ sealed class Model int cell := theSpace.at(i, j); cell => - conductor { label := conductorLabel } - electronHead { label := headLabel } - electronTail { label := tailLabel }; + conductor : { label := conductorLabel } + electronHead : { label := headLabel } + electronTail : { label := tailLabel }; Console.write(label); diff --git a/examples60/rosetta/zeckendorf_arithm/zeckendorf_arithm.l b/examples60/rosetta/zeckendorf_arithm/zeckendorf_arithm.l index 85b81d5655..c6a6a9c986 100644 --- a/examples60/rosetta/zeckendorf_arithm/zeckendorf_arithm.l +++ b/examples60/rosetta/zeckendorf_arithm/zeckendorf_arithm.l @@ -21,7 +21,7 @@ sealed struct ZeckendorfNumber while (i >= 0) { - dVal += ((intConvertor.convert(s[i]) - 48) * q); + dVal += ((IntConvertor.convert(s[i]) - 48) * q); q *= 2; i -= 1 @@ -47,10 +47,10 @@ sealed struct ZeckendorfNumber int v := (dVal $shr (i * 2)) & 3; v => - 0 { ^ self } - 1 { ^ self } - 2 { - ifnot ((dVal $shr ((i + 1) * 2)).allMask(1)) + 0 : { ^ self } + 1 : { ^ self } + 2 : { + if:not ((dVal $shr ((i + 1) * 2)).allMask(1)) { ^ self }; @@ -59,7 +59,7 @@ sealed struct ZeckendorfNumber ^ self } - 3 { + 3 : { int tmp := 3 $shl (i * 2); tmp := tmp.bxor(-1); dVal := dVal & tmp; @@ -81,7 +81,7 @@ sealed struct ZeckendorfNumber { if (pos == 0) { ^ self.inc() }; - ifnot((dVal $shr pos).allMask(1)) + if:not((dVal $shr pos).allMask(1)) { dVal += (1 $shl pos); self.a(pos / 2); diff --git a/examples60/rosetta/zhangsuen/zhangsuen.l b/examples60/rosetta/zhangsuen/zhangsuen.l index 996d007dbc..5924bfeaa2 100644 --- a/examples60/rosetta/zhangsuen/zhangsuen.l +++ b/examples60/rosetta/zhangsuen/zhangsuen.l @@ -50,7 +50,7 @@ extension zhangsuenOp : Matrix if(self.numTransitions(r,c) != 1) { ^ false }; - ifnot (self.atLeastOneIsWhite(r,c,firstStep.iif(0,1))) + if:not (self.atLeastOneIsWhite(r,c,firstStep.iif(0,1))) { ^ false }; toWhite.append(new { x = c; y = r; }); diff --git a/examples60/rosetta60.linux.prjcol b/examples60/rosetta60.linux.prjcol index c43bf6a9af..8a5833ee57 100644 --- a/examples60/rosetta60.linux.prjcol +++ b/examples60/rosetta60.linux.prjcol @@ -1,60 +1,57 @@ - rosetta/accumulator/accumulator.l - rosetta/ackermann/ackermann.l - rosetta/addfield/addfield.l - rosetta/amb/amb.l - rosetta/anagram/anagram.l - rosetta/anonymrec/anonymrec.l - rosetta/aplusb/aplusb.l - rosetta/applycallback/applycallback.l - rosetta/arithmeticint/arithmeticint.l - rosetta/arithmeval/arithmeval.l - rosetta/arithmmean/arithmmean.l - rosetta/arrayconcat/arrayconcat.l - rosetta/arraymode/arraymode.l - rosetta/arrays/arrays.l - rosetta/associativearrays/associativearrays.l - rosetta/bestshuffle/bestshuffle.l - rosetta/binary/binary.l - rosetta/bitwise/bitwise.l - rosetta/brackets/brackets.l - rosetta/bullscows/bullscows.l - rosetta/caesar/caesar.l - rosetta/calendar/calendar.l - rosetta/charmatch/charmatch.l - rosetta/combinations/combinations.l - rosetta/complist/complist.l - rosetta/doors/doors.l - rosetta/dynamic_var/dynamic_var.l - rosetta/evolutionary/evolutionary.l - rosetta/firstclass/firstclass.l - rosetta/gameoflife/gameoflife.prj - rosetta/knutalg/knutalg.l - rosetta/loop_multiple_arrays/loopma.l - rosetta/manboy/manboy.l - rosetta/median/median.l - rosetta/ninetynine/ninetynine.l - rosetta/reverse_words_in_string/reverse_words.l - rosetta/simple_windowed_app/simple_windowed_app.prj - rosetta/smavg/smavg.l - rosetta/string_append/string_append.l - rosetta/string_case/string_case.l - rosetta/string_comparison/string_comparision.l - rosetta/string_concatenation/string_concatenation.l - rosetta/string_interpolation/string_interpolation.l - rosetta/string_matching/string_matching.l - rosetta/string_prepend/string_prepend.l - rosetta/tokenizer/tokenizer.l - rosetta/toppergroup/toppergroup.l - rosetta/treeview/treeview.l - rosetta/trigonometric/trigonometric.l - rosetta/truncprime/truncprime.l - rosetta/twelvestats/twelvestats.l - rosetta/twentyfour/twentyfour.l - rosetta/wireworld/wireworld.l - rosetta/ycombinator/ycombinator.l - rosetta/zeckendorf_arithm/zeckendorf_arithm.l - rosetta/zhangsuen/zhangsuen.l + accumulator.l + ackermann.l + addfield.l + amb.l + anagram.l + anonymrec.l + aplusb.l + applycallback.l + arithmeticint.l + arithmeval.l + arithmmean.l + arrayconcat.l + arraymode.l + arrays.l + associativearrays.l + bestshuffle.l + binary.l + bitwise.l + brackets.l + bullscows.l + caesar.l + calendar.l + charmatch.l + combinations.l + complist.l + doors.l + dynamic_var.l + evolutionary.l + firstclass.l + knutalg.l + loopma.l + manboy.l + median.l + ninetynine.l + reverse_words.l + smavg.l + string_append.l + string_comparision.l + string_concatenation.l + string_interpolation.l + string_matching.l + string_prepend.l + tokenizer.l + toppergroup.l + treeview.l + trigonometric.l + truncprime.l + twelvestats.l + twentyfour.l + wireworld.l + ycombinator.l + zeckendorf_arithm.l + zhangsuen.l \ No newline at end of file diff --git a/examples60/rosetta60.prjcol b/examples60/rosetta60.prjcol index db61bc1a26..1392aa6ef4 100644 --- a/examples60/rosetta60.prjcol +++ b/examples60/rosetta60.prjcol @@ -1,60 +1,60 @@ - rosetta\accumulator\accumulator.l - rosetta\ackermann\ackermann.l - rosetta\addfield\addfield.l - rosetta\amb\amb.l - rosetta\anagram\anagram.l - rosetta\anonymrec\anonymrec.l - rosetta\aplusb\aplusb.l - rosetta\applycallback\applycallback.l - rosetta\arithmeticint\arithmeticint.l - rosetta\arithmeval\arithmeval.l - rosetta\arithmmean\arithmmean.l - rosetta\arrayconcat\arrayconcat.l - rosetta\arraymode\arraymode.l - rosetta\arrays\arrays.l - rosetta\associativearrays\associativearrays.l - rosetta\bestshuffle\bestshuffle.l - rosetta\binary\binary.l - rosetta\bitwise\bitwise.l - rosetta\brackets\brackets.l - rosetta\bullscows\bullscows.l - rosetta\caesar\caesar.l - rosetta\calendar\calendar.l - rosetta\charmatch\charmatch.l - rosetta\combinations\combinations.l - rosetta\complist\complist.l - rosetta\doors\doors.l - rosetta\dynamic_var\dynamic_var.l - rosetta\evolutionary\evolutionary.l - rosetta\firstclass\firstclass.l - rosetta\gameoflife\gameoflife.prj - rosetta\knutalg\knutalg.l - rosetta\loop_multiple_arrays\loopma.l - rosetta\manboy\manboy.l - rosetta\median\median.l - rosetta\ninetynine\ninetynine.l - rosetta\reverse_words_in_string\reverse_words.l + accumulator.l + ackermann.l + addfield.l + amb.l + anagram.l + anonymrec.l + aplusb.l + applycallback.l + arithmeticint.l + arithmeval.l + arithmmean.l + arrayconcat.l + arraymode.l + arrays.l + associativearrays.l + bestshuffle.l + binary.l + bitwise.l + brackets.l + bullscows.l + caesar.l + calendar.l + charmatch.l + combinations.l + complist.l + doors.l + dynamic_var.l + evolutionary.l + firstclass.l + gameoflife.prj + knutalg.l + loopma.l + manboy.l + median.l + ninetynine.l + reverse_words.l rosetta\simple_windowed_app\simple_windowed_app.prj - rosetta\smavg\smavg.l - rosetta\string_append\string_append.l - rosetta\string_case\string_case.l - rosetta\string_comparison\string_comparision.l - rosetta\string_concatenation\string_concatenation.l - rosetta\string_interpolation\string_interpolation.l - rosetta\string_matching\string_matching.l - rosetta\string_prepend\string_prepend.l - rosetta\tokenizer\tokenizer.l - rosetta\toppergroup\toppergroup.l - rosetta\treeview\treeview.l - rosetta\trigonometric\trigonometric.l - rosetta\truncprime\truncprime.l - rosetta\twelvestats\twelvestats.l - rosetta\twentyfour\twentyfour.l - rosetta\wireworld\wireworld.l - rosetta\ycombinator\ycombinator.l - rosetta\zeckendorf_arithm\zeckendorf_arithm.l - rosetta\zhangsuen\zhangsuen.l + smavg.l + string_append.l + string_case.l + string_comparision.l + string_concatenation.l + string_interpolation.l + string_matching.l + string_prepend.l + tokenizer.l + toppergroup.l + treeview.l + trigonometric.l + truncprime.l + twelvestats.l + twentyfour.l + wireworld.l + ycombinator.l + zeckendorf_arithm.l + zhangsuen.l \ No newline at end of file diff --git a/examples60/scripts/calc/calc.prj b/examples60/scripts/calc/calc.prj index 27a64bb02c..35c2851a66 100644 --- a/examples60/scripts/calc/calc.prj +++ b/examples60/scripts/calc/calc.prj @@ -30,7 +30,7 @@ - extensions'programLoop + extensions'ProgramLoop calc'staticRules calc'control diff --git a/examples60/scripts/calc/parser.l b/examples60/scripts/calc/parser.l index 516118eabb..4809a75f6a 100644 --- a/examples60/scripts/calc/parser.l +++ b/examples60/scripts/calc/parser.l @@ -14,16 +14,16 @@ extension lexicalOp { ^ mssg letter }; self => - $32 { ^ mssg whitespace } - $40 { ^ mssg opening } - $41 { ^ mssg closing } - $42 { ^ mssg star } - $43 { ^ mssg plus } - $44 { ^ mssg comma } - $45 { ^ mssg minus } - $46 { ^ mssg dot } - $47 { ^ mssg slash } - ! { ^ mssg unknown } + $32 : { ^ mssg whitespace } + $40 : { ^ mssg opening } + $41 : { ^ mssg closing } + $42 : { ^ mssg star } + $43 : { ^ mssg plus } + $44 : { ^ mssg comma } + $45 : { ^ mssg minus } + $46 : { ^ mssg dot } + $47 : { ^ mssg slash } + ! : { ^ mssg unknown } } } @@ -313,10 +313,10 @@ class StateMachine { var function; operator => - "+" { function := mssgconst add[2]} - "-" { function := mssgconst subtract[2]} - "*" { function := mssgconst multiply[2]} - "/" { function := mssgconst divide[2]}; + "+" : { function := mssgconst add[2]} + "-" : { function := mssgconst subtract[2]} + "*" : { function := mssgconst multiply[2]} + "/" : { function := mssgconst divide[2]}; _derivationTree.append(TreeNode.new(_level + nodeLevel, function)); } diff --git a/examples60/scripts/interpreter/interpreter.l b/examples60/scripts/interpreter/interpreter.l index 3dc71106f3..387ae0a0b4 100644 --- a/examples60/scripts/interpreter/interpreter.l +++ b/examples60/scripts/interpreter/interpreter.l @@ -115,7 +115,7 @@ class TapeAssembler new Message("add[2]"), Expression.MessageCall( new Message("toInt[2]"), - Expression.Constant(intConvertExt), + Expression.Constant(IntConvertExt), Expression.MessageCall( new Message("at[2]"), Expression.Variable("tape"), @@ -142,7 +142,7 @@ class TapeAssembler new Message("subtract[2]"), Expression.MessageCall( new Message("toInt[2]"), - Expression.Constant(intConvertExt), + Expression.Constant(IntConvertExt), Expression.MessageCall( new Message("at[2]"), Expression.Variable("tape"), @@ -360,19 +360,19 @@ public program() string path := program_arguments[1]; solution => - 0 { + 0 : { solution0() } - 1 { + 1 : { solution1() } - 2 { + 2 : { solution2() } - 3 { + 3 : { solution3(path) } - ! { + ! : { solution4(path) }; } \ No newline at end of file diff --git a/recompile60.bat b/recompile60.bat index c85bfa18e1..d2afc27e43 100644 --- a/recompile60.bat +++ b/recompile60.bat @@ -25,7 +25,7 @@ IF "%1"=="-build" GOTO End ECHO Generating data files ECHO ---------------------------------------- -CALL build\rebuild_data60_x86.bat +CALL scripts\rebuild_data60_x86.bat IF NOT %ERRORLEVEL%==0 GOTO CompilerError ECHO Unit tests @@ -35,7 +35,7 @@ IF NOT %ERRORLEVEL%==0 GOTO CompilerError ECHO Generating data files ECHO ---------------------------------------- -CALL build\rebuild_data60_x64.bat +CALL scripts\rebuild_data60_x64.bat IF NOT %ERRORLEVEL%==0 GOTO CompilerError ECHO Unit tests @@ -46,11 +46,11 @@ IF NOT %ERRORLEVEL%==0 GOTO CompilerError ECHO =========== Release Compiled ================== ECHO ============== x86 build ====================== -CALL build\rebuild_lib60_x86.bat +CALL scripts\rebuild_lib60_x86.bat IF NOT %ERRORLEVEL%==0 GOTO CompilerError ECHO ============== x64 build ====================== -CALL build\rebuild_lib60_x64.bat +CALL scripts\rebuild_lib60_x64.bat goto:eof ::ERRORS diff --git a/build/aarch64/build_package_arm64.script b/scripts/aarch64/build_package_arm64.script old mode 100755 new mode 100644 similarity index 94% rename from build/aarch64/build_package_arm64.script rename to scripts/aarch64/build_package_arm64.script index 672ab45748..1c491a322c --- a/build/aarch64/build_package_arm64.script +++ b/scripts/aarch64/build_package_arm64.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.3.aarch64-linux +RELEASE=elena-6.6.5.aarch64-linux mkdir -p ../lib60_64 mkdir -p /usr/share/elena @@ -49,6 +49,16 @@ else exit 1 fi +../../bin/og64-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + cp ../../dat/og/*.dat /usr/share/elena/ cp ../../dat/sg/syntax60.dat /usr/share/elena @@ -155,6 +165,7 @@ fi echo compiling shared files cp ../../dat/og/bt_rules60.dat ./$RELEASE/usr/share/elena + cp ../../dat/og/bt_xrules60.dat ./$RELEASE/usr/share/elena cp ../../dat/og/bc_rules60.dat ./$RELEASE/usr/share/elena cp ../../dat/sg/syntax60.dat ./$RELEASE/usr/share/elena diff --git a/build/aarch64/control b/scripts/aarch64/control similarity index 96% rename from build/aarch64/control rename to scripts/aarch64/control index 8dd0f0bfc3..9397d7168a 100644 --- a/build/aarch64/control +++ b/scripts/aarch64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.3 +Version: 6.6.5 Architecture: aarch64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/amd64/build_package_amd64.script b/scripts/amd64/build_package_amd64.script old mode 100755 new mode 100644 similarity index 94% rename from build/amd64/build_package_amd64.script rename to scripts/amd64/build_package_amd64.script index 3907389338..140f023cea --- a/build/amd64/build_package_amd64.script +++ b/scripts/amd64/build_package_amd64.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.3.amd64-linux +RELEASE=elena-6.6.5.amd64-linux mkdir -p ../../lib60_64 mkdir -p /usr/share/elena @@ -60,6 +60,15 @@ else exit 1 fi +../../bin/og64-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi cp ../../dat/og/*.dat /usr/share/elena/ cp ../../dat/sg/syntax60.dat /usr/share/elena @@ -167,6 +176,7 @@ fi echo compiling shared files cp ../../dat/og/bt_rules60.dat ./$RELEASE/usr/share/elena + cp ../../dat/og/bt_xrules60.dat ./$RELEASE/usr/share/elena cp ../../dat/og/bc_rules60.dat ./$RELEASE/usr/share/elena cp ../../dat/sg/syntax60.dat ./$RELEASE/usr/share/elena diff --git a/build/amd64/control b/scripts/amd64/control similarity index 96% rename from build/amd64/control rename to scripts/amd64/control index 1af39e3b70..336cda6db7 100644 --- a/build/amd64/control +++ b/scripts/amd64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.3 +Version: 6.6.5 Architecture: amd64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/amd64/local_build_package_amd64.script b/scripts/amd64/local_build_package_amd64.script old mode 100644 new mode 100755 similarity index 81% rename from build/amd64/local_build_package_amd64.script rename to scripts/amd64/local_build_package_amd64.script index 3cd77ccf1b..2b09541bd2 --- a/build/amd64/local_build_package_amd64.script +++ b/scripts/amd64/local_build_package_amd64.script @@ -35,6 +35,15 @@ else exit 1 fi +../../bin/og64-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi cp ../../dat/og/*.dat ../../bin cp ../../dat/sg/syntax60.dat ../../bin @@ -83,24 +92,4 @@ fi echo . fi - elena64-cli ../../tests60/system_tests/system_tests.prj - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../tests60/system_tests/system_tests - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - exit 0 \ No newline at end of file diff --git a/scripts/amd64/local_runtests.script b/scripts/amd64/local_runtests.script new file mode 100755 index 0000000000..4024db8511 --- /dev/null +++ b/scripts/amd64/local_runtests.script @@ -0,0 +1,25 @@ +#!/bin/bash + + mkdir -p /usr/lib/elena/lib60_64 + + cp ../../bin/libelenart60_64.so /usr/lib/elena/ + + ../../bin/elena64-cli ../../tests60/system_tests/system_tests.prj + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + ../../tests60/system_tests/system_tests + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi diff --git a/scripts/create_package_x64.bat b/scripts/create_package_x64.bat new file mode 100644 index 0000000000..3feb65dbd6 --- /dev/null +++ b/scripts/create_package_x64.bat @@ -0,0 +1,101 @@ +@echo off + +ECHO =========== Compiling ELENA files ================== + +md %~dp0\x64 +md %~dp0\x64\bin +md %~dp0\x64\bin\templates +md %~dp0\x64\bin\scripts +md %~dp0\x64\bin\amd64 +md %~dp0\x64\doc +md %~dp0\x64\examples60 + +copy %~dp0\..\bin\asm64-cli.exe %~dp0\x64\bin +copy %~dp0\..\bin\elena64-cli.exe %~dp0\x64\bin +copy %~dp0\..\bin\elena64-ide.exe %~dp0\x64\bin +copy %~dp0\..\bin\sg64-cli.exe %~dp0\x64\bin +copy %~dp0\..\bin\og64-cli.exe %~dp0\x64\bin +copy %~dp0\..\bin\ecv64-cli.exe %~dp0\x64\bin +copy %~dp0\..\bin\elenart60_64.dll %~dp0\x64\bin +copy %~dp0\..\bin\winstub.ex_ %~dp0\x64\bin +copy %~dp0\..\bin\elc60.cfg %~dp0\x64\bin +copy %~dp0\..\bin\elenart60.cfg %~dp0\x64\bin +copy %~dp0\..\bin\elenavm60.cfg %~dp0\x64\bin + +copy %~dp0\..\bin\amd64\core60.bin %~dp0\x64\bin\amd64 +copy %~dp0\..\bin\amd64\core60_win.bin %~dp0\x64\bin\amd64 +copy %~dp0\..\bin\amd64\corex60.bin %~dp0\x64\bin\amd64 +copy %~dp0\..\bin\amd64\core60_win_client.bin %~dp0\x64\bin\amd64 + +copy %~dp0\..\bin\templates\*.cfg %~dp0\x64\bin\templates\ +copy %~dp0\..\bin\scripts\*.es %~dp0\x64\bin\scripts\ + +copy %~dp0\..\doc\license %~dp0\x64\doc\ +copy %~dp0\..\doc\contributors %~dp0\x64\doc\ +copy %~dp0\..\readme.md %~dp0\x64\ +copy %~dp0\..\CHANGELOG.md %~dp0\x64\ +copy %~dp0\..\VERSION %~dp0\x64\ + +md %~dp0\x64\src60 +xcopy %~dp0\..\src60\*.l %~dp0\x64\src60\ /s +xcopy %~dp0\..\src60\*.prj %~dp0\x64\src60\ /s + +copy %~dp0\..\src60\elena_api.prjcol %~dp0\x64\src60\ + +%~dp0\..\bin\sg64-cli.exe %~dp0\..\dat\sg\syntax60.txt +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +move %~dp0..\dat\sg\syntax60.dat %~dp0\x64\bin\ + +%~dp0\..\bin\og64-cli %~dp0\..\dat\og\bc_rules60.txt +%~dp0\..\bin\og64-cli -s %~dp0\..\dat\og\bt_rules60.txt +%~dp0\..\bin\og64-cli -s %~dp0\..\dat\og\bt_xrules60.txt + +move %~dp0..\dat\og\bt_rules60.dat %~dp0\x64\bin\ +move %~dp0..\dat\og\bt_xrules60.dat %~dp0\x64\bin\ +move %~dp0..\dat\og\bc_rules60.dat %~dp0\x64\bin\ + +md %~dp0\lib60_64 + +%~dp0\..\bin\asm64-cli -bc64 %~dp0\..\src60\core\system.core_routines.esm %~dp0\x64\lib60_64 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\..\bin\asm64-cli -bc64 %~dp0\..\src60\core\system.win_core_routines.esm %~dp0\x64\lib60_64 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\x64\bin\elena64-cli %~dp0x64\src60\elena_api.prjcol +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\..\bin\asm64-cli -amd64 %~dp0\..\asm\amd64\core60.asm bin\amd64 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\..\bin\asm64-cli -amd64 %~dp0\..\asm\amd64\core60_win.asm bin\amd64 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +xcopy %~dp0\..\examples60\*.l %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.prj %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.txt %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.bmp %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.es %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.js %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.ls %~dp0\x64\examples60\ /s +xcopy %~dp0\..\examples60\*.xs %~dp0\x64\examples60\ /s + +goto:eof +::ERRORS +::--------------------- +:CompilerError +echo The MSBuild returns error %ERRORLEVEL% +goto:eof diff --git a/scripts/create_package_x86.bat b/scripts/create_package_x86.bat new file mode 100644 index 0000000000..4395b3d616 --- /dev/null +++ b/scripts/create_package_x86.bat @@ -0,0 +1,122 @@ +@echo off + +ECHO =========== Compiling ELENA files ================== + +md %~dp0\x86 +md %~dp0\x86\bin +md %~dp0\x86\bin\templates +md %~dp0\x86\bin\scripts +md %~dp0\x86\bin\x32 +md %~dp0\x86\doc +md %~dp0\x86\examples60 + +copy %~dp0\..\bin\asm-cli.exe %~dp0\x86\bin +copy %~dp0\..\bin\elena-cli.exe %~dp0\x86\bin +copy %~dp0\..\bin\elena-ide.exe %~dp0\x86\bin +copy %~dp0\..\bin\sg-cli.exe %~dp0\x86\bin +copy %~dp0\..\bin\og-cli.exe %~dp0\x86\bin +copy %~dp0\..\bin\ecv-cli.exe %~dp0\x86\bin +copy %~dp0\..\bin\elt-cli.exe %~dp0\x86\bin +copy %~dp0\..\bin\elenart60.dll %~dp0\x86\bin +copy %~dp0\..\bin\elenasm60.dll %~dp0\x86\bin +copy %~dp0\..\bin\elenavm60.dll %~dp0\x86\bin +copy %~dp0\..\bin\winstub.ex_ %~dp0\x86\bin +copy %~dp0\..\bin\elc60.cfg %~dp0\x86\bin +copy %~dp0\..\bin\elenart60.cfg %~dp0\x86\bin +copy %~dp0\..\bin\elenavm60.cfg %~dp0\x86\bin +copy %~dp0\..\bin\elt60.es %~dp0\x86\bin +copy %~dp0\..\bin\command60.es %~dp0\x86\bin + +copy %~dp0\..\bin\x86\core60.bin %~dp0\x86\bin\x86\ +copy %~dp0\..\bin\x86\core60_win.bin %~dp0\x86\bin\x86\ +copy %~dp0\..\bin\x86\core60_win_client.bin %~dp0\x86\bin\x86\ +copy %~dp0\..\bin\x86\corex60.bin %~dp0\x86\bin\x86\ +copy %~dp0\..\bin\x86\corex60_win.bin %~dp0\x86\bin\x86\ + +copy %~dp0\..\bin\templates\*.cfg %~dp0\x86\bin\templates\ +copy %~dp0\..\bin\scripts\*.es %~dp0\x86\bin\scripts\ + +copy %~dp0\..\doc\license %~dp0\x86\doc\ +copy %~dp0\..\doc\contributors %~dp0\x86\doc\ +copy %~dp0\..\readme.md %~dp0\x86\ +copy %~dp0\..\CHANGELOG.md %~dp0\x86\ +copy %~dp0\..\VERSION %~dp0\x86\ + +md %~dp0\x86\src60 +xcopy %~dp0\..\src60\*.l %~dp0\x86\src60\ /s +xcopy %~dp0\..\src60\*.prj %~dp0\x86\src60\ /s + +copy %~dp0\..\src60\elena_api.prjcol %~dp0\x86\src60\ + +%~dp0\..\bin\sg-cli.exe %~dp0\..\dat\sg\syntax60.txt +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +move %~dp0..\dat\sg\syntax60.dat %~dp0\x86\bin\ + +%~dp0\..\bin\og-cli %~dp0\..\dat\og\bc_rules60.txt +%~dp0\..\bin\og-cli -s %~dp0\..\dat\og\bt_rules60.txt +%~dp0\..\bin\og-cli -s %~dp0\..\dat\og\bt_xrules60.txt + +move %~dp0..\dat\og\bt_rules60.dat %~dp0\x86\bin\ +move %~dp0..\dat\og\bt_xrules60.dat %~dp0\x86\bin\ +move %~dp0..\dat\og\bc_rules60.dat %~dp0\x86\bin\ + +md %~dp0\lib60 + +%~dp0\..\bin\asm-cli -bc32 %~dp0\..\src60\core\system.core_routines.esm %~dp0\x86\lib60 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\..\bin\asm-cli -bc32 %~dp0\..\src60\core\system.win_core_routines.esm %~dp0\x86\lib60 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\x86\bin\elena-cli %~dp0x86\src60\elena_api.prjcol +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\core60.asm %~dp0\x86\bin\x32 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\core60_win.asm %~dp0\x86\bin\x32 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\corex60_win.asm %~dp0\x86\bin\x32 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\corex60.asm %~dp0\x86\bin\x32 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\core60_win_client.asm %~dp0\x86\bin\x32 +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +xcopy %~dp0\..\examples60\*.l %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.prj %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.txt %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.bmp %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.es %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.js %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.ls %~dp0\x86\examples60\ /s +xcopy %~dp0\..\examples60\*.xs %~dp0\x86\examples60\ /s + +goto:eof +::ERRORS +::--------------------- +:CompilerError +echo The MSBuild returns error %ERRORLEVEL% +goto:eof diff --git a/build/i386/build_package_i386.script b/scripts/i386/build_package_i386.script old mode 100755 new mode 100644 similarity index 91% rename from build/i386/build_package_i386.script rename to scripts/i386/build_package_i386.script index 45150cc9e4..72d1b40073 --- a/build/i386/build_package_i386.script +++ b/scripts/i386/build_package_i386.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.3.i386-linux +RELEASE=elena-6.6.5.i386-linux mkdir -p ../lib60 mkdir -p /usr/share/elena @@ -61,6 +61,16 @@ else exit 1 fi +../../bin/og-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + cp ../../dat/og/*.dat /usr/share/elena/ cp ../../dat/og/*.dat ../../bin cp ../../dat/sg/syntax60.dat /usr/share/elena @@ -78,6 +88,16 @@ else exit 1 fi +../../bin/asm-cli -x86 ../../asm/x32/corex60.asm /usr/lib/elena/core/x32 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + ../../bin/asm-cli -x86 ../../asm/x32/core60_lnx.asm /usr/lib/elena/core/x32 ret=$? if [ $ret -eq 0 ] @@ -169,6 +189,7 @@ echo compiling lib60 files echo compiling shared files cp ../../dat/og/bt_rules60.dat ./$RELEASE/usr/share/elena + cp ../../dat/og/bt_xrules60.dat ./$RELEASE/usr/share/elena cp ../../dat/og/bc_rules60.dat ./$RELEASE/usr/share/elena cp ../../dat/sg/syntax60.dat ./$RELEASE/usr/share/elena diff --git a/build/i386/control b/scripts/i386/control similarity index 96% rename from build/i386/control rename to scripts/i386/control index df5785ced6..1f0c254d08 100644 --- a/build/i386/control +++ b/scripts/i386/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.3 +Version: 6.6.5 Architecture: i386 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/scripts/i386/local_build_package_i386.script b/scripts/i386/local_build_package_i386.script new file mode 100755 index 0000000000..c548caca50 --- /dev/null +++ b/scripts/i386/local_build_package_i386.script @@ -0,0 +1,105 @@ +#!/bin/bash + +mkdir -p ../../lib60 +mkdir -p ../../bin/x32 + +echo compiling data files + +../../bin/sg-cli ../../dat/sg/syntax60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og-cli ../../dat/og/bc_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og-cli -s ../../dat/og/bt_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +cp ../../dat/og/*.dat ../../bin +cp ../../dat/sg/syntax60.dat ../../bin + +echo compiling assembly files + +../../bin/asm-cli -x86 ../../asm/x32/core60.asm ../../bin/x32 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/asm-cli -x86 ../../asm/x32/corex60.asm ../../bin/x32 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/asm-cli -x86 ../../asm/x32/core60_lnx.asm ../../bin/x32 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +# echo compiling lib60 files + + ../../bin/asm-cli -bc32 ../../src60/core/system.core_routines.esm ../../lib60 + ret=$? + if [ $ret -eq 0 ] + then + echo . + else + echo "Failure" >&2 + exit 1 + fi + + ../../bin/elena-cli ../../src60/elena_api.linux.prjcol + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + +exit 0 \ No newline at end of file diff --git a/scripts/i386/local_runtests.script b/scripts/i386/local_runtests.script new file mode 100755 index 0000000000..1b4864983e --- /dev/null +++ b/scripts/i386/local_runtests.script @@ -0,0 +1,25 @@ +#!/bin/bash + + mkdir -p /usr/lib/elena/lib60 + + cp ../../bin/libelenart60.so /usr/lib/elena/ + + ../../bin/elena-cli ../../tests60/system_tests/system_tests.prj + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + ../../tests60/system_tests/system_tests + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi diff --git a/build/ppc64le/build_package_ppc64le.script b/scripts/ppc64le/build_package_ppc64le.script old mode 100755 new mode 100644 similarity index 94% rename from build/ppc64le/build_package_ppc64le.script rename to scripts/ppc64le/build_package_ppc64le.script index 539c09be10..02a890b713 --- a/build/ppc64le/build_package_ppc64le.script +++ b/scripts/ppc64le/build_package_ppc64le.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.3.ppc64le-linux +RELEASE=elena-6.6.5.ppc64le-linux mkdir -p ../lib60_64 mkdir -p /usr/share/elena @@ -49,6 +49,16 @@ else exit 1 fi +../../bin/og64-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + cp ../../dat/og/*.dat /usr/share/elena/ cp ../../dat/sg/syntax60.dat /usr/share/elena @@ -155,6 +165,7 @@ fi echo compiling shared files cp ../../dat/og/bt_rules60.dat ./$RELEASE/usr/share/elena + cp ../../dat/og/bt_xrules60.dat ./$RELEASE/usr/share/elena cp ../../dat/og/bc_rules60.dat ./$RELEASE/usr/share/elena cp ../../dat/sg/syntax60.dat ./$RELEASE/usr/share/elena diff --git a/build/ppc64le/control b/scripts/ppc64le/control similarity index 96% rename from build/ppc64le/control rename to scripts/ppc64le/control index 47fb1f0279..ff68a8b073 100644 --- a/build/ppc64le/control +++ b/scripts/ppc64le/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.3 +Version: 6.6.5 Architecture: ppc64le Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/scripts/rebuild_data60_x64.bat b/scripts/rebuild_data60_x64.bat new file mode 100644 index 0000000000..3d68428ed7 --- /dev/null +++ b/scripts/rebuild_data60_x64.bat @@ -0,0 +1,59 @@ +REM NOTE : the script MUST be called from the root folder + +bin\sg64-cli dat\sg\syntax60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +move dat\sg\syntax60.dat bin + +bin\sg64-cli dat\sg\syntax50.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +move dat\sg\syntax50.dat bin + +bin\og64-cli dat\og\bc_rules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bc_rules60.dat bin + +bin\og64-cli -s dat\og\bt_rules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bt_rules60.dat bin + +bin\og64-cli -s dat\og\bt_xrules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bt_xrules60.dat bin + +@echo off +echo === Done === +@echo on + +@echo off +goto:eof +@echo on + +:Asm2BinError +echo ASM2BINX returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:CompilerError +echo ELC returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:TestError +echo System tests fail %ERRORLEVEL% +@echo off +goto:eof +@echo on diff --git a/scripts/rebuild_data60_x86.bat b/scripts/rebuild_data60_x86.bat new file mode 100644 index 0000000000..fe3175ae2c --- /dev/null +++ b/scripts/rebuild_data60_x86.bat @@ -0,0 +1,59 @@ +REM NOTE : the script MUST be called from the root folder + +.\bin\sg-cli dat\sg\syntax60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +move dat\sg\syntax60.dat bin + +.\bin\sg-cli dat\sg\syntax50.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +move dat\sg\syntax50.dat bin + +bin\og-cli dat\og\bc_rules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bc_rules60.dat bin + +bin\og-cli -s dat\og\bt_rules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bt_rules60.dat bin + +bin\og-cli -s dat\og\bt_xrules60.txt +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on +move dat\og\bt_xrules60.dat bin + +@echo off +echo === Done === +@echo on + +@echo off +goto:eof +@echo on + +:Asm2BinError +echo ASM2BINX returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:CompilerError +echo ELC returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:TestError +echo System tests fail %ERRORLEVEL% +@echo off +goto:eof +@echo on \ No newline at end of file diff --git a/scripts/rebuild_lib60_x64.bat b/scripts/rebuild_lib60_x64.bat new file mode 100644 index 0000000000..fe8ddd239c --- /dev/null +++ b/scripts/rebuild_lib60_x64.bat @@ -0,0 +1,81 @@ +REM NOTE : the script MUST be called from the root folder + +bin\asm64-cli -amd64 asm\amd64\core60.asm bin\amd64 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm64-cli -amd64 asm\amd64\core60_win.asm bin\amd64 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm64-cli -amd64 asm\amd64\corex60.asm bin\amd64 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm64-cli -amd64 asm\amd64\corex60_win.asm bin\amd64 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm64-cli -amd64 asm\amd64\core60_win_client.asm bin\amd64 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm64-cli -bc64 src60\core\system.core_routines.esm lib60_64 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm64-cli -bc64 src60\core\system.win_core_routines.esm lib60_64 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\elena64-cli src60\elena_api.prjcol +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +bin\elena64-cli tests60\system_tests\system_tests.prj +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +echo system api test for amd64 +copy bin\elenart60_64.dll tests60\system_tests\ +copy bin\elenasm60_64.dll tests60\system_tests\ + +tests60\system_tests\system_tests64.exe +@echo off +if %ERRORLEVEL% NEQ 0 GOTO TestError +@echo on + +@echo off +echo === Done === +@echo on + +@echo off +goto:eof +@echo on + +:Asm2BinError +echo ASM2BINX returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:CompilerError +echo ELC returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:TestError +echo System tests fail %ERRORLEVEL% +@echo off +goto:eof +@echo on diff --git a/scripts/rebuild_lib60_x86.bat b/scripts/rebuild_lib60_x86.bat new file mode 100644 index 0000000000..9da306d99f --- /dev/null +++ b/scripts/rebuild_lib60_x86.bat @@ -0,0 +1,116 @@ +REM NOTE : the script MUST be called from the root folder + +bin\asm-cli -x86 asm\x32\core60.asm bin\x32 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm-cli -x86 asm\x32\corex60.asm bin\x32 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm-cli -x86 asm\x32\core60_win.asm bin\x32 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm-cli -x86 asm\x32\corex60_win.asm bin\x32 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm-cli -x86 asm\x32\core60_win_client.asm bin\x32 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm-cli -bc32 src60\core\system.core_routines.esm lib60 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\asm-cli -bc32 src60\core\system.win_core_routines.esm lib60 +@echo off +if %ERRORLEVEL% EQU -1 GOTO Asm2BinError +@echo on + +bin\elena-cli src60\elena_api.prjcol +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +bin\ldoc system doc\api +bin\ldoc system'collections'threadsafe doc\api +bin\ldoc system'routines doc\api +bin\ldoc system'runtime doc\api +bin\ldoc system'threading doc\api +bin\ldoc system'dynamic doc\api +bin\ldoc system'drawing doc\api +bin\ldoc system'winforms doc\api +bin\ldoc system'net doc\api +bin\ldoc extensions doc\api +bin\ldoc extensions'routines doc\api +bin\ldoc extensions'scripting doc\api +bin\ldoc extensions'dynamic doc\api +bin\ldoc extensions'io doc\api +bin\ldoc cellular doc\api +bin\ldoc algorithms doc\api +bin\ldoc sqlite doc\api +bin\ldoc forms doc\api +bin\ldoc ltests doc\api +bin\ldoc net doc\api + +bin\elena-cli tests60\system_tests\system_tests.prj +@echo off +if %ERRORLEVEL% EQU -2 GOTO CompilerError +@echo on + +echo system api test for x86 +copy bin\elenart60.dll tests60\system_tests\ +copy bin\elenasm60.dll tests60\system_tests\ + +tests60\system_tests\system_tests.exe +@echo off +if %ERRORLEVEL% NEQ 0 GOTO TestError +@echo on + +REM bin\elena-cli tests60\script_tests\script_tests.prj +REM @echo off +REM if %ERRORLEVEL% EQU -2 GOTO CompilerError +REM @echo on + +REM echo system api test for x86 +REM copy bin\elenart60.dll tests60\script_tests\ +REM copy bin\elenasm60.dll tests60\script_tests\ + +REM tests60\script_tests\script_tests.exe +REM @echo off +REM if %ERRORLEVEL% NEQ 0 GOTO TestError +REM @echo on + +@echo off +echo === Done === +@echo on + +@echo off +goto:eof +@echo on + +:Asm2BinError +echo ASM2BINX returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:CompilerError +echo ELC returns error %ERRORLEVEL% +@echo off +goto:eof +@echo on + +:TestError +echo System tests fail %ERRORLEVEL% +@echo off +goto:eof +@echo on \ No newline at end of file diff --git a/src60/algorithms/algorithms.linux.prj b/src60/algorithms/algorithms.linux.prj new file mode 100644 index 0000000000..aa017dc878 --- /dev/null +++ b/src60/algorithms/algorithms.linux.prj @@ -0,0 +1,37 @@ + + + + ../../lib60 + + + + + ../../lib60_64 + + + + + ../../lib60_64 + + + + + ../../lib60_64 + + + + algorithms + + + + ELENA Algorithms Library + 6.5.0 + Aleksey Rakov + + + + quicksort.l + sort_extensions.l + + + \ No newline at end of file diff --git a/src60/cellular/cellular.linux.prj b/src60/cellular/cellular.linux.prj new file mode 100644 index 0000000000..10c63dfbdc --- /dev/null +++ b/src60/cellular/cellular.linux.prj @@ -0,0 +1,37 @@ + + + + ../../lib60 + + + + + ../../lib60_64 + + + + + ../../lib60_64 + + + + + ../../lib60_64 + + + + cellular + + + + ELENA Cellular Library + 6.5.0 + Aleksey Rakov + + + + universe.l + rulesets.l + + + diff --git a/src60/core/system.core_routines.esm b/src60/core/system.core_routines.esm index b2dcfe48e9..b9f7d5ad74 100644 --- a/src60/core/system.core_routines.esm +++ b/src60/core/system.core_routines.esm @@ -1946,8 +1946,8 @@ labUnboxing: free i:1 load dp:mssg - and n:0FFFFFFE0h - or n:082h + and n:0FFFFFF80h + or n:062h peek fp:target xrefresh sp:0 diff --git a/src60/elena_api.linux.prjcol b/src60/elena_api.linux.prjcol index 7a185cdea8..73fee2d46c 100644 --- a/src60/elena_api.linux.prjcol +++ b/src60/elena_api.linux.prjcol @@ -3,5 +3,7 @@ system/system.linux.prj extensions/extensions.linux.prj ltests/ltests.linux.prj + algorithms/algorithms.linux.prj + cellular/cellular.linux.prj \ No newline at end of file diff --git a/src60/elena_api.prjcol b/src60/elena_api.prjcol index 0f81d9abee..c7ffe3e24b 100644 --- a/src60/elena_api.prjcol +++ b/src60/elena_api.prjcol @@ -9,5 +9,6 @@ forms\forms.prj xforms\xforms.prj net\net.prj + mbedtls\mbedtls.prj \ No newline at end of file diff --git a/src60/extensions/extensions.linux.prj b/src60/extensions/extensions.linux.prj index 5987b8586b..cc13572986 100644 --- a/src60/extensions/extensions.linux.prj +++ b/src60/extensions/extensions.linux.prj @@ -1,22 +1,22 @@ - /usr/lib/elena/lib60 + ../../lib60 - /usr/lib/elena/lib60_64 + ../../lib60_64 - /usr/lib/elena/lib60_64 + ../../lib60_64 - /usr/lib/elena/lib60_64 + ../../lib60_64 diff --git a/src60/forms/win32_controls.l b/src60/forms/win32_controls.l index abdb73616b..10e84d56b9 100644 --- a/src60/forms/win32_controls.l +++ b/src60/forms/win32_controls.l @@ -136,7 +136,7 @@ public abstract class BaseWinControl : BaseControl { ^ nil }; if(_handle == handle) - { ^ weak self as::IControl }; + { ^ weak self as:IControl }; ^ nil } diff --git a/src60/forms/win_forms.l b/src60/forms/win_forms.l index d6c60319fc..75b886a7ca 100644 --- a/src60/forms/win_forms.l +++ b/src60/forms/win_forms.l @@ -16,7 +16,7 @@ public abstract class BaseWinForm : BaseWinContainer { control.Parent := self; - _controls.append(weak control as::IControl) + _controls.append(weak control as:IControl) } close() diff --git a/src60/ltests/ltests.linux.prj b/src60/ltests/ltests.linux.prj index b397ea42e2..77249b1a04 100644 --- a/src60/ltests/ltests.linux.prj +++ b/src60/ltests/ltests.linux.prj @@ -1,22 +1,22 @@ - /usr/lib/elena/lib60 + ../../lib60 - /usr/lib/elena/lib60_64 + ../../lib60_64 - /usr/lib/elena/lib60_64 + ../../lib60_64 - /usr/lib/elena/lib60_64 + ../../lib60_64 diff --git a/src60/mbedtls/common.l b/src60/mbedtls/common.l new file mode 100644 index 0000000000..7294c466b4 --- /dev/null +++ b/src60/mbedtls/common.l @@ -0,0 +1,230 @@ +/* ********************************************************************* +ELENA Project : MbedTls based SSL Socket + +NOTE : the prject requires wrpmbedtls.dll + +It can be downloaded from https://github.com/ELENA-LANG/mbedtls-as-dll + +********************************************************************* */ + +const string DRBG_PERSONALIZED_STR = "ELENA API6 client"; + +const int MBEDTLS_NET_PROTO_TCP = 0; + +const int MBEDTLS_SSL_IS_CLIENT = 0; +const int MBEDTLS_SSL_TRANSPORT_STREAM = 0; +const int MBEDTLS_SSL_PRESET_DEFAULT = 0; +const int MBEDTLS_SSL_VERIFY_NONE = 0; + +const int MBEDTLS_ERR_SSL_WANT_READ = -26880; +const int MBEDTLS_ERR_SSL_WANT_WRITE = -26752; + +struct mbedtls_aes_context +{ + int nr; + pointer rk_offset; // size_t + int buf[68]; +} + +struct mbedtls_ctr_drbg_context +{ + byte counter[16]; + int reseed_counter; + int prediction_resistance; + pointer entropy_len; // size_t + int reseed_interval; + mbedtls_aes_context aes_ctx; + pointer f_entropy; + pointer p_entropy; + +} + +struct mbedtls_mpi +{ + pointer p; + short s; + short n; +} + +struct mbedtls_ssl_config +{ + int max_tls_version; + int min_tls_version; + byte endpoint; + byte transport; + byte authmode; + byte allow_legacy_renegotiation; + byte mfl_code; + byte encrypt_then_mac; + byte extended_ms; + byte anti_replay; + byte disable_renegotiation; + byte session_tickets; + byte cert_req_ca_list; + byte respect_cli_pref; + byte ignore_unexpected_cid; + pointer ciphersuite_list; + pointer f_dbg; + pointer p_dbg; + pointer f_rng; + pointer p_rng; + pointer f_get_cache; + pointer f_set_cache; + pointer p_cache; + pointer f_sni; + pointer p_sni; + pointer f_vrfy; + pointer p_vrfy; + pointer f_psk; + pointer p_psk; + pointer f_cookie_write; + pointer f_cookie_check; + pointer p_cookie; + pointer f_ticket_write; + pointer f_ticket_parse; + pointer p_ticket; + pointer cid_len; // size_t + pointer cert_profile; + pointer key_cert; + pointer ca_chain; + pointer ca_crl; + pointer sig_hashes; + pointer sig_algs; + pointer curve_list; + pointer group_list; + mbedtls_mpi dhm_P; + mbedtls_mpi dhm_G; + pointer psk; + pointer psk_len; // size_t + pointer psk_identity; + pointer psk_identity_len; // size_t + pointer alpn_list; + int read_timeout; + int hs_timeout_min; + int hs_timeout_max; + int renego_max_records; + byte renego_period[8]; + int badmac_limit; + int dhm_min_bitlen; + pointer user_data; + pointer f_cert_cb; + pointer dn_hints; +} + +struct mbedtls_ssl_context +{ + pointer conf; + int state; + int renego_status; + int renego_records_seen; + int tls_version; + int badmac_seen; + pointer f_vrfy; + pointer p_vrfy; + pointer f_send; + pointer f_recv; + pointer f_recv_timeout; + pointer p_bio; + pointer session_in; + pointer session_out; + pointer session; + pointer session_negotiate; + pointer handshake; + pointer transform_in; + pointer transform_out; + pointer transform; + pointer transform_negotiate; + pointer p_timer; + pointer f_set_timer; + pointer f_get_timer; + pointer in_buf; + pointer in_ctr; + pointer in_hdr; + pointer in_cid; + pointer in_len; + pointer in_iv; + pointer in_msg; + pointer in_offt; + int in_msgtype; + pointer in_msglen; // size_t + pointer in_left; // size_t + short in_epoch; + pointer next_record_offset; // size_t + long in_window_top; + long in_window; + pointer in_hslen; // size_t + int nb_zero; + int keep_current_message; + byte send_alert; + byte alert_type; + int alert_reason; + byte disable_datagram_packing; + + pointer out_buf; + pointer out_ctr; + pointer out_hdr; + pointer out_cid; + pointer out_len; + pointer out_iv; + pointer out_msg; + + int out_msgtype; + pointer out_msglen; // size_t + pointer out_left; // size_t + + byte cur_out_ctr[8]; + short mtu; + pointer hostname; + pointer alpn_chosen; + pointer cli_id; + pointer cli_id_len; // size_t + int secure_renegotiation; + pointer verify_data_len; // size_t + byte own_verify_data[12]; + byte peer_verify_data[12]; + byte own_cid[32]; + byte own_cid_len; + byte negotiate_cid; + pointer f_export_keys; + pointer p_export_keys; + pointer user_data; + + int struct_padding; // !! to align the struct size with required +} + +struct mbedtls_net_context +{ + int fd; +} + +struct mbedtls_entropy_source_state +{ + pointer f_source; + pointer p_source; + pointer size; // !! must be size_t + pointer threshold; // !! must be size_t + int strong; +} + +struct mbedtls_md_context_t +{ + pointer md_info; // mbedtls_md_info_t* + pointer md_ctx; + pointer hmac_ctx; +} + +struct mbedtls_entropy_context +{ + mbedtls_md_context_t accumulator; + int accumulator_started; + int source_count; + mbedtls_entropy_source_state source[20]; +} + +//--- MbedTlsException --- + +public class MbedTlsException : Exception +{ + constructor new(string s) + <= super new(s); +} \ No newline at end of file diff --git a/src60/mbedtls/mbedtls.prj b/src60/mbedtls/mbedtls.prj new file mode 100644 index 0000000000..c5e385c9a4 --- /dev/null +++ b/src60/mbedtls/mbedtls.prj @@ -0,0 +1,23 @@ + + + + ..\..\lib60 + + + + mbedtls + + + + ELENA SSL Socket based on MbedTls routines + 6.6.0 + Aleksey Rakov + + + + common.l + mbedtlssocket.l + registration\registration.l + + + \ No newline at end of file diff --git a/src60/mbedtls/mbedtlssocket.l b/src60/mbedtls/mbedtlssocket.l new file mode 100644 index 0000000000..29fda497aa --- /dev/null +++ b/src60/mbedtls/mbedtlssocket.l @@ -0,0 +1,146 @@ +/* ********************************************************************* +ELENA Project : MbedTls based SSL Socket + +NOTE : the prject requires wrpmbedtls.dll (>= 1.1) + +It can be downloaded from https://github.com/ELENA-LANG/mbedtls-as-dll + +********************************************************************* */ + +import system'net; + +public class MbedTlsSocket : INetSocket +{ + pointer _context; + + private prepare(string host, string port) + { + _context := extern wrpmbedtls.new_context(); + + extern wrpmbedtls.init_context(_context); + // mbedtls_x509_crt_init(&cacert); + + int ret := 0; + + string pers := DRBG_PERSONALIZED_STR; + ret := extern wrpmbedtls.context_drbg_seed_def(_context, DRBG_PERSONALIZED_STR, DRBG_PERSONALIZED_STR.Length + 1); + if (ret != 0) + { + Exception.raise($"Failed. mbedtls_ctr_drbg_seed returned {ret}"); + }; + + ret := extern wrpmbedtls.context_net_connect(_context, host, port, MBEDTLS_NET_PROTO_TCP); + if (ret != 0) + { + Exception.raise($"Failed. mbedtls_net_connect returned {ret}"); + }; + + ret := extern wrpmbedtls.context_ssl_config_defaults(_context, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + if (ret != 0) + { + Exception.raise($"Failed. mbedtls_ssl_config_defaults returned {ret}"); + }; + + ret := extern wrpmbedtls.context_setup(_context, MBEDTLS_SSL_VERIFY_NONE); + if (ret != 0) + { + Exception.raise($"Failed. mbedtls_ssl_setup returned {ret}"); + }; + + ret := extern wrpmbedtls.context_ssl_set_hostname(_context, host); + if (ret != 0) + { + Exception.raise($"Failed. mbedtls_ssl_set_hostname returned {ret}"); + }; + + extern wrpmbedtls.context_ssl_set_bio_def(_context); + } + + constructor open(string host, short port) + { + prepare(host, port.toPrintable()); + } + + int read(byte[] buffer, int length) + { + int retVal := 0; + + while (true) { + extern { + retVal := extern wrpmbedtls.context_read(_context, + buffer, length); + }; + + if (retVal < 0) { + if (retVal == MBEDTLS_ERR_SSL_WANT_WRITE || retVal == MBEDTLS_ERR_SSL_WANT_READ) { + retVal := 0; + } + else MbedTlsException.raise($"Failed. mbedtls_ssl_write returned {retVal}"); + } + else :break; + }; + + ^ retVal + } + + int write(byte[] buffer, int length) + { + int retVal := 0; + while (true) { + retVal := extern wrpmbedtls.context_write(_context, buffer, length); + + if (retVal < 0) { + if (retVal == MBEDTLS_ERR_SSL_WANT_WRITE || retVal == MBEDTLS_ERR_SSL_WANT_READ) { + retVal := 0; + } + else MbedTlsException.raise($"Failed. mbedtls_ssl_write returned {retVal}"); + } + else :break; + }; + + ^ retVal + } + + verify() + { +// byte gp_buf[1024]; +// ret := extern wrpmbedtls.x509_crt_info(gp_buf, 1024, +// ""$10" ", extern wrpmbedtls.ssl_get_peer_cert(ssl)); +// if (ret < 0) { +// Exception.raise($"Failed. mbedtls_x509_crt_info returned {ret}"); +// }; +// //mbedtls_printf("Server certificate:\n%s\n", gp_buf); +// +// // Ensure certificate verification was successful +// int flags := extern wrpmbedtls.ssl_get_verify_result(ssl); +// if (flags != 0) { +// ret := extern wrpmbedtls.x509_crt_verify_info(gp_buf, 1024, +// ""$10" ! ", flags); +// if (ret < 0) { +// Exception.raise($"Failed. mbedtls_x509_crt_verify_info returned {ret}"); +// } +// else { +// Exception.raise("Certificate verification failed"); +// } +// } ; +//// else { +// //mbedtls_printf("Certificate verification passed\n"); +//// } + } + + get bool AvailableToRead() + { + // currently it is not supported + NotSupportedException.raise(); + + ^ false + } + + close() + { + extern wrpmbedtls.free_context(_context); + extern wrpmbedtls.delete_context(_context); + + _context := default; + } +} \ No newline at end of file diff --git a/src60/mbedtls/registration/registration.l b/src60/mbedtls/registration/registration.l new file mode 100644 index 0000000000..f79ed10eb2 --- /dev/null +++ b/src60/mbedtls/registration/registration.l @@ -0,0 +1,23 @@ +import system'net; +import net'http; + +namespace registration +{ + internal class MbedTlsSocketFactory : INetSocketFactory + { + internal static register() + { + SocketFactory.assignHttpsFactory(MbedTlsSocketFactory.create()); + } + + constructor create() + { + } + + INetSocket openSocket(string host, short port) + = MbedTlsSocket.open(host, port); + } +} + +static Registration : preloaded = registration'MbedTlsSocketFactory.register(); + diff --git a/src60/net/http/common.l b/src60/net/http/common.l index 75c82c8b13..ddfcde0228 100644 --- a/src60/net/http/common.l +++ b/src60/net/http/common.l @@ -72,7 +72,6 @@ public sealed class Uri } else { _host := url.Substring(index, end - index); - _port := "80" }; index := end + 1; diff --git a/src60/net/http/httpclient.l b/src60/net/http/httpclient.l index d78ddaa2ec..e6124c72f3 100644 --- a/src60/net/http/httpclient.l +++ b/src60/net/http/httpclient.l @@ -1,42 +1,128 @@ import system'net; import system'threading; +public class SocketFactory +{ + static object _sync := new object(); + + static INetSocketFactory _httpFactory; + static INetSocketFactory _httpsFactory; + + static constructor() + { + _httpFactory := NativeSocketFactory.create(); + } + + static assignHttpsFactory(INetSocketFactory factory) + { + lock(_sync) { + _httpsFactory := factory; + } + } + + static assignHttpFactory(INetSocketFactory factory) + { + lock(_sync) { + _httpFactory := factory; + } + } + + static INetSocket openSocket(Uri uri) + { + INetSocket socket := nil; + string scheme := uri.Scheme; + short port := uri.Port; + scheme => + "http" : + { + if (port==0) + port := 80; + + lock(_sync) { + socket := _httpFactory.openSocket(uri.Host, port); + } + } + "https" : + { + if (port==0) + port := 443; + + lock(_sync) { + socket := _httpsFactory.openSocket(uri.Host, port); + } + } + ! : { + InvalidArgumentException.raise("uri"); + }; + + ^ socket + } +} + public class HttpClient { + string _host; HttpHeaders _headers; - Socket _socket; + INetSocket _socket; + + static Task openAsync(Uri uri) + = ::Task.run({ ^ HttpClient.assign(SocketFactory.openSocket(uri), uri.Host); }); + + static Task openAsync(string url) + = HttpClient.openAsync(Uri.parse(url)); - constructor() + static open(Uri uri) + = HttpClient.assign(SocketFactory.openSocket(uri), uri.Host); + + static open(string url) + = HttpClient.open(Uri.parse(url)); + + internal constructor assign(INetSocket socket, string host) { + _socket := socket; + _host := host; _headers := new HttpHeaders(); } HttpHeaders Headers = _headers; - Task getAsync(string url) - = getAsync(Uri.parse(url)); - - private Task openAsync(Uri uri) - = ::Task.run({ ^ Socket.connect(uri.Host, uri.Port) }); + Task getAsync() + <= getAsync("/"); - async Task getAsync(Uri uri) + async Task getAsync(string path) { - /* Connect */ - _socket := :await openAsync(uri); - /* Send headers to server */ NetworkStream stream := new NetworkStream(_socket); - string host := uri.Host; string headers := _headers.Value; - string request := $"GET / HTTP/1.1"$13$10"Host:{host}"$13$10"Connection:close"$13$10"{headers}"$13$10; + string request := $"GET {path} HTTP/1.1"$13$10"Host:{_host}"$13$10"Connection:close"$13$10"{headers}"$13$10; :await stream.writeAsync(request); HttpResponse response := HttpResponse.assign(stream); - :await response.readHeader(); + :await response.readHeaderAsync(); + + ^ response; + } + + HttpResponse get() + <= get("/"); + + HttpResponse get(string path) + { + /* Send headers to server */ + NetworkStream stream := new NetworkStream(_socket); + + string headers := _headers.Value; + string request := $"GET {path} HTTP/1.1"$13$10"Host:{_host}"$13$10"Connection:close"$13$10"{headers}"$13$10; + + stream.write(request); + + HttpResponse response := HttpResponse.assign(stream); + + response.readHeader(); ^ response; } diff --git a/src60/net/http/httpresponse.l b/src60/net/http/httpresponse.l index 4506910359..11ccb2eb51 100644 --- a/src60/net/http/httpresponse.l +++ b/src60/net/http/httpresponse.l @@ -79,18 +79,8 @@ public class HttpResponse _headers := new HttpHeaders(); } - async internal Task readHeader() + private parseHeaders(int eoh) { - int eoh := 0; - int received := :await _stream.readAsync(_buffer, 512); - while (received > 0) { - eoh := seekHeaderEnd(); - if (eoh > 0) - :break; - - received := :await _stream.readAsync(_buffer, 512); - }; - byte[] buffer := _buffer.Content; int length := _buffer.Length; @@ -124,13 +114,38 @@ public class HttpResponse } } - async Task readAsStringAsync() + async internal Task readHeaderAsync() { + int eoh := 0; int received := :await _stream.readAsync(_buffer, 512); while (received > 0) { + eoh := seekHeaderEnd(); + if (eoh > 0) + :break; + received := :await _stream.readAsync(_buffer, 512); }; + parseHeaders(eoh) + } + + internal readHeader() + { + int eoh := 0; + int received := _stream.readToBuffer(_buffer, 512); + while (received > 0) { + eoh := seekHeaderEnd(); + if (eoh > 0) + :break; + + received := _stream.readToBuffer(_buffer, 512); + }; + + parseHeaders(eoh) + } + + private string returnContentAsString() + { byte[] buffer := _buffer.Content; int length := _buffer.Length; int eoh := seekHeaderEnd(); @@ -157,7 +172,26 @@ public class HttpResponse } else { ^ UTF8Encoding.toString(eoh, length - eoh, _buffer.Content); - } - + } + } + + async Task readAsStringAsync() + { + int received := :await _stream.readAsync(_buffer, 512); + while (received > 0) { + received := :await _stream.readAsync(_buffer, 512); + }; + + ^ returnContentAsString(); + } + + string readAsString() + { + int received := _stream.readToBuffer(_buffer, 512); + while (received > 0) { + received := _stream.readToBuffer(_buffer, 512); + }; + + ^ returnContentAsString(); } } \ No newline at end of file diff --git a/src60/net/net.prj b/src60/net/net.prj index 62bed2577b..60fc71ddc5 100644 --- a/src60/net/net.prj +++ b/src60/net/net.prj @@ -15,7 +15,7 @@ ELENA Network Provider Library - 6.6.0 + 6.6.2 Aleksey Rakov diff --git a/src60/net/server/win32_server.l b/src60/net/server/win32_server.l index 9cb57cc69d..f7c8dd887c 100644 --- a/src60/net/server/win32_server.l +++ b/src60/net/server/win32_server.l @@ -66,18 +66,18 @@ public sealed class EventBasedTcpServer private readClients() { - int counter := _clients.Length; - for (int i := 0; i < counter; i += 1) { - TcpClient client := _clients[i]; - - NetworkStream stream := client.stream(); - if (stream.isDataAvailable) { - byte buffer[BUFFER_SIZE]; - int bytesRead := stream.read(buffer, BUFFER_SIZE); - - OnReceived?.(client,buffer,bytesRead) - } - } +// int counter := _clients.Length; +// for (int i := 0; i < counter; i += 1) { +// TcpClient client := _clients[i]; +// +// NetworkStream stream := client.stream(); +// if (stream.isDataAvailable) { +// byte buffer[BUFFER_SIZE]; +// int bytesRead := stream.read(buffer, BUFFER_SIZE); +// +// OnReceived?.(client,buffer,bytesRead) +// } +// } } private proceed() @@ -102,15 +102,15 @@ public sealed class EventBasedTcpServer broadcast(byte[] buffer, int length) { - int counter := _clients.Length; - - for(int i := 0; i < counter; i += 1) - { - TcpClient client := _clients[i]; - auto stream := client.stream(); - - stream.write(buffer, length) - } +// int counter := _clients.Length; +// +// for(int i := 0; i < counter; i += 1) +// { +// TcpClient client := _clients[i]; +// auto stream := client.stream(); +// +// stream.write(buffer, length) +// } } close() diff --git a/src60/net/win32_client.l b/src60/net/win32_client.l index 69a72c30b1..8c35db2781 100644 --- a/src60/net/win32_client.l +++ b/src60/net/win32_client.l @@ -7,14 +7,14 @@ import extensions; public sealed class TcpClient { - Socket _socket; + NativeSocket _socket; NetworkStream _stream; constructor() { } - internal constructor new(Socket socket) + internal constructor new(NativeSocket socket) { _socket := socket } @@ -40,7 +40,7 @@ public sealed class TcpClient int ai_addrlen := addrinfo.ai_addrlen; pointer ai_addrptr := addrinfo.ai_addr; - _socket := new Socket(ai_family, ai_socktype, ai_protocol); + _socket := new NativeSocket(ai_family, ai_socktype, ai_protocol); if (_socket.tryOpen(ai_addrptr, ai_addrlen)) { @@ -84,8 +84,8 @@ public sealed class TcpClient { closeInternal() } } - NetworkStream stream() - = _stream ?? _stream := NetworkStream.assign(_socket, true); +// NetworkStream stream() +// = _stream ?? _stream := NetworkStream.assign(_socket, true); } //public sealed class TcpClient diff --git a/src60/net/win32_listener.l b/src60/net/win32_listener.l index b47f21cef7..c450cb1925 100644 --- a/src60/net/win32_listener.l +++ b/src60/net/win32_listener.l @@ -4,7 +4,7 @@ import system'threading; public class TcpListener { - Socket _listenSocket; + NativeSocket _listenSocket; bool _noDelayMode; constructor new(int port) @@ -32,7 +32,7 @@ public class TcpListener int ai_addrlen := addrinfo.ai_addrlen; pointer ai_addrptr := addrinfo.ai_addr; - _listenSocket := new Socket(ai_family, ai_socktype, ai_protocol); + _listenSocket := new NativeSocket(ai_family, ai_socktype, ai_protocol); _listenSocket.bind(ai_addrptr, ai_addrlen); @@ -48,9 +48,9 @@ public class TcpListener _listenSocket.close() } - Socket acceptSocket() + NativeSocket acceptSocket() { - Socket socket := _listenSocket.accept(); + NativeSocket socket := _listenSocket.accept(); if:not(socket.isInvalid) { if (_noDelayMode) @@ -60,12 +60,12 @@ public class TcpListener ^ socket } - private Task listenAsync() - = ::Task.run({ ^ _listenSocket.accept(); }); + private Task listenAsync() + = ::Task.run({ ^ _listenSocket.accept(); }); - async Task acceptSocketAsync() + async Task acceptSocketAsync() { - Socket socket := :await listenAsync(); + NativeSocket socket := :await listenAsync(); if:not(socket.isInvalid) { if (_noDelayMode) @@ -77,7 +77,7 @@ public class TcpListener TcpClient acceptTcpClient() { - Socket socket := _listenSocket.accept(); + NativeSocket socket := _listenSocket.accept(); if:not(socket.isInvalid) { if (_noDelayMode) @@ -89,7 +89,7 @@ public class TcpListener async Task acceptTcpClientAsync() { - Socket socket := :await listenAsync(); + NativeSocket socket := :await listenAsync(); if:not(socket.isInvalid) { if (_noDelayMode) diff --git a/src60/system/io/lnx_files.l b/src60/system/io/lnx_files.l index 9687cfe8a7..805d715e9b 100644 --- a/src60/system/io/lnx_files.l +++ b/src60/system/io/lnx_files.l @@ -113,7 +113,7 @@ namespace io bool isAvailable(path) { - int ret := extern libc.access(path as::String, F_OK); + int ret := extern libc.access(path as:String, F_OK); ^ ret == 0 } diff --git a/src60/system/net/netsocket.l b/src60/system/net/netsocket.l new file mode 100644 index 0000000000..81cd797e6f --- /dev/null +++ b/src60/system/net/netsocket.l @@ -0,0 +1,67 @@ +import system'threading; + +public interface INetSocket +{ + Task readAsync(byte[] buffer, int length) + = ::Task.run({ ^ self.read(buffer, length) }); + + Task writeAsync(byte[] buffer, int length) + = ::Task.run({ ^ self.write(buffer, length) }); + + abstract int read(byte[] buffer, int length); + + abstract int write(byte[] buffer, int length); + + get abstract bool AvailableToRead(); + + verify() {} + + abstract close(); +} + +public interface INetSocketFactory +{ + abstract INetSocket openSocket(string host, short port); + + Task openSocketAsync(string host, short port) + = ::Task.run({ ^ self.openSocket(host, port); }); +} + +public class NetSocket : INetSocket +{ + NativeSocket _socket; + + internal constructor assign(NativeSocket socket) + { + _socket := socket + } + + int read(byte[] buffer, int length) + = _socket.receive(buffer, length, 0); + + int write(byte[] buffer, int length) + = _socket.send(buffer, length, 0); + + Task readAsync(byte[] buffer, int length) + = ::Task.run({ ^ self.read(buffer, length) }); + + Task writeAsync(byte[] buffer, int length) + = ::Task.run({ ^ self.write(buffer, length) }); + + get bool AvailableToRead + = _socket.available() != 0; + + close() + => _socket; +} + +public class NativeSocketFactory : INetSocketFactory +{ + constructor create() + { + } + + INetSocket openSocket(string host, short port) + = NetSocket.assign(NativeSocket.connect(host, port)); +} + diff --git a/src60/system/net/networkstream.l b/src60/system/net/networkstream.l index e70a9fd0f4..de8680e5bc 100644 --- a/src60/system/net/networkstream.l +++ b/src60/system/net/networkstream.l @@ -5,18 +5,18 @@ import system'threading; public class NetworkStream : Stream { - Socket _socket; - bool _ownStream; - byte[] _buffer; + INetSocket _socket; + bool _ownStream; + byte[] _buffer; - constructor(Socket socket) + constructor(INetSocket socket) { _socket := socket; _ownStream := false; _buffer := new byte[](512); } - constructor assign(Socket socket, bool socketStream) + constructor assign(INetSocket socket, bool socketStream) { _socket := socket; _ownStream := socketStream; @@ -48,23 +48,23 @@ public class NetworkStream : Stream } int read(byte[] dump, int length) - = _socket.receive(dump, length, 0); + = _socket.read(dump, length); int write(byte[] dump, int length) { - int retVal := _socket.send(dump, length, 0); + int retVal := _socket.write(dump, length); ^ retVal } indexed internal Task readAsync(byte[] dump, int length) - = ::Task.run({ ^ _socket.receive(dump, length, 0) }); + = _socket.readAsync(dump, length); indexed internal Task writeAsync(byte[] dump, int length) - = ::Task.run({ ^ _socket.send(dump, length, 0) }); + = _socket.writeAsync(dump, length); indexed internal bool isDataAvailable - = _socket.available() != 0; + = _socket.AvailableToRead; indexed async internal Task readAsync(MemoryBuffer buffer, int length) { @@ -88,6 +88,28 @@ public class NetworkStream : Stream ^ total_received; } + indexed internal int readToBuffer(MemoryBuffer buffer, int length) + { + int total_received := 0; + int total := length; + while (total > 0) { + int size := 512; + if (size > length) + size := length; + + int received := read(_buffer, size); + if (received > 0) { + total_received += received; + total -= received; + + buffer.write(0, received, _buffer); + } + else :break; + }; + + ^ total_received; + } + indexed async internal Task writeAsync(string s) { byte tmp[1024]; @@ -108,6 +130,26 @@ public class NetworkStream : Stream }; } + indexed internal writeString(string s) + { + byte tmp[1024]; + int len := s.Length; + int index := 0; + while (len > 0) { + int sublen := 1024; + if (len < sublen) { + sublen := len; + }; + + int converted := UTF8Encoder.toByteArray(s, index, ref sublen, tmp, 0, 1024); + + converted := self.write(tmp, converted); + + index += converted; + len -= converted; + }; + } + indexed async internal Task readAsStringAsync() { MemoryBuffer buffer := MemoryBuffer.allocate(); @@ -144,46 +186,17 @@ public extension AsyncStreamExtension : NetworkStream Task writeAsync(string s) = self.writeAsync(s); + write(string s) + = self.writeString(s); + Task readAsStringAsync() = self.readAsStringAsync(); Task readAsync(MemoryBuffer buffer, int length) = self.readAsync(buffer, length); -// async Task writeAsync(string s) -// { -// byte tmp[1024]; -// int len := s.Length; -// int index := 0; -// while (len > 0) { -// int sublen := 1024; -// if (len < sublen) { -// sublen := len; -// }; -// -// int converted := UTF8Encoder.toByteArray(s, index, ref sublen, tmp, 0, 1024); -// -// converted := :await self.writeAsync(tmp, converted); -// -// index += converted; -// len -= converted; -// }; -// } - -// async Task readAsStringAsync() -// { -// MemoryBuffer buffer := MemoryBuffer.allocate(); -// -// byte tmp[1024]; -// int read := :await self.readAsync(tmp, 1024); -// while (read > 0) { -// buffer.write(0, read, tmp); -// -// read := :await self.readAsync(tmp, 1024); -// }; -// -// ^ UTF8Encoding.toString(0, buffer.Length, buffer.Value); -// } + int readToBuffer(MemoryBuffer buffer, int length) + = self.readToBuffer(buffer, length); bool isDataAvailable = self.isDataAvailable; diff --git a/src60/system/net/win_sockets.l b/src60/system/net/win_sockets.l index 798cb026f4..59f64dd3bb 100644 --- a/src60/system/net/win_sockets.l +++ b/src60/system/net/win_sockets.l @@ -207,13 +207,13 @@ public const struct SelectMode : enum(SelectRead ::= 1, SelectWrite ::= 2, // --- Socket --- -public sealed const struct Socket +public sealed const struct NativeSocket { handle _handle; - static Socket connect(string host, short port) + static NativeSocket connect(string host, short port) { - Socket socket := default; + NativeSocket socket := default; //resolve server address and port AddrInfo addrinfo := default; @@ -234,7 +234,7 @@ public sealed const struct Socket int ai_addrlen := addrinfo.ai_addrlen; pointer ai_addrptr := addrinfo.ai_addr; - socket := new Socket(ai_family, ai_socktype, ai_protocol); + socket := new NativeSocket(ai_family, ai_socktype, ai_protocol); if (socket.tryOpen(ai_addrptr, ai_addrlen)) { @@ -350,7 +350,7 @@ public sealed const struct Socket ^ retVal } - Socket accept() + NativeSocket accept() { handle socket := extern WS2_32.accept(_handle, 0, 0); diff --git a/src60/system/operations/advanced/operations.l b/src60/system/operations/advanced/operations.l index cb242ef74b..4d5ab9c6c1 100644 --- a/src60/system/operations/advanced/operations.l +++ b/src60/system/operations/advanced/operations.l @@ -35,7 +35,13 @@ public template if::is(truePart) : __included(statements) public template as(expr) : __included(statements) = cast T(expr); +public template operator::as(expr, T) : __included(statements) + = cast T(expr); + // --- expr is: T --- public template is(expr) : __included(statements) = expr.instanceOf(T); + +public template operator::is(expr, T) : __included(statements) + = expr.instanceOf(T); diff --git a/src60/system/pointers.l b/src60/system/pointers.l index 686d624827..fb123d0c79 100644 --- a/src60/system/pointers.l +++ b/src60/system/pointers.l @@ -58,7 +58,7 @@ public sealed const struct UnsafePointer constructor(object obj) { - if (obj is::pointer) { + if (obj is:pointer) { _pointer := cast UnsafePointer(weak obj) } else self.assignPtr(obj); diff --git a/src60/system/system.linux.prj b/src60/system/system.linux.prj index 621b735eeb..7a0409c9cd 100644 --- a/src60/system/system.linux.prj +++ b/src60/system/system.linux.prj @@ -50,7 +50,7 @@ ELENA Standard Library - 6.6.1 + 6.6.2 Aleksey Rakov diff --git a/src60/system/system.prj b/src60/system/system.prj index 1f855d765c..9e64a83957 100644 --- a/src60/system/system.prj +++ b/src60/system/system.prj @@ -18,7 +18,7 @@ ELENA Standard Library - 6.6.1 + 6.6.3 Aleksey Rakov @@ -143,6 +143,7 @@ net\win_common.l net\win_sockets.l + net\netsocket.l net\networkstream.l diff --git a/src60/system/text/textbuffer.l b/src60/system/text/textbuffer.l index 3ae5675207..0a1394739d 100644 --- a/src60/system/text/textbuffer.l +++ b/src60/system/text/textbuffer.l @@ -544,7 +544,7 @@ namespace text } insert(index, o) - <= insert(index as::IntNumber, o.toPrintable()); + <= insert(index as:IntNumber, o.toPrintable()); delete(int index, int length) { diff --git a/tests60/sandbox/sandbox.l b/tests60/sandbox/sandbox.l index 77b77b1341..19d431ca04 100644 --- a/tests60/sandbox/sandbox.l +++ b/tests60/sandbox/sandbox.l @@ -1,14 +1,14 @@ import extensions; - +import extensions'scripting; + public program() { - int i := 1; - - real a := -1.0/*.power(i)*/; - - //Console.printLine(a); - //Console.printLine(b); - //Console.printLine(c); - //Console.printLine(d); - Console.printLine(a / (i*2/*+1*/) /** 4*/); -} \ No newline at end of file + var t := new ScriptEngine() + .loadScript("[[ #grammar build ]]") + .loadPath("~\scripts\grammar60.es") + .loadPath("~\scripts\lscript60.es"); + + var o := t.buildScript("import extensions; public program() { console.printLine(""Hello World"") }"); + + o.eval(); +} diff --git a/tests60/script_tests/basic.l b/tests60/script_tests/basic.l index 0ab279a1f0..d7dcc958ae 100644 --- a/tests60/script_tests/basic.l +++ b/tests60/script_tests/basic.l @@ -8,5 +8,20 @@ public evalTest() : testCase() Assert.ifEqual(ret, "Hello World"); - Console.write("."); + Console.writeLine("."); } + + +public extensionCallTest() : testCase() +{ + Console.print("Calling an extension in evaluation mode - "); + + var t := new ScriptEngine() + .loadScript("[[ #grammar build ]]") + .loadPath("~\scripts\grammar60.es") + .loadPath("~\scripts\lscript60.es"); + + var o := t.buildScript("import extensions; public program() { Console.printLine(""Done"") }"); + + o.eval(); +} \ No newline at end of file diff --git a/tests60/script_tests/script_tests.prj b/tests60/script_tests/script_tests.prj index 35db799ad8..51376ec011 100644 --- a/tests60/script_tests/script_tests.prj +++ b/tests60/script_tests/script_tests.prj @@ -12,6 +12,7 @@ script_tests + -1 diff --git a/tests60/system_tests/basic.l b/tests60/system_tests/basic.l index d4cdea3b29..369a69bc65 100644 --- a/tests60/system_tests/basic.l +++ b/tests60/system_tests/basic.l @@ -1964,7 +1964,7 @@ public interfaceImplTests() : testCase() II_I i := o; var r := i.retrieve(); - Assert.ifTrue(r is::II_A); + Assert.ifTrue(r is:II_A); Console.write("."); } @@ -2016,7 +2016,7 @@ public decoratorTest() : testCase() var a := new DecoratorBaseA(2); var decA := new DecoratorA(a, 3); - Assert.ifEqual((decA as::IDecoratorA).giveMe(), 5); + Assert.ifEqual((decA as:IDecoratorA).giveMe(), 5); Console.write("."); } @@ -2383,7 +2383,7 @@ sealed class MyIntValue public implicitConvertorTest() : testCase() { - auto v := "2" as:: MyIntValue; + auto v := "2" as:MyIntValue; Assert.ifEqual(v.Value, 2); Console.write("."); From 187f4bb94b0710c071ec156fb1403fadf2070b7d Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Mon, 14 Apr 2025 09:45:57 +0200 Subject: [PATCH 40/53] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 47c1b84a96..10f92b3115 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@
    [![MSBuild](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml/badge.svg?branch=master)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml) +[![Nightly](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml/badge.svg?branch=develop)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/nightly.yml) [![Sponsor](https://img.shields.io/badge/patreon-donate-green.svg)](https://www.patreon.com/elena_lang) [![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&link=https://github.com/sponsors/arakov)](https://github.com/sponsors/arakov) From 25be34d5a14c495cb04c86b03b08482570217959 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Mon, 14 Apr 2025 09:46:17 +0200 Subject: [PATCH 41/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10f92b3115..aca8e0c31d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@
    [![MSBuild](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml/badge.svg?branch=master)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml) -[![Nightly](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml/badge.svg?branch=develop)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/nightly.yml) +[![Nightly](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml/badge.svg?nightly=develop)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/nightly.yml) [![Sponsor](https://img.shields.io/badge/patreon-donate-green.svg)](https://www.patreon.com/elena_lang) [![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&link=https://github.com/sponsors/arakov)](https://github.com/sponsors/arakov) From 174f2509108598bd8332f0e970ce9b52e9cdc9d6 Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Mon, 14 Apr 2025 09:47:35 +0200 Subject: [PATCH 42/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aca8e0c31d..d6ea93946c 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@
    [![MSBuild](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml/badge.svg?branch=master)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml) -[![Nightly](https://github.com/ELENA-LANG/elena-lang/actions/workflows/msbuild.yml/badge.svg?nightly=develop)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/nightly.yml) +[![Nightly MSBuild](https://github.com/ELENA-LANG/elena-lang/actions/workflows/nightly.yml/badge.svg)](https://github.com/ELENA-LANG/elena-lang/actions/workflows/nightly.yml) [![Sponsor](https://img.shields.io/badge/patreon-donate-green.svg)](https://www.patreon.com/elena_lang) [![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&link=https://github.com/sponsors/arakov)](https://github.com/sponsors/arakov) From 849f274e1d94663af89e0b86d4268257a8242c7e Mon Sep 17 00:00:00 2001 From: arakov Date: Mon, 14 Apr 2025 13:25:24 +0200 Subject: [PATCH 43/53] updating action yml --- .github/workflows/msbuild.yml | 2 +- .github/workflows/nightly.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index c88f522663..783a942f5e 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -71,7 +71,7 @@ jobs: shell: cmd run: scripts\create_package_${{matrix.platform}}.bat - - run: Compress-Archive .\scripts\${{matrix.platform}}\* .\scripts\elena-lang-${{matrix.platform}}-${{ env.BUILD_TAG }}.zip + - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-${{ env.BUILD_TAG }}.zip - name: Upload Release uses: softprops/action-gh-release@v2 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index d8cc22f498..a3e35b1f6e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -74,7 +74,7 @@ jobs: name: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }} path: scripts\${{matrix.platform}} - - run: Compress-Archive .\scripts\${{matrix.platform}}\* .\scripts\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip - name: Upload Release uses: softprops/action-gh-release@v2 @@ -83,4 +83,4 @@ jobs: draft: false prerelease: true files: | - ./scripts/*.zip + ./build/*.zip From bf7f2aed7bc523641d1622e3d586ebaa399792eb Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Tue, 15 Apr 2025 16:25:58 +0200 Subject: [PATCH 44/53] Update README.md --- README.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index d6ea93946c..20cd99b4be 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,28 @@ ELENA is a general-purpose language with late binding. It is multi-paradigm, com - **macOS** : arm64 (a64) +## Resources +- **Nightly builds:** +- **ELENA Documentation** +- **ELENA API 6.0** +- **Git clone URL:** +- **Tutorials:** +- **ELENA reddit:** +- **Source code:** +- **BluSky:** +- **Rosetta code:** + +## Contact Us + +Reach out with any questions you may have and we'll make sure to answer them as soon as possible! + +| Platform | Link | +|:----------|:------------| +| 💬 Instant Message Chat | [![Discord Banner](https://discordapp.com/api/guilds/1023392280087908352/widget.png?style=banner2)](https://discord.gg/pMCjunWSxH) +| Forum | [Discussions](https://github.com/orgs/ELENA-LANG/discussions) +| 📧 E-mail | elenaprolang@gmail.com +| 🐤 BlueSky | [@elena_language](https://bsky.app/profile/alexrakov.bsky.social) + ## Installing ELENA from source To acquire the source code clone the git repository: @@ -214,28 +236,6 @@ If you've noticed a bug or have a question go ahead and [make one](https://githu You may look at or try to implement some of [Rosetta code tasks](https://rosettacode.org/wiki/Category:Elena) which are not yet implemented -## Contact Us - -Reach out with any questions you may have and we'll make sure to answer them as soon as possible! - -| Platform | Link | -|:----------|:------------| -| 💬 Instant Message Chat | [![Discord Banner](https://discordapp.com/api/guilds/1023392280087908352/widget.png?style=banner2)](https://discord.gg/pMCjunWSxH) -| Forum | [Discussions](https://github.com/orgs/ELENA-LANG/discussions) -| 📧 E-mail | elenaprolang@gmail.com -| 🐤 BlueSky | [@elena_language](https://bsky.app/profile/alexrakov.bsky.social) - -## Resources -- **Nightly builds:** -- **ELENA Documentation** -- **ELENA API 6.0** -- **Git clone URL:** -- **Tutorials:** -- **ELENA reddit:** -- **Source code:** -- **BluSky:** -- **Rosetta code:** - ## License The compiler and executables distributed in this package fall under MIT License, From 121961a0c4d2c5cb1a05974f8a1460f1f263b59d Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Tue, 15 Apr 2025 16:33:39 +0200 Subject: [PATCH 45/53] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 20cd99b4be..1dd8e3c385 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,12 @@ If you've noticed a bug or have a question go ahead and [make one](https://githu You may look at or try to implement some of [Rosetta code tasks](https://rosettacode.org/wiki/Category:Elena) which are not yet implemented +## Terminal, IDEs + +ELENA support both [command-line tools](https://github.com/ELENA-LANG/elena-lang/wiki/Using-command%E2%80%90line-tools) and IDE. + +The work on [VSCode extension](https://github.com/ELENA-LANG/vscode-elena-lang) & [Debug Adapter Protoco support](https://github.com/ELENA-LANG/elena_dap) is going on + ## License The compiler and executables distributed in this package fall under MIT License, From 9fa234d148b71efb020847912846e22caab98c1c Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Wed, 16 Apr 2025 13:24:00 +0200 Subject: [PATCH 46/53] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1dd8e3c385..edfda446fc 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,9 @@ ELENA is a general-purpose language with late binding. It is multi-paradigm, com - Concurrent programming - Closures - Mixins - - Type interfaces / conversions - - Class / code templates + - Type interfaces / Conversions + - Class / Code templates + - Extensions / Template extensions - Script Engine ## Currently Supported Platforms From 268f4769ca013c929cc8df7d35ee1f17eff27d6a Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Wed, 16 Apr 2025 13:25:47 +0200 Subject: [PATCH 47/53] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index edfda446fc..989c198df6 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,8 @@ ELENA is a general-purpose language with late binding. It is multi-paradigm, com - Closures - Mixins - Type interfaces / Conversions - - Class / Code templates - - Extensions / Template extensions + - Class templates / Expression templates + - Extensions / Extension Templates - Script Engine ## Currently Supported Platforms From b0f278806bf728c6e7d41726b1190d659eb95b60 Mon Sep 17 00:00:00 2001 From: arakov Date: Thu, 17 Apr 2025 08:47:59 +0200 Subject: [PATCH 48/53] fixing action script --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index a3e35b1f6e..bca4cef95d 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -72,7 +72,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }} - path: scripts\${{matrix.platform}} + path: build\${{matrix.platform}} - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip From ea511f57327795ee80941dcb985ce3e97eb3803a Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Wed, 30 Apr 2025 21:06:21 +0200 Subject: [PATCH 49/53] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 989c198df6..a5dff3fad8 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ ELENA is a general-purpose language with late binding. It is multi-paradigm, com - **Windows** : x86 (32-bit) / x86-64 (64-bit) - **Linux** : x86 (32-bit) / x86-64 (64-bit) / ppc64le / arm64 (a64) +- **FreeBSD** :x86-64 (64-bit) ## Platforms to be supported From 60ebf8b6725c0e9612066cf5effb1dc964a42f7c Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sun, 4 May 2025 18:39:34 +0200 Subject: [PATCH 50/53] Iteration40 (#758) * [ADDED] #742 : Declaring external callback * [ADDED] "use" statement to declare a class / external reference shortcut * working on xml * fixing external routine * [ADDED] "#import" statement to register the external library name * [ADDED] project variables * [ADDED] Conditional compilation * [ADDED] system'UnsafePointer * working on meta programming : executing int comparison in compile-time * #562 : working on nullable field and template argument * #731 : loading xml * fixing a critical error with a field sequence * [FIXED] system'io'MemoryStream - reading operation * [FIXED] ByteArrayExConvertor.toByteArray extension method * [ADDED] new library : textgen * working on script engine - for loop * replace gcvt with snprintf * [IDE][ADDED] brackets highlighting * #748 : working on FreeBSD support * implement ELF hash table * working on #756 : supporting mingw * #34 : working on HttpClient - post method --- .github/workflows/make.yml | 19 +- .github/workflows/msbuild.yml | 11 +- .github/workflows/nightly.yml | 20 +- .gitignore | 1 - BSDmakefile | 80 ++ CHANGELOG.md | 34 + VERSION | 2 +- asm/aarch64/core60.asm | 2 + asm/amd64/core60.asm | 6 + asm/amd64/core60_lnx.asm | 13 +- asm/ppc64le/core60.asm | 2 + asm/x32/core60.asm | 38 + asm/x32/core60_lnx.asm | 26 - asm/x32/core60_win.asm | 18 - asm/x32/corex60.asm | 191 ++- asm/x32/corex60_win.asm | 16 - bin/elc60.cfg | 7 +- bin/elc60.config | 29 +- bin/elenart60.config | 5 + bin/elenavm60.cfg | 1 - bin/local.elc60.config | 29 +- bin/scripts/grammar60.es | 56 +- bin/scripts/lscript60.es | 43 +- bin/templates/lib60.config | 5 + bin/templates/lnx_console60.config | 5 + bin/templates/local.lib60.config | 5 + bin/templates/local.mt_lnx_console60.config | 2 +- bin/templates/mt_lnx_console60.config | 2 +- bin/templates/mt_win_console60.cfg | 1 - build/create_package_x64.bat | 99 -- build/create_package_x86.bat | 120 -- build/rebuild_data60_x64.bat | 53 - build/rebuild_data60_x86.bat | 53 - build/rebuild_lib60_x64.bat | 81 -- build/rebuild_lib60_x86.bat | 116 -- dat/api2html/api2html.bat | 62 +- dat/og/bt_rules60.txt | 1 + dat/sg/syntax60.txt | 84 +- doc/api/algorithms-summary.html | 9 + doc/api/algorithms.html | 103 ++ doc/api/extensions-runtime-summary.html | 20 + doc/api/extensions-runtime.html | 39 + doc/api/extensions-scripting-summary.html | 24 +- doc/api/extensions-scripting.html | 45 +- doc/api/extensions-text.html | 59 +- doc/api/forms.html | 67 +- doc/api/index.html | 44 +- doc/api/net-http-summary.html | 65 + doc/api/net-http.html | 688 +++++++++- .../system-dynamic-expressions-summary.html | 57 +- doc/api/system-dynamic-expressions.html | 160 ++- doc/api/system-io.html | 27 + doc/api/system-routines-summary.html | 51 +- doc/api/system-routines.html | 268 +++- doc/api/system-summary.html | 79 +- doc/api/system-text.html | 22 +- doc/api/system-winforms.html | 21 +- doc/api/system.html | 117 +- doc/api/textgen-summary.html | 85 ++ doc/api/textgen.html | 81 ++ doc/api/xforms.html | 2 +- doc/api/xml-summary.html | 119 ++ doc/api/xml.html | 900 +++++++++++++ doc/features | 79 ++ doc/todo.txt | 75 +- elenasrc3/common/common.h | 2 +- elenasrc3/common/files.cpp | 14 +- elenasrc3/common/files.h | 4 +- elenasrc3/common/paths.cpp | 4 +- elenasrc3/common/paths.h | 8 +- elenasrc3/common/tools.h | 10 +- elenasrc3/common/tree.h | 5 +- elenasrc3/common/ustring.cpp | 19 +- elenasrc3/elc/clicommon.h | 14 +- elenasrc3/elc/cliconst.h | 2 +- .../elc/codeblocks/bsd.clang_elc_amd64.mak | 180 +++ elenasrc3/elc/codeblocks/bsd.elc_amd64.mak | 180 +++ elenasrc3/elc/codeblocks/elc_amd64.mak | 63 +- elenasrc3/elc/compiler.cpp | 1138 +++++++++++++---- elenasrc3/elc/compiler.h | 88 +- elenasrc3/elc/compilerlogic.cpp | 48 +- elenasrc3/elc/compilerlogic.h | 3 +- elenasrc3/elc/compiling.cpp | 53 +- elenasrc3/elc/compiling.h | 4 + elenasrc3/elc/derivation.cpp | 69 +- elenasrc3/elc/derivation.h | 7 +- elenasrc3/elc/linux/elc.cpp | 9 + elenasrc3/elc/linux/elfimage.cpp | 137 +- elenasrc3/elc/linux/elfimage.h | 10 +- elenasrc3/elc/linux/elflinker.cpp | 4 +- elenasrc3/elc/linux/elflinker.h | 8 +- elenasrc3/elc/linux/elflinker32.cpp | 11 +- elenasrc3/elc/linux/elflinker64.cpp | 25 +- elenasrc3/elc/linux/pathmanager.cpp | 19 + elenasrc3/elc/modulescope.h | 31 +- elenasrc3/elc/project.cpp | 1 + elenasrc3/elc/separser.cpp | 6 +- elenasrc3/elc/windows/ntlinker.cpp | 2 +- elenasrc3/elc/windows/ntlinker.h | 2 +- elenasrc3/elc/windows/winsyslibloader.cpp | 4 + elenasrc3/elena-tests/bt_optimization.h | 26 + elenasrc3/elena-tests/scenario_consts.h | 2 + .../elena-tests/tests_bt_optimization.cpp | 80 +- elenasrc3/elena-tests/tests_build.cpp | 11 + elenasrc3/elena-tests/tests_common.cpp | 29 + elenasrc3/elena-tests/tests_common.h | 17 + .../codeblocks/bsd.clang_elenart_amd64.mak | 116 ++ .../elenart/codeblocks/bsd.elenart_amd64.mak | 116 ++ .../elenart/codeblocks/elenart_amd64.mak | 66 +- elenasrc3/elenart/linux/elenart.h | 6 + elenasrc3/elenart/linux/main.cpp | 6 + .../codeblocks/bsd.clang_elenasm_amd64.mak | 100 ++ .../elenasm/codeblocks/bsd.elenasm_amd64.mak | 100 ++ .../elenasm/codeblocks/elenasm_amd64.mak | 51 +- elenasrc3/elenasm/smcommon.h | 2 +- elenasrc3/elenasm/treeparser.cpp | 60 +- elenasrc3/elenasm/treeparser.h | 6 +- elenasrc3/engine/bcwriter.cpp | 126 +- elenasrc3/engine/buildtree.h | 28 +- elenasrc3/engine/bytecode.cpp | 68 +- elenasrc3/engine/bytecode.h | 8 +- elenasrc3/engine/elena.h | 8 + elenasrc3/engine/elenaconst.h | 2 + elenasrc3/engine/langcommon.h | 15 +- elenasrc3/engine/linux/lnxroutines.cpp | 133 +- elenasrc3/engine/projectbase.h | 2 +- elenasrc3/engine/syntaxtree.h | 18 + elenasrc3/engine/windows/winroutines.cpp | 4 + elenasrc3/engine/xmlprojectbase.cpp | 31 +- elenasrc3/engine/xmlprojectbase.h | 5 + elenasrc3/gui/controller.cpp | 116 ++ elenasrc3/gui/controller.h | 2 + elenasrc3/gui/document.cpp | 127 +- elenasrc3/gui/document.h | 49 +- elenasrc3/gui/guieditor.h | 32 +- elenasrc3/gui/text.cpp | 31 + elenasrc3/gui/text.h | 5 + elenasrc3/gui/view.cpp | 2 +- elenasrc3/ide/debugcontroller.cpp | 15 +- elenasrc3/ide/debugcontroller.h | 2 + elenasrc3/ide/idecommon.h | 2 + elenasrc3/ide/idecontroller.cpp | 25 +- elenasrc3/ide/ideproject.h | 1 + elenasrc3/ide/ideversion.h | 2 +- elenasrc3/ide/windows/Resource.h | 1 + elenasrc3/ide/windows/elide.rc | Bin 46214 -> 46444 bytes elenasrc3/ide/windows/factory.cpp | 3 + elenasrc3/ide/windows/windialogs.cpp | 5 + elenasrc3/tools/asmc/asmc.cpp | 60 +- elenasrc3/tools/asmc/asmconst.h | 12 +- elenasrc3/tools/asmc/assembler.cpp | 34 +- elenasrc3/tools/asmc/assembler.h | 11 + .../tools/asmc/codeblocks/asmc_amd64.mak | 12 +- .../tools/asmc/codeblocks/bsd.asmc_amd64.mak | 101 ++ .../asmc/codeblocks/bsd.clang_asmc_amd64.mak | 101 ++ elenasrc3/tools/asmc/x86assembler.cpp | 10 + .../ecv/codeblocks/bsd.clang_ecv_amd64.mak | 93 ++ .../tools/ecv/codeblocks/bsd.ecv_amd64.mak | 93 ++ elenasrc3/tools/ecv/codeblocks/ecv_amd64.mak | 33 +- elenasrc3/tools/ecv/ecvconst.h | 6 +- elenasrc3/tools/ecv/ecviewer.cpp | 21 +- elenasrc3/tools/ecv/ecviewer.h | 2 +- .../og/codeblocks/bsd.clang_og_amd64.mak | 75 ++ .../tools/og/codeblocks/bsd.og_amd64.mak | 75 ++ elenasrc3/tools/og/codeblocks/og_amd64.mak | 12 +- elenasrc3/tools/og/og.cpp | 8 + elenasrc3/tools/og/ogconst.h | 2 +- .../sg/codeblocks/bsd.clang_sg_amd64.mak | 75 ++ .../tools/sg/codeblocks/bsd.sg_amd64.mak | 75 ++ elenasrc3/tools/sg/codeblocks/sg_amd64.mak | 12 +- examples60/rosetta/twentyfour/twentyfour.l | 3 +- scripts/aarch64/build_package_arm64.script | 2 +- scripts/aarch64/control | 2 +- scripts/amd64/build_package_amd64.script | 75 -- scripts/amd64/control | 2 +- .../amd64/local_build_package_amd64.script | 3 + scripts/amd64/local_create_package.script | 48 + scripts/amd64/local_runtests.script | 4 - scripts/amd64/runtests.script | 21 + .../bsd.amd64/bash/build_package_amd64.script | 132 ++ .../bash/local_build_package_amd64.script | 98 ++ scripts/bsd.amd64/bash/local_runtests.script | 21 + scripts/bsd.amd64/bash/runtests.script | 21 + scripts/bsd.amd64/build_package_amd64.script | 132 ++ .../local_build_package_amd64.script | 98 ++ scripts/bsd.amd64/local_runtests.script | 21 + scripts/bsd.amd64/runtests.script | 21 + scripts/create_package_x64.bat | 155 +-- scripts/create_package_x86.bat | 178 +-- scripts/i386/build_package_i386.script | 77 +- scripts/i386/control | 2 +- scripts/i386/local_build_package_i386.script | 19 +- scripts/i386/local_create_package.script | 47 + scripts/i386/local_runtests.script | 4 - scripts/ppc64le/build_package_ppc64le.script | 2 +- scripts/ppc64le/control | 2 +- scripts/rebuild_lib60_x86.bat | 35 +- src60/algorithms/algorithms.linux.prj | 9 +- src60/algorithms/algorithms.prj | 4 +- src60/algorithms/binary.l | 22 + src60/algorithms/insertsort.l | 47 + src60/algorithms/quicksort.l | 58 + src60/algorithms/sort_extensions.l | 69 + src60/cellular/cellular.linux.prj | 5 + src60/core/system.core_routines.esm | 8 +- src60/elena_api.linux.prjcol | 1 + src60/elena_api.prjcol | 2 + src60/extensions/convertors.l | 2 +- src60/extensions/extensions.linux.prj | 7 +- src60/extensions/extensions.prj | 2 +- src60/extensions/scripting/lscript.l | 6 +- src60/extensions/text/strings.l | 35 +- src60/forms/forms.prj | 2 +- src60/forms/win32_controls.l | 38 +- src60/forms/win_forms.l | 38 +- src60/ltests/ltests.linux.prj | 5 + src60/net/http/httpclient.l | 62 + src60/net/http/httpheaders.l | 22 +- src60/net/http/httprequest.l | 32 + src60/net/http/httpresponse.l | 26 +- src60/net/net.prj | 1 + src60/system/attributes/attributes.l | 6 +- src60/system/basic.l | 30 +- .../system/dynamic/expressions/expressions.l | 31 +- src60/system/events.l | 2 +- src60/system/exceptions.l | 11 +- src60/system/inline_templates.l | 66 + src60/system/io/files.l | 13 +- src60/system/io/lnx_files.l | 41 +- src60/system/io/memorystream.l | 16 +- src60/system/io/win_files.l | 6 +- src60/system/object.l | 2 +- src60/system/pointers.l | 56 +- src60/system/predefined/predefined.l | 1 + src60/system/routines/enumerables.l | 3 + src60/system/routines/patterns.l | 42 + src60/system/routines/sorting.l | 73 ++ src60/system/system.linux.prj | 15 +- src60/system/system.prj | 3 +- src60/system/text/base64.l | 278 ++++ src60/system/text/encoding.l | 42 + src60/system/text/textbuffer.l | 42 +- src60/system/winforms/win_windows.l | 6 + src60/textgen/extensions.l | 17 + src60/textgen/parser.l | 74 ++ src60/textgen/textgen.prj | 29 + src60/xml/xml.linux.prj | 46 + src60/xml/xml.prj | 31 + src60/xml/xmldoc.l | 126 ++ src60/xml/xmlformatter.l | 48 + src60/xml/xmlnode.l | 178 +++ src60/xml/xmlreader.l | 124 ++ tests60/api_tests/api_tests.prj | 43 + tests60/api_tests/main.l | 10 + tests60/api_tests/textgen.l | 16 + tests60/api_tests/xml.l | 75 ++ tests60/sandbox/sandbox.l | 15 +- tests60/script_tests/basic.l | 2 +- tests60/system_tests/basic.l | 66 + tests60/system_tests/main.l | 2 +- 260 files changed, 10846 insertions(+), 1982 deletions(-) create mode 100644 BSDmakefile delete mode 100644 asm/x32/core60_lnx.asm delete mode 100644 asm/x32/core60_win.asm delete mode 100644 asm/x32/corex60_win.asm delete mode 100644 build/create_package_x64.bat delete mode 100644 build/create_package_x86.bat delete mode 100644 build/rebuild_data60_x64.bat delete mode 100644 build/rebuild_data60_x86.bat delete mode 100644 build/rebuild_lib60_x64.bat delete mode 100644 build/rebuild_lib60_x86.bat create mode 100644 doc/api/textgen-summary.html create mode 100644 doc/api/textgen.html create mode 100644 doc/api/xml-summary.html create mode 100644 doc/api/xml.html create mode 100644 elenasrc3/elc/codeblocks/bsd.clang_elc_amd64.mak create mode 100644 elenasrc3/elc/codeblocks/bsd.elc_amd64.mak create mode 100644 elenasrc3/elenart/codeblocks/bsd.clang_elenart_amd64.mak create mode 100644 elenasrc3/elenart/codeblocks/bsd.elenart_amd64.mak create mode 100644 elenasrc3/elenasm/codeblocks/bsd.clang_elenasm_amd64.mak create mode 100644 elenasrc3/elenasm/codeblocks/bsd.elenasm_amd64.mak create mode 100644 elenasrc3/tools/asmc/codeblocks/bsd.asmc_amd64.mak create mode 100644 elenasrc3/tools/asmc/codeblocks/bsd.clang_asmc_amd64.mak create mode 100644 elenasrc3/tools/ecv/codeblocks/bsd.clang_ecv_amd64.mak create mode 100644 elenasrc3/tools/ecv/codeblocks/bsd.ecv_amd64.mak create mode 100644 elenasrc3/tools/og/codeblocks/bsd.clang_og_amd64.mak create mode 100644 elenasrc3/tools/og/codeblocks/bsd.og_amd64.mak create mode 100644 elenasrc3/tools/sg/codeblocks/bsd.clang_sg_amd64.mak create mode 100644 elenasrc3/tools/sg/codeblocks/bsd.sg_amd64.mak mode change 100644 => 100755 scripts/amd64/build_package_amd64.script create mode 100755 scripts/amd64/local_create_package.script create mode 100755 scripts/amd64/runtests.script create mode 100755 scripts/bsd.amd64/bash/build_package_amd64.script create mode 100755 scripts/bsd.amd64/bash/local_build_package_amd64.script create mode 100755 scripts/bsd.amd64/bash/local_runtests.script create mode 100755 scripts/bsd.amd64/bash/runtests.script create mode 100755 scripts/bsd.amd64/build_package_amd64.script create mode 100755 scripts/bsd.amd64/local_build_package_amd64.script create mode 100755 scripts/bsd.amd64/local_runtests.script create mode 100755 scripts/bsd.amd64/runtests.script mode change 100644 => 100755 scripts/i386/build_package_i386.script create mode 100755 scripts/i386/local_create_package.script create mode 100644 src60/algorithms/binary.l create mode 100644 src60/algorithms/insertsort.l create mode 100644 src60/net/http/httprequest.l create mode 100644 src60/system/text/base64.l create mode 100644 src60/textgen/extensions.l create mode 100644 src60/textgen/parser.l create mode 100644 src60/textgen/textgen.prj create mode 100644 src60/xml/xml.linux.prj create mode 100644 src60/xml/xml.prj create mode 100644 src60/xml/xmldoc.l create mode 100644 src60/xml/xmlformatter.l create mode 100644 src60/xml/xmlnode.l create mode 100644 src60/xml/xmlreader.l create mode 100644 tests60/api_tests/api_tests.prj create mode 100644 tests60/api_tests/main.l create mode 100644 tests60/api_tests/textgen.l create mode 100644 tests60/api_tests/xml.l diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index 48032f1026..38ab2f1faa 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -33,7 +33,7 @@ jobs: - name: Install dependencies run: | - sudo apt-get install gcc-multilib g++-multilib + sudo apt-get install build-essential gcc-multilib g++-multilib alien dpkg-dev debhelper - name: Build run: make all_${{ matrix.platform }} @@ -46,4 +46,19 @@ jobs: - name: Run functional test run: | cd scripts/${{ matrix.platform }} - sudo ./local_runtests.script + ./local_runtests.script + + - name: Create a package + run: | + cd scripts/${{ matrix.platform }} + ./local_create_package.script + + - name: Upload Release + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ env.BUILD_TAG }} + draft: false + prerelease: true + files: | + ./build/*.rpm + ./build/*.deb diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 783a942f5e..00d831990e 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -39,15 +39,16 @@ jobs: uses: microsoft/setup-msbuild@v2 - name: Setup Nuget - uses: Nuget/setup-nuget@v1.0.5 + uses: Nuget/setup-nuget@v2 - name: Restore nuget packages run: nuget restore ${{env.SOLUTION_FILE_PATH}} - name: Set version + shell: bash run: | VER=$(cat VERSION) - echo "BUILD_TAG=$VER" >> $GITHUB_ENV + echo "VERSION=$VER" >> $GITHUB_ENV - name: Build working-directory: ${{env.GITHUB_WORKSPACE}} @@ -71,13 +72,13 @@ jobs: shell: cmd run: scripts\create_package_${{matrix.platform}}.bat - - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-${{ env.BUILD_TAG }}.zip + - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-${{ env.VERSION }}.zip - name: Upload Release uses: softprops/action-gh-release@v2 with: - tag_name: v${{ env.BUILD_TAG }} + tag_name: v${{ env.VERSION }} draft: false prerelease: true files: | - ./scripts/*.zip + ./build/*.zip diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index bca4cef95d..efc3c7ce2d 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -19,8 +19,6 @@ env: # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix BUILD_CONFIGURATION: Release - BUILD_TAG: 6.6.5 - permissions: write-all jobs: @@ -35,7 +33,7 @@ jobs: steps: - uses: actions/checkout@v4 with: - ref: iteration40 + ref: iteration41 - name: Add MSBuild to PATH uses: microsoft/setup-msbuild@v2 @@ -46,6 +44,16 @@ jobs: - name: Restore nuget packages run: nuget restore ${{env.SOLUTION_FILE_PATH}} + - name: Set version + shell: bash + run: | + VER=$(cat VERSION) + echo "VERSION=$VER" >> $GITHUB_ENV + + - name: Show variables + run: | + echo "${{ env.VERSION }}" + - name: Build working-directory: ${{env.GITHUB_WORKSPACE}} # Add additional options to the MSBuild command line here (like platform or verbosity level). @@ -71,10 +79,10 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }} + name: elena-lang-${{matrix.platform}}-nightly-${{ env.VERSION }} path: build\${{matrix.platform}} - - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-nightly-${{ env.BUILD_TAG }}.zip + - run: Compress-Archive .\build\${{matrix.platform}}\* .\build\elena-lang-${{matrix.platform}}-nightly-${{ env.VERSION }}.zip - name: Upload Release uses: softprops/action-gh-release@v2 @@ -83,4 +91,4 @@ jobs: draft: false prerelease: true files: | - ./build/*.zip + ./build/*.zip \ No newline at end of file diff --git a/.gitignore b/.gitignore index 67feb15ee6..b32bb31f05 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ /lib60 /lib60_64 /dat/api2html -/scripts /bin /doc /tests60 diff --git a/BSDmakefile b/BSDmakefile new file mode 100644 index 0000000000..bb4ba73ae2 --- /dev/null +++ b/BSDmakefile @@ -0,0 +1,80 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WRKDIR = `pwd` +MAKE = make + +all_amd64: elc_amd64 sg_amd64 og_amd64 asmc_amd64 ecv_amd64 elenart_amd64 elenasm_amd64 + +clang_all_amd64: clang_elc_amd64 clang_sg_amd64 clang_og_amd64 clang_asmc_amd64 clang_ecv_amd64 clang_elenart_amd64 clang_elenasm_amd64 + +elc_amd64: + $(MAKE) -C elenasrc3/elc/codeblocks all -f bsd.elc_amd64.mak + +clang_elc_amd64: + $(MAKE) -C elenasrc3/elc/codeblocks all -f bsd.clang_elc_amd64.mak + +sg_amd64: + $(MAKE) -C elenasrc3/tools/sg/codeblocks all -f bsd.clang_sg_amd64.mak + +clang_sg_amd64: + $(MAKE) -C elenasrc3/tools/sg/codeblocks all -f bsd.sg_amd64.mak + +og_amd64: + $(MAKE) -C elenasrc3/tools/og/codeblocks all -f bsd.og_amd64.mak + +clang_og_amd64: + $(MAKE) -C elenasrc3/tools/og/codeblocks all -f bsd.clang_og_amd64.mak + +asmc_amd64: + $(MAKE) -C elenasrc3/tools/asmc/codeblocks all -f bsd.asmc_amd64.mak + +clang_asmc_amd64: + $(MAKE) -C elenasrc3/tools/asmc/codeblocks all -f bsd.clang_asmc_amd64.mak + +ecv_amd64: + $(MAKE) -C elenasrc3/tools/ecv/codeblocks all -f bsd.ecv_amd64.mak + +clang_ecv_amd64: + $(MAKE) -C elenasrc3/tools/ecv/codeblocks all -f bsd.clang_ecv_amd64.mak + +elenart_amd64: + $(MAKE) -C elenasrc3/elenart/codeblocks all -f bsd.elenart_amd64.mak + +clang_elenart_amd64: + $(MAKE) -C elenasrc3/elenart/codeblocks all -f bsd.clang_elenart_amd64.mak + +elenasm_amd64: + $(MAKE) -C elenasrc3/elenasm/codeblocks all -f bsd.elenasm_amd64.mak + +clang_elenasm_amd64: + $(MAKE) -C elenasrc3/elenasm/codeblocks all -f bsd.clang_elenasm_amd64.mak + +clean_amd64: clean_elc_amd64 clean_og_amd64 clean_sg_amd64 clean_asmc_amd64 clean_ecv_amd64 clean_elenart_amd64 clean_elenasm_amd64 + +clean_elc_amd64: + $(MAKE) -C elenasrc3/elc/codeblocks clean -f bsd.elc_amd64.mak + +clean_sg_amd64: + $(MAKE) -C elenasrc3/tools/sg/codeblocks clean -f bsd.sg_amd64.mak + +clean_og_amd64: + $(MAKE) -C elenasrc3/tools/og/codeblocks clean -f bsd.og_amd64.mak + +clean_og_ppc64le: + $(MAKE) -C elenasrc3/tools/og/codeblocks clean -f bsd.og_ppc64le.mak + +clean_asmc_amd64: + $(MAKE) -C elenasrc3/tools/asmc/codeblocks clean -f bsd.asmc_amd64.mak + +clean_ecv_amd64: + $(MAKE) -C elenasrc3/tools/ecv/codeblocks clean -f bsd.ecv_amd64.mak + +clean_elenart_amd64: + $(MAKE) -C elenasrc3/elenart/codeblocks clean -f bsd.elenart_amd64.mak + +clean_elenasm_amd64: + $(MAKE) -C elenasrc3/elenasm/codeblocks clean -f bsd.elenasm_amd64.mak + +.PHONY: clean_elc_amd64 clean_sg_amd64 clean_og_amd64 clean_asmc_amd64 clean_ecv_amd64 clean_elenart_amd64 diff --git a/CHANGELOG.md b/CHANGELOG.md index e42925492f..fba99e2d44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ - ELENA - [ADDED] user defined type alias - [ADDED] supporting auto field + - [ADDED] async action / async program entry + - [ADDED] "use" statement to declare a short cut + - [ADDED] "#import" statement to register the external library name + - [ADDED] project variables + - [ADDED] Conditional compilation - ELC - [ADDED] new option "-xj" to turn on jump alignment @@ -36,6 +41,12 @@ - [FIXED] string interpolation with character codes - [FIXED] ppc64le : fiadd, fisub, fimul, fidiv opcodes - [ADDED] project collection : support sub folders + - [FIXED] AARXH64 : fiadd, fisub, fimul, fidiv + - [ADDED] supporting base_path attribute in a project collection + - [ADDED] supporting profile attribute in a project collection + - [ADDED] #742 : Declaring external callback + - [ADDED] #748 : Supporting FreeBSD + - [ADDED] #756 : supporting mingw toolset - API - [ADDED] net'http'HttpClient, net'http'Uri @@ -47,17 +58,33 @@ - [ADDED] net'HttpClient - [FIXED] system'threading'Task - raise an exception if the task was completed before - [FIXED] BlockingQueue implementation + - [ADDED] new library : mbedtls + - [FIXED] VariadicExtensionDispatcher : dispatcher + - [ADDED] system'routines'CountDownEnumerator + - [ADDED] extension countDown + - [ADDED] BaseEdit.onChange event + - [ADDED] algorithms'InsertSortAlgorithm, algorithms'InsertSortAlgorithm + - [ADDED] algorithms'BinarySearchAlgorithm + - [ADDED] system'UnsafePointer + - [FIXED] system'io'MemoryStream - reading operation + - [FIXED] ByteArrayExConvertor.toByteArray extension method + - [ADDED] new library : textgen + - [ADDED] system'dynamic'expressions : ForLoopExpression + - [ADDED] net'http'HttpClient : post, postAsync + - [ADDED] system'text : Base64Encoding, Base64Encoder - SM - [ADDED] supporting $regex rules - Scripts - [ADDED] xforms : supporting RadioButton, Panel, Edit, Combobox + - [ADDED] LScript : for loop - SAMPLES - [ADDED] console regex sample - [ADDED] net : httpget sample - [FIXED] ppc64le : pi sample + - [FIXED] aarch64 : pi sample - IDE - [FIXED]debugger : step over multi-select statement @@ -72,6 +99,13 @@ - [ADDED] #723 : include path to approot temporally inside IDE - [ADDED] #722 : [IDE] Scrolling experience - [ADDED] #725 : [IDE] large toolbar buttons + - [FIXED] highlighting a string containing character codes + - [FIXED] saving IDE config file in the correct folder + - [FIXED] supporting clipboard operation without selection + - [FIXED] IDE64 : fixing undo / redo operations + - [ADDED] auto indent + - [FIXED] an outage is not being calculated correctly + - [ADDED] brackets highlighting - Tools - [ADDED][LDOC] static methods are in the separate category diff --git a/VERSION b/VERSION index 653877f1f9..07a7b03c99 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.6.5 \ No newline at end of file +6.7.0 \ No newline at end of file diff --git a/asm/aarch64/core60.asm b/asm/aarch64/core60.asm index d6bfd74c39..867ac29eaa 100644 --- a/asm/aarch64/core60.asm +++ b/asm/aarch64/core60.asm @@ -3161,6 +3161,7 @@ inline %1DDh ldrsw x17, [x0] ldrsw x18, [x19] + and x18, x18, 0FFh lsr x18, x18, x17 strb w18, [x19] @@ -3175,6 +3176,7 @@ inline %2DDh ldrsw x17, [x0] ldrsw x18, [x19] + and x18, x18, 0FFFFh lsr x18, x18, x17 strh w18, [x19] diff --git a/asm/amd64/core60.asm b/asm/amd64/core60.asm index 450f6f5552..2c4f293e12 100644 --- a/asm/amd64/core60.asm +++ b/asm/amd64/core60.asm @@ -2396,6 +2396,7 @@ inline %1DCh lea rdi, [rbp + __arg32_1] mov rcx, [r10] mov eax, dword ptr [rdi] + and eax, 0FFh shl eax, cl mov byte ptr [rdi], al @@ -2407,6 +2408,7 @@ inline %2DCh lea rdi, [rbp + __arg32_1] mov rcx, [r10] mov eax, dword ptr [rdi] + and eax, 0FFFFh shl eax, cl mov word ptr [rdi], ax @@ -2440,6 +2442,7 @@ inline %1DDh lea rdi, [rbp + __arg32_1] mov rcx, [r10] mov eax, dword ptr [rdi] + and eax, 0FFh shr eax, cl mov byte ptr [rdi], al @@ -2451,6 +2454,7 @@ inline %2DDh lea rdi, [rbp + __arg32_1] mov rcx, [r10] mov eax, dword ptr [rdi] + and eax, 0FFFFh shr eax, cl mov word ptr [rdi], ax @@ -2648,6 +2652,7 @@ inline %1E4h mov rcx, [r10] mov rax, [rbp+__arg32_1] + and eax, 0FFh cdq idiv cl mov byte ptr [rbp+__arg32_1], al @@ -2659,6 +2664,7 @@ inline %2E4h mov rcx, [r10] mov rax, [rbp+__arg32_1] + and eax, 0FFFFh cdq idiv cx mov word ptr [rbp+__arg32_1], ax diff --git a/asm/amd64/core60_lnx.asm b/asm/amd64/core60_lnx.asm index e42570733d..05408c15f7 100644 --- a/asm/amd64/core60_lnx.asm +++ b/asm/amd64/core60_lnx.asm @@ -144,9 +144,20 @@ end inline %4CFh finit - mov [data : %CORE_SINGLE_CONTENT + tt_stack_root], rsp + +#if _FREEBSD + + push 0 + mov rax, rdi + +#elif _LNX mov rax, rsp + +#endif + + mov [data : %CORE_SINGLE_CONTENT + tt_stack_root], rsp + call %PREPARE xor rbp, rbp diff --git a/asm/ppc64le/core60.asm b/asm/ppc64le/core60.asm index 72199efccf..0360157753 100644 --- a/asm/ppc64le/core60.asm +++ b/asm/ppc64le/core60.asm @@ -3015,6 +3015,7 @@ inline %1DDh lwz r17, 0(r3) lwz r18, 0(r19) + andi. r18, r18, 0FFh srd r18, r18, r17 stb r17, 0(r19) @@ -3029,6 +3030,7 @@ inline %2DDh lwz r17, 0(r3) lwz r18, 0(r19) + andi. r18, r18, 0FFFFh srd r18, r18, r17 sth r17, 0(r19) diff --git a/asm/x32/core60.asm b/asm/x32/core60.asm index a1f0e3979b..5ea504f6c4 100644 --- a/asm/x32/core60.asm +++ b/asm/x32/core60.asm @@ -288,8 +288,19 @@ end procedure %PREPARE +#if _WIN + + ret + +#elif _LNX + + push eax + call extern "$rt.PrepareLA" + add esp, 4 ret +#endif + end procedure %THREAD_WAIT @@ -2423,6 +2434,7 @@ inline %1DCh lea edi, [ebp + __arg32_1] mov ecx, [esi] mov eax, [edi] + and eax, 0FFh shl eax, cl mov byte ptr [edi], al @@ -2434,6 +2446,7 @@ inline %2DCh lea edi, [ebp + __arg32_1] mov ecx, [esi] mov eax, [edi] + and eax, 0FFFFh shl eax, cl mov word ptr [edi], ax @@ -2494,6 +2507,7 @@ inline %1DDh lea edi, [ebp + __arg32_1] mov ecx, [esi] mov eax, [edi] + and eax, 0FFh shr eax, cl mov byte ptr [edi], al @@ -2505,6 +2519,7 @@ inline %2DDh lea edi, [ebp + __arg32_1] mov ecx, [esi] mov eax, [edi] + and eax, 0FFFFh shr eax, cl mov word ptr [edi], ax @@ -2761,6 +2776,7 @@ inline %1E4h mov ecx, [esi] mov eax, [ebp+__arg32_1] + and eax, 0FFh cdq idiv cl mov byte ptr [ebp+__arg32_1], al @@ -2772,6 +2788,7 @@ inline %2E4h mov ecx, [esi] mov eax, [ebp+__arg32_1] + and eax, 0FFFFh cdq idiv cx mov word ptr [ebp+__arg32_1], ax @@ -4581,3 +4598,24 @@ inline %7FEh call extern __ptr32_1 end + +// VEH_HANDLER() +procedure % VEH_HANDLER + +#if _WIN + + mov esi, edx + mov edx, eax // ; set exception code + mov eax, [data : % CORE_SINGLE_CONTENT] + jmp eax + +#elif _LNX + + mov esi, edx + mov edx, eax // ; set exception code + mov eax, [data : % CORE_SINGLE_CONTENT] + jmp eax + +#endif + +end \ No newline at end of file diff --git a/asm/x32/core60_lnx.asm b/asm/x32/core60_lnx.asm deleted file mode 100644 index be4bde9194..0000000000 --- a/asm/x32/core60_lnx.asm +++ /dev/null @@ -1,26 +0,0 @@ -// ; --- Predefined References -- -define VEH_HANDLER 10003h -define PREPARE 10006h - -define CORE_SINGLE_CONTENT 2000Bh - -// ; ==== System commands === - -// VEH_HANDLER() -procedure % VEH_HANDLER - - mov esi, edx - mov edx, eax // ; set exception code - mov eax, [data : % CORE_SINGLE_CONTENT] - jmp eax - -end - -procedure %PREPARE - - push eax - call extern "$rt.PrepareLA" - add esp, 4 - ret - -end diff --git a/asm/x32/core60_win.asm b/asm/x32/core60_win.asm deleted file mode 100644 index acdd72e56c..0000000000 --- a/asm/x32/core60_win.asm +++ /dev/null @@ -1,18 +0,0 @@ -// ; --- Predefined References -- -define VEH_HANDLER 10003h - -define CORE_TOC 20001h -define SYSTEM_ENV 20002h -define CORE_SINGLE_CONTENT 2000Bh - -// ; ==== System commands === - -// VEH_HANDLER() -procedure % VEH_HANDLER - - mov esi, edx - mov edx, eax // ; set exception code - mov eax, [data : % CORE_SINGLE_CONTENT] - jmp eax - -end diff --git a/asm/x32/corex60.asm b/asm/x32/corex60.asm index 14c468b26d..990861610f 100644 --- a/asm/x32/corex60.asm +++ b/asm/x32/corex60.asm @@ -129,11 +129,20 @@ inline % GC_COLLECT labStart: // ; GCXT: find the current thread entry + +#if _WIN mov eax, fs:[2Ch] +#elif _LNX + mov eax, gs:[0] +#endif push esi +#if _WIN // ; GCXT: find the current thread entry mov eax, [eax] +#elif _LNX + lea eax, [eax-tt_size] +#endif push ebp @@ -384,12 +393,21 @@ labPERMCollect: sub ecx, eax // ; GCXT: find the current thread entry + +#if _WIN mov eax, fs:[2Ch] +#elif _LNX + mov eax, gs:[0] +#endif push esi // ; GCXT: find the current thread entry +#if _WIN mov eax, [eax] +#elif _LNX + lea eax, [eax-tt_size] +#endif push ebp @@ -531,8 +549,13 @@ labWait: jnz short labWait // ; find the current thread entry +#if _WIN mov eax, fs:[2Ch] mov eax, [eax] +#elif _LNX + mov eax, gs:[0] + lea eax, [eax-tt_size] +#endif mov esi, [eax+tt_sync_event] // ; get current thread event mov [eax+tt_stack_frame], edi // ; lock stack frame @@ -583,8 +606,14 @@ end // ; throw inline %0Ah +#if _WIN mov eax, fs:[2Ch] mov ecx, [eax] +#elif _LNX + mov eax, gs:[0] + lea ecx, [eax-tt_size] +#endif + mov edi, [ecx + et_current] jmp [edi + es_catch_addr] @@ -594,8 +623,14 @@ end inline %0Bh // ; GCXT: get current thread frame +#if _WIN mov eax, fs:[2Ch] mov ecx, [eax] +#elif _LNX + mov eax, gs:[0] + lea ecx, [eax-tt_size] +#endif + mov edi, [ecx + et_current] mov eax, [edi + es_prev_struct] @@ -609,8 +644,13 @@ end // ; exclude inline % 10h +#if _WIN mov eax, fs:[2Ch] mov edi, [eax] +#elif _LNX + mov eax, gs:[0] + lea edi, [eax-tt_size] +#endif mov [edi + tt_flags], 1 mov eax, [edi + tt_stack_frame] push eax @@ -623,8 +663,15 @@ end inline % 11h add esp, 4 + +#if _WIN mov eax, fs:[2Ch] mov edi, [eax] +#elif _LNX + mov eax, gs:[0] + lea edi, [eax-tt_size] +#endif + mov [edi + tt_flags], 0 pop eax mov [edi + tt_stack_frame], eax @@ -635,8 +682,14 @@ end inline %17h // ; COREX +#if _WIN mov eax, fs:[2Ch] mov edi, [eax] +#elif _LNX + mov eax, gs:[0] + lea edi, [eax-tt_size] +#endif + mov eax, [edi + tt_stack_root] xor ecx, ecx @@ -672,9 +725,16 @@ end // ; peektls inline %0BBh - mov eax, fs: [2Ch] +#if _WIN + mov eax, fs:[2Ch] mov eax, [eax] lea edi, [eax + __arg32_1] +#elif _LNX + mov eax, gs:[0] + lea edi, [eax - __arg32_1] + lea edi, [edi-4] +#endif + mov ebx, [edi] end @@ -682,9 +742,16 @@ end // ; storetls inline %0BCh - mov eax, fs: [2Ch] +#if _WIN + mov eax, fs:[2Ch] mov eax, [eax] lea edi, [eax + __arg32_1] +#elif _LNX + mov eax, gs:[0] + lea edi, [eax - __arg32_1] + lea edi, [edi-4] +#endif + mov [edi], ebx end @@ -699,8 +766,15 @@ inline %0CAh add esp, 8 pop ebx + +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif + mov [edi + tt_stack_frame], ebx pop ebp @@ -721,8 +795,15 @@ inline %1CAh add esp, 8 pop ebx + +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif + mov [edi + tt_stack_frame], ebx pop ebp @@ -771,8 +852,14 @@ end // ; system 3 (thread startup) inline %3CFh - mov eax, fs: [2Ch] +#if _WIN + mov eax, fs:[2Ch] mov eax, [eax] +#elif _LNX + mov eax, gs:[0] + lea eax, [eax-tt_size] +#endif + mov edi, data : %CORE_THREAD_TABLE + tt_slots mov [edi + edx * 8], eax @@ -819,9 +906,18 @@ end inline %0E6h // ; GCXT: get current thread frame +#if _WIN mov eax, fs:[2Ch] +#elif _LNX + mov eax, gs:[0] +#endif + lea edi, [ebp + __arg32_1] +#if _WIN mov eax, [eax] +#elif _LNX + lea eax, [eax-tt_size] +#endif mov ecx, [eax + et_current] mov [edi + es_catch_frame], ebp @@ -842,8 +938,15 @@ inline %0F2h push ebx push ebp + +#if _WIN mov eax, fs:[2Ch] mov edi, [eax] +#elif _LNX + mov eax, gs:[0] + lea edi, [eax-tt_size] +#endif + mov eax, [edi + tt_stack_frame] push eax @@ -877,8 +980,14 @@ inline %1F2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif + mov eax, [edi + tt_stack_frame] push eax @@ -908,8 +1017,13 @@ inline %2F2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -940,8 +1054,13 @@ inline %3F2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -973,8 +1092,13 @@ inline %4F2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -1007,8 +1131,13 @@ inline %5F2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -1042,8 +1171,13 @@ inline %6F2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -1073,8 +1207,13 @@ inline %7F2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -1099,8 +1238,13 @@ inline %8F2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -1126,8 +1270,13 @@ inline %9F2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -1155,8 +1304,13 @@ inline %0AF2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -1185,8 +1339,13 @@ inline %0BF2h push ebx push ebp +#if _WIN mov ecx, fs:[2Ch] mov edi, [ecx] +#elif _LNX + mov ecx, gs:[0] + lea edi, [ecx-tt_size] +#endif mov eax, [edi + tt_stack_frame] push eax @@ -1206,3 +1365,29 @@ inline %0BF2h mov esi, eax end + +// VEH_HANDLER() +procedure % VEH_HANDLER + +#if _WIN + + mov esi, edx + mov edx, eax // ; set exception code + + mov ecx, fs:[2Ch] + mov ecx, [ecx] + jmp [ecx] + +#elif _LNX + + mov esi, edx + mov edx, eax // ; set exception code + + mov ecx, gs:[0] + lea ecx, [ecx-tt_size] + + jmp [ecx] + +#endif + +end diff --git a/asm/x32/corex60_win.asm b/asm/x32/corex60_win.asm deleted file mode 100644 index c47deee1d3..0000000000 --- a/asm/x32/corex60_win.asm +++ /dev/null @@ -1,16 +0,0 @@ -// ; --- Predefined References -- -define VEH_HANDLER 10003h - -// ; ==== System commands === - -// VEH_HANDLER() -procedure % VEH_HANDLER - - mov esi, edx - mov edx, eax // ; set exception code - - mov ecx, fs:[2Ch] - mov ecx, [ecx] - jmp [ecx] - -end diff --git a/bin/elc60.cfg b/bin/elc60.cfg index d207a2a944..cf9886732f 100644 --- a/bin/elc60.cfg +++ b/bin/elc60.cfg @@ -1,7 +1,6 @@ - x32\core60.bin x32\core60_win.bin @@ -11,6 +10,9 @@ + + -1 + KERNEL32 USER32 @@ -34,5 +36,8 @@ KERNEL32 + + -1 + diff --git a/bin/elc60.config b/bin/elc60.config index 699b297307..f6f87b03e4 100644 --- a/bin/elc60.config +++ b/bin/elc60.config @@ -6,12 +6,14 @@ - /usr/lib/elena/core/x32/core60.bin /usr/lib/elena/core/x32/core60_lnx.bin libc.so.6 + + -1 + @@ -25,6 +27,25 @@ libc.so.6 + + -1 + + + + + + + + + /usr/local/lib/elena/core/amd64/core60.bin + /usr/local/lib/elena/core/amd64/core60_lnx.bin + + + libc.so.7 + + + -1 + @@ -38,6 +59,9 @@ libc.so.6 + + -1 + @@ -51,5 +75,8 @@ libc.so.6 + + -1 + \ No newline at end of file diff --git a/bin/elenart60.config b/bin/elenart60.config index d80ea0f0a7..88c4151c8d 100644 --- a/bin/elenart60.config +++ b/bin/elenart60.config @@ -19,4 +19,9 @@ /usr/lib/elena/lib60_64 + + + /usr/local/lib/elena/lib60_64 + + diff --git a/bin/elenavm60.cfg b/bin/elenavm60.cfg index a0d2350c73..e979abde95 100644 --- a/bin/elenavm60.cfg +++ b/bin/elenavm60.cfg @@ -1,7 +1,6 @@ - x32\core60.bin x32\core60_win.bin diff --git a/bin/local.elc60.config b/bin/local.elc60.config index 4bb31f396c..0ecbb1247d 100644 --- a/bin/local.elc60.config +++ b/bin/local.elc60.config @@ -6,12 +6,14 @@ - x32/core60.bin x32/core60_lnx.bin libc.so.6 + + -1 + @@ -25,6 +27,25 @@ libc.so.6 + + -1 + + + + + + + + + amd64/core60.bin + amd64/core60_lnx.bin + + + libc.so.7 + + + -1 + @@ -38,6 +59,9 @@ libc.so.6 + + -1 + @@ -51,5 +75,8 @@ libc.so.6 + + -1 + \ No newline at end of file diff --git a/bin/scripts/grammar60.es b/bin/scripts/grammar60.es index 74fb318083..9866e6ecff 100644 --- a/bin/scripts/grammar60.es +++ b/bin/scripts/grammar60.es @@ -128,9 +128,12 @@ ) =>; - #define statement ::= "expression" "(" root_expr ")"; + #define statement ::= statement_expr; + #define statement ::= for_looping; #define statement ::= ret_expression; + #define statement_expr ::= "expression" "(" root_expr ")"; + #define root_expr ::= expression; #define root_expr ::= "assign_operation" "(" variable ")"; #define root_expr ::= "assign_operation" "(" assigning ")"; @@ -138,7 +141,8 @@ #define root_expr ::= looping; #define branching ::= "branch_operation" "(" branch_op ")"; - #define looping ::= "loop_expression" "(" "if_operation" "(" loop_op ")" ")"; + #define looping ::= "loop_expression" "(" "if_operation" "(" loop_op ")" ")"; + #define for_looping ::= "virtual_for_loop" "(" for_loop_op ")"; #define expression ::= "expression" "(" expression ")"; #define expression ::= "message_operation" "(" call_expression ")"; @@ -148,7 +152,10 @@ #define expression ::= "mul_operation" "(" mul_expression ")"; #define expression ::= "div_operation" "(" div_expression ")"; #define expression ::= "equal_operation" "(" equal_expression ")"; + #define expression ::= "not_equal_operation" "(" not_equal_expression ")"; #define expression ::= "less_operation" "(" less_expression ")"; + #define expression ::= "greater_operation" "(" greater_expression ")"; + #define expression ::= "at_operation" "(" at_expression ")"; #define expression ::= object_expr; #define branch_op ::= @@ -169,6 +176,15 @@ ) =>; + #define for_loop_op ::= +<= + system'dynamic'expressions'ForLoopExpression ( +=> + statement_expr expression statement_expr closure_body +<= + ) +=>; + #define closure_body ::= "expression" "(" "closure" "(" body ")" ")"; #define variable ::= @@ -234,6 +250,18 @@ ) =>; + #define at_expression ::= +<= + system'dynamic'expressions'MessageCallExpression ( +=> + expression at_operation +<= + ) +=>; + + #define at_operation ::= + <= "at" => expression; + #define add_expression ::= <= system'dynamic'expressions'MessageCallExpression ( @@ -294,6 +322,18 @@ #define equal_operation ::= <= "equal" => expression; + #define not_equal_expression ::= +<= + system'dynamic'expressions'MessageCallExpression ( +=> + expression not_equal_operation +<= + ) +=>; + + #define not_equal_operation ::= + <= "notequal" => expression; + #define less_expression ::= <= system'dynamic'expressions'MessageCallExpression ( @@ -306,6 +346,18 @@ #define less_operation ::= <= "less" => expression; + #define greater_expression ::= +<= + system'dynamic'expressions'MessageCallExpression ( +=> + expression greater_operation +<= + ) +=>; + + #define greater_operation ::= + <= "greater" => expression; + #define object_expr ::= "object" "(" object ")"; #define object_expr ::= diff --git a/bin/scripts/lscript60.es b/bin/scripts/lscript60.es index aec2248df4..4f0d0fb98d 100644 --- a/bin/scripts/lscript60.es +++ b/bin/scripts/lscript60.es @@ -70,11 +70,14 @@ #define method ::= <= get_method ( => name ret_statement ";" <= ) =>; #define method ::= <= script_method ( => name f_parameters body <= ) =>; + #define var_statement ::= "var" decl_variable; + #define statement ::= expression; #define statement ::= ret_expr; - #define statement ::= "var" decl_variable; + #define statement ::= var_statement; #define statement ::= branching; #define statement ::= looping; + #define statement ::= for_looping; #define statement ::= assign_expr; #define decl_variable ::= <= expression ( assign_operation ( => new_variable ":=" expression <= ) ) =>; @@ -110,6 +113,29 @@ ) =>; + #define for_looping ::= +<= + virtual_for_loop + ( +=> + "for" "(" var_statement ";" expression ";" step_expr ")" code_brackets +<= + ) +=>; + + #define step_expr ::= <= expression ( => l5 <= ) =>; + #define step_expr ::= +<= + expression + ( + assign_operation ( +=> + variable ":=" expression +<= + ) + ) +=>; + #define assign_expr ::= <= expression @@ -141,16 +167,18 @@ #define l4_expression ::= <= expression ( => l4 <= ) =>; - #define l5 ::= $ object l1_operation* l2_operation* l3_operation* l4_operation* l5_operation?; + #define l5 ::= $ object l0_operation* l1_operation* l2_operation* l3_operation* l4_operation* l5_operation?; - #define l4 ::= $ object l1_operation* l2_operation* l3_operation* l4_operation*; + #define l4 ::= $ object l0_operation* l1_operation* l2_operation* l3_operation* l4_operation*; - #define l3 ::= $ object l1_operation* l2_operation* l3_operation*; + #define l3 ::= $ object l0_operation* l1_operation* l2_operation* l3_operation*; - #define l2 ::= $ object l1_operation* l2_operation*; + #define l2 ::= $ object l0_operation* l1_operation* l2_operation*; #define new_operation ::= <= message_operation ( => "new" new_terminal args <= ) =>; + #define l0_operation ::= ^ <= at_operation ( => "[" expression "]" <= ) =>; + #define l1_operation ::= function_call; #define l2_operation ::= "." message mssg_call; @@ -163,7 +191,9 @@ #define l4_operation ::= ^ <= sub_operation ( => "-" l3_expression <= ) =>; #define l5_operation ::= ^ <= equal_operation ( => "==" l4_expression <= ) =>; + #define l5_operation ::= ^ <= not_equal_operation ( => "!=" l4_expression <= ) =>; #define l5_operation ::= ^ <= less_operation ( => "<" l4_expression <= ) =>; + #define l5_operation ::= ^ <= greater_operation ( => ">" l4_expression <= ) =>; #define mssg_call ::= ^ <= message_operation ( => args <= ) =>; #define prop_call ::= ^ <= property_operation ( => not_bracket <= ) =>; @@ -172,7 +202,6 @@ #define args ::= "(" ")"; #define args ::= "(" arg next_arg* ")"; - #define args ::= ":" s_expression; #define arg ::= expression; #define next_arg ::= "," arg; @@ -222,6 +251,7 @@ #define parameter ::= <= parameter ( nameattr ( identifier = $identifier )) =>; #define message ::= <= message ( identifier = $identifier ) =>; + #define at_message ::= <= message ( identifier = => at_str <= ) =>; #define name ::= <= nameattr ( identifier = $identifier ) =>; #define s_name ::= <= nameattr ( identifier = $identifier ) =>; @@ -233,4 +263,5 @@ #define integer ::= <= integer = $numeric =>; #define literal ::= <= literal = "$literal" =>; #define character ::= <= character = $character =>; + #define at_str ::= <= at =>; ]] \ No newline at end of file diff --git a/bin/templates/lib60.config b/bin/templates/lib60.config index d6cd268604..e26179a0aa 100644 --- a/bin/templates/lib60.config +++ b/bin/templates/lib60.config @@ -9,6 +9,11 @@ /usr/lib/elena/lib60_64 + + + /usr/local/lib/elena/lib60_64 + + /usr/lib/elena/lib60_64 diff --git a/bin/templates/lnx_console60.config b/bin/templates/lnx_console60.config index 7d708677e1..fbb31e9d14 100644 --- a/bin/templates/lnx_console60.config +++ b/bin/templates/lnx_console60.config @@ -9,6 +9,11 @@ /usr/lib/elena/libelenart60_64.so + + + /usr/local/lib/elena/libelenart60_64.so + + /usr/lib/elena/libelenart60_64.so diff --git a/bin/templates/local.lib60.config b/bin/templates/local.lib60.config index daca90e1e1..356c33b398 100644 --- a/bin/templates/local.lib60.config +++ b/bin/templates/local.lib60.config @@ -9,6 +9,11 @@ ../../lib60_64 + + + ../../lib60_64 + + ../../lib60_64 diff --git a/bin/templates/local.mt_lnx_console60.config b/bin/templates/local.mt_lnx_console60.config index 24c461d5d4..df8cfa25f7 100644 --- a/bin/templates/local.mt_lnx_console60.config +++ b/bin/templates/local.mt_lnx_console60.config @@ -1,7 +1,7 @@ - ../x32/corex60.bin + ../x32/corex60_lnx.bin /usr/lib/elena/libelenart60.so diff --git a/bin/templates/mt_lnx_console60.config b/bin/templates/mt_lnx_console60.config index 9d123a25e6..ab24e13600 100644 --- a/bin/templates/mt_lnx_console60.config +++ b/bin/templates/mt_lnx_console60.config @@ -1,7 +1,7 @@ - /usr/lib/elena/core/x32/corex60.bin + /usr/lib/elena/core/x32/corex60_lnx.bin /usr/lib/elena/libelenart60.so diff --git a/bin/templates/mt_win_console60.cfg b/bin/templates/mt_win_console60.cfg index 6b3d04c9b2..b78169c775 100644 --- a/bin/templates/mt_win_console60.cfg +++ b/bin/templates/mt_win_console60.cfg @@ -1,7 +1,6 @@ - ..\x32\corex60.bin ..\x32\corex60_win.bin diff --git a/build/create_package_x64.bat b/build/create_package_x64.bat deleted file mode 100644 index 458b31341e..0000000000 --- a/build/create_package_x64.bat +++ /dev/null @@ -1,99 +0,0 @@ -@echo off - -ECHO =========== Compiling ELENA files ================== - -md %~dp0\x64 -md %~dp0\x64\bin -md %~dp0\x64\bin\templates -md %~dp0\x64\bin\scripts -md %~dp0\x64\bin\amd64 -md %~dp0\x64\doc -md %~dp0\x64\examples60 - -copy %~dp0\..\bin\asm64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\elena64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\elena64-ide.exe %~dp0\x64\bin -copy %~dp0\..\bin\sg64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\og64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\ecv64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\elenart60_64.dll %~dp0\x64\bin -copy %~dp0\..\bin\winstub.ex_ %~dp0\x64\bin -copy %~dp0\..\bin\elc60.cfg %~dp0\x64\bin -copy %~dp0\..\bin\elenart60.cfg %~dp0\x64\bin -copy %~dp0\..\bin\elenavm60.cfg %~dp0\x64\bin - -copy %~dp0\..\bin\amd64\core60.bin %~dp0\x64\bin\amd64 -copy %~dp0\..\bin\amd64\core60_win.bin %~dp0\x64\bin\amd64 -copy %~dp0\..\bin\amd64\corex60.bin %~dp0\x64\bin\amd64 -copy %~dp0\..\bin\amd64\core60_win_client.bin %~dp0\x64\bin\amd64 - -copy %~dp0\..\bin\templates\*.cfg %~dp0\x64\bin\templates\ -copy %~dp0\..\bin\scripts\*.es %~dp0\x64\bin\scripts\ - -copy %~dp0\..\doc\license %~dp0\x64\doc\ -copy %~dp0\..\doc\contributors %~dp0\x64\doc\ -copy %~dp0\..\readme.md %~dp0\x64\ -copy %~dp0\..\CHANGELOG.md %~dp0\x64\ -copy %~dp0\..\VERSION %~dp0\x64\ - -md %~dp0\x64\src60 -xcopy %~dp0\..\src60\*.l %~dp0\x64\src60\ /s -xcopy %~dp0\..\src60\*.prj %~dp0\x64\src60\ /s - -copy %~dp0\..\src60\elena_api.prjcol %~dp0\x64\src60\ - -%~dp0\..\bin\sg64-cli.exe %~dp0\..\dat\sg\syntax60.txt -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -move %~dp0..\dat\sg\syntax60.dat %~dp0\x64\bin\ - -%~dp0\..\bin\og64-cli %~dp0\..\dat\og\bc_rules60.txt -%~dp0\..\bin\og64-cli -s %~dp0\..\dat\og\bt_rules60.txt - -move %~dp0..\dat\og\bt_rules60.dat %~dp0\x64\bin\ -move %~dp0..\dat\og\bc_rules60.dat %~dp0\x64\bin\ - -md %~dp0\lib60_64 - -%~dp0\..\bin\asm64-cli -bc64 %~dp0\..\src60\core\system.core_routines.esm %~dp0\x64\lib60_64 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm64-cli -bc64 %~dp0\..\src60\core\system.win_core_routines.esm %~dp0\x64\lib60_64 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\x64\bin\elena64-cli %~dp0x64\src60\elena_api.prjcol -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm64-cli -amd64 %~dp0\..\asm\amd64\core60.asm bin\amd64 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm64-cli -amd64 %~dp0\..\asm\amd64\core60_win.asm bin\amd64 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -xcopy %~dp0\..\examples60\*.l %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.prj %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.txt %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.bmp %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.es %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.js %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.ls %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.xs %~dp0\x64\examples60\ /s - -goto:eof -::ERRORS -::--------------------- -:CompilerError -echo The MSBuild returns error %ERRORLEVEL% -goto:eof diff --git a/build/create_package_x86.bat b/build/create_package_x86.bat deleted file mode 100644 index 08bd69e19e..0000000000 --- a/build/create_package_x86.bat +++ /dev/null @@ -1,120 +0,0 @@ -@echo off - -ECHO =========== Compiling ELENA files ================== - -md %~dp0\x86 -md %~dp0\x86\bin -md %~dp0\x86\bin\templates -md %~dp0\x86\bin\scripts -md %~dp0\x86\bin\x32 -md %~dp0\x86\doc -md %~dp0\x86\examples60 - -copy %~dp0\..\bin\asm-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\elena-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\elena-ide.exe %~dp0\x86\bin -copy %~dp0\..\bin\sg-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\og-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\ecv-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\elt-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\elenart60.dll %~dp0\x86\bin -copy %~dp0\..\bin\elenasm60.dll %~dp0\x86\bin -copy %~dp0\..\bin\elenavm60.dll %~dp0\x86\bin -copy %~dp0\..\bin\winstub.ex_ %~dp0\x86\bin -copy %~dp0\..\bin\elc60.cfg %~dp0\x86\bin -copy %~dp0\..\bin\elenart60.cfg %~dp0\x86\bin -copy %~dp0\..\bin\elenavm60.cfg %~dp0\x86\bin -copy %~dp0\..\bin\elt60.es %~dp0\x86\bin -copy %~dp0\..\bin\command60.es %~dp0\x86\bin - -copy %~dp0\..\bin\x86\core60.bin %~dp0\x86\bin\x86\ -copy %~dp0\..\bin\x86\core60_win.bin %~dp0\x86\bin\x86\ -copy %~dp0\..\bin\x86\core60_win_client.bin %~dp0\x86\bin\x86\ -copy %~dp0\..\bin\x86\corex60.bin %~dp0\x86\bin\x86\ -copy %~dp0\..\bin\x86\corex60_win.bin %~dp0\x86\bin\x86\ - -copy %~dp0\..\bin\templates\*.cfg %~dp0\x86\bin\templates\ -copy %~dp0\..\bin\scripts\*.es %~dp0\x86\bin\scripts\ - -copy %~dp0\..\doc\license %~dp0\x86\doc\ -copy %~dp0\..\doc\contributors %~dp0\x86\doc\ -copy %~dp0\..\readme.md %~dp0\x86\ -copy %~dp0\..\CHANGELOG.md %~dp0\x86\ -copy %~dp0\..\VERSION %~dp0\x86\ - -md %~dp0\x86\src60 -xcopy %~dp0\..\src60\*.l %~dp0\x86\src60\ /s -xcopy %~dp0\..\src60\*.prj %~dp0\x86\src60\ /s - -copy %~dp0\..\src60\elena_api.prjcol %~dp0\x86\src60\ - -%~dp0\..\bin\sg-cli.exe %~dp0\..\dat\sg\syntax60.txt -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -move %~dp0..\dat\sg\syntax60.dat %~dp0\x86\bin\ - -%~dp0\..\bin\og-cli %~dp0\..\dat\og\bc_rules60.txt -%~dp0\..\bin\og-cli -s %~dp0\..\dat\og\bt_rules60.txt - -move %~dp0..\dat\og\bt_rules60.dat %~dp0\x86\bin\ -move %~dp0..\dat\og\bc_rules60.dat %~dp0\x86\bin\ - -md %~dp0\lib60 - -%~dp0\..\bin\asm-cli -bc32 %~dp0\..\src60\core\system.core_routines.esm %~dp0\x86\lib60 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -bc32 %~dp0\..\src60\core\system.win_core_routines.esm %~dp0\x86\lib60 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\x86\bin\elena-cli %~dp0x86\src60\elena_api.prjcol -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\core60.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\core60_win.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\corex60_win.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\corex60.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\core60_win_client.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -xcopy %~dp0\..\examples60\*.l %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.prj %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.txt %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.bmp %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.es %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.js %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.ls %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.xs %~dp0\x86\examples60\ /s - -goto:eof -::ERRORS -::--------------------- -:CompilerError -echo The MSBuild returns error %ERRORLEVEL% -goto:eof diff --git a/build/rebuild_data60_x64.bat b/build/rebuild_data60_x64.bat deleted file mode 100644 index cbc329c444..0000000000 --- a/build/rebuild_data60_x64.bat +++ /dev/null @@ -1,53 +0,0 @@ -REM NOTE : the script MUST be called from the root folder - -bin\sg64-cli dat\sg\syntax60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -move dat\sg\syntax60.dat bin - -bin\sg64-cli dat\sg\syntax50.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -move dat\sg\syntax50.dat bin - -bin\og64-cli dat\og\bc_rules60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on -move dat\og\bc_rules60.dat bin - -bin\og64-cli -s dat\og\bt_rules60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on -move dat\og\bt_rules60.dat bin - -@echo off -echo === Done === -@echo on - -@echo off -goto:eof -@echo on - -:Asm2BinError -echo ASM2BINX returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on - -:CompilerError -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on - -:TestError -echo System tests fail %ERRORLEVEL% -@echo off -goto:eof -@echo on diff --git a/build/rebuild_data60_x86.bat b/build/rebuild_data60_x86.bat deleted file mode 100644 index 961552a4b8..0000000000 --- a/build/rebuild_data60_x86.bat +++ /dev/null @@ -1,53 +0,0 @@ -REM NOTE : the script MUST be called from the root folder - -.\bin\sg-cli dat\sg\syntax60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -move dat\sg\syntax60.dat bin - -.\bin\sg-cli dat\sg\syntax50.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -move dat\sg\syntax50.dat bin - -bin\og-cli dat\og\bc_rules60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on -move dat\og\bc_rules60.dat bin - -bin\og-cli -s dat\og\bt_rules60.txt -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on -move dat\og\bt_rules60.dat bin - -@echo off -echo === Done === -@echo on - -@echo off -goto:eof -@echo on - -:Asm2BinError -echo ASM2BINX returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on - -:CompilerError -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on - -:TestError -echo System tests fail %ERRORLEVEL% -@echo off -goto:eof -@echo on \ No newline at end of file diff --git a/build/rebuild_lib60_x64.bat b/build/rebuild_lib60_x64.bat deleted file mode 100644 index fe8ddd239c..0000000000 --- a/build/rebuild_lib60_x64.bat +++ /dev/null @@ -1,81 +0,0 @@ -REM NOTE : the script MUST be called from the root folder - -bin\asm64-cli -amd64 asm\amd64\core60.asm bin\amd64 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm64-cli -amd64 asm\amd64\core60_win.asm bin\amd64 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm64-cli -amd64 asm\amd64\corex60.asm bin\amd64 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm64-cli -amd64 asm\amd64\corex60_win.asm bin\amd64 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm64-cli -amd64 asm\amd64\core60_win_client.asm bin\amd64 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm64-cli -bc64 src60\core\system.core_routines.esm lib60_64 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm64-cli -bc64 src60\core\system.win_core_routines.esm lib60_64 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\elena64-cli src60\elena_api.prjcol -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -bin\elena64-cli tests60\system_tests\system_tests.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -echo system api test for amd64 -copy bin\elenart60_64.dll tests60\system_tests\ -copy bin\elenasm60_64.dll tests60\system_tests\ - -tests60\system_tests\system_tests64.exe -@echo off -if %ERRORLEVEL% NEQ 0 GOTO TestError -@echo on - -@echo off -echo === Done === -@echo on - -@echo off -goto:eof -@echo on - -:Asm2BinError -echo ASM2BINX returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on - -:CompilerError -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on - -:TestError -echo System tests fail %ERRORLEVEL% -@echo off -goto:eof -@echo on diff --git a/build/rebuild_lib60_x86.bat b/build/rebuild_lib60_x86.bat deleted file mode 100644 index 9da306d99f..0000000000 --- a/build/rebuild_lib60_x86.bat +++ /dev/null @@ -1,116 +0,0 @@ -REM NOTE : the script MUST be called from the root folder - -bin\asm-cli -x86 asm\x32\core60.asm bin\x32 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm-cli -x86 asm\x32\corex60.asm bin\x32 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm-cli -x86 asm\x32\core60_win.asm bin\x32 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm-cli -x86 asm\x32\corex60_win.asm bin\x32 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm-cli -x86 asm\x32\core60_win_client.asm bin\x32 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm-cli -bc32 src60\core\system.core_routines.esm lib60 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm-cli -bc32 src60\core\system.win_core_routines.esm lib60 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\elena-cli src60\elena_api.prjcol -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -bin\ldoc system doc\api -bin\ldoc system'collections'threadsafe doc\api -bin\ldoc system'routines doc\api -bin\ldoc system'runtime doc\api -bin\ldoc system'threading doc\api -bin\ldoc system'dynamic doc\api -bin\ldoc system'drawing doc\api -bin\ldoc system'winforms doc\api -bin\ldoc system'net doc\api -bin\ldoc extensions doc\api -bin\ldoc extensions'routines doc\api -bin\ldoc extensions'scripting doc\api -bin\ldoc extensions'dynamic doc\api -bin\ldoc extensions'io doc\api -bin\ldoc cellular doc\api -bin\ldoc algorithms doc\api -bin\ldoc sqlite doc\api -bin\ldoc forms doc\api -bin\ldoc ltests doc\api -bin\ldoc net doc\api - -bin\elena-cli tests60\system_tests\system_tests.prj -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -echo system api test for x86 -copy bin\elenart60.dll tests60\system_tests\ -copy bin\elenasm60.dll tests60\system_tests\ - -tests60\system_tests\system_tests.exe -@echo off -if %ERRORLEVEL% NEQ 0 GOTO TestError -@echo on - -REM bin\elena-cli tests60\script_tests\script_tests.prj -REM @echo off -REM if %ERRORLEVEL% EQU -2 GOTO CompilerError -REM @echo on - -REM echo system api test for x86 -REM copy bin\elenart60.dll tests60\script_tests\ -REM copy bin\elenasm60.dll tests60\script_tests\ - -REM tests60\script_tests\script_tests.exe -REM @echo off -REM if %ERRORLEVEL% NEQ 0 GOTO TestError -REM @echo on - -@echo off -echo === Done === -@echo on - -@echo off -goto:eof -@echo on - -:Asm2BinError -echo ASM2BINX returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on - -:CompilerError -echo ELC returns error %ERRORLEVEL% -@echo off -goto:eof -@echo on - -:TestError -echo System tests fail %ERRORLEVEL% -@echo off -goto:eof -@echo on \ No newline at end of file diff --git a/dat/api2html/api2html.bat b/dat/api2html/api2html.bat index a44736647d..998222a00c 100644 --- a/dat/api2html/api2html.bat +++ b/dat/api2html/api2html.bat @@ -1,31 +1,31 @@ -..\..\bin\ldoc system -..\..\bin\ldoc system'collections'threadsafe -..\..\bin\ldoc system'routines -..\..\bin\ldoc system'routines'stex -..\..\bin\ldoc system'runtime -..\..\bin\ldoc system'threading -..\..\bin\ldoc system'io'threading -..\..\bin\ldoc system'dynamic -..\..\bin\ldoc system'drawing -..\..\bin\ldoc system'winforms -..\..\bin\ldoc system'net -..\..\bin\ldoc system'text'parsing -..\..\bin\ldoc extensions -..\..\bin\ldoc extensions'routines -..\..\bin\ldoc extensions'runtime -..\..\bin\ldoc extensions'routines'stex -..\..\bin\ldoc extensions'scripting -..\..\bin\ldoc extensions'dynamic -..\..\bin\ldoc extensions'threading -..\..\bin\ldoc extensions'io -..\..\bin\ldoc cellular -..\..\bin\ldoc algorithms -..\..\bin\ldoc sqlite -..\..\bin\ldoc forms -..\..\bin\ldoc ltests -..\..\bin\ldoc net -..\..\bin\ldoc net'http -..\..\bin\ldoc net'server -..\..\bin\ldoc xforms - -copy *.html ..\..\doc\api +bin\ldoc system doc\api +bin\ldoc system'collections'threadsafe doc\api +bin\ldoc system'routines doc\api +bin\ldoc system'routines'stex doc\api +bin\ldoc system'runtime doc\api +bin\ldoc system'threading doc\api +bin\ldoc system'io'threading doc\api +bin\ldoc system'dynamic doc\api +bin\ldoc system'drawing doc\api +bin\ldoc system'winforms doc\api +bin\ldoc system'net doc\api +bin\ldoc system'text'parsing doc\api +bin\ldoc extensions doc\api +bin\ldoc extensions'routines doc\api +bin\ldoc extensions'runtime doc\api +bin\ldoc extensions'routines'stex doc\api +bin\ldoc extensions'scripting doc\api +bin\ldoc extensions'dynamic doc\api +bin\ldoc extensions'threading doc\api +bin\ldoc extensions'io doc\api +bin\ldoc cellular doc\api +bin\ldoc algorithms doc\api +bin\ldoc sqlite doc\api +bin\ldoc forms doc\api +bin\ldoc ltests doc\api +bin\ldoc net doc\api +bin\ldoc net'http doc\api +bin\ldoc net'server doc\api +bin\ldoc textgen doc\api +bin\ldoc xforms doc\api +bin\ldoc xml doc\api diff --git a/dat/og/bt_rules60.txt b/dat/og/bt_rules60.txt index 64d8db7c5e..df9acc05fc 100644 --- a/dat/og/bt_rules60.txt +++ b/dat/og/bt_rules60.txt @@ -2,6 +2,7 @@ breakpoint, breakpoint => 1; byrefmark => 2; int_literal, copying => 3; local_address, saving_stack, int_literal, saving_stack =1, intop => 4; +local_address, saving_stack, int_literal, saving_stack =1, byteop => 4; int_literal, saving_stack =0, intop => 5; copying, addingint, local_address, copying => 15; saving_index, addingint, local_address, copying => 15; diff --git a/dat/sg/syntax60.txt b/dat/sg/syntax60.txt index 0e696fb46a..5c88e49c42 100644 --- a/dat/sg/syntax60.txt +++ b/dat/sg/syntax60.txt @@ -22,7 +22,11 @@ __define END_OF_BLOCK 4107; __define DICTIONARY 4128; __define META_STATEMENT 4129; __define INCLUDE_STATEMENT 4130; +__define IMPORT_STATEMENT 4131; +__define COND_STATEMENT 4132; __define SHARED_DICTIONARY 4133; +__define ENDCOND_STATEMENT 4134; +__define ELSE_COND_STATEMENT 4135; __define OBJECT 4145; __define TEMPLATE_TYPE 4146; __define ARRAY_TYPE 4147; @@ -141,7 +145,11 @@ META_DECLARATION ::= "#new" DICTIONARY DECLARATION_END | "#share" SHARED_DICTIONARY DECLARATION_END | "#let" META_STATEMENT DECLARATION_END - | "#include" INCLUDE_STATEMENT DECLARATION_END; + | "#include" INCLUDE_STATEMENT DECLARATION_END + | "#import" IMPORT_STATEMENT DECLARATION_END + | "#if" COND_STATEMENT + | "#elif" ELSE_COND_STATEMENT + | ENDCOND_STATEMENT; DECLARATION ::= { identifier | reference }+ IR_DECLARATION @@ -199,6 +207,7 @@ NO_BODY ::= BLOCK ::= STATEMENT NEXT_STATEMENT + | "#if" COND_STATEMENT STATEMENT NEXT_STATEMENT | "^" RET_EXPRESSION LAST_STATEMENT | END_OF_BLOCK; @@ -208,11 +217,15 @@ STATEMENT ::= | "#let" META_STATEMENT | "#new" DICTIONARY | "#share" SHARED_DICTIONARY + | "#import" IMPORT_STATEMENT | "{" BLOCK; NEXT_STATEMENT ::= DECLARATION_END { STATEMENT NEXT_STATEMENT + | "#if" COND_STATEMENT STATEMENT NEXT_STATEMENT + | "#elif" ELSE_COND_STATEMENT STATEMENT NEXT_STATEMENT + | ENDCOND_STATEMENT { STATEMENT NEXT_STATEMENT | "^" RET_EXPRESSION LAST_STATEMENT | END_OF_BLOCK } | "^" RET_EXPRESSION LAST_STATEMENT | END_OF_BLOCK } @@ -279,7 +292,7 @@ ROOT_EXPRESSION ::= | L1a_OOP | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { BRACKET FUNCTION_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? - | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? + | "{" ^OBJECT COLLECTION? "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? | identifier ^OBJECT ASSIGN ASSIGN_R } | BRACKET ^OBJECT { @@ -368,7 +381,7 @@ NESTED_ROOT_EXPRESSION ::= | L1a_OOP | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { BRACKET FUNCTION_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? - | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? + | "{" ^OBJECT COLLECTION? "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? | identifier ^OBJECT ASSIGN ASSIGN_R } | BRACKET ^OBJECT MESSAGE_PARAMETERS? ")" { @@ -447,9 +460,9 @@ NESTED_ROOT_EXPRESSION ::= EXPRESSION ::= identifier { identifier+ { - | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { + { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { BRACKET ^OBJECT FUNCTION_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? - | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? + | "{" ^OBJECT COLLECTION? "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? } | "::" ^^OBJECT ^^EXPRESSION TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK | ":" ^^OBJECT ^^EXPRESSION SINGLE_EXPRESSION ^ TEMPLATE_EXPR_BLOCK @@ -481,6 +494,7 @@ EXPRESSION ::= | L7_OOP L7_OP* L8_OP? L9_OP? | L8_OOP | L9_OOP + | eps ^OBJECT } | "{" NESTED_EXPRESSION ^NESTED L_F | eps ^OBJECT @@ -499,7 +513,7 @@ EXPRESSION ::= } | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { BRACKET FUNCTION_R L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? - | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? + | "{" ^OBJECT COLLECTION? "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? | identifier ^OBJECT { ASSIGN ASSIGN_R }? } | "::=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION @@ -540,6 +554,7 @@ EXPRESSION ::= | L7_OOP L7_OP* L8_OP? L9_OP? | L8_OOP | L9_OOP + | eps ^OBJECT } | "{" NESTED_EXPRESSION ^NESTED L_F } @@ -555,20 +570,12 @@ EXPRESSION ::= | "$value" SINGLE_EXPRESSION ^EXPRVAL_OPERATION | "$reference" SINGLE_EXPRESSION ^REFER_OPERATION | "$len" SINGLE_EXPRESSION ^LEN_OPERATION - | "$size" SINGLE_EXPRESSION ^SIZE_OPERATION + | "$size" SINGLE_EXPRESSION ^SIZE_OPERATION L4_OP* L5_OP* L6_OP? L7_OP* | "$await" EXPRESSION ^ASYNC_OPERATION | "{" BLOCK ^CLOSURE L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? | BRACKET SUB_EXPRESSION { - L2_OP+ L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? - | L3_OP+ L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? - | L4_OP+ L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? - | L5_OP+ L6_OP? L7_OP* L8_OP? L9_OP? - | L6_OP L7_OP* L8_OP? L9_OP? - | L7_OP+ L8_OP? L9_OP? - | L8_OP - | L9_OP - | ASSIGN ^TUPLE_BLOCK EXPRESSION ^TUPLE_ASSIGNING - | eps + ASSIGN ^TUPLE_BLOCK EXPRESSION ^TUPLE_ASSIGNING + | L_F } | "$lazy" EXPRESSION ^LAZY_OPERATION | ":" identifier L3_EXPRESSION? ^OPERATION_TEMPLATE; @@ -654,11 +661,11 @@ INTERPOL_EXPRESSION ::= SUB_EXPRESSION ::= identifier { identifier+ { - SBRACKET ^OBJECT INDEXER_R L0_OP* L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? ")" + SBRACKET ^OBJECT INDEXER_R L_F TUPLE_R? ")" | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { identifier ")" "{" ^ PARAMETER_BLOCK BLOCK ^CLOSURE ^EXPRESSION | L2_OOP L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* - | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* } ")" + | "{" ^OBJECT COLLECTION? "}" ^ COLLECTION_EXPRESSION L3_OP* } ")" | "::" ^^OBJECT ^^EXPRESSION TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^EXPRESSION ")" | ":" ^^OBJECT ^^EXPRESSION SINGLE_EXPRESSION ^ TEMPLATE_EXPR_BLOCK ^EXPRESSION ")" | L2_OOP L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? ")" @@ -718,7 +725,7 @@ SUB_EXPRESSION ::= | TUPLE_OR ")" | ")" ^OBJECT } - | SBRACKET ^OBJECT INDEXER_R L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? ")" + | SBRACKET ^OBJECT INDEXER_R L_F TUPLE_R? ")" | L2_OOP L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? ")" | DOT ^OBJECT MESSAGE { L3_F | eps ^PROPERTY_OPERATION } TUPLE_R? ")" | IF_DOT ^OBJECT MESSAGE? CALL_R ^IF_OPERATION ^OPERATION_TEMPLATE ^EXPRESSION OL_F TUPLE_R? ")" @@ -766,7 +773,7 @@ SUB_EXPRESSION ::= | ")" "{" ^ PARAMETER_BLOCK BLOCK ^CLOSURE ^EXPRESSION } | ":" identifier L3_EXPRESSION? ^OPERATION_TEMPLATE ")" - | BRACKET SUB_EXPRESSION SUB_L_F ")"; + | BRACKET SUB_EXPRESSION SUB_L_F2 ")"; SUB_SINGLE_EXPRESSION ::= identifier { @@ -1060,6 +1067,23 @@ SUB_L_F ::= | TUPLE_OR | eps; +SUB_L_F2 ::= + L0_OP+ L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? + | L2_OP+ L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? + | L3_OP+ L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? + | L4_OP+ L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? + | L5_OP+ L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? + | L6_OP L7_OP* L8_OP? L9_OP? TUPLE_R? + | L7_OP+ L8_OP? L9_OP? TUPLE_R? + | L8_OP TUPLE_R? + | L9_OP TUPLE_R? + | identifier { + "::" ^^EXPRESSION TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^ EXPRESSION + | ":" ^^EXPRESSION SINGLE_EXPRESSION ^ TEMPLATE_EXPR_BLOCK ^ EXPRESSION + } TUPLE_R? + | TUPLE_OR + | eps; + OL_F ::= L3_OP+ L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? | L4_OP+ L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? @@ -1317,6 +1341,18 @@ RESEND_R ::= INCLUDE_STATEMENT ::= { identifier | reference }+ ^ OBJECT; +IMPORT_STATEMENT ::= + { identifier | reference }+ ^ OBJECT "=" EXPRESSION; + +COND_STATEMENT ::= + "(" EXPRESSION ")"; + +ELSE_COND_STATEMENT ::= + "(" EXPRESSION ")"; + +ENDCOND_STATEMENT ::= + "#endif"; + COMPLEX_NAME ::= identifier; @@ -1356,9 +1392,9 @@ TEMPLATE_BRACKETS ::= "<" TEMPLATE_ARG { "," TEMPLATE_ARG }* ">"; TEMPLATE_ARG ::= - identifier { TEMPLATE_BRACKETS ^ TEMPLATE_TYPE | DYNAMIC_DIMENSION ^ARRAY_TYPE }? - | reference - | global; + identifier { TEMPLATE_BRACKETS ^ TEMPLATE_TYPE | DYNAMIC_DIMENSION ^ARRAY_TYPE }? { "?" ^NULLABLE_TYPE }? + | reference { "?" ^NULLABLE_TYPE }? + | global { "?" ^NULLABLE_TYPE }?; POSTFIXES ::= ":" POSTFIX { "," POSTFIX }*; diff --git a/doc/api/algorithms-summary.html b/doc/api/algorithms-summary.html index ce7535505f..85810f65c5 100644 --- a/doc/api/algorithms-summary.html +++ b/doc/api/algorithms-summary.html @@ -44,6 +44,15 @@

    +InsertSortAlgorithm + + +
    +public singleton InsertSortAlgorithm
    + + + + QuickSortAlgorithm diff --git a/doc/api/algorithms.html b/doc/api/algorithms.html index 003df65410..b12fd58392 100644 --- a/doc/api/algorithms.html +++ b/doc/api/algorithms.html @@ -23,6 +23,55 @@

    + + + +
    +
    +algorithms'
    +

    InsertSortAlgorithm

    +
    +
    +
    +
    +
    +
    +public singleton InsertSortAlgorithm
    +
    +
    + + + +
    +
    @@ -115,6 +164,24 @@

    Extension Summary

    + + + + + +insertSort(Func2 compf) + + + + + + + + +insertSort() + + + @@ -163,6 +230,24 @@

    Extension Summary

    + + + + + +insertSort(IntNumber length, Func2 compf) + + + + + + + + +insertSort(IntNumber length) + + + @@ -211,6 +296,24 @@

    Extension Summary

    + + + + + +insertSort(Func2 compf) + + + + + + + + +insertSort() + + + diff --git a/doc/api/extensions-runtime-summary.html b/doc/api/extensions-runtime-summary.html index bd18aa6919..abca876d4d 100644 --- a/doc/api/extensions-runtime-summary.html +++ b/doc/api/extensions-runtime-summary.html @@ -53,6 +53,26 @@

    +
  • + +
    +Extended Class Summary +
    + + + + + + + + +
    Symbol nameDescription
    +Object + +
    +public class Object
    +
    +
  • diff --git a/doc/api/extensions-runtime.html b/doc/api/extensions-runtime.html index 2ae91846cb..0eb31905f1 100644 --- a/doc/api/extensions-runtime.html +++ b/doc/api/extensions-runtime.html @@ -72,6 +72,45 @@

    Method Summary


    + + + +
    +
    +system'
    +

    Object

    +
    +
    +
    +
    +
    +
    +public class Object
    +
    +
    + +
      +
    • +

      Extension Summary

      + + + + + + + + + +
      Modifier and TypeExtension Method
      + +String +getFullPackageInfo() + +
      +
    • +
    +
    +
    @@ -71,6 +71,26 @@

    +
  • + +
    +Symbol Summary +
    + + + + + + + + +
    Symbol nameDescription
    +lscript + +
    +lscript
    +
    +
  • diff --git a/doc/api/extensions-scripting.html b/doc/api/extensions-scripting.html index 839f0a8200..6042b468ad 100644 --- a/doc/api/extensions-scripting.html +++ b/doc/api/extensions-scripting.html @@ -23,20 +23,20 @@
    - +
    extensions'scripting'
    -

    lscript

    +

    LScript



    -public singleton lscript
    +public singleton LScript
      @@ -45,7 +45,7 @@

      lscript

      • -extensions'scripting'lscript
      • +extensions'scripting'LScript
    @@ -347,6 +347,43 @@

    Constructor Summary


    + + + +
    +
    +extensions'scripting'
    +

    lscript

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public   +lscript +
      +
    • +
    +
    +
    +
    diff --git a/doc/api/forms.html b/doc/api/forms.html index b3cef8153d..92762615d7 100644 --- a/doc/api/forms.html +++ b/doc/api/forms.html @@ -129,7 +129,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1>
    onClick @@ -596,7 +596,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1>
    onResize @@ -845,7 +845,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1> onResize @@ -1228,6 +1228,15 @@

    Method Summary

    + + + + + +change() + + + @@ -1353,7 +1362,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1> onResize @@ -1526,7 +1535,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1> onClick @@ -1704,7 +1713,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1> onResize @@ -2047,6 +2056,14 @@

    Field Summary

    _handle + + + +EventHandler<system'Func1> + +onChange + + @@ -2344,6 +2361,15 @@

    Method Summary

    + + + +abstract   + +change() + + + @@ -2469,7 +2495,7 @@

    Field Summary

    -Func<system'Object,system'drawing'Canvas,system'Object> +EventHandler<system'Func<system'Object,system'drawing'Canvas,system'Object>> onPaint @@ -2767,7 +2793,7 @@

    Method Summary

    -open() +change() @@ -2776,7 +2802,7 @@

    Method Summary

    -appendImage(String path) +open() @@ -2785,6 +2811,15 @@

    Method Summary

    +appendImage(String path) + + + + + + + + close() @@ -3290,7 +3325,7 @@

    Field Summary

    -Func<system'Object,system'drawing'Canvas,system'Object> +EventHandler<system'Func<system'Object,system'drawing'Canvas,system'Object>>
    onPaint @@ -3486,7 +3521,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1>
    onResize @@ -3676,7 +3711,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1> onClick @@ -3900,7 +3935,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1> onResize @@ -3924,7 +3959,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1> onIndexChanged @@ -4302,7 +4337,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1> onResize @@ -4480,7 +4515,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1> onResize diff --git a/doc/api/index.html b/doc/api/index.html index 9f11ad7bb6..86587d97ec 100644 --- a/doc/api/index.html +++ b/doc/api/index.html @@ -694,7 +694,28 @@

  • -xforms Package +xml Package +
    + + + + + + + + +
    ModuleDescription
    +xml + +
    +Provides classes to work with XML +
    +
  • + +
  • + +
    +ltest Package
    @@ -712,6 +733,27 @@

    Module
  • +
  • + +
    +textgen Package +
    + + + + + + + + +
    ModuleDescription
    +ltests + +
    +Provides classes to generate the text output based on an object and a script +
    +
  • +

    diff --git a/doc/api/net-http-summary.html b/doc/api/net-http-summary.html index a3ebb3496d..fb5cb07020 100644 --- a/doc/api/net-http-summary.html +++ b/doc/api/net-http-summary.html @@ -44,6 +44,51 @@

    +HttpClient + + +
    +public class HttpClient
    + + + + +HttpException + + +
    +public class HttpException
    + + + + +HttpHeaders + + +
    +public class HttpHeaders
    + + + + +HttpResponse + + +
    +public class HttpResponse
    + + + + +SocketFactory + + +
    +public class SocketFactory
    + + + + Uri @@ -53,6 +98,26 @@

    +
  • + +
    +Symbol Summary +
    + + + + + + + + +
    Symbol nameDescription
    +SocketFactory#initializer$inline0 + +
    +SocketFactory#initializer$inline0
    +
    +
  • diff --git a/doc/api/net-http.html b/doc/api/net-http.html index a274d6f6ea..55424cec0a 100644 --- a/doc/api/net-http.html +++ b/doc/api/net-http.html @@ -23,6 +23,645 @@
    + + + +
    +
    +net'http'
    +

    HttpClient

    +
    +
    +
    +
    +
    +
    +public class HttpClient
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeField
      + +String +_host +
      + +HttpHeaders +_headers +
      + +INetSocket +_socket +
      +
    • +
    + +
      +
    • +

      Constructor Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +internal  HttpClient +assign(INetSocket socket, String host) + +
      +
    • +
    + + + +
      +
    • +

      Property Summary

      + + + + + + + + + +
      Modifier and TypeProperty
      + +get  HttpHeaders +Headers() +
      +
    • +
    + + +
    +
    + + + +
    +
    +net'http'
    +

    HttpException

    +
    +
    +
    +
    +
    +
    +public class HttpException
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + + + + + +
      Modifier and TypeField
      + +String +message +
      + +CallStack +callStack +
      +
    • +
    + +
      +
    • +

      Constructor Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +HttpException +new(String s) + +
      +
    • +
    +
    +
    + + + +
    +
    +net'http'
    +

    HttpHeaders

    +
    +
    +
    +
    +
    +
    +public class HttpHeaders
    +
    +
    + + + + +
      +
    • +

      Constructor Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +HttpHeaders +constructor() + +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + +
      Modifier and TypeProperty
      + +get  String +Value() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + + +add(String name, String content) + +
      + +String +at(String key) + +
      +
    • +
    +
    +
    + + + +
    +
    +net'http'
    +

    HttpResponse

    +
    +
    +
    +
    +
    +
    +public class HttpResponse
    +
    +
    + + + + +
      +
    • +

      Constructor Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +internal  HttpResponse +assign(NetworkStream stream) + +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + +internal  Task +readHeaderAsync() + +
      + +internal   +readHeader() + +
      + +Task<system'String> +readAsStringAsync() + +
      + +String +readAsString() + +
      +
    • +
    +
    +
    + + + +
    +
    +net'http'
    +

    SocketFactory

    +
    +
    +
    +
    +
    +
    +public class SocketFactory
    +
    +
    + + +
      +
    • +

      Static Method Summary

      + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +private   +function:#class_init() + +
      + + +assignHttpsFactory(INetSocketFactory factory) + +
      + + +assignHttpFactory(INetSocketFactory factory) + +
      + +INetSocket +openSocket(Uri uri) + +
      +
    • +
    +
    +
    @@ -161,18 +800,26 @@

    Property Summary

    get  String -Port() +PortValue() +get  ShortNumber + +Port() + + + + + get  String Path() - + get  String @@ -185,6 +832,43 @@

    Property Summary


    + + + +
    +
    +net'http'
    +

    SocketFactory#initializer$inline0

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Symbol Summary

      + + + + + + + +
      Modifier and TypeName
      + +public   +SocketFactory#initializer$inline0 +
      +
    • +
    +
    +
    +
    - + GetDynamicPropertyExpression @@ -186,7 +195,7 @@

    public class GetDynamicPropertyExpression - + GetPropertyExpression @@ -195,7 +204,7 @@

    public class GetPropertyExpression - + IdentifierExpression @@ -204,7 +213,7 @@

    public class IdentifierExpression - + IdleExpressionScope @@ -213,7 +222,7 @@

    public singleton IdleExpressionScope - + IfExpression @@ -222,7 +231,7 @@

    public class IfExpression - + ImportInfo @@ -231,7 +240,7 @@

    public class ImportInfo - + IntConstantExpression @@ -240,7 +249,7 @@

    public class IntConstantExpression - + LazySymbolExpression @@ -249,7 +258,7 @@

    public class LazySymbolExpression - + LoopExpression @@ -258,7 +267,7 @@

    public class LoopExpression - + MessageCallExpression @@ -267,7 +276,7 @@

    public class MessageCallExpression - + MethodExpression @@ -276,7 +285,7 @@

    public class MethodExpression - + MethodParameterList @@ -285,7 +294,7 @@

    public class MethodParameterList - + NestedExpression @@ -294,7 +303,7 @@

    public class NestedExpression - + NewExpression @@ -303,7 +312,7 @@

    public class NewExpression - + ReturnExpression @@ -312,7 +321,7 @@

    public class ReturnExpression - + RootExpressionScope @@ -321,7 +330,7 @@

    public class RootExpressionScope - + ScopeIdentifier @@ -330,7 +339,7 @@

    public class ScopeIdentifier - + SetDynamicPropertyExpression @@ -339,7 +348,7 @@

    public class SetDynamicPropertyExpression - + SetPropertyExpression @@ -348,7 +357,7 @@

    public class SetPropertyExpression - + SymbolCollection @@ -357,7 +366,7 @@

    public class SymbolCollection - + SymbolExpression @@ -366,7 +375,7 @@

    public class SymbolExpression - + SymbolInfo @@ -375,7 +384,7 @@

    public class SymbolInfo - + VariableByIndexExpression @@ -384,7 +393,7 @@

    public class VariableByIndexExpression - + VariableExpression diff --git a/doc/api/system-dynamic-expressions.html b/doc/api/system-dynamic-expressions.html index 26bb36b9ac..79deeb984d 100644 --- a/doc/api/system-dynamic-expressions.html +++ b/doc/api/system-dynamic-expressions.html @@ -1575,7 +1575,7 @@

    Static Method Summary

    Expression -VariableByIndex(IntNumber index) +ForLoop(Expression init_cond, Expression cond, Expression step, Expression body) @@ -1584,7 +1584,7 @@

    Static Method Summary

    Expression -Variable(String variable) +VariableByIndex(IntNumber index) @@ -1593,7 +1593,7 @@

    Static Method Summary

    Expression -ClassReference(String s) +Variable(String variable) @@ -1602,7 +1602,7 @@

    Static Method Summary

    Expression -ClassIdentifier(String s) +ClassReference(String s) @@ -1611,7 +1611,7 @@

    Static Method Summary

    Expression -New(Expression t) +ClassIdentifier(String s) @@ -1620,7 +1620,7 @@

    Static Method Summary

    Expression -New(Expression t, Expression p0) +New(Expression t) @@ -1629,7 +1629,7 @@

    Static Method Summary

    Expression -FunctionCall(params Expression[] arguments) +New(Expression t, Expression p0) @@ -1638,7 +1638,7 @@

    Static Method Summary

    Expression -Assigning(String variable, Expression expr) +FunctionCall(params Expression[] arguments) @@ -1647,7 +1647,7 @@

    Static Method Summary

    Expression -DeclareAndAssigning(String variable, Expression expr) +Assigning(String variable, Expression expr) @@ -1656,7 +1656,7 @@

    Static Method Summary

    Expression -Method(String name, Expression body, params ScopeIdentifier[] variables) +DeclareAndAssigning(String variable, Expression expr) @@ -1665,20 +1665,29 @@

    Static Method Summary

    Expression -ActionMethod(Expression body) +Method(String name, Expression body, params ScopeIdentifier[] variables) +Expression + +ActionMethod(Expression body) + + + + + + internal   saveMessageCallTo(List<system'dynamic'TapeFunction> list, ExpressionScope scope, Expression target, system'dynamic'expressions'Expression[] arguments, TapeFunction operation) - + internal   @@ -2169,6 +2178,133 @@

    Method Summary


    + + + +
    +
    +system'dynamic'expressions'
    +

    ForLoopExpression

    +
    +
    +
    +
    +
    +
    +public class ForLoopExpression
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeField
      + +Expression +condition +
      + +Expression +body +
      + +Expression +init_expr +
      +
    • +
    + + + + +
    +
    diff --git a/doc/api/system-io.html b/doc/api/system-io.html index ce4a285daa..d477313aec 100644 --- a/doc/api/system-io.html +++ b/doc/api/system-io.html @@ -1343,6 +1343,24 @@

    Static Method Summary

    + + + +TextWriter + +textwriter(String path) + + + + + + +TextReader + +textreader(String path) + + + @@ -2228,6 +2246,15 @@

    Constructor Summary

    + + + +MemoryStream + +load(system'ByteNumber[] array) + + + diff --git a/doc/api/system-routines-summary.html b/doc/api/system-routines-summary.html index 462e85a882..f0342d7d1e 100644 --- a/doc/api/system-routines-summary.html +++ b/doc/api/system-routines-summary.html @@ -71,6 +71,15 @@

    +CountDownEnumerator + + +
    +public class CountDownEnumerator
    + + + + Filter @@ -78,7 +87,7 @@

    public class Filter - + GroupingEnumerator @@ -87,7 +96,7 @@

    public class GroupingEnumerator - + ifDecrescent @@ -96,7 +105,7 @@

    public singleton ifDecrescent - + ifOrdered @@ -105,7 +114,7 @@

    public singleton ifOrdered - + IndexerSortingAgent @@ -114,7 +123,7 @@

    public class IndexerSortingAgent - + IntervalEnumerator @@ -123,7 +132,7 @@

    public class IntervalEnumerator - + JoinEnumerator @@ -132,7 +141,7 @@

    public class JoinEnumerator - + OrderingEnumerator @@ -141,7 +150,7 @@

    public class OrderingEnumerator - + PatternFilter2 @@ -150,7 +159,7 @@

    public class PatternFilter2 - + PatternFilter3 @@ -159,7 +168,7 @@

    public class PatternFilter3 - + PatternFilter4 @@ -168,7 +177,7 @@

    public class PatternFilter4 - + PatternFilter5 @@ -177,7 +186,7 @@

    public class PatternFilter5 - + PatternFilter6 @@ -186,7 +195,7 @@

    public class PatternFilter6 - + QuickSorting @@ -195,7 +204,7 @@

    public singleton QuickSorting - + RangeEnumerator @@ -204,7 +213,7 @@

    public class RangeEnumerator - + Repeater @@ -213,7 +222,7 @@

    public class Repeater - + Selector @@ -222,7 +231,7 @@

    public class Selector - + SkipFilter @@ -231,7 +240,7 @@

    public class SkipFilter - + SortingAgent @@ -240,7 +249,7 @@

    abstract public class SortingAgent - + Summing @@ -249,7 +258,7 @@

    public class Summing - + TopFilter @@ -258,7 +267,7 @@

    public class TopFilter - + ZipEnumerator diff --git a/doc/api/system-routines.html b/doc/api/system-routines.html index 1e70d07f20..ed876a5a3f 100644 --- a/doc/api/system-routines.html +++ b/doc/api/system-routines.html @@ -265,6 +265,15 @@

    Method Summary

    + + + + + +move(IntNumber i, IntNumber j) + + + @@ -339,6 +348,170 @@

    Method Summary


    + + + +
    +
    +system'routines'
    +

    CountDownEnumerator

    +
    +
    +
    +
    +
    +
    +public class CountDownEnumerator
    +
    +
    + + + + +
      +
    • +

      Constructor Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +CountDownEnumerator +new(IntNumber count) + +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + +
      Modifier and TypeProperty
      + +get  IntNumber +Value() +
      +
    • +
    + +
      +
    • +

      Conversion Summary

      + + + + + + + + + +
      Modifier and TypeConversion Method
      + +Enumerator +cast() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + +BoolValue +next() + +
      + + +reset() + +
      + + +enumerable() + +
      +
    • +
    +
    +
    @@ -839,6 +1012,15 @@

    Method Summary

    + + + + + +move(IntNumber i, IntNumber j) + + + @@ -2904,6 +3086,15 @@

    Method Summary

    + + + +abstract   + +move(IntNumber i, IntNumber j) + + + @@ -3560,7 +3751,7 @@

    Extension Summary

    -joinBy(Object list, Func2 filter_f, Func2 select_f) +coundDown() @@ -3569,7 +3760,7 @@

    Extension Summary

    -repeatTo(Object n) +joinBy(Object list, Func2 filter_f, Func2 select_f) @@ -3578,7 +3769,7 @@

    Extension Summary

    -repeatTill(Object n) +repeatTo(Object n) @@ -3587,7 +3778,7 @@

    Extension Summary

    -summarize(Object var) +repeatTill(Object n) @@ -3596,7 +3787,7 @@

    Extension Summary

    -summarize() +summarize(Object var) @@ -3605,20 +3796,29 @@

    Extension Summary

    -seekFor(Object val) +summarize() + + +seekFor(Object val) + + + + + + BoolValue ifExists(Object val) - + BoolValue @@ -3627,7 +3827,7 @@

    Extension Summary

    - + get property   @@ -3635,7 +3835,7 @@

    Extension Summary

    FirstMember() - + get property   @@ -3643,7 +3843,7 @@

    Extension Summary

    LastMember() - + @@ -3652,7 +3852,7 @@

    Extension Summary

    - + @@ -3661,7 +3861,7 @@

    Extension Summary

    - + @@ -3670,7 +3870,7 @@

    Extension Summary

    - + BoolValue @@ -3679,7 +3879,7 @@

    Extension Summary

    - + @@ -3688,7 +3888,7 @@

    Extension Summary

    - + IntNumber @@ -3697,7 +3897,7 @@

    Extension Summary

    - + get property   @@ -3705,7 +3905,7 @@

    Extension Summary

    MaximalMember() - + get property   @@ -3713,7 +3913,7 @@

    Extension Summary

    MinimalMember() - + @@ -3722,7 +3922,7 @@

    Extension Summary

    - + @@ -3731,7 +3931,7 @@

    Extension Summary

    - + @@ -3740,7 +3940,7 @@

    Extension Summary

    - + @@ -3749,7 +3949,7 @@

    Extension Summary

    - + @@ -3758,7 +3958,7 @@

    Extension Summary

    - + @@ -3767,7 +3967,7 @@

    Extension Summary

    - + @@ -3776,7 +3976,7 @@

    Extension Summary

    - + BoolValue @@ -3785,7 +3985,7 @@

    Extension Summary

    - + @@ -3794,7 +3994,7 @@

    Extension Summary

    - + @@ -3803,7 +4003,7 @@

    Extension Summary

    - + IntNumber @@ -3812,7 +4012,7 @@

    Extension Summary

    - + BoolValue @@ -3821,7 +4021,7 @@

    Extension Summary

    - + @@ -3830,7 +4030,7 @@

    Extension Summary

    - + @@ -3839,7 +4039,7 @@

    Extension Summary

    - + @@ -3848,7 +4048,7 @@

    Extension Summary

    - + @@ -3857,7 +4057,7 @@

    Extension Summary

    - + diff --git a/doc/api/system-summary.html b/doc/api/system-summary.html index 9b286731f0..d132fa4640 100644 --- a/doc/api/system-summary.html +++ b/doc/api/system-summary.html @@ -790,6 +790,15 @@

    +MessageLoaderException + + +
    +public class MessageLoaderException
    + + + + MessageName @@ -797,7 +806,7 @@

    public class MessageName - + MethodNotFoundException @@ -806,7 +815,7 @@

    public class MethodNotFoundException - + MssgConvertor @@ -815,7 +824,7 @@

    public singleton MssgConvertor - + NilReferenceException @@ -824,7 +833,7 @@

    public class NilReferenceException - + nilValue @@ -834,7 +843,7 @@

    A nil value - + NotSupportedException @@ -843,7 +852,7 @@

    public class NotSupportedException - + Object @@ -853,7 +862,7 @@

    a common ancestor - + OutOfMemoryException @@ -862,7 +871,7 @@

    public class OutOfMemoryException - + OutOfRangeException @@ -871,7 +880,7 @@

    public class OutOfRangeException - + Range @@ -880,7 +889,7 @@

    public class Range - + RealConvertor @@ -889,7 +898,7 @@

    public singleton RealConvertor - + RealMatrix @@ -898,7 +907,7 @@

    public class RealMatrix - + RealNumber @@ -908,7 +917,7 @@

    A 64bit float numeric value - + Reference<T1> @@ -917,7 +926,7 @@

    public template Reference<T1> - + SByteConvertor @@ -926,7 +935,7 @@

    public singleton SByteConvertor - + SByteNumber @@ -936,7 +945,7 @@

    a signed 8 bit integer - + ShortArrayConvertor @@ -945,7 +954,7 @@

    public singleton ShortArrayConvertor - + ShortConvertor @@ -954,7 +963,7 @@

    public singleton ShortConvertor - + ShortNumber @@ -964,7 +973,7 @@

    a signed 16 bit integer - + SMALL_RECT @@ -973,7 +982,7 @@

    public class SMALL_RECT - + StackOverflowException @@ -982,7 +991,7 @@

    public class StackOverflowException - + StartUpEvents @@ -991,7 +1000,7 @@

    public class StartUpEvents - + String @@ -1001,7 +1010,7 @@

    A UTF-8 literal value - + StringConvertor @@ -1010,7 +1019,7 @@

    public singleton StringConvertor - + Symbol @@ -1019,7 +1028,7 @@

    public class Symbol - + SymbolLoaderException @@ -1028,7 +1037,7 @@

    public class SymbolLoaderException - + TypeLoaderException @@ -1037,7 +1046,7 @@

    public class TypeLoaderException - + UIntConvertor @@ -1046,7 +1055,7 @@

    public singleton UIntConvertor - + UIntNumber @@ -1056,7 +1065,7 @@

    A unsigned 32 bit integer - + UnsafePointer @@ -1065,7 +1074,7 @@

    public class UnsafePointer - + UShortConvertor @@ -1074,7 +1083,7 @@

    public singleton UShortConvertor - + UShortNumber @@ -1084,7 +1093,7 @@

    an unsigned 16 bit integer - + Variable @@ -1094,7 +1103,7 @@

    A generic variable.
    Extends an assigned value
    - + Variant @@ -1104,7 +1113,7 @@

    A basic type variant class - + WideConvertor @@ -1113,7 +1122,7 @@

    public singleton WideConvertor - + WideString diff --git a/doc/api/system-text.html b/doc/api/system-text.html index 63d9d93637..bd4f44c326 100644 --- a/doc/api/system-text.html +++ b/doc/api/system-text.html @@ -279,7 +279,7 @@

    Method Summary

    -insert(IntNumber index, CharValue ch) +writeSubstring(String s, IntNumber index, IntNumber length) @@ -288,7 +288,7 @@

    Method Summary

    -insert(IntNumber index, String s) +insert(IntNumber index, CharValue ch) @@ -297,6 +297,15 @@

    Method Summary

    +insert(IntNumber index, String s) + + + + + + + + delete(IntNumber index, IntNumber length) @@ -995,6 +1004,15 @@

    Method Summary

    + + + +IntNumber + +getSubStringCharCount(String s, IntNumber index, IntNumber length) + + + diff --git a/doc/api/system-winforms.html b/doc/api/system-winforms.html index 3a8b93e2e1..0a915016ed 100644 --- a/doc/api/system-winforms.html +++ b/doc/api/system-winforms.html @@ -1148,7 +1148,7 @@

    Method Summary

    -onSize(Handle control, IntNumber width, IntNumber height) +onChange(Handle control) @@ -1157,7 +1157,7 @@

    Method Summary

    -onWMCreate(Handle hwnd, CREATESTRUCT struct) +onSize(Handle control, IntNumber width, IntNumber height) @@ -1166,7 +1166,7 @@

    Method Summary

    -onWMDestoy(Handle hwnd) +onWMCreate(Handle hwnd, CREATESTRUCT struct) @@ -1175,7 +1175,7 @@

    Method Summary

    -onWMPaint(Handle hwnd) +onWMDestoy(Handle hwnd) @@ -1184,7 +1184,7 @@

    Method Summary

    -onWMSize(Handle hwnd, IntNumber lParam) +onWMPaint(Handle hwnd) @@ -1193,7 +1193,7 @@

    Method Summary

    -onWMCommand(Handle hwnd, IntNumber wParam, Handle control) +onWMSize(Handle hwnd, IntNumber lParam) @@ -1202,6 +1202,15 @@

    Method Summary

    +onWMCommand(Handle hwnd, IntNumber wParam, Handle control) + + + + + + + + onWMClose(Handle hwnd) diff --git a/doc/api/system.html b/doc/api/system.html index 3cf3c053c0..caf298b384 100644 --- a/doc/api/system.html +++ b/doc/api/system.html @@ -2048,6 +2048,8 @@

    Method Summary

    add(BaseVariable var) +
    +Adds a variable value of var argument
    @@ -2057,6 +2059,8 @@

    Method Summary

    subtract(BaseVariable var) +
    +Subtracts a variable value of var argument
    @@ -2066,6 +2070,8 @@

    Method Summary

    multiply(BaseVariable var) +
    +Multiplies a variable value of var argument
    @@ -2075,6 +2081,8 @@

    Method Summary

    divide(BaseVariable var) +
    +Divides by a variable value of var argument
    @@ -2123,7 +2131,7 @@

    Method Summary

    abstract  BoolValue -less(v) +less(o)
    Returns true if the object value is less than o; otherwise, false;
    should be overridden
    @@ -2134,7 +2142,7 @@

    Method Summary

    BoolValue -greater(v) +greater(o)
    Returns true if the object value is greater than o; otherwise, false;
    by default sends less[2] to o with the object as an argument
    @@ -2145,7 +2153,7 @@

    Method Summary

    BoolValue -notless(v) +notless(o)
    Returns true if the object value is not less than o; otherwise, false;
    by default inverts the result of less[2] operation
    @@ -2156,7 +2164,7 @@

    Method Summary

    BoolValue -notgreater(v) +notgreater(o)
    Returns true if the object value is not greater than o; otherwise, false;
    by default inverts the result of greater[2] operation
    @@ -2170,7 +2178,7 @@

    Method Summary

    equal(BaseVariable var)
    -Returns true if a value of var is equal to the object value; otherwise, false
    +Returns true if a value of a variable var is equal to the object value; otherwise, false @@ -2181,7 +2189,7 @@

    Method Summary

    less(BaseVariable var)
    -Returns true if the object value is less than a value of var; otherwise, false
    +Returns true if the object value is less than a value of a variable var ; otherwise, false @@ -2703,7 +2711,7 @@

    Method Summary

    equal(BoolValue f)
    -Determines whether the specified object is equal to the current object boolean value;
    has to be implemented
    +Returns true if an argument f is equal to the current object boolean value;
    has to be implemented @@ -2713,6 +2721,8 @@

    Method Summary

    notequal(BoolValue f) +
    +Returns true if an argument f is not equal to the current object boolean value;
    has to be implemented
    @@ -3075,7 +3085,7 @@

    Method Summary

    equal(BoolValue b)
    -Determines whether the specified object is equal to the current object boolean value.
    +Returns true if an argument b is true @@ -3503,6 +3513,8 @@

    Static Property Summary

    get  ByteNumber
    Default() +
    +returns the default value (0)
    @@ -11503,6 +11515,89 @@

    Method Summary


    + + + +
    +
    +system'
    +

    MessageLoaderException

    +
    +
    +
    +
    +
    +
    +public class MessageLoaderException
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + + + + + +
      Modifier and TypeField
      + +String +message +
      + +CallStack +callStack +
      +
    • +
    + +
      +
    • +

      Constructor Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +MessageLoaderException +new(String messageName) + +
      +
    • +
    +
    +
    @@ -12104,7 +12199,7 @@

    Constructor Summary

    constructor()
    -Creates the object
    +Creates an object @@ -16606,7 +16701,7 @@

    Field Summary

    -Func +EventHandler<system'Func>
    OnStop @@ -16614,7 +16709,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1>
    OnError diff --git a/doc/api/textgen-summary.html b/doc/api/textgen-summary.html new file mode 100644 index 0000000000..eb5181c364 --- /dev/null +++ b/doc/api/textgen-summary.html @@ -0,0 +1,85 @@ + + + + +ELENA Standard Library 6.5: Module textgen + + + + + +
    + +
    + +ELENA Standard Library
    6.5 +
    +
    +
    +
    +

    +Module textgen +

    +
    +
    +
    +
    +
    +
      +
    • + +
      +Class Summary +
      + + + + +
      Class nameDescription
      +
    • +
    • + +
      +Extended Class Summary +
      + + + + + + + + +
      Symbol nameDescription
      +Object + +
      +public class Object
      +
      +
    • +
    +
    +
    + +
    + +ELENA Standard Library
    6.5 +
    +
    +
    + + diff --git a/doc/api/textgen.html b/doc/api/textgen.html new file mode 100644 index 0000000000..bb1647fbba --- /dev/null +++ b/doc/api/textgen.html @@ -0,0 +1,81 @@ + + + + +ELENA Standard Library 6.5: Module textgen + + + + + +
    + +
    + +ELENA Standard Library
    6.5 +
    +
    +
    + + + +
    +
    +system'
    +

    Object

    +
    +
    +
    +
    +
    +
    +public class Object
    +
    +
    + +
      +
    • +

      Extension Summary

      + + + + + + + + + +
      Modifier and TypeExtension Method
      + +String +generateFrom(String script) + +
      +
    • +
    +
    +
    +
    + +
    + +ELENA Standard Library
    6.5 +
    +
    +
    + + diff --git a/doc/api/xforms.html b/doc/api/xforms.html index 4a80f92842..4f8c723a4d 100644 --- a/doc/api/xforms.html +++ b/doc/api/xforms.html @@ -125,7 +125,7 @@

    Field Summary

    -Func1 +EventHandler<system'Func1>
    onResize diff --git a/doc/api/xml-summary.html b/doc/api/xml-summary.html new file mode 100644 index 0000000000..40179ddc32 --- /dev/null +++ b/doc/api/xml-summary.html @@ -0,0 +1,119 @@ + + + + +ELENA Standard Library 6.5: Module xml + + + + + +
    + +
    + +ELENA Standard Library
    6.5 +
    +
    +
    +
    +

    +Module xml +

    +
    +
    +
    +
    +
    +
      +
    • + +
      +Class Summary +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Class nameDescription
      +IXmlFormatter + +
      +abstract public class IXmlFormatter
      +
      +IXmlReader + +
      +abstract public class IXmlReader
      +
      +TabXmlFormatter + +
      +public singleton TabXmlFormatter
      +
      +XmlDocument + +
      +public class XmlDocument
      +
      +XmlNode + +
      +public class XmlNode
      +
      +XmlReader + +
      +public class XmlReader
      +
      +
    • +
    +
    +
    + +
    + +ELENA Standard Library
    6.5 +
    +
    +
    + + diff --git a/doc/api/xml.html b/doc/api/xml.html new file mode 100644 index 0000000000..93ce08a4b9 --- /dev/null +++ b/doc/api/xml.html @@ -0,0 +1,900 @@ + + + + +ELENA Standard Library 6.5: Module xml + + + + + +
    + +
    + +ELENA Standard Library
    6.5 +
    +
    +
    + + + +
    +
    +xml'
    +

    IXmlFormatter

    +
    +
    +
    +
    +
    +
    +abstract public class IXmlFormatter
    +
    +
    + + + +
    +
    + + + +
    +
    +xml'
    +

    IXmlReader

    +
    +
    +
    +
    +
    +
    +abstract public class IXmlReader
    +
    +
    + + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get abstract  BoolValue +isAvailable() +
      + +get abstract  BoolValue +isOpenTag() +
      + +get abstract  BoolValue +isCloseTag() +
      + +get abstract  BoolValue +isContent() +
      + +get abstract  String +Name() +
      + +get abstract  String +Content() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + +
      Modifier and TypeMethod
      + +abstract   +read() + +
      +
    • +
    +
    +
    + + + +
    +
    +xml'
    +

    TabXmlFormatter

    +
    +
    +
    +
    +
    +
    +public singleton TabXmlFormatter
    +
    +
    + + + +
    +
    + + + +
    +
    +xml'
    +

    XmlDocument

    +
    +
    +
    +
    +
    +
    +public class XmlDocument
    +
    +
    + + +
      +
    • +

      Field Summary

      + + + + + + + + + +
      Modifier and TypeField
      + +XmlNode +_root +
      +
    • +
    + +
      +
    • +

      Constructor Summary

      + + + + + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +XmlDocument +new(XmlNode root) + +
      + +XmlDocument +new() + +
      +
    • +
    + + +
    +
    + + + +
    +
    +xml'
    +

    XmlNode

    +
    +
    +
    +
    +
    +
    +public class XmlNode
    +
    +
    + + + + +
      +
    • +

      Constructor Summary

      + + + + + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +internal  XmlNode +new(XmlNode parent, String name) + +
      + +internal  XmlNode +new(XmlNode parent, String name, String content) + +
      +
    • +
    + + + +
      +
    • +

      Property Summary

      + + + + + + + + + +
      Modifier and TypeProperty
      + +get  IntNumber +ChildCounter() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeMethod
      + + +appendChild(XmlNode child) + +
      + +internal   +setParent(XmlNode parent) + +
      + +internal   +setContent(String content) + +
      + +internal  IntNumber +getChildIndex(XmlNode child) + +
      + +internal  XmlNode +getChild(IntNumber index) + +
      + +XmlNode +findChild(String xpath) + +
      + +XmlNode +nextSibling() + +
      + +XmlNode +previousSibling() + +
      + +XmlNode +firstChild() + +
      + +XmlNode +lastChild() + +
      +
    • +
    +
    +
    + + + +
    +
    +xml'
    +

    XmlReader

    +
    +
    +
    +
    +
    +
    +public class XmlReader
    +
    +
    + + + + +
      +
    • +

      Constructor Summary

      + + + + + + + + + +
      Modifier and TypeConstructor / Static Method
      + +XmlReader +open(TextReader input) + +
      +
    • +
    + +
      +
    • +

      Property Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Modifier and TypeProperty
      + +get  BoolValue +isAvailable() +
      + +get  BoolValue +isOpenTag() +
      + +get  BoolValue +isCloseTag() +
      + +get  BoolValue +isContent() +
      + +get  String +Name() +
      + +get  String +Content() +
      +
    • +
    + +
      +
    • +

      Method Summary

      + + + + + + + + + +
      Modifier and TypeMethod
      + + +read() + +
      +
    • +
    +
    +
    +
    + +
    + +ELENA Standard Library
    6.5 +
    +
    +
    + + diff --git a/doc/features b/doc/features index 3eb6df7b42..ed29945d88 100644 --- a/doc/features +++ b/doc/features @@ -275,3 +275,82 @@ public program() o.eval(); } +---------------------------------------------------------------------------- + Using a callback function declared in ELENA +---------------------------------------------------------------------------- + +const int CTRL_C_EVENT = 0; +const int CTRL_BREAK_EVENT = 1; + +extern int myFunction(uint fdwCtrlType) +{ + fdwCtrlType => + CTRL_C_EVENT : { Console.writeLine("Ctrl-C event"); ^ -1 } + CTRL_BREAK_EVENT : { Console.writeLine("Ctrl-Break event"); ^ 0 }; + + ^ 0; +} + +public program() +{ + extern KERNEL32.SetConsoleCtrlHandler(&myFunction, -1); + + Console.writeLine("The Control Handler is installed."); + Console.writeLine("-- Now try pressing Ctrl+C or Ctrl+Break"); + + while(true) {} +} + +---------------------------------------------------------------------------- + Enumerations +---------------------------------------------------------------------------- + +public const struct Color : enum(Red ::= 1,Green ::= 2,Blue ::= 3); + +public program() +{ + Color color := Color.Red; +} + +---------------------------------------------------------------------------- + Type short-cuts +---------------------------------------------------------------------------- + +use extern KERNEL32; +use system'text'StringBuilder; + +public program() +{ + StringBuilder sb := new StringBuilder(); // allow to use the class proper name without importing the whole namespace + + pointer commandLinePtr := KERNEL32.GetCommandLineW(); // skipping extern attribute +} + +---------------------------------------------------------------------------- + Providing an external library name +---------------------------------------------------------------------------- + +use extern libcxx : importing("libc++"); + +public program() +{ + libcxx.do(); +} + +---------------------------------------------------------------------------- + Conditional compilation +---------------------------------------------------------------------------- + +#if (__project["_Win32"]) + +class Win32A +{ +} + +#elif (__project["_Win64"]) + +class Win64A +{ +} + +#endif diff --git a/doc/todo.txt b/doc/todo.txt index 274a750777..cac39ba0a6 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -5,71 +5,84 @@ In development: [development] ### EPIC: elena 6.7 ### - === Iteration 40 (4.05) === + ### EPIC: elena 6.8 ### + + === Iteration 41 === -------------------------------------- dev: - - MTA support for Linux - - upndown (connector - interaction) + - #739 + - #743 + - VM support for Linux (make for both linux and windows) + - MTA support for Linux : support MT routines in elenart - support :sizeof - #708 : compile the project (elc, og, sg, asm, ecv), compile library, compile executable, test executable + - implement analog of record using meta programming (extensions'records) + - upndown (connector - cmdSearch) + - #748 : i386 - #620 : backlog - - #34 : http client : support redirects, post, put, patch, delete, head, options, trace), web api - - MTA support for Linux (fix simple program - access to TLS) - - support fladd, flsub, fldiv, flmul (throu special prefix??) - - conditional compiling - - #622 : api backlog - - #731 gen: - - lpad / elt : declare an extension, parse it and apply to the input - ide: - - auto indent + - work on REPL (elt) : execute simple program + api: + - api refactoring : main program entry to be called - Program + - #622 : api backlog + - #34 : http client : support redirects, put, delete, support patch, head, options, web api + - textgen : support {{ }} special symbols + ide: + - splitter is not correctly displayed + - compile in the separate thread + - debugger : stepped into the property / operator automatically (see for example xml) + - debugger : watch list is not refreshed correctly (see for example xml) - #184 : linux - open project, new project, save project, save all, close project ... - syntax highlighting - async method - auto watch : self and some variables are not displayed maint: - - remove old scripts from build folder - - optimization : pi (used classes byte code) + - freebsd : create package, workflow - test all x86-64 examples - - github actions : `set-output` command is deprecated - API - review / description - - Actions : create a release archive - api: - - api refactoring : main program entry to be called - Program + - review pi performance (must < 6) : realOp.power[3] byte code + - nillable single dispatcher : use direct reference to nilValue symbol + samples: + - optimization : pi (used classes byte code) + - rosetta code : Program termination, Parallel calculations + - rosetta code : moving to 6.6 : (..Add a variable to a class instance at runtime) + port: + - chat sample tools: - #658 : debug elena program in VSCode : new thread event, loading source info, step over source - vs #2 : elena.tmLanguage.json - port: - - x86-64 : net, threading samples - - rosetta code : moving to 6.6 (test, use Console) - - chat sample - samples: - - rosetta code : Comma quibbling, Program termination, Parallel calculations - prom: - - bi-posting weekly + prom: + - api : BaseNumber + - post an article about records using meta programming + - weekly posting -------------------------------------- -------------------------------------- -------------------------------------- - ### EPIC: elena 6.8 ### - - === Iteration 41 === + === Iteration 42 === -------------------------------------- dev: gen: + api: + ide: maint: - - review pi performance (must < 6) : realOp.power[3] byte code + samples: port: + tools: prom: -------------------------------------- -------------------------------------- -------------------------------------- - === Iteration 42 === + === Iteration 43 === -------------------------------------- dev: gen: + api: + ide: maint: + samples: port: + tools: prom: -------------------------------------- -------------------------------------- diff --git a/elenasrc3/common/common.h b/elenasrc3/common/common.h index 1d7cf7fb4e..b7078decd5 100644 --- a/elenasrc3/common/common.h +++ b/elenasrc3/common/common.h @@ -70,7 +70,7 @@ namespace elena_lang #endif -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) constexpr auto PATH_SEPARATOR = '\\'; diff --git a/elenasrc3/common/files.cpp b/elenasrc3/common/files.cpp index 771ecd1d1f..9b13debcb5 100644 --- a/elenasrc3/common/files.cpp +++ b/elenasrc3/common/files.cpp @@ -3,7 +3,7 @@ // // This file contains ELENA Engine File class implementations. // -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "common.h" @@ -13,7 +13,7 @@ using namespace elena_lang; -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) #define file_open _wfopen @@ -79,7 +79,7 @@ bool File :: readText(char* s, FileEncoding encoding, size_t length, size_t& was } return wasRead != 0; } -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) case FileEncoding::Ansi: #endif case FileEncoding::UTF8: @@ -115,7 +115,7 @@ bool File :: readText(wide_c* s, FileEncoding encoding, size_t length, size_t& w } return (wasRead > 0); } -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) case FileEncoding::Ansi: default: { @@ -165,7 +165,7 @@ bool File :: writeText(const wide_c* s, FileEncoding encoding, size_t length) } return true; } - #ifdef _MSC_VER + #if (defined(_WIN32) || defined(__WIN32__)) case FileEncoding::Ansi: default: { @@ -216,7 +216,7 @@ bool File :: writeText(const char* s, FileEncoding encoding, size_t length) } return true; } - #ifdef _MSC_VER + #if (defined(_WIN32) || defined(__WIN32__)) case FileEncoding::Ansi: default: { @@ -362,7 +362,7 @@ bool TextFileReader :: read(char* s, pos_t length) { switch (_encoding) { case FileEncoding::UTF8: -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) case FileEncoding::Ansi: #endif return _file.readLine(s, length); diff --git a/elenasrc3/common/files.h b/elenasrc3/common/files.h index e1c9e13d91..a2bcbdd932 100644 --- a/elenasrc3/common/files.h +++ b/elenasrc3/common/files.h @@ -3,7 +3,7 @@ // // This file contains ELENA Engine File class declarations. // -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef FILES_H @@ -12,7 +12,7 @@ namespace elena_lang { -#ifdef _MSC_VER + #if (defined(_WIN32) || defined(__WIN32__)) // --- FileEncoding --- enum class FileEncoding { Ansi = 0, Raw = -1, UTF8 = -2, UTF16 = -3, UTF32 = -4 }; diff --git a/elenasrc3/common/paths.cpp b/elenasrc3/common/paths.cpp index b8efec4288..3325b0da29 100644 --- a/elenasrc3/common/paths.cpp +++ b/elenasrc3/common/paths.cpp @@ -12,7 +12,7 @@ using namespace elena_lang; -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) #include #include @@ -79,7 +79,7 @@ void PathUtil :: makeCorrectExePath(PathString& target) } } -#elif __GNUG__ +#elif defined(__unix__) #include #include diff --git a/elenasrc3/common/paths.h b/elenasrc3/common/paths.h index 3bd3a9bbca..d389734fcf 100644 --- a/elenasrc3/common/paths.h +++ b/elenasrc3/common/paths.h @@ -13,11 +13,11 @@ namespace elena_lang { // --- path_t --- -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) typedef wstr_t path_t; -#elif __GNUG__ +#elif defined(__unix__) typedef ustr_t path_t; @@ -41,7 +41,7 @@ namespace elena_lang static bool isRelative(path_t path, size_t length); static bool checkExtension(path_t path, path_t extension); -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) static bool checkExtension(path_t path, ustr_t extension); #endif @@ -133,7 +133,7 @@ namespace elena_lang copy(root); combine(subPath); } - #ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) bool append(const path_c* s, size_t length) { return String::append(s, length); diff --git a/elenasrc3/common/tools.h b/elenasrc3/common/tools.h index 098a8c5834..59de708d9b 100644 --- a/elenasrc3/common/tools.h +++ b/elenasrc3/common/tools.h @@ -3,7 +3,7 @@ // // This file contains the common ELENA Project routine functions // -// (C)2021, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef TOOLS_H @@ -13,8 +13,6 @@ #include -#define _gcvt gcvt - #endif // __GNUG__ #if !defined(_max) @@ -28,7 +26,7 @@ namespace elena_lang { -#ifdef __GNUG__ +#ifdef __unix__ inline size_t wcslen(const unsigned short* s) { const unsigned short* p = s; @@ -89,7 +87,7 @@ inline void freestr(unsigned short* s) // --- miscellaneous string routines --- -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) inline static size_t __fastcall getlength(const wchar_t* s) { @@ -106,7 +104,7 @@ inline static int __fastcall getlength_int(const wchar_t* s) return (s == nullptr) ? 0 : (int)wcslen(s); } -#elif __GNUG__ +#elif defined(__unix__) inline size_t getlength(const unsigned short* s) { diff --git a/elenasrc3/common/tree.h b/elenasrc3/common/tree.h index 1a12f8ab8f..dc510bfcc3 100644 --- a/elenasrc3/common/tree.h +++ b/elenasrc3/common/tree.h @@ -637,7 +637,10 @@ namespace elena_lang { _bookmarks.pop(); } - + void setBookmark(Node node) + { + _bookmarks.push(node._position); + } void newNode(Key key, ref_t arg) { if (_current == INVALID_POS) { diff --git a/elenasrc3/common/ustring.cpp b/elenasrc3/common/ustring.cpp index 234810513d..aaa042296e 100644 --- a/elenasrc3/common/ustring.cpp +++ b/elenasrc3/common/ustring.cpp @@ -545,7 +545,18 @@ char* StrConvertor :: toString(double value, int precision, char* s, size_t dest s[destLength] = 0; } - else _gcvt(value, precision, s); + else if (precision == 10) { + snprintf(s, destLength, "%.10g", value); + } + else { + char format[10] = "%."; + snprintf(format + 2, 8, "%d", precision); + size_t len = strlen(format); + format[len] = 'g'; + format[len + 1] = 0; + + snprintf(s, destLength, format, value); + } return s; } @@ -553,7 +564,7 @@ char* StrConvertor :: toString(double value, int precision, char* s, size_t dest wchar_t* StrConvertor :: toString(double value, int precision, wchar_t* s, size_t destLength) { char tmp[25]; - gcvt(value, precision, tmp); + StrConvertor::toString(value, precision, tmp, 25); for (size_t i = 0; i <= getlength(tmp); i++) { s[i] = tmp[i]; @@ -637,7 +648,7 @@ char* util_clone(const char* s, size_t length) else return nullptr; } -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) char* util_clone(const char* s) { @@ -1065,7 +1076,7 @@ char* StrFactory :: reallocate(char* s, size_t size) return (char*)realloc(s, size); } -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) void StrUtil :: move(wide_c* s1, const wide_c* s2, size_t length) { diff --git a/elenasrc3/elc/clicommon.h b/elenasrc3/elc/clicommon.h index e652625247..cbaf3294f4 100644 --- a/elenasrc3/elc/clicommon.h +++ b/elenasrc3/elc/clicommon.h @@ -163,7 +163,8 @@ enum class SymbolKind { Normal = 0, Static = 1, - ThreadVar = 2 + ThreadVar = 2, + ExternVar = 3 }; struct BranchingInfo @@ -298,6 +299,7 @@ class ModuleScopeBase : public SectionScopeBase IdentifierString declVar; IdentifierString superVar; IdentifierString receivedVar; + IdentifierString projectVar; pos_t stackAlingment, rawStackAlingment; pos_t ehTableEntrySize; @@ -355,6 +357,11 @@ class ModuleScopeBase : public SectionScopeBase virtual Visibility retrieveVisibility(ref_t reference) = 0; + virtual bool declareImport(ustr_t name, ustr_t importName) = 0; + virtual ustr_t resolveImport(ustr_t) = 0; + + virtual bool checkVariable(ustr_t name) = 0; + virtual void flush() = 0; ModuleScopeBase(ModuleBase* module, @@ -502,14 +509,13 @@ struct FieldAttributes bool isReadonly; bool inlineArray; bool fieldArray; - bool overrideMode; bool autogenerated; bool privateOne; bool isAuto; }; // --- CompilerBase --- -typedef Map ForwardMap; +typedef Map ForwardMap; class CompilerBase { @@ -743,7 +749,7 @@ class LinkerBase public: virtual LinkResult run(ProjectBase& project, ImageProviderBase& provider, - PlatformType uiType, path_t exeExtension) = 0; + PlatformType osType, PlatformType uiType, path_t exeExtension) = 0; LinkerBase(ErrorProcessorBase* errorProcessor) { diff --git a/elenasrc3/elc/cliconst.h b/elenasrc3/elc/cliconst.h index 9c467021cf..d23a340a4d 100644 --- a/elenasrc3/elc/cliconst.h +++ b/elenasrc3/elc/cliconst.h @@ -13,7 +13,7 @@ namespace elena_lang { - #define ELC_REVISION_NUMBER 0x00B0 + #define ELC_REVISION_NUMBER 0x00C8 #if defined _M_IX86 || _M_X64 diff --git a/elenasrc3/elc/codeblocks/bsd.clang_elc_amd64.mak b/elenasrc3/elc/codeblocks/bsd.clang_elc_amd64.mak new file mode 100644 index 0000000000..1cb254edbf --- /dev/null +++ b/elenasrc3/elc/codeblocks/bsd.clang_elc_amd64.mak @@ -0,0 +1,180 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = clang +CXX = clang++ +AR = ar +LD = clang++ +WINDRES = windres + +INC = -I.. -I../../engine -I../../common +CFLAGS = -Wall -std=c++20 -m64 -static-libgcc -static-libstdc++ +LDFLAGS = -m64 -ldl -fuse-ld=lld + +RESINC = +LIBDIR = +LIB = + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../temp/elena64-cli +DEP_RELEASE = +OUT_RELEASE = ../../../bin/elena64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker32.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o $(OBJDIR_RELEASE)/__/__/engine/serializer.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../bin || mkdir -p ../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/engine/linux || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/linux + test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux + test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/common/config.o: ../../common/config.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/config.cpp -o $(OBJDIR_RELEASE)/__/__/common/config.o + +$(OBJDIR_RELEASE)/__/__/common/dump.o: ../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/common/files.o: ../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/common/paths.o: ../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/common/ustring.o: ../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/common/xmltree.o: ../../common/xmltree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/xmltree.cpp -o $(OBJDIR_RELEASE)/__/__/common/xmltree.o + +$(OBJDIR_RELEASE)/__/__/engine/bcwriter.o: ../../engine/bcwriter.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/bcwriter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o + +$(OBJDIR_RELEASE)/__/__/engine/codescope.o: ../../engine/codescope.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/codescope.cpp -o $(OBJDIR_RELEASE)/__/__/engine/codescope.o + +$(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o: ../../engine/jitcompiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/jitcompiler.cpp -o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o + +$(OBJDIR_RELEASE)/__/__/engine/jitlinker.o: ../../engine/jitlinker.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/jitlinker.cpp -o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o + +$(OBJDIR_RELEASE)/__/__/engine/libman.o: ../../engine/libman.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/libman.cpp -o $(OBJDIR_RELEASE)/__/__/engine/libman.o + +$(OBJDIR_RELEASE)/__/__/engine/module.o: ../../engine/module.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/module.cpp -o $(OBJDIR_RELEASE)/__/__/engine/module.o + +$(OBJDIR_RELEASE)/__/__/engine/parsertable.o: ../../engine/parsertable.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/parsertable.cpp -o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o + +$(OBJDIR_RELEASE)/__/__/engine/section.o: ../../engine/section.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/section.cpp -o $(OBJDIR_RELEASE)/__/__/engine/section.o + +$(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o: ../../engine/x86_64compiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/x86_64compiler.cpp -o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o + +$(OBJDIR_RELEASE)/__/__/engine/x86compiler.o: ../../engine/x86compiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/x86compiler.cpp -o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o + +$(OBJDIR_RELEASE)/__/__/engine/x86helper.o: ../../engine/x86helper.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/x86helper.cpp -o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o + +$(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o: ../../engine/syntaxtree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/syntaxtree.cpp -o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o + +$(OBJDIR_RELEASE)/__/__/engine/bytecode.o: ../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o: ../../engine/xmlprojectbase.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/xmlprojectbase.cpp -o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o + +$(OBJDIR_RELEASE)/__/__/engine/serializer.o: ../../engine/serializer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/serializer.cpp -o $(OBJDIR_RELEASE)/__/__/engine/serializer.o + +$(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/codeimage.o: ../codeimage.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../codeimage.cpp -o $(OBJDIR_RELEASE)/__/codeimage.o + +$(OBJDIR_RELEASE)/__/compiler.o: ../compiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../compiler.cpp -o $(OBJDIR_RELEASE)/__/compiler.o + +$(OBJDIR_RELEASE)/__/compiling.o: ../compiling.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../compiling.cpp -o $(OBJDIR_RELEASE)/__/compiling.o + +$(OBJDIR_RELEASE)/__/derivation.o: ../derivation.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../derivation.cpp -o $(OBJDIR_RELEASE)/__/derivation.o + +$(OBJDIR_RELEASE)/__/compilerlogic.o: ../compilerlogic.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../compilerlogic.cpp -o $(OBJDIR_RELEASE)/__/compilerlogic.o + +$(OBJDIR_RELEASE)/__/modulescope.o: ../modulescope.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../modulescope.cpp -o $(OBJDIR_RELEASE)/__/modulescope.o + +$(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o: ../../engine/linux/presenter.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/presenter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o + +$(OBJDIR_RELEASE)/__/linux/elc.o: ../linux/elc.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elc.cpp -o $(OBJDIR_RELEASE)/__/linux/elc.o + +$(OBJDIR_RELEASE)/__/linux/elfimage.o: ../linux/elfimage.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elfimage.cpp -o $(OBJDIR_RELEASE)/__/linux/elfimage.o + +$(OBJDIR_RELEASE)/__/linux/elflinker.o: ../linux/elflinker.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elflinker.cpp -o $(OBJDIR_RELEASE)/__/linux/elflinker.o + +$(OBJDIR_RELEASE)/__/linux/elflinker32.o: ../linux/elflinker32.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elflinker32.cpp -o $(OBJDIR_RELEASE)/__/linux/elflinker32.o + +$(OBJDIR_RELEASE)/__/linux/elflinker64.o: ../linux/elflinker64.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elflinker64.cpp -o $(OBJDIR_RELEASE)/__/linux/elflinker64.o + +$(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o: ../linux/elfsyslibloader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elfsyslibloader.cpp -o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o + +$(OBJDIR_RELEASE)/__/linux/pathmanager.o: ../linux/pathmanager.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/pathmanager.cpp -o $(OBJDIR_RELEASE)/__/linux/pathmanager.o + +$(OBJDIR_RELEASE)/__/parser.o: ../parser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../parser.cpp -o $(OBJDIR_RELEASE)/__/parser.o + +$(OBJDIR_RELEASE)/__/separser.o: ../separser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../separser.cpp -o $(OBJDIR_RELEASE)/__/separser.o + +$(OBJDIR_RELEASE)/__/project.o: ../project.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../project.cpp -o $(OBJDIR_RELEASE)/__/project.o + +$(OBJDIR_RELEASE)/__/source.o: ../source.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../source.cpp -o $(OBJDIR_RELEASE)/__/source.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/linux + rm -rf $(OBJDIR_RELEASE)/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/elc/codeblocks/bsd.elc_amd64.mak b/elenasrc3/elc/codeblocks/bsd.elc_amd64.mak new file mode 100644 index 0000000000..6f6af7b314 --- /dev/null +++ b/elenasrc3/elc/codeblocks/bsd.elc_amd64.mak @@ -0,0 +1,180 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = gcc +CXX = g++ +AR = ar +LD = g++ +WINDRES = windres + +INC = -I.. -I../../engine -I../../common +CFLAGS = -Wall -std=c++20 -m64 +LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl + +RESINC = +LIBDIR = +LIB = + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../temp/elena64-cli +DEP_RELEASE = +OUT_RELEASE = ../../../bin/elena64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker32.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o $(OBJDIR_RELEASE)/__/__/engine/serializer.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../bin || mkdir -p ../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/engine/linux || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/linux + test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux + test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/common/config.o: ../../common/config.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/config.cpp -o $(OBJDIR_RELEASE)/__/__/common/config.o + +$(OBJDIR_RELEASE)/__/__/common/dump.o: ../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/common/files.o: ../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/common/paths.o: ../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/common/ustring.o: ../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/common/xmltree.o: ../../common/xmltree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/xmltree.cpp -o $(OBJDIR_RELEASE)/__/__/common/xmltree.o + +$(OBJDIR_RELEASE)/__/__/engine/bcwriter.o: ../../engine/bcwriter.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/bcwriter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o + +$(OBJDIR_RELEASE)/__/__/engine/codescope.o: ../../engine/codescope.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/codescope.cpp -o $(OBJDIR_RELEASE)/__/__/engine/codescope.o + +$(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o: ../../engine/jitcompiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/jitcompiler.cpp -o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o + +$(OBJDIR_RELEASE)/__/__/engine/jitlinker.o: ../../engine/jitlinker.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/jitlinker.cpp -o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o + +$(OBJDIR_RELEASE)/__/__/engine/libman.o: ../../engine/libman.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/libman.cpp -o $(OBJDIR_RELEASE)/__/__/engine/libman.o + +$(OBJDIR_RELEASE)/__/__/engine/module.o: ../../engine/module.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/module.cpp -o $(OBJDIR_RELEASE)/__/__/engine/module.o + +$(OBJDIR_RELEASE)/__/__/engine/parsertable.o: ../../engine/parsertable.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/parsertable.cpp -o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o + +$(OBJDIR_RELEASE)/__/__/engine/section.o: ../../engine/section.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/section.cpp -o $(OBJDIR_RELEASE)/__/__/engine/section.o + +$(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o: ../../engine/x86_64compiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/x86_64compiler.cpp -o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o + +$(OBJDIR_RELEASE)/__/__/engine/x86compiler.o: ../../engine/x86compiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/x86compiler.cpp -o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o + +$(OBJDIR_RELEASE)/__/__/engine/x86helper.o: ../../engine/x86helper.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/x86helper.cpp -o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o + +$(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o: ../../engine/syntaxtree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/syntaxtree.cpp -o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o + +$(OBJDIR_RELEASE)/__/__/engine/bytecode.o: ../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o: ../../engine/xmlprojectbase.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/xmlprojectbase.cpp -o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o + +$(OBJDIR_RELEASE)/__/__/engine/serializer.o: ../../engine/serializer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/serializer.cpp -o $(OBJDIR_RELEASE)/__/__/engine/serializer.o + +$(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/codeimage.o: ../codeimage.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../codeimage.cpp -o $(OBJDIR_RELEASE)/__/codeimage.o + +$(OBJDIR_RELEASE)/__/compiler.o: ../compiler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../compiler.cpp -o $(OBJDIR_RELEASE)/__/compiler.o + +$(OBJDIR_RELEASE)/__/compiling.o: ../compiling.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../compiling.cpp -o $(OBJDIR_RELEASE)/__/compiling.o + +$(OBJDIR_RELEASE)/__/derivation.o: ../derivation.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../derivation.cpp -o $(OBJDIR_RELEASE)/__/derivation.o + +$(OBJDIR_RELEASE)/__/compilerlogic.o: ../compilerlogic.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../compilerlogic.cpp -o $(OBJDIR_RELEASE)/__/compilerlogic.o + +$(OBJDIR_RELEASE)/__/modulescope.o: ../modulescope.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../modulescope.cpp -o $(OBJDIR_RELEASE)/__/modulescope.o + +$(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o: ../../engine/linux/presenter.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/presenter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o + +$(OBJDIR_RELEASE)/__/linux/elc.o: ../linux/elc.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elc.cpp -o $(OBJDIR_RELEASE)/__/linux/elc.o + +$(OBJDIR_RELEASE)/__/linux/elfimage.o: ../linux/elfimage.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elfimage.cpp -o $(OBJDIR_RELEASE)/__/linux/elfimage.o + +$(OBJDIR_RELEASE)/__/linux/elflinker.o: ../linux/elflinker.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elflinker.cpp -o $(OBJDIR_RELEASE)/__/linux/elflinker.o + +$(OBJDIR_RELEASE)/__/linux/elflinker32.o: ../linux/elflinker32.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elflinker32.cpp -o $(OBJDIR_RELEASE)/__/linux/elflinker32.o + +$(OBJDIR_RELEASE)/__/linux/elflinker64.o: ../linux/elflinker64.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elflinker64.cpp -o $(OBJDIR_RELEASE)/__/linux/elflinker64.o + +$(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o: ../linux/elfsyslibloader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elfsyslibloader.cpp -o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o + +$(OBJDIR_RELEASE)/__/linux/pathmanager.o: ../linux/pathmanager.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/pathmanager.cpp -o $(OBJDIR_RELEASE)/__/linux/pathmanager.o + +$(OBJDIR_RELEASE)/__/parser.o: ../parser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../parser.cpp -o $(OBJDIR_RELEASE)/__/parser.o + +$(OBJDIR_RELEASE)/__/separser.o: ../separser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../separser.cpp -o $(OBJDIR_RELEASE)/__/separser.o + +$(OBJDIR_RELEASE)/__/project.o: ../project.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../project.cpp -o $(OBJDIR_RELEASE)/__/project.o + +$(OBJDIR_RELEASE)/__/source.o: ../source.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../source.cpp -o $(OBJDIR_RELEASE)/__/source.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/linux + rm -rf $(OBJDIR_RELEASE)/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/elc/codeblocks/elc_amd64.mak b/elenasrc3/elc/codeblocks/elc_amd64.mak index 4d97991f52..6838cf7f54 100644 --- a/elenasrc3/elc/codeblocks/elc_amd64.mak +++ b/elenasrc3/elc/codeblocks/elc_amd64.mak @@ -11,11 +11,22 @@ LD = g++ WINDRES = windres INC = -I.. -I../../engine -I../../common + +ifeq ($(OS),Windows_NT) + +CFLAGS = -Wall -std=c++20 -m64 -municode +LDFLAGS = -m64 -static-libgcc -static-libstdc++ + +else + CFLAGS = -Wall -std=c++20 -m64 +LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl + +endif + RESINC = LIBDIR = LIB = -LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl INC_RELEASE = $(INC) CFLAGS_RELEASE = $(CFLAGS) -O3 @@ -28,8 +39,16 @@ OBJDIR_RELEASE = ../../temp/elena64-cli DEP_RELEASE = OUT_RELEASE = ../../../bin/elena64-cli +ifeq ($(OS),Windows_NT) + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/windows/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/windows/elc.o $(OBJDIR_RELEASE)/__/windows/ntimage.o $(OBJDIR_RELEASE)/__/windows/ntlinker.o $(OBJDIR_RELEASE)/__/windows/ntlinker32.o $(OBJDIR_RELEASE)/__/windows/ntlinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/windows/winsyslibloader.o $(OBJDIR_RELEASE)/__/__/engine/serializer.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + +else + OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/engine/bcwriter.o $(OBJDIR_RELEASE)/__/__/engine/codescope.o $(OBJDIR_RELEASE)/__/__/engine/jitcompiler.o $(OBJDIR_RELEASE)/__/__/engine/jitlinker.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/x86_64compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86compiler.o $(OBJDIR_RELEASE)/__/__/engine/x86helper.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/xmlprojectbase.o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o $(OBJDIR_RELEASE)/__/codeimage.o $(OBJDIR_RELEASE)/__/compiler.o $(OBJDIR_RELEASE)/__/compiling.o $(OBJDIR_RELEASE)/__/derivation.o $(OBJDIR_RELEASE)/__/linux/elc.o $(OBJDIR_RELEASE)/__/linux/elfimage.o $(OBJDIR_RELEASE)/__/linux/elflinker.o $(OBJDIR_RELEASE)/__/linux/elflinker32.o $(OBJDIR_RELEASE)/__/linux/elflinker64.o $(OBJDIR_RELEASE)/__/parser.o $(OBJDIR_RELEASE)/__/separser.o $(OBJDIR_RELEASE)/__/project.o $(OBJDIR_RELEASE)/__/source.o $(OBJDIR_RELEASE)/__/modulescope.o $(OBJDIR_RELEASE)/__/compilerlogic.o $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o $(OBJDIR_RELEASE)/__/linux/pathmanager.o $(OBJDIR_RELEASE)/__/__/engine/serializer.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o +endif + all: release clean: clean_release @@ -38,8 +57,13 @@ before_release: test -d ../../../bin || mkdir -p ../../../bin test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine +ifeq ($(OS),Windows_NT) + test -d $(OBJDIR_RELEASE)/__/__/engine/windows || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/windows + test -d $(OBJDIR_RELEASE)/__/windows || mkdir -p $(OBJDIR_RELEASE)/__/windows +else test -d $(OBJDIR_RELEASE)/__/__/engine/linux || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/linux test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux +endif test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common after_release: @@ -115,9 +139,6 @@ $(OBJDIR_RELEASE)/__/__/engine/serializer.o: ../../engine/serializer.cpp $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o -$(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o: ../../engine/linux/presenter.cpp - $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/presenter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o - $(OBJDIR_RELEASE)/__/codeimage.o: ../codeimage.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../codeimage.cpp -o $(OBJDIR_RELEASE)/__/codeimage.o @@ -136,6 +157,34 @@ $(OBJDIR_RELEASE)/__/compilerlogic.o: ../compilerlogic.cpp $(OBJDIR_RELEASE)/__/modulescope.o: ../modulescope.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../modulescope.cpp -o $(OBJDIR_RELEASE)/__/modulescope.o +ifeq ($(OS),Windows_NT) + +$(OBJDIR_RELEASE)/__/__/engine/windows/presenter.o: ../../engine/windows/presenter.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/windows/presenter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/windows/presenter.o + +$(OBJDIR_RELEASE)/__/windows/elc.o: ../windows/elc.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../windows/elc.cpp -o $(OBJDIR_RELEASE)/__/windows/elc.o + +$(OBJDIR_RELEASE)/__/windows/ntimage.o: ../windows/ntimage.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../windows/ntimage.cpp -o $(OBJDIR_RELEASE)/__/windows/ntimage.o + +$(OBJDIR_RELEASE)/__/windows/ntlinker.o: ../windows/ntlinker.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../windows/ntlinker.cpp -o $(OBJDIR_RELEASE)/__/windows/ntlinker.o + +$(OBJDIR_RELEASE)/__/windows/ntlinker32.o: ../windows/ntlinker32.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../windows/ntlinker32.cpp -o $(OBJDIR_RELEASE)/__/windows/ntlinker32.o + +$(OBJDIR_RELEASE)/__/windows/ntlinker64.o: ../windows/ntlinker64.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../windows/ntlinker64.cpp -o $(OBJDIR_RELEASE)/__/windows/ntlinker64.o + +$(OBJDIR_RELEASE)/__/windows/winsyslibloader.o: ../windows/winsyslibloader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../windows/winsyslibloader.cpp -o $(OBJDIR_RELEASE)/__/windows/winsyslibloader.o + +else + +$(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o: ../../engine/linux/presenter.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/presenter.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/presenter.o + $(OBJDIR_RELEASE)/__/linux/elc.o: ../linux/elc.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elc.cpp -o $(OBJDIR_RELEASE)/__/linux/elc.o @@ -157,6 +206,8 @@ $(OBJDIR_RELEASE)/__/linux/elfsyslibloader.o: ../linux/elfsyslibloader.cpp $(OBJDIR_RELEASE)/__/linux/pathmanager.o: ../linux/pathmanager.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/pathmanager.cpp -o $(OBJDIR_RELEASE)/__/linux/pathmanager.o +endif + $(OBJDIR_RELEASE)/__/parser.o: ../parser.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../parser.cpp -o $(OBJDIR_RELEASE)/__/parser.o @@ -173,7 +224,11 @@ clean_release: rm -f $(OBJ_RELEASE) $(OUT_RELEASE) rm -rf $(OBJDIR_RELEASE)/__ rm -rf $(OBJDIR_RELEASE)/__/__/engine +ifeq ($(OS),Windows_NT) + rm -rf $(OBJDIR_RELEASE)/__/windows +else rm -rf $(OBJDIR_RELEASE)/__/linux +endif rm -rf $(OBJDIR_RELEASE)/__/__/common .PHONY: before_release after_release clean_release diff --git a/elenasrc3/elc/compiler.cpp b/elenasrc3/elc/compiler.cpp index 469c281217..7b9a167211 100644 --- a/elenasrc3/elc/compiler.cpp +++ b/elenasrc3/elc/compiler.cpp @@ -62,6 +62,19 @@ MethodHint operator | (const ref_t& l, const MethodHint& r) // } //} +inline bool isSimpleNode(SyntaxNode node) +{ + SyntaxNode current = node.firstChild(); + + if (current == SyntaxKey::Expression && current.nextNode() == SyntaxKey::None) { + return isSimpleNode(current); + } + else if (current == SyntaxKey::Object && current.nextNode() == SyntaxKey::None) { + return true; + } + return false; +} + inline bool isSelfCall(ObjectInfo target) { switch (target.kind) { @@ -140,15 +153,17 @@ void declareTemplateParameters(ModuleBase* module, TemplateTypeList& typeList, dummyWriter.newNode(SyntaxKey::Root); for (size_t i = 0; i < typeList.count(); i++) { - ref_t elementRef = typeList[i]; + TypeInfo elementInfo = typeList[i]; - dummyWriter.newNode(SyntaxKey::TemplateArg, elementRef); + assert(!isPrimitiveRef(elementInfo.typeRef)); // NOTE that the code must check if it is nullable + + dummyWriter.newNode(SyntaxKey::TemplateArg, elementInfo.typeRef); parameters.add(dummyWriter.CurrentNode()); - dummyWriter.newNode(SyntaxKey::Type); + dummyWriter.newNode(elementInfo.nillable ? SyntaxKey::NullableType : SyntaxKey::Type); - ustr_t referenceName = module->resolveReference(elementRef); + ustr_t referenceName = module->resolveReference(elementInfo.typeRef); if (isWeakReference(referenceName)) { dummyWriter.appendNode(SyntaxKey::reference, referenceName); } @@ -184,25 +199,6 @@ void declareArguments(SyntaxNode node, SyntaxTree& dummyTree, List& current = current.nextNode(); } - //for (size_t i = 0; i < typeList.count(); i++) { - // ref_t elementRef = typeList[i]; - - // dummyWriter.newNode(SyntaxKey::TemplateArg, elementRef); - - // parameters.add(dummyWriter.CurrentNode()); - - // dummyWriter.newNode(SyntaxKey::Type); - - // ustr_t referenceName = module->resolveReference(elementRef); - // if (isWeakReference(referenceName)) { - // dummyWriter.appendNode(SyntaxKey::reference, referenceName); - // } - // else dummyWriter.appendNode(SyntaxKey::globalreference, referenceName); - - // dummyWriter.closeNode(); - // dummyWriter.closeNode(); - //} - dummyWriter.closeNode(); } @@ -368,6 +364,26 @@ void Interpreter::addIntArrayItem(ref_t dictionaryRef, int value) writer.writeDWord(value); } +void Interpreter :: addByteArrayItem(ref_t dictionaryRef, int value) +{ + MemoryBase* dictionary = _scope->module->mapSection(dictionaryRef | mskConstant, true); + if (!dictionary) + throw InternalError(errFatalError); + + MemoryWriter writer(dictionary); + writer.writeByte(value); +} + +void Interpreter::addWordArrayItem(ref_t dictionaryRef, int value) +{ + MemoryBase* dictionary = _scope->module->mapSection(dictionaryRef | mskConstant, true); + if (!dictionary) + throw InternalError(errFatalError); + + MemoryWriter writer(dictionary); + writer.writeWord(value); +} + void Interpreter::addLongArrayItem(ref_t dictionaryRef, long long value) { MemoryBase* dictionary = _scope->module->mapSection(dictionaryRef | mskConstant, true); @@ -503,7 +519,7 @@ void Interpreter::copyConstCollection(ref_t sourRef, ref_t destRef, bool byValue } } -ObjectInfo Interpreter::createConstCollection(ref_t arrayRef, ref_t typeRef, ArgumentsInfo& args, bool byValue) +ObjectInfo Interpreter::createConstCollection(ref_t arrayRef, ref_t typeRef, ArgumentsInfo& args, bool byValue, int elementSize) { ref_t mask = byValue ? mskConstant : mskConstArray; auto section = _scope->module->mapSection(arrayRef | mask, false); @@ -516,7 +532,17 @@ ObjectInfo Interpreter::createConstCollection(ref_t arrayRef, ref_t typeRef, Arg break; case ObjectKind::IntLiteral: if (byValue) { - addIntArrayItem(arrayRef, arg.extra); + switch (elementSize) { + case 1: + addByteArrayItem(arrayRef, arg.extra); + break; + case 2: + addWordArrayItem(arrayRef, arg.extra); + break; + default: + addIntArrayItem(arrayRef, arg.extra); + break; + } } else addConstArrayItem(arrayRef, arg.reference, mskIntLiteralRef); break; @@ -678,6 +704,72 @@ bool Interpreter::evalIntOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& return false; } +bool Interpreter :: evalIntCondOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal) +{ + ObjectInfo loperand = args[0]; + ObjectInfo roperand = args[1]; + + switch (operator_id) { + case EQUAL_OPERATOR_ID: + if (loperand.kind == ObjectKind::IntLiteral && roperand.kind == ObjectKind::IntLiteral) { + bool value = loperand.extra == roperand.extra; + + retVal = { ObjectKind::Singleton, { V_FLAG }, 0, value ? -1 : 0 }; + + return true; + } + break; + case NOTEQUAL_OPERATOR_ID: + if (loperand.kind == ObjectKind::IntLiteral && roperand.kind == ObjectKind::IntLiteral) { + bool value = loperand.extra != roperand.extra; + + retVal = { ObjectKind::Singleton, { V_FLAG }, 0, value ? -1 : 0 }; + + return true; + } + break; + case GREATER_OPERATOR_ID: + if (loperand.kind == ObjectKind::IntLiteral && roperand.kind == ObjectKind::IntLiteral) { + bool value = loperand.extra > roperand.extra; + + retVal = { ObjectKind::Singleton, { V_FLAG }, 0, value ? -1 : 0 }; + + return true; + } + break; + case NOTGREATER_OPERATOR_ID: + if (loperand.kind == ObjectKind::IntLiteral && roperand.kind == ObjectKind::IntLiteral) { + bool value = loperand.extra <= roperand.extra; + + retVal = { ObjectKind::Singleton, { V_FLAG }, 0, value ? -1 : 0 }; + + return true; + } + break; + case LESS_OPERATOR_ID: + if (loperand.kind == ObjectKind::IntLiteral && roperand.kind == ObjectKind::IntLiteral) { + bool value = loperand.extra < roperand.extra; + + retVal = { ObjectKind::Singleton, { V_FLAG }, 0, value ? -1 : 0 }; + + return true; + } + break; + case NOTLESS_OPERATOR_ID: + if (loperand.kind == ObjectKind::IntLiteral && roperand.kind == ObjectKind::IntLiteral) { + bool value = loperand.extra >= roperand.extra; + + retVal = { ObjectKind::Singleton, { V_FLAG }, 0, value ? -1 : 0 }; + + return true; + } + break; + default: + break; + } + return false; +} + bool Interpreter::evalRealOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal) { ObjectInfo loperand = args[0]; @@ -718,6 +810,21 @@ bool Interpreter::evalRealOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& return true; } +bool Interpreter :: evalProjectInfoOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal) +{ + ObjectInfo loperand = args[0]; + ObjectInfo roperand = args[1]; + + if (loperand.kind == ObjectKind::ProjectInfo && roperand.kind == ObjectKind::StringLiteral) { + ustr_t variableStr = _scope->module->resolveConstant(roperand.reference); + + retVal = { ObjectKind::ProjectVariable, { V_FLAG }, 0, _scope->checkVariable(variableStr) ? -1 : 0 }; + + return true; + } + return false; +} + bool Interpreter::evalDeclOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal) { ObjectInfo loperand = args[0]; @@ -772,6 +879,10 @@ bool Interpreter::eval(BuildKey key, ref_t operator_id, ArgumentsInfo& arguments return evalIntOp(operator_id, arguments, retVal); case BuildKey::RealOp: return evalRealOp(operator_id, arguments, retVal); + case BuildKey::ProjectInfoOp: + return evalProjectInfoOp(operator_id, arguments, retVal); + case BuildKey::IntCondOp: + return evalIntCondOp(operator_id, arguments, retVal); default: return false; } @@ -781,6 +892,7 @@ bool Interpreter::eval(BuildKey key, ref_t operator_id, ArgumentsInfo& arguments Compiler::NamespaceScope::NamespaceScope(NamespaceScope* parent) : Scope(parent), + shortcuts({}), forwards(0), importedNs(nullptr), extensions({}), @@ -936,6 +1048,10 @@ ObjectInfo Compiler::NamespaceScope::defineObjectInfo(ref_t reference, Expressio return defineConstant(symbolInfo); } break; + case SymbolType::Procedure: + return { ObjectKind::InternalCallback, { V_OBJECT }, reference }; + case SymbolType::External: + return { ObjectKind::ExternalVar, { symbolInfo.typeRef }, symbolInfo.valueRef }; default: break; } @@ -1002,6 +1118,11 @@ ObjectInfo Compiler::NamespaceScope::mapIdentifier(ustr_t identifier, bool refer reference = moduleScope->aliases.get(identifier); if (isPrimitiveRef(reference)) reference = 0; + + // try resolve as shortcut + ObjectInfo shortcut = shortcuts.get(identifier); + if (shortcut.kind != ObjectKind::Unknown) + return shortcut; } if (!reference) @@ -1107,15 +1228,28 @@ ObjectInfo Compiler::MetaScope::mapDecl() return { ObjectKind::Symbol, { V_DECLARATION }, symbolScope->reference }; } + ShortcutScope* shortcutScope = Scope::getScope(*this, ScopeLevel::Shortcut); + if (shortcutScope != nullptr) { + return shortcutScope->shortcutInfo; + } + return {}; } +ObjectInfo Compiler::MetaScope :: mapProject() +{ + return { ObjectKind::ProjectInfo, { V_PROJECT_VAR }, 0 }; +} + ObjectInfo Compiler::MetaScope::mapIdentifier(ustr_t identifier, bool referenceOne, EAttr attr) { if (!referenceOne) { if (moduleScope->declVar.compare(identifier)) { return mapDecl(); } + else if (moduleScope->projectVar.compare(identifier)) { + return mapProject(); + } else { ObjectInfo retVal = {}; if (EAttrs::testAndExclude(attr, EAttr::Superior) && parent->parent != nullptr) { @@ -1157,11 +1291,16 @@ void Compiler::SymbolScope::load() info.load(&metaReader); } +void Compiler::SymbolScope :: saveSymbolInfo(ModuleBase* module, SymbolInfo& info, ref_t reference) +{ + MemoryWriter metaWriter(module->mapSection(reference | mskMetaSymbolInfoRef, false), 0); + info.save(&metaWriter); +} + void Compiler::SymbolScope::save() { // save class meta data - MemoryWriter metaWriter(moduleScope->module->mapSection(reference | mskMetaSymbolInfoRef, false), 0); - info.save(&metaWriter); + saveSymbolInfo(moduleScope->module, info, reference); } // --- Compiler::TemplateScope --- @@ -1341,7 +1480,7 @@ ObjectInfo Compiler::ClassClassScope::mapField(ustr_t identifier, ExpressionAttr // --- Compiler::MethodScope --- -Compiler::MethodScope::MethodScope(ClassScope* parent) : +Compiler::MethodScope::MethodScope(SourceScope* parent) : Scope(parent), message(0), parameters({}), @@ -1503,6 +1642,14 @@ Compiler::CodeScope::CodeScope(CodeScope* parent) withRetStatement = false; } +Compiler::CodeScope::CodeScope(SymbolScope* parent) + : Scope(parent), locals({}), localNodes({}), flowMode(CodeFlowMode::Normal) +{ + allocated1 = reserved1 = 0; + allocated2 = reserved2 = 0; + withRetStatement = false; +} + ObjectInfo Compiler::CodeScope::mapLocal(ustr_t identifier) { Parameter local = locals.get(identifier); @@ -1550,6 +1697,15 @@ void Compiler::CodeScope::syncStack(MethodScope* methodScope) methodScope->reserved2 = reserved2; } +void Compiler::CodeScope::syncStack(SymbolScope* methodScope) +{ + if (methodScope->reserved1 < reserved1) + methodScope->reserved1 = reserved1; + + if (methodScope->reserved2 < reserved2) + methodScope->reserved2 = reserved2; +} + void Compiler::CodeScope::syncStack(CodeScope* parentScope) { if (allocated1 > reserved1) @@ -2165,7 +2321,7 @@ ref_t Compiler::retrieveBlock(NamespaceScope& scope, SyntaxNode node) return reference; } -bool Compiler::importEnumTemplate(Scope& scope, SyntaxNode node, SyntaxNode target) +bool Compiler :: importEnumTemplate(Scope& scope, SyntaxNode node, SyntaxNode target) { TypeAttributes attributes = {}; @@ -2252,7 +2408,7 @@ bool Compiler::importInlineTemplate(Scope& scope, SyntaxNode node, ustr_t postfi return true; } -bool Compiler::importPropertyTemplate(Scope& scope, SyntaxNode node, ustr_t postfix, SyntaxNode target) +bool Compiler :: importPropertyTemplate(Scope& scope, SyntaxNode node, ustr_t postfix, SyntaxNode& target) { List parameters({}); @@ -2279,6 +2435,28 @@ bool Compiler::importPropertyTemplate(Scope& scope, SyntaxNode node, ustr_t post writer.closeNode(); } + + // add extra arguments if available + SyntaxNode extraNameNode = node.findChild(SyntaxKey::Expression); + if (extraNameNode != SyntaxKey::None) { + if (!isSimpleNode(extraNameNode)) + scope.raiseError(errInvalidSyntax, extraNameNode); + + // the third one is a name as well + writer.newNode(SyntaxKey::TemplateArg); + writer.newNode(SyntaxKey::Name); + SyntaxTree::copyNode(writer, extraNameNode.firstChild(), false); + + writer.closeNode(); + parameters.add(writer.CurrentNode()); + + writer.closeNode(); + + // only upto three arguments are allowed so far + if (extraNameNode.nextNode() != SyntaxKey::None) + scope.raiseError(errInvalidSyntax, extraNameNode.nextNode()); + } + writer.closeNode(); NamespaceScope* ns = Scope::getScope(scope, Scope::ScopeLevel::Namespace); @@ -2286,11 +2464,20 @@ bool Compiler::importPropertyTemplate(Scope& scope, SyntaxNode node, ustr_t post if (!templateRef) return false; + // NOTE : for the property template, target is the property field if (!_templateProcessor->importPropertyTemplate(*scope.moduleScope, templateRef, - target.parentNode(), parameters)) + target, parameters)) { scope.raiseError(errInvalidOperation, node); } + // field must be declared explictitly inside the field template; + // so the original field must be removed + target.setKey(SyntaxKey::Idle); + + // try to find a new field and set it as a target + SyntaxNode newTarget = SyntaxTree::gotoNode(target, SyntaxKey::Field); + if (newTarget == SyntaxKey::Field) + target = newTarget; return true; } @@ -2317,6 +2504,28 @@ ustr_t Compiler :: retrieveDictionaryOwner(Scope& scope, ustr_t properName, ustr return defaultPrefix; } +bool Compiler :: declareImport(Scope& scope, SyntaxNode node) +{ + MetaScope metaScope(&scope, Scope::ScopeLevel::Namespace); + + SyntaxNode objNode = node.firstChild(); + SyntaxNode exprNode = objNode.nextNode(); + + ObjectInfo alias = evalExpression(metaScope, objNode); + ObjectInfo externalName = evalExpression(metaScope, exprNode); + + if (alias.kind == ObjectKind::ExternLibrary && externalName.kind == ObjectKind::StringLiteral) { + scope.moduleScope->declareImport( + scope.module->resolveConstant(alias.reference), + scope.module->resolveConstant(externalName.reference) + ); + + return true; + } + + return false; +} + void Compiler :: declareDictionary(Scope& scope, SyntaxNode node, Visibility visibility, Scope::ScopeLevel level, bool shareMode) { bool superMode = false; @@ -2396,6 +2605,13 @@ void Compiler :: declareVMT(ClassScope& scope, SyntaxNode node, bool& withConstr case SyntaxKey::SharedMetaDictionary: declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Class, true); break; + case SyntaxKey::ElseCondStatement: + case SyntaxKey::CondStatement: + if (!evalCondStatement(scope, current)) { + skipCondStatement(current); + continue; + } + break; case SyntaxKey::Method: { MethodScope methodScope(&scope); @@ -3214,7 +3430,7 @@ void Compiler :: generateMethodDeclarations(ClassScope& scope, SyntaxNode node, hintNode.setArgumentReference(hintNode.arg.reference & ~(ref_t)MethodHint::Async); } - ref_t hints = current.findChild(SyntaxKey::Hints).arg.value; + //ref_t hints = current.findChild(SyntaxKey::Hints).arg.value; } } current = current.nextNode(); @@ -3376,23 +3592,6 @@ void Compiler::generateClassStaticField(ClassScope& scope, SyntaxNode node, Fiel } } -inline bool checkPreviousDeclaration(SyntaxNode node, ustr_t name) -{ - SyntaxNode current = node.prevNode(); - while (current != SyntaxKey::None) { - if (current == SyntaxKey::Field) { - ustr_t currentName = node.findChild(SyntaxKey::Name).firstChild(SyntaxKey::TerminalMask).identifier(); - - if (currentName.compare(name)) - return true; - } - - current = current.prevNode(); - } - - return false; -} - inline bool isInterface(int flagMask) { return flagMask == elInterface || flagMask == elWeakInterface; @@ -3536,12 +3735,7 @@ DeclResult Compiler::checkAndGenerateClassField(ClassScope& scope, SyntaxNode no } if (!generateClassField(scope, attrs, name, sizeHint, typeInfo, singleField)) { - if (attrs.overrideMode && checkPreviousDeclaration(node, name)) { - // override the field type if both declared in the same scope - auto it = scope.info.fields.getIt(name); - (*it).typeInfo = typeInfo; - } - else return DeclResult::Illegal; + return DeclResult::Illegal; } if (attrs.privateOne) @@ -3603,6 +3797,16 @@ void Compiler::declareSymbol(SymbolScope& scope, SyntaxNode node) declareSymbolAttributes(scope, node, false); declareSymbolMetaInfo(scope, node); + if (scope.type == SymbolKind::ExternVar) { + auto externalInfo = mapExternalVariable(scope, node, 0); + + scope.info.symbolType = SymbolType::External; + scope.info.valueRef = externalInfo.reference; + + // external variable must be handled only in declaration pass + node.setKey(SyntaxKey::Idle); + } + scope.save(); } @@ -3671,18 +3875,21 @@ void Compiler::declareMetaInfo(Scope& scope, SyntaxNode node) } } -void Compiler::declareFieldMetaInfo(FieldScope& scope, SyntaxNode node) +void Compiler :: declareFieldMetaInfo(FieldScope& scope, SyntaxNode node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { switch (current.key) { case SyntaxKey::InlineTemplate: + // NOTE : that node variable can be updated inside importPropertyTemplate, pointing to a actual field! if (!importPropertyTemplate(scope, current, INLINE_PROPERTY_PREFIX, node)) { if (!importInlineTemplate(scope, current, INLINE_PROPERTY_PREFIX, node)) scope.raiseError(errUnknownTemplate, node); } + break; case SyntaxKey::InlinePropertyTemplate: + // NOTE : that node variable can be updated inside importPropertyTemplate, pointing to a actual field! if (!importPropertyTemplate(scope, current, INLINE_PROPERTY_PREFIX, node)) { @@ -3708,6 +3915,7 @@ void Compiler::declareFieldMetaInfo(FieldScope& scope, SyntaxNode node) break; case SyntaxKey::Name: case SyntaxKey::Type: + case SyntaxKey::NullableType: case SyntaxKey::TemplateType: case SyntaxKey::Attribute: case SyntaxKey::Dimension: @@ -3723,6 +3931,31 @@ void Compiler::declareFieldMetaInfo(FieldScope& scope, SyntaxNode node) } } +void Compiler :: declareShortcutMetaInfo(Scope& scope, SyntaxNode node) +{ + SyntaxNode current = node.firstChild(); + while (current != SyntaxKey::None) { + switch (current.key) { + case SyntaxKey::InlineTemplate: + if (!importInlineTemplate(scope, current, INLINE_PREFIX, node)) + scope.raiseError(errUnknownTemplate, node); + + current.setKey(SyntaxKey::Idle); + break; + case SyntaxKey::ImportStatement: + if (declareImport(scope, current)) { + current.setKey(SyntaxKey::Idle); + } + else scope.raiseError(errInvalidSyntax, current); + break; + default: + break; + } + + current = current.nextNode(); + } +} + void Compiler::declareSymbolMetaInfo(SymbolScope& scope, SyntaxNode node) { SyntaxNode current = node.firstChild(); @@ -3861,6 +4094,36 @@ void Compiler::declareParameter(MethodScope& scope, SyntaxNode current, bool wit nillable |= paramTypeInfo.nillable; } +void Compiler :: declareParameters(MethodScope& scope, SyntaxNode node, bool withoutWeakMessages, bool declarationMode, + bool& variadicMode, bool& weakSignature, bool& noSignature, pos_t& paramCount, size_t& signatureLen, ref_t* signature) +{ + int argMask = 1; + int nillableArgs = 0; + + // if method has an argument list + SyntaxNode current = node.findChild(SyntaxKey::Parameter); + while (current != SyntaxKey::None) { + if (current == SyntaxKey::Parameter) { + bool nillable = false; + declareParameter(scope, current, withoutWeakMessages, + declarationMode, variadicMode, weakSignature, noSignature, + paramCount, signature, signatureLen, nillable); + + if (nillable) + { + nillableArgs |= argMask; + } + } + else break; + + current = current.nextNode(); + argMask <<= 1; + } + + if (nillableArgs) + scope.info.nillableArgs = nillableArgs; +} + void Compiler :: declareVMTMessage(MethodScope& scope, SyntaxNode node, bool withoutWeakMessages, bool declarationMode, bool templateBasedMode) { IdentifierString actionStr; @@ -3901,32 +4164,11 @@ void Compiler :: declareVMTMessage(MethodScope& scope, SyntaxNode node, bool wit flags |= FUNCTION_MESSAGE; } - int nillableArgs = 0; - int argMask = 1; bool mixinFunction = false; bool noSignature = true; // NOTE : is similar to weakSignature except if withoutWeakMessages=true - // if method has an argument list - SyntaxNode current = node.findChild(SyntaxKey::Parameter); - while (current != SyntaxKey::None) { - if (current == SyntaxKey::Parameter) { - bool nillable = false; - declareParameter(scope, current, withoutWeakMessages, - declarationMode, variadicMode, weakSignature, noSignature, - paramCount, signature, signatureLen, nillable); - if (nillable) - { - nillableArgs |= argMask; - } - } - else break; - - current = current.nextNode(); - argMask <<= 1; - } - - if (nillableArgs) - scope.info.nillableArgs = nillableArgs; + declareParameters(scope, node, withoutWeakMessages, declarationMode, + variadicMode, weakSignature, noSignature, paramCount, signatureLen, signature); // if the signature consists only of generic parameters - ignore it if (weakSignature) @@ -4212,6 +4454,40 @@ bool inline isExtensionDeclaration(SyntaxNode node) return false; } +bool Compiler :: evalCondStatement(Scope& scope, SyntaxNode& node) +{ + MetaScope metaScope(&scope, Scope::ScopeLevel::Namespace); + + ObjectInfo retVal = evalExpression(metaScope, node.firstChild()); + + return (retVal.typeInfo.typeRef == V_FLAG && retVal.extra == -1); +} + +void Compiler :: skipCondStatement(SyntaxNode& node) +{ + node.setKey(SyntaxKey::Idle); + + int level = 0; + while (node != SyntaxKey::None) { + node = node.nextNode(); + + if (node == SyntaxKey::CondStatement) { + level++; + node.setKey(SyntaxKey::Idle); + } + else if (node == SyntaxKey::ElseCondStatement && level == 0) { + break; + } + else if (node != SyntaxKey::EndCondStatement || level > 0) { + if (node == SyntaxKey::EndCondStatement) + level--; + + node.setKey(SyntaxKey::Idle); + } + else break; + } +} + void Compiler::declareFieldMetaInfos(ClassScope& scope, SyntaxNode node) { SyntaxNode current = node.firstChild(); @@ -4277,7 +4553,7 @@ ObjectInfo Compiler::evalExprValueOperation(Interpreter& interpreter, Scope& sco return {}; } -ObjectInfo Compiler::evalSizeOperation(Interpreter& interpreter, Scope& scope, SyntaxNode node, bool ignoreErrors) +ObjectInfo Compiler::evalSizeOperation(Interpreter& interpreter, Scope& scope, SyntaxNode node, bool ignoreErrors, bool metaMode) { SyntaxNode lnode = node.firstChild(SyntaxKey::DeclarationMask); @@ -4299,7 +4575,7 @@ ObjectInfo Compiler::evalSizeOperation(Interpreter& interpreter, Scope& scope, S break; } - if (sizeInfo.size > 0) + if (sizeInfo.size > 0 || metaMode) return { ObjectKind::IntLiteral, { V_INT32 }, ::mapIntConstant(scope.moduleScope, sizeInfo.size), sizeInfo.size }; if (!ignoreErrors) { @@ -4430,6 +4706,7 @@ ObjectInfo Compiler::evalCollection(Interpreter& interpreter, Scope& scope, Synt ref_t collectionTypeRef = 0; ref_t elementTypeRef = 0; + bool numericOne = false; if (!anonymousOne) { ObjectInfo objectInfo = evalObject(interpreter, scope, current); @@ -4453,6 +4730,7 @@ ObjectInfo Compiler::evalCollection(Interpreter& interpreter, Scope& scope, Synt auto fieldInfo = *(collectionInfo.fields.start()); elementTypeRef = resolveStrongType(scope, { fieldInfo.typeInfo.elementRef }); + numericOne = _logic->isNumericType(*scope.moduleScope, elementTypeRef); } ArgumentsInfo arguments; @@ -4462,6 +4740,12 @@ ObjectInfo Compiler::evalCollection(Interpreter& interpreter, Scope& scope, Synt argInfo.typeInfo.typeRef = resolveStrongType(scope, argInfo.typeInfo); + ref_t typeRef = argInfo.typeInfo.typeRef; + if (argInfo.kind == ObjectKind::IntLiteral && numericOne) { + // HOTFIX : convert int literal in place + argInfo = convertIntLiteral(scope, node, argInfo, elementTypeRef); + } + if (!isConstant(argInfo.kind) || (elementTypeRef && !_logic->isCompatible(*scope.moduleScope, { elementTypeRef }, argInfo.typeInfo, true))) { @@ -4483,9 +4767,12 @@ ObjectInfo Compiler::evalCollection(Interpreter& interpreter, Scope& scope, Synt node.setArgumentReference(nestedRef); } + int size = 0; bool byValue = _logic->isEmbeddableArray(*scope.moduleScope, collectionTypeRef); + if (byValue) + size = _logic->defineStructSize(*scope.moduleScope, elementTypeRef).size; - return interpreter.createConstCollection(nestedRef, collectionTypeRef, arguments, byValue); + return interpreter.createConstCollection(nestedRef, collectionTypeRef, arguments, byValue, size); } ObjectInfo Compiler::evalExpression(Interpreter& interpreter, Scope& scope, SyntaxNode node, bool ignoreErrors, bool resolveMode) @@ -4509,11 +4796,21 @@ ObjectInfo Compiler::evalExpression(Interpreter& interpreter, Scope& scope, Synt case SyntaxKey::AddAssignOperation: case SyntaxKey::NameOperation: case SyntaxKey::ReferOperation: + case SyntaxKey::IndexerOperation: + case SyntaxKey::GreaterOperation: + case SyntaxKey::NotGreaterOperation: + case SyntaxKey::EqualOperation: + case SyntaxKey::NotEqualOperation: + case SyntaxKey::LessOperation: + case SyntaxKey::NotLessOperation: retVal = evalOperation(interpreter, scope, node, (int)node.key - OPERATOR_MAKS, ignoreErrors); break; case SyntaxKey::ExprValOperation: retVal = evalExprValueOperation(interpreter, scope, node, ignoreErrors); break; + case SyntaxKey::SizeOperation: + retVal = evalSizeOperation(interpreter, scope, node, ignoreErrors, true); + break; case SyntaxKey::Object: retVal = evalObject(interpreter, scope, node); if (!ignoreErrors && retVal.kind == ObjectKind::Unknown) { @@ -4583,7 +4880,7 @@ ObjectInfo Compiler::evalExpression(Interpreter& interpreter, Scope& scope, Synt return retVal; } -void Compiler::evalStatement(MetaScope& scope, SyntaxNode node) +void Compiler :: evalStatement(MetaScope& scope, SyntaxNode node) { Interpreter interpreter(scope.moduleScope, _logic); @@ -4592,6 +4889,17 @@ void Compiler::evalStatement(MetaScope& scope, SyntaxNode node) scope.raiseError(errCannotEval, node); } +ObjectInfo Compiler :: evalExpression(MetaScope& scope, SyntaxNode node) +{ + Interpreter interpreter(scope.moduleScope, _logic); + + ObjectInfo retVal = evalExpression(interpreter, scope, node); + if (retVal.kind == ObjectKind::Unknown) + scope.raiseError(errCannotEval, node); + + return retVal; +} + inline bool hasToBePresaved(ObjectInfo retVal) { return retVal.kind == ObjectKind::Object || retVal.kind == ObjectKind::Extern || retVal.kind == ObjectKind::FloatExtern @@ -4760,6 +5068,7 @@ ref_t Compiler :: resolvePrimitiveType(ModuleScopeBase& moduleScope, TypeInfo ty case V_WRAPPER: case V_OUTWRAPPER: return resolveWrapperTemplate(moduleScope, typeInfo.elementRef, declarationMode); + case V_UINT8ARRAY: case V_INT8ARRAY: case V_INT16ARRAY: case V_INT32ARRAY: @@ -4784,13 +5093,35 @@ ref_t Compiler :: resolvePrimitiveType(ModuleScopeBase& moduleScope, TypeInfo ty } } -void Compiler::declareClassAttributes(ClassScope& scope, SyntaxNode node, ref_t& flags) +bool isFunctionClass(SyntaxNode node) +{ + int counter = 0; + + SyntaxNode current = node.firstChild(); + while (current != SyntaxKey::None) { + if (current == SyntaxKey::Method) { + if (counter > 0) + return false; + + if (!SyntaxTree::ifChildExists(current, SyntaxKey::Attribute, V_FUNCTION)) + return false; + + counter++; + } + + current = current.nextNode(); + } + + return true; +} + +void Compiler :: declareClassAttributes(ClassScope& scope, SyntaxNode node, ref_t& flags, bool& externalOne) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { switch (current.key) { case SyntaxKey::Attribute: - if (!_logic->validateClassAttribute(current.arg.value, flags, scope.visibility)) { + if (!_logic->validateClassAttribute(current.arg.value, flags, scope.visibility, externalOne)) { current.setArgumentValue(0); // HOTFIX : to prevent duplicate warnings scope.raiseWarning(WARNING_LEVEL_1, wrnInvalidHint, current); } @@ -4805,6 +5136,12 @@ void Compiler::declareClassAttributes(ClassScope& scope, SyntaxNode node, ref_t& current = current.nextNode(); } + if (externalOne) { + // NOTE : validate if it is the external callback + if (!test(flags, elRole | elSealed | elStateless) || !isFunctionClass(node)) + scope.raiseError(errInvalidSyntax, current); + } + // handle the abstract flag if (test(scope.info.header.flags, elAbstract)) { // clear the interface flag by inheriting @@ -4851,11 +5188,14 @@ void Compiler::declareSymbolAttributes(SymbolScope& scope, SyntaxNode node, bool current = current.nextNode(); } - if (scope.visibility == Visibility::Public) { + if (scope.visibility == Visibility::Public && scope.type != SymbolKind::ExternVar) { scope.info.loadableInRuntime = true; } if (constant && !identifierDeclarationMode) { + if (scope.type == SymbolKind::ExternVar) + scope.raiseError(errInvalidOperation, node); // !! currently external variable cannot be constant + scope.info.symbolType = SymbolType::Constant; Interpreter interpreter(scope.moduleScope, _logic); @@ -4978,6 +5318,7 @@ void Compiler::declareMethodAttributes(MethodScope& scope, SyntaxNode node, bool break; } case SyntaxKey::Type: + case SyntaxKey::NullableType: case SyntaxKey::ArrayType: case SyntaxKey::TemplateType: // if it is a type attribute @@ -5534,7 +5875,7 @@ void Compiler::declareTemplateAttributes(Scope& scope, SyntaxNode node, case SyntaxKey::TemplateType: { auto typeInfo = resolveStrongTypeAttribute(scope, current, declarationMode, attributes.mssgNameLiteral); - parameters.add(typeInfo.typeRef); + parameters.add(typeInfo); break; } @@ -5588,7 +5929,7 @@ ObjectInfo Compiler::defineArrayType(Scope& scope, ObjectInfo info, bool declara return info; } -ref_t Compiler::resolveTypeTemplate(Scope& scope, SyntaxNode node, +TypeInfo Compiler::resolveTypeTemplate(Scope& scope, SyntaxNode node, TypeAttributes& attributes, bool declarationMode, bool objectMode) { TemplateTypeList typeList; @@ -5703,6 +6044,7 @@ ref_t Compiler::resolveArgArrayTemplate(ModuleScopeBase& moduleScope, ref_t elem TypeInfo Compiler::resolveTypeScope(Scope& scope, SyntaxNode node, TypeAttributes& attributes, bool declarationMode, bool allowRole) { + bool nullable = false; ref_t elementRef = 0; SyntaxNode current = node.firstChild(); @@ -5718,11 +6060,15 @@ TypeInfo Compiler::resolveTypeScope(Scope& scope, SyntaxNode node, TypeAttribute case SyntaxKey::TemplateType: elementRef = resolveTypeAttribute(scope, current, attributes, declarationMode, allowRole).typeRef; break; + case SyntaxKey::NullableType: + elementRef = resolveTypeAttribute(scope, current, attributes, declarationMode, allowRole).typeRef; + nullable = true; + break; case SyntaxKey::identifier: case SyntaxKey::reference: - elementRef = resolveTypeIdentifier(scope, current.identifier(), node.key, declarationMode, allowRole); + case SyntaxKey::globalreference: + elementRef = resolveTypeIdentifier(scope, current.identifier(), current.key, declarationMode, allowRole); break; - case SyntaxKey::NullableType: case SyntaxKey::ArrayType: elementRef = resolvePrimitiveType(*scope.moduleScope, resolveTypeAttribute(scope, current, attributes, declarationMode, allowRole), declarationMode); @@ -5739,7 +6085,7 @@ TypeInfo Compiler::resolveTypeScope(Scope& scope, SyntaxNode node, TypeAttribute if (attributes.variadicOne) { return { V_ARGARRAY, elementRef }; } - else return { defineArrayType(scope, elementRef, declarationMode), elementRef }; + else return { defineArrayType(scope, elementRef, declarationMode), elementRef, nullable }; } else if (node == SyntaxKey::NullableType) { return { elementRef, 0, true }; @@ -5766,20 +6112,20 @@ TypeInfo Compiler::resolveTypeAttribute(Scope& scope, SyntaxNode node, TypeAttri typeInfo = resolveTypeAttribute(scope, current, attributes, declarationMode, allowRole); } else if (current == SyntaxKey::TemplateType) { - typeInfo.typeRef = resolveTypeTemplate(scope, current, attributes, declarationMode); + typeInfo = resolveTypeTemplate(scope, current, attributes, declarationMode); } else if (SyntaxTree::test(current.key, SyntaxKey::TerminalMask)) { if (current.nextNode() == SyntaxKey::TemplateArg) { // !! should be refactored : TemplateType should be used instead - typeInfo.typeRef = resolveTypeTemplate(scope, current, attributes, declarationMode); + typeInfo = resolveTypeTemplate(scope, current, attributes, declarationMode); } - else typeInfo.typeRef = resolveTypeIdentifier(scope, current.identifier(), current.key, declarationMode, allowRole); + else typeInfo = resolveTypeIdentifier(scope, current.identifier(), current.key, declarationMode, allowRole); } else assert(false); break; } case SyntaxKey::TemplateType: - typeInfo.typeRef = resolveTypeTemplate(scope, node, attributes, declarationMode); + typeInfo = resolveTypeTemplate(scope, node, attributes, declarationMode); break; case SyntaxKey::ArrayType: { @@ -5848,6 +6194,7 @@ void Compiler::readFieldAttributes(ClassScope& scope, SyntaxNode node, FieldAttr break; case SyntaxKey::Type: case SyntaxKey::TemplateType: + case SyntaxKey::NullableType: if (!attrs.typeInfo.typeRef) { TypeAttributes typeAttributes = {}; @@ -6110,38 +6457,9 @@ void Compiler :: markYieldVariable(Scope& scope, ref_t localOffset) smScope->localMappings.add(localOffset, fieldInfo.reference); } -bool Compiler::declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeInfo, bool ignoreDuplicate) +DeclarationError Compiler :: declareVariable(Scope& scope, ustr_t identifier, TypeInfo typeInfo, ObjectInfo& variable, int& size, + ExprScope* exprScope, CodeScope* codeScope, MethodScope* methodScope) { - int size = 0; - if (terminal == SyntaxKey::IndexerOperation) { - // COMPILER MAGIC : if it is a fixed-sized array - size = resolveArraySize(scope, terminal.firstChild(SyntaxKey::ScopeMask)); - - terminal = terminal.findChild(SyntaxKey::Object).findChild(SyntaxKey::identifier); - } - - ExprScope* exprScope = Scope::getScope(scope, Scope::ScopeLevel::Expr); - CodeScope* codeScope = Scope::getScope(scope, Scope::ScopeLevel::Code); - MethodScope* methodScope = Scope::getScope(scope, Scope::ScopeLevel::Method); - if (codeScope == nullptr) { - scope.raiseError(errInvalidOperation, terminal); - return false; // the code will never be reached - } - - IdentifierString identifier(terminal.identifier()); - if (ignoreDuplicate) { - auto var = codeScope->mapIdentifier(*identifier, false, EAttr::None); - switch (var.kind) { - case ObjectKind::Local: - case ObjectKind::LocalAddress: - // exit if the variable with this names does exist - return false; - default: - break; - } - } - - ObjectInfo variable; variable.typeInfo = typeInfo; variable.kind = ObjectKind::Local; @@ -6151,7 +6469,7 @@ bool Compiler::declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeI variable.typeInfo.elementRef = variable.typeInfo.typeRef; variable.typeInfo.typeRef = _logic->definePrimitiveArray(*scope.moduleScope, variable.typeInfo.elementRef, true); } - else scope.raiseError(errInvalidHint, terminal); + else return DeclarationError::Hint; } else if (_logic->isPrimitiveArrRef(variable.typeInfo.typeRef)) { // if it is an array reference @@ -6162,7 +6480,7 @@ bool Compiler::declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeI ClassInfo localInfo; //bool binaryArray = false; if (!_logic->defineClassInfo(*scope.moduleScope, localInfo, variable.typeInfo.typeRef)) - scope.raiseError(errUnknownVariableType, terminal); + return DeclarationError::Type; if (variable.typeInfo.typeRef == V_BINARYARRAY) // HOTFIX : recognize binary array actual size @@ -6181,7 +6499,7 @@ bool Compiler::declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeI variable.reference = allocateLocalAddress(*codeScope, size, false); } else if (size != 0) { - scope.raiseError(errInvalidOperation, terminal); + return DeclarationError::Operation; } else { variable.reference = codeScope->newLocal(); @@ -6194,11 +6512,64 @@ bool Compiler::declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeI if (exprScope) exprScope->syncStack(); - if (!codeScope->locals.exist(*identifier)) { - codeScope->mapNewLocal(*identifier, variable.reference, variable.typeInfo, + if (!codeScope->locals.exist(identifier)) { + codeScope->mapNewLocal(identifier, variable.reference, variable.typeInfo, size, true); } - else scope.raiseError(errDuplicatedLocal, terminal); + else return DeclarationError::Duplicate; + + return DeclarationError::None; +} + +bool Compiler::declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeInfo, bool ignoreDuplicate) +{ + int size = 0; + if (terminal == SyntaxKey::IndexerOperation) { + // COMPILER MAGIC : if it is a fixed-sized array + size = resolveArraySize(scope, terminal.firstChild(SyntaxKey::ScopeMask)); + + terminal = terminal.findChild(SyntaxKey::Object).findChild(SyntaxKey::identifier); + } + + ExprScope* exprScope = Scope::getScope(scope, Scope::ScopeLevel::Expr); + CodeScope* codeScope = Scope::getScope(scope, Scope::ScopeLevel::Code); + MethodScope* methodScope = Scope::getScope(scope, Scope::ScopeLevel::Method); + if (codeScope == nullptr) { + scope.raiseError(errInvalidOperation, terminal); + return false; // the code will never be reached + } + + IdentifierString identifier(terminal.identifier()); + if (ignoreDuplicate) { + auto var = codeScope->mapIdentifier(*identifier, false, EAttr::None); + switch (var.kind) { + case ObjectKind::Local: + case ObjectKind::LocalAddress: + // exit if the variable with this names does exist + return false; + default: + break; + } + } + + ObjectInfo variable = {}; + DeclarationError err = declareVariable(scope, *identifier, typeInfo, variable, size, exprScope, codeScope, methodScope); + switch (err) { + case DeclarationError::Hint: + scope.raiseError(errInvalidHint, terminal); + break; + case DeclarationError::Duplicate: + scope.raiseError(errDuplicatedLocal, terminal); + break; + case DeclarationError::Type: + scope.raiseError(errUnknownVariableType, terminal); + break; + case DeclarationError::Operation: + scope.raiseError(errInvalidOperation, terminal); + break; + default: + break; + } if (_trackingUnassigned) { if (size > 0) { @@ -6456,21 +6827,35 @@ ObjectInfo Compiler::mapClassSymbol(Scope& scope, ref_t classRef) else return {}; } -ExternalInfo Compiler::mapExternal(Scope& scope, SyntaxNode node) +ExternalInfo Compiler :: mapExternal(Scope& scope, SyntaxNode node, ref_t nameRef) { - SyntaxNode objNode = node.parentNode(); - - ustr_t dllAlias = node.identifier(); - ustr_t functionName = SyntaxTree::gotoNode(objNode, SyntaxKey::Message).firstChild(SyntaxKey::TerminalMask).identifier(); + ustr_t dllAlias = node.firstChild(SyntaxKey::TerminalMask).identifier(); + ustr_t functionName = SyntaxTree::gotoNode(node, SyntaxKey::Message).firstChild(SyntaxKey::TerminalMask).identifier(); if (functionName.empty()) { functionName = dllAlias; dllAlias = RT_FORWARD; } + else if (nameRef) + dllAlias = scope.module->resolveConstant(nameRef); return scope.moduleScope->mapExternal(dllAlias, functionName); } +ExternalInfo Compiler :: mapExternalVariable(Scope& scope, SyntaxNode node, ref_t nameRef) +{ + IdentifierString variableName("##", node.findChild(SyntaxKey::Name).firstChild(SyntaxKey::TerminalMask).identifier()); + ustr_t dllAlias = node.firstChild(SyntaxKey::GetExpression).firstChild(SyntaxKey::Expression).findChild(SyntaxKey::Object).firstChild(SyntaxKey::TerminalMask).identifier(); + + if (dllAlias.empty() || variableName.length() <= 2) + scope.raiseError(errInvalidOperation, node); + + if (nameRef) + dllAlias = scope.module->resolveConstant(nameRef); + + return scope.moduleScope->mapExternal(dllAlias, *variableName); +} + SyntaxNode Compiler::addStaticInitializerMethod(ClassScope& scope, SyntaxNode node) { SyntaxNode rootNode = node.parentNode(); @@ -6566,47 +6951,48 @@ mssg_t Compiler::resolveOperatorMessage(ModuleScopeBase* scope, int operatorId) inline bool isPrimitiveArray(ref_t typeRef) { switch (typeRef) { - case V_BINARYARRAY: - case V_OBJARRAY: - case V_INT32ARRAY: - case V_INT8ARRAY: - case V_INT16ARRAY: - case V_FLOAT64ARRAY: - return true; - default: - return false; + case V_BINARYARRAY: + case V_OBJARRAY: + case V_INT32ARRAY: + case V_INT8ARRAY: + case V_UINT8ARRAY: + case V_INT16ARRAY: + case V_FLOAT64ARRAY: + return true; + default: + return false; } } inline bool DoesOperationSupportConvertableIntLiteral(int operatorId) { switch (operatorId) { - case ADD_OPERATOR_ID: - case SUB_OPERATOR_ID: - case LESS_OPERATOR_ID: - case EQUAL_OPERATOR_ID: - case NOTEQUAL_OPERATOR_ID: - case ELSE_OPERATOR_ID: - case MUL_OPERATOR_ID: - case DIV_OPERATOR_ID: - case NOTLESS_OPERATOR_ID: - case GREATER_OPERATOR_ID: - case NOTGREATER_OPERATOR_ID: - case BAND_OPERATOR_ID: - case BOR_OPERATOR_ID: - case BXOR_OPERATOR_ID: - case BNOT_OPERATOR_ID: - case AND_OPERATOR_ID: - case OR_OPERATOR_ID: - case XOR_OPERATOR_ID: - case ADD_ASSIGN_OPERATOR_ID: - case SUB_ASSIGN_OPERATOR_ID: - case MUL_ASSIGN_OPERATOR_ID: - case DIV_ASSIGN_OPERATOR_ID: - case SET_INDEXER_OPERATOR_ID: - return true; - default: - return false; + case ADD_OPERATOR_ID: + case SUB_OPERATOR_ID: + case LESS_OPERATOR_ID: + case EQUAL_OPERATOR_ID: + case NOTEQUAL_OPERATOR_ID: + case ELSE_OPERATOR_ID: + case MUL_OPERATOR_ID: + case DIV_OPERATOR_ID: + case NOTLESS_OPERATOR_ID: + case GREATER_OPERATOR_ID: + case NOTGREATER_OPERATOR_ID: + case BAND_OPERATOR_ID: + case BOR_OPERATOR_ID: + case BXOR_OPERATOR_ID: + case BNOT_OPERATOR_ID: + case AND_OPERATOR_ID: + case OR_OPERATOR_ID: + case XOR_OPERATOR_ID: + case ADD_ASSIGN_OPERATOR_ID: + case SUB_ASSIGN_OPERATOR_ID: + case MUL_ASSIGN_OPERATOR_ID: + case DIV_ASSIGN_OPERATOR_ID: + case SET_INDEXER_OPERATOR_ID: + return true; + default: + return false; } } @@ -6900,19 +7286,6 @@ inline bool isConditionalOp(SyntaxKey key) } } -inline bool isSimpleNode(SyntaxNode node) -{ - SyntaxNode current = node.firstChild(); - - if (current == SyntaxKey::Expression && current.nextNode() == SyntaxKey::None) { - return isSimpleNode(current); - } - else if (current == SyntaxKey::Object && current.nextNode() == SyntaxKey::None) { - return true; - } - return false; -} - inline SyntaxNode skipNestedExpression(SyntaxNode node) { if (node == SyntaxKey::Expression) { @@ -7233,6 +7606,49 @@ ObjectInfo Compiler::defineTerminalInfo(Scope& scope, SyntaxNode node, TypeInfo return retVal; } +void Compiler :: declareShortcut(NamespaceScope& scope, SyntaxNode node) +{ + SyntaxNode nameNode = node.findChild(SyntaxKey::Name); + SyntaxNode identNode = nameNode.firstChild(SyntaxKey::TerminalMask); + SyntaxNode postfix = node.findChild(SyntaxKey::InlineTemplate); + + SyntaxNode current = node.firstChild().nextNode(); + + // generate an expected expression + SyntaxTree exprTree; + SyntaxTreeWriter exprWriter(exprTree); + exprWriter.newNode(SyntaxKey::Root); + while (current != SyntaxKey::None) { + if (current != postfix) { + SyntaxTree::copyNode(exprWriter, current, current != SyntaxKey::Name); + } + else break; + + current = current.nextNode(); + } + exprWriter.closeNode(); + + ReferenceName name; + ReferenceName::copyProperName(name, identNode.identifier()); + + ObjectInfo info = mapObject(scope, exprTree.readRoot(), EAttr::None); + switch (info.kind) { + case ObjectKind::ExternLibrary: + case ObjectKind::Class: + scope.shortcuts.add(*name, info); + break; + default: + scope.raiseError(errInvalidOperation, node); + break; + } + + if (postfix != SyntaxKey::None) { + ShortcutScope shortcutScope(&scope, info); + + declareShortcutMetaInfo(shortcutScope, node); + } +} + ObjectInfo Compiler::mapTerminal(Scope& scope, SyntaxNode node, TypeInfo declaredTypeInfo, EAttr attrs) { bool externalOp = EAttrs::testAndExclude(attrs, ExpressionAttribute::Extern); @@ -7252,13 +7668,9 @@ ObjectInfo Compiler::mapTerminal(Scope& scope, SyntaxNode node, TypeInfo declare ObjectInfo retVal; bool invalid = false; if (externalOp) { - auto externalInfo = mapExternal(scope, node); - switch (externalInfo.type) { - case ExternalType::WinApi: - return { ObjectKind::Extern, {}, externalInfo.reference, 0, TargetMode::WinApi }; - default: - return { ObjectKind::Extern, {}, externalInfo.reference, 0, TargetMode::External }; - } + ustr_t externLibName = scope.moduleScope->resolveImport(node.identifier()); + + return { ObjectKind::ExternLibrary, {}, scope.module->mapConstant(externLibName), TargetMode::External}; } else if (newOp || castOp) { if (node.key == SyntaxKey::identifier && EAttrs::testAndExclude(attrs, ExpressionAttribute::RetrievingType)) { @@ -7380,7 +7792,7 @@ inline bool isNormalConstant(ObjectInfo info) } } -ObjectInfo Compiler::convertIntLiteral(ExprScope& scope, SyntaxNode node, ObjectInfo source, ref_t targetRef, bool ignoreError) +ObjectInfo Compiler::convertIntLiteral(Scope& scope, SyntaxNode node, ObjectInfo source, ref_t targetRef, bool ignoreError) { bool invalid = false; switch (targetRef) { @@ -7913,6 +8325,13 @@ ObjectInfo Compiler :: compileCode(BuildTreeWriter& writer, CodeScope& codeScope case SyntaxKey::EOP: addBreakpoint(writer, current, BuildKey::EOPBreakpoint); break; + case SyntaxKey::ElseCondStatement: + case SyntaxKey::CondStatement: + if (!evalCondStatement(codeScope, current)) { + skipCondStatement(current); + continue; + } + break; default: break; } @@ -8720,6 +9139,98 @@ void Compiler :: compileAsyncInvoker(BuildTreeWriter& writer, MethodScope& metho writer.appendNode(BuildKey::CloseFrame); } +inline bool isArg32(CompilerLogic* logic, ModuleScopeBase* moduleScope, ref_t typeRef) +{ + return logic->isCompatible(*moduleScope, { V_INT32 }, { typeRef }, false) + || logic->isCompatible(*moduleScope, { V_PTR32 }, { typeRef }, false) + || logic->isCompatible(*moduleScope, { V_UINT32 }, { typeRef }, false); +} + +inline bool isArg64(CompilerLogic* logic, ModuleScopeBase* moduleScope, ref_t typeRef) +{ + return logic->isCompatible(*moduleScope, { V_INT64 }, { typeRef }, false) + || logic->isCompatible(*moduleScope, { V_PTR64 }, { typeRef }, false); +} + +void Compiler :: compileExternalCallback(BuildTreeWriter& writer, SymbolScope& scope, SyntaxNode node) +{ + MethodScope dummyScope(&scope); + ref_t signature[ARG_COUNT] = {}; + size_t signatureLen = 0; + + pos_t paramCount = 0; + + bool variadicMode = false; + bool weakSignature = false; + bool noSignature = false; + declareParameters(dummyScope, node, true, false, + variadicMode, weakSignature, noSignature, paramCount, signatureLen, signature); + + if (variadicMode || weakSignature) + scope.raiseError(errInvalidOperation, node); + + writer.newNode(BuildKey::Procedure, scope.reference); + + NamespaceScope* ns = Scope::getScope(scope, Scope::ScopeLevel::Namespace); + writer.appendNode(BuildKey::Path, *ns->sourcePath); + + writer.newNode(BuildKey::Tape); + + writer.appendNode(BuildKey::OpenExtFrame); + + CodeScope codeScope(&scope); + + if (paramCount > 0) { + // declare the output argument as a stack allocated variable and copy the values + for (auto p_it = dummyScope.parameters.start(); !p_it.eof(); ++p_it) { + Parameter param = *p_it; + ObjectInfo variable = {}; + + int size = 0; + auto err = declareVariable(scope, p_it.key(), param.typeInfo, variable, size, nullptr, &codeScope, nullptr); + assert(err == DeclarationError::None); + + writer.appendNode(BuildKey::LoadExtArg, -param.offset); + + if (isArg32(_logic, scope.moduleScope, param.typeInfo.typeRef)) { + writer.appendNode(BuildKey::SavingIndex, variable.reference); + } + else if (isArg64(_logic, scope.moduleScope, param.typeInfo.typeRef)) { + writer.appendNode(BuildKey::SavingLongIndex, variable.reference); + } + } + } + + ObjectInfo retVal = { }; + + SyntaxNode bodyNode = node.firstChild(SyntaxKey::ScopeMask); + switch (bodyNode.key) { + case SyntaxKey::CodeBlock: + retVal = compileCode(writer, codeScope, bodyNode, true, !_withDebugInfo); + break; + default: + scope.raiseError(errInvalidOperation, bodyNode); + break; + } + + codeScope.syncStack(&scope); + + // load the returning value as external retval + if (!isArg64(_logic, scope.moduleScope, retVal.typeInfo.typeRef) + && !isArg32(_logic, scope.moduleScope, retVal.typeInfo.typeRef)) + { + scope.raiseError(errInvalidOperation, node); + } + + writer.appendNode(BuildKey::CloseExtFrame); + + writer.appendNode(BuildKey::ExtExit); + + writer.closeNode(); + saveFrameAttributes(writer, scope, scope.reserved1 + scope.reservedArgs, scope.reserved2); + writer.closeNode(); +} + void Compiler::writeMessageInfo(BuildTreeWriter& writer, MethodScope& scope) { IdentifierString methodName; @@ -8762,7 +9273,7 @@ void Compiler :: writeParameterDebugInfo(BuildTreeWriter& writer, Scope& scope, if (typeInfo.typeRef == V_INT16ARRAY) { writer.newNode(BuildKey::ShortArrayParameter, name); } - else if (typeInfo.typeRef == V_INT8ARRAY) { + else if (typeInfo.typeRef == V_INT8ARRAY || typeInfo.typeRef == V_UINT8ARRAY) { writer.newNode(BuildKey::ByteArrayParameter, name); } else if (typeInfo.typeRef == V_INT32ARRAY) { @@ -9925,7 +10436,10 @@ void Compiler :: compileNestedClass(BuildTreeWriter& writer, ClassScope& scope, scope.info.attributes.exclude({ 0, ClassAttribute::RuntimeLoadable }); ref_t dummy = 0; - declareClassAttributes(scope, {}, dummy); + bool externalOp = false; + declareClassAttributes(scope, {}, dummy, externalOp); + if (externalOp) + scope.raiseError(errInvalidOperation, node); if (scope.abstractBasedMode && test(scope.info.header.flags, elClosed | elNoCustomDispatcher)) { @@ -10094,6 +10608,13 @@ void Compiler::compileNamespace(BuildTreeWriter& writer, NamespaceScope& ns, Syn } break; } + case SyntaxKey::ExternalFunction: + { + SymbolScope procedureScope(&ns, current.arg.reference, ns.defaultVisibility); + compileExternalCallback(writer, procedureScope, current.findChild(SyntaxKey::Method)); + + break; + } default: // to make compiler happy break; @@ -10320,6 +10841,11 @@ void Compiler :: prepare(ModuleScopeBase* moduleScope, ForwardResolverBase* forw { return current == reference; })); + moduleScope->projectVar.copy(moduleScope->predefined.retrieve("@project_var", V_PROJECT_VAR, + [](ref_t reference, ustr_t key, ref_t current) + { + return current == reference; + })); moduleScope->superVar.copy(moduleScope->predefined.retrieve("@super", V_SUPER_VAR, [](ref_t reference, ustr_t key, ref_t current) { @@ -11091,6 +11617,11 @@ void Compiler::Namespace::declareNamespace(SyntaxNode node, bool ignoreImport, b } } break; + case SyntaxKey::Shortcut: + if (!ignoreImport) { + compiler->declareShortcut(scope, current); + } + break; default: // to make compiler happy break; @@ -11105,48 +11636,59 @@ void Compiler::Namespace::declareMemberIdentifiers(SyntaxNode node) SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { switch (current.key) { - case SyntaxKey::Namespace: - { - Namespace subNamespace(compiler, &scope); - subNamespace.declare(current, false); - break; - } - case SyntaxKey::Symbol: - { - SymbolScope symbolScope(&scope, 0, scope.defaultVisibility); - compiler->declareSymbolAttributes(symbolScope, current, true); + case SyntaxKey::Namespace: + { + Namespace subNamespace(compiler, &scope); + subNamespace.declare(current, false); + break; + } + case SyntaxKey::Symbol: + { + SymbolScope symbolScope(&scope, 0, scope.defaultVisibility); + compiler->declareSymbolAttributes(symbolScope, current, true); - SyntaxNode name = current.findChild(SyntaxKey::Name); + SyntaxNode name = current.findChild(SyntaxKey::Name); - ref_t reference = compiler->mapNewTerminal(symbolScope, nullptr, name, nullptr, symbolScope.visibility); - symbolScope.module->mapSection(reference | mskSymbolRef, false); + ref_t reference = compiler->mapNewTerminal(symbolScope, nullptr, name, nullptr, symbolScope.visibility); + symbolScope.module->mapSection(reference | mskSymbolRef, false); - current.setArgumentReference(reference); - break; - } - case SyntaxKey::Class: - { - ClassScope classScope(&scope, 0, scope.defaultVisibility); + current.setArgumentReference(reference); + break; + } + case SyntaxKey::Class: + { + ClassScope classScope(&scope, 0, scope.defaultVisibility); - ref_t flags = classScope.info.header.flags; - compiler->declareClassAttributes(classScope, current, flags); + ref_t flags = classScope.info.header.flags; + bool externalOp = false; + compiler->declareClassAttributes(classScope, current, flags, externalOp); - SyntaxNode name = current.findChild(SyntaxKey::Name); - if (current.arg.reference == INVALID_REF) { - // if it is a template based class - its name was already resolved - classScope.reference = current.findChild(SyntaxKey::Name).arg.reference; - } - else classScope.reference = compiler->mapNewTerminal(classScope, nullptr, - name, nullptr, classScope.visibility); + SyntaxNode name = current.findChild(SyntaxKey::Name); + if (current.arg.reference == INVALID_REF) { + // if it is a template based class - its name was already resolved + classScope.reference = current.findChild(SyntaxKey::Name).arg.reference; + } + else classScope.reference = compiler->mapNewTerminal(classScope, nullptr, + name, nullptr, classScope.visibility); - classScope.module->mapSection(classScope.reference | mskSymbolRef, false); + if (externalOp) { + classScope.module->mapSection(classScope.reference | mskProcedureRef, false); + } + else classScope.module->mapSection(classScope.reference | mskSymbolRef, false); - current.setArgumentReference(classScope.reference); - break; - } - default: - // to make compiler happy - break; + current.setArgumentReference(classScope.reference); + break; + } + case SyntaxKey::ElseCondStatement: + case SyntaxKey::CondStatement: + if (!compiler->evalCondStatement(scope, current)) { + compiler->skipCondStatement(current); + continue; + } + break; + default: + // to make compiler happy + break; } current = current.nextNode(); @@ -11218,6 +11760,12 @@ bool Compiler::Namespace::declareMembers(SyntaxNode node, bool& repeatMode, bool case SyntaxKey::SharedMetaDictionary: compiler->declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Namespace, true); break; + case SyntaxKey::ImportStatement: + if (compiler->declareImport(scope, current)) { + current.setKey(SyntaxKey::Idle); + } + else scope.raiseError(errInvalidSyntax, current); + break; default: // to make compiler happy break; @@ -11281,8 +11829,19 @@ void Compiler::Class::declare(SyntaxNode node) // HOTFIX : remove inherited loadable attribute scope.info.attributes.exclude({ 0, ClassAttribute::RuntimeLoadable }); + bool externalOp = false; ref_t declaredFlags = 0; - compiler->declareClassAttributes(scope, node, declaredFlags); + compiler->declareClassAttributes(scope, node, declaredFlags, externalOp); + + // HOTFIX : special case - external callback + if (externalOp) { + node.setKey(SyntaxKey::ExternalFunction); + + SymbolInfo procInfo(SymbolType::Procedure, node.arg.reference, 0, false); + SymbolScope::saveSymbolInfo(scope.moduleScope->module, procInfo, node.arg.reference); + + return; + } // NOTE : due to implementation the field meta information should be analyzed before // declaring VMT @@ -12287,14 +12846,12 @@ ObjectInfo Compiler::Expression :: compileMessageOperation(SyntaxNode node, bool probeMode = source.mode == TargetMode::Probe; switch (source.mode) { case TargetMode::External: - case TargetMode::WinApi: { compileMessageArguments(current, arguments, 0, EAttr::None, nullptr, argListType, 0); if (argListType != ArgumentListType::Normal) scope.raiseError(errInvalidOperation, current); - retVal = compileExternalOp(node, source.reference, - source.mode == TargetMode::WinApi, arguments, expectedRef); + retVal = compileExternalOp(current, source.reference, arguments, expectedRef); break; } case TargetMode::CreatingArray: @@ -13359,6 +13916,8 @@ ObjectInfo Compiler::Expression::compileClosureOperation(SyntaxNode node, ref_t int dummy = 0; targetMessage = compiler->_logic->resolveFunctionSingleDispatch(*scope.moduleScope, function.reference, dummy); } + else if (function.kind == ObjectKind::InternalCallback) + return function; } else { targetArg = *scope.moduleScope->selfVar; @@ -13661,9 +14220,12 @@ ref_t Compiler::Expression::compileMessageArguments(SyntaxNode current, Argument return 0; } -ObjectInfo Compiler::Expression::compileExternalOp(SyntaxNode node, ref_t externalRef, - bool stdCall, ArgumentsInfo& arguments, ref_t expectedRef) +ObjectInfo Compiler::Expression::compileExternalOp(SyntaxNode node, ref_t nameRef, + ArgumentsInfo& arguments, ref_t expectedRef) { + auto externalInfo = compiler->mapExternal(scope, node, nameRef); + bool stdCall = externalInfo.type == ExternalType::WinApi; + pos_t count = arguments.count_pos(); writer->appendNode(BuildKey::Allocating, @@ -13692,37 +14254,40 @@ ObjectInfo Compiler::Expression::compileExternalOp(SyntaxNode node, ref_t extern writeObjectInfo(arg, node); switch (arg.kind) { - case ObjectKind::IntLiteral: - writer->appendNode(BuildKey::SavingNInStack, i - 1); - break; - default: - if (compiler->_logic->isCompatible(*scope.moduleScope, { intArgType }, - arg.typeInfo, true)) - { - writer->appendNode(intArgOp, i - 1); - } - // NOTE : it is a duplicate for 32 bit target, but is required for 64 bit one - else if (compiler->_logic->isCompatible(*scope.moduleScope, { V_INT32 }, - arg.typeInfo, true)) - { - writer->appendNode(BuildKey::SavingNInStack, i - 1); - } - else if (compiler->_logic->isCompatible(*scope.moduleScope, { V_INT16 }, - arg.typeInfo, true)) - { - writer->appendNode(BuildKey::SavingNInStack, i - 1); - } - else if (compiler->_logic->isCompatible(*scope.moduleScope, { V_INT8 }, - arg.typeInfo, true)) - { + case ObjectKind::IntLiteral: writer->appendNode(BuildKey::SavingNInStack, i - 1); - } - else writer->appendNode(BuildKey::SavingInStack, i - 1); // !! temporally - passing dynamic references to the exteranl routines should not be allowed - break; + break; + case ObjectKind::InternalCallback: + writer->appendNode(BuildKey::SavingInStack, i - 1); + break; + default: + if (compiler->_logic->isCompatible(*scope.moduleScope, { intArgType }, + arg.typeInfo, true)) + { + writer->appendNode(intArgOp, i - 1); + } + // NOTE : it is a duplicate for 32 bit target, but is required for 64 bit one + else if (compiler->_logic->isCompatible(*scope.moduleScope, { V_INT32 }, + arg.typeInfo, true)) + { + writer->appendNode(BuildKey::SavingNInStack, i - 1); + } + else if (compiler->_logic->isCompatible(*scope.moduleScope, { V_INT16 }, + arg.typeInfo, true)) + { + writer->appendNode(BuildKey::SavingNInStack, i - 1); + } + else if (compiler->_logic->isCompatible(*scope.moduleScope, { V_INT8 }, + arg.typeInfo, true)) + { + writer->appendNode(BuildKey::SavingNInStack, i - 1); + } + else writer->appendNode(BuildKey::SavingInStack, i - 1); // !! temporally - passing dynamic references to the exteranl routines should not be allowed + break; } } - writer->newNode(BuildKey::ExtCallOp, externalRef); + writer->newNode(BuildKey::ExtCallOp, externalInfo.reference); BuildNode opNode = writer->CurrentNode(); @@ -14505,6 +15070,12 @@ bool Compiler::Expression::writeObjectInfo(ObjectInfo info, bool allowMeta) case ObjectKind::ClassSelf: case ObjectKind::Singleton: case ObjectKind::ConstantRole: + if (!info.reference) { + if (info.typeInfo.typeRef == V_FLAG) { + info.reference = info.extra == -1 ? scope.moduleScope->branchingInfo.trueRef : scope.moduleScope->branchingInfo.falseRef; + } + else assert(false); + } writer->appendNode(BuildKey::ClassReference, info.reference); break; case ObjectKind::Constant: @@ -14592,6 +15163,12 @@ bool Compiler::Expression::writeObjectInfo(ObjectInfo info, bool allowMeta) break; case ObjectKind::Object: break; + case ObjectKind::InternalCallback: + writer->appendNode(BuildKey::ProcedureReference, info.reference); + break; + case ObjectKind::ExternalVar: + writer->appendNode(BuildKey::ExternalVarReference, info.reference); + break; default: return false; } @@ -15936,23 +16513,26 @@ void Compiler::Expression::convertIntLiteralForOperation(SyntaxNode node, int op ObjectInfo literal = {}; ref_t loperandRef = messageArguments[0].typeInfo.typeRef; switch (loperandRef) { - case V_INT16ARRAY: - literal = convertIntLiteral(scope, node, messageArguments[1], V_INT16, true); - break; - case V_INT8ARRAY: - literal = convertIntLiteral(scope, node, messageArguments[1], V_INT8, true); - break; - case V_BINARYARRAY: - literal = convertIntLiteral(scope, node, messageArguments[1], - compiler->_logic->retrievePrimitiveType(*scope.moduleScope, messageArguments[0].typeInfo.elementRef), true); - break; - default: - { - literal = convertIntLiteral(scope, node, messageArguments[1], - compiler->_logic->retrievePrimitiveType(*scope.moduleScope, loperandRef), true); + case V_INT16ARRAY: + literal = convertIntLiteral(scope, node, messageArguments[1], V_INT16, true); + break; + case V_INT8ARRAY: + literal = convertIntLiteral(scope, node, messageArguments[1], V_INT8, true); + break; + case V_UINT8ARRAY: + literal = convertIntLiteral(scope, node, messageArguments[1], V_UINT8, true); + break; + case V_BINARYARRAY: + literal = convertIntLiteral(scope, node, messageArguments[1], + compiler->_logic->retrievePrimitiveType(*scope.moduleScope, messageArguments[0].typeInfo.elementRef), true); + break; + default: + { + literal = convertIntLiteral(scope, node, messageArguments[1], + compiler->_logic->retrievePrimitiveType(*scope.moduleScope, loperandRef), true); - break; - } + break; + } } if (literal.kind != ObjectKind::Unknown) diff --git a/elenasrc3/elc/compiler.h b/elenasrc3/elc/compiler.h index 6634d09e7b..a21546af76 100644 --- a/elenasrc3/elc/compiler.h +++ b/elenasrc3/elc/compiler.h @@ -69,6 +69,7 @@ namespace elena_lang LocalAddress, TempLocalAddress, SelfBoxableLocal, // the argument can be stack allocated + ExternLibrary, Extern, FloatExtern, NewVariable, @@ -98,6 +99,10 @@ namespace elena_lang MemberInfo, LocalField, ConstGetter, // key = value constant + InternalCallback, + ProjectInfo, + ProjectVariable, + ExternalVar, }; enum TargetMode @@ -105,7 +110,6 @@ namespace elena_lang None, Probe, External, - WinApi, CreatingArray, Creating, Casting, @@ -142,6 +146,15 @@ namespace elena_lang Alt = 2 }; + enum class DeclarationError + { + None = 0, + Hint, + Duplicate, + Type, + Operation + }; + struct ObjectInfo { ObjectKind kind; @@ -282,7 +295,9 @@ namespace elena_lang typedef Pair ObjectKey; typedef MemoryMap, Map_GetKey> ObjectKeyMap; typedef Map ObjectTrackingMap; - typedef CachedList TemplateTypeList; + typedef CachedList TemplateTypeList; + + typedef Map < ustr_t, ObjectInfo, allocUStr, freeUStr> ShortcutMap; struct Parameter { @@ -344,6 +359,8 @@ namespace elena_lang void addTypeListItem(ref_t dictionaryRef, ref_t symbolRef, ref_t mask); void addConstArrayItem(ref_t dictionaryRef, ref_t item, ref_t mask); void addIntArrayItem(ref_t dictionaryRef, int value); + void addByteArrayItem(ref_t dictionaryRef, int value); + void addWordArrayItem(ref_t dictionaryRef, int value); void addLongArrayItem(ref_t dictionaryRef, long long value); void addFloatArrayItem(ref_t dictionaryRef, double value); void addMssgNameArrayItem(ref_t dictionaryRef, ref_t constRef); @@ -353,7 +370,9 @@ namespace elena_lang bool evalObjArrayOp(ref_t operator_id, ArgumentsInfo& args); bool evalDeclOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal); bool evalIntOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal); + bool evalIntCondOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal); bool evalRealOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal); + bool evalProjectInfoOp(ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal); public: ObjectInfo mapStringConstant(ustr_t s); @@ -361,7 +380,7 @@ namespace elena_lang bool eval(BuildKey key, ref_t operator_id, ArgumentsInfo& args, ObjectInfo& retVal); - ObjectInfo createConstCollection(ref_t arrayRef, ref_t typeRef, ArgumentsInfo& args, bool byValue); + ObjectInfo createConstCollection(ref_t arrayRef, ref_t typeRef, ArgumentsInfo& args, bool byValue, int elementSize = 0); void copyConstCollection(ref_t sourRef, ref_t destRef, bool byValue); @@ -399,7 +418,8 @@ namespace elena_lang Method, Field, Code, - Expr + Expr, + Shortcut }; ModuleBase* module; @@ -505,11 +525,32 @@ namespace elena_lang } }; + struct ShortcutScope : Scope + { + ObjectInfo shortcutInfo; + + Scope* getScope(ScopeLevel level) override + { + if (level == ScopeLevel::Shortcut) { + return this; + } + else return Scope::getScope(level); + } + + ShortcutScope(Scope* parent, ObjectInfo info) + : Scope(parent), shortcutInfo(info) + { + + } + }; + struct NamespaceScope : Scope { ReferenceName nsName; IdentifierString sourcePath; + // shortcuts + ShortcutMap shortcuts; // forward declarations ForwardMap forwards; // imported namespaces @@ -565,6 +606,7 @@ namespace elena_lang NamespaceScope(ModuleScopeBase* moduleScope, ErrorProcessor* errorProcessor, CompilerLogic* compilerLogic, ExtensionMap* outerExtensionList) : Scope(nullptr), + shortcuts({}), forwards(0), importedNs(nullptr), extensions({}), @@ -653,6 +695,8 @@ namespace elena_lang void save(); void load(); + static void saveSymbolInfo(ModuleBase* module, SymbolInfo& info, ref_t reference); + SymbolScope(NamespaceScope* ns, ref_t reference, Visibility visibility); }; @@ -880,7 +924,7 @@ namespace elena_lang return false; } - MethodScope(ClassScope* classScope); + MethodScope(SourceScope* classScope); }; typedef Map NodeMap; @@ -1005,7 +1049,9 @@ namespace elena_lang void syncStack(MethodScope* methodScope); void syncStack(CodeScope* parentScope); + void syncStack(SymbolScope* methodScope); + CodeScope(SymbolScope* scope); CodeScope(MethodScope* scope); CodeScope(CodeScope* scope); }; @@ -1015,6 +1061,7 @@ namespace elena_lang ScopeLevel scopeLevel; ObjectInfo mapDecl(); + ObjectInfo mapProject(); ObjectInfo mapIdentifier(ustr_t identifier, bool referenceOne, ExpressionAttribute attr) override; @@ -1446,8 +1493,7 @@ namespace elena_lang ObjectInfo validateObject(SyntaxNode node, ObjectInfo retVal, ref_t targetRef, bool noPrimitives, bool paramMode, bool dynamicRequired, bool nillable); - ObjectInfo compileExternalOp(SyntaxNode node, ref_t externalRef, bool stdCall, - ArgumentsInfo& arguments, ref_t expectedRef); + ObjectInfo compileExternalOp(SyntaxNode node, ref_t nameRef, ArgumentsInfo& arguments, ref_t expectedRef); ObjectInfo compileNewArrayOp(SyntaxNode node, ObjectInfo source, ref_t targetRef, ArgumentsInfo& arguments); @@ -1626,7 +1672,8 @@ namespace elena_lang ref_t flags, ref_t* signature, size_t signatureLen, bool withoutWeakMessages, bool noSignature); mssg_t mapMessage(Scope& scope, SyntaxNode node, bool propertyMode, bool extensionMode, bool probeMode); - ExternalInfo mapExternal(Scope& scope, SyntaxNode node); + ExternalInfo mapExternal(Scope& scope, SyntaxNode node, ref_t nameRef); + ExternalInfo mapExternalVariable(Scope& scope, SyntaxNode node, ref_t nameRef); static ObjectInfo mapClassSymbol(Scope& scope, ref_t classRef); ObjectInfo mapConstructorTarget(MethodScope& scope); @@ -1639,6 +1686,11 @@ namespace elena_lang mssg_t defineMultimethod(Scope& scope, mssg_t messageRef, bool extensionMode); + bool evalCondStatement(Scope& scope, SyntaxNode& node); + void skipCondStatement(SyntaxNode& node); + + void declareShortcut(NamespaceScope& scope, SyntaxNode node); + void declareTemplateAttributes(Scope& scope, SyntaxNode node, TemplateTypeList& parameters, TypeAttributes& attributes, bool declarationMode, bool objectMode); void declareIncludeAttributes(Scope& scope, SyntaxNode node, bool& textBlock); @@ -1656,7 +1708,7 @@ namespace elena_lang ref_t retrieveType(Scope& scope, ObjectInfo info); ref_t resolveTypeIdentifier(Scope& scope, ustr_t identifier, SyntaxKey type, bool declarationMode, bool allowRole); - ref_t resolveTypeTemplate(Scope& scope, SyntaxNode node, + TypeInfo resolveTypeTemplate(Scope& scope, SyntaxNode node, TypeAttributes& attributes, bool declarationMode, bool objectMode = false); ref_t resolveTemplate(ModuleScopeBase& moduleScope, ref_t templateRef, ref_t elementRef, bool declarationMode); @@ -1690,7 +1742,7 @@ namespace elena_lang bool importTemplate(Scope& scope, SyntaxNode node, SyntaxNode target, bool weakOne); bool includeBlock(Scope& scope, SyntaxNode node, SyntaxNode target); bool importInlineTemplate(Scope& scope, SyntaxNode node, ustr_t postfix, SyntaxNode target); - bool importPropertyTemplate(Scope& scope, SyntaxNode node, ustr_t postfix, SyntaxNode target); + bool importPropertyTemplate(Scope& scope, SyntaxNode node, ustr_t postfix, SyntaxNode& target); void importCode(Scope& scope, SyntaxNode node, SyntaxNode& importNode); void injectLocalLoadingForYieldMethod(BuildTreeWriter& writer, ClassScope* classScope, CodeScope& codeScope); @@ -1705,7 +1757,7 @@ namespace elena_lang ref_t declareMultiType(Scope& scope, SyntaxNode& node, ref_t elementRef); - void declareClassAttributes(ClassScope& scope, SyntaxNode node, ref_t& fldeclaredFlagsags); + void declareClassAttributes(ClassScope& scope, SyntaxNode node, ref_t& fldeclaredFlagsags, bool& externalOp); void declareTemplateAttributes(TemplateScope& scope, SyntaxNode node, IdentifierString& postfix); void declareSymbolAttributes(SymbolScope& scope, SyntaxNode node, bool identifierDeclarationMode); @@ -1717,6 +1769,8 @@ namespace elena_lang static ustr_t retrieveDictionaryOwner(Scope& scope, ustr_t properName, ustr_t defaultPrefix, ExpressionAttribute mode); + bool declareImport(Scope& scope, SyntaxNode node); + void declareDictionary(Scope& scope, SyntaxNode node, Visibility visibility, Scope::ScopeLevel level, bool shareMode); @@ -1765,6 +1819,8 @@ namespace elena_lang void generateClassFields(ClassScope& scope, SyntaxNode node, bool singleField); void generateClassDeclaration(ClassScope& scope, SyntaxNode node, ref_t declaredFlags); + DeclarationError declareVariable(Scope& scope, ustr_t identifier, TypeInfo typeInfo, ObjectInfo& variable, int& size, + ExprScope* exprScope, CodeScope* codeScope, MethodScope* methodScope); bool declareVariable(Scope& scope, SyntaxNode terminal, TypeInfo typeInfo, bool ignoreDuplicate); void markYieldVariable(Scope& scope, ref_t localOffset); @@ -1779,6 +1835,8 @@ namespace elena_lang ref_t declareClosureParameters(MethodScope& methodScope, SyntaxNode argNode); + void declareParameters(MethodScope& scope, SyntaxNode node, bool withoutWeakMessages, bool declarationMode, + bool& variadicMode, bool& weakSignature, bool& noSignature, pos_t& paramCount, size_t& signatureLen, ref_t* signature); void declareVMTMessage(MethodScope& scope, SyntaxNode node, bool withoutWeakMessages, bool declarationMode, bool templateBasedMode); void declareClosureMessage(MethodScope& scope, SyntaxNode node); void declareIteratorMessage(MethodScope& scope, SyntaxNode node); @@ -1786,6 +1844,7 @@ namespace elena_lang void initializeMethod(ClassScope& scope, MethodScope& methodScope, SyntaxNode current); void declareSymbolMetaInfo(SymbolScope& scope, SyntaxNode node); + void declareShortcutMetaInfo(Scope& scope, SyntaxNode node); void declareInvoker(ClassInfo& info, mssg_t targetMssg, MethodInfo& methodInfo, bool abstractOne, ref_t newHints); void declareByRefHandler(ClassInfo& info, mssg_t message, bool abstractOne); @@ -1822,9 +1881,10 @@ namespace elena_lang ObjectInfo evalCollection(Interpreter& interpreter, Scope& scope, SyntaxNode node, bool anonymousOne, bool ignoreErrors); ObjectInfo evalPropertyOperation(Interpreter& interpreter, Scope& scope, SyntaxNode node, bool ignoreErrors); ObjectInfo evalExprValueOperation(Interpreter& interpreter, Scope& scope, SyntaxNode node, bool ignoreErrors); - ObjectInfo evalSizeOperation(Interpreter& interpreter, Scope& scope, SyntaxNode node, bool ignoreErrors); + ObjectInfo evalSizeOperation(Interpreter& interpreter, Scope& scope, SyntaxNode node, bool ignoreErrors, bool metaMode = false); ObjectInfo evalGetter(Interpreter& interpreter, Scope& scope, SyntaxNode node, bool ignoreErrors); + ObjectInfo evalExpression(MetaScope& scope, SyntaxNode node); void evalStatement(MetaScope& scope, SyntaxNode node); static void addBreakpoint(BuildTreeWriter& writer, SyntaxNode node, BuildKey bpKey); @@ -1843,7 +1903,7 @@ namespace elena_lang void compileInlineInitializing(BuildTreeWriter& writer, ClassScope& classScope, SyntaxNode node); - static ObjectInfo convertIntLiteral(ExprScope& scope, SyntaxNode node, ObjectInfo source, ref_t targetRef, bool ignoreError = false); + static ObjectInfo convertIntLiteral(Scope& scope, SyntaxNode node, ObjectInfo source, ref_t targetRef, bool ignoreError = false); bool compileSymbolConstant(SymbolScope& scope, ObjectInfo retVal); @@ -1928,6 +1988,8 @@ namespace elena_lang void compileNestedClass(BuildTreeWriter& writer, ClassScope& scope, SyntaxNode node, ref_t parentRef); void compileStatemachineClass(BuildTreeWriter& writer, StatemachineClassScope& scope, SyntaxNode node, ref_t parentRef); + void compileExternalCallback(BuildTreeWriter& writer, SymbolScope& symbolScope, SyntaxNode node); + void compileVMT(BuildTreeWriter& writer, ClassScope& scope, SyntaxNode node, bool exclusiveMode = false, bool ignoreAutoMultimethod = false); void compileClassVMT(BuildTreeWriter& writer, ClassScope& classClassScope, ClassScope& scope, SyntaxNode node); diff --git a/elenasrc3/elc/compilerlogic.cpp b/elenasrc3/elc/compilerlogic.cpp index 37472c043f..d981e7f614 100644 --- a/elenasrc3/elc/compilerlogic.cpp +++ b/elenasrc3/elc/compilerlogic.cpp @@ -42,7 +42,7 @@ bool testMethodHint(ref_t hint, MethodHint mask) typedef CompilerLogic::Op Op; -constexpr auto OperationLength = 207; +constexpr auto OperationLength = 215; constexpr Op Operations[OperationLength] = { { @@ -75,6 +75,9 @@ constexpr Op Operations[OperationLength] = { NAME_OPERATOR_ID, BuildKey::DeclOp, V_GETTER, 0, 0, V_STRING }, + { + INDEX_OPERATOR_ID, BuildKey::ProjectInfoOp, V_PROJECT_VAR, V_STRING, 0, V_FLAG + }, { REFERENCE_OPERATOR_ID, BuildKey::DeclOp, V_DECLARATION, 0, 0, V_STRING }, @@ -568,9 +571,33 @@ constexpr Op Operations[OperationLength] = { SET_INDEXER_OPERATOR_ID, BuildKey::ByteArrayOp, V_INT8ARRAY, V_ELEMENT, V_INT32, 0 }, + { + // NOTE : the output should be in the stack, aligned to the 4 / 8 bytes + INDEX_OPERATOR_ID, BuildKey::ByteArrayOp, V_UINT8ARRAY, V_INT32, 0, V_ELEMENT + }, + { + SET_INDEXER_OPERATOR_ID, BuildKey::ByteArrayOp, V_UINT8ARRAY, V_ELEMENT, V_INT32, 0 + }, + { + // NOTE : the output should be in the stack, aligned to the 4 / 8 bytes + INDEX_OPERATOR_ID, BuildKey::ByteArrayOp, V_UINT8ARRAY, V_UINT8, 0, V_ELEMENT + }, + { + SET_INDEXER_OPERATOR_ID, BuildKey::ByteArrayOp, V_UINT8ARRAY, V_ELEMENT, V_UINT8, 0 + }, + { + // NOTE : the output should be in the stack, aligned to the 4 / 8 bytes + INDEX_OPERATOR_ID, BuildKey::ByteArrayOp, V_INT8ARRAY, V_INT8, 0, V_ELEMENT + }, + { + SET_INDEXER_OPERATOR_ID, BuildKey::ByteArrayOp, V_INT8ARRAY, V_ELEMENT, V_INT8, 0 + }, { LEN_OPERATOR_ID, BuildKey::ByteArraySOp, V_INT8ARRAY, 0, 0, V_INT32 }, + { + LEN_OPERATOR_ID, BuildKey::ByteArraySOp, V_UINT8ARRAY, 0, 0, V_INT32 + }, { LEN_OPERATOR_ID, BuildKey::ShortArraySOp, V_INT16ARRAY, 0, 0, V_INT32 }, @@ -777,7 +804,9 @@ bool CompilerLogic :: validateTemplateAttribute(ref_t attribute, Visibility& vis default: { ref_t dummy = 0; - return validateClassAttribute(attribute, dummy, visibility); + bool externalOp = false; + if (validateClassAttribute(attribute, dummy, visibility, externalOp)) + return !externalOp; } } @@ -807,6 +836,9 @@ bool CompilerLogic :: validateSymbolAttribute(ref_t attribute, Visibility& visib case V_THREADVAR: symbolKind = SymbolKind::ThreadVar; break; + case V_EXTERN: + symbolKind = SymbolKind::ExternVar; + break; case 0: // ignore idle break; @@ -817,7 +849,7 @@ bool CompilerLogic :: validateSymbolAttribute(ref_t attribute, Visibility& visib return true; } -bool CompilerLogic :: validateClassAttribute(ref_t attribute, ref_t& flags, Visibility& visibility) +bool CompilerLogic :: validateClassAttribute(ref_t attribute, ref_t& flags, Visibility& visibility, bool& externalOne) { switch (attribute) { case V_PUBLIC: @@ -871,6 +903,9 @@ bool CompilerLogic :: validateClassAttribute(ref_t attribute, ref_t& flags, Visi case V_PACKED_STRUCT: flags |= elPacked | elStructureRole; break; + case V_EXTERN: + externalOne = true; + break; case 0: // ignore idle break; @@ -914,9 +949,6 @@ bool CompilerLogic :: validateFieldAttribute(ref_t attribute, FieldAttributes& a case V_READONLY: attrs.isReadonly = true; break; - case V_OVERRIDE: - attrs.overrideMode = true; - break; case V_PRIVATE: attrs.privateOne = true; break; @@ -1842,6 +1874,7 @@ bool CompilerLogic :: defineClassInfo(ModuleScopeBase& scope, ClassInfo& info, r info.size = 2; break; case V_INT8ARRAY: + case V_UINT8ARRAY: info.header.parentRef = scope.buildins.superReference; info.header.flags = elDebugBytes | elStructureRole | elDynamicRole | elWrapper; info.size = -1; @@ -1939,6 +1972,9 @@ ref_t CompilerLogic :: definePrimitiveArray(ModuleScopeBase& scope, ref_t elemen if (isCompatible(scope, { V_INT8 }, { elementRef }, true) && info.size == 1) return V_INT8ARRAY; + if (isCompatible(scope, { V_UINT8 }, { elementRef }, true) && info.size == 1) + return V_UINT8ARRAY; + if (isCompatible(scope, { V_INT16 }, { elementRef }, true) && info.size == 2) return V_INT16ARRAY; diff --git a/elenasrc3/elc/compilerlogic.h b/elenasrc3/elc/compilerlogic.h index 363ad624a3..b3dd4e5217 100644 --- a/elenasrc3/elc/compilerlogic.h +++ b/elenasrc3/elc/compilerlogic.h @@ -102,7 +102,7 @@ namespace elena_lang bool validateTemplateAttribute(ref_t attribute, Visibility& visibility, TemplateType& type); bool validateSymbolAttribute(ref_t attribute, Visibility& visibility, bool& constant, SymbolKind& symbolKind); - bool validateClassAttribute(ref_t attribute, ref_t& flags, Visibility& visibility); + bool validateClassAttribute(ref_t attribute, ref_t& flags, Visibility& visibility, bool& externalOp); bool validateFieldAttribute(ref_t attribute, FieldAttributes& attrs); bool validateMethodAttribute(ref_t attribute, ref_t& hint, bool& explicitMode); bool validateImplicitMethodAttribute(ref_t attribute, ref_t& hint); @@ -238,6 +238,7 @@ namespace elena_lang case V_INT32ARRAY: case V_INT16ARRAY: case V_INT8ARRAY: + case V_UINT8ARRAY: case V_FLOAT64ARRAY: case V_BINARYARRAY: return true; diff --git a/elenasrc3/elc/compiling.cpp b/elenasrc3/elc/compiling.cpp index 3b3bb8aaed..ddff82e8bc 100644 --- a/elenasrc3/elc/compiling.cpp +++ b/elenasrc3/elc/compiling.cpp @@ -201,21 +201,20 @@ size_t getLengthSkipPostfix(ustr_t name) return len; } -ref_t CompilingProcess::TemplateGenerator :: generateTemplateName(ModuleScopeBase& moduleScope, Visibility visibility, - ref_t templateRef, List& parameters, bool& alreadyDeclared) +void CompilingProcess::TemplateGenerator :: defineTemplateName(ModuleScopeBase& moduleScope, IdentifierString& name, + ref_t templateRef, List& parameters) { ModuleBase* module = moduleScope.module; ustr_t templateName = module->resolveReference(templateRef); - IdentifierString name; if (isWeakReference(templateName)) { name.copy(module->name()); name.append(templateName); } else name.copy(templateName); - for(auto it = parameters.start(); !it.eof(); ++it) { + for (auto it = parameters.start(); !it.eof(); ++it) { name.append("&"); ref_t typeRef = (*it).arg.reference; @@ -232,12 +231,19 @@ ref_t CompilingProcess::TemplateGenerator :: generateTemplateName(ModuleScopeBas name.append(param, paramLen); } else name.append(param, paramLen); + + // NOTE : the names must be different for normal and nullable template argument + if ((*it).existChild(SyntaxKey::NullableType)) + name.append("#nble"); } name.replaceAll('\'', '@', 0); +} - // !! temporal - if ((*name).findStr("Task#1&system@Int") != NOTFOUND_POS) - alreadyDeclared |= false; +ref_t CompilingProcess::TemplateGenerator :: generateTemplateName(ModuleScopeBase& moduleScope, Visibility visibility, + ref_t templateRef, List& parameters, bool& alreadyDeclared) +{ + IdentifierString name; + defineTemplateName(moduleScope, name, templateRef, parameters); return moduleScope.mapTemplateIdentifier(*name, visibility, alreadyDeclared, false); } @@ -245,32 +251,8 @@ ref_t CompilingProcess::TemplateGenerator :: generateTemplateName(ModuleScopeBas ref_t CompilingProcess::TemplateGenerator :: declareTemplateName(ModuleScopeBase& moduleScope, Visibility visibility, ref_t templateRef, List& parameters) { - ModuleBase* module = moduleScope.module; - - ustr_t templateName = module->resolveReference(templateRef); IdentifierString name; - if (isWeakReference(templateName)) { - name.copy(module->name()); - name.append(templateName); - } - else name.copy(templateName); - - for (auto it = parameters.start(); !it.eof(); ++it) { - name.append("&"); - - ref_t typeRef = (*it).arg.reference; - ustr_t param = module->resolveReference(typeRef); - if (isTemplateWeakReference(param)) { - // if template based argument - pass as is - name.append(param); - } - else if (isWeakReference(param)) { - name.append(module->name()); - name.append(param); - } - else name.append(param); - } - name.replaceAll('\'', '@', 0); + defineTemplateName(moduleScope, name, templateRef, parameters); bool dummy = false; return moduleScope.mapTemplateIdentifier(*name, visibility, dummy, true); @@ -604,6 +586,7 @@ void CompilingProcess :: printBuildTree(ModuleBase* module, BuildTree& buildTree filters.add(BuildKey::ArgumentsInfo); filters.add(BuildKey::OpenStatement); filters.add(BuildKey::EndStatement); + filters.add(BuildKey::Idle); } _presenter->print("\nBuild Tree:"); @@ -658,6 +641,7 @@ bool CompilingProcess :: buildModule(ProjectEnvironment& env, LexicalMap::Iterator& lexical_it, ModuleIteratorBase& module_it, SyntaxTree* syntaxTree, ForwardResolverBase* forwardResolver, + VariableResolverBase* variableResolver, ModuleSettings& moduleSettings, int minimalArgList, int ptrSize) @@ -665,6 +649,7 @@ bool CompilingProcess :: buildModule(ProjectEnvironment& env, ModuleScope moduleScope( &_libraryProvider, forwardResolver, + variableResolver, _libraryProvider.createModule(module_it.name()), moduleSettings.debugMode ? _libraryProvider.createDebugModule(module_it.name()) : nullptr, moduleSettings.stackAlingment, @@ -804,7 +789,7 @@ void CompilingProcess :: compile(ProjectBase& project, compiled |= buildModule( env, lexical_it, - *module_it, &syntaxTree, &project, + *module_it, &syntaxTree, &project, &project, moduleSettings, minimalArgList, sizeof(uintptr_t)); @@ -855,7 +840,7 @@ void CompilingProcess :: link(Project& project, LinkerBase& linker, bool withTLS return; } - auto result = linker.run(project, code, uiType, _exeExtension); + auto result = linker.run(project, code, imageInfo.type, uiType, _exeExtension); _presenter->print(ELC_SUCCESSFUL_LINKING); diff --git a/elenasrc3/elc/compiling.h b/elenasrc3/elc/compiling.h index 6372aec705..daa9c3efd2 100644 --- a/elenasrc3/elc/compiling.h +++ b/elenasrc3/elc/compiling.h @@ -36,6 +36,9 @@ namespace elena_lang CompilingProcess* _process; TemplateProssesor _processor; + void defineTemplateName(ModuleScopeBase& moduleScope, IdentifierString& name, + ref_t templateRef, List& parameters); + ref_t declareTemplateName(ModuleScopeBase& moduleScope, Visibility visibility, ref_t templateRef, List& parameters); ref_t generateTemplateName(ModuleScopeBase& moduleScope, Visibility visibility, @@ -124,6 +127,7 @@ namespace elena_lang ModuleIteratorBase& module_it, SyntaxTree* syntaxTree, ForwardResolverBase* forwardResolver, + VariableResolverBase* variableResolver, ModuleSettings& moduleSettings, int minimalArgList, int ptrSize); diff --git a/elenasrc3/elc/derivation.cpp b/elenasrc3/elc/derivation.cpp index 2aea3c54a2..b675b31c52 100644 --- a/elenasrc3/elc/derivation.cpp +++ b/elenasrc3/elc/derivation.cpp @@ -99,6 +99,8 @@ void SyntaxTreeBuilder :: flush(SyntaxTreeWriter& writer, SyntaxNode node) flushDictionary(writer, current); break; case SyntaxKey::MetaExpression: + case SyntaxKey::CondStatement: + case SyntaxKey::ElseCondStatement: { Scope scope; flushStatement(writer, scope, current); @@ -813,7 +815,7 @@ void SyntaxTreeBuilder :: flushDescriptor(SyntaxTreeWriter& writer, Scope& scope if (scope.withNameParameters()) { int index = scope.arguments.get(current.identifier()); - if (index == 1) { + if (scope.isNameIndex(index)) { key = SyntaxKey::NameArgParameter; attrRef = index + scope.nestedLevel; } @@ -1063,7 +1065,15 @@ void SyntaxTreeBuilder :: flushSymbolPostfixes(SyntaxTreeWriter& writer, Scope& SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { if (current.key == SyntaxKey::Postfix) { - flushTemplageExpression(writer, scope, current, SyntaxKey::InlineTemplate, false); + SyntaxNode child = current.firstChild(); + switch (child.key) { + case SyntaxKey::InlinePostfix: + flushTemplageExpression(writer, scope, child, SyntaxKey::InlineTemplate, false); + break; + default: + flushTemplageExpression(writer, scope, current, SyntaxKey::InlineTemplate, false); + break; + } } current = current.nextNode(); @@ -1151,6 +1161,13 @@ void SyntaxTreeBuilder :: flushMethodCode(SyntaxTreeWriter& writer, Scope& scope case SyntaxKey::EOP: flushNode(writer, scope, current); break; + case SyntaxKey::CondStatement: + case SyntaxKey::ElseCondStatement: + case SyntaxKey::EndCondStatement: + { + flushStatement(writer, scope, current); + break; + } default: if (SyntaxTree::testSuperKey(current.key, SyntaxKey::Expression)) { current.setKey(SyntaxKey::Expression); @@ -1427,8 +1444,20 @@ void SyntaxTreeBuilder :: flushClass(SyntaxTreeWriter& writer, Scope& scope, Syn else { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { - if (current.key == SyntaxKey::Declaration) { - flushClassMember(writer, scope, current); + switch (current.key) { + case SyntaxKey::CondStatement: + case SyntaxKey::ElseCondStatement: + case SyntaxKey::EndCondStatement: + { + Scope scope; + flushStatement(writer, scope, current); + break; + } + case SyntaxKey::Declaration: + flushClassMember(writer, scope, current); + break; + default: + break; } current = current.nextNode(); @@ -1445,6 +1474,7 @@ void SyntaxTreeBuilder :: flushTemplateCode(SyntaxTreeWriter& writer, Scope& sco while (current != SyntaxKey::None) { switch (current.key) { case SyntaxKey::IncludeStatement: + case SyntaxKey::ImportStatement: flushExpression(writer, scope, current); break; case SyntaxKey::MetaExpression: @@ -1610,6 +1640,7 @@ enum DeclarationType { Class, Import, + Shortcut, Namespace }; @@ -1624,6 +1655,9 @@ inline DeclarationType defineDeclarationType(SyntaxNode node) case V_IMPORT: type = DeclarationType::Import; break; + case V_USE: + type = DeclarationType::Shortcut; + break; case V_NAMESPACE: type = DeclarationType::Namespace; break; @@ -1799,6 +1833,11 @@ void SyntaxTreeBuilder :: flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode& case DeclarationType::Import: writer.CurrentNode().setKey(SyntaxKey::Import); break; + case DeclarationType::Shortcut: + writer.CurrentNode().setKey(SyntaxKey::Shortcut); + + flushSymbolPostfixes(writer, scope, node); + break; case DeclarationType::Namespace: writer.CurrentNode().setKey(SyntaxKey::Namespace); @@ -2173,7 +2212,13 @@ void TemplateProssesor :: importTemplate(Type type, MemoryBase* templateSection, bufferWriter.closeNode(); - SyntaxTreeWriter targetWriter(target); + // NOTE : for the inline property, the target is the property node, so targetWriter must be assigned to the property parent + SyntaxNode writerTarget = type == Type::InlineProperty ? target.parentNode() : target; + SyntaxTreeWriter targetWriter(writerTarget); + if (type == Type::InlineProperty) { + targetWriter.setBookmark(target); + } + if (type == Type::Class || type == Type::InlineProperty || type == Type::Enumeration) { SyntaxNode current = bufferTree.readRoot().firstChild(); while (current != SyntaxKey::None) { @@ -2184,10 +2229,16 @@ void TemplateProssesor :: importTemplate(Type type, MemoryBase* templateSection, targetWriter.closeNode(); } else if (current == SyntaxKey::Field) { - targetWriter.newNode(current.key, current.arg.value); - targetWriter.appendNode(SyntaxKey::Autogenerated); - SyntaxTree::copyNode(targetWriter, current); - targetWriter.closeNode(); + if (type == Type::InlineProperty) { + // NOTE : field must be injected next to the original place for inline property + SyntaxTree::injectNode(targetWriter, current); + } + else { + targetWriter.newNode(current.key, current.arg.value); + targetWriter.appendNode(SyntaxKey::Autogenerated); + SyntaxTree::copyNode(targetWriter, current); + targetWriter.closeNode(); + } } else SyntaxTree::copyNode(targetWriter, current, true); diff --git a/elenasrc3/elc/derivation.h b/elenasrc3/elc/derivation.h index 43887e055a..27cb1233bb 100644 --- a/elenasrc3/elc/derivation.h +++ b/elenasrc3/elc/derivation.h @@ -52,6 +52,11 @@ namespace elena_lang return type == ScopeType::Enumeration; } + bool isNameIndex(int index) + { + return (index == 1 || index == 3) && type == ScopeType::PropertyTemplate; + } + bool isParameter(SyntaxNode node, SyntaxKey& parameterKey, ref_t& parameterIndex, bool allowType) { switch (type) { @@ -75,7 +80,7 @@ namespace elena_lang case ScopeType::PropertyTemplate: { ref_t index = arguments.get(node.identifier()); - if (index == 1) { + if (isNameIndex(index)) { parameterKey = SyntaxKey::NameParameter; parameterIndex = index + nestedLevel; return true; diff --git a/elenasrc3/elc/linux/elc.cpp b/elenasrc3/elc/linux/elc.cpp index b788b9c440..f63755d209 100644 --- a/elenasrc3/elc/linux/elc.cpp +++ b/elenasrc3/elc/linux/elc.cpp @@ -50,8 +50,16 @@ using namespace elena_lang; #if defined(__x86_64__) +#if defined(__FreeBSD__) + +constexpr auto CURRENT_PLATFORM = PlatformType::FreeBSD_x86_64; + +#else + constexpr auto CURRENT_PLATFORM = PlatformType::Linux_x86_64; +#endif + constexpr int MINIMAL_ARG_LIST = 2; constexpr auto DEFAULT_STACKALIGNMENT = 2; @@ -145,6 +153,7 @@ JITCompilerBase* createJITCompiler(PlatformType platform) #endif #if defined(__x86_64__) case PlatformType::Linux_x86_64: + case PlatformType::FreeBSD_x86_64: return new X86_64JITCompiler(); #endif #if defined(__PPC64__) diff --git a/elenasrc3/elc/linux/elfimage.cpp b/elenasrc3/elc/linux/elfimage.cpp index 585eb52199..46fbdbc171 100644 --- a/elenasrc3/elc/linux/elfimage.cpp +++ b/elenasrc3/elc/linux/elfimage.cpp @@ -17,6 +17,20 @@ using namespace elena_lang; +unsigned long elf_hash(const unsigned char* name) +{ + unsigned long h = 0, g; + + while (*name) + { + h = (h << 4) + *name++; + if (g = h & 0xf0000000) + h ^= g >> 24; + h &= ~g; + } + return h; +} + // --- ElfImageFormatter --- pos_t ElfImageFormatter :: fillImportTable(AddressMap::Iterator it, ElfData& elfData) @@ -35,7 +49,11 @@ pos_t ElfImageFormatter :: fillImportTable(AddressMap::Iterator it, ElfData& elf } } - elfData.functions.add(functionName, (ref_t)*it); + if (!functionName.startsWith("##")) { + elfData.functions.add(functionName, (ref_t)*it); + count++; + } + else elfData.variables.add(functionName + 2, (ref_t)*it); ustr_t lib = elfData.libraries.retrieve(*dll, [](ustr_t item, ustr_t current) { @@ -46,7 +64,6 @@ pos_t ElfImageFormatter :: fillImportTable(AddressMap::Iterator it, ElfData& elf } ++it; - count++; } return count; @@ -146,7 +163,7 @@ void ElfImageFormatter :: mapImage(ImageProviderBase& provider, AddressSpace& ma map.stat = map.tls + tls->length(); } else map.stat = map.data + data->length(); - + map.dataSize += stat->length(); sectionSize += align(stat->length(), fileAlignment); @@ -279,7 +296,7 @@ void Elf32ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& el pltIndex++; } - // write dynamic segment + // == write dynamic segment == // write libraries needed to be loaded auto dll = elfData.libraries.start(); @@ -380,10 +397,46 @@ pos_t ElfI386ImageFormatter :: writePLTEntry(MemoryWriter& codeWriter, pos_t sym // --- Elf64ImageFormatter --- +pos_t Elf64ImageFormatter :: fillElfHashTable(ElfData& elfData, MemoryBase* import, int nbucket, int nchain) +{ + MemoryWriter hashWriter(import); + + pos_t position = hashWriter.position(); + hashWriter.writeDWord(nbucket); + hashWriter.writeDWord(nchain); + + pos_t bucketPos = hashWriter.position(); + hashWriter.writeBytes(0, sizeof(Elf64_Word) * nbucket); + pos_t chainPos = hashWriter.position(); + hashWriter.writeBytes(0, sizeof(Elf64_Word) * nchain); + + int* bucket = (int*)import->get(bucketPos); + int* chain = (int*)import->get(chainPos); + + Elf64_Word k = 0; + for (auto fun = elfData.functions.start(); !fun.eof(); ++fun) { + const unsigned char* symbol = (const unsigned char*)fun.key().str(); + unsigned long x = elf_hash(symbol); + if (bucket[x % nbucket] == STN_UNDEF) { + bucket[x % nbucket] = k; + } + else { + Elf64_Word y = bucket[x % nbucket]; + while (chain[y] != STN_UNDEF) + y = chain[y]; + chain[y] = k; + } + k++; + } + + return position; +} + void Elf64ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& elfData, pos_t fileAlignment, RelocationMap& importMapping) { pos_t count = fillImportTable(provider.externals(), elfData); + pos_t global_count = /*elfData.variables.count()*/0; MemoryBase* code = provider.getTextSection(); MemoryBase* data = provider.getDataSection(); @@ -401,23 +454,24 @@ void Elf64ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& el // reserve got table MemoryWriter gotWriter(import); + //pos_t gotStartVar = gotWriter.position(); + //gotWriter.writeBytes(0, global_count * 8); + pos_t gotPltPos = gotWriter.position(); gotWriter.writeQReference(mskDataRef64, elfData.dynamicOffset); gotWriter.writeQWord(0); // reserved for run-time linker gotWriter.writeQWord(0); pos_t gotStart = gotWriter.position(); gotWriter.writeBytes(0, count * 8); - gotWriter.seek(gotStart); // reserve relocation table MemoryWriter reltabWriter(import); pos_t reltabOffset = reltabWriter.position(); reltabWriter.writeBytes(0, count * 24); - reltabWriter.seek(reltabOffset); // reserve symbol table MemoryWriter symtabWriter(import); pos_t symtabOffset = symtabWriter.position(); - symtabWriter.writeBytes(0, (count + 1) * 24); + symtabWriter.writeBytes(0, (global_count + count + 1) * 24); symtabWriter.seek(symtabOffset + 24); // string table @@ -427,8 +481,11 @@ void Elf64ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& el // code writer MemoryWriter codeWriter(code); - writePLTStartEntry(codeWriter, importRelRef, 0); + writePLTStartEntry(codeWriter, importRelRef, gotPltPos); + // functions + gotWriter.seek(gotStart); + reltabWriter.seek(reltabOffset); int relocateType = getRelocationType(); long long symbolIndex = 1; int pltIndex = 1; @@ -464,7 +521,39 @@ void Elf64ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& el pltIndex++; } - // write dynamic segment + //// globals + //if (global_count > 0) { + // gotWriter.seek(gotStartVar); + // for (auto glob = elfData.variables.start(); !glob.eof(); ++glob) { + // pos_t gotPosition = gotWriter.position(); + + // ref_t globalRef = *glob & ~mskAnyRef; + // importMapping.add(globalRef | mskImportRelRef32, gotPosition); + + // pos_t strIndex = strWriter.position() - strOffset; + + // // symbol table entry + // symtabWriter.writeDWord(strIndex); + // symtabWriter.writeByte(0x11); + // symtabWriter.writeByte(0); + // symtabWriter.writeWord(0x1B); // R_X86_64_GOT64 + // symtabWriter.writeQReference(importRef, gotPosition); + // symtabWriter.writeQWord(0); + + // relocation table entry + //relatabWriter.writeQReference(importRef, gotPosition); + //relatabWriter.writeQWord((symbolIndex << 32) + /*relocateType*/6); + //relatabWriter.writeQWord(0); + + // // string table entry + // strWriter.writeString(glob.key()); + + // gotWriter.writeQWord(0); + // symbolIndex++; + // } + //} + + // == write dynamic segment == // write libraries needed to be loaded auto dll = elfData.libraries.start(); @@ -479,6 +568,14 @@ void Elf64ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& el strWriter.writeChar('\0'); pos_t strLength = strWriter.position() - strOffset; + // build hash table + int nchain = count + 1; + int nbucket = nchain * 2 + 1; + pos_t hashffset = fillElfHashTable(elfData, import, nchain, nbucket); + dynamicWriter.writeQWord(DT_HASH); + dynamicWriter.writeQReference(importRef, hashffset); + + // fill other mandatory entries dynamicWriter.writeQWord(DT_STRTAB); dynamicWriter.writeQReference(importRef, strOffset); @@ -492,7 +589,7 @@ void Elf64ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& el dynamicWriter.writeQWord(24); dynamicWriter.writeQWord(DT_PLTGOT); - dynamicWriter.writeQReference(importRef, /*gotStart*/0); + dynamicWriter.writeQReference(importRef, gotPltPos); dynamicWriter.writeQWord(DT_PLTRELSZ); dynamicWriter.writeQWord(count * 24); @@ -503,11 +600,21 @@ void Elf64ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& el dynamicWriter.writeQWord(DT_JMPREL); dynamicWriter.writeQReference(importRef, reltabOffset); + assert(global_count == 0); // !! temporally globals are not supported + +#if defined(__FreeBSD__) + dynamicWriter.writeQWord(DT_RELA); + dynamicWriter.writeQReference(importRef, reltabOffset/*relatabOffset*/); + + dynamicWriter.writeQWord(DT_RELASZ); + dynamicWriter.writeQWord(/*global_count * 24*/0); +#else dynamicWriter.writeQWord(DT_RELA); dynamicWriter.writeQReference(importRef, reltabOffset); dynamicWriter.writeQWord(DT_RELASZ); dynamicWriter.writeQWord(count * 24); +#endif dynamicWriter.writeQWord(DT_RELAENT); dynamicWriter.writeQWord(24); @@ -524,7 +631,11 @@ void Elf64ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& el int ElfAmd64ImageFormatter:: getRelocationType() { +#if defined(__FreeBSD__) + return R_X86_64_JMP_SLOT; +#else return R_X86_64_JUMP_SLOT; +#endif } void ElfAmd64ImageFormatter :: fixSection(MemoryBase* section, AddressSpace& map) @@ -539,12 +650,12 @@ void ElfAmd64ImageFormatter :: fixImportSection(MemoryBase* section, AddressSpac dynamic_cast(section)->fixupReferences(&map, relocateElf64Import); } -void ElfAmd64ImageFormatter :: writePLTStartEntry(MemoryWriter& codeWriter, ref_t gotReference, pos_t) +void ElfAmd64ImageFormatter :: writePLTStartEntry(MemoryWriter& codeWriter, ref_t gotReference, pos_t gotPlt) { codeWriter.writeWord(0x35FF); - codeWriter.writeDReference(gotReference, 8); + codeWriter.writeDReference(gotReference, gotPlt + 8); codeWriter.writeWord(0x25FF); - codeWriter.writeDReference(gotReference, 16); + codeWriter.writeDReference(gotReference, gotPlt + 16); codeWriter.writeDWord(0); } diff --git a/elenasrc3/elc/linux/elfimage.h b/elenasrc3/elc/linux/elfimage.h index 3e541c5e72..4a6e25525a 100644 --- a/elenasrc3/elc/linux/elfimage.h +++ b/elenasrc3/elc/linux/elfimage.h @@ -9,6 +9,12 @@ #ifndef ELFIMAGE_H #define ELFIMAGE_H +#if defined(__FreeBSD__) + + #define R_X86_64_JUMP_SLOT R_X86_64_JMP_SLOT + +#endif + namespace elena_lang { typedef List LibraryList; @@ -22,13 +28,14 @@ namespace elena_lang struct ElfData { ReferenceMap functions; + ReferenceMap variables; LibraryList libraries; pos_t dynamicOffset; pos_t dynamicSize; ElfData() - : functions(0), libraries(nullptr) + : functions(0), variables(0), libraries(nullptr) { dynamicOffset = dynamicSize = 0; } @@ -115,6 +122,7 @@ namespace elena_lang virtual int getRelocationType() = 0; + pos_t fillElfHashTable(ElfData& elfData, MemoryBase* image, int nbucket, int nchain); void fillElfData(ImageProviderBase& provider, ElfData& elfData, pos_t fileAlignment, RelocationMap& importMapping) override; public: diff --git a/elenasrc3/elc/linux/elflinker.cpp b/elenasrc3/elc/linux/elflinker.cpp index 7c8c7d31f3..e1f340dada 100644 --- a/elenasrc3/elc/linux/elflinker.cpp +++ b/elenasrc3/elc/linux/elflinker.cpp @@ -113,10 +113,10 @@ void ElfLinker :: prepareElfImage(ImageProviderBase& provider, ElfExecutableImag image.withTLS = true; } -LinkResult ElfLinker :: run(ProjectBase& project, ImageProviderBase& provider, PlatformType, path_t) +LinkResult ElfLinker :: run(ProjectBase& project, ImageProviderBase& provider, PlatformType osType, PlatformType, path_t) { bool withDebugMode = project.BoolSetting(ProjectOption::DebugMode, true); - ElfExecutableImage image(withDebugMode); + ElfExecutableImage image(withDebugMode, osType); image.addressMap.entryPoint = (pos_t)provider.getEntryPoint(); prepareElfImage(provider, image, calcHeaderSize()); diff --git a/elenasrc3/elc/linux/elflinker.h b/elenasrc3/elc/linux/elflinker.h index 5263fc6ecb..06f5303d44 100644 --- a/elenasrc3/elc/linux/elflinker.h +++ b/elenasrc3/elc/linux/elflinker.h @@ -16,6 +16,8 @@ namespace elena_lang // --- ElfExecutableImage --- struct ElfExecutableImage { + PlatformType platformType; + unsigned int sectionAlignment; unsigned int fileAlignment; unsigned int flags; @@ -26,8 +28,8 @@ namespace elena_lang ImageSections imageSections; - ElfExecutableImage(bool withDebugInfo) - : imageSections(ImageSections()) + ElfExecutableImage(bool withDebugInfo, PlatformType platformType) + : imageSections(ImageSections()), platformType(platformType) { this->fileAlignment = this->sectionAlignment = 0; this->flags = 0; @@ -58,7 +60,7 @@ namespace elena_lang virtual void prepareElfImage(ImageProviderBase& provider, ElfExecutableImage& image, unsigned int headerSize); public: - LinkResult run(ProjectBase& project, ImageProviderBase& code, PlatformType uiType, + LinkResult run(ProjectBase& project, ImageProviderBase& code, PlatformType osType, PlatformType uiType, path_t exeExtension) override; ElfLinker(ErrorProcessorBase* errorProcessor, ImageFormatter* imageFormatter) diff --git a/elenasrc3/elc/linux/elflinker32.cpp b/elenasrc3/elc/linux/elflinker32.cpp index 02e6e39268..853e51a5c9 100644 --- a/elenasrc3/elc/linux/elflinker32.cpp +++ b/elenasrc3/elc/linux/elflinker32.cpp @@ -38,6 +38,14 @@ void Elf32Linker :: writeELFHeader(ElfExecutableImage& image, FileWriter* file, header.e_ident[EI_CLASS] = ELFCLASS32; header.e_ident[EI_DATA] = ELFDATA2LSB; header.e_ident[EI_VERSION] = EV_CURRENT; + switch (image.platformType) { + case PlatformType::Linux_x86: + header.e_ident[EI_OSABI] = ELFOSABI_LINUX; + break; + default: + assert(false); // !! should not be here + break; + } header.e_type = ET_EXEC; header.e_machine = getMachine(); @@ -113,11 +121,12 @@ void Elf32Linker :: writePHTable(ElfExecutableImage& image, FileWriter* file, un // Dynamic pos_t dynamicOffset = image.addressMap.dictionary.get(elfDynamicOffset); - pos_t dynamicVAddress = image.addressMap.dictionary.get(elfDynamicVAddress); pos_t dynamicSize = image.addressMap.dictionary.get(elfDynamicSize); + pos_t dynamicVAddress = image.addressMap.dictionary.get(elfDynamicVAddress); ph_header.p_type = PT_DYNAMIC; ph_header.p_offset = dynamicOffset; + ph_header.p_paddr = ph_header.p_vaddr = image.addressMap.imageBase + dynamicVAddress; ph_header.p_filesz = ph_header.p_memsz = align(dynamicSize, 8); ph_header.p_flags = PF_R + PF_W; diff --git a/elenasrc3/elc/linux/elflinker64.cpp b/elenasrc3/elc/linux/elflinker64.cpp index 400a958228..a3679da6d9 100644 --- a/elenasrc3/elc/linux/elflinker64.cpp +++ b/elenasrc3/elc/linux/elflinker64.cpp @@ -3,7 +3,7 @@ // // This header contains ELENA Executive Linker class body // Supported platforms: Linux 64 -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elflinker64.h" @@ -16,8 +16,16 @@ constexpr unsigned int HEADER_INTERPRETER_SIZE = 0x200; constexpr unsigned int ELF64_HEADER_SIZE = 0x40; constexpr unsigned int ELF64_PH_SIZE = 0x38; +#if defined(__FreeBSD__) + +constexpr auto INTERPRETER64_PATH = "/libexec/ld-elf.so.1"; + +#else + constexpr auto INTERPRETER64_PATH = "/lib64/ld-linux-x86-64.so.2"; +#endif + using namespace elena_lang; // --- Elf64Linker --- @@ -42,6 +50,19 @@ void Elf64Linker :: writeELFHeader(ElfExecutableImage& image, FileWriter* file, header.e_ident[EI_CLASS] = ELFCLASS64; header.e_ident[EI_DATA] = ELFDATA2LSB; header.e_ident[EI_VERSION] = EV_CURRENT; + switch (image.platformType) { + case PlatformType::Linux_x86_64: + case PlatformType::Linux_ARM64: + case PlatformType::Linux_PPC64le: + header.e_ident[EI_OSABI] = ELFOSABI_LINUX; + break; + case PlatformType::FreeBSD_x86_64: + header.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; + break; + default: + assert(false); // !! should not be here + break; + } header.e_type = ET_EXEC; header.e_machine = getMachine(); @@ -117,8 +138,8 @@ void Elf64Linker :: writePHTable(ElfExecutableImage& image, FileWriter* file, un // Dynamic pos_t dynamicOffset = image.addressMap.dictionary.get(elfDynamicOffset); - pos_t dynamicVAddress = image.addressMap.dictionary.get(elfDynamicVAddress); pos_t dynamicSize = image.addressMap.dictionary.get(elfDynamicSize); + pos_t dynamicVAddress = image.addressMap.dictionary.get(elfDynamicVAddress); ph_header.p_type = PT_DYNAMIC; ph_header.p_offset = dynamicOffset; diff --git a/elenasrc3/elc/linux/pathmanager.cpp b/elenasrc3/elc/linux/pathmanager.cpp index e200111f33..a23f272844 100644 --- a/elenasrc3/elc/linux/pathmanager.cpp +++ b/elenasrc3/elc/linux/pathmanager.cpp @@ -11,6 +11,12 @@ #include "pathmanager.h" #include +#if defined(__FreeBSD__) + +#include + +#endif + using namespace elena_lang; // --- PathHelper --- @@ -19,9 +25,22 @@ PathHelper::PathMap* PathHelper::pathCache = nullptr; inline bool loadAppPath(char* appPath, size_t len) { +#if defined(__FreeBSD__) + + int mib[4]; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + sysctl(mib, 4, appPath, &len, nullptr, 0); + +#elif defined(__unix__) + if (readlink("/proc/self/exe", appPath, len) == -1) return false; +#endif + size_t index = path_t(appPath).findLast(PATH_SEPARATOR); if (index != NOTFOUND_POS) appPath[index] = 0; diff --git a/elenasrc3/elc/modulescope.h b/elenasrc3/elc/modulescope.h index fedea357ec..f6f84bb010 100644 --- a/elenasrc3/elc/modulescope.h +++ b/elenasrc3/elc/modulescope.h @@ -17,12 +17,14 @@ namespace elena_lang // --- ModuleScope --- class ModuleScope : public ModuleScopeBase { - int hints; + int hints; - LibraryLoaderBase* loader; - ForwardResolverBase* forwardResolver; + LibraryLoaderBase* loader; + ForwardResolverBase* forwardResolver; + VariableResolverBase* variableResolver; - Forwards reusedTemplates; + Forwards reusedTemplates; + Forwards declaredImportLibraries; void saveListMember(ustr_t name, ustr_t memberName); @@ -82,10 +84,28 @@ class ModuleScope : public ModuleScopeBase Visibility retrieveVisibility(ref_t reference) override; + bool declareImport(ustr_t name, ustr_t importName) override + { + return declaredImportLibraries.add(name, importName, true); + } + + ustr_t resolveImport(ustr_t alias) override + { + ustr_t declared = declaredImportLibraries.get(alias); + + return declared.empty() ? alias : declared; + } + + bool checkVariable(ustr_t name) override + { + return variableResolver->checkVariable(name); + } + void flush() override; ModuleScope(LibraryLoaderBase* loader, ForwardResolverBase* forwardResolver, + VariableResolverBase* variableResolver, ModuleBase* module, ModuleBase* debugModule, pos_t stackAlingment, @@ -95,10 +115,11 @@ class ModuleScope : public ModuleScopeBase int ptrSize, int moduleHint) : ModuleScopeBase(module, debugModule, stackAlingment, rawStackAlingment, ehTableEntrySize, - minimalArgList, ptrSize, false), reusedTemplates(nullptr) + minimalArgList, ptrSize, false), reusedTemplates(nullptr), declaredImportLibraries(nullptr) { this->loader = loader; this->forwardResolver = forwardResolver; + this->variableResolver = variableResolver; this->hints = moduleHint; } }; diff --git a/elenasrc3/elc/project.cpp b/elenasrc3/elc/project.cpp index 7265a80832..1862a0ffb7 100644 --- a/elenasrc3/elc/project.cpp +++ b/elenasrc3/elc/project.cpp @@ -317,6 +317,7 @@ void Project :: loadConfig(ConfigFile& config, path_t configPath, ConfigFile::No ProjectOption::References, configPath); loadForwards(config, root, FORWARD_CATEGORY); + loadVariables(config, root, VARIABLE_CATEGORY); loadLexicals(config, root, LEXICAL_CATEGORY); diff --git a/elenasrc3/elc/separser.cpp b/elenasrc3/elc/separser.cpp index e9c94752f5..1fa70c5783 100644 --- a/elenasrc3/elc/separser.cpp +++ b/elenasrc3/elc/separser.cpp @@ -3,7 +3,7 @@ // // This header contains ELENA Script Engine Parser class declaration. // -// (C)2023-2024, by Aleksey Rakov +// (C)2023-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -12,7 +12,7 @@ #include "parser.h" -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) #include "windows\winsyslibloader.h" @@ -42,7 +42,7 @@ ScriptParser :: ScriptParser() { _encoding = FileEncoding::UTF8; -#ifdef _MSC_VER +#if (defined(_WIN32) || defined(__WIN32__)) _library = new WinSysLibraryLoader(SCRIPTENGINE_LIB); diff --git a/elenasrc3/elc/windows/ntlinker.cpp b/elenasrc3/elc/windows/ntlinker.cpp index 8013ad016d..5229e40c40 100644 --- a/elenasrc3/elc/windows/ntlinker.cpp +++ b/elenasrc3/elc/windows/ntlinker.cpp @@ -188,7 +188,7 @@ void WinNtLinker :: prepareNtImage(ImageProviderBase& provider, WinNtExecutableI image.headerSize += IMAGE_SIZEOF_SECTION_HEADER * image.imageSections.headers.count(); } -LinkResult WinNtLinker :: run(ProjectBase& project, ImageProviderBase& provider, PlatformType uiType, path_t exeExtension) +LinkResult WinNtLinker :: run(ProjectBase& project, ImageProviderBase& provider, PlatformType, PlatformType uiType, path_t exeExtension) { bool withDebugMode = project.BoolSetting(ProjectOption::DebugMode, true); // !! temporally by default the debug mode is on diff --git a/elenasrc3/elc/windows/ntlinker.h b/elenasrc3/elc/windows/ntlinker.h index 1a4dcca515..f025219292 100644 --- a/elenasrc3/elc/windows/ntlinker.h +++ b/elenasrc3/elc/windows/ntlinker.h @@ -73,7 +73,7 @@ namespace elena_lang bool createDebugFile(ImageProviderBase& provider, WinNtExecutableImage& image, path_t debugFilePath); public: - LinkResult run(ProjectBase& project, ImageProviderBase& code, PlatformType uiType, path_t exeExtension) override; + LinkResult run(ProjectBase& project, ImageProviderBase& code, PlatformType, PlatformType uiType, path_t exeExtension) override; WinNtLinker(ErrorProcessorBase* errorProcessor, ImageFormatter* imageFormatter) : LinkerBase(errorProcessor) diff --git a/elenasrc3/elc/windows/winsyslibloader.cpp b/elenasrc3/elc/windows/winsyslibloader.cpp index 763ad4f8b8..e165beed2e 100644 --- a/elenasrc3/elc/windows/winsyslibloader.cpp +++ b/elenasrc3/elc/windows/winsyslibloader.cpp @@ -23,5 +23,9 @@ WinSysLibraryLoader :: WinSysLibraryLoader(path_t libraryPath) void* WinSysLibraryLoader :: loadFunction(const char* name) { +#if defined(_MSC_VER) return GetProcAddress((HINSTANCE)_handle, name); +#else + return (void*)GetProcAddress((HINSTANCE)_handle, name); +#endif } diff --git a/elenasrc3/elena-tests/bt_optimization.h b/elenasrc3/elena-tests/bt_optimization.h index 4da9d7e616..65ba817401 100644 --- a/elenasrc3/elena-tests/bt_optimization.h +++ b/elenasrc3/elena-tests/bt_optimization.h @@ -155,6 +155,20 @@ namespace elena_lang void runTest(bool withVariadic, int scenario = 0); }; + class ArrayOpTest : public ScenarioTest + { + protected: + ref_t intNumberRef; + ref_t arrayTemplateRef; + ref_t elementRef; + ref_t arrayRef; + + void SetUp() override; + + public: + void runTest(int scenario = 0); + }; + class CallMethodWithoutTarget : public MethodCallTest { protected: @@ -222,6 +236,18 @@ namespace elena_lang protected: void SetUp() override; }; + + class ByteArrayOperation : public ArrayOpTest + { + protected: + void SetUp() override; + }; + + class ByteArrayOperation2 : public ArrayOpTest + { + protected: + void SetUp() override; + }; } #endif diff --git a/elenasrc3/elena-tests/scenario_consts.h b/elenasrc3/elena-tests/scenario_consts.h index 8a034a1474..ad3420734d 100644 --- a/elenasrc3/elena-tests/scenario_consts.h +++ b/elenasrc3/elena-tests/scenario_consts.h @@ -6,6 +6,7 @@ constexpr auto S_DefaultNamespace_3 = "namespace (class (nameattr (identifier \" // scenario basic types constexpr auto S_IntNumber = "class (attribute -2147467263 () attribute -2147475455 () attribute -2147479550 () nameattr (identifier \"IntNumber\" ()) field (attribute -2147475454 () attribute -2147481597 () nameattr (identifier \"_value\" ())dimension (integer \"4\" ())))"; +constexpr auto S_ByteNumber = "class (attribute -2147467263 () attribute -2147475455 () attribute -2147479550 () nameattr (identifier \"ByteNumber\" ()) field (attribute -2147475454 () attribute -2147481596 () nameattr (identifier \"_value\" ())dimension (integer \"1\" ())))"; constexpr auto S_IntRefeference = "class ( attribute -2147471359 () nameattr (identifier \"IntReference\" ()) field (attribute -2147475454 () type (identifier \"IntNumber\" ()) nameattr (identifier \"_value\" ())) )"; // main program body @@ -13,6 +14,7 @@ constexpr auto S_NillableIntAssigning = "class (attribute -2147467263 ()nameattr constexpr auto S_IntAssigningNil = "class (attribute -2147467263 ()nameattr (identifier \"program\" ())attribute -2147479546 ()method (attribute -2147479540 ()code (expression (assign_operation (object (type (identifier \"IntNumber\" ())identifier \"m\" ())expression (object (identifier \"nil\" ())))))))"; constexpr auto S1_VariadicTemplates = " class (attribute -2147467263 ()attribute -2147471359 ()attribute -2147479542 ()nameattr (identifier \"VariadicArray\" ())field (attribute -2147475454 ()attribute -2147481599 ()array_type (type (identifier \"Object\" ()))nameattr (identifier \"array\" ()))) class (attribute -2147467263 ()attribute -2147471359 ()attribute -2147479542 ()nameattr (identifier \"VariadicBArray\" ())field (attribute -2147475454 ()attribute -2147481599 ()array_type (type (identifier \"B\" ()))nameattr (identifier \"array\" ())))"; +constexpr auto S_DummyByteArray = " class (attribute -2147467263 ()attribute -2147471359 ()nameattr (identifier \"ByteArray\" ())field (attribute -2147475454 ()attribute -2147481599 ()array_type (type (identifier \"ByteNumber\" ()))nameattr (identifier \"array\" ())))"; constexpr auto Tester_2Args = "class (attribute -2147467263 ()attribute -2147479546 () nameattr (identifier \"Tester\" ()) method (nameattr (identifier \"testArg2\" ()) parameter (nameattr (identifier \"arg1\" ())) parameter (nameattr (identifier \"arg2\" ())) code ()))"; diff --git a/elenasrc3/elena-tests/tests_bt_optimization.cpp b/elenasrc3/elena-tests/tests_bt_optimization.cpp index 04f62594b2..7e1aba9421 100644 --- a/elenasrc3/elena-tests/tests_bt_optimization.cpp +++ b/elenasrc3/elena-tests/tests_bt_optimization.cpp @@ -53,6 +53,9 @@ constexpr auto S1_DirectCall_3 = "class (attribute -2147479546 ()nameattr (ident constexpr auto S1_MethodWithSignatureOfObject = "class (attribute -2147479546 ()nameattr (identifier \"Helper\" ())method (nameattr (identifier \"test\" ())parameter (type (identifier \"Object\" ())nameattr (identifier \"arg\" ()))code ())) class (attribute -2147467263 ()nameattr (identifier \"program\" ())attribute -2147479546 ()method (attribute -2147479540 ()code (expression (assign_operation (object (type (identifier \"Object\" ())identifier \"arg\" ())expression (object (integer \"2\" ()))))expression (message_operation (object (identifier \"Helper\" ()) message(identifier \"test\" ())expression (object (identifier \"arg\" ())))))))"; +constexpr auto S1_DirectByteOperation = "class (attribute -2147467263 ()nameattr (identifier \"program\" ())attribute -2147479546 ()method (attribute -2147479540 ()code (expression (index_operation (object (type (identifier \"ByteNumber\" ()) identifier \"tmp\" ()) expression (object (integer \"10\" ())))) expression (assign_operation (object (type (identifier \"ByteNumber\" ())identifier \"r\" ())expression (index_operation (object (identifier \"tmp\" ())expression (object (integer \"10\" ())))))))))))"; +constexpr auto S1_DirectByteOperation2 = "class (attribute -2147467263 ()nameattr (identifier \"program\" ())attribute -2147479546 ()method (attribute -2147479540 ()code (expression (index_operation (object (type (identifier \"ByteNumber\" ())identifier \"tmp\" ())expression (object (integer \"10\" ()))))expression (object (type (identifier \"ByteNumber\" ())identifier \"index\" ()))expression (assign_operation (object (type (identifier \"ByteNumber\" ())identifier \"r\" ())expression (index_operation (object (identifier \"tmp\" ())expression (object (identifier \"index\" ()))))))))))"; + // S2 Scenarion : lmbda constexpr auto S2_Func = "class (attribute -2147467263 ()attribute -2147479545 ()nameattr (identifier \"Func\" ())method (attribute -2147471358 ()nameattr (identifier \"function\" ())no_body ()))"; @@ -80,6 +83,8 @@ constexpr auto BuildTree_VariadicSingleDispatch_4 = "tape (open_frame ()assignin constexpr auto BuildTree_CallMethodWithoutTarget = "tape (open_frame ()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 6 ())assigning 2 ()local 2 ()saving_stack 1 ()local 1 ()saving_stack ()argument ()direct_call_op 3074 (type 4 ())local 1 ()close_frame ()exit ())reserved 4 ()"; constexpr auto BuildTree_CallVariadicMethodWithoutTarget = "tape(open_frame()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 2 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 3 ()local 2 ()saving_stack()argument()call_op 1217 ()assigning 4 ()local 3 ()saving_stack()argument()call_op 1217 ()assigning 5 ()terminator()saving_stack 3 ()local 5 ()saving_stack 2 ()local 4 ()saving_stack 1 ()local 1 ()saving_stack()argument()direct_call_op 3138 (type 4 ())local 1 ()close_frame()exit())reserved 9 ()"; constexpr auto BuildTree_CallMethodWithNil = "tape (open_frame ()assigning 1 ()nil_reference ()saving_stack 1 ()class_reference 3 ()saving_stack ()argument ()direct_call_op 1538 (type 3 ())local 1 ()close_frame ()exit ())reserved 3 ()"; +constexpr auto BuildTree_DirectByteOperation = "tape (open_frame ()assigning 1 ()local_address -8 ()saving_stack ()int_literal 3 (value 10 ())saving_stack 1 ()bytearray_op -24 (operator_id 1 ()) local_address -24 ()copying -20 (size 1 ())local 1 ()close_frame ()exit ())reserved 3 ()reserved_n 24 ()"; +constexpr auto BuildTree_DirectByteOperation2 = "tape (open_frame ()assigning 1 ()local_address -8 ()saving_stack ()local_address -20 ()saving_stack 1 ()bytearray_op -28 (operator_id 1 ())local_address -28 ()copying -24 (size 1 ())local 1 ()close_frame ()exit ())reserved 3 ()reserved_n 28 ()"; constexpr auto BuildTree_LambdaCallPrivate = "tape (open_frame ()assigning 1 ()local 1 ()field ()saving_stack ()argument ()direct_call_op 3329 (type 3 ())close_frame ()exit ())reserved 2 ()"; @@ -112,6 +117,8 @@ constexpr auto BuildTree_VariadicSingleDispatch_4 = "tape (open_frame ()assignin constexpr auto BuildTree_CallMethodWithoutTarget = "tape (open_frame ()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 6 ())assigning 2 ()local 2 ()saving_stack 1 ()local 1 ()saving_stack ()argument ()direct_call_op 3074 (type 4 ())local 1 ()close_frame ()exit ())reserved 4 ()"; constexpr auto BuildTree_CallVariadicMethodWithoutTarget = "tape(open_frame()assigning 1 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 2 ()class_reference 2 ()direct_call_op 544 (type 8 ())assigning 3 ()local 2 ()saving_stack()argument()call_op 1217 ()assigning 4 ()local 3 ()saving_stack()argument()call_op 1217 ()assigning 5 ()terminator()saving_stack 3 ()local 5 ()saving_stack 2 ()local 4 ()saving_stack 1 ()local 1 ()saving_stack()argument()direct_call_op 3138 (type 4 ())local 1 ()close_frame()exit())reserved 10 ()"; constexpr auto BuildTree_CallMethodWithNil = "tape (open_frame ()assigning 1 ()nil_reference ()saving_stack 1 ()class_reference 3 ()saving_stack ()argument ()direct_call_op 1538 (type 3 ())local 1 ()close_frame ()exit ())reserved 4 ()"; +constexpr auto BuildTree_DirectByteOperation = "tape (open_frame ()assigning 1 ()local_address -24 ()saving_stack ()int_literal 3 (value 10 ())saving_stack 1 ()bytearray_op -56 (operator_id 1 ()) local_address -56 ()copying -40 (size 1 ())local 1 ()close_frame ()exit ())reserved 4 ()reserved_n 64 ()"; +constexpr auto BuildTree_DirectByteOperation2 = "tape (open_frame ()assigning 1 ()local_address -24 ()saving_stack ()local_address -40 ()saving_stack 1 ()bytearray_op -72 (operator_id 1 ())local_address -72 ()copying -56 (size 1 ())local 1 ()close_frame ()exit ())reserved 4 ()reserved_n 80 ()"; constexpr auto BuildTree_LambdaCallPrivate = "tape (open_frame ()assigning 1 ()local 1 ()field ()saving_stack ()argument ()direct_call_op 3329 (type 3 ())close_frame ()exit ())reserved 4 ()"; @@ -450,31 +457,30 @@ void MethodCallTest :: runTest(bool withVariadic, int scenario) env.setUpTemplateMockup(argArrayRef, 2, targetVargRef); } - moduleScope->predefined.add("nil", V_NIL); - - Compiler* compiler = env.createCompiler(); - - BuildTree output; - BuildTreeWriter writer(output); - Compiler::Namespace nsScope(compiler, moduleScope, TestErrorProcessor::getInstance(), nullptr, nullptr); + run(moduleScope, scenario); +} - // Act - nsScope.declare(declarationNode.firstChild(), true); +// --- ArrayOpTest --- - Compiler::Class classHelper(nsScope, targetRef, Visibility::Public); - classHelper.load(); - Compiler::Method methodHelper(classHelper); +void ArrayOpTest::SetUp() +{ + ScenarioTest::SetUp(); +} - SyntaxNode methodNode = findTargetNode(scenario); - if (methodNode != SyntaxKey::None) - methodHelper.compile(writer, methodNode); +void ArrayOpTest :: runTest(int scenario) +{ + // Arrange + ModuleScopeBase* moduleScope = env.createModuleScope(true); + moduleScope->buildins.superReference = 1; + moduleScope->buildins.intReference = intNumberRef; + moduleScope->buildins.constructor_message = + encodeMessage(moduleScope->module->mapAction(CONSTRUCTOR_MESSAGE, 0, false), + 0, FUNCTION_MESSAGE); - // Assess - bool matched = BuildTree::compare(output.readRoot(), controlOutputNode, true); - EXPECT_TRUE(matched); + moduleScope->buildins.arrayTemplateReference = arrayTemplateRef; + env.setUpTemplateMockup(arrayTemplateRef, elementRef, arrayRef); - freeobj(compiler); - freeobj(moduleScope); + run(moduleScope, scenario); } // --- CallMethodWithoutTarget --- @@ -533,6 +539,40 @@ void CallMethodWithNil :: SetUp() BuildTreeSerializer::load(BuildTree_CallMethodWithNil, controlOutputNode); } +// --- ByteArrayOperation --- + +void ByteArrayOperation :: SetUp() +{ + ArrayOpTest::SetUp(); + + arrayTemplateRef = 0x80; + intNumberRef = 2; + elementRef = 3; + arrayRef = 5; + targetRef = 5; + + LoadDeclarationScenario(S_DefaultNamespace_3, S_IntNumber, S_ByteNumber, S_DummyByteArray, S1_DirectByteOperation); + + BuildTreeSerializer::load(BuildTree_DirectByteOperation, controlOutputNode); +} + +// --- ByteArrayOperation --- + +void ByteArrayOperation2 :: SetUp() +{ + ArrayOpTest::SetUp(); + + arrayTemplateRef = 0x80; + intNumberRef = 2; + elementRef = 3; + arrayRef = 5; + targetRef = 5; + + LoadDeclarationScenario(S_DefaultNamespace_3, S_IntNumber, S_ByteNumber, S_DummyByteArray, S1_DirectByteOperation2); + + BuildTreeSerializer::load(BuildTree_DirectByteOperation2, controlOutputNode); +} + // --- LambdaTest --- BuildNode LambdaTest :: findOutput(BuildNode root) diff --git a/elenasrc3/elena-tests/tests_build.cpp b/elenasrc3/elena-tests/tests_build.cpp index 37ebc3ccd4..3584b96d24 100644 --- a/elenasrc3/elena-tests/tests_build.cpp +++ b/elenasrc3/elena-tests/tests_build.cpp @@ -53,6 +53,7 @@ * NillableIntAssigning * -------------------- * +* ByteArrayOp */ @@ -153,4 +154,14 @@ TEST_F(IntAssigningNil, BuildTest) TEST_F(NillableIntAssigning, BuildTest) { runTest(false); +} + +TEST_F(ByteArrayOperation, BuildTest) +{ + runTest(); +} + +TEST_F(ByteArrayOperation2, BuildTest) +{ + runTest(); } \ No newline at end of file diff --git a/elenasrc3/elena-tests/tests_common.cpp b/elenasrc3/elena-tests/tests_common.cpp index ad197e0367..ed517429da 100644 --- a/elenasrc3/elena-tests/tests_common.cpp +++ b/elenasrc3/elena-tests/tests_common.cpp @@ -415,6 +415,35 @@ void ScenarioTest::SetUp() controlOutputNode = buildTree.readRoot().appendChild(BuildKey::Tape); } +void ScenarioTest :: run(ModuleScopeBase* moduleScope, int scenario) +{ + moduleScope->predefined.add("nil", V_NIL); + + Compiler* compiler = env.createCompiler(); + + BuildTree output; + BuildTreeWriter writer(output); + Compiler::Namespace nsScope(compiler, moduleScope, TestErrorProcessor::getInstance(), nullptr, nullptr); + + // Act + nsScope.declare(declarationNode.firstChild(), true); + + Compiler::Class classHelper(nsScope, targetRef, Visibility::Public); + classHelper.load(); + Compiler::Method methodHelper(classHelper); + + SyntaxNode methodNode = findTargetNode(scenario); + if (methodNode != SyntaxKey::None) + methodHelper.compile(writer, methodNode); + + // Assess + bool matched = BuildTree::compare(output.readRoot(), controlOutputNode, true); + EXPECT_TRUE(matched); + + freeobj(compiler); + freeobj(moduleScope); +} + // --- CompileTest --- void CompileTest :: SetUp() diff --git a/elenasrc3/elena-tests/tests_common.h b/elenasrc3/elena-tests/tests_common.h index 3db0d67d4a..a473b366ed 100644 --- a/elenasrc3/elena-tests/tests_common.h +++ b/elenasrc3/elena-tests/tests_common.h @@ -143,6 +143,21 @@ namespace elena_lang { } + bool declareImport(ustr_t, ustr_t) override + { + return false; + } + + ustr_t resolveImport(ustr_t alias) override + { + return alias; + } + + bool checkVariable(ustr_t) override + { + return false; + } + TestModuleScope(bool tapeOptMode); }; @@ -242,6 +257,8 @@ namespace elena_lang virtual SyntaxNode findTargetNode(int scenario); void SetUp() override; + + void run(ModuleScopeBase* moduleScope, int scenario); }; // --- ScenarioTest --- diff --git a/elenasrc3/elenart/codeblocks/bsd.clang_elenart_amd64.mak b/elenasrc3/elenart/codeblocks/bsd.clang_elenart_amd64.mak new file mode 100644 index 0000000000..26b586887e --- /dev/null +++ b/elenasrc3/elenart/codeblocks/bsd.clang_elenart_amd64.mak @@ -0,0 +1,116 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = clang +CXX = clang++ +AR = ar +LD = clang++ +WINDRES = windres + +RESINC = +LIBDIR = +LIB = +LDFLAGS = -m64 -fvisibility=hidden +INC = -I.. -I../../engine -I../../common +CFLAGS = -Wall -std=c++20 -m64 -fPIC + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../temp/elenart64 +DEP_RELEASE = +OUT_RELEASE = ../../../bin/libelenart60_64.so + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/engine/elenamachine.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/gcroutines.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/rtmanager.o $(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o $(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o $(OBJDIR_RELEASE)/__/elenartmachine.o $(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o $(OBJDIR_RELEASE)/__/linux/main.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../bin || mkdir -p ../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/engine/amd64 || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/amd64 + test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux + test -d $(OBJDIR_RELEASE)/__/__/engine/linux || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/linux + test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common + +after_release: + +release: before_release out_release after_release + +$(OBJDIR_RELEASE)/__/__/common/config.o: ../../common/config.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/config.cpp -o $(OBJDIR_RELEASE)/__/__/common/config.o + +$(OBJDIR_RELEASE)/__/__/common/dump.o: ../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/common/files.o: ../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/common/paths.o: ../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/common/ustring.o: ../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/common/xmltree.o: ../../common/xmltree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/xmltree.cpp -o $(OBJDIR_RELEASE)/__/__/common/xmltree.o + +$(OBJDIR_RELEASE)/__/__/engine/elenamachine.o: ../../engine/elenamachine.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/elenamachine.cpp -o $(OBJDIR_RELEASE)/__/__/engine/elenamachine.o + +$(OBJDIR_RELEASE)/__/__/engine/rtmanager.o: ../../engine/rtmanager.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/rtmanager.cpp -o $(OBJDIR_RELEASE)/__/__/engine/rtmanager.o + +$(OBJDIR_RELEASE)/__/__/engine/gcroutines.o: ../../engine/gcroutines.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/gcroutines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/gcroutines.o + +$(OBJDIR_RELEASE)/__/__/engine/bytecode.o: ../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/__/engine/libman.o: ../../engine/libman.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/libman.cpp -o $(OBJDIR_RELEASE)/__/__/engine/libman.o + +$(OBJDIR_RELEASE)/__/__/engine/module.o: ../../engine/module.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/module.cpp -o $(OBJDIR_RELEASE)/__/__/engine/module.o + +$(OBJDIR_RELEASE)/__/__/engine/section.o: ../../engine/section.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/section.cpp -o $(OBJDIR_RELEASE)/__/__/engine/section.o + +$(OBJDIR_RELEASE)/__/elenartmachine.o: ../elenartmachine.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../elenartmachine.cpp -o $(OBJDIR_RELEASE)/__/elenartmachine.o + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) -shared $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o: ../../engine/amd64/amd64routines.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/amd64/amd64routines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o + +$(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o: ../../engine/linux/lnxroutines.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/lnxroutines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o + +$(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o: ../../engine/linux/elfhelper.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/elfhelper.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o + +$(OBJDIR_RELEASE)/__/linux/main.o: ../linux/main.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/main.cpp -o $(OBJDIR_RELEASE)/__/linux/main.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/engine/amd64 + rm -rf $(OBJDIR_RELEASE)/__/linux + rm -rf $(OBJDIR_RELEASE)/__/__/engine/linux + rm -rf $(OBJDIR_RELEASE)/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/elenart/codeblocks/bsd.elenart_amd64.mak b/elenasrc3/elenart/codeblocks/bsd.elenart_amd64.mak new file mode 100644 index 0000000000..afd3980445 --- /dev/null +++ b/elenasrc3/elenart/codeblocks/bsd.elenart_amd64.mak @@ -0,0 +1,116 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = gcc +CXX = g++ +AR = ar +LD = g++ +WINDRES = windres + +RESINC = +LIBDIR = +LIB = +LDFLAGS = -m64 -fvisibility=hidden +INC = -I.. -I../../engine -I../../common +CFLAGS = -Wall -std=c++20 -m64 -fPIC + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../temp/elenart64 +DEP_RELEASE = +OUT_RELEASE = ../../../bin/libelenart60_64.so + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/engine/elenamachine.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/gcroutines.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/rtmanager.o $(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o $(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o $(OBJDIR_RELEASE)/__/elenartmachine.o $(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o $(OBJDIR_RELEASE)/__/linux/main.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../bin || mkdir -p ../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/engine/amd64 || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/amd64 + test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux + test -d $(OBJDIR_RELEASE)/__/__/engine/linux || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/linux + test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common + +after_release: + +release: before_release out_release after_release + +$(OBJDIR_RELEASE)/__/__/common/config.o: ../../common/config.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/config.cpp -o $(OBJDIR_RELEASE)/__/__/common/config.o + +$(OBJDIR_RELEASE)/__/__/common/dump.o: ../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/common/files.o: ../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/common/paths.o: ../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/common/ustring.o: ../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/common/xmltree.o: ../../common/xmltree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/xmltree.cpp -o $(OBJDIR_RELEASE)/__/__/common/xmltree.o + +$(OBJDIR_RELEASE)/__/__/engine/elenamachine.o: ../../engine/elenamachine.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/elenamachine.cpp -o $(OBJDIR_RELEASE)/__/__/engine/elenamachine.o + +$(OBJDIR_RELEASE)/__/__/engine/rtmanager.o: ../../engine/rtmanager.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/rtmanager.cpp -o $(OBJDIR_RELEASE)/__/__/engine/rtmanager.o + +$(OBJDIR_RELEASE)/__/__/engine/gcroutines.o: ../../engine/gcroutines.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/gcroutines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/gcroutines.o + +$(OBJDIR_RELEASE)/__/__/engine/bytecode.o: ../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/__/engine/libman.o: ../../engine/libman.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/libman.cpp -o $(OBJDIR_RELEASE)/__/__/engine/libman.o + +$(OBJDIR_RELEASE)/__/__/engine/module.o: ../../engine/module.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/module.cpp -o $(OBJDIR_RELEASE)/__/__/engine/module.o + +$(OBJDIR_RELEASE)/__/__/engine/section.o: ../../engine/section.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/section.cpp -o $(OBJDIR_RELEASE)/__/__/engine/section.o + +$(OBJDIR_RELEASE)/__/elenartmachine.o: ../elenartmachine.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../elenartmachine.cpp -o $(OBJDIR_RELEASE)/__/elenartmachine.o + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) -shared $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o: ../../engine/amd64/amd64routines.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/amd64/amd64routines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o + +$(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o: ../../engine/linux/lnxroutines.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/lnxroutines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o + +$(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o: ../../engine/linux/elfhelper.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/elfhelper.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o + +$(OBJDIR_RELEASE)/__/linux/main.o: ../linux/main.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/main.cpp -o $(OBJDIR_RELEASE)/__/linux/main.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/engine/amd64 + rm -rf $(OBJDIR_RELEASE)/__/linux + rm -rf $(OBJDIR_RELEASE)/__/__/engine/linux + rm -rf $(OBJDIR_RELEASE)/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/elenart/codeblocks/elenart_amd64.mak b/elenasrc3/elenart/codeblocks/elenart_amd64.mak index 9cf2367a0e..0b0afdb377 100644 --- a/elenasrc3/elenart/codeblocks/elenart_amd64.mak +++ b/elenasrc3/elenart/codeblocks/elenart_amd64.mak @@ -10,13 +10,23 @@ AR = ar LD = g++ WINDRES = windres -INC = -I.. -I../../engine -I../../common -CFLAGS = -Wall -std=c++20 -m64 -fPIC RESINC = LIBDIR = LIB = LDFLAGS = -m64 -fvisibility=hidden +ifeq ($(OS),Windows_NT) + +INC = -I.. -I../../engine -I../../common -I../../lruntime +CFLAGS = -Wall -std=c++20 -m64 -fPIC -municode + +else + +INC = -I.. -I../../engine -I../../common +CFLAGS = -Wall -std=c++20 -m64 -fPIC + +endif + INC_RELEASE = $(INC) CFLAGS_RELEASE = $(CFLAGS) -O3 RESINC_RELEASE = $(RESINC) @@ -26,9 +36,18 @@ LIB_RELEASE = $(LIB) LDFLAGS_RELEASE = $(LDFLAGS) -s OBJDIR_RELEASE = ../../temp/elenart64 DEP_RELEASE = -OUT_RELEASE = ../../../bin/libelenart60_64.so + +ifeq ($(OS),Windows_NT) + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/engine/elenamachine.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/gcroutines.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/rtmanager.o $(OBJDIR_RELEASE)/__/__/engine/windows/winroutines.o $(OBJDIR_RELEASE)/__/__/engine/windows/pehelper.o $(OBJDIR_RELEASE)/__/elenartmachine.o $(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o $(OBJDIR_RELEASE)/__/windows/dllmain.o +OUT_RELEASE = ../../../bin/elenart60_64.dll + +else OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/engine/elenamachine.o $(OBJDIR_RELEASE)/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/engine/gcroutines.o $(OBJDIR_RELEASE)/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/engine/rtmanager.o $(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o $(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o $(OBJDIR_RELEASE)/__/elenartmachine.o $(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o $(OBJDIR_RELEASE)/__/linux/main.o +OUT_RELEASE = ../../../bin/libelenart60_64.so + +endif all: release @@ -38,9 +57,14 @@ before_release: test -d ../../../bin || mkdir -p ../../../bin test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine - test -d $(OBJDIR_RELEASE)/__/__/engine/linux || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/linux test -d $(OBJDIR_RELEASE)/__/__/engine/amd64 || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/amd64 +ifeq ($(OS),Windows_NT) + test -d $(OBJDIR_RELEASE)/__/windows || mkdir -p $(OBJDIR_RELEASE)/__/windows + test -d $(OBJDIR_RELEASE)/__/__/engine/windows || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/windows +else test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux + test -d $(OBJDIR_RELEASE)/__/__/engine/linux || mkdir -p $(OBJDIR_RELEASE)/__/__/engine/linux +endif test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common after_release: @@ -71,12 +95,6 @@ $(OBJDIR_RELEASE)/__/__/engine/elenamachine.o: ../../engine/elenamachine.cpp $(OBJDIR_RELEASE)/__/__/engine/rtmanager.o: ../../engine/rtmanager.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/rtmanager.cpp -o $(OBJDIR_RELEASE)/__/__/engine/rtmanager.o -$(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o: ../../engine/linux/lnxroutines.cpp - $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/lnxroutines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o - -$(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o: ../../engine/linux/elfhelper.cpp - $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/elfhelper.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o - $(OBJDIR_RELEASE)/__/__/engine/gcroutines.o: ../../engine/gcroutines.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/gcroutines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/gcroutines.o @@ -101,16 +119,42 @@ out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) $(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o: ../../engine/amd64/amd64routines.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/amd64/amd64routines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o +ifeq ($(OS),Windows_NT) + +$(OBJDIR_RELEASE)/__/__/engine/windows/winroutines.o: ../../engine/windows/winroutines.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/windows/winroutines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/windows/winroutines.o + +$(OBJDIR_RELEASE)/__/__/engine/windows/pehelper.o: ../../lruntime/windows/pehelper.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../lruntime/windows/pehelper.cpp -o $(OBJDIR_RELEASE)/__/__/engine/windows/pehelper.o + +$(OBJDIR_RELEASE)/__/windows/dllmain.o: ../windows/dllmain.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../windows/dllmain.cpp -o $(OBJDIR_RELEASE)/__/windows/dllmain.o + +else + +$(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o: ../../engine/linux/lnxroutines.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/lnxroutines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/lnxroutines.o + +$(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o: ../../engine/linux/elfhelper.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/linux/elfhelper.cpp -o $(OBJDIR_RELEASE)/__/__/engine/linux/elfhelper.o + $(OBJDIR_RELEASE)/__/linux/main.o: ../linux/main.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/main.cpp -o $(OBJDIR_RELEASE)/__/linux/main.o +endif + clean_release: rm -f $(OBJ_RELEASE) $(OUT_RELEASE) rm -rf $(OBJDIR_RELEASE)/__ rm -rf $(OBJDIR_RELEASE)/__/__/engine - rm -rf $(OBJDIR_RELEASE)/__/__/engine/linux rm -rf $(OBJDIR_RELEASE)/__/__/engine/amd64 +ifeq ($(OS),Windows_NT) + rm -rf $(OBJDIR_RELEASE)/__/windows + rm -rf $(OBJDIR_RELEASE)/__/__/engine/windows +else rm -rf $(OBJDIR_RELEASE)/__/linux + rm -rf $(OBJDIR_RELEASE)/__/__/engine/linux +endif rm -rf $(OBJDIR_RELEASE)/__/__/common .PHONY: before_release after_release clean_release diff --git a/elenasrc3/elenart/linux/elenart.h b/elenasrc3/elenart/linux/elenart.h index 845f4a76bb..ed7b0a6ed5 100644 --- a/elenasrc3/elenart/linux/elenart.h +++ b/elenasrc3/elenart/linux/elenart.h @@ -24,6 +24,12 @@ extern "C" { +#ifdef __FreeBSD__ + // temporal solution to work on FreeBSD + DLL_PUBLIC char** environ = nullptr; + DLL_PUBLIC const char* __progname = "elena-prog"; +#endif + DLL_PUBLIC void InitializeSTLA(elena_lang::SystemEnv* env, elena_lang::SymbolList* entryList, void* criricalHandler); DLL_PUBLIC void InitializeMTLA(elena_lang::SystemEnv* env, elena_lang::SymbolList* entryList, void* criricalHandler); DLL_PUBLIC void* CollectGCLA(void* roots, size_t size); diff --git a/elenasrc3/elenart/linux/main.cpp b/elenasrc3/elenart/linux/main.cpp index 69abc560e1..0e99b924ac 100644 --- a/elenasrc3/elenart/linux/main.cpp +++ b/elenasrc3/elenart/linux/main.cpp @@ -218,6 +218,12 @@ void PrepareLA(uintptr_t arg) __argv = (char**)(arg + sizeof(uintptr_t)); #endif + +#if defined __FreeBSD__ + + __progname = __argv[0]; + +#endif } void ExitLA(int retVal) diff --git a/elenasrc3/elenasm/codeblocks/bsd.clang_elenasm_amd64.mak b/elenasrc3/elenasm/codeblocks/bsd.clang_elenasm_amd64.mak new file mode 100644 index 0000000000..f6e161136b --- /dev/null +++ b/elenasrc3/elenasm/codeblocks/bsd.clang_elenasm_amd64.mak @@ -0,0 +1,100 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = clang +CXX = clang++ +AR = ar +LD = clang++ +WINDRES = windres + +INC = -I.. -I../../engine -I../../common +RESINC = +LIBDIR = +LIB = +LDFLAGS = -m64 -fvisibility=hidden +CFLAGS = -Wall -std=c++20 -m64 -fPIC + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../temp/elenasm64 +DEP_RELEASE = +OUT_RELEASE = ../../../bin/libelenasm60_64.so + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/cfparser.o $(OBJDIR_RELEASE)/__/scriptmachine.o $(OBJDIR_RELEASE)/__/transformer.o $(OBJDIR_RELEASE)/__/treeparser.o $(OBJDIR_RELEASE)/__/vmparser.o $(OBJDIR_RELEASE)/__/linux/main.o $(OBJDIR_RELEASE)/__/regex.o $(OBJDIR_RELEASE)/__/scriptparser.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../bin || mkdir -p ../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine + test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux + test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common + +after_release: + +release: before_release out_release after_release + +$(OBJDIR_RELEASE)/__/__/common/dump.o: ../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/common/files.o: ../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/common/paths.o: ../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/common/ustring.o: ../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o: ../../engine/syntaxtree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/syntaxtree.cpp -o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o + +$(OBJDIR_RELEASE)/__/cfparser.o: ../cfparser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../cfparser.cpp -o $(OBJDIR_RELEASE)/__/cfparser.o + +$(OBJDIR_RELEASE)/__/scriptmachine.o: ../scriptmachine.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../scriptmachine.cpp -o $(OBJDIR_RELEASE)/__/scriptmachine.o + +$(OBJDIR_RELEASE)/__/transformer.o: ../transformer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../transformer.cpp -o $(OBJDIR_RELEASE)/__/transformer.o + +$(OBJDIR_RELEASE)/__/treeparser.o: ../treeparser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../treeparser.cpp -o $(OBJDIR_RELEASE)/__/treeparser.o + +$(OBJDIR_RELEASE)/__/vmparser.o: ../vmparser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../vmparser.cpp -o $(OBJDIR_RELEASE)/__/vmparser.o + +$(OBJDIR_RELEASE)/__/regex.o: ../regex.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../regex.cpp -o $(OBJDIR_RELEASE)/__/regex.o + +$(OBJDIR_RELEASE)/__/scriptparser.o: ../scriptparser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../scriptparser.cpp -o $(OBJDIR_RELEASE)/__/scriptparser.o + +$(OBJDIR_RELEASE)/__/linux/main.o: ../linux/main.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/main.cpp -o $(OBJDIR_RELEASE)/__/linux/main.o + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) -shared $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/linux + rm -rf $(OBJDIR_RELEASE)/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/elenasm/codeblocks/bsd.elenasm_amd64.mak b/elenasrc3/elenasm/codeblocks/bsd.elenasm_amd64.mak new file mode 100644 index 0000000000..4c4806d81d --- /dev/null +++ b/elenasrc3/elenasm/codeblocks/bsd.elenasm_amd64.mak @@ -0,0 +1,100 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = gcc +CXX = g++ +AR = ar +LD = g++ +WINDRES = windres + +INC = -I.. -I../../engine -I../../common +RESINC = +LIBDIR = +LIB = +LDFLAGS = -m64 -fvisibility=hidden +CFLAGS = -Wall -std=c++20 -m64 -fPIC + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../temp/elenasm64 +DEP_RELEASE = +OUT_RELEASE = ../../../bin/libelenasm60_64.so + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/cfparser.o $(OBJDIR_RELEASE)/__/scriptmachine.o $(OBJDIR_RELEASE)/__/transformer.o $(OBJDIR_RELEASE)/__/treeparser.o $(OBJDIR_RELEASE)/__/vmparser.o $(OBJDIR_RELEASE)/__/linux/main.o $(OBJDIR_RELEASE)/__/regex.o $(OBJDIR_RELEASE)/__/scriptparser.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../bin || mkdir -p ../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine + test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux + test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common + +after_release: + +release: before_release out_release after_release + +$(OBJDIR_RELEASE)/__/__/common/dump.o: ../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/common/files.o: ../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/common/paths.o: ../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/common/ustring.o: ../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/engine/scriptreader.o: ../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o: ../../engine/syntaxtree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/syntaxtree.cpp -o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o + +$(OBJDIR_RELEASE)/__/cfparser.o: ../cfparser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../cfparser.cpp -o $(OBJDIR_RELEASE)/__/cfparser.o + +$(OBJDIR_RELEASE)/__/scriptmachine.o: ../scriptmachine.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../scriptmachine.cpp -o $(OBJDIR_RELEASE)/__/scriptmachine.o + +$(OBJDIR_RELEASE)/__/transformer.o: ../transformer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../transformer.cpp -o $(OBJDIR_RELEASE)/__/transformer.o + +$(OBJDIR_RELEASE)/__/treeparser.o: ../treeparser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../treeparser.cpp -o $(OBJDIR_RELEASE)/__/treeparser.o + +$(OBJDIR_RELEASE)/__/vmparser.o: ../vmparser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../vmparser.cpp -o $(OBJDIR_RELEASE)/__/vmparser.o + +$(OBJDIR_RELEASE)/__/regex.o: ../regex.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../regex.cpp -o $(OBJDIR_RELEASE)/__/regex.o + +$(OBJDIR_RELEASE)/__/scriptparser.o: ../scriptparser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../scriptparser.cpp -o $(OBJDIR_RELEASE)/__/scriptparser.o + +$(OBJDIR_RELEASE)/__/linux/main.o: ../linux/main.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/main.cpp -o $(OBJDIR_RELEASE)/__/linux/main.o + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) -shared $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/linux + rm -rf $(OBJDIR_RELEASE)/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/elenasm/codeblocks/elenasm_amd64.mak b/elenasrc3/elenasm/codeblocks/elenasm_amd64.mak index a10489f0e9..f30ae59d70 100644 --- a/elenasrc3/elenasm/codeblocks/elenasm_amd64.mak +++ b/elenasrc3/elenasm/codeblocks/elenasm_amd64.mak @@ -11,12 +11,21 @@ LD = g++ WINDRES = windres INC = -I.. -I../../engine -I../../common -CFLAGS = -Wall -std=c++20 -m64 -fPIC RESINC = LIBDIR = LIB = LDFLAGS = -m64 -fvisibility=hidden +ifeq ($(OS),Windows_NT) + +CFLAGS = -Wall -std=c++20 -m64 -fPIC -municode + +else + +CFLAGS = -Wall -std=c++20 -m64 -fPIC + +endif + INC_RELEASE = $(INC) CFLAGS_RELEASE = $(CFLAGS) -O3 RESINC_RELEASE = $(RESINC) @@ -26,9 +35,18 @@ LIB_RELEASE = $(LIB) LDFLAGS_RELEASE = $(LDFLAGS) -s OBJDIR_RELEASE = ../../temp/elenasm64 DEP_RELEASE = + +ifeq ($(OS),Windows_NT) + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/cfparser.o $(OBJDIR_RELEASE)/__/scriptmachine.o $(OBJDIR_RELEASE)/__/transformer.o $(OBJDIR_RELEASE)/__/treeparser.o $(OBJDIR_RELEASE)/__/vmparser.o $(OBJDIR_RELEASE)/__/windows/dllmain.o $(OBJDIR_RELEASE)/__/regex.o $(OBJDIR_RELEASE)/__/scriptparser.o +OUT_RELEASE = ../../../bin/elenasm60_64.dll + +else + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/cfparser.o $(OBJDIR_RELEASE)/__/scriptmachine.o $(OBJDIR_RELEASE)/__/transformer.o $(OBJDIR_RELEASE)/__/treeparser.o $(OBJDIR_RELEASE)/__/vmparser.o $(OBJDIR_RELEASE)/__/linux/main.o $(OBJDIR_RELEASE)/__/regex.o $(OBJDIR_RELEASE)/__/scriptparser.o OUT_RELEASE = ../../../bin/libelenasm60_64.so -OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/__/engine/syntaxtree.o $(OBJDIR_RELEASE)/__/cfparser.o $(OBJDIR_RELEASE)/__/scriptmachine.o $(OBJDIR_RELEASE)/__/transformer.o $(OBJDIR_RELEASE)/__/treeparser.o $(OBJDIR_RELEASE)/__/vmparser.o $(OBJDIR_RELEASE)/__/linux/main.o +endif all: release @@ -38,7 +56,11 @@ before_release: test -d ../../../bin || mkdir -p ../../../bin test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ test -d $(OBJDIR_RELEASE)/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/engine +ifeq ($(OS),Windows_NT) + test -d $(OBJDIR_RELEASE)/__/windows || mkdir -p $(OBJDIR_RELEASE)/__/windows +else test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux +endif test -d $(OBJDIR_RELEASE)/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/common after_release: @@ -78,23 +100,36 @@ $(OBJDIR_RELEASE)/__/treeparser.o: ../treeparser.cpp $(OBJDIR_RELEASE)/__/vmparser.o: ../vmparser.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../vmparser.cpp -o $(OBJDIR_RELEASE)/__/vmparser.o -$(OBJDIR_RELEASE)/__/linux/main.o: ../linux/main.cpp - $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/main.cpp -o $(OBJDIR_RELEASE)/__/linux/main.o +$(OBJDIR_RELEASE)/__/regex.o: ../regex.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../regex.cpp -o $(OBJDIR_RELEASE)/__/regex.o -out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) - $(LD) -shared $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) +$(OBJDIR_RELEASE)/__/scriptparser.o: ../scriptparser.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../scriptparser.cpp -o $(OBJDIR_RELEASE)/__/scriptparser.o + +ifeq ($(OS),Windows_NT) -$(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o: ../../engine/amd64/amd64routines.cpp - $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../engine/amd64/amd64routines.cpp -o $(OBJDIR_RELEASE)/__/__/engine/amd64/amd64routines.o +$(OBJDIR_RELEASE)/__/windows/dllmain.o: ../windows/dllmain.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../windows/dllmain.cpp -o $(OBJDIR_RELEASE)/__/windows/dllmain.o + +else $(OBJDIR_RELEASE)/__/linux/main.o: ../linux/main.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/main.cpp -o $(OBJDIR_RELEASE)/__/linux/main.o +endif + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) -shared $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + clean_release: rm -f $(OBJ_RELEASE) $(OUT_RELEASE) rm -rf $(OBJDIR_RELEASE)/__ rm -rf $(OBJDIR_RELEASE)/__/__/engine +ifeq ($(OS),Windows_NT) + rm -rf $(OBJDIR_RELEASE)/__/windows +else rm -rf $(OBJDIR_RELEASE)/__/linux +endif rm -rf $(OBJDIR_RELEASE)/__/__/common .PHONY: before_release after_release clean_release diff --git a/elenasrc3/elenasm/smcommon.h b/elenasrc3/elenasm/smcommon.h index d6e2b28ad0..1e3b0e1c76 100644 --- a/elenasrc3/elenasm/smcommon.h +++ b/elenasrc3/elenasm/smcommon.h @@ -9,7 +9,7 @@ #ifndef RTCOMMON_H #define RTCOMMON_H -#define ELENASM_REVISION_NUMBER 0x0016 +#define ELENASM_REVISION_NUMBER 0x0017 namespace elena_lang { diff --git a/elenasrc3/elenasm/treeparser.cpp b/elenasrc3/elenasm/treeparser.cpp index 3274ab57b3..b2194c2a38 100644 --- a/elenasrc3/elenasm/treeparser.cpp +++ b/elenasrc3/elenasm/treeparser.cpp @@ -34,6 +34,61 @@ void TreeScriptParser :: parseScope(ScriptEngineReaderBase& reader, ScriptBookma } } +void TreeScriptParser::parseVirtualStatement(ScriptEngineReaderBase& reader, ScriptBookmark& bm, + SyntaxTreeWriter& writer) +{ + ScriptBookmark nameBm = bm; + ustr_t virtualOp = reader.lookup(bm); + + SyntaxTree tempTree; + SyntaxTreeWriter tempWriter(tempTree); + tempWriter.newNode(SyntaxKey::Root); + + bm = reader.read(); + if (!reader.compare("(")) + throw SyntaxError("invalid grammar rule", bm.lineInfo); + + bm = reader.read(); + while (!reader.compare(")")) { + parseStatement(reader, bm, tempWriter); + + bm = reader.read(); + } + + tempWriter.closeNode(); + + if (virtualOp.compare("virtual_for_loop")) { + SyntaxNode initNode = tempTree.readRoot().firstChild(); + SyntaxNode condNode = initNode.nextNode(); + SyntaxNode stepNode = condNode.nextNode(); + SyntaxNode bodyNode = stepNode.nextNode(); + + SyntaxNode codeNode = bodyNode.firstChild(); + if (codeNode == SyntaxKey::ClosureBlock) { + codeNode = codeNode.firstChild(); + } + if (codeNode == SyntaxKey::CodeBlock) { + SyntaxTreeWriter codeWriter(codeNode); + + SyntaxTree::copyNode(codeWriter, stepNode); + } + else throw SyntaxError("invalid grammar rule", nameBm.lineInfo); + + SyntaxTree::copyNode(writer, initNode); + + writer.newNode(SyntaxKey::Expression); + writer.newNode(SyntaxKey::LoopOperation); + writer.newNode(SyntaxKey::IfOperation); + SyntaxTree::copyNode(writer, condNode); + SyntaxTree::copyNode(writer, bodyNode); + + writer.closeNode(); + writer.closeNode(); + writer.closeNode(); + } + else throw SyntaxError("invalid grammar rule", nameBm.lineInfo); +} + void TreeScriptParser :: parseStatement(ScriptEngineReaderBase& reader, ScriptBookmark& bm, SyntaxTreeWriter& writer) { @@ -91,7 +146,10 @@ void TreeScriptParser :: parse(ScriptEngineReaderBase& reader, MemoryDump* outpu ScriptBookmark bm = reader.read(); while (!reader.eof()) { - parseStatement(reader, bm, treeWriter); + if (reader.lookup(bm).startsWith("virtual_")) { + parseVirtualStatement(reader, bm, treeWriter); + } + else parseStatement(reader, bm, treeWriter); bm = reader.read(); } diff --git a/elenasrc3/elenasm/treeparser.h b/elenasrc3/elenasm/treeparser.h index 8a3894b174..3f159d7e6b 100644 --- a/elenasrc3/elenasm/treeparser.h +++ b/elenasrc3/elenasm/treeparser.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA VM Script Engine // -// (C)2023 by Aleksey Rakov +// (C)2023-2025 by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef TREEPARSER_H @@ -22,7 +22,9 @@ namespace elena_lang void parseScope(ScriptEngineReaderBase& reader, ScriptBookmark& bm, SyntaxTreeWriter& writer, SyntaxKey type); - void parseStatement(ScriptEngineReaderBase& reader, ScriptBookmark& bm, + void parseVirtualStatement(ScriptEngineReaderBase& reader, ScriptBookmark& bm, + SyntaxTreeWriter& writer); + void parseStatement(ScriptEngineReaderBase& reader, ScriptBookmark& bm, SyntaxTreeWriter& writer); public: diff --git a/elenasrc3/engine/bcwriter.cpp b/elenasrc3/engine/bcwriter.cpp index 9a2f6e2d35..cda491f391 100644 --- a/elenasrc3/engine/bcwriter.cpp +++ b/elenasrc3/engine/bcwriter.cpp @@ -81,6 +81,15 @@ void openFrame(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) tape.write(ByteCode::OpenIN, reservedManaged, reservedUnmanaged); } +void extOpenFrame(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +{ + int reservedManaged = tapeScope.reserved; + int reservedUnmanaged = tapeScope.reservedN; + + tape.newLabel(); + tape.write(ByteCode::ExtOpenIN, reservedManaged, reservedUnmanaged); +} + void closeFrame(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) { int reservedUnmanaged = tapeScope.reservedN; @@ -95,6 +104,19 @@ void closeFrame(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) } } +void close_ext_frame(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +{ + int reservedUnmanaged = tapeScope.reservedN; + + tape.setLabel(); + if (tapeScope.scope->ptrSize == 8) { + tape.write(ByteCode::LLoad); + } + else tape.write(ByteCode::Load); + + tape.write(ByteCode::ExtCloseN, reservedUnmanaged); +} + void nilReference(CommandTape& tape, BuildNode& node, TapeScope&) { tape.write(ByteCode::SetR, 0); @@ -202,6 +224,11 @@ void exit(CommandTape& tape, BuildNode&, TapeScope&) tape.write(ByteCode::Quit); } +void ext_exit(CommandTape& tape, BuildNode&, TapeScope&) +{ + tape.write(ByteCode::XQuit); +} + void savingInStack(CommandTape& tape, BuildNode& node, TapeScope&) { tape.write(ByteCode::StoreSI, node.arg.value); @@ -439,6 +466,16 @@ void constantArray(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) tape.write(ByteCode::SetR, node.arg.reference | mskConstArray); } +void procedure_ref(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +{ + tape.write(ByteCode::SetR, node.arg.reference | mskProcedureRef); +} + +void externalvar_ref(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) +{ + tape.write(ByteCode::SetR, node.arg.reference | mskExternalRef); +} + void goingToEOP(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) { //gotoEnd(tape, baFirstLabel); @@ -782,6 +819,53 @@ void intOpWithConst(CommandTape& tape, BuildNode& node, TapeScope&) tape.write(ByteCode::SaveDP, targetOffset); } +void byteOpWithConst(CommandTape& tape, BuildNode& node, TapeScope&) +{ + // NOTE : sp[0] - loperand + int targetOffset = node.arg.value; + int operatorId = node.findChild(BuildKey::OperatorId).arg.value; + int sourceOffset = node.findChild(BuildKey::Source).arg.value; + int value = node.findChild(BuildKey::Value).arg.value; + + // loaddpn + tape.write(ByteCode::LoadDP, sourceOffset); + + switch (operatorId) { + case ADD_OPERATOR_ID: + tape.write(ByteCode::AndN, 0xFF); + tape.write(ByteCode::AddN, value); + break; + case SUB_OPERATOR_ID: + tape.write(ByteCode::AndN, 0xFF); + tape.write(ByteCode::SubN, value); + break; + case MUL_OPERATOR_ID: + tape.write(ByteCode::AndN, 0xFF); + tape.write(ByteCode::MulN, value); + break; + case BAND_OPERATOR_ID: + tape.write(ByteCode::AndN, value); + break; + case BOR_OPERATOR_ID: + tape.write(ByteCode::AndN, 0xFF); + tape.write(ByteCode::OrN, value); + break; + case SHL_OPERATOR_ID: + tape.write(ByteCode::AndN, 0xFF); + tape.write(ByteCode::Shl, value); + break; + case SHR_OPERATOR_ID: + tape.write(ByteCode::AndN, 0xFF); + tape.write(ByteCode::Shr, value); + break; + default: + throw InternalError(errFatalError); + } + + // savedpn + tape.write(ByteCode::SaveDP, targetOffset); +} + void uintOp(CommandTape& tape, BuildNode& node, TapeScope&) { // NOTE : sp[0] - loperand, sp[1] - roperand @@ -1857,7 +1941,7 @@ void breakOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) if (eolLabel > 0) { tape.write(ByteCode::Jump, eolLabel); } - else tape.write(ByteCode::Jump, PseudoArg::CurrentLabel); + else tape.write(ByteCode::Jump, PseudoArg::FirstLabel); } void continueOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) @@ -2075,6 +2159,12 @@ void freeStack(CommandTape& tape, BuildNode& node, TapeScope&) tape.write(ByteCode::DFree); } + +inline void load_ext_arg(CommandTape& tape, BuildNode& node, TapeScope&) +{ + tape.write(ByteCode::XLoadArgFI, node.arg.value); +} + inline void savingInt(CommandTape& tape, BuildNode& node, TapeScope&) { BuildNode value = node.findChild(BuildKey::Value); @@ -2087,6 +2177,11 @@ inline void loadingAccToIndex(CommandTape& tape, BuildNode& node, TapeScope&) tape.write(ByteCode::Load); } +inline void loadingAccToLongIndex(CommandTape& tape, BuildNode& node, TapeScope&) +{ + tape.write(ByteCode::LLoad); +} + inline void savingIndexToAcc(CommandTape& tape, BuildNode& node, TapeScope&) { tape.write(ByteCode::Save); @@ -2192,7 +2287,9 @@ ByteCodeWriter::Saver commands[] = intRealOp, real_int_op, copyingToLocalArr, loadingStackDump, savingStackDump, savingFloatIndex, intCopyingToAccField, intOpWithConst, uint8CondOp, uint16CondOp, intLongOp, distrConstant, unboxingAndCallMessage, threadVarOp, threadVarAssigning, threadVarBegin, - threadVarEnd, load_long_index, save_long_index, real_int_xop + threadVarEnd, load_long_index, save_long_index, real_int_xop, extOpenFrame, load_ext_arg, close_ext_frame, ext_exit, + + procedure_ref, loadingAccToLongIndex, externalvar_ref, byteOpWithConst }; inline bool duplicateBreakpoints(BuildNode lastNode) @@ -2351,6 +2448,22 @@ inline bool intOpWithConsts(BuildNode lastNode) BuildNode savingOp1 = getPrevious(intNode); BuildNode sourceNode = getPrevious(savingOp1); + BuildKey constOp = BuildKey::None; + int size = 0; + switch (opNode.key) { + case BuildKey::IntOp: + size = 4; + constOp = BuildKey::IntConstOp; + break; + case BuildKey::ByteOp: + size = 1; + constOp = BuildKey::ByteConstOp; + break; + default: + assert(false); + break; + } + int tempTarget = opNode.arg.value; int operatorId = opNode.findChild(BuildKey::OperatorId).arg.value; switch (operatorId) { @@ -2358,7 +2471,7 @@ inline bool intOpWithConsts(BuildNode lastNode) case SUB_OPERATOR_ID: savingOp1.setKey(BuildKey::Copying); savingOp1.setArgumentValue(tempTarget); - savingOp1.appendChild(BuildKey::Size, 4); + savingOp1.appendChild(BuildKey::Size, size); intNode.setKey(BuildKey::AddingInt); intNode.setArgumentValue(tempTarget); if (operatorId == SUB_OPERATOR_ID) { @@ -2384,7 +2497,7 @@ inline bool intOpWithConsts(BuildNode lastNode) setChild(intNode, BuildKey::Source, sourceNode.arg.value); setChild(intNode, BuildKey::OperatorId, operatorId); - intNode.setKey(BuildKey::IntConstOp); + intNode.setKey(constOp); intNode.setArgumentValue(tempTarget); opNode.setKey(BuildKey::Idle); @@ -3707,7 +3820,9 @@ void ByteCodeWriter :: saveTape(CommandTape& tape, BuildNode node, TapeScope& ta void ByteCodeWriter :: saveSymbol(BuildNode node, SectionScopeBase* moduleScope, int minimalArgList, int ptrSize, ReferenceMap& paths, bool tapeOptMode) { - auto section = moduleScope->mapSection(node.arg.reference | mskSymbolRef, false); + ref_t mask = node.key == BuildKey::Procedure ? mskProcedureRef : mskSymbolRef; + + auto section = moduleScope->mapSection(node.arg.reference | mask, false); MemoryWriter writer(section); Scope scope = { nullptr, &writer, moduleScope, nullptr, nullptr, minimalArgList, ptrSize }; @@ -4007,6 +4122,7 @@ void ByteCodeWriter :: save(BuildTree& tree, SectionScopeBase* moduleScope, while (current != BuildKey::None) { switch (current.key) { case BuildKey::Symbol: + case BuildKey::Procedure: saveSymbol(current, moduleScope, minimalArgList, ptrSize, paths, tapeOptMode); break; case BuildKey::Class: diff --git a/elenasrc3/engine/buildtree.h b/elenasrc3/engine/buildtree.h index 4dfa7fd69e..6896ed735f 100644 --- a/elenasrc3/engine/buildtree.h +++ b/elenasrc3/engine/buildtree.h @@ -34,6 +34,7 @@ namespace elena_lang Method = 0x1004, Tape = 0x1005, AbstractMethod = 0x1006, + Procedure = 0x1007, OpenFrame = 0x0001, CloseFrame = 0x0002, @@ -174,13 +175,17 @@ namespace elena_lang LoadingLIndex = 0x0089, SavingLIndex = 0x008A, RealIntXOp = 0x008B, - - MaxOperationalKey = 0x008B, - - Import = 0x0090, - DictionaryOp = 0x0091, - ObjOp = 0x0092, - AttrDictionaryOp = 0x0093, + OpenExtFrame = 0x008C, + LoadExtArg = 0x008D, + CloseExtFrame = 0x008E, + ExtExit = 0x008F, + ProcedureReference = 0x0090, + LoadingAccToLongIndex = 0x0091, + ExternalVarReference = 0x0092, + ByteConstOp = 0x0093, + + MaxOperationalKey = 0x0093, + DeclOp = 0x0094, DeclDictionaryOp = 0x0095, LoopOp = 0x0096, @@ -202,6 +207,11 @@ namespace elena_lang NilRefBranchOp = 0x00A6, ExcludeTry = 0x00A7, IncludeTry = 0x00A8, + Import = 0x00A9, + DictionaryOp = 0x00AA, + ProjectInfoOp = 0x00AB, + ObjOp = 0x00AC, + AttrDictionaryOp = 0x00AD, VariableInfo = 0x00B0, Variable = 0x00B1, @@ -367,6 +377,7 @@ namespace elena_lang map.add("local_address", BuildKey::LocalAddress); map.add("saving_stack", BuildKey::SavingInStack); map.add("intop", BuildKey::IntOp); + map.add("byteop", BuildKey::ByteOp); map.add("create_struct", BuildKey::CreatingStruct); map.add("assigning", BuildKey::Assigning); map.add("copying_to_acc", BuildKey::CopyingToAcc); @@ -438,6 +449,9 @@ namespace elena_lang map.add("load_long_index", BuildKey::LoadingLIndex); map.add("save_long_index", BuildKey::SavingLIndex); map.add("real_int_xop", BuildKey::RealIntXOp); + map.add("procedure_ref", BuildKey::ProcedureReference); + map.add("break_op", BuildKey::BreakOp); + map.add("bytearray_op", BuildKey::ByteArrayOp); } }; diff --git a/elenasrc3/engine/bytecode.cpp b/elenasrc3/engine/bytecode.cpp index afa14b4414..d663eac6d9 100644 --- a/elenasrc3/engine/bytecode.cpp +++ b/elenasrc3/engine/bytecode.cpp @@ -134,8 +134,7 @@ void ByteCodeUtil :: decode(ByteCode code, IdentifierString& target) target.append(_fnOpcodes[(int)code]); } -void ByteCodeUtil :: formatMessageName(IdentifierString& messageName, ModuleBase* module, ustr_t actionName, - ref_t* references, size_t len, pos_t argCount, ref_t flags) +inline void addMessageNamePrefix(IdentifierString& messageName, ref_t flags) { if (test(flags, STATIC_MESSAGE)) messageName.append("static:"); @@ -156,6 +155,21 @@ void ByteCodeUtil :: formatMessageName(IdentifierString& messageName, ModuleBase default: break; } +} + +inline void addMessageNamePostfix(IdentifierString& messageName, pos_t argCount) +{ + if (argCount != 0) { + messageName.append('['); + messageName.appendInt(argCount); + messageName.append(']'); + } +} + +void ByteCodeUtil :: formatMessageName(IdentifierString& messageName, ModuleBase* module, ustr_t actionName, + ref_t* references, size_t len, pos_t argCount, ref_t flags) +{ + addMessageNamePrefix(messageName, flags); messageName.append(actionName); if (len > 0) { @@ -170,11 +184,34 @@ void ByteCodeUtil :: formatMessageName(IdentifierString& messageName, ModuleBase messageName.append('>'); } - if (argCount != 0) { - messageName.append('['); - messageName.appendInt(argCount); - messageName.append(']'); + addMessageNamePostfix(messageName, argCount); +} + +void ByteCodeUtil :: formatMessageNameWithNullableArgs(IdentifierString& messageName, ModuleBase* module, ustr_t actionName, + ref_t* references, size_t len, pos_t argCount, ref_t flags, int nullableArgs) +{ + addMessageNamePrefix(messageName, flags); + + messageName.append(actionName); + if (len > 0) { + messageName.append('<'); + + int currentArg = 1; + for (size_t i = 0; i < len; i++) { + if (i != 0) + messageName.append(','); + + messageName.append(module->resolveReference(references[i])); + + if (test(nullableArgs, currentArg)) + messageName.append('?'); + + currentArg <<= 1; + } + messageName.append('>'); } + + addMessageNamePostfix(messageName, argCount); } bool ByteCodeUtil :: resolveMessageName(IdentifierString& messageName, ModuleBase* module, mssg_t message) @@ -196,6 +233,25 @@ bool ByteCodeUtil :: resolveMessageName(IdentifierString& messageName, ModuleBas return true; } +bool ByteCodeUtil :: resolveMessageNameWithNullableArgs(IdentifierString& messageName, ModuleBase* module, mssg_t message, int nullableArgs) +{ + ref_t actionRef, flags; + pos_t argCount = 0; + decodeMessage(message, actionRef, argCount, flags); + + ref_t signature = 0; + ustr_t actionName = module->resolveAction(actionRef, signature); + if (emptystr(actionName)) + return false; + + ref_t references[ARG_COUNT]; + size_t len = signature ? module->resolveSignature(signature, references) : 0; + + formatMessageNameWithNullableArgs(messageName, module, actionName, references, len, argCount, flags, nullableArgs); + + return true; +} + void ByteCodeUtil :: parseMessageName(ustr_t messageName, IdentifierString& actionName, ref_t& flags, pos_t& argCount) { if (messageName.startsWith("static:")) { diff --git a/elenasrc3/engine/bytecode.h b/elenasrc3/engine/bytecode.h index ce862f250c..b869879717 100644 --- a/elenasrc3/engine/bytecode.h +++ b/elenasrc3/engine/bytecode.h @@ -1,9 +1,10 @@ //------------------------------------------------------------------------------ +// // E L E N A P r o j e c t: ELENA Engine // // This file contains common ELENA byte code classes and constants // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //------------------------------------------------------------------------------ #ifndef BYTECODE_H @@ -503,6 +504,11 @@ namespace elena_lang ref_t* references, size_t len, pos_t argCount, ref_t flags); static bool resolveMessageName(IdentifierString& messageName, ModuleBase* module, mssg_t message); + // NOTE : information about nullable arguments are optional and is used only in ECV tool + static void formatMessageNameWithNullableArgs(IdentifierString& messageName, ModuleBase* module, ustr_t actionName, + ref_t* references, size_t len, pos_t argCount, ref_t flags, int nullableArgs); + static bool resolveMessageNameWithNullableArgs(IdentifierString& messageName, ModuleBase* module, mssg_t message, int nullableArgs); + static void parseMessageName(ustr_t messageName, IdentifierString& actionName, ref_t& flags, pos_t& argCount); static mssg_t resolveMessage(ustr_t messageName, ModuleBase* module, bool readOnlyMode); diff --git a/elenasrc3/engine/elena.h b/elenasrc3/engine/elena.h index 000c422538..f512842af6 100644 --- a/elenasrc3/engine/elena.h +++ b/elenasrc3/engine/elena.h @@ -129,6 +129,7 @@ namespace elena_lang typedef Map ResolvedMap; typedef Map FieldAddressMap; typedef MemoryMap Forwards; + typedef Map Variables; // --- Lists --- typedef List IdentifierList; @@ -286,6 +287,13 @@ namespace elena_lang virtual void forEachForward(void* arg, void(*feedback)(void* arg, ustr_t key, ustr_t value)) = 0; }; + // --- VariableResolverBase --- + class VariableResolverBase + { + public: + virtual bool checkVariable(ustr_t name) = 0; + }; + // --- ModuleLoaderBase --- struct SectionInfo { diff --git a/elenasrc3/engine/elenaconst.h b/elenasrc3/engine/elenaconst.h index c51f0e0b82..b77cdac23f 100644 --- a/elenasrc3/engine/elenaconst.h +++ b/elenasrc3/engine/elenaconst.h @@ -223,6 +223,8 @@ namespace elena_lang MacOS_ARM64 = 0x00034, + FreeBSD_x86_64 = 0x00042, + TargetMask = 0x00F00, Standalone = 0x00000, VMClient = 0x00100, diff --git a/elenasrc3/engine/langcommon.h b/elenasrc3/engine/langcommon.h index c0e8a6fd43..b873f64ca7 100644 --- a/elenasrc3/engine/langcommon.h +++ b/elenasrc3/engine/langcommon.h @@ -125,6 +125,8 @@ namespace elena_lang Singleton, Constant, ConstantArray, + Procedure, + External }; struct SymbolInfo @@ -455,6 +457,10 @@ namespace elena_lang constexpr auto V_CATEGORY_MASK = 0x7FFFFF00u; constexpr auto V_CATEGORY_MAX = 0x0000F000u; + /// instruction + constexpr auto V_USE = 0x80008001u; + constexpr auto V_IMPORT = 0x80008002u; + /// modificator constexpr auto V_IGNOREDUPLICATE = 0x80007001u; constexpr auto V_SCRIPTSELFMODE = 0x80007002u; @@ -479,7 +485,6 @@ namespace elena_lang constexpr auto V_ABSTRACT = 0x80003002u; constexpr auto V_CLOSED = 0x80003003u; constexpr auto V_PREDEFINED = 0x80003005u; - constexpr auto V_OVERRIDE = 0x80003006u; /// scope_prefix: constexpr auto V_CONST = 0x80002001u; @@ -514,7 +519,6 @@ namespace elena_lang constexpr auto V_EXTERN = 0x80001015u; constexpr auto V_INTERN = 0x80001016u; constexpr auto V_FORWARD = 0x80001017u; - constexpr auto V_IMPORT = 0x80001018u; constexpr auto V_MIXIN = 0x80001019u; constexpr auto V_DISTRIBUTED_FORWARD = 0x8000101Au; constexpr auto V_AUTO = 0x8000101Cu; @@ -582,12 +586,14 @@ namespace elena_lang constexpr auto V_NILLABLE = 0x80000023u; constexpr auto V_FLOAT64ARRAY = 0x80000024u; constexpr auto V_GETTER = 0x80000025u; + constexpr auto V_UINT8ARRAY = 0x80000026u; /// built-in variables constexpr auto V_SELF_VAR = 0x80000081u; constexpr auto V_DECL_VAR = 0x80000082u; constexpr auto V_SUPER_VAR = 0x80000083u; constexpr auto V_RECEIVED_VAR = 0x80000084u; + constexpr auto V_PROJECT_VAR = 0x80000085u; // === Operators === constexpr auto OPERATOR_MAKS = 0x1840; @@ -735,6 +741,8 @@ namespace elena_lang constexpr auto MACOS_ARM64_KEY = "MacOS_ARM64"; + constexpr auto FREEBSD_X86_64_KEY = "FreeBSD_AMD64"; + constexpr auto LIBRARY_KEY = "Library"; constexpr auto CONSOLE_KEY = "STA Console"; constexpr auto GUI_KEY = "STA GUI"; @@ -755,6 +763,7 @@ namespace elena_lang constexpr auto PRIMITIVE_CATEGORY = "primitives/*"; constexpr auto LEXICAL_CATEGORY = "lexicals/*"; constexpr auto FORWARD_CATEGORY = "forwards/*"; + constexpr auto VARIABLE_CATEGORY = "variables/*"; constexpr auto EXTERNAL_CATEGORY = "externals/*"; constexpr auto WINAPI_CATEGORY = "winapi/*"; constexpr auto REFERENCE_CATEGORY = "references/*"; @@ -806,6 +815,8 @@ namespace elena_lang return LINUX_ARM64_KEY; case PlatformType::MacOS_ARM64: return MACOS_ARM64_KEY; + case PlatformType::FreeBSD_x86_64: + return FREEBSD_X86_64_KEY; default: return nullptr; } diff --git a/elenasrc3/engine/linux/lnxroutines.cpp b/elenasrc3/engine/linux/lnxroutines.cpp index df8afbc6c5..7fc9e9b341 100644 --- a/elenasrc3/engine/linux/lnxroutines.cpp +++ b/elenasrc3/engine/linux/lnxroutines.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: Linux ELENA System Routines // -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -50,20 +50,50 @@ uintptr_t SystemRoutineProvider :: NewHeap(size_t totalSize, size_t committedSiz uintptr_t SystemRoutineProvider :: ExpandHeap(void* allocPtr, size_t newSize) { +#if defined(__FreeBSD__) + + void* r = mmap(allocPtr, newSize, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + +#else + void* r = mremap(allocPtr, newSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); +#endif + + //assert(r == allocPtr); + return !r ? 0 : (uintptr_t)r; } uintptr_t SystemRoutineProvider :: ExpandPerm(void* allocPtr, size_t newSize) { +#if defined(__FreeBSD__) + + void* r = mmap(allocPtr, newSize, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + +#else + void* r = mremap(allocPtr, newSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); +#endif + + //assert(r == allocPtr); + return !r ? 0 : (uintptr_t)allocPtr; } +void* SystemRoutineProvider::CreateThread(size_t tt_index, int stackSize, int flags, void* threadProc) +{ +} + +void SystemRoutineProvider::ExitThread(int exitCode) +{ +} + void SystemRoutineProvider :: RaiseError(int code) { ::raise(code); @@ -80,6 +110,28 @@ static void ELENASignalHandler(int sig, siginfo_t* si, void* unused) { ucontext_t* u = (ucontext_t*)unused; +#if defined(__FreeBSD__) + + switch (sig) { + case SIGFPE: + u->uc_mcontext.mc_edx = u->uc_mcontext.mc_eip; + u->uc_mcontext.mc_eax = ELENA_ERR_DIVIDE_BY_ZERO; + u->uc_mcontext.mc_eip = CriticalHandler; + break; + case SIGSEGV: + u->uc_mcontext.mc_edx = u->uc_mcontext.mc_eip; + u->uc_mcontext.mc_eax = ELENA_ERR_ACCESS_VIOLATION; + u->uc_mcontext.mc_eip = CriticalHandler; + break; + default: + u->uc_mcontext.mc_edx = u->uc_mcontext.mc_eip; + u->uc_mcontext.mc_eax = ELENA_ERR_CRITICAL; + u->uc_mcontext.mc_eip = CriticalHandler; + break; + } + +#else + switch (sig) { case SIGFPE: u->uc_mcontext.gregs[REG_EDX] = u->uc_mcontext.gregs[REG_EIP]; @@ -98,6 +150,7 @@ static void ELENASignalHandler(int sig, siginfo_t* si, void* unused) break; } +#endif } #elif __x86_64__ @@ -106,23 +159,47 @@ static void ELENASignalHandler(int sig, siginfo_t* si, void* unused) { ucontext_t* u = (ucontext_t*)unused; +#if defined(__FreeBSD__) + switch (sig) { - case SIGFPE: - u->uc_mcontext.gregs[REG_RDX] = u->uc_mcontext.gregs[REG_RIP]; - u->uc_mcontext.gregs[REG_RAX] = ELENA_ERR_DIVIDE_BY_ZERO; - u->uc_mcontext.gregs[REG_RIP] = CriticalHandler; - break; - case SIGSEGV: - u->uc_mcontext.gregs[REG_RDX] = u->uc_mcontext.gregs[REG_RIP]; - u->uc_mcontext.gregs[REG_RAX] = ELENA_ERR_ACCESS_VIOLATION; - u->uc_mcontext.gregs[REG_RIP] = CriticalHandler; - break; - default: - u->uc_mcontext.gregs[REG_RDX] = u->uc_mcontext.gregs[REG_RIP]; - u->uc_mcontext.gregs[REG_RAX] = ELENA_ERR_CRITICAL; - u->uc_mcontext.gregs[REG_RIP] = CriticalHandler; - break; + case SIGFPE: + u->uc_mcontext.mc_rdx = u->uc_mcontext.mc_rip; + u->uc_mcontext.mc_rax = ELENA_ERR_DIVIDE_BY_ZERO; + u->uc_mcontext.mc_rip = CriticalHandler; + break; + case SIGSEGV: + u->uc_mcontext.mc_rdx = u->uc_mcontext.mc_rip; + u->uc_mcontext.mc_rax = ELENA_ERR_ACCESS_VIOLATION; + u->uc_mcontext.mc_rip = CriticalHandler; + break; + default: + u->uc_mcontext.mc_rdx = u->uc_mcontext.mc_rip; + u->uc_mcontext.mc_rax = ELENA_ERR_CRITICAL; + u->uc_mcontext.mc_rip = CriticalHandler; + break; } + +#else + + switch (sig) { + case SIGFPE: + u->uc_mcontext.gregs[REG_RDX] = u->uc_mcontext.gregs[REG_RIP]; + u->uc_mcontext.gregs[REG_RAX] = ELENA_ERR_DIVIDE_BY_ZERO; + u->uc_mcontext.gregs[REG_RIP] = CriticalHandler; + break; + case SIGSEGV: + u->uc_mcontext.gregs[REG_RDX] = u->uc_mcontext.gregs[REG_RIP]; + u->uc_mcontext.gregs[REG_RAX] = ELENA_ERR_ACCESS_VIOLATION; + u->uc_mcontext.gregs[REG_RIP] = CriticalHandler; + break; + default: + u->uc_mcontext.gregs[REG_RDX] = u->uc_mcontext.gregs[REG_RIP]; + u->uc_mcontext.gregs[REG_RAX] = ELENA_ERR_CRITICAL; + u->uc_mcontext.gregs[REG_RIP] = CriticalHandler; + break; + } + +#endif } #elif __aarch64__ @@ -198,3 +275,27 @@ long long SystemRoutineProvider :: GenerateSeed() return seed; } + +void SystemRoutineProvider::InitMTASignals(SystemEnv* env, size_t index) +{ +} + +void SystemRoutineProvider::ClearMTASignals(SystemEnv* env, size_t index) +{ +} + +void SystemRoutineProvider::GCSignalStop(void* handle) +{ +} + +void SystemRoutineProvider::GCWaitForSignals(size_t count, void* handles) +{ +} + +void SystemRoutineProvider::GCWaitForSignal(void* handle) +{ +} + +void SystemRoutineProvider::GCSignalClear(void* handle) +{ +} diff --git a/elenasrc3/engine/projectbase.h b/elenasrc3/engine/projectbase.h index f79d0df643..8bf82ecf07 100644 --- a/elenasrc3/engine/projectbase.h +++ b/elenasrc3/engine/projectbase.h @@ -193,7 +193,7 @@ namespace elena_lang typedef Map LexicalMap; - class ProjectBase : public ForwardResolverBase + class ProjectBase : public ForwardResolverBase, public VariableResolverBase { public: virtual ModuleIteratorBase* allocModuleIterator() = 0; diff --git a/elenasrc3/engine/syntaxtree.h b/elenasrc3/engine/syntaxtree.h index a153bca827..154af9417e 100644 --- a/elenasrc3/engine/syntaxtree.h +++ b/elenasrc3/engine/syntaxtree.h @@ -66,7 +66,11 @@ namespace elena_lang MetaDictionary = 0x001020, MetaExpression = 0x001021, IncludeStatement = 0x001022, + ImportStatement = 0x001023, + CondStatement = 0x001024, SharedMetaDictionary = 0x001025, + EndCondStatement = 0x001026, + ElseCondStatement = 0x001027, Object = 0x001031, TemplateType = 0x001032, ArrayType = 0x001033, @@ -212,11 +216,13 @@ namespace elena_lang HasStaticConstructor = 0x000116, AsyncInvoker = 0x000117, SourceRef = 0x000118, + Shortcut = 0x000119, Column = 0x000201, Row = 0x000202, ExternalTree = 0x000301, + ExternalFunction = 0x000302, Idle = 0x000F01, }; @@ -283,6 +289,18 @@ namespace elena_lang else writer.newNode(node.key, node.arg.reference); } + static void injectNode(SyntaxTreeWriter& writer, SyntaxNode node) + { + if (node.arg.strArgPosition != INVALID_POS) { + writer.inject(node.key, node.identifier()); + } + else writer.inject(node.key, node.arg.reference); + + copyNode(writer, node); + + writer.closeNode(); + } + static void copyNode(SyntaxTreeWriter& writer, SyntaxNode node, bool includingNode = false); static void copyNodeSafe(SyntaxTreeWriter& writer, SyntaxNode node, bool includingNode = false); static void saveNode(SyntaxNode node, MemoryBase* section, bool includingNode = false); diff --git a/elenasrc3/engine/windows/winroutines.cpp b/elenasrc3/engine/windows/winroutines.cpp index e9f9e22475..bf9c014f68 100644 --- a/elenasrc3/engine/windows/winroutines.cpp +++ b/elenasrc3/engine/windows/winroutines.cpp @@ -51,6 +51,8 @@ uintptr_t SystemRoutineProvider :: ExpandHeap(void* allocPtr, size_t newSize) // allocate LPVOID r = VirtualAlloc(allocPtr, newSize, MEM_COMMIT, PAGE_READWRITE); + assert(r == allocPtr); + return !r ? 0 : (uintptr_t)allocPtr; } @@ -59,6 +61,8 @@ uintptr_t SystemRoutineProvider :: ExpandPerm(void* allocPtr, size_t newSize) // allocate LPVOID r = VirtualAlloc(allocPtr, newSize, MEM_COMMIT, PAGE_READWRITE); + assert(r == allocPtr); + return !r ? 0 : (uintptr_t)allocPtr; } diff --git a/elenasrc3/engine/xmlprojectbase.cpp b/elenasrc3/engine/xmlprojectbase.cpp index 7cf0a28b7b..12f84978cf 100644 --- a/elenasrc3/engine/xmlprojectbase.cpp +++ b/elenasrc3/engine/xmlprojectbase.cpp @@ -75,7 +75,7 @@ unsigned int XmlProjectBase :: UIntSetting(ProjectOption option, unsigned int de } XmlProjectBase :: XmlProjectBase(PlatformType platform) - : _paths(nullptr), _forwards(nullptr), _lexicals(nullptr) + : _paths(nullptr), _forwards(nullptr), _variables(false), _lexicals(nullptr) { _platform = platform; @@ -227,6 +227,24 @@ void XmlProjectBase :: loadForwards(ConfigFile& config, ConfigFile::Node& root, } } +void XmlProjectBase :: loadVariables(ConfigFile& config, ConfigFile::Node& root, ustr_t xpath) +{ + DynamicString key, value; + + ConfigFile::Collection collection; + if (config.select(root, xpath, collection)) { + for (auto it = collection.start(); !it.eof(); ++it) { + ConfigFile::Node node = *it; + + if (node.readAttribute("key", key)) { + node.readContent(value); + + addVariable(key.str(), ustr_t(value.str()).compare("-1")); + } + } + } +} + void XmlProjectBase :: loadLexicals(ConfigFile& config, ConfigFile::Node& root, ustr_t xpath) { DynamicString key, value; @@ -273,3 +291,14 @@ void XmlProjectBase :: addForward(ustr_t forward, ustr_t referenceName) _forwards.add(forward, referenceName.clone()); } + +void XmlProjectBase :: addVariable(ustr_t name, bool value) +{ + _variables.erase(name); + _variables.add(name, value); +} + +bool XmlProjectBase :: checkVariable(ustr_t name) +{ + return _variables.get(name); +} \ No newline at end of file diff --git a/elenasrc3/engine/xmlprojectbase.h b/elenasrc3/engine/xmlprojectbase.h index 8d27edff12..fea769f6e7 100644 --- a/elenasrc3/engine/xmlprojectbase.h +++ b/elenasrc3/engine/xmlprojectbase.h @@ -188,6 +188,7 @@ namespace elena_lang Paths _paths; Forwards _forwards; + Variables _variables; LexicalMap _lexicals; ProjectTree _projectTree; @@ -209,17 +210,21 @@ namespace elena_lang ProjectOption key); void loadForwards(ConfigFile& config, ConfigFile::Node& root, ustr_t xpath); + void loadVariables(ConfigFile& config, ConfigFile::Node& root, ustr_t xpath); void loadLexicals(ConfigFile& config, ConfigFile::Node& root, ustr_t xpath); ustr_t resolveKey(ProjectOption category, ProjectOption item, ustr_t key); public: void addForward(ustr_t forward, ustr_t referenceName) override; + void addVariable(ustr_t name, bool value); ustr_t resolveForward(ustr_t weakReference) override; ustr_t resolveWinApi(ustr_t forward) override; ustr_t resolveExternal(ustr_t forward) override; + bool checkVariable(ustr_t name) override; + ustr_t StringSetting(ProjectOption option) const override; path_t PathSetting(ProjectOption option) const override; diff --git a/elenasrc3/gui/controller.cpp b/elenasrc3/gui/controller.cpp index e02d9ab90e..20d64d4b79 100644 --- a/elenasrc3/gui/controller.cpp +++ b/elenasrc3/gui/controller.cpp @@ -7,8 +7,39 @@ #include "elena.h" #include "idecommon.h" +#ifdef _MSC_VER + +#include + +#endif + using namespace elena_lang; +constexpr auto OPENING_BRACKETS = _T("({[\""); +constexpr auto CLOSING_BRACKETS = _T(")}]\""); + +bool isPairedBracket(text_c ch) +{ + size_t len = getlength(OPENING_BRACKETS); + for (size_t i = 0; i < len; i++) { + if (OPENING_BRACKETS[i] == ch) + return true; + } + + return false; +} + +text_c getClosingBracket(text_c ch) +{ + size_t len = getlength(OPENING_BRACKETS); + for (size_t i = 0; i < len; i++) { + if (OPENING_BRACKETS[i] == ch) + return CLOSING_BRACKETS[i]; + } + + return 0; +} + // --- TextViewController --- void TextViewController :: newDocument(TextViewModelBase* model, ustr_t name, bool included) @@ -159,7 +190,14 @@ bool TextViewController :: insertNewLine(TextViewModelBase* model) auto docView = model->DocView(); if (!docView->isReadOnly()) { docView->eraseSelection(status); + + auto lastPoint = docView->getCaret(); + text_c currentChar = docView->getCurrentChar(); docView->insertNewLine(status); + if (currentChar == '}') { + docView->setCaret(lastPoint, false, status); + docView->insertNewLine(status); + } notifyTextModelChange(model, status); @@ -177,6 +215,12 @@ bool TextViewController :: insertChar(TextViewModelBase* model, text_c ch) docView->eraseSelection(status); docView->insertChar(status, ch); + if (isPairedBracket(ch)) { + auto caret = docView->getCaret(); + if (caret.x == docView->getCurrentLineLength()) + docView->insertChar(status, getClosingBracket(ch), 1, false); + } + notifyTextModelChange(model, status); return true; @@ -374,10 +418,82 @@ void TextViewController :: notifyOnClipboardOperation(ClipboardBase* clipboard) } +bool findBracket(Text* text, TextBookmark& bookmark, text_c starting, text_c ending, bool forward) +{ + // define the upper / lower border of bracket search + int frameY = 0; + if (forward) + frameY = text->getRowCount(); + + int counter = 0; + while (true) { + text_c ch = text->getChar(bookmark); + if (ch == starting) + counter++; + else if (ch == ending) { + counter--; + if (counter == 0) + return true; + } + + if (forward) { + if (!bookmark.moveOn(1) || (bookmark.row() > frameY)) + break; + } + else { + if (!bookmark.moveOn(-1) || bookmark.row() < frameY) + break; + } + } + return false; +} + + +void TextViewController :: highlightBrackets(TextViewModelBase* model, DocumentChangeStatus& changeStatus) +{ + auto docView = model->DocView(); + + Text* text = docView->getText(); + TextBookmark caret = docView->getCurrentTextBookmark(); + + if (docView->clearHighlights()) + changeStatus.formatterChanged = true; + + text_c current_ch = text->getChar(caret); + if (current_ch == '"') + return; + + size_t pos = text_str(OPENING_BRACKETS).find(current_ch); + if (pos != NOTFOUND_POS) { + docView->addHighlight(caret.position(), STYLE_HIGHLIGHTED_BRACKET); + + if (findBracket(text, caret, OPENING_BRACKETS[pos], CLOSING_BRACKETS[pos], true)) { + docView->addHighlight(caret.position(), STYLE_HIGHLIGHTED_BRACKET); + } + + changeStatus.formatterChanged = true; + } + + pos = text_str(CLOSING_BRACKETS).find(current_ch); + if (pos != NOTFOUND_POS) { + pos_t closeBracketPos = caret.position(); + if (findBracket(text, caret, CLOSING_BRACKETS[pos], OPENING_BRACKETS[pos], false)) { + docView->addHighlight(caret.position(), STYLE_HIGHLIGHTED_BRACKET); + docView->addHighlight(closeBracketPos, STYLE_HIGHLIGHTED_BRACKET); + + changeStatus.formatterChanged = true; + } + } +} + void TextViewController :: notifyTextModelChange(TextViewModelBase* model, DocumentChangeStatus& changeStatus) { model->refresh(changeStatus); + if (changeStatus.caretChanged && model->highlightBrackets) { + highlightBrackets(model, changeStatus); + } + if (!_notifier) return; diff --git a/elenasrc3/gui/controller.h b/elenasrc3/gui/controller.h index c66a24008e..7ba078f74b 100644 --- a/elenasrc3/gui/controller.h +++ b/elenasrc3/gui/controller.h @@ -168,6 +168,8 @@ namespace elena_lang void goToLine(TextViewModelBase* model, int row); + void highlightBrackets(TextViewModelBase* model, DocumentChangeStatus& changeStatus); + TextViewController() { _notifier = nullptr; diff --git a/elenasrc3/gui/document.cpp b/elenasrc3/gui/document.cpp index a413c32771..6b4992c223 100644 --- a/elenasrc3/gui/document.cpp +++ b/elenasrc3/gui/document.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA IDE // DocumentView class body -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "guicommon.h" @@ -25,10 +25,12 @@ constexpr auto UNDO_BUFFER_SIZE = 0x40000; // --- LexicalFormatter --- -LexicalFormatter :: LexicalFormatter(Text* text, TextFormatterBase* formatter, MarkerList* markers) +LexicalFormatter :: LexicalFormatter(Text* text, TextFormatterBase* formatter, MarkerList* markers, + HighlightList* highlights) { _text = text; _markers = markers; + _highlights = highlights; _formatter = formatter; _enabled = false; @@ -118,6 +120,24 @@ bool LexicalFormatter :: checkMarker(ReaderInfo& info) return false; } +bool LexicalFormatter :: checkPrecedingHighlight(pos_t start, pos_t& end) +{ + for (auto it = _highlights->start(); !it.eof(); ++it) { + pos_t current = it.key(); + + if (current < start) { + break; + } + if (current < end) { + end = it.key(); + + return true; + } + } + + return false; +} + pos_t LexicalFormatter :: proceed(pos_t position, ReaderInfo& info) { if (!_enabled) @@ -137,8 +157,18 @@ pos_t LexicalFormatter :: proceed(pos_t position, ReaderInfo& info) pos_t current = 0; while (reader.readPos(curStyle)) { current = reader.getPos(); + if (_highlights->get(position) != INVALID_POS) { + info.style = _highlights->get(position); + count = 1; + break; + } + if (current > position) { info.style = curStyle; + // to allow bracket highlighting foregoing another operator + if (curStyle == STYLE_OPERATOR && checkPrecedingHighlight(position, current)) { + + } count = current - position; break; } @@ -254,10 +284,11 @@ bool DocumentView::LexicalReader :: readNext(TextWriter& writer, pos_t l int DocumentView::VerticalScrollOffset = 1; -DocumentView :: DocumentView(Text* text, TextFormatterBase* formatter) : +DocumentView :: DocumentView(Text* text, TextFormatterBase* formatter, bool autoIndent) : _undoBuffer(UNDO_BUFFER_SIZE), - _formatter(text, formatter, &_markers), - _markers({}) + _markers({}), _highlights(INVALID_POS), + _formatter(text, formatter, &_markers, &_highlights), + _autoIndent(autoIndent) { _text = text; @@ -801,8 +832,11 @@ void DocumentView :: tabbing(DocumentChangeStatus& changeStatus, text_c space, s changeStatus.selelectionChanged = true; } -void DocumentView :: insertChar(DocumentChangeStatus& changeStatus, text_c ch, size_t count) +void DocumentView :: insertChar(DocumentChangeStatus& changeStatus, text_c ch, size_t count, bool advancing) { + if (count == 0) + return; + if (hasSelection()) { int rowCount = _text->getRowCount(); @@ -821,8 +855,11 @@ void DocumentView :: insertChar(DocumentChangeStatus& changeStatus, text_c ch, s changeStatus.textChanged = true; _text->validateBookmark(_caret); - _caret.moveOn(1); - setCaret(_caret.getCaret(), false, changeStatus); + if (advancing) { + _caret.moveOn(1); + + setCaret(_caret.getCaret(), false, changeStatus); + } } else break; @@ -830,14 +867,88 @@ void DocumentView :: insertChar(DocumentChangeStatus& changeStatus, text_c ch, s } } +text_t DocumentView :: getCurrentLine(disp_t disp, size_t& length) +{ + TextBookmark bm = _caret; + bm.moveTo(0, _caret.row()); + if (disp == 0 || bm.moveOn(disp)) { + return _text->getLine(bm, length); + } + else { + length = 0; + + return nullptr; + } +} + +text_c DocumentView :: getCurrentChar() +{ + size_t length = 0; + text_t line = NULL; + + TextBookmark bm = _caret; + // return current or previous if EOL + if (!bm.isEOL()) { + line = _text->getLine(bm, length); + } + else { + if (bm.moveOn(-1)) + line = _text->getLine(bm, length); + } + + return (length > 0) ? line[0] : 0; +} + +DocumentView::IndentDirection DocumentView :: IsAutoIndent(text_c ch) +{ + if (ch == '{') + return IndentDirection::Right; + else if (ch == '}') { + return IndentDirection::Left; + } + else return IndentDirection::None; +} + +disp_t DocumentView :: calcAutoIndent(text_c currentChar) +{ + if (!_autoIndent) + return 0; + + size_t length = 0; + disp_t disp = 0; + text_t line = getCurrentLine(0, length); + while (length > 0) { + IndentDirection dir = IsAutoIndent(currentChar); + for (size_t i = 0; i < length; i++) { + if (line[i] != 0x20 && line[i] != 0x9) { + disp += i; + + if (dir == IndentDirection::Right) + disp += Text::TabSize; + + return disp; + } + } + disp += length; + + line = getCurrentLine(disp, length); + } + + return 0; +} + void DocumentView :: insertNewLine(DocumentChangeStatus& changeStatus) { + text_c currentChar = getCurrentChar(); + int rowCount = _text->getRowCount(); eraseSelection(changeStatus); + disp_t disp = calcAutoIndent(currentChar); if (_text->insertNewLine(_caret)) { setCaret(0, _caret.row() + 1, false, changeStatus); + insertChar(changeStatus, ' ', disp); changeStatus.textChanged = true; } diff --git a/elenasrc3/gui/document.h b/elenasrc3/gui/document.h index 476497a77e..4732cdc509 100644 --- a/elenasrc3/gui/document.h +++ b/elenasrc3/gui/document.h @@ -50,6 +50,7 @@ namespace elena_lang } }; typedef CachedMemoryMap MarkerList; + typedef CachedMemoryMap HighlightList; // --- TextFormatterBase --- class TextFormatterBase @@ -67,6 +68,7 @@ namespace elena_lang Text* _text; MarkerList* _markers; + HighlightList* _highlights; MemoryDump _indexes; MemoryDump _lexical; @@ -82,6 +84,7 @@ namespace elena_lang } bool checkMarker(ReaderInfo& info); + bool checkPrecedingHighlight(pos_t start, pos_t& end); void format(); public: @@ -93,7 +96,7 @@ namespace elena_lang pos_t proceed(pos_t position, ReaderInfo& info); - LexicalFormatter(Text* text, TextFormatterBase* formatter, MarkerList* markers); + LexicalFormatter(Text* text, TextFormatterBase* formatter, MarkerList* markers, HighlightList* highlights); virtual ~LexicalFormatter(); }; @@ -112,7 +115,7 @@ namespace elena_lang bool isViewChanged() { - bool flag = formatterChanged | frameChanged | textChanged | selelectionChanged; + bool flag = formatterChanged || frameChanged || textChanged || selelectionChanged; return flag; } @@ -219,6 +222,13 @@ namespace elena_lang } }; + enum class IndentDirection + { + None = 0, + Left, + Right + }; + friend struct LexicalReader; protected: @@ -227,6 +237,7 @@ namespace elena_lang Text* _text; TextHistory _undoBuffer; LexicalFormatter _formatter; + HighlightList _highlights; Point _size; TextBookmark _frame; @@ -235,6 +246,8 @@ namespace elena_lang int _maxColumn; + bool _autoIndent; + MarkerList _markers; pos_t format(LexicalReader& reader); @@ -247,6 +260,11 @@ namespace elena_lang void setCaret(int column, int row, bool selecting, DocumentChangeStatus& changeStatus); + text_t getCurrentLine(disp_t disp, size_t& length); + + IndentDirection IsAutoIndent(text_c ch); + disp_t calcAutoIndent(text_c currentChar); + public: void addMarker(int row, pos_t style, bool instanteMode, bool togleMark, DocumentChangeStatus& changeStatus) { @@ -279,6 +297,25 @@ namespace elena_lang return false; } + bool clearHighlights() + { + if (_highlights.count() > 0) { + _highlights.clear(); + + return true; + } + return false; + } + + void addHighlight(pos_t position, pos_t style) + { + _highlights.add(position, style); + } + + Text* getText() { return _text; } + + TextBookmark getCurrentTextBookmark() { return _caret; } + Point getFrame() const { return _frame.getCaret(); } Point getCaret(bool virtualOne = true) const { return _caret.getCaret(virtualOne); } void setCaret(Point caret, bool selecting, DocumentChangeStatus& changeStatus) @@ -325,6 +362,8 @@ namespace elena_lang status.included = false; } + text_c getCurrentChar(); + Point getSize() const { return _size; } virtual void setSize(Point size); @@ -366,7 +405,7 @@ namespace elena_lang { insertChar(changeStatus, ch, 1); } - void insertChar(DocumentChangeStatus& changeStatus, text_c ch, size_t number); + void insertChar(DocumentChangeStatus& changeStatus, text_c ch, size_t number, bool advancing = true); void insertNewLine(DocumentChangeStatus& changeStatus); void insertLine(DocumentChangeStatus& changeStatus, const_text_t text, size_t length); @@ -392,9 +431,9 @@ namespace elena_lang void refresh(DocumentChangeStatus& changeStatus); - bool findLine(DocumentChangeStatus& changeStatus, const_text_t text, bool matchCase, bool wholeWord); + bool findLine(DocumentChangeStatus& changeStatus, const_text_t text, bool matchCase, bool wholeWord); - DocumentView(Text* text, TextFormatterBase* formatter); + DocumentView(Text* text, TextFormatterBase* formatter, bool autoIndent); virtual ~DocumentView(); }; } diff --git a/elenasrc3/gui/guieditor.h b/elenasrc3/gui/guieditor.h index 194bac167d..d6932965c5 100644 --- a/elenasrc3/gui/guieditor.h +++ b/elenasrc3/gui/guieditor.h @@ -13,24 +13,24 @@ namespace elena_lang { // --- ELENA IDE Styles --- - constexpr auto SCHEME_COUNT = 2; - - constexpr auto STYLE_DEFAULT = 0; - constexpr auto STYLE_MARGIN = 1; - constexpr auto STYLE_SELECTION = 2; - constexpr auto STYLE_TRACE_LINE = 3; - constexpr auto STYLE_ERROR_LINE = 4; - constexpr auto STYLE_BREAKPOINT = 5; - constexpr auto STYLE_KEYWORD = 6; - constexpr auto STYLE_OPERATOR = 7; - constexpr auto STYLE_COMMENT = 8; - constexpr auto STYLE_NUMBER = 9; - constexpr auto STYLE_STRING = 10; + constexpr auto SCHEME_COUNT = 2; + + constexpr auto STYLE_DEFAULT = 0; + constexpr auto STYLE_MARGIN = 1; + constexpr auto STYLE_SELECTION = 2; + constexpr auto STYLE_TRACE_LINE = 3; + constexpr auto STYLE_ERROR_LINE = 4; + constexpr auto STYLE_BREAKPOINT = 5; + constexpr auto STYLE_KEYWORD = 6; + constexpr auto STYLE_OPERATOR = 7; + constexpr auto STYLE_COMMENT = 8; + constexpr auto STYLE_NUMBER = 9; + constexpr auto STYLE_STRING = 10; + constexpr auto STYLE_HIGHLIGHTED_BRACKET = 11; //#define STYLE_MESSAGE 6 //#define STYLE_HINT 9 // !! not used //#define STYLE_TRACE 12 - //#define STYLE_HIGHLIGHTED_BRACKET 14 - constexpr auto STYLE_MAX = 10; + constexpr auto STYLE_MAX = 11; // --- ClipboardBase ---- class ClipboardBase @@ -109,6 +109,7 @@ namespace elena_lang bool lineNumbersVisible; bool highlightSyntax; + bool highlightBrackets; bool empty; FontInfo fontInfo; int schemeIndex; @@ -165,6 +166,7 @@ namespace elena_lang this->empty = true; this->schemeIndex = 0; this->highlightSyntax = true; + this->highlightBrackets = true; this->scrollOffset = 1; } }; diff --git a/elenasrc3/gui/text.cpp b/elenasrc3/gui/text.cpp index b783d56373..5cae19ca60 100644 --- a/elenasrc3/gui/text.cpp +++ b/elenasrc3/gui/text.cpp @@ -683,6 +683,37 @@ text_t Text :: getLine(TextBookmark& bookmark, pos_t& length) } } +text_c Text :: getChar(TextBookmark& bookmark) +{ + validateBookmark(bookmark); + + bookmark.normalize(); + if (bookmark._status == BM_EOT) { + return 0; + } + else return *((*bookmark._page).text + bookmark._offset); +} + +#if defined _M_X64 || __x86_64__ || __PPC64__ || __aarch64__ + +text_t Text::getLine(TextBookmark& bookmark, size_t& length) +{ + validateBookmark(bookmark); + + bookmark.normalize(); + if (bookmark._status == BM_EOT) { + length = 0; + return nullptr; + } + else { + length = (*bookmark._page).used - bookmark._offset; + + return (*bookmark._page).text + bookmark._offset; + } +} + +#endif // + void Text :: create() { _pages.clear(); diff --git a/elenasrc3/gui/text.h b/elenasrc3/gui/text.h index 647778e692..dd39479fcb 100644 --- a/elenasrc3/gui/text.h +++ b/elenasrc3/gui/text.h @@ -309,6 +309,11 @@ namespace elena_lang void copyTo(TextBookmark bookmark, text_c* buffer, disp_t length); text_t getLine(TextBookmark& bookmark, pos_t& length); + text_c getChar(TextBookmark& bookmark); + +#if defined _M_X64 || __x86_64__ || __PPC64__ || __aarch64__ + text_t getLine(TextBookmark& bookmark, size_t& length); +#endif void create(); bool load(path_t path, FileEncoding encoding, bool autoDetecting); diff --git a/elenasrc3/gui/view.cpp b/elenasrc3/gui/view.cpp index 2a103e8188..ab1767f27a 100644 --- a/elenasrc3/gui/view.cpp +++ b/elenasrc3/gui/view.cpp @@ -133,7 +133,7 @@ void TextViewModel :: addDocumentView(ustr_t name, Text* text, path_t path, bool { empty = false; - auto docView = new DocumentView(text, SourceFormatter::getInstance()); + auto docView = new DocumentView(text, SourceFormatter::getInstance(), true); docView->setSize(_size); if (included) docView->markAsInclued(); diff --git a/elenasrc3/ide/debugcontroller.cpp b/elenasrc3/ide/debugcontroller.cpp index fb085c95fa..514ac7cad8 100644 --- a/elenasrc3/ide/debugcontroller.cpp +++ b/elenasrc3/ide/debugcontroller.cpp @@ -44,17 +44,22 @@ inline bool isEqualOrSubSetNs(ustr_t package, ustr_t value) return package.compare(value) || (value.compare(package, package.length()) && (value[package.length()] == '\'')); } +void DebugInfoProvider :: defineModulePath(ustr_t name, PathString& path, path_t projectPath, path_t outputPath, path_t extension) +{ + path.copy(projectPath); + path.combine(outputPath); + + ReferenceName::nameToPath(path, name); + path.appendExtension(extension); +} + void DebugInfoProvider :: retrievePath(ustr_t name, PathString& path, path_t extension) { ustr_t package = _model->getPackage(); // if it is the project package if (isEqualOrSubSetNs(package, name)) { - path.copy(*_model->projectPath); - path.combine(_model->getOutputPath()); - - ReferenceName::nameToPath(path, name); - path.appendExtension(extension); + defineModulePath(name, path, *_model->projectPath, _model->getOutputPath(), extension); } else { // check external libraries diff --git a/elenasrc3/ide/debugcontroller.h b/elenasrc3/ide/debugcontroller.h index af7a7540da..8d0b5287fd 100644 --- a/elenasrc3/ide/debugcontroller.h +++ b/elenasrc3/ide/debugcontroller.h @@ -57,6 +57,8 @@ namespace elena_lang ModuleBase* getDebugModule(addr_t address); public: + static void defineModulePath(ustr_t name, PathString& path, path_t projectPath, path_t outputPath, path_t extension); + addr_t getEntryPoint() { return _entryPoint; diff --git a/elenasrc3/ide/idecommon.h b/elenasrc3/ide/idecommon.h index f073d45cc8..f59eaccf5d 100644 --- a/elenasrc3/ide/idecommon.h +++ b/elenasrc3/ide/idecommon.h @@ -39,6 +39,8 @@ namespace elena_lang constexpr auto LINUX_PPC64le_KEY = "Linux_PPC64le"; constexpr auto LINUX_ARM64_KEY = "Linux_ARM64"; + constexpr auto FREEBSD_X86_64_KEY = "FreeBSD_AMD64"; + constexpr auto ERROR_RUN_NEED_TARGET = 0x0001; constexpr auto ERROR_DEBUG_FILE_NOT_FOUND_COMPILE = 0x0002; constexpr auto ERROR_RUN_NEED_RECOMPILE = 0x0003; diff --git a/elenasrc3/ide/idecontroller.cpp b/elenasrc3/ide/idecontroller.cpp index 4a2f838396..7a3dec813a 100644 --- a/elenasrc3/ide/idecontroller.cpp +++ b/elenasrc3/ide/idecontroller.cpp @@ -33,6 +33,8 @@ inline ustr_t getPlatformName(PlatformType type) return LINUX_X86_KEY; case PlatformType::Linux_x86_64: return LINUX_X86_64_KEY; + case PlatformType::FreeBSD_x86_64: + return FREEBSD_X86_64_KEY; case PlatformType::Linux_PPC64le: return LINUX_PPC64le_KEY; case PlatformType::Linux_ARM64: @@ -335,9 +337,8 @@ bool ProjectController :: isOutaged(ProjectModel& projectModel, SourceViewModel& size_t projectPathLen = projectModel.projectPath.length(); NamespaceString name; - PathString rootPath(*projectModel.projectPath, projectModel.getOutputPath()); for (auto it = projectModel.sources.start(); !it.eof(); ++it) { - PathString source(*rootPath, *it); + PathString source(*projectModel.projectPath, *it); PathString module; module.copySubPath(*source, true); @@ -347,17 +348,16 @@ bool ProjectController :: isOutaged(ProjectModel& projectModel, SourceViewModel& _debugController.resolveNamespace(name); - ReferenceName::nameToPath(module, *name); - module.append(_T(".nl")); + DebugInfoProvider::defineModulePath(*name, module, *projectModel.projectPath, projectModel.getOutputPath(), _T("nl")); - if (name.length() != 0) { + if (module.length() != 0) { if (_compareFileModifiedTime(*source, *module)) - return false; + return true; } - else return false; + else return true; } - return true; + return false; } bool ProjectController :: onDebugAction(ProjectModel& model, SourceViewModel& sourceModel, DebugAction action, @@ -365,7 +365,7 @@ bool ProjectController :: onDebugAction(ProjectModel& model, SourceViewModel& so { if (!_debugController.isStarted()) { bool toRecompile = model.autoRecompile && !withoutPostponeAction; - if (!isOutaged(model, sourceModel)) { + if (isOutaged(model, sourceModel)) { if (toRecompile) { if (!doCompileProject(model, action)) return false; @@ -1059,6 +1059,7 @@ bool IDEController :: loadConfig(IDEModel* model, path_t path, GUISettinngs& gui model->rememberLastPath = loadSetting(config, LASTPATH_SETTINGS, -1) != 0; model->rememberLastProject = loadSetting(config, LASTPROJECT_SETTINGS, -1) != 0; model->sourceViewModel.highlightSyntax = loadSetting(config, HIGHLIGHTSYNTAX_SETTINGS, -1) != 0; + model->sourceViewModel.highlightBrackets = loadSetting(config, HIGHLIGHTBRACKETS_SETTINGS, -1) != 0; model->sourceViewModel.lineNumbersVisible = loadSetting(config, LINENUMBERS_SETTINGS, -1) != 0; model->sourceViewModel.scrollOffset = loadSetting(config, VSCROLL_SETTINGS, 1); model->sourceViewModel.settings.tabSize = loadSetting(config, TABSIZE_SETTINGS, 3); @@ -1103,6 +1104,7 @@ void IDEController :: saveConfig(IDEModel* model, path_t configPath, GUISettinng saveSetting(config, LASTPATH_SETTINGS, model->rememberLastPath); saveSetting(config, LASTPROJECT_SETTINGS, model->rememberLastProject); saveSetting(config, HIGHLIGHTSYNTAX_SETTINGS, model->sourceViewModel.highlightSyntax); + saveSetting(config, HIGHLIGHTBRACKETS_SETTINGS, model->sourceViewModel.highlightBrackets); saveSetting(config, LINENUMBERS_SETTINGS, model->sourceViewModel.lineNumbersVisible); saveSetting(config, VSCROLL_SETTINGS, model->sourceViewModel.scrollOffset); saveSetting(config, TABSIZE_SETTINGS, model->sourceViewModel.settings.tabSize); @@ -2001,9 +2003,12 @@ void IDEController :: doConfigureEditorSettings(EditorSettingsBase& editorDialog { int prevSchemeIndex = model->viewModel()->schemeIndex; bool prevHighlightSyntax = model->viewModel()->highlightSyntax; + bool prevHighlightBrackets = model->viewModel()->highlightBrackets; if(editorDialog.showModal()) { - if (prevSchemeIndex != model->viewModel()->schemeIndex || prevHighlightSyntax != model->viewModel()->highlightSyntax) { + if (prevSchemeIndex != model->viewModel()->schemeIndex || prevHighlightSyntax != model->viewModel()->highlightSyntax + || prevHighlightBrackets != model->viewModel()->highlightBrackets) + { notifyOnModelChange(STATUS_FRAME_CHANGED | STATUS_COLORSCHEME_CHANGED); } } diff --git a/elenasrc3/ide/ideproject.h b/elenasrc3/ide/ideproject.h index 9d84332621..ccce056bb8 100644 --- a/elenasrc3/ide/ideproject.h +++ b/elenasrc3/ide/ideproject.h @@ -31,6 +31,7 @@ namespace elena_lang constexpr auto FONTNAME_SETTINGS = "configuration/settings/font_name"; constexpr auto SCHEME_SETTINGS = "configuration/settings/scheme"; constexpr auto HIGHLIGHTSYNTAX_SETTINGS = "configuration/settings/highlight"; + constexpr auto HIGHLIGHTBRACKETS_SETTINGS = "configuration/settings/highlight_brackets"; constexpr auto PERSISTENT_CONSOLE_SETTINGS = "configuration/settings/persist_output"; constexpr auto VSCROLL_SETTINGS = "configuration/settings/vscroll"; constexpr auto TABSIZE_SETTINGS = "configuration/settings/tabsize"; diff --git a/elenasrc3/ide/ideversion.h b/elenasrc3/ide/ideversion.h index 9f785e85bc..7b9d4995c0 100644 --- a/elenasrc3/ide/ideversion.h +++ b/elenasrc3/ide/ideversion.h @@ -1,2 +1,2 @@ -#define IDE_REVISION_NUMBER 37 +#define IDE_REVISION_NUMBER 41 diff --git a/elenasrc3/ide/windows/Resource.h b/elenasrc3/ide/windows/Resource.h index 8169753621..726a4b70ee 100644 --- a/elenasrc3/ide/windows/Resource.h +++ b/elenasrc3/ide/windows/Resource.h @@ -205,6 +205,7 @@ #define IDC_IDE_AUTOSAVE 1717 #define IDC_IDE_INCLUDE_APPPATH 1718 #define IDC_EDITOR_SCROLLOFFSET 1719 +#define IDC_EDITOR_HIGHLIGHBRACKETFLAG 1720 #define IDM_EDITOR_OPTIONS 1750 #define IDM_IDE_OPTIONS 1751 diff --git a/elenasrc3/ide/windows/elide.rc b/elenasrc3/ide/windows/elide.rc index 98a4b752b1de8e40886eca2576101acb5d48d4df..62eb3e89182c5f2152a398546cba255844392fd7 100644 GIT binary patch delta 82 zcmV-Y0ImOq=>qKP0vyc0CE6f0Am1a0A&DllYNLClZ1&74MG4? o06_pl080Qx092EoiB}0Y05$+D05bqEld*LZlOTxBCcleRnY?ZS-)6IJGc5qU84Sz- diff --git a/elenasrc3/ide/windows/factory.cpp b/elenasrc3/ide/windows/factory.cpp index 86addad4b2..37780e2f49 100644 --- a/elenasrc3/ide/windows/factory.cpp +++ b/elenasrc3/ide/windows/factory.cpp @@ -79,6 +79,7 @@ StyleInfo defaultStyles[STYLE_MAX + 1] = { {Color(0, 0x80, 0), Color(0xFF, 0xFF, 0xFF), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, {Color(0xFF, 0x80, 0x40), Color(0xFF, 0xFF, 0xFF), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, {Color(0, 0x80, 0x80), Color(0xFF, 0xFF, 0xFF), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, + {Color(0), Color(0xFF, 0xFF, 0xFF), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, }; StyleInfo classicStyles[STYLE_MAX + 1] = { @@ -93,6 +94,7 @@ StyleInfo classicStyles[STYLE_MAX + 1] = { {Color(0xC0, 0xC0, 0xC0), Color(0, 0, 0x80), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, {Color(0, 0xFF, 0x80), Color(0, 0, 0x80), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, {Color(0, 0xFF, 0xFF), Color(0, 0, 0x80), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, + {Color(0xFF, 0xFF, 0), Color(0, 0, 0x80), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, }; StyleInfo darkStyles[STYLE_MAX + 1] = { @@ -107,6 +109,7 @@ StyleInfo darkStyles[STYLE_MAX + 1] = { {Color(87, 166, 74), Color(50, 50, 50), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, {Color(181, 230, 168), Color(50, 50, 50), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, {Color(214, 157, 133), Color(50, 50, 50), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, + {Color(0xFF, 0xFF, 0xFF), Color(0x27, 0x2D, 0x60), _T("Courier New"), IDE_CHARSET_ANSI, 10, false, false}, }; constexpr auto STYLE_SCHEME_COUNT = 3; diff --git a/elenasrc3/ide/windows/windialogs.cpp b/elenasrc3/ide/windows/windialogs.cpp index 4c055dd63c..919f69ca76 100644 --- a/elenasrc3/ide/windows/windialogs.cpp +++ b/elenasrc3/ide/windows/windialogs.cpp @@ -479,6 +479,7 @@ void EditorSettings::onCreate() setComboBoxIndex(IDC_EDITOR_COLORSCHEME, _model->schemeIndex); setCheckState(IDC_EDITOR_HIGHLIGHSYNTAXFLAG, _model->highlightSyntax); + setCheckState(IDC_EDITOR_HIGHLIGHBRACKETFLAG, _model->highlightBrackets); setCheckState(IDC_EDITOR_LINENUMBERFLAG, _model->lineNumbersVisible); setIntText(IDC_EDITOR_TABSIZE, _model->settings.tabSize); @@ -495,6 +496,10 @@ void EditorSettings :: onOK() if (_model->highlightSyntax != value) _model->setHighlightMode(value); + value = getCheckState(IDC_EDITOR_HIGHLIGHBRACKETFLAG); + if (_model->highlightBrackets != value) + _model->highlightBrackets = value; + _model->lineNumbersVisible = getCheckState(IDC_EDITOR_LINENUMBERFLAG); int intValue = getIntText(IDC_EDITOR_TABSIZE); diff --git a/elenasrc3/tools/asmc/asmc.cpp b/elenasrc3/tools/asmc/asmc.cpp index 868effd1a9..39149a2c44 100644 --- a/elenasrc3/tools/asmc/asmc.cpp +++ b/elenasrc3/tools/asmc/asmc.cpp @@ -3,7 +3,7 @@ // // Asm2BinX main file // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include @@ -60,6 +60,20 @@ void printLine(ustr_t mssg, path_t path) #endif +#ifdef __FreeBSD__ + +constexpr auto targetPlatform = ASM_FREEBSD_TARGET; + +#elif __unix__ + +constexpr auto targetPlatform = ASM_LNX_TARGET; + +#elif defined(_WIN32) || defined(_WIN64) + +constexpr auto targetPlatform = ASM_WIN_TARGET; + +#endif + enum class CompileMode { x86, @@ -70,7 +84,7 @@ enum class CompileMode bc64 }; -template void compileAssembly(path_t source, path_t target) +template void compileAssembly(path_t source, path_t target, ustr_t platform) { Module targetModule(BINARY_MODULE); @@ -82,6 +96,8 @@ template void compileAssembly(path_t source, path_t target) AssemblyT assembler(4, &reader, &targetModule); + assembler.defineMacro(platform, true); + assembler.compile(); FileWriter writer(target, FileEncoding::Raw, false); @@ -120,17 +136,22 @@ void compileByteCode(path_t source, path_t target, bool mode64, int rawDataAlign int main(int argc, char* argv[]) { printf(ASM_GREETING, ENGINE_MAJOR_VERSION, ENGINE_MINOR_VERSION, ASM_REVISION_NUMBER); - if (argc < 2 || argc > 4) { + if (argc < 2 || argc > 6) { printf(ASM_HELP); return -1; } + IdentifierString platform(targetPlatform); PathString source; PathString target; + PathString targetName; CompileMode mode = CompileMode::x86; bool supportStdMode = false; + int optionIndex = 0; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { + optionIndex = i; + ustr_t arg(argv[i] + 1); if (arg.compare(ASM_X86_MODE)) { mode = CompileMode::x86; @@ -147,6 +168,15 @@ int main(int argc, char* argv[]) else if (arg.compare(ASM_AARCH64_MODE)) { mode = CompileMode::arm64; } + else if (arg.compare(ASM_WIN_TARGET_MODE)) { + platform.copy(ASM_WIN_TARGET); + } + else if (arg.compare(ASM_LNX_TARGET_MODE)) { + platform.copy(ASM_LNX_TARGET); + } + else if (arg.compare(ASM_FREEBSD_TARGET_MODE)) { + platform.copy(ASM_FREEBSD_TARGET); + } else if (arg.compare(BC_32_MODE)) { mode = CompileMode::bc32; #ifdef WIN32 @@ -161,12 +191,15 @@ int main(int argc, char* argv[]) return -1; } } - else if (i == 2) { + else if (i == optionIndex + 1) { source.copy(argv[i]); } - else if (i == 3) { + else if (i == optionIndex + 2) { target.copy(argv[i]); } + else if (i == optionIndex + 3) { + targetName.copy(argv[i]); + } else { printf(ASM_HELP); return -1; @@ -175,6 +208,15 @@ int main(int argc, char* argv[]) if (target.empty()) { target.copy(*source); + + if (!targetName.empty()) { + PathString temp; + temp.copySubPath(*target, true); + target.combine(*targetName); + } + } + else if (!targetName.empty()) { + target.combine(*targetName); } else { FileNameString name(*source, true); @@ -192,7 +234,7 @@ int main(int argc, char* argv[]) target.changeExtension("bin"); - compileAssembly(*source, *target); + compileAssembly(*source, *target, *platform); break; } case CompileMode::amd64: @@ -201,7 +243,7 @@ int main(int argc, char* argv[]) target.changeExtension("bin"); - compileAssembly(*source, *target); + compileAssembly(*source, *target, *platform); break; } case CompileMode::ppc64le: @@ -210,7 +252,7 @@ int main(int argc, char* argv[]) target.changeExtension("bin"); - compileAssembly(*source, *target); + compileAssembly(*source, *target, *platform); break; } @@ -220,7 +262,7 @@ int main(int argc, char* argv[]) target.changeExtension("bin"); - compileAssembly(*source, *target); + compileAssembly(*source, *target, *platform); break; } diff --git a/elenasrc3/tools/asmc/asmconst.h b/elenasrc3/tools/asmc/asmconst.h index 34b5d5b2e4..ac5136d52c 100644 --- a/elenasrc3/tools/asmc/asmconst.h +++ b/elenasrc3/tools/asmc/asmconst.h @@ -12,7 +12,7 @@ namespace elena_lang { - #define ASM_REVISION_NUMBER 0x000D + #define ASM_REVISION_NUMBER 0x0010 constexpr auto N_ARGUMENT1 = "__n_1"; constexpr auto N_ARGUMENT2 = "__n_2"; @@ -55,7 +55,7 @@ namespace elena_lang constexpr auto QWORD_ARGUMENT2 = "__arg64_2"; constexpr auto ASM_GREETING = "ELENA Assembler Compiler %d.%d.%d (C)2011-2025 by Alexei Rakov\n"; - constexpr auto ASM_HELP = "asmc-cli [-amd64 | -x86] \n"; + constexpr auto ASM_HELP = "asmc-cli [-amd64 | -x86] [-windows | -linux] []\n"; constexpr auto ASM_COMPILE_X86 = "X86 Assembler : compiling %s\n"; constexpr auto ASM_COMPILE_X86_64 = "X86-64 Assembler : compiling %s\n"; @@ -65,6 +65,10 @@ namespace elena_lang constexpr auto BC_COMPILE_64 = "64bit Byte-code Compiler : compiling %s\n"; constexpr auto ASM_DONE = "Successfully compiled\n"; + constexpr auto ASM_WIN_TARGET_MODE = "windows"; + constexpr auto ASM_LNX_TARGET_MODE = "linux"; + constexpr auto ASM_FREEBSD_TARGET_MODE = "freebsd"; + constexpr auto ASM_X86_MODE = "x86"; constexpr auto ASM_AMD64_MODE = "amd64"; constexpr auto ASM_PPC64le_MODE = "ppc64le"; @@ -73,6 +77,10 @@ namespace elena_lang constexpr auto BC_32_MODE = "bc32"; constexpr auto BC_64_MODE = "bc64"; + constexpr auto ASM_WIN_TARGET = "_WIN"; + constexpr auto ASM_LNX_TARGET = "_LNX"; + constexpr auto ASM_FREEBSD_TARGET = "_FREEBSD"; + constexpr auto ASM_SYNTAXERROR = "(%d,%d): Syntax error\n"; constexpr auto ASM_INVALID_SOURCE = "(%d,%d): Invalid source operand\n"; constexpr auto ASM_INVALID_TARGET = "(%d,%d): Invalid target operand\n"; diff --git a/elenasrc3/tools/asmc/assembler.cpp b/elenasrc3/tools/asmc/assembler.cpp index 0f830b1248..2ce94f446e 100644 --- a/elenasrc3/tools/asmc/assembler.cpp +++ b/elenasrc3/tools/asmc/assembler.cpp @@ -16,13 +16,13 @@ using namespace elena_lang; // --- AssemblerBase --- AssemblerBase :: AssemblerBase(int tabSize, UStrReader* reader, ModuleBase* target) - : _reader(tabSize, reader), constants(0) + : _reader(tabSize, reader), constants(0), _macros(false) { _target = target; } AssemblerBase :: AssemblerBase(const char** dfa, int tabSize, UStrReader* reader, ModuleBase* target) - : _reader(dfa, tabSize, reader), constants(0) + : _reader(dfa, tabSize, reader), constants(0), _macros(false) { _target = target; } @@ -390,6 +390,22 @@ bool AssemblerBase :: compileOpCode(ScriptToken& tokenInfo, MemoryWriter& writer } } +bool AssemblerBase :: isMacroVariableDefined(ustr_t macro) +{ + return _macros.get(macro); +} + +void AssemblerBase :: skipBlock(ScriptToken& tokenInfo) +{ + int level = 1; + do { + read(tokenInfo); + if (tokenInfo.compare("#endif") || tokenInfo.compare("#elif")) + level--; + + } while (level > 0); +} + void AssemblerBase :: compileProcedure(ScriptToken& tokenInfo, LabelHelper* helper) { PrefixInfo prefixScope; @@ -402,7 +418,19 @@ void AssemblerBase :: compileProcedure(ScriptToken& tokenInfo, LabelHelper* help while (!tokenInfo.compare("end")) { if (!compileOpCode(tokenInfo, writer, labelScope, prefixScope)) { - if (tokenInfo.state != dfaEOF) { + if (tokenInfo.compare("#if") || tokenInfo.compare("#elif")) { + read(tokenInfo); + + if (!isMacroVariableDefined(*tokenInfo.token)) { + skipBlock(tokenInfo); + } + else read(tokenInfo); + } + else if (tokenInfo.compare("#endif")) { + // ignore preprosessor directive + read(tokenInfo); + } + else if (tokenInfo.state != dfaEOF) { declareLabel(tokenInfo, writer, labelScope); } else throw SyntaxError(ASM_SYNTAXERROR, tokenInfo.lineInfo); diff --git a/elenasrc3/tools/asmc/assembler.h b/elenasrc3/tools/asmc/assembler.h index a48f03a523..bf54637849 100644 --- a/elenasrc3/tools/asmc/assembler.h +++ b/elenasrc3/tools/asmc/assembler.h @@ -86,6 +86,7 @@ namespace elena_lang { protected: typedef Map ConstantMap; + typedef Map MacroMap; struct PrefixInfo { @@ -101,6 +102,7 @@ namespace elena_lang ScriptReader _reader; ModuleBase* _target; + MacroMap _macros; ConstantMap constants; void checkComma(ScriptToken& tokenInfo); @@ -156,9 +158,18 @@ namespace elena_lang void compileStructure(ScriptToken& tokenInfo); void declareConstant(ScriptToken& tokenInfo); + bool isMacroVariableDefined(ustr_t macro); + void skipBlock(ScriptToken& tokenInfo); + public: void compile(); + void defineMacro(ustr_t macro, bool value) + { + _macros.erase(macro); + _macros.add(macro, value); + } + AssemblerBase(int tabSize, UStrReader* reader, ModuleBase* target); AssemblerBase(const char** dfa, int tabSize, UStrReader* reader, ModuleBase* target); }; diff --git a/elenasrc3/tools/asmc/codeblocks/asmc_amd64.mak b/elenasrc3/tools/asmc/codeblocks/asmc_amd64.mak index 0b331820c1..8ca479c0cd 100644 --- a/elenasrc3/tools/asmc/codeblocks/asmc_amd64.mak +++ b/elenasrc3/tools/asmc/codeblocks/asmc_amd64.mak @@ -11,12 +11,22 @@ LD = g++ WINDRES = windres INC = -I.. -I../../../engine -I../../../common -CFLAGS = -Wall -std=c++20 -m64 RESINC = LIBDIR = LIB = + +ifeq ($(OS),Windows_NT) + +CFLAGS = -Wall -std=c++20 -m64 -municode +LDFLAGS = -m64 -static-libgcc -static-libstdc++ + +else + +CFLAGS = -Wall -std=c++20 -m64 LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl +endif + INC_RELEASE = $(INC) CFLAGS_RELEASE = $(CFLAGS) -O3 RESINC_RELEASE = $(RESINC) diff --git a/elenasrc3/tools/asmc/codeblocks/bsd.asmc_amd64.mak b/elenasrc3/tools/asmc/codeblocks/bsd.asmc_amd64.mak new file mode 100644 index 0000000000..7d7ffe99c6 --- /dev/null +++ b/elenasrc3/tools/asmc/codeblocks/bsd.asmc_amd64.mak @@ -0,0 +1,101 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = gcc +CXX = g++ +AR = ar +LD = g++ +WINDRES = windres + +INC = -I.. -I../../../engine -I../../../common +RESINC = +LIBDIR = +LIB = +CFLAGS = -Wall -std=c++20 -m64 +LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../../temp/asm64-cli/ +DEP_RELEASE = +OUT_RELEASE = ../../../../bin/asm64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/__/engine/section.o $(OBJDIR_RELEASE)/__/asmc.o $(OBJDIR_RELEASE)/__/assembler.o $(OBJDIR_RELEASE)/__/x86assembler.o $(OBJDIR_RELEASE)/__/ppc64assembler.o $(OBJDIR_RELEASE)/__/armassembler.o $(OBJDIR_RELEASE)/__/bcassembler.o $(OBJDIR_RELEASE)/__/__/__/engine/x86helper.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../../bin || mkdir -p ../../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/__/common + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/__/common/dump.o: ../../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/__/common/files.o: ../../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/__/common/paths.o: ../../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/__/common/ustring.o: ../../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/__/engine/module.o: ../../../engine/module.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/module.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/module.o + +$(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o: ../../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o: ../../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/__/__/engine/section.o: ../../../engine/section.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/section.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/section.o + +$(OBJDIR_RELEASE)/__/asmc.o : ../asmc.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../asmc.cpp -o $(OBJDIR_RELEASE)/__/asmc.o + +$(OBJDIR_RELEASE)/__/assembler.o : ../assembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../assembler.cpp -o $(OBJDIR_RELEASE)/__/assembler.o + +$(OBJDIR_RELEASE)/__/x86assembler.o : ../x86assembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../x86assembler.cpp -o $(OBJDIR_RELEASE)/__/x86assembler.o + +$(OBJDIR_RELEASE)/__/__/__/engine/x86helper.o: ../../../engine/x86helper.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/x86helper.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/x86helper.o + +$(OBJDIR_RELEASE)/__/ppc64assembler.o : ../ppc64assembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../ppc64assembler.cpp -o $(OBJDIR_RELEASE)/__/ppc64assembler.o + +$(OBJDIR_RELEASE)/__/armassembler.o : ../armassembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../armassembler.cpp -o $(OBJDIR_RELEASE)/__/armassembler.o + +$(OBJDIR_RELEASE)/__/bcassembler.o : ../bcassembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../bcassembler.cpp -o $(OBJDIR_RELEASE)/__/bcassembler.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/tools/asmc/codeblocks/bsd.clang_asmc_amd64.mak b/elenasrc3/tools/asmc/codeblocks/bsd.clang_asmc_amd64.mak new file mode 100644 index 0000000000..29e5bfb557 --- /dev/null +++ b/elenasrc3/tools/asmc/codeblocks/bsd.clang_asmc_amd64.mak @@ -0,0 +1,101 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = clang +CXX = clang++ +AR = ar +LD = clang++ +WINDRES = windres + +INC = -I.. -I../../../engine -I../../../common +RESINC = +LIBDIR = +LIB = +CFLAGS = -Wall -std=c++20 -m64 -static-libgcc -static-libstdc++ +LDFLAGS = -m64 -ldl -fuse-ld=lld + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../../temp/asm64-cli/ +DEP_RELEASE = +OUT_RELEASE = ../../../../bin/asm64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/__/engine/section.o $(OBJDIR_RELEASE)/__/asmc.o $(OBJDIR_RELEASE)/__/assembler.o $(OBJDIR_RELEASE)/__/x86assembler.o $(OBJDIR_RELEASE)/__/ppc64assembler.o $(OBJDIR_RELEASE)/__/armassembler.o $(OBJDIR_RELEASE)/__/bcassembler.o $(OBJDIR_RELEASE)/__/__/__/engine/x86helper.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../../bin || mkdir -p ../../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/__/common + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/__/common/dump.o: ../../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/__/common/files.o: ../../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/__/common/paths.o: ../../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/__/common/ustring.o: ../../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/__/engine/module.o: ../../../engine/module.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/module.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/module.o + +$(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o: ../../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o: ../../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/__/__/engine/section.o: ../../../engine/section.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/section.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/section.o + +$(OBJDIR_RELEASE)/__/asmc.o : ../asmc.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../asmc.cpp -o $(OBJDIR_RELEASE)/__/asmc.o + +$(OBJDIR_RELEASE)/__/assembler.o : ../assembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../assembler.cpp -o $(OBJDIR_RELEASE)/__/assembler.o + +$(OBJDIR_RELEASE)/__/x86assembler.o : ../x86assembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../x86assembler.cpp -o $(OBJDIR_RELEASE)/__/x86assembler.o + +$(OBJDIR_RELEASE)/__/__/__/engine/x86helper.o: ../../../engine/x86helper.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/x86helper.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/x86helper.o + +$(OBJDIR_RELEASE)/__/ppc64assembler.o : ../ppc64assembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../ppc64assembler.cpp -o $(OBJDIR_RELEASE)/__/ppc64assembler.o + +$(OBJDIR_RELEASE)/__/armassembler.o : ../armassembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../armassembler.cpp -o $(OBJDIR_RELEASE)/__/armassembler.o + +$(OBJDIR_RELEASE)/__/bcassembler.o : ../bcassembler.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../bcassembler.cpp -o $(OBJDIR_RELEASE)/__/bcassembler.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/tools/asmc/x86assembler.cpp b/elenasrc3/tools/asmc/x86assembler.cpp index 77874b3469..fb1fcc857c 100644 --- a/elenasrc3/tools/asmc/x86assembler.cpp +++ b/elenasrc3/tools/asmc/x86assembler.cpp @@ -2043,6 +2043,13 @@ bool X86Assembler :: compileJmpBack(bool shortJump, int offset, MemoryWriter& wr bool X86Assembler :: compileLea(X86Operand source, X86Operand target, MemoryWriter& writer) { + if (target.prefix == SegmentPrefix::FS) { + writer.writeByte(0x64); + } + else if (target.prefix == SegmentPrefix::GS) { + writer.writeByte(0x65); + } + if (source.isR32() && target.isM32()) { writer.writeByte(0x8D); X86Helper::writeModRM(writer, source, target); @@ -2057,6 +2064,9 @@ bool X86Assembler :: compileMov(X86Operand source, X86Operand target, MemoryWrit if (target.prefix == SegmentPrefix::FS) { writer.writeByte(0x64); } + else if (target.prefix == SegmentPrefix::GS) { + writer.writeByte(0x65); + } if(source.type == X86OperandType::EAX && target.type == X86OperandType::Disp32) { writer.writeByte(0xA1); diff --git a/elenasrc3/tools/ecv/codeblocks/bsd.clang_ecv_amd64.mak b/elenasrc3/tools/ecv/codeblocks/bsd.clang_ecv_amd64.mak new file mode 100644 index 0000000000..69dc9f66ed --- /dev/null +++ b/elenasrc3/tools/ecv/codeblocks/bsd.clang_ecv_amd64.mak @@ -0,0 +1,93 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = clang +CXX = clang++ +AR = ar +LD = clang++ +WINDRES = windres + +INC = -I.. -I../../../engine -I../../../common +RESINC = +LIBDIR = +LIB = +CFLAGS = -Wall -std=c++20 -m64 -static-libgcc -static-libstdc++ +LDFLAGS = -m64 -ldl -fuse-ld=lld + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../../temp/ecv64-cli/ +DEP_RELEASE = +OUT_RELEASE = ../../../../bin/ecv64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/ecviewer.o $(OBJDIR_RELEASE)/__/linux/ecv.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../../bin || mkdir -p ../../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/__/common + test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/__/common/dump.o: ../../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/__/common/files.o: ../../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/__/common/paths.o: ../../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/__/common/xmltree.o: ../../../common/xmltree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/xmltree.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/xmltree.o + +$(OBJDIR_RELEASE)/__/__/__/common/config.o: ../../../common/config.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/config.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/config.o + +$(OBJDIR_RELEASE)/__/__/__/common/ustring.o: ../../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o: ../../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/__/__/engine/module.o: ../../../engine/module.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/module.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/module.o + +$(OBJDIR_RELEASE)/__/__/__/engine/section.o: ../../../engine/section.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/section.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/section.o + +$(OBJDIR_RELEASE)/__/__/__/engine/libman.o: ../../../engine/libman.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/libman.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/libman.o + +$(OBJDIR_RELEASE)/__/ecviewer.o : ../ecviewer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../ecviewer.cpp -o $(OBJDIR_RELEASE)/__/ecviewer.o + +$(OBJDIR_RELEASE)/__/linux/ecv.o : ../linux/ecv.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/ecv.cpp -o $(OBJDIR_RELEASE)/__/linux/ecv.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/__/common + rm -rf $(OBJDIR_RELEASE)/__/linux + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/tools/ecv/codeblocks/bsd.ecv_amd64.mak b/elenasrc3/tools/ecv/codeblocks/bsd.ecv_amd64.mak new file mode 100644 index 0000000000..8a017618ee --- /dev/null +++ b/elenasrc3/tools/ecv/codeblocks/bsd.ecv_amd64.mak @@ -0,0 +1,93 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = gcc +CXX = g++ +AR = ar +LD = g++ +WINDRES = windres + +INC = -I.. -I../../../engine -I../../../common +RESINC = +LIBDIR = +LIB = +CFLAGS = -Wall -std=c++20 -m64 +LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../../temp/ecv64-cli/ +DEP_RELEASE = +OUT_RELEASE = ../../../../bin/ecv64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/ecviewer.o $(OBJDIR_RELEASE)/__/linux/ecv.o + +all: release + +clean: clean_release + +before_release: + test -d ../../../../bin || mkdir -p ../../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/__/common + test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/__/common/dump.o: ../../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/__/common/files.o: ../../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/__/common/paths.o: ../../../common/paths.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/paths.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/paths.o + +$(OBJDIR_RELEASE)/__/__/__/common/xmltree.o: ../../../common/xmltree.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/xmltree.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/xmltree.o + +$(OBJDIR_RELEASE)/__/__/__/common/config.o: ../../../common/config.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/config.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/config.o + +$(OBJDIR_RELEASE)/__/__/__/common/ustring.o: ../../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o: ../../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/__/__/engine/module.o: ../../../engine/module.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/module.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/module.o + +$(OBJDIR_RELEASE)/__/__/__/engine/section.o: ../../../engine/section.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/section.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/section.o + +$(OBJDIR_RELEASE)/__/__/__/engine/libman.o: ../../../engine/libman.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/libman.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/libman.o + +$(OBJDIR_RELEASE)/__/ecviewer.o : ../ecviewer.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../ecviewer.cpp -o $(OBJDIR_RELEASE)/__/ecviewer.o + +$(OBJDIR_RELEASE)/__/linux/ecv.o : ../linux/ecv.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/ecv.cpp -o $(OBJDIR_RELEASE)/__/linux/ecv.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/__/common + rm -rf $(OBJDIR_RELEASE)/__/linux + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/tools/ecv/codeblocks/ecv_amd64.mak b/elenasrc3/tools/ecv/codeblocks/ecv_amd64.mak index 84d753473f..71c59dfeda 100644 --- a/elenasrc3/tools/ecv/codeblocks/ecv_amd64.mak +++ b/elenasrc3/tools/ecv/codeblocks/ecv_amd64.mak @@ -11,12 +11,22 @@ LD = g++ WINDRES = windres INC = -I.. -I../../../engine -I../../../common -CFLAGS = -Wall -std=c++20 -m64 RESINC = LIBDIR = LIB = + +ifeq ($(OS),Windows_NT) + +CFLAGS = -Wall -std=c++20 -m64 -municode +LDFLAGS = -m64 -static-libgcc -static-libstdc++ + +else + +CFLAGS = -Wall -std=c++20 -m64 LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl +endif + INC_RELEASE = $(INC) CFLAGS_RELEASE = $(CFLAGS) -O3 RESINC_RELEASE = $(RESINC) @@ -28,8 +38,16 @@ OBJDIR_RELEASE = ../../../temp/ecv64-cli/ DEP_RELEASE = OUT_RELEASE = ../../../../bin/ecv64-cli +ifeq ($(OS),Windows_NT) + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/ecviewer.o $(OBJDIR_RELEASE)/__/windows/ecv.o + +else + OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/paths.o $(OBJDIR_RELEASE)/__/__/__/common/xmltree.o $(OBJDIR_RELEASE)/__/__/__/common/config.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/__/engine/module.o $(OBJDIR_RELEASE)/__/__/__/engine/section.o $(OBJDIR_RELEASE)/__/__/__/engine/libman.o $(OBJDIR_RELEASE)/__/ecviewer.o $(OBJDIR_RELEASE)/__/linux/ecv.o +endif + all: release clean: clean_release @@ -39,7 +57,11 @@ before_release: test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ test -d $(OBJDIR_RELEASE)/__/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/__/engine test -d $(OBJDIR_RELEASE)/__/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/__/common +ifeq ($(OS),Windows_NT) + test -d $(OBJDIR_RELEASE)/__/windows || mkdir -p $(OBJDIR_RELEASE)/__/windows +else test -d $(OBJDIR_RELEASE)/__/linux || mkdir -p $(OBJDIR_RELEASE)/__/linux +endif after_release: @@ -81,9 +103,18 @@ $(OBJDIR_RELEASE)/__/__/__/engine/libman.o: ../../../engine/libman.cpp $(OBJDIR_RELEASE)/__/ecviewer.o : ../ecviewer.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../ecviewer.cpp -o $(OBJDIR_RELEASE)/__/ecviewer.o +ifeq ($(OS),Windows_NT) + +$(OBJDIR_RELEASE)/__/windows/ecv.o : ../windows/ecv.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../windows/ecv.cpp -o $(OBJDIR_RELEASE)/__/windows/ecv.o + +else + $(OBJDIR_RELEASE)/__/linux/ecv.o : ../linux/ecv.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/ecv.cpp -o $(OBJDIR_RELEASE)/__/linux/ecv.o +endif + clean_release: rm -f $(OBJ_RELEASE) $(OUT_RELEASE) rm -rf $(OBJDIR_RELEASE)/__/__/__/engine diff --git a/elenasrc3/tools/ecv/ecvconst.h b/elenasrc3/tools/ecv/ecvconst.h index 424014dc77..facf11df0a 100644 --- a/elenasrc3/tools/ecv/ecvconst.h +++ b/elenasrc3/tools/ecv/ecvconst.h @@ -3,7 +3,7 @@ // // This file contains the ecv common interfaces & types // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ECVCONST_H @@ -11,9 +11,9 @@ namespace elena_lang { - #define ECV_REVISION_NUMBER 0x0006 + #define ECV_REVISION_NUMBER 0x0007 - constexpr auto ECV_GREETING = "ELENA command line ByteCode Viewer %d.%d.%d (C)2021-24 by Aleksey Rakov\n"; + constexpr auto ECV_GREETING = "ELENA command line ByteCode Viewer %d.%d.%d (C)2021-25 by Aleksey Rakov\n"; constexpr auto ECV_MODULE_NOTLOADED = "cannot load a module: %s"; constexpr auto ECV_MODULE_LOADED = "module %s loaded\n"; diff --git a/elenasrc3/tools/ecv/ecviewer.cpp b/elenasrc3/tools/ecv/ecviewer.cpp index 90b22b3fa9..f8bbb1c0bd 100644 --- a/elenasrc3/tools/ecv/ecviewer.cpp +++ b/elenasrc3/tools/ecv/ecviewer.cpp @@ -3,7 +3,7 @@ // // This is a main file containing ecode viewer code // -// (C)2021-2024, by Aleksey Rakov +// (C)2021-2025, by Aleksey Rakov //--------------------------------------------------------------------------- #include "ecviewer.h" @@ -516,12 +516,16 @@ void ByteCodeViewer :: addCommandArguments(ByteCommand& command, IdentifierStrin } } -void ByteCodeViewer :: addMessage(IdentifierString& commandStr, mssg_t message) +void ByteCodeViewer :: addMessage(IdentifierString& commandStr, mssg_t message, int nullableArgs) { - if (!ByteCodeUtil::resolveMessageName(commandStr, _module, message)) { - commandStr.append("invalid "); - commandStr.appendUInt(message); - } + if (nullableArgs != 0 && ByteCodeUtil::resolveMessageNameWithNullableArgs(commandStr, _module, message, nullableArgs)) { + return; + } + else if (ByteCodeUtil::resolveMessageName(commandStr, _module, message)) + return; + + commandStr.append("invalid "); + commandStr.appendUInt(message); } inline void appendHex32(IdentifierString& command, unsigned int hex) @@ -840,6 +844,9 @@ void ByteCodeViewer :: printFields(ClassInfo& classInfo, int& row, int pageSize) line.append(" of "); line.append(typeName); + + if (fieldInfo.typeInfo.nillable) + line.append('?'); } printLineAndCount("@field ", *line, row, pageSize); @@ -936,7 +943,7 @@ void ByteCodeViewer::printMethod(ustr_t name, bool fullInfo) IdentifierString line; line.copy(*className); line.append('.'); - addMessage(line, message); + addMessage(line, message, methodInfo.nillableArgs); if (methodInfo.outputRef) { line.append("->"); line.append(_module->resolveReference(methodInfo.outputRef)); diff --git a/elenasrc3/tools/ecv/ecviewer.h b/elenasrc3/tools/ecv/ecviewer.h index 2219cf4101..d07e789d9f 100644 --- a/elenasrc3/tools/ecv/ecviewer.h +++ b/elenasrc3/tools/ecv/ecviewer.h @@ -87,7 +87,7 @@ namespace elena_lang void addCommandArguments(ByteCommand& command, IdentifierString& commandStr, List& labels, pos_t commandPosition); - void addMessage(IdentifierString& commandStr, mssg_t message); + void addMessage(IdentifierString& commandStr, mssg_t message, int nullableArgs = 0); void printCommand(ByteCommand& command, int indent, List& labels, pos_t commandPosition); diff --git a/elenasrc3/tools/og/codeblocks/bsd.clang_og_amd64.mak b/elenasrc3/tools/og/codeblocks/bsd.clang_og_amd64.mak new file mode 100644 index 0000000000..f4e50b4b1d --- /dev/null +++ b/elenasrc3/tools/og/codeblocks/bsd.clang_og_amd64.mak @@ -0,0 +1,75 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = clang +CXX = clang++ +AR = ar +LD = clang++ +WINDRES = windres + +INC = -I.. -I../../../engine -I../../../common +RESINC = +LIBDIR = +LIB = +CFLAGS = -Wall -std=c++20 -m64 -static-libgcc -static-libstdc++ +LDFLAGS = -m64 -ldl -fuse-ld=lld + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../../temp/og64-cli/ +DEP_RELEASE = +OUT_RELEASE = ../../../../bin/og64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/og.o + + +all: release + +clean: clean_release + +before_release: + test -d ../../../../bin || mkdir -p ../../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/__/common + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/__/common/dump.o: ../../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/__/common/files.o: ../../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/__/common/ustring.o: ../../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o: ../../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o: ../../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/og.o : ../og.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../og.cpp -o $(OBJDIR_RELEASE)/__/og.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/tools/og/codeblocks/bsd.og_amd64.mak b/elenasrc3/tools/og/codeblocks/bsd.og_amd64.mak new file mode 100644 index 0000000000..2df42dd960 --- /dev/null +++ b/elenasrc3/tools/og/codeblocks/bsd.og_amd64.mak @@ -0,0 +1,75 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = gcc +CXX = g++ +AR = ar +LD = g++ +WINDRES = windres + +INC = -I.. -I../../../engine -I../../../common +RESINC = +LIBDIR = +LIB = +CFLAGS = -Wall -std=c++20 -m64 +LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../../temp/og64-cli/ +DEP_RELEASE = +OUT_RELEASE = ../../../../bin/og64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/og.o + + +all: release + +clean: clean_release + +before_release: + test -d ../../../../bin || mkdir -p ../../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/__/common + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/__/common/dump.o: ../../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/__/common/files.o: ../../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/__/common/ustring.o: ../../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o: ../../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o: ../../../engine/bytecode.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/bytecode.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/bytecode.o + +$(OBJDIR_RELEASE)/__/og.o : ../og.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../og.cpp -o $(OBJDIR_RELEASE)/__/og.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/tools/og/codeblocks/og_amd64.mak b/elenasrc3/tools/og/codeblocks/og_amd64.mak index 8464c5b17e..fd3a18df2f 100644 --- a/elenasrc3/tools/og/codeblocks/og_amd64.mak +++ b/elenasrc3/tools/og/codeblocks/og_amd64.mak @@ -11,12 +11,22 @@ LD = g++ WINDRES = windres INC = -I.. -I../../../engine -I../../../common -CFLAGS = -Wall -std=c++20 -m64 RESINC = LIBDIR = LIB = + +ifeq ($(OS),Windows_NT) + +CFLAGS = -Wall -std=c++20 -m64 -municode +LDFLAGS = -m64 -static-libgcc -static-libstdc++ + +else + +CFLAGS = -Wall -std=c++20 -m64 LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl +endif + INC_RELEASE = $(INC) CFLAGS_RELEASE = $(CFLAGS) -O3 RESINC_RELEASE = $(RESINC) diff --git a/elenasrc3/tools/og/og.cpp b/elenasrc3/tools/og/og.cpp index 3e98f1226a..509e9b2cc8 100644 --- a/elenasrc3/tools/og/og.cpp +++ b/elenasrc3/tools/og/og.cpp @@ -326,6 +326,14 @@ int parseBuildKeyRules(FileEncoding encoding, path_t path) outputFile.changeExtension("dat"); FileWriter file(*outputFile, FileEncoding::Raw, false); + if (!file.isOpen()) { + IdentifierString pathStr(*outputFile); + + printf("\nCannot create a file %s\n", pathStr.str()); + + return -1; + } + trie.save(&file); printf("\nSuccessfully created\n"); diff --git a/elenasrc3/tools/og/ogconst.h b/elenasrc3/tools/og/ogconst.h index b0992806b0..e6ddbdf0c9 100644 --- a/elenasrc3/tools/og/ogconst.h +++ b/elenasrc3/tools/og/ogconst.h @@ -11,7 +11,7 @@ namespace elena_lang { - #define SG_REVISION_NUMBER 0x0014 + #define SG_REVISION_NUMBER 0x0016 constexpr auto OG_GREETING = "ELENA command line optimization rule set generator %d.%d.%d (C)2023-2025 by Aleksey Rakov\n"; diff --git a/elenasrc3/tools/sg/codeblocks/bsd.clang_sg_amd64.mak b/elenasrc3/tools/sg/codeblocks/bsd.clang_sg_amd64.mak new file mode 100644 index 0000000000..66f5d3fb3f --- /dev/null +++ b/elenasrc3/tools/sg/codeblocks/bsd.clang_sg_amd64.mak @@ -0,0 +1,75 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = clang +CXX = clang++ +AR = ar +LD = clang++ +WINDRES = windres + +INC = -I.. -I../../../engine -I../../../common +RESINC = +LIBDIR = +LIB = +CFLAGS = -Wall -std=c++20 -m64 -static-libgcc -static-libstdc++ +LDFLAGS = -m64 -ldl -fuse-ld=lld + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../../temp/sg64-cli/ +DEP_RELEASE = +OUT_RELEASE = ../../../../bin/sg64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/sg.o + + +all: release + +clean: clean_release + +before_release: + test -d ../../../../bin || mkdir -p ../../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/__/common + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/__/common/dump.o: ../../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/__/common/files.o: ../../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/__/common/ustring.o: ../../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/__/engine/parsertable.o: ../../../engine/parsertable.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/parsertable.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/parsertable.o + +$(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o: ../../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/sg.o : ../sg.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../sg.cpp -o $(OBJDIR_RELEASE)/__/sg.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/tools/sg/codeblocks/bsd.sg_amd64.mak b/elenasrc3/tools/sg/codeblocks/bsd.sg_amd64.mak new file mode 100644 index 0000000000..7d6f63337b --- /dev/null +++ b/elenasrc3/tools/sg/codeblocks/bsd.sg_amd64.mak @@ -0,0 +1,75 @@ +#------------------------------------------------------------------------------# +# ELENA make file # +#------------------------------------------------------------------------------# + +WORKDIR = `pwd` + +CC = gcc +CXX = g++ +AR = ar +LD = g++ +WINDRES = windres + +INC = -I.. -I../../../engine -I../../../common +RESINC = +LIBDIR = +LIB = +CFLAGS = -Wall -std=c++20 -m64 +LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl + +INC_RELEASE = $(INC) +CFLAGS_RELEASE = $(CFLAGS) -O3 +RESINC_RELEASE = $(RESINC) +RCFLAGS_RELEASE = $(RCFLAGS) +LIBDIR_RELEASE = $(LIBDIR) +LIB_RELEASE = $(LIB) +LDFLAGS_RELEASE = $(LDFLAGS) -s +OBJDIR_RELEASE = ../../../temp/sg64-cli/ +DEP_RELEASE = +OUT_RELEASE = ../../../../bin/sg64-cli + +OBJ_RELEASE = $(OBJDIR_RELEASE)/__/__/__/common/dump.o $(OBJDIR_RELEASE)/__/__/__/common/files.o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o $(OBJDIR_RELEASE)/__/__/__/engine/parsertable.o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o $(OBJDIR_RELEASE)/__/sg.o + + +all: release + +clean: clean_release + +before_release: + test -d ../../../../bin || mkdir -p ../../../../bin + test -d $(OBJDIR_RELEASE)/__ || mkdir -p $(OBJDIR_RELEASE)/__ + test -d $(OBJDIR_RELEASE)/__/__/__/engine || mkdir -p $(OBJDIR_RELEASE)/__/__/__/engine + test -d $(OBJDIR_RELEASE)/__/__/__/common || mkdir -p $(OBJDIR_RELEASE)/__/__/__/common + +after_release: + +release: before_release out_release after_release + +out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) + $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) + +$(OBJDIR_RELEASE)/__/__/__/common/dump.o: ../../../common/dump.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/dump.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/dump.o + +$(OBJDIR_RELEASE)/__/__/__/common/files.o: ../../../common/files.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/files.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/files.o + +$(OBJDIR_RELEASE)/__/__/__/common/ustring.o: ../../../common/ustring.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../common/ustring.cpp -o $(OBJDIR_RELEASE)/__/__/__/common/ustring.o + +$(OBJDIR_RELEASE)/__/__/__/engine/parsertable.o: ../../../engine/parsertable.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/parsertable.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/parsertable.o + +$(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o: ../../../engine/scriptreader.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../../../engine/scriptreader.cpp -o $(OBJDIR_RELEASE)/__/__/__/engine/scriptreader.o + +$(OBJDIR_RELEASE)/__/sg.o : ../sg.cpp + $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../sg.cpp -o $(OBJDIR_RELEASE)/__/sg.o + +clean_release: + rm -f $(OBJ_RELEASE) $(OUT_RELEASE) + rm -rf $(OBJDIR_RELEASE)/__ + rm -rf $(OBJDIR_RELEASE)/__/__/__/engine + rm -rf $(OBJDIR_RELEASE)/__/__/__/common + +.PHONY: before_release after_release clean_release diff --git a/elenasrc3/tools/sg/codeblocks/sg_amd64.mak b/elenasrc3/tools/sg/codeblocks/sg_amd64.mak index 29c710017d..c18f1bc866 100644 --- a/elenasrc3/tools/sg/codeblocks/sg_amd64.mak +++ b/elenasrc3/tools/sg/codeblocks/sg_amd64.mak @@ -11,12 +11,22 @@ LD = g++ WINDRES = windres INC = -I.. -I../../../engine -I../../../common -CFLAGS = -Wall -std=c++20 -m64 RESINC = LIBDIR = LIB = + +ifeq ($(OS),Windows_NT) + +CFLAGS = -Wall -std=c++20 -m64 -municode +LDFLAGS = -m64 -static-libgcc -static-libstdc++ + +else + +CFLAGS = -Wall -std=c++20 -m64 LDFLAGS = -m64 -static-libgcc -static-libstdc++ -ldl +endif + INC_RELEASE = $(INC) CFLAGS_RELEASE = $(CFLAGS) -O3 RESINC_RELEASE = $(RESINC) diff --git a/examples60/rosetta/twentyfour/twentyfour.l b/examples60/rosetta/twentyfour/twentyfour.l index 1c8084f68b..13ef56075b 100644 --- a/examples60/rosetta/twentyfour/twentyfour.l +++ b/examples60/rosetta/twentyfour/twentyfour.l @@ -188,8 +188,7 @@ extension gameOp } catch(Exception e) { - Console.printLine(e) - //Console.printLine:"An error occurred. Check your input and try again." + Console.printLine:"An error occurred. Check your input and try again." } }; diff --git a/scripts/aarch64/build_package_arm64.script b/scripts/aarch64/build_package_arm64.script index 1c491a322c..a2c6682178 100644 --- a/scripts/aarch64/build_package_arm64.script +++ b/scripts/aarch64/build_package_arm64.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.5.aarch64-linux +RELEASE=elena-6.7.0.aarch64-linux mkdir -p ../lib60_64 mkdir -p /usr/share/elena diff --git a/scripts/aarch64/control b/scripts/aarch64/control index 9397d7168a..8c599da2be 100644 --- a/scripts/aarch64/control +++ b/scripts/aarch64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.5 +Version: 6.7.0 Architecture: aarch64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/scripts/amd64/build_package_amd64.script b/scripts/amd64/build_package_amd64.script old mode 100644 new mode 100755 index 140f023cea..7caf0ac0b2 --- a/scripts/amd64/build_package_amd64.script +++ b/scripts/amd64/build_package_amd64.script @@ -1,6 +1,4 @@ #!/bin/bash -RELEASE=elena-6.6.5.amd64-linux - mkdir -p ../../lib60_64 mkdir -p /usr/share/elena mkdir -p /etc/elena/ @@ -130,77 +128,4 @@ fi cp ../../lib60_64/*.nl /usr/lib/elena/lib60_64 cp ../../lib60_64/*.dnl /usr/lib/elena/lib60_64 - elena64-cli ../../tests60/system_tests/system_tests.prj - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - ../../tests60/system_tests/system_tests - ret=$? - if [ $ret -eq 2 ] - then - echo "Failure" >&2 - exit 1 - else - echo . - fi - - echo "Do you wish to create a package?" - select yn in "Yes" "No"; do - case $yn in - Yes ) break;; - No ) exit;; - esac - done - - mkdir -p ./$RELEASE/etc/elena/ - mkdir -p ./$RELEASE/etc/elena/templates/ - mkdir -p ./$RELEASE/usr/share/elena/ - mkdir -p ./$RELEASE/usr/lib/elena/core/amd64/ - mkdir -p ./$RELEASE/usr/lib/elena/lib60_64/ - mkdir -p ./$RELEASE/usr/bin/ - mkdir -p ./$RELEASE/usr/elena-lang - - mkdir -p ./$RELEASE/usr/elena-lang/examples60/ - - echo copying configuration - - cp ../../bin/*.config ./$RELEASE/etc/elena/ - cp ../../bin/templates/*.config ./$RELEASE/etc/elena/templates - - echo compiling shared files - - cp ../../dat/og/bt_rules60.dat ./$RELEASE/usr/share/elena - cp ../../dat/og/bt_xrules60.dat ./$RELEASE/usr/share/elena - cp ../../dat/og/bc_rules60.dat ./$RELEASE/usr/share/elena - cp ../../dat/sg/syntax60.dat ./$RELEASE/usr/share/elena - - echo copying binaries - - cp ../../bin/elena64-cli ./$RELEASE/usr/bin/ - cp ../../bin/libelenart60_64.so ./$RELEASE/usr/lib/elena/ - - echo compiling core - - cp /usr/lib/elena/core/amd64/*.bin ./$RELEASE/usr/lib/elena/core/amd64/ - - echo compiling lib60 - - cp /usr/lib/elena/lib60_64/*.* ./$RELEASE/usr/lib/elena/lib60_64/ - - cp -r ../../examples60 $RELEASE/usr/elena-lang - cp -r ../../src60 $RELEASE/usr/elena-lang - - mkdir ./$RELEASE/DEBIAN - cp ./control ./$RELEASE/DEBIAN - - dpkg-deb --build $RELEASE - - alien -r -c -v *.deb - exit 0 \ No newline at end of file diff --git a/scripts/amd64/control b/scripts/amd64/control index 336cda6db7..56ed7c9079 100644 --- a/scripts/amd64/control +++ b/scripts/amd64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.5 +Version: 6.7.0 Architecture: amd64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/scripts/amd64/local_build_package_amd64.script b/scripts/amd64/local_build_package_amd64.script index 2b09541bd2..cf5343fd1c 100755 --- a/scripts/amd64/local_build_package_amd64.script +++ b/scripts/amd64/local_build_package_amd64.script @@ -92,4 +92,7 @@ fi echo . fi + mkdir -p /usr/lib/elena/ + ln -s $(realpath ../../bin/libelenart60_64.so) /usr/lib/elena/libelenart60_64.so + exit 0 \ No newline at end of file diff --git a/scripts/amd64/local_create_package.script b/scripts/amd64/local_create_package.script new file mode 100755 index 0000000000..4749ff0abe --- /dev/null +++ b/scripts/amd64/local_create_package.script @@ -0,0 +1,48 @@ +#!/bin/bash + + RELEASE=elena-6.7.0.amd64-linux + + mkdir -p ../../build/$RELEASE/etc/elena/ + mkdir -p ../../build/$RELEASE/etc/elena/templates/ + mkdir -p ../../build/$RELEASE/usr/share/elena/ + mkdir -p ../../build/$RELEASE/usr/lib/elena/core/amd64/ + mkdir -p ../../build/$RELEASE/usr/lib/elena/lib60_64/ + mkdir -p ../../build/$RELEASE/usr/bin/ + mkdir -p ../../build/$RELEASE/usr/elena-lang + + mkdir -p ../../build/$RELEASE/usr/elena-lang/examples60/ + + echo copying configuration + + cp ../../bin/*.config ../../build/$RELEASE/etc/elena/ + cp ../../bin/templates/*.config ../../build/$RELEASE/etc/elena/templates + + echo compiling shared files + + cp ../../dat/og/bt_rules60.dat ../../build/$RELEASE/usr/share/elena + cp ../../dat/og/bt_xrules60.dat ../../build/$RELEASE/usr/share/elena + cp ../../dat/og/bc_rules60.dat ../../build/$RELEASE/usr/share/elena + cp ../../dat/sg/syntax60.dat ../../build/$RELEASE/usr/share/elena + + echo copying binaries + + cp ../../bin/elena64-cli ../../build/$RELEASE/usr/bin/ + cp ../../bin/libelenart60_64.so ../../build/$RELEASE/usr/lib/elena/ + + echo compiling core + + cp ../../bin/amd64/*.bin ../../build/$RELEASE/usr/lib/elena/core/amd64/ + + echo compiling lib60 + + cp ../../bin/lib60_64/*.* ../../build/$RELEASE/usr/lib/elena/lib60_64/ + + cp -r ../../examples60 $RELEASE/usr/elena-lang + cp -r ../../src60 $RELEASE/usr/elena-lang + + mkdir ../../build/$RELEASE/DEBIAN + cp ./control ../../build/$RELEASE/DEBIAN + + dpkg-deb --build ../../build/$RELEASE + + alien -r -c -v ../../build/*.deb diff --git a/scripts/amd64/local_runtests.script b/scripts/amd64/local_runtests.script index 4024db8511..67f6985090 100755 --- a/scripts/amd64/local_runtests.script +++ b/scripts/amd64/local_runtests.script @@ -1,9 +1,5 @@ #!/bin/bash - mkdir -p /usr/lib/elena/lib60_64 - - cp ../../bin/libelenart60_64.so /usr/lib/elena/ - ../../bin/elena64-cli ../../tests60/system_tests/system_tests.prj ret=$? if [ $ret -eq 2 ] diff --git a/scripts/amd64/runtests.script b/scripts/amd64/runtests.script new file mode 100755 index 0000000000..74682c7958 --- /dev/null +++ b/scripts/amd64/runtests.script @@ -0,0 +1,21 @@ +#!/bin/bash + + elena64-cli ../../tests60/system_tests/system_tests.prj + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + ../../tests60/system_tests/system_tests + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi diff --git a/scripts/bsd.amd64/bash/build_package_amd64.script b/scripts/bsd.amd64/bash/build_package_amd64.script new file mode 100755 index 0000000000..dda9b546df --- /dev/null +++ b/scripts/bsd.amd64/bash/build_package_amd64.script @@ -0,0 +1,132 @@ +#!/bin/bash + +mkdir -p ../../lib60_64 +mkdir -p /usr/share/elena +mkdir -p /etc/elena/ +mkdir -p /etc/elena/templates/ +mkdir -p /usr/local/lib/elena/core/x32/ +mkdir -p /usr/local/lib/elena/core/amd64/ +mkdir -p /usr/local/lib/elena/lib60_64 + +cp ../../bin/libelenart60_64.so /usr/local/lib/elena/ +cp ../../bin/libelenasm60_64.so /usr/local/lib/elena/ +# cp ../bin/libelenavm.so /usr/lib/elena/ +cp ../../bin/elena64-cli /usr/bin/ + +cp ../../bin/elc60.config /etc/elena/ +# cp ../bin/elenavm.config /etc/elena/ +cp ../../bin/templates/*.config /etc/elena/templates/ + +echo compiling data files + +../../bin/sg64-cli ../../dat/sg/syntax60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +# ../bin/elena-og ../dat/og/rules.txt +# ret=$? +# if [ $ret -eq 0 ] +# then +# echo . +# else +# echo "Failure" >&2 +# exit 1 +# fi + +../../bin/og64-cli ../../dat/og/bc_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli -s ../../dat/og/bt_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +cp ../../dat/og/*.dat /usr/share/elena/ +cp ../../dat/sg/syntax60.dat /usr/share/elena + +echo compiling assembly files + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60.asm /usr/local/lib/elena/core/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60_lnx.asm /usr/local/lib/elena/core/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +# ../bin/elena-asm2binx ../asm/x32/coreapi.asm /usr/lib/elena/core/x32 +# ret=$? +# if [ $ret -eq 0 ] +# then +# echo . +# else +# echo "Failure" >&2 +# exit 1 +# fi +# +# echo compiling lib50 files + + ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm ../../lib60_64 + ret=$? + if [ $ret -eq 0 ] + then + echo . + else + echo "Failure" >&2 + exit 1 + fi + + ../../bin/elena64-cli ../../src60/elena_api.linux.prjcol + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + cp ../../lib60_64/*.nl /usr/local/lib/elena/lib60_64 + cp ../../lib60_64/*.dnl /usr/local/lib/elena/lib60_64 + +exit 0 \ No newline at end of file diff --git a/scripts/bsd.amd64/bash/local_build_package_amd64.script b/scripts/bsd.amd64/bash/local_build_package_amd64.script new file mode 100755 index 0000000000..3dc2d5045a --- /dev/null +++ b/scripts/bsd.amd64/bash/local_build_package_amd64.script @@ -0,0 +1,98 @@ +#!/bin/bash + +mkdir -p ../../lib60_64 +mkdir -p ../../bin/amd64 + +echo compiling data files + +../../bin/sg64-cli ../../dat/sg/syntax60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli ../../dat/og/bc_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli -s ../../dat/og/bt_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +cp ../../dat/og/*.dat ../../bin +cp ../../dat/sg/syntax60.dat ../../bin + +echo compiling assembly files + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60.asm ../../bin/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60_lnx.asm ../../bin/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +# echo compiling lib60 files + + ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm ../../lib60_64 + ret=$? + if [ $ret -eq 0 ] + then + echo . + else + echo "Failure" >&2 + exit 1 + fi + + ../../bin/elena64-cli ../../src60/elena_api.linux.prjcol + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + mkdir -p /usr/local/lib/elena/ + ln -s $(realpath ../../bin/libelenart60_64.so) /usr/local/lib/elena/libelenart60_64.so + +exit 0 \ No newline at end of file diff --git a/scripts/bsd.amd64/bash/local_runtests.script b/scripts/bsd.amd64/bash/local_runtests.script new file mode 100755 index 0000000000..67f6985090 --- /dev/null +++ b/scripts/bsd.amd64/bash/local_runtests.script @@ -0,0 +1,21 @@ +#!/bin/bash + + ../../bin/elena64-cli ../../tests60/system_tests/system_tests.prj + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + ../../tests60/system_tests/system_tests + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi diff --git a/scripts/bsd.amd64/bash/runtests.script b/scripts/bsd.amd64/bash/runtests.script new file mode 100755 index 0000000000..74682c7958 --- /dev/null +++ b/scripts/bsd.amd64/bash/runtests.script @@ -0,0 +1,21 @@ +#!/bin/bash + + elena64-cli ../../tests60/system_tests/system_tests.prj + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + ../../tests60/system_tests/system_tests + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi diff --git a/scripts/bsd.amd64/build_package_amd64.script b/scripts/bsd.amd64/build_package_amd64.script new file mode 100755 index 0000000000..1408b1ac92 --- /dev/null +++ b/scripts/bsd.amd64/build_package_amd64.script @@ -0,0 +1,132 @@ +#!/bin/sh + +mkdir -p ../../lib60_64 +mkdir -p /usr/share/elena +mkdir -p /etc/elena/ +mkdir -p /etc/elena/templates/ +mkdir -p /usr/local/lib/elena/core/x32/ +mkdir -p /usr/local/lib/elena/core/amd64/ +mkdir -p /usr/local/lib/elena/lib60_64 + +cp ../../bin/libelenart60_64.so /usr/local/lib/elena/ +cp ../../bin/libelenasm60_64.so /usr/local/lib/elena/ +# cp ../bin/libelenavm.so /usr/lib/elena/ +cp ../../bin/elena64-cli /usr/bin/ + +cp ../../bin/elc60.config /etc/elena/ +# cp ../bin/elenavm.config /etc/elena/ +cp ../../bin/templates/*.config /etc/elena/templates/ + +echo compiling data files + +../../bin/sg64-cli ../../dat/sg/syntax60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +# ../bin/elena-og ../dat/og/rules.txt +# ret=$? +# if [ $ret -eq 0 ] +# then +# echo . +# else +# echo "Failure" >&2 +# exit 1 +# fi + +../../bin/og64-cli ../../dat/og/bc_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli -s ../../dat/og/bt_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +cp ../../dat/og/*.dat /usr/share/elena/ +cp ../../dat/sg/syntax60.dat /usr/share/elena + +echo compiling assembly files + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60.asm /usr/local/lib/elena/core/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60_lnx.asm /usr/local/lib/elena/core/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +# ../bin/elena-asm2binx ../asm/x32/coreapi.asm /usr/lib/elena/core/x32 +# ret=$? +# if [ $ret -eq 0 ] +# then +# echo . +# else +# echo "Failure" >&2 +# exit 1 +# fi +# +# echo compiling lib50 files + + ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm ../../lib60_64 + ret=$? + if [ $ret -eq 0 ] + then + echo . + else + echo "Failure" >&2 + exit 1 + fi + + ../../bin/elena64-cli ../../src60/elena_api.linux.prjcol + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + cp ../../lib60_64/*.nl /usr/local/lib/elena/lib60_64 + cp ../../lib60_64/*.dnl /usr/local/lib/elena/lib60_64 + +exit 0 \ No newline at end of file diff --git a/scripts/bsd.amd64/local_build_package_amd64.script b/scripts/bsd.amd64/local_build_package_amd64.script new file mode 100755 index 0000000000..af0af31819 --- /dev/null +++ b/scripts/bsd.amd64/local_build_package_amd64.script @@ -0,0 +1,98 @@ +#!/bin/sh + +mkdir -p ../../lib60_64 +mkdir -p ../../bin/amd64 + +echo compiling data files + +../../bin/sg64-cli ../../dat/sg/syntax60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli ../../dat/og/bc_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli -s ../../dat/og/bt_rules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/og64-cli -s ../../dat/og/bt_xrules60.txt +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +cp ../../dat/og/*.dat ../../bin +cp ../../dat/sg/syntax60.dat ../../bin + +echo compiling assembly files + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60.asm ../../bin/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +../../bin/asm64-cli -amd64 ../../asm/amd64/core60_lnx.asm ../../bin/amd64 +ret=$? +if [ $ret -eq 0 ] +then + echo . +else + echo "Failure" >&2 + exit 1 +fi + +# echo compiling lib60 files + + ../../bin/asm64-cli -bc64 ../../src60/core/system.core_routines.esm ../../lib60_64 + ret=$? + if [ $ret -eq 0 ] + then + echo . + else + echo "Failure" >&2 + exit 1 + fi + + ../../bin/elena64-cli ../../src60/elena_api.linux.prjcol + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + mkdir -p /usr/local/lib/elena/ + ln -s $(realpath ../../bin/libelenart60_64.so) /usr/local/lib/elena/libelenart60_64.so + +exit 0 \ No newline at end of file diff --git a/scripts/bsd.amd64/local_runtests.script b/scripts/bsd.amd64/local_runtests.script new file mode 100755 index 0000000000..5ab32d6bf7 --- /dev/null +++ b/scripts/bsd.amd64/local_runtests.script @@ -0,0 +1,21 @@ +#!/bin/sh + + ../../bin/elena64-cli ../../tests60/system_tests/system_tests.prj + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + ../../tests60/system_tests/system_tests + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi diff --git a/scripts/bsd.amd64/runtests.script b/scripts/bsd.amd64/runtests.script new file mode 100755 index 0000000000..5dcd0dc9ed --- /dev/null +++ b/scripts/bsd.amd64/runtests.script @@ -0,0 +1,21 @@ +#!/bin/sh + + elena64-cli ../../tests60/system_tests/system_tests.prj + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi + + ../../tests60/system_tests/system_tests + ret=$? + if [ $ret -eq 2 ] + then + echo "Failure" >&2 + exit 1 + else + echo . + fi diff --git a/scripts/create_package_x64.bat b/scripts/create_package_x64.bat index 3feb65dbd6..7ed64b8b6c 100644 --- a/scripts/create_package_x64.bat +++ b/scripts/create_package_x64.bat @@ -1,101 +1,62 @@ -@echo off - -ECHO =========== Compiling ELENA files ================== - -md %~dp0\x64 -md %~dp0\x64\bin -md %~dp0\x64\bin\templates -md %~dp0\x64\bin\scripts -md %~dp0\x64\bin\amd64 -md %~dp0\x64\doc -md %~dp0\x64\examples60 - -copy %~dp0\..\bin\asm64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\elena64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\elena64-ide.exe %~dp0\x64\bin -copy %~dp0\..\bin\sg64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\og64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\ecv64-cli.exe %~dp0\x64\bin -copy %~dp0\..\bin\elenart60_64.dll %~dp0\x64\bin -copy %~dp0\..\bin\winstub.ex_ %~dp0\x64\bin -copy %~dp0\..\bin\elc60.cfg %~dp0\x64\bin -copy %~dp0\..\bin\elenart60.cfg %~dp0\x64\bin -copy %~dp0\..\bin\elenavm60.cfg %~dp0\x64\bin - -copy %~dp0\..\bin\amd64\core60.bin %~dp0\x64\bin\amd64 -copy %~dp0\..\bin\amd64\core60_win.bin %~dp0\x64\bin\amd64 -copy %~dp0\..\bin\amd64\corex60.bin %~dp0\x64\bin\amd64 -copy %~dp0\..\bin\amd64\core60_win_client.bin %~dp0\x64\bin\amd64 - -copy %~dp0\..\bin\templates\*.cfg %~dp0\x64\bin\templates\ -copy %~dp0\..\bin\scripts\*.es %~dp0\x64\bin\scripts\ - -copy %~dp0\..\doc\license %~dp0\x64\doc\ -copy %~dp0\..\doc\contributors %~dp0\x64\doc\ -copy %~dp0\..\readme.md %~dp0\x64\ -copy %~dp0\..\CHANGELOG.md %~dp0\x64\ -copy %~dp0\..\VERSION %~dp0\x64\ - -md %~dp0\x64\src60 -xcopy %~dp0\..\src60\*.l %~dp0\x64\src60\ /s -xcopy %~dp0\..\src60\*.prj %~dp0\x64\src60\ /s - -copy %~dp0\..\src60\elena_api.prjcol %~dp0\x64\src60\ - -%~dp0\..\bin\sg64-cli.exe %~dp0\..\dat\sg\syntax60.txt -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on +REM NOTE : the script MUST be called from the root folder -move %~dp0..\dat\sg\syntax60.dat %~dp0\x64\bin\ - -%~dp0\..\bin\og64-cli %~dp0\..\dat\og\bc_rules60.txt -%~dp0\..\bin\og64-cli -s %~dp0\..\dat\og\bt_rules60.txt -%~dp0\..\bin\og64-cli -s %~dp0\..\dat\og\bt_xrules60.txt - -move %~dp0..\dat\og\bt_rules60.dat %~dp0\x64\bin\ -move %~dp0..\dat\og\bt_xrules60.dat %~dp0\x64\bin\ -move %~dp0..\dat\og\bc_rules60.dat %~dp0\x64\bin\ - -md %~dp0\lib60_64 - -%~dp0\..\bin\asm64-cli -bc64 %~dp0\..\src60\core\system.core_routines.esm %~dp0\x64\lib60_64 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm64-cli -bc64 %~dp0\..\src60\core\system.win_core_routines.esm %~dp0\x64\lib60_64 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\x64\bin\elena64-cli %~dp0x64\src60\elena_api.prjcol -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm64-cli -amd64 %~dp0\..\asm\amd64\core60.asm bin\amd64 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm64-cli -amd64 %~dp0\..\asm\amd64\core60_win.asm bin\amd64 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on +@echo off -xcopy %~dp0\..\examples60\*.l %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.prj %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.txt %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.bmp %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.es %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.js %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.ls %~dp0\x64\examples60\ /s -xcopy %~dp0\..\examples60\*.xs %~dp0\x64\examples60\ /s +ECHO =========== Copying ELENA files ================== + +md build\x64 +md build\x64\bin +md build\x64\bin\templates +md build\x64\bin\scripts +md build\x64\bin\amd64 +md build\x64\doc +md build\x64\examples60 +md build\x64\src60 +md build\x64\lib60 + +copy bin\asm64-cli.exe build\x64\bin +copy bin\elena64-cli.exe build\x64\bin +copy bin\elena64-ide.exe build\x64\bin +copy bin\sg64-cli.exe build\x64\bin +copy bin\og64-cli.exe bindx64\bin +copy bin\ecv64-cli.exe build\x64\bin +copy bin\elt64-cli.exe build\x64\bin +copy bin\elenart60_64.dll build\x64\bin +copy bin\elenasm60_64.dll build\x64\bin +copy bin\elenavm60_64.dll build\x64\bin +copy bin\winstub.ex_ build\x64\bin +copy bin\elc60.cfg build\x64\bin +copy bin\elenart60.cfg build\x64\bin +copy bin\elenavm60.cfg build\x64\bin +copy bin\*.es build\x64\bin + +copy bin\*.dat build\x64\bin\ +copy bin\amd64\*.bin build\x64\bin\amd64\ + +copy bin\templates\*.cfg build\x64\bin\templates\ +copy bin\scripts\*.es build\x64\bin\scripts\ + +copy doc\license build\x64\doc\ +copy doc\contributors build\x64\doc\ +copy readme.md build\x64\ +copy CHANGELOG.md build\x64\ +copy VERSION build\x64\ + +xcopy src60\*.l build\x64\src60\ /s +xcopy src60\*.prj build\x64\src60\ /s + +copy src60\elena_api.prjcol build\x64\src60\ + +xcopy lib60_64\*.nl build\x64\lib60_64\ /s +xcopy lib60_64\*.dnl build\x64\lib60_64\ /s + +xcopy examples60\*.l build\x64\examples60\ /s +xcopy examples60\*.prj build\x64\examples60\ /s +xcopy examples60\*.txt build\x64\examples60\ /s +xcopy examples60\*.bmp build\x64\examples60\ /s +xcopy examples60\*.es build\x64\examples60\ /s +xcopy examples60\*.js build\x64\examples60\ /s +xcopy examples60\*.ls build\x64\examples60\ /s +xcopy examples60\*.xs build\x64\examples60\ /s goto:eof -::ERRORS -::--------------------- -:CompilerError -echo The MSBuild returns error %ERRORLEVEL% -goto:eof diff --git a/scripts/create_package_x86.bat b/scripts/create_package_x86.bat index 4395b3d616..411b3246fb 100644 --- a/scripts/create_package_x86.bat +++ b/scripts/create_package_x86.bat @@ -1,122 +1,64 @@ -@echo off - -ECHO =========== Compiling ELENA files ================== - -md %~dp0\x86 -md %~dp0\x86\bin -md %~dp0\x86\bin\templates -md %~dp0\x86\bin\scripts -md %~dp0\x86\bin\x32 -md %~dp0\x86\doc -md %~dp0\x86\examples60 - -copy %~dp0\..\bin\asm-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\elena-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\elena-ide.exe %~dp0\x86\bin -copy %~dp0\..\bin\sg-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\og-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\ecv-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\elt-cli.exe %~dp0\x86\bin -copy %~dp0\..\bin\elenart60.dll %~dp0\x86\bin -copy %~dp0\..\bin\elenasm60.dll %~dp0\x86\bin -copy %~dp0\..\bin\elenavm60.dll %~dp0\x86\bin -copy %~dp0\..\bin\winstub.ex_ %~dp0\x86\bin -copy %~dp0\..\bin\elc60.cfg %~dp0\x86\bin -copy %~dp0\..\bin\elenart60.cfg %~dp0\x86\bin -copy %~dp0\..\bin\elenavm60.cfg %~dp0\x86\bin -copy %~dp0\..\bin\elt60.es %~dp0\x86\bin -copy %~dp0\..\bin\command60.es %~dp0\x86\bin - -copy %~dp0\..\bin\x86\core60.bin %~dp0\x86\bin\x86\ -copy %~dp0\..\bin\x86\core60_win.bin %~dp0\x86\bin\x86\ -copy %~dp0\..\bin\x86\core60_win_client.bin %~dp0\x86\bin\x86\ -copy %~dp0\..\bin\x86\corex60.bin %~dp0\x86\bin\x86\ -copy %~dp0\..\bin\x86\corex60_win.bin %~dp0\x86\bin\x86\ - -copy %~dp0\..\bin\templates\*.cfg %~dp0\x86\bin\templates\ -copy %~dp0\..\bin\scripts\*.es %~dp0\x86\bin\scripts\ - -copy %~dp0\..\doc\license %~dp0\x86\doc\ -copy %~dp0\..\doc\contributors %~dp0\x86\doc\ -copy %~dp0\..\readme.md %~dp0\x86\ -copy %~dp0\..\CHANGELOG.md %~dp0\x86\ -copy %~dp0\..\VERSION %~dp0\x86\ - -md %~dp0\x86\src60 -xcopy %~dp0\..\src60\*.l %~dp0\x86\src60\ /s -xcopy %~dp0\..\src60\*.prj %~dp0\x86\src60\ /s - -copy %~dp0\..\src60\elena_api.prjcol %~dp0\x86\src60\ - -%~dp0\..\bin\sg-cli.exe %~dp0\..\dat\sg\syntax60.txt -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -move %~dp0..\dat\sg\syntax60.dat %~dp0\x86\bin\ - -%~dp0\..\bin\og-cli %~dp0\..\dat\og\bc_rules60.txt -%~dp0\..\bin\og-cli -s %~dp0\..\dat\og\bt_rules60.txt -%~dp0\..\bin\og-cli -s %~dp0\..\dat\og\bt_xrules60.txt +REM NOTE : the script MUST be called from the root folder -move %~dp0..\dat\og\bt_rules60.dat %~dp0\x86\bin\ -move %~dp0..\dat\og\bt_xrules60.dat %~dp0\x86\bin\ -move %~dp0..\dat\og\bc_rules60.dat %~dp0\x86\bin\ - -md %~dp0\lib60 - -%~dp0\..\bin\asm-cli -bc32 %~dp0\..\src60\core\system.core_routines.esm %~dp0\x86\lib60 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -bc32 %~dp0\..\src60\core\system.win_core_routines.esm %~dp0\x86\lib60 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\x86\bin\elena-cli %~dp0x86\src60\elena_api.prjcol -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\core60.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\core60_win.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\corex60_win.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\corex60.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on - -%~dp0\..\bin\asm-cli -x86 %~dp0\..\asm\x32\core60_win_client.asm %~dp0\x86\bin\x32 -@echo off -if %ERRORLEVEL% EQU -2 GOTO CompilerError -@echo on +@echo off -xcopy %~dp0\..\examples60\*.l %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.prj %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.txt %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.bmp %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.es %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.js %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.ls %~dp0\x86\examples60\ /s -xcopy %~dp0\..\examples60\*.xs %~dp0\x86\examples60\ /s +ECHO =========== Copying ELENA files ================== + +md build\x86 +md build\x86\bin +md build\x86\bin\templates +md build\x86\bin\scripts +md build\x86\bin\x32 +md build\x86\doc +md build\x86\examples60 +md build\x86\src60 +md build\x86\lib60 + +dat\api2html\api2html.bat + +copy bin\asm-cli.exe build\x86\bin +copy bin\elena-cli.exe build\x86\bin +copy bin\elena-ide.exe build\x86\bin +copy bin\sg-cli.exe build\x86\bin +copy bin\og-cli.exe bindx86\bin +copy bin\ecv-cli.exe build\x86\bin +copy bin\elt-cli.exe build\x86\bin +copy bin\elenart60.dll build\x86\bin +copy bin\elenasm60.dll build\x86\bin +copy bin\elenavm60.dll build\x86\bin +copy bin\winstub.ex_ build\x86\bin +copy bin\elc60.cfg build\x86\bin +copy bin\elenart60.cfg build\x86\bin +copy bin\elenavm60.cfg build\x86\bin +copy bin\*.es build\x86\bin + +copy bin\*.dat build\x86\bin\ +copy bin\x32\*.bin build\x86\bin\x32\ + +copy bin\templates\*.cfg build\x86\bin\templates\ +copy bin\scripts\*.es build\x86\bin\scripts\ + +copy doc\license build\x86\doc\ +copy doc\contributors build\x86\doc\ +copy readme.md build\x86\ +copy CHANGELOG.md build\x86\ +copy VERSION build\x86\ + +xcopy src60\*.l build\x86\src60\ /s +xcopy src60\*.prj build\x86\src60\ /s + +copy src60\elena_api.prjcol build\x86\src60\ + +xcopy lib60\*.nl build\x86\lib60\ /s +xcopy lib60\*.dnl build\x86\lib60\ /s + +xcopy examples60\*.l build\x86\examples60\ /s +xcopy examples60\*.prj build\x86\examples60\ /s +xcopy examples60\*.txt build\x86\examples60\ /s +xcopy examples60\*.bmp build\x86\examples60\ /s +xcopy examples60\*.es build\x86\examples60\ /s +xcopy examples60\*.js build\x86\examples60\ /s +xcopy examples60\*.ls build\x86\examples60\ /s +xcopy examples60\*.xs build\x86\examples60\ /s goto:eof -::ERRORS -::--------------------- -:CompilerError -echo The MSBuild returns error %ERRORLEVEL% -goto:eof diff --git a/scripts/i386/build_package_i386.script b/scripts/i386/build_package_i386.script old mode 100644 new mode 100755 index 72d1b40073..3f28f55a33 --- a/scripts/i386/build_package_i386.script +++ b/scripts/i386/build_package_i386.script @@ -1,5 +1,4 @@ #!/bin/bash -RELEASE=elena-6.6.5.i386-linux mkdir -p ../lib60 mkdir -p /usr/share/elena @@ -78,7 +77,7 @@ cp ../../dat/sg/syntax60.dat ../../bin echo compiling assembly files -../../bin/asm-cli -x86 ../../asm/x32/core60.asm /usr/lib/elena/core/x32 +../../bin/asm-cli -linux -x86 ../../asm/x32/core60.asm /usr/lib/elena/core/x32 core60_lnx.bin ret=$? if [ $ret -eq 0 ] then @@ -88,7 +87,7 @@ else exit 1 fi -../../bin/asm-cli -x86 ../../asm/x32/corex60.asm /usr/lib/elena/core/x32 +../../bin/asm-cli -linux -x86 ../../asm/x32/corex60.asm /usr/lib/elena/core/x32 corex60_lnx.bin ret=$? if [ $ret -eq 0 ] then @@ -98,26 +97,6 @@ else exit 1 fi -../../bin/asm-cli -x86 ../../asm/x32/core60_lnx.asm /usr/lib/elena/core/x32 -ret=$? -if [ $ret -eq 0 ] -then - echo . -else - echo "Failure" >&2 - exit 1 -fi - -# ../bin/elena-asm2binx ../asm/x32/coreapi.asm /usr/lib/elena/core/x32 -# ret=$? -# if [ $ret -eq 0 ] -# then -# echo . -# else -# echo "Failure" >&2 -# exit 1 -# fi - echo compiling lib60 files ../../bin/asm-cli -bc32 ../../src60/core/system.core_routines.esm ../../lib60 @@ -163,57 +142,5 @@ echo compiling lib60 files echo . fi - echo "Do you wish to create a package?" - select yn in "Yes" "No"; do - case $yn in - Yes ) break;; - No ) exit;; - esac - done - - mkdir -p ./$RELEASE/etc/elena/ - mkdir -p ./$RELEASE/etc/elena/templates/ - mkdir -p ./$RELEASE/usr/share/elena/ - mkdir -p ./$RELEASE/usr/lib/elena/core/x32/ - mkdir -p ./$RELEASE/usr/lib/elena/lib60/ - mkdir -p ./$RELEASE/usr/bin/ - mkdir -p ./$RELEASE/usr/elena-lang - - mkdir -p ./$RELEASE/usr/elena-lang/examples60 - - echo copying configuration - - cp ../../bin/*.config ./$RELEASE/etc/elena/ - cp ../../bin/templates/*.config ./$RELEASE/etc/elena/templates - - echo compiling shared files - - cp ../../dat/og/bt_rules60.dat ./$RELEASE/usr/share/elena - cp ../../dat/og/bt_xrules60.dat ./$RELEASE/usr/share/elena - cp ../../dat/og/bc_rules60.dat ./$RELEASE/usr/share/elena - cp ../../dat/sg/syntax60.dat ./$RELEASE/usr/share/elena - - echo copying binaries - - cp ../../bin/elena-cli ./$RELEASE/usr/bin/ - cp ../../bin/libelenart60.so ./$RELEASE/usr/lib/elena/ - - echo compiling core - - cp /usr/lib/elena/core/x32/*.bin ./$RELEASE/usr/lib/elena/core/x32/ - - echo compiling lib60 - - cp /usr/lib/elena/lib60/*.* ./$RELEASE/usr/lib/elena/lib60/ - - cp -r ../../examples60 $RELEASE/usr/elena-lang - cp -r ../../src60 $RELEASE/usr/elena-lang - - mkdir ./$RELEASE/DEBIAN - cp ./control ./$RELEASE/DEBIAN - - dpkg-deb --build $RELEASE - - alien -r -c -v *.deb exit 0 \ No newline at end of file diff --git a/scripts/i386/control b/scripts/i386/control index 1f0c254d08..76b38f7b5a 100644 --- a/scripts/i386/control +++ b/scripts/i386/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.5 +Version: 6.7.0 Architecture: i386 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/scripts/i386/local_build_package_i386.script b/scripts/i386/local_build_package_i386.script index c548caca50..54ac3badbd 100755 --- a/scripts/i386/local_build_package_i386.script +++ b/scripts/i386/local_build_package_i386.script @@ -1,5 +1,7 @@ #!/bin/bash +BASEDIR=$(dirname $0) + mkdir -p ../../lib60 mkdir -p ../../bin/x32 @@ -50,7 +52,7 @@ cp ../../dat/sg/syntax60.dat ../../bin echo compiling assembly files -../../bin/asm-cli -x86 ../../asm/x32/core60.asm ../../bin/x32 +../../bin/asm-cli -linux -x86 ../../asm/x32/core60.asm ../../bin/x32 core60_lnx.bin ret=$? if [ $ret -eq 0 ] then @@ -60,17 +62,7 @@ else exit 1 fi -../../bin/asm-cli -x86 ../../asm/x32/corex60.asm ../../bin/x32 -ret=$? -if [ $ret -eq 0 ] -then - echo . -else - echo "Failure" >&2 - exit 1 -fi - -../../bin/asm-cli -x86 ../../asm/x32/core60_lnx.asm ../../bin/x32 +../../bin/asm-cli -linux -x86 ../../asm/x32/corex60.asm ../../bin/x32 corex60_lnx.bin ret=$? if [ $ret -eq 0 ] then @@ -102,4 +94,7 @@ fi echo . fi + mkdir -p /usr/lib/elena/ + ln -s $(realpath ../../bin/libelenart60.so) /usr/lib/elena/libelenart60.so + exit 0 \ No newline at end of file diff --git a/scripts/i386/local_create_package.script b/scripts/i386/local_create_package.script new file mode 100755 index 0000000000..945653d73f --- /dev/null +++ b/scripts/i386/local_create_package.script @@ -0,0 +1,47 @@ +#!/bin/bash +RELEASE=elena-6.7.0.i386-linux + + mkdir -p ../../build/$RELEASE/etc/elena/ + mkdir -p ../../build/$RELEASE/etc/elena/templates/ + mkdir -p ../../build/$RELEASE/usr/share/elena/ + mkdir -p ../../build/$RELEASE/usr/lib/elena/core/x32/ + mkdir -p ../../build/$RELEASE/usr/lib/elena/lib60/ + mkdir -p ../../build/$RELEASE/usr/bin/ + mkdir -p ../../build/$RELEASE/usr/elena-lang + + mkdir -p ../../build/$RELEASE/usr/elena-lang/examples60 + + echo copying configuration + + cp ../../bin/*.config ../../build/$RELEASE/etc/elena/ + cp ../../bin/templates/*.config ../../build/$RELEASE/etc/elena/templates + + echo compiling shared files + + cp ../../dat/og/bt_rules60.dat ../../build/$RELEASE/usr/share/elena + cp ../../dat/og/bt_xrules60.dat ../../build/$RELEASE/usr/share/elena + cp ../../dat/og/bc_rules60.dat ../../build/$RELEASE/usr/share/elena + cp ../../dat/sg/syntax60.dat ../../build/$RELEASE/usr/share/elena + + echo copying binaries + + cp ../../bin/elena-cli ../../build/$RELEASE/usr/bin/ + cp ../../bin/libelenart60.so ../../build/$RELEASE/usr/lib/elena/ + + echo compiling core + + cp ../../bin/x32/*.bin ../../build/$RELEASE/usr/lib/elena/core/x32/ + + echo compiling lib60 + + cp ../../bin/lib60/*.* ../../build/$RELEASE/usr/lib/elena/lib60/ + + cp -r ../../examples60 $RELEASE/usr/elena-lang + cp -r ../../src60 $RELEASE/usr/elena-lang + + mkdir ../../build/$RELEASE/DEBIAN + cp ./control ../../build/$RELEASE/DEBIAN + + dpkg-deb --build ../../build/$RELEASE + + alien -r -c -v ../../build/*.deb diff --git a/scripts/i386/local_runtests.script b/scripts/i386/local_runtests.script index 1b4864983e..e5347fbec5 100755 --- a/scripts/i386/local_runtests.script +++ b/scripts/i386/local_runtests.script @@ -1,9 +1,5 @@ #!/bin/bash - mkdir -p /usr/lib/elena/lib60 - - cp ../../bin/libelenart60.so /usr/lib/elena/ - ../../bin/elena-cli ../../tests60/system_tests/system_tests.prj ret=$? if [ $ret -eq 2 ] diff --git a/scripts/ppc64le/build_package_ppc64le.script b/scripts/ppc64le/build_package_ppc64le.script index 02a890b713..a3f63bd35c 100644 --- a/scripts/ppc64le/build_package_ppc64le.script +++ b/scripts/ppc64le/build_package_ppc64le.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.6.5.ppc64le-linux +RELEASE=elena-6.7.0.ppc64le-linux mkdir -p ../lib60_64 mkdir -p /usr/share/elena diff --git a/scripts/ppc64le/control b/scripts/ppc64le/control index ff68a8b073..8c39570181 100644 --- a/scripts/ppc64le/control +++ b/scripts/ppc64le/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.6.5 +Version: 6.7.0 Architecture: ppc64le Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/scripts/rebuild_lib60_x86.bat b/scripts/rebuild_lib60_x86.bat index 9da306d99f..fbc1edc6f7 100644 --- a/scripts/rebuild_lib60_x86.bat +++ b/scripts/rebuild_lib60_x86.bat @@ -1,21 +1,11 @@ REM NOTE : the script MUST be called from the root folder -bin\asm-cli -x86 asm\x32\core60.asm bin\x32 +bin\asm-cli -windows -x86 asm\x32\core60.asm bin\x32 core60_win.bin @echo off if %ERRORLEVEL% EQU -1 GOTO Asm2BinError @echo on -bin\asm-cli -x86 asm\x32\corex60.asm bin\x32 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm-cli -x86 asm\x32\core60_win.asm bin\x32 -@echo off -if %ERRORLEVEL% EQU -1 GOTO Asm2BinError -@echo on - -bin\asm-cli -x86 asm\x32\corex60_win.asm bin\x32 +bin\asm-cli -windows -x86 asm\x32\corex60.asm bin\x32 corex60_win.bin @echo off if %ERRORLEVEL% EQU -1 GOTO Asm2BinError @echo on @@ -40,27 +30,6 @@ bin\elena-cli src60\elena_api.prjcol if %ERRORLEVEL% EQU -2 GOTO CompilerError @echo on -bin\ldoc system doc\api -bin\ldoc system'collections'threadsafe doc\api -bin\ldoc system'routines doc\api -bin\ldoc system'runtime doc\api -bin\ldoc system'threading doc\api -bin\ldoc system'dynamic doc\api -bin\ldoc system'drawing doc\api -bin\ldoc system'winforms doc\api -bin\ldoc system'net doc\api -bin\ldoc extensions doc\api -bin\ldoc extensions'routines doc\api -bin\ldoc extensions'scripting doc\api -bin\ldoc extensions'dynamic doc\api -bin\ldoc extensions'io doc\api -bin\ldoc cellular doc\api -bin\ldoc algorithms doc\api -bin\ldoc sqlite doc\api -bin\ldoc forms doc\api -bin\ldoc ltests doc\api -bin\ldoc net doc\api - bin\elena-cli tests60\system_tests\system_tests.prj @echo off if %ERRORLEVEL% EQU -2 GOTO CompilerError diff --git a/src60/algorithms/algorithms.linux.prj b/src60/algorithms/algorithms.linux.prj index aa017dc878..2c379eb91e 100644 --- a/src60/algorithms/algorithms.linux.prj +++ b/src60/algorithms/algorithms.linux.prj @@ -9,6 +9,11 @@ ../../lib60_64
    + + + ../../lib60_64 + + ../../lib60_64 @@ -25,12 +30,14 @@ ELENA Algorithms Library - 6.5.0 + 6.6.0 Aleksey Rakov quicksort.l + insertsort.l + binary.l sort_extensions.l diff --git a/src60/algorithms/algorithms.prj b/src60/algorithms/algorithms.prj index aff167535a..de9a6dd937 100644 --- a/src60/algorithms/algorithms.prj +++ b/src60/algorithms/algorithms.prj @@ -15,12 +15,14 @@ ELENA Algorithms Library - 6.5.0 + 6.6.0 Aleksey Rakov quicksort.l + insertsort.l + binary.l sort_extensions.l diff --git a/src60/algorithms/binary.l b/src60/algorithms/binary.l new file mode 100644 index 0000000000..6e6eaf8ebf --- /dev/null +++ b/src60/algorithms/binary.l @@ -0,0 +1,22 @@ +public singleton BinarySearchAlgorithm +{ + int search(SortingAgent source, T value) + { + int low := 0; + int high := source.Length - 1; + while (low <= high) { + int mid := (low + high) / 2; + if (source[mid] > value) { + high := mid - 1; + } + else if (source[mid] < value) { + low := mid + 1; + } + else { + ^ mid + } + }; + + ^ -1 // indicate not found + } +} \ No newline at end of file diff --git a/src60/algorithms/insertsort.l b/src60/algorithms/insertsort.l new file mode 100644 index 0000000000..23e391cca9 --- /dev/null +++ b/src60/algorithms/insertsort.l @@ -0,0 +1,47 @@ +import system'routines; + +public singleton InsertSortAlgorithm +{ + sort(SortingAgent source, int start, int length, Func2 compf) + { + int end := start + length; + + for(int i := start + 1; i < end; i += 1) + { + var entry := source[i]; + int j := i; + + while (j > start && compf(entry, source[j - 1])) + { + source.move(j, j - 1); + + j -= 1 + }; + + source[j] := entry + } + } +} + +public singleton InsertSortAlgorithm +{ + sort(SortingAgent source, int start, int length, Func compf) + { + int end := start + length; + + for(int i := start + 1; i < end; i += 1) + { + T entry := source[i]; + int j := i; + + while (j > start && compf(entry, source[j - 1])) + { + source.move(j, j - 1); + + j -= 1 + }; + + source[j] := entry + } + } +} diff --git a/src60/algorithms/quicksort.l b/src60/algorithms/quicksort.l index c972864733..04c77fa473 100644 --- a/src60/algorithms/quicksort.l +++ b/src60/algorithms/quicksort.l @@ -59,3 +59,61 @@ public singleton QuickSortAlgorithm } } } + + +public singleton QuickSortAlgorithm +{ + sort(SortingAgent source, int start, int length, Func compf) + { + int beg[MAX_LEVELS]; + int end[MAX_LEVELS]; + + beg[0] := start; + end[0] := length; + + int i := 0; + while (i >= 0) { + int L := beg[i]; + int R := end[i]; + if (R > L + 1) { + R--; + + T piv := source[L]; + while (L < R) { + while ((!compf(source[R], piv)) && L < R) + R--; + + if (L < R) { + source[L] := source[R]; + L++; + }; + + while (compf(source[L], piv) && L < R) + L++; + + if (L < R) { + source[R] := source[L]; + R--; + } + }; + source[L] := piv; + if (L - beg[i] > end[i] - R) { + beg[i + 1] := L + 1; + end[i + 1] := end[i]; + end[i] := L; + i++; + } + else { + beg[i + 1] := beg[i]; + end[i + 1] := L; + beg[i] := L + 1; + i++; + }; + } + else + { + i--; + } + } + } +} diff --git a/src60/algorithms/sort_extensions.l b/src60/algorithms/sort_extensions.l index 11520cb555..3b5be9d305 100644 --- a/src60/algorithms/sort_extensions.l +++ b/src60/algorithms/sort_extensions.l @@ -1,6 +1,12 @@ import system'collections; import system'routines; +public singleton IfOrdered : Func +{ + bool function(T f, T l) + = f < l; +} + public extension quickSortOp : Indexable { quickSort(int length, Func2 compf) @@ -36,4 +42,67 @@ public extension quickSortOp3 { QuickSortAlgorithm.sort(new IndexerSortingAgent(self), 0, self.Length, ifOrdered); } +} + +public extension quickSortOp : Array +{ + quickSort(Func compf) + { + QuickSortAlgorithm.sort(new ArraySortingAgent(self), 0, self.Length, compf); + } + + quickSort() + { + QuickSortAlgorithm.sort(new ArraySortingAgent(self), 0, self.Length, ::IfOrdered); + } +} + +public extension insertSortOp : Indexable +{ + insertSort(int length, Func2 compf) + { + InsertSortAlgorithm.sort(new IndexerSortingAgent(self), 0, length, compf); + } + + insertSort(int length) + = self.quickSort(length, ifOrdered); +} + +public extension isnertSortOp2 : ArrayList +{ + insertSort(Func2 compf) + { + InsertSortAlgorithm.sort(new IndexerSortingAgent(self), 0, self.Length, compf); + } + + insertSort() + { + InsertSortAlgorithm.sort(new IndexerSortingAgent(self), 0, self.Length, ifOrdered); + } +} + +public extension insertSortOp3 +{ + insertSort(Func2 compf) + { + InsertSortAlgorithm.sort(new IndexerSortingAgent(self), 0, self.Length, compf); + } + + insertSort() + { + InsertSortAlgorithm.sort(new IndexerSortingAgent(self), 0, self.Length, ifOrdered); + } +} + +public extension insertSortOp : Array +{ + insertSort(Func compf) + { + InsertSortAlgorithm.sort(new ArraySortingAgent(self), 0, self.Length, compf); + } + + insertSort() + { + InsertSortAlgorithm.sort(new ArraySortingAgent(self), 0, self.Length, ::IfOrdered); + } } \ No newline at end of file diff --git a/src60/cellular/cellular.linux.prj b/src60/cellular/cellular.linux.prj index 10c63dfbdc..0cf32b1c37 100644 --- a/src60/cellular/cellular.linux.prj +++ b/src60/cellular/cellular.linux.prj @@ -9,6 +9,11 @@ ../../lib60_64 + + + ../../lib60_64 + + ../../lib60_64 diff --git a/src60/core/system.core_routines.esm b/src60/core/system.core_routines.esm index b9f7d5ad74..dfd9f2095d 100644 --- a/src60/core/system.core_routines.esm +++ b/src60/core/system.core_routines.esm @@ -1601,9 +1601,13 @@ procedure __messagename_loadbystr (self, s) cmp n:0 jne labExit - xstore sp:0, class : "system'InvalidArgumentException" - set mssgconst : "new[1]" + peek fp:s + store sp:1 + + xstore sp:0, class : "system'MessageLoaderException" + + set mssgconst : "new[2]" throw labExit: diff --git a/src60/elena_api.linux.prjcol b/src60/elena_api.linux.prjcol index 73fee2d46c..e9a7c1ea0c 100644 --- a/src60/elena_api.linux.prjcol +++ b/src60/elena_api.linux.prjcol @@ -5,5 +5,6 @@ ltests/ltests.linux.prj algorithms/algorithms.linux.prj cellular/cellular.linux.prj + xml/xml.linux.prj
    \ No newline at end of file diff --git a/src60/elena_api.prjcol b/src60/elena_api.prjcol index c7ffe3e24b..0ac2067245 100644 --- a/src60/elena_api.prjcol +++ b/src60/elena_api.prjcol @@ -10,5 +10,7 @@ xforms\xforms.prj net\net.prj mbedtls\mbedtls.prj + xml\xml.prj + textgen\textgen.prj \ No newline at end of file diff --git a/src60/extensions/convertors.l b/src60/extensions/convertors.l index 0f9bb9497f..cdc7101b38 100644 --- a/src60/extensions/convertors.l +++ b/src60/extensions/convertors.l @@ -184,7 +184,7 @@ public singleton ByteArrayExConvertor if (len > tmp_len) { len := tmp_len }; - UTF8Encoder.toByteArray(s, i, ref len, tmp, 0, ref tmp_len); + tmp_len := UTF8Encoder.toByteArray(s, i, ref len, tmp, 0, tmp_len); if (nil == retVal) { diff --git a/src60/extensions/extensions.linux.prj b/src60/extensions/extensions.linux.prj index cc13572986..ea259d049e 100644 --- a/src60/extensions/extensions.linux.prj +++ b/src60/extensions/extensions.linux.prj @@ -9,6 +9,11 @@ ../../lib60_64 + + + ../../lib60_64 + + ../../lib60_64 @@ -25,7 +30,7 @@ ELENA Extension Library - 6.6.0 + 6.6.2 Alex Rakov diff --git a/src60/extensions/extensions.prj b/src60/extensions/extensions.prj index 6fc4138a06..5723043748 100644 --- a/src60/extensions/extensions.prj +++ b/src60/extensions/extensions.prj @@ -15,7 +15,7 @@ ELENA Extension Library - 6.6.1 + 6.6.2 Alex Rakov diff --git a/src60/extensions/scripting/lscript.l b/src60/extensions/scripting/lscript.l index 18c70ccb5c..56f9bbd267 100644 --- a/src60/extensions/scripting/lscript.l +++ b/src60/extensions/scripting/lscript.l @@ -1,4 +1,4 @@ -public singleton lscript +public singleton LScript { eval(string script) = lscriptEngine.buildScript(script).compile(); @@ -34,4 +34,6 @@ public singleton lscript var s := ns.program; ^ s() } -} \ No newline at end of file +} + +public lscript = LScript; // !! obsolte \ No newline at end of file diff --git a/src60/extensions/text/strings.l b/src60/extensions/text/strings.l index 2c43697bfc..57308eb83c 100644 --- a/src60/extensions/text/strings.l +++ b/src60/extensions/text/strings.l @@ -1,5 +1,9 @@ namespace text { + use system'io'TextWriter; + use system'text'Encoder; + //use system'text'UTF8Encoder; + // --- StringBookmark --- public class StringBookmark : BaseValue { @@ -156,7 +160,7 @@ namespace text } // --- StringWriter --- - public sealed class StringWriter : BaseVariable + public sealed class StringWriter : BaseVariable, interface { string _value; string _newLine; @@ -188,6 +192,11 @@ namespace text _value := _value.add(s) } + write(wide s) + { + _value := _value.add(s) + } + write(char ch) { _value := _value.add(ch) @@ -197,6 +206,11 @@ namespace text { self.write(s).write(_newLine) } + + writeLine(wide s) + { + self.write(s).write(_newLine) + } writeLine() { @@ -229,10 +243,25 @@ namespace text _value := EmptyString } + close() {} + + write(char[] array, int length) + { + write(String.copy(0, length, array)) + } + string toPrintable() = _value; string cast() = _value; + wide cast() = _value; + + Source + = self; + + Encoder Encoder + = system'text'UTF8Encoder; + string Value { get() = _value; @@ -242,9 +271,5 @@ namespace text _value := val } } - - wide cast() = _value; - - dispatch() => _value; } } \ No newline at end of file diff --git a/src60/forms/forms.prj b/src60/forms/forms.prj index 9160cf818a..8416051884 100644 --- a/src60/forms/forms.prj +++ b/src60/forms/forms.prj @@ -17,7 +17,7 @@ ELENA GUI Library - 6.6.0 + 6.6.1 Aleksey Rakov diff --git a/src60/forms/win32_controls.l b/src60/forms/win32_controls.l index 10e84d56b9..59645e7d06 100644 --- a/src60/forms/win32_controls.l +++ b/src60/forms/win32_controls.l @@ -3,6 +3,29 @@ import system'collections; import system'runtime; import system'drawing; +// --- ListenerBase --- + +textblock ListenerBase +{ + onClick(Handle handle) + { + auto control := _owner.retrieve(handle); + if(nil != control) + { control.click() }; + + super.onClick(handle) + } + + onChange(Handle handle) + { + auto control := _owner.retrieve(handle); + if(nil != control) + { control.change() }; + + super.onClick(handle) + } +} + // --- IControl --- public interface IControl @@ -18,6 +41,8 @@ public interface IControl abstract close(); abstract click(); + + abstract change(); } // --- BaseWindowControl --- @@ -155,6 +180,8 @@ public abstract class BaseWinControl : BaseControl } click() {} + + change() {} } // --- BaseWinContainer --- @@ -283,10 +310,17 @@ public class StaticLabel : Label abstract class BaseEdit : BaseWinControl { + Func1 onChange : event; + protected constructor new() <= super new() { } + + change() + { + onChange?.(self) + } string Value = self.Caption; @@ -813,7 +847,7 @@ public abstract class BasePanel : BaseWinContainer } } -class PanelListener : WindowCallback +class PanelListener : WindowCallback, using(ListenerBase) { Panel _owner; @@ -1091,6 +1125,8 @@ public sealed class ImageList : Object, interface } click() {} + + change() {} open() { diff --git a/src60/forms/win_forms.l b/src60/forms/win_forms.l index 75b886a7ca..47d9bddb83 100644 --- a/src60/forms/win_forms.l +++ b/src60/forms/win_forms.l @@ -26,19 +26,10 @@ public abstract class BaseWinForm : BaseWinContainer // --- SDI --- -class SDIWindowListener : SDIWindowCallback +class SDIWindowListener : SDIWindowCallback, using(ListenerBase) { SDIForm _owner; - onClick(Handle handle) - { - auto control := _owner.retrieve(handle); - if(nil != control) - { control.click() }; - - super.onClick(handle) - } - onWMDestoy(Handle hwnd) { super.onWMDestoy(hwnd); @@ -123,22 +114,13 @@ public class SDIDialog : SDIForm // --- Child --- -class ChildWindowListener : ChildWindowCallback +class ChildWindowListener : ChildWindowCallback, using(ListenerBase) { - ChildForm _owner; - - constructor(ChildForm owner) - { - _owner := owner - } + ChildForm _owner; - onClick(Handle handle) + constructor(ChildForm owner) { - auto control := _owner.retrieve(handle); - if(nil != control) - { control.click() }; - - super.onClick(handle) + _owner := owner } onWMDestoy(Handle hwnd) @@ -152,15 +134,6 @@ class ChildWindowListener : ChildWindowCallback { _owner.resize(control, width, height); } - -// onchange(WindowHandle hwnd, ref int retVal) -// { -// auto control := theOwner.retrieve(handle); -// if(nil != control) -// { control.click() }; -// -// super.onchange(handle, ref retVal) -// } } public closed class ChildForm : BaseWinForm @@ -210,4 +183,3 @@ public closed class ChildForm : BaseWinForm } } - diff --git a/src60/ltests/ltests.linux.prj b/src60/ltests/ltests.linux.prj index 77249b1a04..bef7025de5 100644 --- a/src60/ltests/ltests.linux.prj +++ b/src60/ltests/ltests.linux.prj @@ -9,6 +9,11 @@ ../../lib60_64 + + + ../../lib60_64 + + ../../lib60_64 diff --git a/src60/net/http/httpclient.l b/src60/net/http/httpclient.l index e6124c72f3..4cd4e40f5f 100644 --- a/src60/net/http/httpclient.l +++ b/src60/net/http/httpclient.l @@ -107,6 +107,35 @@ public class HttpClient ^ response; } + async Task postAsync(string path, HttpRequest request) + { + int length := request.ContentLength; + + /* Send headers to server */ + NetworkStream stream := new NetworkStream(_socket); + + HttpHeaders postHeaders := default; + if (request.Headers.Length == 0) { + postHeaders := _headers; + } + else { + postHeaders := HttpHeaders.combine(_headers, request.Headers); + }; + + string headers := postHeaders.Value; + string content := request.Content; + + string request := $"POST {path} HTTP/1.1"$13$10"Host:{_host}"$13$10"Connection:close"$13$10"Content-Length:{length}"$13$10"Content-Type:application/x-www-form-urlencoded"$13$10"{headers}"$13$10"{content}"; + + :await stream.writeAsync(request); + + HttpResponse response := HttpResponse.assign(stream); + + :await response.readHeaderAsync(); + + ^ response; + } + HttpResponse get() <= get("/"); @@ -127,6 +156,39 @@ public class HttpClient ^ response; } + + HttpResponse post(HttpRequest request) + <= post("/", request); + + HttpResponse post(string path, HttpRequest request) + { + int length := request.ContentLength; + + /* Send headers to server */ + NetworkStream stream := new NetworkStream(_socket); + + HttpHeaders postHeaders := default; + if (request.Headers.Length == 0) { + postHeaders := _headers; + } + else { + postHeaders := HttpHeaders.combine(_headers, request.Headers); + }; + + string headers := postHeaders.Value; + string content := request.Content; + + string request := $"POST {path} HTTP/1.1"$13$10"Host:{_host}"$13$10"Connection:close"$13$10"Content-Length:{length}"$13$10"Content-Type:application/x-www-form-urlencoded"$13$10"{headers}"$13$10"{content}"; + + stream.write(request); + + HttpResponse response := HttpResponse.assign(stream); + + response.readHeader(); + + ^ response; + } + close() { if:not:nil(_socket) diff --git a/src60/net/http/httpheaders.l b/src60/net/http/httpheaders.l index a9edb08433..f52e013c01 100644 --- a/src60/net/http/httpheaders.l +++ b/src60/net/http/httpheaders.l @@ -1,20 +1,40 @@ import system'text; import system'collections; -public class HttpHeaders +public sealed class HttpHeaders { List> _headers; + static HttpHeaders combine(HttpHeaders headers1, HttpHeaders headers2) + { + auto headers := new List>(); + headers.appendRange(headers1.List.enumerator()); + headers.appendRange(headers2.List.enumerator()); + + ^ HttpHeaders.assign(headers); + } + + internal constructor assign(List> headers) + { + _headers := headers; + } + constructor() { _headers := new List>(); } + internal List> List + = _headers; + add(string name, string content) { _headers.append(new Tuple(name, content)); } + int Length + = _headers.Length; + string at(string key) { foreach(auto p; in _headers) { diff --git a/src60/net/http/httprequest.l b/src60/net/http/httprequest.l new file mode 100644 index 0000000000..45f54cbaed --- /dev/null +++ b/src60/net/http/httprequest.l @@ -0,0 +1,32 @@ +import system'io; +import system'text; + +public sealed class HttpRequest +{ + MemoryBuffer _buffer; + + HttpHeaders _headers; + + HttpHeaders Headers + { + get() + { + ^ _headers; + } + } + + int ContentLength + = _buffer.Length; + + string Content + = UTF8Encoding.toString(0, _buffer.Length, *_buffer); + + constructor new(byte[] body, int length) + { + _buffer := MemoryBuffer.allocate(); + + _headers := new HttpHeaders(); + + Base64Encoding.encode(0, length, body, _buffer); + } +} \ No newline at end of file diff --git a/src60/net/http/httpresponse.l b/src60/net/http/httpresponse.l index 11ccb2eb51..dcee8cc6c6 100644 --- a/src60/net/http/httpresponse.l +++ b/src60/net/http/httpresponse.l @@ -6,7 +6,7 @@ import system'routines; import system'culture; import extensions; -public class HttpResponse +public sealed class HttpResponse { NetworkStream _stream; MemoryBuffer _buffer; @@ -17,6 +17,30 @@ public class HttpResponse int _statusCode; string _statusText; + string StatusText + { + get() + { + ^ _statusText; + } + } + + int StatusCode + { + get() + { + ^ _statusCode; + } + } + + HttpHeaders Headers + { + get() + { + ^ _headers; + } + } + private int seekEOL(byte[] buffer, int start, int length) { for (int i := start; i < length; i++) { diff --git a/src60/net/net.prj b/src60/net/net.prj index 60fc71ddc5..f6af8a0fb9 100644 --- a/src60/net/net.prj +++ b/src60/net/net.prj @@ -28,6 +28,7 @@ http\common.l http\httpheaders.l http\httpresponse.l + http\httprequest.l http\httpclient.l
    diff --git a/src60/system/attributes/attributes.l b/src60/system/attributes/attributes.l index 3bc44525e7..280d5aab80 100644 --- a/src60/system/attributes/attributes.l +++ b/src60/system/attributes/attributes.l @@ -1,5 +1,9 @@ #new attributes; +/// instruction: +#let attributes["use"] := 80008001h; +#let attributes["import"] := 80008002h; + /// modificator: #let attributes["__ignore_duplicates"] := 80007001h; @@ -23,7 +27,6 @@ #let attributes["abstract"] := 80003002h; #let attributes["closed"] := 80003003h; #let attributes["predefined"] := 80003005h; -#let attributes["override"] := 80003006h; /// scope_prefix: #let attributes["const"] := 80002001h; @@ -58,7 +61,6 @@ #let attributes["extern"] := 80001015h; #let attributes["intern"] := 80001016h; #let attributes["forward"] := 80001017h; -#let attributes["import"] := 80001018h; #let attributes["mixin"] := 80001019h; #let attributes["distributed"] := 8000101Ah; #let attributes["auto"] := 8000101Ch; diff --git a/src60/system/basic.l b/src60/system/basic.l index 0b91d1ea46..e1a1c468cd 100644 --- a/src60/system/basic.l +++ b/src60/system/basic.l @@ -3,27 +3,27 @@ public abstract class BaseValue : info("a base value") { bool equal(BaseVariable var) - : info("Returns true if a value of var is equal to the object value; otherwise, false") + : info("Returns true if a value of a variable var is equal to the object value; otherwise, false") <= equal(*var); bool less(BaseVariable var) - : info("Returns true if the object value is less than a value of var; otherwise, false") + : info("Returns true if the object value is less than a value of a variable var ; otherwise, false") <= less(*var); - abstract bool less(v) + abstract bool less(o) : info("Returns true if the object value is less than o; otherwise, false;
    should be overridden"); - bool greater(v) + bool greater(o) : info("Returns true if the object value is greater than o; otherwise, false;
    by default sends less[2] to o with the object as an argument") - = v.less(self); + = o.less(self); - bool notless(v) + bool notless(o) : info("Returns true if the object value is not less than o; otherwise, false;
    by default inverts the result of less[2] operation") - = !self.less(v); + = !self.less(o); - bool notgreater(v) + bool notgreater(o) : info("Returns true if the object value is not greater than o; otherwise, false;
    by default inverts the result of greater[2] operation") - = !self.greater(v); + = !self.greater(o); } // --- BoolValue --- @@ -49,9 +49,10 @@ public interface BoolValue : info("Returns trueVal if the value is true or falseVal otherwise;
    has to be implemented"); abstract bool equal(bool f) - : info("Determines whether the specified object is equal to the current object boolean value;
    has to be implemented"); + : info("Returns true if an argument f is equal to the current object boolean value;
    has to be implemented"); - abstract bool notequal(bool f); + abstract bool notequal(bool f) + : info("Returns true if an argument f is not equal to the current object boolean value;
    has to be implemented"); abstract bool or(expr) : info("Executes logical OR operation<;br/>has to be implemented"); @@ -88,7 +89,7 @@ public interface BoolValue = trueVal; bool equal(bool b) - : info("Determines whether the specified object is equal to the current object boolean value.") + : info("Returns true if an argument b is true") = b; bool notequal(bool b) @@ -185,15 +186,19 @@ public abstract class BaseNumber : BaseValue, info("a base numeric value") { add(BaseVariable var) + : info("Adds a variable value of var argument") <= add(*var); subtract(BaseVariable var) + : info("Subtracts a variable value of var argument") <= subtract(*var); multiply(BaseVariable var) + : info("Multiplies a variable value of var argument") <= multiply(*var); divide(BaseVariable var) + : info("Divides by a variable value of var argument") <= divide(*var); abstract add(o) @@ -263,6 +268,7 @@ public const struct ByteNumber : IntBaseNumber, = 255; static byte Default + : info("returns the default value (0)") = 0; constructor() diff --git a/src60/system/dynamic/expressions/expressions.l b/src60/system/dynamic/expressions/expressions.l index 6e7f722039..c4f8467e44 100644 --- a/src60/system/dynamic/expressions/expressions.l +++ b/src60/system/dynamic/expressions/expressions.l @@ -188,6 +188,9 @@ namespace expressions static Expression Loop(Expression cond, Expression body) = new LoopExpression(cond, body); + static Expression ForLoop(Expression init_cond, Expression cond, Expression step, Expression body) + = new ForLoopExpression(init_cond, cond, step, body); + static Expression VariableByIndex(int index) = new VariableByIndexExpression(index); @@ -1569,6 +1572,33 @@ namespace expressions } } + public class ForLoopExpression : LoopExpression + { + Expression init_expr; + + constructor(Expression init_expr, Expression condition, Expression step_expr, Expression body) + { + this init_expr := init_expr; + this condition := condition; + + this body := CodeblockExpression.load(body, step_expr); + } + + declare(ExpressionScope scope) + { + init_expr.declare(scope); + + super.declare(scope); + } + + saveTo(List list, ExpressionScope scope, int index) + { + init_expr.saveTo(list, scope, 0); + + super.saveTo(list, scope, index); + } + } + public struct VariableByIndexExpression : Expression { int varIndex; @@ -1971,4 +2001,3 @@ namespace expressions } } } - diff --git a/src60/system/events.l b/src60/system/events.l index 042e9d2dc4..66d610e99b 100644 --- a/src60/system/events.l +++ b/src60/system/events.l @@ -30,7 +30,7 @@ public sealed EventHandler public field event { - override EventHandler name; + EventHandler name; set name(T f) { diff --git a/src60/system/exceptions.l b/src60/system/exceptions.l index 56475e0ac5..d8bafa9363 100644 --- a/src60/system/exceptions.l +++ b/src60/system/exceptions.l @@ -72,7 +72,7 @@ public class OutOfMemoryException : Exception public class InvalidArgumentException : Exception { constructor new() : info("Creates the exception") - <= new("Invalid argument"); + <= super new("Invalid argument"); constructor new(string argument) : info("Creates the exception") <= super new($"an invalid argument {argument}"); @@ -175,3 +175,12 @@ public class TypeLoaderException : Exception <= super new("Type " + className + " cannot be loaded"); } +// --- TypeLoaderException --- + +public class MessageLoaderException : Exception +{ + /// Creates the exception + constructor new(string messageName) + <= super new("Message " + messageName + " cannot be loaded"); +} + diff --git a/src60/system/inline_templates.l b/src60/system/inline_templates.l index f8ca3de42f..954b27beb1 100644 --- a/src60/system/inline_templates.l +++ b/src60/system/inline_templates.l @@ -32,10 +32,34 @@ public inline preloaded() #let preloadedSymbols += __decl; } +// --- importing --- + +public inline importing(libraryName) +{ + #import __decl = libraryName; +} + // --- prop --- +public field prop +{ + T field_name; + + get T prop_name() + { + ^ field_name + } + + set prop_name(T value) + { + field_name := value + } +} + public field prop { + T name; + get T name() { ^ name @@ -49,6 +73,8 @@ public field prop public field prop { + T name; + get name() { ^ name @@ -62,8 +88,20 @@ public field prop // --- rprop --- +public field rprop +{ + T field_name; + + get T prop_name() + { + ^ field_name + } +} + public field rprop { + T name; + get T name() { ^ name @@ -72,6 +110,8 @@ public field rprop public field rprop { + T name; + get name() { ^ name @@ -80,8 +120,34 @@ public field rprop // --- dto_prop --- +public field dto_prop +{ + T field_name; + + get T prop_name() + { + ^ field_name + } + + set prop_name(T value) + { + field_name := value + } + + const subject[] __dto_properties; + + this __dto_properties += mssg prop_name; + + static MessageName[] __dto_properties() + { + ^ __dto_properties + } +} + public field dto_prop { + T name; + get T name() { ^ name diff --git a/src60/system/io/files.l b/src60/system/io/files.l index dba97a6d2b..32f97eb1ef 100644 --- a/src60/system/io/files.l +++ b/src60/system/io/files.l @@ -21,7 +21,7 @@ namespace io TextReader textreader() = fileControl.newReader(_path); - TextWriter textwriter() = fileControl.writer(_path); + TextWriter textwriter() = fileControl.newWriter(_path); TextWriter logger() = fileControl.logger(_path); @@ -51,14 +51,14 @@ namespace io static saveContent(string path, string content) { - using(TextWriter writer := fileControl.writer(path)) { + using(TextWriter writer := fileControl.newWriter(path)) { writer.write(content); } } static saveContent(string path, string content, Encoder encoder) { - using(TextWriter writer := fileControl.writer(path, encoder)) { + using(TextWriter writer := fileControl.newWriter(path, encoder)) { writer.write(content); } } @@ -95,6 +95,13 @@ namespace io ^ output.Value } + + static TextWriter textwriter(string path) + = fileControl.newWriter(path); + + static TextReader textreader(string path) + = fileControl.newReader(path); + } // --- Directory --- diff --git a/src60/system/io/lnx_files.l b/src60/system/io/lnx_files.l index 805d715e9b..eebaf5e261 100644 --- a/src60/system/io/lnx_files.l +++ b/src60/system/io/lnx_files.l @@ -8,6 +8,10 @@ namespace io const int SEEK_CUR = 1; const int SEEK_END = 2; + const int S_IRWXU = 448; + const int S_IRGRP = 32; + const int S_IXGRP = 8; + // --- FileStream --- public struct FileStream : Stream { @@ -105,22 +109,22 @@ namespace io { TextReader newReader(path) = TextStreamReader.new(path); - TextWriter writer(path) = StreamWriter.new(FileStream.openForReWrite(path), UTF8Encoder); + TextWriter newWriter(path) = StreamWriter.new(FileStream.openForReWrite(path), UTF8Encoder); - TextWriter writer(string path, Encoder encoder) = StreamWriter.new(FileStream.openForReWrite(path), encoder); + TextWriter newWriter(string path, Encoder encoder) = StreamWriter.new(FileStream.openForReWrite(path), encoder); TextWriter logger(path) = StreamWriter.new(FileStream.openForAppend(path), UTF8Encoder); - bool isAvailable(path) + bool isAvailable(string path) { - int ret := extern libc.access(path as:String, F_OK); + int ret := extern libc.access(path, F_OK); ^ ret == 0 } - bool delete(path) + bool delete(string path) { - int ret := extern libc.remove(path as::String); + int ret := extern libc.remove(path); ^ ret == 0 } @@ -128,13 +132,28 @@ namespace io singleton directoryControl { - bool isAvailable(path) + create(string path) + { + int ret := extern libc.mkdir(path, S_IRWXU|S_IRGRP|S_IXGRP); + + if(ret != 0) + { IOException.new("Cannot create a directory").raise() } + } + + bool delete(string path) + { + int ret := extern libc.rmdir(path); + + ^ ret == 0 + } + + bool isAvailable(string path) { - string s := path as::String; - if:not(s.endingWith("/")) - s := s + "/"; + string s := path; + if:not(path.endingWith("/")) + s := path + "/"; - int ret := extern libc.access(s, F_OK); + int ret := extern libc.access(path, F_OK); ^ ret == 0 } diff --git a/src60/system/io/memorystream.l b/src60/system/io/memorystream.l index 161461e695..7105cd1130 100644 --- a/src60/system/io/memorystream.l +++ b/src60/system/io/memorystream.l @@ -176,6 +176,11 @@ namespace io self.write(array, index, length) } + constructor load(byte[] array) + { + self.write(array, 0, array.Length) + } + write(byte[] dump, int length) { _buffer.write(0, length, dump) @@ -188,13 +193,18 @@ namespace io int read(byte[] dump, int len) { + int totalLen := _buffer.Length; int pos := _position.Value; - _buffer.read(pos, len, dump); + int actualLen := len; + if (len > totalLen - pos) + actualLen := totalLen - pos; + + _buffer.read(pos, actualLen, dump); - _position.append(len); + _position.append(actualLen); - ^ len + ^ actualLen } int Index diff --git a/src60/system/io/win_files.l b/src60/system/io/win_files.l index ba6cc5a98b..47302bbe4e 100644 --- a/src60/system/io/win_files.l +++ b/src60/system/io/win_files.l @@ -143,9 +143,9 @@ namespace io { TextReader newReader(path) = TextStreamReader.new(path); - TextWriter writer(path) = StreamWriter.new(FileStream.openForReWrite(path), UTF8Encoder); + TextWriter newWriter(path) = StreamWriter.new(FileStream.openForReWrite(path), UTF8Encoder); - TextWriter writer(string path, Encoder encoder) = StreamWriter.new(FileStream.openForReWrite(path), encoder); + TextWriter newWriter(string path, Encoder encoder) = StreamWriter.new(FileStream.openForReWrite(path), encoder); TextWriter logger(path) = StreamWriter.new(FileStream.openForAppend(path), UTF8Encoder); @@ -201,7 +201,7 @@ namespace io { IOException.new("Cannot create a directory").raise() } } - delete(path) + bool delete(path) { wide s := cast wide(path); // !! temporal diff --git a/src60/system/object.l b/src60/system/object.l index 49af066d63..2ea921cd90 100644 --- a/src60/system/object.l +++ b/src60/system/object.l @@ -9,7 +9,7 @@ public class Object const __ptr __packageInfo := $reference __decl; constructor() - : info("Creates the object") + : info("Creates an object") { } diff --git a/src60/system/pointers.l b/src60/system/pointers.l index fb123d0c79..13130ede21 100644 --- a/src60/system/pointers.l +++ b/src60/system/pointers.l @@ -148,6 +148,60 @@ public sealed const struct UnsafePointer copyTo(byte[] target, int index, int len) : external(system'core_routines'__ptrCopySubTo); } +// --- UnsafePointer --- + +public sealed const struct UnsafePointer +{ + embeddable __ptr _pointer; + + private assignPtr(object obj) : external(system'core_routines'__assignPtr); + private loadData(T target, int size) : external(system'core_routines'__ptrCopyTo); + + constructor() + = default; + + constructor(UnsafePointer ptr) + { + _pointer := ptr + } + + constructor(T obj) + { + self.assignPtr(obj); + } + + get T Value() + { +#if ($size class T > 0) + + T value := default; + + self.loadData(value, $size class T); + +#elif ($size class T <= 0) + T value := nil; + + NotSupportedException.raise("Operation is not supported"); + +#endif + + ^ value + } + + copyTo(T value, int size) + { +#if ($size class T >= 0) + + NotSupportedException.raise("Operation is not supported"); + +#elif ($size class T < 0) + + self.loadData(value, size); + +#endif + } +} + // --- CallStack --- public sealed class CallStack @@ -191,5 +245,5 @@ public sealed class CallStack }; ^ callStackText - } + } } diff --git a/src60/system/predefined/predefined.l b/src60/system/predefined/predefined.l index 419729b861..d9226a12fb 100644 --- a/src60/system/predefined/predefined.l +++ b/src60/system/predefined/predefined.l @@ -7,3 +7,4 @@ #let defaults["__decl"] := 80000082h; #let defaults["super"] := 80000083h; #let defaults["__received"] := 80000084h; +#let defaults["__project"] := 80000085h; diff --git a/src60/system/routines/enumerables.l b/src60/system/routines/enumerables.l index 6e1dc19770..c1f741c717 100644 --- a/src60/system/routines/enumerables.l +++ b/src60/system/routines/enumerables.l @@ -192,6 +192,9 @@ public extension enumerableOp top(counter) = TopFilter.new(cast int(counter), cast Enumerator(self.enumerator())); + coundDown() + = CountDownEnumerator.new(self); + joinBy(object list, Func2 filter_f, Func2 select_f) = JoinEnumerator.new(filter_f, select_f, cast Enumerator(self.enumerator()), cast Enumerator(list.enumerator())); diff --git a/src60/system/routines/patterns.l b/src60/system/routines/patterns.l index 6a6b8c6f5b..0a47782103 100644 --- a/src60/system/routines/patterns.l +++ b/src60/system/routines/patterns.l @@ -678,6 +678,48 @@ public class RangeEnumerator : Enumerator enumerable() = _variable; } +// -- CountDownEnumerator --- + +public class CountDownEnumerator : Enumerator +{ + Reference _current; + int _count; + bool _start; + + constructor new(int count) + { + _count := count; + _current := count; + _start := true + } + + reset() + { + _current.Value := _count; + _start := true + } + + get int Value() + = *_current; + + bool next() + { + if (_start) { + _start := false; + + ^ true + } + else _current.reduce(1); + + ^ *_current > 0 + } + + Enumerator cast() = new Enumerator { embeddable dispatch() => self; }; + + enumerable() + = _count; +} + // --- ZipEnumerator --- public class ZipEnumerator : Enumerator diff --git a/src60/system/routines/sorting.l b/src60/system/routines/sorting.l index 12e5dd8c4e..df8c8f6828 100644 --- a/src60/system/routines/sorting.l +++ b/src60/system/routines/sorting.l @@ -12,6 +12,24 @@ public interface SortingAgent abstract setAt(int index, object value); abstract exchange(int i, int j); + + abstract move(int i, int j); +} + +public interface SortingAgent +{ + abstract int Length + { + get(); + } + + abstract T at(int index); + + abstract setAt(int index, T value); + + abstract exchange(int i, int j); + + abstract move(int i, int j); } public sealed ArraySortingAgent : SortingAgent @@ -47,6 +65,11 @@ public sealed ArraySortingAgent : SortingAgent a[i]:= a[j]; a[j] := tmp } + + move(int i, int j) + { + a[i]:= a[j]; + } } public sealed IndexerSortingAgent : SortingAgent @@ -98,6 +121,56 @@ public sealed IndexerSortingAgent : SortingAgent a.Index := i; a.Value := vj } + + move(int i, int j) + { + a.Index := j; + var vj := *a; + + a.Index := i; + a.Value := vj + } +} + +public class ArraySortingAgent : SortingAgent +{ + T[] _array; + + constructor(T[] array) + { + _array := array + } + + + int Length + { + get() + { + int len := _array.Length; + + ^ len + } + } + + T at(int index) + = _array[index]; + + setAt(int index, T value) + { + _array[index] := value + } + + exchange(int i, int j) + { + T tmp := _array[i]; + _array[i] := _array[j]; + _array[j] := tmp + } + + move(int i, int j) + { + _array[i] := _array[j]; + } } public singleton QuickSorting diff --git a/src60/system/system.linux.prj b/src60/system/system.linux.prj index 7a0409c9cd..ca74a2dc23 100644 --- a/src60/system/system.linux.prj +++ b/src60/system/system.linux.prj @@ -21,6 +21,17 @@
    + + + ../../lib60_64 + + + + calendar/lnx64_datetime.l + calendar/dates.l + + + ../../lib60_64 @@ -50,7 +61,7 @@ ELENA Standard Library - 6.6.2 + 6.6.9 Aleksey Rakov @@ -99,9 +110,11 @@ math/math.l text/encoding.l text/textbuffer.l + text/base64.l io/common.l io/streamreader.l io/streamwriter.l + io/memorystream.l io/lnx_console.l io/files.l io/ioexceptions.l diff --git a/src60/system/system.prj b/src60/system/system.prj index 9e64a83957..b761778481 100644 --- a/src60/system/system.prj +++ b/src60/system/system.prj @@ -18,7 +18,7 @@ ELENA Standard Library - 6.6.3 + 6.6.9 Aleksey Rakov @@ -72,6 +72,7 @@ text\encoding.l text\win_encoding.l text\textbuffer.l + text\base64.l io\common.l io\streamreader.l io\streamwriter.l diff --git a/src60/system/text/base64.l b/src60/system/text/base64.l new file mode 100644 index 0000000000..8d92d5674f --- /dev/null +++ b/src60/system/text/base64.l @@ -0,0 +1,278 @@ +namespace text +{ + import system'io; + + internal const byte[] base_map = new byte[] + { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 + }; + + public singleton Base64Encoding + { + internal int encoding(byte[] src, int src_index, ref int src_len, byte[] dest, int dest_len) + { + byte[] map := base_map; // !! temporally + + int buffer_index := 0; + byte buffer[4]; + + int len := src_len; + int end := src_index + len; + int dest_index := 0; + for (int i := src_index; i < end; i++) { + buffer[buffer_index] := src[i]; + buffer_index++; + + if (buffer_index == 3) { + dest[dest_index] := map[buffer[0] shr:2]; dest_index++; + dest[dest_index] := map[((buffer[0] & 3) shl:4) + (buffer[1] shr:4)]; dest_index++; + dest[dest_index] := map[((buffer[1] & 0Fh) shl:2) + (buffer[2] shr:6)]; dest_index++; + dest[dest_index] := map[buffer[2] & 3Fh]; dest_index++; + buffer_index := 0; + + if (dest_len - dest_index < 5) { + src_len := end - i; + + :break; + } + } + }; + + if (buffer_index > 0) { + dest[dest_index] := map[buffer[0] shr:2]; dest_index++; + if (buffer_index == 1) { + dest[dest_index] := map[((buffer[0] & 3) shl:4)]; dest_index++; + dest[dest_index] := 61; dest_index++; + } + else { + dest[dest_index] := map[((buffer[0] & 3) shl:4) + (buffer[1] shr:4)]; dest_index++; + dest[dest_index] := map[(buffer[1] & 0Fh) shl:2]; dest_index++; + }; + dest[dest_index] := 61; dest_index++; + }; + + ^ dest_index + } + + internal int decoding(byte[] src, int src_index, ref int src_len, byte[] dest, int dest_len) + { + byte[] map := base_map; // !! temporally + + byte buffer_index := 0; + byte buffer[4]; + + int len := src_len; + int end := src_index + len; + int dest_index := 0; + for (int i := src_index; i < end; i++) { + int map_index := 0; + while (map_index < 64) { + if (map[map_index] == src[i]) { + :break; + }; + + map_index++; + }; + + buffer[buffer_index] := map_index; buffer_index++; + if (buffer_index == 4) { + dest[dest_index] := (buffer[0] shl:2) + (buffer[1] shr:4); dest_index++; + if (buffer[2] != 64) { + dest[dest_index] := (buffer[1] shl:4) + (buffer[2] shr:2); dest_index++; + }; + if (buffer[3] != 64) { + dest[dest_index] := (buffer[2] shl:6) + buffer[3]; dest_index++; + }; + buffer_index := 0; + + if (dest_len - dest_index < 5) { + src_len := end - i; + + :break; + } + } + }; + + ^ dest_index; + } + + string toString(int index, int size, byte[] buffer) + { + auto builder := new StringBuilder(); + byte tmp[1024]; + int tmp_len := 1024; + int len := size; + int src_index := index; + while (len > 0) { + if (len < 1024) { + tmp_len := len; + } + else tmp_len := 1024; + + int dest_len := encoding(buffer, src_index, tmp_len, tmp, 1024); + builder.write(tmp, 0, dest_len); + len -= tmp_len; + src_index += tmp_len; + }; + + ^ *builder; + } + + int fromString(string s, MemoryBuffer output) + { + int saved := 0; + int len := s.Length; + + byte dest_tmp[1024]; + byte tmp[1024]; + int tmp_len := 1024; + int src_index := 0; + while (len > 0) { + if (len < 1024) { + tmp_len := len; + } + else tmp_len := 1024; + + s.saveToByteArray(src_index, tmp, tmp_len); + + int dest_len := decoding(tmp, 0, tmp_len, dest_tmp, 1024); + output.write(0, dest_len, dest_tmp); + saved += dest_len; + + src_index += tmp_len; + len -= tmp_len; + }; + + ^ saved; + } + + encode(int index, int length, byte[] src, MemoryBuffer output) + { + byte tmp[1024]; + int tmp_len := 1024; + int src_index := index; + int len := length; + while (len > 0) { + if (len < 1024) { + tmp_len := len; + } + else tmp_len := 1024; + + int dest_len := encoding(src, 0, ref tmp_len, tmp, 1024); + output.write(0, dest_len, tmp); + + src_index += tmp_len; + len -= tmp_len; + }; + } + + decode(int index, int length, byte[] src, MemoryBuffer output) + { + byte tmp[1024]; + int tmp_len := 1024; + int src_index := index; + int len := length; + while (len > 0) { + if (len < 1024) { + tmp_len := len; + } + else tmp_len := 1024; + + int dest_len := decoding(src, 0, ref tmp_len, tmp, 1024); + output.write(0, dest_len, tmp); + + src_index += tmp_len; + len -= tmp_len; + }; + } + + byte[] fromString(string s) + { + auto output := MemoryBuffer.allocate(s.Length); + + fromString(s, output); + + ^ *output + } + } + + public sealed singleton Base64Encoder : Encoder + { + int convertFrom(byte[] byteArray, int index, ref int len, char[] output, int outputIndex, int outputLen) + { + auto dest_output := MemoryBuffer.allocate(len); + + byte tmp[1024]; + int tmp_len := 1024; + + int src_len := len; + int src_index := index; + while (src_len > 0) { + if (src_len < 1024) { + tmp_len := src_len; + } + else tmp_len := 1024; + + int dest_len := Base64Encoding.encoding(byteArray, src_index, ref tmp_len, tmp, 1024); + dest_output.write(0, dest_len, tmp); + + len -= src_len; + src_index += src_len; + }; + + int total_len := dest_output.Length; + + ^ UTF8Encoder.convertFrom(*dest_output, 0, ref total_len, output, outputIndex, outputLen); + } + + int convertTo(char[] chars, int index, ref int len, byte[] output, int outputIndex, int outputLen) + { + auto temp_buffer := MemoryBuffer.allocate(outputLen); + + int maximalSize := outputLen; + + byte tmp[1024]; + int tmp_len := 1024; + int src_len := len; + int src_index := 0; + while (src_len > 0) { + if (maximalSize < 1024) { + tmp_len := maximalSize; + } + else tmp_len := 1024; + + int sub_len := src_len; + int byte_len := UTF8Encoder.convertTo(chars, src_index, ref sub_len, tmp, 0, tmp_len); + + maximalSize -= byte_len; + + temp_buffer.write(0, byte_len, tmp); + + src_index += sub_len; + src_len -= sub_len; + }; + + int temp_buffer_len := temp_buffer.Length; + int convered := Base64Encoding.decoding(*temp_buffer, 0, ref temp_buffer_len, tmp, 1024); + + Array.copyTo(output, *temp_buffer, outputIndex, temp_buffer_len); + + ^ temp_buffer_len; + } + + int convertChar(char ch, byte[] byteArray, int index) + { + NotSupportedException.raise(); + + ^ 0 + } + + char convertToChar(byte[] byteArray, int index, ref int sourLen) + { + NotSupportedException.raise(); + + ^ 0 + } + } +} \ No newline at end of file diff --git a/src60/system/text/encoding.l b/src60/system/text/encoding.l index 7db4535919..be03a8ce0a 100644 --- a/src60/system/text/encoding.l +++ b/src60/system/text/encoding.l @@ -1,5 +1,7 @@ namespace text { + import system'io; + // --- Encoder --- public interface Encoder { @@ -121,6 +123,32 @@ namespace text ^ String.fromByteArray(index, size, buffer); } + string toString(MemoryBuffer buffer) + <= toString(0, buffer.Length, *buffer); + + int fromString(string sour, MemoryBuffer output) + { + byte tmp[1024]; + int len := sour.Length; + int tmp_len := 1024; + int index := 0; + while (len > 0) { + if (len < 1024) { + tmp_len := len; + } + else tmp_len := 1024; + + sour.saveToByteArray(index, tmp, tmp_len); + + output.write(0, tmp_len, tmp); + + len -= tmp_len; + index += tmp_len; + }; + + ^ index + } + int getCharCount(string s) { int len := 0; @@ -131,6 +159,20 @@ namespace text ^ len } + + int getSubStringCharCount(string s, int index, int length) + { + int i := index; + int len := 0; + int end := index + length; + while (i < end) { + i += s[index].Length; + + len += 1; + }; + + ^ len + } } // --- UTF16Encoding --- diff --git a/src60/system/text/textbuffer.l b/src60/system/text/textbuffer.l index 0a1394739d..bdc906168d 100644 --- a/src60/system/text/textbuffer.l +++ b/src60/system/text/textbuffer.l @@ -41,7 +41,7 @@ namespace text } char[] cast() - = _buffer; + = ::Array.copy(_buffer, 0, *_length); string cast() = String.copy(0, *_length, _buffer); @@ -53,7 +53,7 @@ namespace text { ^ WideString.copy(0, _length.Value, _buffer); } - + wide cast() = WideString.copy(0, *_length, _buffer); @@ -506,6 +506,44 @@ namespace text _length.append(counter) } + writeSubstring(string s, int index, int length) + { + int counter := UTF8Encoding.getSubStringCharCount(s, index, length); + self.reserve(counter); + + int s_len := length; + UTF8Encoder.toByteArray(s, index, ref s_len, _buffer, *_length, ref counter); + + _length.append(counter) + } + + internal write(byte[] src, int index, int src_len) + { + if (index == 0) { + Array.copyTo(_buffer, src, *_length, src_len); + _length.append(src_len) + } + else { + byte tmp[1024]; + int len := src_len; + int tmp_len := 1024; + int s_index := index; + while (len > 0) { + if (len < 1024) { + tmp_len := len; + } + else tmp_len := 1024; + + Array.copy(tmp, src, s_index, tmp_len); + Array.copyTo(_buffer, tmp, *_length, tmp_len); + _length.append(tmp_len); + + s_index += tmp_len; + len -= tmp_len; + } + } + } + write(o) <= write(o.toPrintable()); diff --git a/src60/system/winforms/win_windows.l b/src60/system/winforms/win_windows.l index 0c4884ae11..d6c6c58486 100644 --- a/src60/system/winforms/win_windows.l +++ b/src60/system/winforms/win_windows.l @@ -57,6 +57,10 @@ public closed class WindowCallback { } + onChange(Handle control) + { + } + onSize(Handle control, int width, int height) { } @@ -100,6 +104,8 @@ public closed class WindowCallback if (command == BN_CLICKED) { self.onClick(control); ^ self }; + if (command == EN_CHANGE) + { self.onChange(control); ^ self }; } onWMClose(Handle hwnd) diff --git a/src60/textgen/extensions.l b/src60/textgen/extensions.l new file mode 100644 index 0000000000..358c766077 --- /dev/null +++ b/src60/textgen/extensions.l @@ -0,0 +1,17 @@ +import system'text; +import extensions'scripting; + +public extension textGenOp +{ + string generateFrom(string script) + { + string full_script := ScriptGenerator.parse(script); + auto output := new StringBuilder(); + + var function := LScript.eval(full_script).program; + + function(self, output); + + ^ *output + } +} diff --git a/src60/textgen/parser.l b/src60/textgen/parser.l new file mode 100644 index 0000000000..53bf75c7ae --- /dev/null +++ b/src60/textgen/parser.l @@ -0,0 +1,74 @@ +import system'text; + +singleton ScriptGenerator +{ + private writeOutput(StringBuilder fullScript, string script, int start, int index) + { + if (start == index) + :break; + + fullScript.write("output.write("""); + fullScript.writeSubstring(script, start, index - start); + fullScript.write(""");"); + } + + private writeExpression(StringBuilder fullScript, string script, int start, int index) + { + fullScript.write("output.write("); + fullScript.writeSubstring(script, start, index - start); + fullScript.write(");"); + } + + string parse(string script) + { + int length := script.Length; + + auto fullScript := new StringBuilder(); + fullScript.write("program(self, output) { "); + + int start := 0; + + while (start < length) { + int index := script.indexOf(start, "<="); + if (index >= 0) { + fullScript.writeSubstring(script, start, index - start); + + start := index + 2; + index := script.indexOf(start, "=>"); + + if (index >= 0) { + int injectIndex := script.indexOf(start, "{"); + while (injectIndex > 0 && injectIndex < index) { + if (injectIndex > start) { + writeOutput(fullScript, script, start, injectIndex); + }; + + start := script.indexOf(start, "}"); + if (start == -1 || start > index) + InvalidArgumentException.raise("script"); + + writeExpression(fullScript, script, injectIndex + 1, start); + + injectIndex := script.indexOf(start, "{"); + + start++ + }; + + writeOutput(fullScript, script, start, index); + + start := index + 2; + } + else InvalidArgumentException.raise("script"); + } + else { + fullScript.writeSubstring(script, start, length - start); + + start := length; + } + }; + + fullScript.write(" }"); + + ^ *fullScript + } +} \ No newline at end of file diff --git a/src60/textgen/textgen.prj b/src60/textgen/textgen.prj new file mode 100644 index 0000000000..a6c2e91762 --- /dev/null +++ b/src60/textgen/textgen.prj @@ -0,0 +1,29 @@ + + + + ..\..\lib60 + + + + + ..\..\lib60_64 + + + + + parser.l + extensions.l + + + + ELENA TextGen Library + 6.6.1 + Aleksey Rakov + + + + + textgen + + + \ No newline at end of file diff --git a/src60/xml/xml.linux.prj b/src60/xml/xml.linux.prj new file mode 100644 index 0000000000..eba5b5a9a2 --- /dev/null +++ b/src60/xml/xml.linux.prj @@ -0,0 +1,46 @@ + + + + ../../lib60 + + + + + ../../lib60_64 + + + + + ../../lib60_64 + + + + + ../../lib60_64 + + + + + ../../lib60_64 + + + + + xmlnode.l + xmldoc.l + xmlformatter.l + xmlreader.l + + + + ELENA XML Library + 6.6.1 + Aleksey Rakov + + + + + xml + + + \ No newline at end of file diff --git a/src60/xml/xml.prj b/src60/xml/xml.prj new file mode 100644 index 0000000000..39c659693b --- /dev/null +++ b/src60/xml/xml.prj @@ -0,0 +1,31 @@ + + + + ..\..\lib60 + + + + + ..\..\lib60_64 + + + + + xmlnode.l + xmldoc.l + xmlformatter.l + xmlreader.l + + + + ELENA XML Library + 6.6.2 + Aleksey Rakov + + + + + xml + + + \ No newline at end of file diff --git a/src60/xml/xmldoc.l b/src60/xml/xmldoc.l new file mode 100644 index 0000000000..a7c004f557 --- /dev/null +++ b/src60/xml/xmldoc.l @@ -0,0 +1,126 @@ +import system'collections; +import system'text; +import system'io; + +public interface IXmlFormatter +{ + abstract openTag(TextWriter output, int level, XmlNode node); + + abstract writeElement(TextWriter output, int level, XmlNode node); + + abstract closeTag(TextWriter output, int level, XmlNode node); +} + +public interface IXmlReader +{ + abstract read(); + + get abstract bool isAvailable(); + + get abstract bool isOpenTag(); + + get abstract bool isCloseTag(); + + get abstract bool isContent(); + + get abstract string Name(); + + get abstract string Content(); +} + +public class XmlDocument +{ + XmlNode _root; + + constructor new(XmlNode root) + { + _root := root; + } + + constructor new() + { + } + + load(IXmlReader reader) + { + Stack nodes := new Stack(); + + reader.read(); + while(reader.isAvailable) { + if (reader.isOpenTag) { + XmlNode node := XmlNode.newNode(reader.Name); + + nodes.push(node); + } + else if(reader.isCloseTag) { + XmlNode node := nodes.pop(); + if (nodes.Length > 0) { + nodes.peek().appendChild(node) + } + else if:not:nil(_root) { + InvalidOperationException.raise("The XML can have only one root element"); + } + else _root := node; + } + else if (reader.isContent) { + nodes.peek().setContent(reader.Content); + }; + + reader.read(); + } + } + + save(IXmlFormatter formatter, TextWriter output) + { + Stack stack := new Stack(); + + int level := 0; + stack.push(_root); + while (stack.Length > 0) { + XmlNode node := stack.pop(); + if:not:nil(node) { + if (node.ChildCounter > 0) { + level++; + formatter.openTag(output, level, node); + + stack.push(node); + stack.push(nil); + + XmlNode child := node.firstChild(); + if:not:nil(child) + stack.push(child); + } + else { + formatter.writeElement(output, level + 1, node); + + XmlNode next := node.nextSibling(); + if:not:nil(next) + stack.push(next); + } + } + else { + node := stack.pop(); + + formatter.closeTag(output, level, node); + level--; + + XmlNode next := node.nextSibling(); + if:not:nil(next) + stack.push(next); + } + }; + } + + XmlNode findNode(string xpath) + { + if (xpath[0]==$47) { + string current, string subpath := XmlNode.parseXPath(1, xpath); + + if (_root.Name == current) { + ^ _root.findChild(subpath) + }; + }; + + ^ nil; + } +} \ No newline at end of file diff --git a/src60/xml/xmlformatter.l b/src60/xml/xmlformatter.l new file mode 100644 index 0000000000..b7305edc34 --- /dev/null +++ b/src60/xml/xmlformatter.l @@ -0,0 +1,48 @@ +import system'io; + +public singleton TabXmlFormatter : IXmlFormatter +{ + openTag(TextWriter output, int level, XmlNode node) + { + for (int i := 1; i < level; i++) + output.write($9); + + output.write("<"); + output.write(node.Name); + output.writeLine(">") + } + + writeElement(TextWriter output, int level, XmlNode node) + { + for (int i := 1; i < level; i++) + output.write($9); + + if:not:nil(node.Content) { + output.write("<"); + output.write(node.Name); + output.write(">"); + + output.write(node.Content); + + output.write("") + } + else { + output.write("<"); + output.write(node.Name); + output.writeLine("/>") + } + } + + closeTag(TextWriter output, int level, XmlNode node) + { + for (int i := 1; i < level; i++) + output.write($9); + + output.write("") + } + +} \ No newline at end of file diff --git a/src60/xml/xmlnode.l b/src60/xml/xmlnode.l new file mode 100644 index 0000000000..db6142821b --- /dev/null +++ b/src60/xml/xmlnode.l @@ -0,0 +1,178 @@ +import system'collections; + +public class XmlNode +{ + XmlNode _parent; + + List> _attributes; + List _children; + + string Name : rprop(_name); + + string Content : rprop(_content); + + appendChild(XmlNode child) + { + if:not:nil(_content) + InvalidOperationException.raise("The node has already content"); + + _children.append(child); + + child.setParent(self); + } + + internal setParent(XmlNode parent) + { + if:not:nil(_parent) + InvalidOperationException.raise("The node has already a parent"); + + _parent := parent + } + + internal setContent(string content) + { + if(_children.Length > 0) { + InvalidOperationException.raise("The node has children"); + }; + + _content := content + } + + static XmlNode newElement(string name, string value) + { + auto node := XmlNode.new(nil, name, value); + + ^ node + } + + static XmlNode newNode(string name, params XmlNode[] children) + { + auto node := XmlNode.new(nil, name); + for (int i := 0; i < children.Length; i++) { + node.appendChild(children[i]); + }; + + ^ node + } + + internal int getChildIndex(XmlNode child) + { + for (int i := 0; i < _children.Length; i++) { + if (child.equalReference(_children[i])) { + ^ i; + } + }; + + ^ -1 + } + + internal XmlNode getChild(int index) + = _children[index]; + + get int ChildCounter() + = _children.Length; + + internal static ::(string, string) parseXPath(int index, string xpath) + { + int separator := xpath.indexOf(index, $47); + if (separator != -1) { + ^ (xpath.Substring(index, separator - index), xpath.Substring(separator + 1)); + }; + + ^ (xpath.Substring(index), String.MinValue); + } + + XmlNode findChild(string xpath) + { + if (xpath == String.MinValue) + { + ^ self + }; + + string current, string subpath := XmlNode.parseXPath(0, xpath); + + if (current != _name) { + ^ nil + }; + + for (int i := 0; i < _children.Length; i++) { + auto node := _children[i].findChild(subpath); + if:not:nil(node) { + ^ node + } + }; + + ^ nil + } + + XmlNode nextSibling() + { + if:nil(_parent) + { + ^ nil; + }; + + int index := _parent.getChildIndex(self); + int length := _parent.ChildCounter; + + index += 1; + if (index < length) { + ^ _parent.getChild(index) + }; + + ^ nil + } + + XmlNode previousSibling() + { + if:nil(_parent) + { ^ nil }; + + int index := _parent.getChildIndex(self); + + if (index > 0) { + ^ _parent.getChild(index - 1) + }; + + ^ nil + } + + XmlNode firstChild() + { + if (_children.Length == 0) { + ^ nil + }; + + ^ _children[0] + } + + XmlNode lastChild() + { + if (_children.Length == 0) { + ^ nil + }; + + ^ _children[_children.Length - 1] + } + + internal constructor new(XmlNode? parent, string name) + { + _attributes := new List>(); + _children := new List(); + _name := name; + + if:not:nil(parent) + parent.appendChild(self) + } + + internal constructor new(XmlNode? parent, string name, string content) + { + _attributes := new List>(); + _children := new List(); + _name := name; + _content := content; + + if:not:nil(parent) + parent.appendChild(self) + } +} diff --git a/src60/xml/xmlreader.l b/src60/xml/xmlreader.l new file mode 100644 index 0000000000..c92ee314c3 --- /dev/null +++ b/src60/xml/xmlreader.l @@ -0,0 +1,124 @@ +import system'io; + +const struct TokenType : enum(None ::= 0, Content ::= 1, OpenTag ::= 2, CloseTag ::= 3); + +public class XmlReader : IXmlReader +{ + TextReader input; + string currentLine; + Reference currentOffset; + Reference lineNumber; + bool available; + TokenType tokenMode; + string tagName; + string content; + + constructor open(TextReader input) + { + this input := input; + this currentOffset := 0; + this lineNumber := 0; + this available := true; + this currentLine := String.MinValue; + this tokenMode := TokenType.None; + } + + bool isAvailable + = available; + + bool isOpenTag + = tokenMode == TokenType.OpenTag; + + bool isCloseTag + = tokenMode == TokenType.CloseTag; + + bool isContent + = tokenMode == TokenType.Content; + + string Name + = tagName; + + get string Content() + { + if (tokenMode != TokenType.Content) { + ^ String.MinValue + }; + + ^ content; + } + + read() + { + if:not(available) + :break; + + int offs := *currentOffset; + if (offs >= currentLine.Length) { + if (!input.Available) { + available := false; + + :break; + }; + + currentLine := input.readLine(); + lineNumber.append(1); + currentOffset.Value := 0; + offs := 0; + + if (currentLine.isEmpty()) { + read(); + :break; + } + }; + + int start := offs; + while (currentLine[offs].isWhitespace()) + offs += currentLine[offs].Length; + + if (tokenMode == TokenType.OpenTag && currentLine[offs] != $60) { + tokenMode := TokenType.Content; + + while (currentLine[offs] != $60) { + offs += currentLine[offs].Length; + }; + + content := currentLine.Substring(start, offs - start); + } + else { + while (currentLine[offs].isWhitespace()) + offs += currentLine[offs].Length; + + if (currentLine[offs] != $60) + InvalidOperationException.raise($"Invalid xml line:{lineNumber}"); + + offs += currentLine[offs].Length; + start := offs; + + if (currentLine[offs] == $47) { + tokenMode := TokenType.CloseTag; + + offs += currentLine[offs].Length; + start := offs; + } + else { + if (tokenMode == TokenType.Content) + InvalidOperationException.raise($"Invalid xml line:{lineNumber}"); + + tokenMode := TokenType.OpenTag; + }; + + while (currentLine[offs] != $62) { + if (currentLine[offs].isWhitespace()) + InvalidOperationException.raise($"Invalid xml line:{lineNumber}"); + + offs += currentLine[offs].Length; + }; + + tagName := currentLine.Substring(start, offs - start); + + offs++; + }; + + currentOffset := offs; + } +} \ No newline at end of file diff --git a/tests60/api_tests/api_tests.prj b/tests60/api_tests/api_tests.prj new file mode 100644 index 0000000000..5c8e662a24 --- /dev/null +++ b/tests60/api_tests/api_tests.prj @@ -0,0 +1,43 @@ + + + + api_tests.exe + + + + + api_tests64.exe + + + + + 4129 + + + + + 4130 + + + + + 4133 + + + + + 4132 + + + + api_tests + + + + + main.l + xml.l + textgen.l + + + \ No newline at end of file diff --git a/tests60/api_tests/main.l b/tests60/api_tests/main.l new file mode 100644 index 0000000000..965568fe79 --- /dev/null +++ b/tests60/api_tests/main.l @@ -0,0 +1,10 @@ +import ltests; + +public program() +{ + Console.writeLine("--- ELENA 6 API Functional Tests ---"); + + Engine.run(); + + Console.writeLine("--- Passed ---") +} \ No newline at end of file diff --git a/tests60/api_tests/textgen.l b/tests60/api_tests/textgen.l new file mode 100644 index 0000000000..bbf4ca8523 --- /dev/null +++ b/tests60/api_tests/textgen.l @@ -0,0 +1,16 @@ +import ltests; +import textgen; +import extensions; + +// == TEXTGEN tests == +// ======================= + +// --- ForLoopTest --- + +public textGen_ForLoopTest() : testCase() +{ + var actual := 5.generateFrom("for(var n := 0; n < self; n := n + 1) { <={n}=> }"); + + Assert.ifEqual(actual, "01234"); + Console.writeLine("."); +} \ No newline at end of file diff --git a/tests60/api_tests/xml.l b/tests60/api_tests/xml.l new file mode 100644 index 0000000000..1a7790ab60 --- /dev/null +++ b/tests60/api_tests/xml.l @@ -0,0 +1,75 @@ +import system'io; +import system'text; +import xml; +import extensions; +import extensions'text; +import ltests; + +// == XML Library tests == +// ======================= + +// --- LoadSave Tests --- + +const string XmlExpected1 = " + + Lydia Thomason + 25.64 + 1 + + + June Grath + 16.38 + 4 + + +"; + +public xmlLoadSaveTest() : testCase() +{ + XmlDocument doc := XmlDocument.new(); + + auto stream := MemoryStream.load(XmlExpected1.toByteArray()); + using(auto reader := TextStreamReader.new(stream, UTF8Encoder)) { + doc.load(XmlReader.open(reader)); + }; + + var actual := String.MinValue; + + using(auto writer := new StringWriter()) { + doc.save(TabXmlFormatter, writer); + + actual := writer.Value + }; + + Assert.ifEqual(actual, XmlExpected1); + Console.writeLine("."); +} + +public xmlBuildTest() : testCase() +{ + XmlDocument doc := XmlDocument.new( + XmlNode.newNode("Employees", + XmlNode.newNode("Employee", + XmlNode.newElement("FullName", "Lydia Thomason"), + XmlNode.newElement("Salary", "25.64"), + XmlNode.newElement("DepartmentID", "1") + ), + XmlNode.newNode("Employee", + XmlNode.newElement("FullName", "June Grath"), + XmlNode.newElement("Salary", "16.38"), + XmlNode.newElement("DepartmentID", "4") + ) + ) + ); + + var actual := String.MinValue; + + using(auto writer := new StringWriter()) { + doc.save(TabXmlFormatter, writer); + + actual := writer.Value + }; + + Assert.ifEqual(actual, XmlExpected1); + Console.writeLine("."); +} diff --git a/tests60/sandbox/sandbox.l b/tests60/sandbox/sandbox.l index 19d431ca04..5521e19e63 100644 --- a/tests60/sandbox/sandbox.l +++ b/tests60/sandbox/sandbox.l @@ -1,14 +1,7 @@ import extensions; -import extensions'scripting; - + +const byte[] base_map = new byte[] { 65, 66, 67 }; + public program() { - var t := new ScriptEngine() - .loadScript("[[ #grammar build ]]") - .loadPath("~\scripts\grammar60.es") - .loadPath("~\scripts\lscript60.es"); - - var o := t.buildScript("import extensions; public program() { console.printLine(""Hello World"") }"); - - o.eval(); -} +} \ No newline at end of file diff --git a/tests60/script_tests/basic.l b/tests60/script_tests/basic.l index d7dcc958ae..242bfd904c 100644 --- a/tests60/script_tests/basic.l +++ b/tests60/script_tests/basic.l @@ -4,7 +4,7 @@ import ltests; public evalTest() : testCase() { - var ret := lscript.interpretLine("""Hello "".add(""World"")"); + var ret := LScript.interpretLine("""Hello "".add(""World"")"); Assert.ifEqual(ret, "Hello World"); diff --git a/tests60/system_tests/basic.l b/tests60/system_tests/basic.l index 369a69bc65..65f71218ad 100644 --- a/tests60/system_tests/basic.l +++ b/tests60/system_tests/basic.l @@ -4,6 +4,7 @@ import system'dynamic; import system'dynamic'expressions; import system'text; import system'text'parsing; +import system'io; import ltests; // --- ControlTest --- @@ -67,6 +68,51 @@ public booleanTest() : testCase() // --- intTests --- +// --- intTests --- + +public byteTests() : testCase() +{ + byte n := 2; + byte m := 3; + byte k := 4; + byte l := 3; + + Assert.ifTrue(2 + 3 * 4 == 14); + Assert.ifTrue(n + m * k == 14); + Console.write("."); + Assert.ifFalse(n == m); + Assert.ifTrue(n == n); + Assert.ifTrue(n < m); + Assert.ifFalse(n > m); + Assert.ifTrue(n <= m); + Assert.ifTrue(n <= n); + Assert.ifTrue(n >= n); + Assert.ifFalse(n >= m); + Assert.ifFalse(m > l); + Assert.ifFalse(m < l); + Assert.ifTrue(m >= l); + Assert.ifTrue(m <= l); + Console.write("."); + + m := n + 3; + Assert.ifEqual(m, 5); + n := m - 2; + Assert.ifEqual(n, 3); + m := n * 4; + Assert.ifEqual(m, 12); + m := m / 3; + Assert.ifEqual(m, 4); + Console.write("."); + + n := 12; + n := n shr:2; + Assert.ifEqual(n, 3); + n := 12; + n := n shl:2; + Assert.ifEqual(n, 48); + Console.write("."); +} + public intTests() : testCase() { int n := 2; @@ -2448,3 +2494,23 @@ public regExTest() : testCase() Assert.ifFalse(regex7.match("http")); Console.write("."); } + +public base64EncodingTest() : testCase() +{ + auto source := "Standard comparison operations are defined for all the primitive numeric types."; + auto expected := "U3RhbmRhcmQgY29tcGFyaXNvbiBvcGVyYXRpb25zIGFyZSBkZWZpbmVkIGZvciBhbGwgdGhlIHByaW1pdGl2ZSBudW1lcmljIHR5cGVzLg=="; + + auto buffer := MemoryBuffer.allocate(); + UTF8Encoding.fromString(source, buffer); + var dest := Base64Encoding.toString(0, buffer.Length, *buffer); + + Assert.ifEqual(dest, expected); + Console.write("."); + + buffer.clear(); + Base64Encoding.fromString(dest, buffer); + + var decoded := UTF8Encoding.toString(buffer); + Assert.ifEqual(decoded, source); + Console.write("."); +} diff --git a/tests60/system_tests/main.l b/tests60/system_tests/main.l index 965568fe79..8777bc3ea1 100644 --- a/tests60/system_tests/main.l +++ b/tests60/system_tests/main.l @@ -2,7 +2,7 @@ import ltests; public program() { - Console.writeLine("--- ELENA 6 API Functional Tests ---"); + Console.writeLine("--- ELENA 6 System API Functional Tests ---"); Engine.run(); From f018341a546220f42f56570d872338cb04aacd8e Mon Sep 17 00:00:00 2001 From: arakov Date: Sun, 4 May 2025 19:14:42 +0200 Subject: [PATCH 51/53] fixing script --- build/elena_inno.iss | 2 +- scripts/aarch64/build_package_arm64.script | 0 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 scripts/aarch64/build_package_arm64.script diff --git a/build/elena_inno.iss b/build/elena_inno.iss index 2ddc96780f..5708affdd4 100644 --- a/build/elena_inno.iss +++ b/build/elena_inno.iss @@ -18,7 +18,7 @@ DefaultGroupName=ELENA Programming Language AllowNoIcons=yes LicenseFile=..\doc\license InfoAfterFile=..\CHANGELOG.md -OutputBaseFilename=elena-lang-6.6.3.x86-win-setup +OutputBaseFilename=elena-lang-6.7.0.x86-win-setup Compression=lzma SolidCompression=yes ChangesEnvironment=yes diff --git a/scripts/aarch64/build_package_arm64.script b/scripts/aarch64/build_package_arm64.script old mode 100644 new mode 100755 From 98d40af30ac11bb63260112f25c26643f05528ce Mon Sep 17 00:00:00 2001 From: arakov Date: Sun, 4 May 2025 19:18:56 +0200 Subject: [PATCH 52/53] fixing aarch64 code --- asm/aarch64/core60.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asm/aarch64/core60.asm b/asm/aarch64/core60.asm index 867ac29eaa..f4febff146 100644 --- a/asm/aarch64/core60.asm +++ b/asm/aarch64/core60.asm @@ -940,7 +940,7 @@ inline %034h end // ; dfree -inline % 16h +inline % 35h lsl x12, x9, #3 add x12, x12, #8 // ; rounding to 10h From d6a167a7f56b2fad0e6ff12d951011ed9b8ec572 Mon Sep 17 00:00:00 2001 From: arakov Date: Sun, 4 May 2025 19:23:21 +0200 Subject: [PATCH 53/53] adding missing x permission --- scripts/ppc64le/build_package_ppc64le.script | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/ppc64le/build_package_ppc64le.script diff --git a/scripts/ppc64le/build_package_ppc64le.script b/scripts/ppc64le/build_package_ppc64le.script old mode 100644 new mode 100755