From a92df96658731619a14143d6dbaac46489aff94a Mon Sep 17 00:00:00 2001 From: Aleksey Rakov Date: Sat, 19 Oct 2024 20:50:49 +0200 Subject: [PATCH] Iteration34 (#698) * [FIXED]fix opcode mov gs,r/m64 * resolving #696 comments & suggestions * some API code refactoring * working on #696 - linux version will look into the app path to try to retrieve data files * supporting relative paths #696 * removing unused variables * [FIXED]#696 : probable memory corruption by tree node operations * [REDUX]!! refactoring grammar to make it more readable * refactoring the compiler code to support parameterized method call * [ELENA][ADDED] support parameterized extension method call * [API][ADDED] extensions'routines'stex : toArray * fix encoder code (see an example with ConsoleFileWriter) * [FIXED]variadic argument list of super class is type-casted * refactoring api * fixing viardic message extension handler * [FIXED] #689: declaring a lambda function with template based argument * #696 : provide set of config files for Linux with relative paths * [FIXED] fixing issues ABI convention for external calls * fixing thread code invoker * [FIXED] preloaded symbols in sub namespaces * fixing byref handler retrieving routine * [FIXED] calling indexed method from the sealed class * [ADDED]new functional test : script_tests * fixing elt operation * [ADDED] new option -xs - Strict type enforcing option (raise an error if the sealed class is typecasted / called the method that does not exists) * #676 : supporting strict type flag in IDE Project Settings dialog * [ADDED] supporting multi-byte nop operand --------- Co-authored-by: Alex --- .github/workflows/msbuild.yml | 2 +- CHANGELOG.md | 20 + VERSION | 2 +- asm/aarch64/core60.asm | 4 +- asm/aarch64/core60_lnx.asm | 36 - asm/amd64/core60.asm | 42 +- asm/amd64/core60_lnx.asm | 49 +- asm/amd64/core60_win.asm | 45 - asm/amd64/core60_win_client.asm | 79 +- asm/amd64/corex60.asm | 619 ++++++++++- asm/ppc64le/core60.asm | 8 +- asm/ppc64le/core60_lnx.asm | 50 - asm/x32/core60.asm | 118 ++- asm/x32/core60_lnx.asm | 33 - asm/x32/core60_win.asm | 33 - asm/x32/core60_win_client.asm | 57 +- asm/x32/corex60.asm | 438 +++++++- bin/command60.es | 2 +- bin/local.elc60.config.bak | 54 + bin/scripts/jscript60.es | 2 +- bin/templates/local.lib60.config | 62 ++ build/aarch64/build_package_arm64.script | 2 +- build/aarch64/control | 2 +- build/amd64/build_package_amd64.script | 2 +- build/amd64/control | 2 +- build/elena_inno.iss | 6 +- build/i386/build_package_i386.script | 4 +- build/i386/control | 2 +- build/ppc64le/build_package_ppc64le.script | 2 +- build/ppc64le/control | 2 +- build/rebuild_lib60_x86.bat | 14 + dat/sg/syntax60.txt | 77 +- doc/api/extensions-routines-stex-summary.html | 54 + doc/api/extensions-routines-stex.html | 42 + doc/api/extensions-summary.html | 12 +- doc/api/extensions.html | 24 +- doc/api/system-io.html | 15 +- doc/api/system-summary.html | 56 +- doc/api/system.html | 188 ++-- doc/tech/bytecode60.txt | 6 +- doc/todo.txt | 21 +- elenasrc3/common/common.h | 29 +- elenasrc3/common/config.cpp | 8 + elenasrc3/common/config.h | 2 + elenasrc3/common/dump.cpp | 5 + elenasrc3/common/dump.h | 2 + elenasrc3/common/lists.h | 2 + elenasrc3/common/tree.h | 64 +- elenasrc3/elc/clicommon.h | 7 +- elenasrc3/elc/cliconst.h | 5 +- elenasrc3/elc/codeblocks/elc_amd64.mak | 5 +- elenasrc3/elc/codeblocks/elc_arm64.mak | 5 +- elenasrc3/elc/codeblocks/elc_i386.mak | 5 +- elenasrc3/elc/codeblocks/elc_linux_x86.cbp | 8 + elenasrc3/elc/codeblocks/elc_ppc64le.mak | 5 +- elenasrc3/elc/codeimage.cpp | 6 +- elenasrc3/elc/codeimage.h | 2 +- elenasrc3/elc/compiler.cpp | 966 +++++++++--------- elenasrc3/elc/compiler.h | 131 ++- elenasrc3/elc/compilerlogic.cpp | 109 +- elenasrc3/elc/compilerlogic.h | 5 + elenasrc3/elc/compiling.cpp | 29 +- elenasrc3/elc/derivation.cpp | 164 ++- elenasrc3/elc/derivation.h | 106 +- elenasrc3/elc/errors.h | 5 + elenasrc3/elc/linux/constants.h | 1 + elenasrc3/elc/linux/elc.cpp | 13 +- elenasrc3/elc/linux/elfarmimage.cpp | 2 +- elenasrc3/elc/linux/pathmanager.cpp | 77 ++ elenasrc3/elc/linux/pathmanager.h | 28 + elenasrc3/elc/messages.h | 10 +- elenasrc3/elc/parser.cpp | 12 +- elenasrc3/elc/project.cpp | 38 +- elenasrc3/elc/windows/elc.cpp | 3 + elenasrc3/elena-tests/bt_optimization.h | 14 +- elenasrc3/elena-tests/compile_tests.h | 6 + elenasrc3/elena-tests/scenario_consts.h | 3 +- .../elena-tests/tests_bt_optimization.cpp | 61 +- elenasrc3/elena-tests/tests_build.cpp | 10 +- elenasrc3/elena-tests/tests_common.cpp | 62 ++ elenasrc3/elena-tests/tests_common.h | 17 + elenasrc3/elena-tests/tests_compile.cpp | 42 + elenasrc3/elenart/elenartmachine.cpp | 4 +- elenasrc3/elenart/rtcommon.h | 2 +- elenasrc3/elenavm/elenavmmachine.cpp | 30 +- elenasrc3/elenavm/elenavmmachine.h | 4 +- elenasrc3/elenavm/vmcommon.h | 2 +- elenasrc3/elenavm/windows/dllmain.cpp | 3 + elenasrc3/engine/bcwriter.cpp | 61 +- elenasrc3/engine/buildtree.h | 2 + elenasrc3/engine/bytecode.cpp | 24 +- elenasrc3/engine/bytecode.h | 3 +- elenasrc3/engine/codescope.h | 8 +- elenasrc3/engine/core.h | 7 +- elenasrc3/engine/elena.h | 40 +- elenasrc3/engine/elenamachine.cpp | 14 +- elenasrc3/engine/elenamachine.h | 4 +- elenasrc3/engine/jitcompiler.cpp | 31 +- elenasrc3/engine/jitcompiler.h | 3 +- elenasrc3/engine/langcommon.h | 95 +- elenasrc3/engine/parsertable.h | 1 + elenasrc3/engine/projectbase.h | 1 + elenasrc3/engine/syntaxtree.h | 6 +- elenasrc3/engine/x86helper.h | 22 +- elenasrc3/ide/idecommon.h | 1 + elenasrc3/ide/idecontroller.cpp | 87 +- elenasrc3/ide/ideproject.cpp | 1 + elenasrc3/ide/ideproject.h | 3 + elenasrc3/ide/windows/Resource.h | 1 + elenasrc3/ide/windows/elide.rc | Bin 43690 -> 43924 bytes elenasrc3/ide/windows/windialogs.cpp | 26 +- elenasrc3/ide/windows/windialogs.h | 2 + elenasrc3/tools/asmc/asmconst.h | 2 +- elenasrc3/tools/asmc/x86assembler.cpp | 30 +- elenasrc3/tools/ecv/ecvconst.h | 2 +- elenasrc3/tools/ecv/ecviewer.cpp | 6 + elenasrc3/tools/elt/eltconst.h | 2 +- elenasrc3/tools/sg/sg.cpp | 36 +- elenasrc3/tools/sg/sgconst.h | 2 +- examples60/console/datetime/control.l | 12 +- examples60/console/helloworld/helloworld.es | 2 +- examples60/console/matrix/matrix.l | 12 +- examples60/console/pi2/pi2.l | 8 +- examples60/db/sqlite/main.l | 34 +- examples60/files/textdb/textdb.l | 4 +- examples60/files/textfile/textfile.l | 4 +- examples60/gui/c_a_g/calc_area_gui.l | 68 +- examples60/threads/threadpool/threadpool.l | 4 +- recompile60.bat | 2 +- src60/core/system.core_routines.esm | 63 +- src60/extensions/convertors.l | 38 +- src60/extensions/dynamic/json.l | 12 +- src60/extensions/formatter.l | 2 +- src60/extensions/random.l | 2 +- src60/extensions/routines/stex/convertors.l | 16 +- src60/forms/win32_controls.l | 10 +- src60/forms/win_forms.l | 2 +- src60/sqlite/common.l | 12 +- src60/system/app.l | 1 + src60/system/basic.l | 139 ++- src60/system/calendar/dates.l | 8 +- src60/system/calendar/lnx32_datetime.l | 8 +- src60/system/calendar/lnx64_datetime.l | 2 +- src60/system/collections/tuples.l | 120 +-- src60/system/convertors.l | 76 +- src60/system/dynamic/closure.l | 4 +- .../system/dynamic/expressions/expressions.l | 8 +- src60/system/dynamic/groups.l | 4 +- src60/system/dynamic/reflection.l | 4 +- src60/system/extensions.l | 38 +- src60/system/io/files.l | 7 + src60/system/io/lnx_console.l | 2 +- src60/system/io/lnx_files.l | 6 +- src60/system/io/streamwriter.l | 2 +- src60/system/io/win_console.l | 2 +- src60/system/io/win_files.l | 2 + src60/system/math/math.l | 16 +- src60/system/operations/advanced/operations.l | 4 +- src60/system/pointers.l | 34 +- src60/system/primitives.l | 32 +- src60/system/strings.l | 24 +- src60/system/text/encoding.l | 4 +- src60/system/text/textbuffer.l | 6 +- tests60/sandbox/sandbox.l | 2 + tests60/script_tests/basic.l | 12 + tests60/script_tests/main.l | 10 + tests60/script_tests/script_tests.prj | 22 + tests60/system_tests/basic.l | 90 +- tests60/system_tests/main.l | 2 +- 169 files changed, 3959 insertions(+), 1969 deletions(-) create mode 100644 bin/local.elc60.config.bak create mode 100644 bin/templates/local.lib60.config create mode 100644 doc/api/extensions-routines-stex-summary.html create mode 100644 doc/api/extensions-routines-stex.html create mode 100644 elenasrc3/elc/linux/pathmanager.cpp create mode 100644 elenasrc3/elc/linux/pathmanager.h create mode 100644 tests60/script_tests/basic.l create mode 100644 tests60/script_tests/main.l create mode 100644 tests60/script_tests/script_tests.prj diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 017c054891..80f819d993 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -20,7 +20,7 @@ env: # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix BUILD_CONFIGURATION: Release - BUILD_TAG: 6.4.3 + BUILD_TAG: 6.5.0 permissions: contents: read diff --git a/CHANGELOG.md b/CHANGELOG.md index ae7b3ed5b4..fbc9376840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ - [FIXED] ?? operator - [ADDED] static constructor - [ADDED] internal symbols + - [ADDED] supporting async methods + - [ADDED] supporting indexed methods + - [ADDED] indexed internal methods can be declared in a closed class - ELC - [ADDED] new option -el5 / -el6 (default) - specifying grammar compatible to ELENA 5.x or 6.x @@ -19,6 +22,9 @@ - [FIXED] calling a method directly with nil argument when allowed - [FIXED] single dispatch of a private / internal / protected method - [FIXED] closure argument types can be specified by an expected type + - [FIXED] it is not possible to declare internal default constructor + - [FIXED] #675 - Using ++ operator with a weak type + - [FIXED] incorrect typecast handler signature for the classes inheriting template-based ones - VM @@ -36,18 +42,32 @@ - [ADDED] #154 : system'threading: ManualResetEvent, AutoResetEvent, CountDownEvent - [ADDED] system'threading : Task - [ADDED] system'io'Directory : static getFiles / getFiles + - [ADDED] File : saveContent, readContent, readWideContent + - [ADDED] system'io'threading : asyncStreamOp extension + - [ADDED] system'threading.Task - sleep + - [ADDED] extensions'threading : outputConcurrentOp extension + - [REDUX] all symbols must start with a capital letter + - [ADDED] system'threading : Task + - [FIXED] system'objectOp.__getClassName[1] - SAMPLES - [ADDED] threadpool - [ADDED] tasks + - [ADDED] asyncsamples + - [ADDED] task sample 2 - Tools - [ECV][ADDED] displaying class attributes + - [FIXED][ldoc] system-threading-.html must not be generated + - [FIXED][ldoc] system-threading : generate only templates declared in the module - IDE - [FIXED] #679 : class already exist - [FIXED] debug source path - [ADDED] it is possible to set the target type for a single file project + - [FIXED] project options - debug command arguments + - [FIXED] correct debug info of the constructor self variable + - [FIXED] #413 - boxing variadic argument ## ELENA 6.3.0 diff --git a/VERSION b/VERSION index 8e0a2119a7..4be2c727ad 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.4.3 \ No newline at end of file +6.5.0 \ No newline at end of file diff --git a/asm/aarch64/core60.asm b/asm/aarch64/core60.asm index eb59389e2c..58bd0d1444 100644 --- a/asm/aarch64/core60.asm +++ b/asm/aarch64/core60.asm @@ -1,5 +1,4 @@ // ; --- Predefined References -- -define INVOKER 10001h define GC_ALLOC 10002h define VEH_HANDLER 10003h define GC_COLLECT 10004h @@ -118,7 +117,7 @@ structure %SYSTEM_ENV dq data : %CORE_GC_TABLE dq data : %CORE_SINGLE_CONTENT dq 0 - dq code : %INVOKER + dq 0 dq code : %VEH_HANDLER // ; dd GCMGSize // ; dd GCYGSize @@ -3703,6 +3702,7 @@ labLoop: b labLoop labEnd: + // ; init x0, x1 with zero (and in all variants) end diff --git a/asm/aarch64/core60_lnx.asm b/asm/aarch64/core60_lnx.asm index 753141c29d..cc8ce828a4 100644 --- a/asm/aarch64/core60_lnx.asm +++ b/asm/aarch64/core60_lnx.asm @@ -3,48 +3,12 @@ // ; ==== Overridden Command Set == // ; --- Predefined References -- -define INVOKER 10001h define VEH_HANDLER 10003h define CORE_ET_TABLE 2000Bh // ; ==== System commands === -// INVOKER(function, arg) -procedure % INVOKER - - // ; x0 - function - // ; x1 - arg - - stp x19, x20, [sp, #-16]! - stp x21, x22, [sp, #-16]! - stp x23, x24, [sp, #-16]! - stp x25, x26, [sp, #-16]! - stp x27, x28, [sp, #-16]! - stp x29, x30, [sp, #-16]! - - mov x3, 0 - stp x3, x3, [sp, #-16]! - mov x29, sp - - mov x8, x0 - mov x0, x1 - - blr x8 - mov x0, x10 - - add sp, sp, #16 - ldp x29, x30, [sp], #16 - ldp x27, x28, [sp], #16 - ldp x25, x26, [sp], #16 - ldp x23, x24, [sp], #16 - ldp x21, x22, [sp], #16 - ldp x19, x20, [sp], #16 - - ret x30 - -end - // VEH_HANDLER() procedure % VEH_HANDLER diff --git a/asm/amd64/core60.asm b/asm/amd64/core60.asm index bd6b19dd44..7070499fbd 100644 --- a/asm/amd64/core60.asm +++ b/asm/amd64/core60.asm @@ -1,7 +1,6 @@ // !! NOTE : R15 register must be preserved // ; --- Predefined References -- -define INVOKER 10001h define GC_ALLOC 10002h define VEH_HANDLER 10003h define GC_COLLECT 10004h @@ -118,7 +117,7 @@ structure %SYSTEM_ENV dq data : %CORE_GC_TABLE dq data : %CORE_SINGLE_CONTENT dq 0 - dq code : %INVOKER + dq 0 dq code : %VEH_HANDLER // ; dd GCMGSize // ; dd GCYGSize @@ -526,7 +525,7 @@ inline %17h setl cl cmp rbx, rax setg ch - cmp ecx, 0 + test ecx, ecx end @@ -1803,8 +1802,7 @@ end // ; cmpr 0 inline %1C0h - mov rax, 0 - cmp rbx, rax + test rbx, rbx end @@ -1970,7 +1968,10 @@ inline %0CAh mov rsp, rbp pop rbp - add rsp, 24 + add rsp, 16 + pop rbx + mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], rbx + pop rbp pop r15 pop r14 @@ -1989,7 +1990,10 @@ inline %1CAh mov rsp, rbp pop rbp - add rsp, 24 + add rsp, 16 + pop rbx + mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], rbx + pop rbp pop r15 pop r14 @@ -3023,6 +3027,8 @@ inline %0F2h sub rsp, __arg32_1 mov rdi, rsp rep stos + mov r10, rax + mov r11, rax end @@ -3060,6 +3066,8 @@ inline %1F2h push rbp push rax mov rbp, rsp + mov r10, rax + mov r11, rax end @@ -3099,6 +3107,8 @@ inline %2F2h mov rbp, rsp push rax push rax + mov r10, rax + mov r11, rax end @@ -3138,6 +3148,8 @@ inline %3F2h mov rbp, rsp push rax push rax + mov r10, rax + mov r11, rax end @@ -3179,6 +3191,8 @@ inline %4F2h push rax push rax push rax + mov r10, rax + mov r11, rax end @@ -3220,6 +3234,8 @@ inline %5F2h push rax push rax push rax + mov r10, rax + mov r11, rax end @@ -3257,6 +3273,8 @@ inline %6F2h sub rsp, __arg32_1 mov rdi, rsp rep stos + mov r10, rax + mov r11, rax end @@ -3289,6 +3307,8 @@ inline %7F2h push rbp mov rbp, rsp + mov r10, rax + mov r11, rax end @@ -3323,6 +3343,8 @@ inline %8F2h mov rbp, rsp push 0 push 0 + mov r10, rax + mov r11, rax end @@ -3358,6 +3380,8 @@ inline %9F2h mov rbp, rsp push rax push rax + mov r10, rax + mov r11, rax end @@ -3395,6 +3419,8 @@ inline %0AF2h push rax push rax push rax + mov r10, rax + mov r11, rax end @@ -3432,6 +3458,8 @@ inline %0BF2h push rax push rax push rax + mov r10, rax + mov r11, rax end diff --git a/asm/amd64/core60_lnx.asm b/asm/amd64/core60_lnx.asm index cb8578514e..e9638046b8 100644 --- a/asm/amd64/core60_lnx.asm +++ b/asm/amd64/core60_lnx.asm @@ -1,7 +1,7 @@ // ; --- Predefined References -- -define INVOKER 10001h define GC_ALLOC 10002h define VEH_HANDLER 10003h +define GC_COLLECT 10004h define PREPARE 10006h define SYSTEM_ENV 20002h @@ -18,6 +18,9 @@ define gc_mg_start 0038h define gc_mg_current 0040h define gc_end 0048h define gc_mg_wbar 0050h +define gc_perm_start 0058h +define gc_perm_end 0060h +define gc_perm_current 0068h define et_current 0008h define tt_stack_frame 0010h @@ -30,50 +33,6 @@ define elObjectOffset 0010h // ; ==== System commands === -// INVOKER(function, arg) -procedure % INVOKER - - // ; RDI - function - // ; RSI - arg - - // ; save registers - push 0 - push rsi - push rdi - push rbx - push rbp - push r12 - push r13 - push r14 - push r15 - - // ; declare new frame - mov rax, rdi - xor rdi, rdi - push 0 // ; FrameHeader.previousFrame - push 0 // ; FrameHeader.reserved - mov rbp, rsp // ; FrameHeader - push rdi - push rsi // ; arg - - call rax - add rsp, 32 // ; clear FrameHeader+arg - mov rax, rbx - - // ; restore registers - pop r15 - pop r14 - pop r13 - pop r12 - pop rbp - pop rbx - pop rdi - pop rsi - add rsp, 8 - ret - -end - // VEH_HANDLER() procedure % VEH_HANDLER diff --git a/asm/amd64/core60_win.asm b/asm/amd64/core60_win.asm index 64135dfab5..a7b83c00db 100644 --- a/asm/amd64/core60_win.asm +++ b/asm/amd64/core60_win.asm @@ -1,55 +1,10 @@ // ; --- Predefined References -- -define INVOKER 10001h define VEH_HANDLER 10003h define CORE_ET_TABLE 2000Bh // ; ==== System commands === -// INVOKER(function, arg) -procedure % INVOKER - - // ; RCX - function - // ; RDX - arg - - // ; save registers - push 0 - push rsi - push rdi - push rbx - push rbp - push r12 - push r13 - push r14 - push r15 - - // ; declare new frame - xor rdi, rdi - mov rax, rcx - push 0 // ; FrameHeader.previousFrame - push 0 // ; FrameHeader.reserved - mov rbp, rsp // ; FrameHeader - push 0 - push r8 // ; arg - - call rax - add rsp, 32 // ; clear FrameHeader+arg - mov rax, rbx - - // ; restore registers - pop r15 - pop r14 - pop r13 - pop r12 - pop rbp - pop rbx - pop rdi - pop rsi - add rsp, 8 - ret - -end - // VEH_HANDLER() procedure % VEH_HANDLER diff --git a/asm/amd64/core60_win_client.asm b/asm/amd64/core60_win_client.asm index 4db5b2c6c0..54c6bc1e9c 100644 --- a/asm/amd64/core60_win_client.asm +++ b/asm/amd64/core60_win_client.asm @@ -1,86 +1,11 @@ -define INVOKER 10001h - define CORE_SINGLE_CONTENT 2000Bh define tt_stack_frame 0010h define tt_stack_root 0028h -// INVOKER(function, arg) -procedure % INVOKER - - // ; RCX - function - // ; RDX - arg - - // ; save registers - push 0 - push rsi - push rdi - push rbx - push rbp - push r12 - push r13 - push r14 - push r15 - - // ; check if it is a nested call - mov rsi, [data : %CORE_SINGLE_CONTENT + tt_stack_root] - test rsi, rsi - jnz labNested - - // ; declare new frame - xor rdi, rdi - mov rax, rcx - push 0 // ; FrameHeader.previousFrame - push 0 // ; FrameHeader.reserved - mov rbp, rsp // ; FrameHeader +// ; system startup +inline %4CFh mov [data : %CORE_SINGLE_CONTENT + tt_stack_root], rsp - mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], rsp - - // ; allocate shadow stack - sub rsp, 20h - mov rcx, rdx - mov rdx, rdi - mov r8, rdi - mov r9, rdi - - call rax - add rsp, 30h // ; clear FrameHeader+args - mov rax, rbx - - // ; clear root - xor ecx, ecx - mov [data : %CORE_SINGLE_CONTENT + tt_stack_root], rcx - mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], rcx - - jmp labEnd - -labNested: - mov rax, rcx - - // ; allocate shadow stack - sub rsp, 20h - mov rcx, rdx - xor rdx, rdx - mov r8, rdx - mov r9, rdx - - call rax - add rsp, 20h // ; clear args - mov rax, rbx - -labEnd: - - // ; restore registers - pop r15 - pop r14 - pop r13 - pop r12 - pop rbp - pop rbx - pop rdi - pop rsi - add rsp, 8 - ret end diff --git a/asm/amd64/corex60.asm b/asm/amd64/corex60.asm index 9f5df14e6b..8f24174dc5 100644 --- a/asm/amd64/corex60.asm +++ b/asm/amd64/corex60.asm @@ -1,7 +1,6 @@ // !! NOTE : R15 register must be preserved // ; --- Predefined References -- -define INVOKER 10001h define GC_ALLOC 10002h define VEH_HANDLER 10003h define GC_COLLECT 10004h @@ -85,7 +84,7 @@ structure %SYSTEM_ENV dq data : %CORE_GC_TABLE dq 0 dq data : %CORE_THREAD_TABLE - dq code : %INVOKER + dq 0 dq code : %VEH_HANDLER // ; dd GCMGSize // ; dd GCYGSize @@ -388,7 +387,36 @@ end // in: ecx - size ; out: ebx - created object procedure %GC_ALLOCPERM + // ; GCXT: set lock labStart: + mov rdi, data : %CORE_GC_TABLE + gc_lock + +labWait: + mov edx, 1 + xor eax, eax + lock cmpxchg dword ptr[rdi], edx + jnz short labWait + + mov rax, [data : %CORE_GC_TABLE + gc_perm_current] + mov r12, [data : %CORE_GC_TABLE + gc_perm_end] + add rcx, rax + cmp rcx, r12 + jae short labPERMCollect + mov [data : %CORE_GC_TABLE + gc_perm_current], rcx + + // ; GCXT: clear sync field + mov edx, 0FFFFFFFFh + lea rbx, [rax + elObjectOffset] + + // ; GCXT: free lock + // ; could we use mov [esi], 0 instead? + lock xadd [rdi], edx + + ret + +labPERMCollect: + sub rcx, rax + // ; GCXT: find the current thread entry mov rdi, gs:[58h] mov rax, [data : %CORE_TLS_INDEX] @@ -513,7 +541,7 @@ labSkipWait: sub rsp, 30h - mov rcx, [rbp + 8] + mov rcx, [rbp] call extern "$rt.CollectPermGCLA" mov rdi, rax @@ -527,7 +555,7 @@ labSkipWait: call extern "$rt.SignalStopGCLA" mov rbx, rdi - add rsp, 30h + add rsp, 40h pop rbp pop r11 @@ -556,7 +584,7 @@ labWait: jnz short labWait // ; find the current thread entry - mov rdi, gs:[58h] + mov rdx, gs:[58h] mov rax, [data : %CORE_TLS_INDEX] mov rax, [rdx+rax*8] @@ -677,7 +705,7 @@ inline %17h setl cl cmp rbx, rax setg ch - cmp ecx, 0 + test ecx, ecx end @@ -724,6 +752,63 @@ inline %0BCh end + + + +// ; extclosen +inline %0CAh + + add rbp, __n_1 + mov rsp, rbp + pop rbp + + add rsp, 16 + pop rbx + + mov rcx, gs:[58h] + mov rdx, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rdx*8] + mov [rdi + tt_stack_frame], rbx + + pop rbp + pop r15 + pop r14 + pop r13 + pop r12 + pop rbx + pop rdi + pop rsi + add rsp, 8 + +end + +// ; extclosen 0 +inline %1CAh + + mov rsp, rbp + pop rbp + + add rsp, 16 + pop rbx + + mov rcx, gs:[58h] + mov rdx, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rdx*8] + mov [rdi + tt_stack_frame], rbx + + pop rbp + pop r15 + pop r14 + pop r13 + pop r12 + pop rbx + pop rdi + pop rsi + add rsp, 8 + +end + + // ; system minor collect inline %1CFh @@ -827,3 +912,525 @@ inline %0E6h mov [rax + et_current], rdi end + +// ; extopenin +inline %0F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + sub rsp, __n_2 + push rbp + push rax + mov rbp, rsp + mov rcx, __n_1 + sub rsp, __arg32_1 + mov rdi, rsp + rep stos + mov r10, rax + mov r11, rax + +end + +// ; extopenin 0, n +inline %1F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + sub rsp, __n_2 + push rbp + push rax + mov rbp, rsp + mov r10, rax + mov r11, rax + +end + +// ; extopenin 1, n +inline %2F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + sub rsp, __n_2 + push rbp + push rax + mov rbp, rsp + push rax + push rax + mov r10, rax + mov r11, rax + +end + +// ; extopenin 2, n +inline %3F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + sub rsp, __n_2 + push rbp + push rax + mov rbp, rsp + push rax + push rax + mov r10, rax + mov r11, rax + +end + +// ; extopenin 3, n +inline %4F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + sub rsp, __n_2 + push rbp + push rax + mov rbp, rsp + push rax + push rax + push rax + push rax + mov r10, rax + mov r11, rax + +end + +// ; extopenin 4, n +inline %5F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + sub rsp, __n_2 + push rbp + push rax + mov rbp, rsp + push rax + push rax + push rax + push rax + mov r10, rax + mov r11, rax + +end + +// ; extopenin i, 0 +inline %6F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + mov rcx, __n_1 + sub rsp, __arg32_1 + mov rdi, rsp + rep stos + mov r10, rax + mov r11, rax + +end + +// ; extopenin 0, 0 +inline %7F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + mov rbp, rsp + mov r10, rax + mov r11, rax + +end + +// ; extopenin 1, 0 +inline %8F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + mov rbp, rsp + push 0 + push 0 + mov r10, rax + mov r11, rax + +end + +// ; extopenin 2, 0 +inline %9F2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + push rax + push rax + mov r10, rax + mov r11, rax + +end + +// ; extopenin 3, 0 +inline %0AF2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + push rax + push rax + push rax + push rax + mov r10, rax + mov r11, rax + +end + +// ; extopenin 4, 0 +inline %0BF2h + + mov [rsp+8], rcx + mov [rsp+16], rdx + mov [rsp+24], r8 + mov [rsp+32], r9 + + push 0 + push rsi + push rdi + push rbx + push r12 + push r13 + push r14 + push r15 + + push rbp + + mov rcx, gs:[58h] + mov rax, [data : %CORE_TLS_INDEX] + mov rdi, [rcx+rax*8] + mov rax, [rdi + tt_stack_frame] + push rax + + mov rbp, rax + xor eax, eax + push rbp + push rax + mov rbp, rsp + + push rbp + xor rax, rax + mov rbp, rsp + push rax + push rax + push rax + push rax + mov r10, rax + mov r11, rax + +end diff --git a/asm/ppc64le/core60.asm b/asm/ppc64le/core60.asm index 0a894662b5..29807facc6 100644 --- a/asm/ppc64le/core60.asm +++ b/asm/ppc64le/core60.asm @@ -1,5 +1,4 @@ // ; --- Predefined References -- -define INVOKER 10001h define GC_ALLOC 10002h define VEH_HANDLER 10003h define GC_COLLECT 10004h @@ -142,7 +141,7 @@ structure %SYSTEM_ENV dq data : %CORE_GC_TABLE dq data : %CORE_SINGLE_CONTENT dq 0 - dq code : %INVOKER + dq 0 dq code : %VEH_HANDLER // ; dd GCMGSize // ; dd GCYGSize @@ -3212,7 +3211,7 @@ inline % 6ECh ld r16, -elVMTOffset(r15) ld r17, -elVMTSizeOffset(r16) sldi r17, r17, 4 - addi r16, r16, r17 + add r16, r16, r17 ld r17, __arg16_1(r16) mtctr r17 // ; put code address into ctr bctr // ; and jump to it @@ -3641,6 +3640,7 @@ labLoop: b labLoop labEnd: + // ; init r3, r4 with zero (and in all variants) end @@ -4810,7 +4810,7 @@ inline % 6FCh ld r17, -elVMTSizeOffset(r16) sldi r17, r17, 4 addi r16, r16, __arg16_1 - addi r16, r16, r17 + add r16, r16, r17 ld r17, 8(r16) mtctr r17 // ; put code address into ctr bctrl // ; and call it diff --git a/asm/ppc64le/core60_lnx.asm b/asm/ppc64le/core60_lnx.asm index 666ab2f49c..42d5e666e9 100644 --- a/asm/ppc64le/core60_lnx.asm +++ b/asm/ppc64le/core60_lnx.asm @@ -3,7 +3,6 @@ // ; ==== Overridden Command Set == // ; --- Predefined References -- -define INVOKER 10001h define VEH_HANDLER 10003h define CORE_TOC 20001h @@ -20,55 +19,6 @@ define toc_data 0030h // ; ==== System commands === -// INVOKER(function, arg) -procedure % INVOKER - - // ; loading TOC pointer - lis r2, rdata32_hi : %CORE_TOC - addi r2, r2, rdata32_lo : %CORE_TOC - - // ; R3 - function - // ; R4 - arg - stdu r1, -176(r1) // ; 0xf821ff51 - - mflr r0 - - std r31, 168(r1) - std r30, 160(r1) - std r29, 152(r1) - std r28, 144(r1) - std r27, 136(r1) - std r0, 128(r1) - - li r16, 0 - std r16, -10h(r1) // ; save frame pointer - std r16, -08h(r1) // ; save return address - - addi r1, r1, -16 // ; allocate raw stack - mr r31, r1 // ; set frame pointer - - mtctr r3 // ; put code address into ctr - mr r3, r4 - bctrl // ; and call it - - mr r3, r15 - - addi r1, r1, 16 - - ld r31, 168(r1) - ld r30, 160(r1) - ld r29, 152(r1) - ld r28, 144(r1) - ld r27, 136(r1) - - ld r0, 128(r1) - mtlr r0 - - addi r1, r1, 176 - blr - -end - // VEH_HANDLER() procedure % VEH_HANDLER diff --git a/asm/x32/core60.asm b/asm/x32/core60.asm index 937bcdf237..06d68ea1e4 100644 --- a/asm/x32/core60.asm +++ b/asm/x32/core60.asm @@ -1,5 +1,4 @@ // ; --- Predefined References -- -define INVOKER 10001h define GC_ALLOC 10002h define VEH_HANDLER 10003h define GC_COLLECT 10004h @@ -120,7 +119,7 @@ structure %SYSTEM_ENV dd data : %CORE_GC_TABLE dd data : %CORE_SINGLE_CONTENT dd 0 - dd code : %INVOKER + dd 0 dd code : %VEH_HANDLER // ; dd GCMGSize // ; dd GCYGSize @@ -152,7 +151,8 @@ inline % GC_ALLOC mov eax, [data : %CORE_GC_TABLE + gc_yg_current] add ecx, eax - cmp ecx, [data : %CORE_GC_TABLE + gc_yg_end] + mov edi, [data : %CORE_GC_TABLE + gc_yg_end] + cmp ecx, edi jae short labYGCollect mov [data : %CORE_GC_TABLE + gc_yg_current], ecx lea ebx, [eax + elObjectOffset] @@ -311,18 +311,22 @@ labSplit: labStart: shr esi, 1 setnc cl - cmp edx, [edi+esi*8] + mov eax, [edi+esi*8] + cmp edx, eax je short labFound lea eax, [edi+esi*8] jb short labSplit lea edi, [eax+8] sub esi, ecx jmp short labSplit + nop labFound: mov eax, [edi+esi*8+4] mov esi, [esp+4] jmp eax + rgw nop [eax + eax + 0] + labEnd: mov esi, [esp+4] @@ -508,7 +512,7 @@ inline %17h setl cl cmp ebx, eax setg ch - cmp ecx, 0 + test ecx, ecx end @@ -1811,7 +1815,8 @@ labSplit: labStart: shr esi, 1 setnc cl - cmp edx, [edi+esi*8] + mov eax, [edi+esi*8] + cmp edx, eax je short labFound lea eax, [edi+esi*8] jb short labSplit @@ -1850,7 +1855,7 @@ end // ; cmpr 0 inline %1C0h - cmp ebx, 0 + test ebx, ebx end @@ -1968,7 +1973,8 @@ end // ; xcmpsi inline %0C6h - cmp edx, [esp + __arg32_1] + mov eax, [esp + __arg32_1] + cmp edx, eax end @@ -1982,14 +1988,16 @@ end // ; cmpfi inline %0C8h - cmp ebx, [ebp + __arg32_1] + mov eax, [ebp + __arg32_1] + cmp ebx, eax end // ; cmpsi inline %0C9h - cmp ebx, [esp + __arg32_1] + mov eax, [esp + __arg32_1] + cmp ebx, eax end @@ -2008,11 +2016,16 @@ inline %0CAh pop ebp add esp, 8 - pop eax - mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], eax + pop ebx + mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], ebx pop ebp + pop ebx + pop ecx + pop edi + pop esi + end // ; extclosen 0 @@ -2023,10 +2036,15 @@ inline %1CAh add esp, 8 - pop eax - mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], eax + pop ebx + mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], ebx pop ebp + + pop ebx + pop ecx + pop edi + pop esi end @@ -3239,6 +3257,11 @@ end // ; extopenin inline %0F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3260,12 +3283,18 @@ inline %0F2h sub esp, __arg32_1 mov edi, esp rep stos + mov esi, eax end // ; extopenin 0, n inline %1F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3283,12 +3312,18 @@ inline %1F2h push ebp push eax mov ebp, esp + mov esi, eax end // ; extopenin 1, n inline %2F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3307,12 +3342,18 @@ inline %2F2h push eax mov ebp, esp push eax + mov esi, eax end // ; extopenin 2, n inline %3F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3332,12 +3373,18 @@ inline %3F2h mov ebp, esp push eax push eax + mov esi, eax end // ; extopenin 3, n inline %4F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3358,12 +3405,18 @@ inline %4F2h push eax push eax push eax + mov esi, eax end // ; extopenin 4, n inline %5F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3385,12 +3438,18 @@ inline %5F2h push eax push eax push eax + mov esi, eax end // ; extopenin i, 0 inline %6F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3408,12 +3467,18 @@ inline %6F2h sub esp, __arg32_1 mov edi, esp rep stos + mov esi, eax end // ; extopenin 0, 0 inline %7F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3426,12 +3491,18 @@ inline %7F2h push ebp mov ebp, esp + mov esi, eax end // ; extopenin 1, 0 inline %8F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3445,12 +3516,18 @@ inline %8F2h push ebp mov ebp, esp push 0 + mov esi, eax end // ; extopenin 2, 0 inline %9F2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3466,12 +3543,18 @@ inline %9F2h mov ebp, esp push eax push eax + mov esi, eax end // ; extopenin 3, 0 inline %0AF2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3488,12 +3571,18 @@ inline %0AF2h push eax push eax push eax + mov esi, eax end // ; extopenin 4, 0 inline %0BF2h + push esi + push edi + push ecx + push ebx + push ebp mov eax, [data : %CORE_SINGLE_CONTENT + tt_stack_frame] push eax @@ -3511,6 +3600,7 @@ inline %0BF2h push eax push eax push eax + mov esi, eax end diff --git a/asm/x32/core60_lnx.asm b/asm/x32/core60_lnx.asm index 49923eb6c1..be4bde9194 100644 --- a/asm/x32/core60_lnx.asm +++ b/asm/x32/core60_lnx.asm @@ -1,5 +1,4 @@ // ; --- Predefined References -- -define INVOKER 10001h define VEH_HANDLER 10003h define PREPARE 10006h @@ -7,38 +6,6 @@ define CORE_SINGLE_CONTENT 2000Bh // ; ==== System commands === -// INVOKER(function, arg) -procedure % INVOKER - - // ; save registers - mov eax, [esp+4] // ; function - push esi - mov esi, [esp+12] // ; arg - push edi - push ecx - push ebx - push ebp - - // ; declare new frame - push 0 // ; FrameHeader.previousFrame - push 0 // ; FrameHeader.reserved - mov ebp, esp // ; FrameHeader - push esi // ; arg - - call eax - add esp, 12 // ; clear FrameHeader+arg - mov eax, ebx - - // ; restore registers - pop ebp - pop ebx - pop ecx - pop edi - pop esi - ret - -end - // VEH_HANDLER() procedure % VEH_HANDLER diff --git a/asm/x32/core60_win.asm b/asm/x32/core60_win.asm index c87835273f..acdd72e56c 100644 --- a/asm/x32/core60_win.asm +++ b/asm/x32/core60_win.asm @@ -1,5 +1,4 @@ // ; --- Predefined References -- -define INVOKER 10001h define VEH_HANDLER 10003h define CORE_TOC 20001h @@ -8,38 +7,6 @@ define CORE_SINGLE_CONTENT 2000Bh // ; ==== System commands === -// INVOKER(function, arg) -procedure % INVOKER - - // ; save registers - mov eax, [esp+4] // ; function - push esi - mov esi, [esp+12] // ; arg - push edi - push ecx - push ebx - push ebp - - // ; declare new frame - push 0 // ; FrameHeader.previousFrame - push 0 // ; FrameHeader.reserved - mov ebp, esp // ; FrameHeader - push esi // ; arg - - call eax - add esp, 12 // ; clear FrameHeader+arg - mov eax, ebx - - // ; restore registers - pop ebp - pop ebx - pop ecx - pop edi - pop esi - ret - -end - // VEH_HANDLER() procedure % VEH_HANDLER diff --git a/asm/x32/core60_win_client.asm b/asm/x32/core60_win_client.asm index 2b0ce7c028..7d97eb9512 100644 --- a/asm/x32/core60_win_client.asm +++ b/asm/x32/core60_win_client.asm @@ -1,62 +1,11 @@ -define INVOKER 10001h - define CORE_SINGLE_CONTENT 2000Bh define tt_stack_frame 0008h define tt_stack_root 0014h -// INVOKER(function, arg) -procedure % INVOKER - - // ; save registers - mov eax, [esp+4] // ; function - push esi - mov esi, [esp+12] // ; arg - push edi - push ecx - push ebx - push ebp - - // ; check if it is a nested call - mov ecx, [data : %CORE_SINGLE_CONTENT + tt_stack_root] - test ecx, ecx - jnz labNested - - // ; declare new frame - push 0 // ; FrameHeader.previousFrame - push 0 // ; FrameHeader.reserved - mov ebp, esp // ; FrameHeader - - mov [data : %CORE_SINGLE_CONTENT + tt_stack_root], esp - mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], esp - - push esi // ; arg - - call eax - add esp, 12 // ; clear FrameHeader+arg - mov eax, ebx - - // ; clear root - xor ecx, ecx - mov [data : %CORE_SINGLE_CONTENT + tt_stack_root], ecx - mov [data : %CORE_SINGLE_CONTENT + tt_stack_frame], ecx - - jmp labEnd - -labNested: - - push esi // ; arg - call eax - add esp, 4 // ; clear arg - -labEnd: +// ; system startup +inline %4CFh - // ; restore registers - pop ebp - pop ebx - pop ecx - pop edi - pop esi - ret + mov [data : %CORE_SINGLE_CONTENT + tt_stack_root], esp end diff --git a/asm/x32/corex60.asm b/asm/x32/corex60.asm index f1daad09bc..4509dc8eb6 100644 --- a/asm/x32/corex60.asm +++ b/asm/x32/corex60.asm @@ -1,5 +1,4 @@ // ; --- Predefined References -- -define INVOKER 10001h define GC_ALLOC 10002h define VEH_HANDLER 10003h define GC_COLLECT 10004h @@ -68,7 +67,7 @@ structure %SYSTEM_ENV dd data : %CORE_GC_TABLE dd 0 dd data : %CORE_THREAD_TABLE - dd code : %INVOKER + dd 0 dd code : %VEH_HANDLER // ; dd GCMGSize // ; dd GCYGSize @@ -655,7 +654,7 @@ inline %17h setl cl cmp ebx, eax setg ch - cmp ecx, 0 + test ecx, ecx end @@ -702,6 +701,53 @@ inline %0BCh end +// ; extclosen +inline %0CAh + + add ebp, __n_1 + mov esp, ebp + pop ebp + + add esp, 8 + + pop ebx + mov ecx, fs:[2Ch] + mov edx, [data : %CORE_TLS_INDEX] + mov edi, [ecx+edx*4] + mov [edi + tt_stack_frame], ebx + + pop ebp + + pop ebx + pop ecx + pop edi + pop esi + +end + +// ; extclosen 0 +inline %1CAh + + mov esp, ebp + pop ebp + + add esp, 8 + + pop ebx + mov ecx, fs:[2Ch] + mov edx, [data : %CORE_TLS_INDEX] + mov edi, [ecx+edx*4] + mov [edi + tt_stack_frame], ebx + + pop ebp + + pop ebx + pop ecx + pop edi + pop esi + +end + // ; system minor collect inline %1CFh @@ -802,3 +848,389 @@ inline %0E6h mov [eax + et_current], edi end + +// ; extopenin +inline %0F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + sub esp, __n_2 + push ebp + push eax + mov ebp, esp + mov ecx, __n_1 + sub esp, __arg32_1 + mov edi, esp + rep stos + mov esi, eax + +end + +// ; extopenin 0, n +inline %1F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + sub esp, __n_2 + push ebp + push eax + mov ebp, esp + mov esi, eax + +end + +// ; extopenin 1, n +inline %2F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + sub esp, __n_2 + push ebp + push eax + mov ebp, esp + push eax + mov esi, eax + +end + +// ; extopenin 2, n +inline %3F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + sub esp, __n_2 + push ebp + push eax + mov ebp, esp + push eax + push eax + mov esi, eax + +end + +// ; extopenin 3, n +inline %4F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + sub esp, __n_2 + push ebp + push eax + mov ebp, esp + push eax + push eax + push eax + mov esi, eax + +end + +// ; extopenin 4, n +inline %5F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + sub esp, __n_2 + push ebp + push eax + mov ebp, esp + push eax + push eax + push eax + push eax + mov esi, eax + +end + +// ; extopenin i, 0 +inline %6F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + mov ecx, __n_1 + sub esp, __arg32_1 + mov edi, esp + rep stos + mov esi, eax + +end + +// ; extopenin 0, 0 +inline %7F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + mov ebp, esp + mov esi, eax + +end + +// ; extopenin 1, 0 +inline %8F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + mov ebp, esp + push 0 + mov esi, eax + +end + +// ; extopenin 2, 0 +inline %9F2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + push eax + push eax + mov esi, eax + +end + +// ; extopenin 3, 0 +inline %0AF2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + push eax + push eax + push eax + mov esi, eax + +end + +// ; extopenin 4, 0 +inline %0BF2h + + push esi + push edi + push ecx + push ebx + + push ebp + mov ecx, fs:[2Ch] + mov eax, [data : %CORE_TLS_INDEX] + mov edi, [ecx+eax*4] + mov eax, [edi + tt_stack_frame] + push eax + + mov ebp, eax + xor eax, eax + push ebp + push eax + mov ebp, esp + + push ebp + xor eax, eax + mov ebp, esp + push eax + push eax + push eax + push eax + mov esi, eax + +end diff --git a/bin/command60.es b/bin/command60.es index a4c42630ea..55b4170262 100644 --- a/bin/command60.es +++ b/bin/command60.es @@ -1 +1 @@ -public program() { system'console.writeLine($1) } \ No newline at end of file +public program() { system'Console.writeLine($1) } \ No newline at end of file diff --git a/bin/local.elc60.config.bak b/bin/local.elc60.config.bak new file mode 100644 index 0000000000..41799916ee --- /dev/null +++ b/bin/local.elc60.config.bak @@ -0,0 +1,54 @@ + + + + + + + + x32/core60.bin + x32/core60_lnx.bin + + + libc.so.6 + + + + + + + + + amd64/core60.bin + amd64/core60_lnx.bin + + + libc.so.6 + + + + + + + + + ppc64le/core60.bin + ppc64le/core60_lnx.bin + + + libc.so.6 + + + + + + + + + aarch64/core60.bin + aarch64/core60_lnx.bin + + + libc.so.6 + + + \ No newline at end of file diff --git a/bin/scripts/jscript60.es b/bin/scripts/jscript60.es index 9999029e3b..33c63ece3a 100644 --- a/bin/scripts/jscript60.es +++ b/bin/scripts/jscript60.es @@ -145,7 +145,7 @@ <= expression ( message_operation ( - object ( reference = system'console ) + object ( reference = system'Console ) message ( identifier = writeLine ) => diff --git a/bin/templates/local.lib60.config b/bin/templates/local.lib60.config new file mode 100644 index 0000000000..a11a75bec2 --- /dev/null +++ b/bin/templates/local.lib60.config @@ -0,0 +1,62 @@ + + + + ../../lib60 + + + + + ../../lib60_64 + + + + + ../../lib60_64 + + + + + ../../lib60_64 + + + + import system; + #load system'operations'advanced'statements; + + + system'attributes'attributes + system'predefined'defaults + system'predefined'aliases + system'operations'statements + system'Object + system'nilValue + system'IntNumber + system'UIntNumber + system'LongNumber + system'RealNumber + system'ByteNumber + system'Int8Number + system'ShortNumber + system'UShortNumber + system'String + system'WideString + system'CharValue + system'BoolValue + system'BoolValue#true + system'BoolValue#false + system'Reference#1 + system'Array#1 + system'VariadicArray#1 + system'Message + system'MessageName + system'ExtensionMessage + system'Func + system'collections'Tuple + system'BaseLazyExpression + system'Nullable#1 + system'UnsafePointer + meta$preloadedSymbols + meta$preloadedSymbols + system'YieldStateEnumerator + + \ No newline at end of file diff --git a/build/aarch64/build_package_arm64.script b/build/aarch64/build_package_arm64.script index 8cef692b95..e2ce7424b7 100755 --- a/build/aarch64/build_package_arm64.script +++ b/build/aarch64/build_package_arm64.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.4.3.aarch64-linux +RELEASE=elena-6.5.0.aarch64-linux mkdir -p /usr/share/elena mkdir -p /etc/elena/ diff --git a/build/aarch64/control b/build/aarch64/control index 45ee120449..c91730ee80 100644 --- a/build/aarch64/control +++ b/build/aarch64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.4.3 +Version: 6.5.0 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 4a670f9759..85718bb1c4 100755 --- a/build/amd64/build_package_amd64.script +++ b/build/amd64/build_package_amd64.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.4.3.amd64-linux +RELEASE=elena-6.5.0.amd64-linux mkdir -p /usr/share/elena mkdir -p /etc/elena/ diff --git a/build/amd64/control b/build/amd64/control index 0cb114e6da..204db989e3 100644 --- a/build/amd64/control +++ b/build/amd64/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.4.3 +Version: 6.5.0 Architecture: amd64 Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/elena_inno.iss b/build/elena_inno.iss index 793ddb0797..745e007afb 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.4.3 -;AppVerName=ELENA Programming Language 6.4.0 +AppVersion=6.5.0 +;AppVerName=ELENA Programming Language 6.5.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.4.3.x86-win-setup +OutputBaseFilename=elena-lang-6.5.0.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 8c07d866a1..1ac52302c8 100755 --- a/build/i386/build_package_i386.script +++ b/build/i386/build_package_i386.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.4.3.i386-linux +RELEASE=elena-6.5.0.i386-linux mkdir -p /usr/share/elena mkdir -p /etc/elena/ @@ -61,7 +61,9 @@ else fi cp ../../dat/og/*.dat /usr/share/elena/ +cp ../../dat/og/*.dat ../../bin cp ../../dat/sg/syntax60.dat /usr/share/elena +cp ../../dat/sg/syntax60.dat ../../bin echo compiling assembly files diff --git a/build/i386/control b/build/i386/control index cbe7bbbd76..64e0bf7235 100644 --- a/build/i386/control +++ b/build/i386/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.4.3 +Version: 6.5.0 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 0ad1abd82d..a026fa102b 100755 --- a/build/ppc64le/build_package_ppc64le.script +++ b/build/ppc64le/build_package_ppc64le.script @@ -1,5 +1,5 @@ #!/bin/bash -RELEASE=elena-6.4.3.ppc64le-linux +RELEASE=elena-6.5.0.ppc64le-linux mkdir -p /usr/share/elena mkdir -p /etc/elena/ diff --git a/build/ppc64le/control b/build/ppc64le/control index 8fff55adc0..70fc4edd73 100644 --- a/build/ppc64le/control +++ b/build/ppc64le/control @@ -1,5 +1,5 @@ Package: elena-lang -Version: 6.4.3 +Version: 6.5.0 Architecture: ppc64le Maintainer: Alex Rakov Depends: libc6 (>= 2.1) diff --git a/build/rebuild_lib60_x86.bat b/build/rebuild_lib60_x86.bat index 07ca3284c1..9da306d99f 100644 --- a/build/rebuild_lib60_x86.bat +++ b/build/rebuild_lib60_x86.bat @@ -75,6 +75,20 @@ tests60\system_tests\system_tests.exe 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 diff --git a/dat/sg/syntax60.txt b/dat/sg/syntax60.txt index 9c05d0b931..4912a5f645 100644 --- a/dat/sg/syntax60.txt +++ b/dat/sg/syntax60.txt @@ -444,13 +444,16 @@ EXPRESSION ::= 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 ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK + | ":" ^^OBJECT ^^EXPRESSION TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK | "::=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION | SBRACKET ^OBJECT INDEXER_R L0_F | ASSIGN ^OBJECT ASSIGN_R | L1a_OOP | BRACKET ^OBJECT FUNCTION_R L2_F - | DOT ^OBJECT MESSAGE { L3_F | eps ^PROPERTY_OPERATION } + | DOT ^OBJECT { + MESSAGE { L3_F | eps ^PROPERTY_OPERATION } + | "&" EXT_R R3 + } | L4_OOP L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? | L5_OOP L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? | L6_OOP L7_OP* L8_OP? L9_OP? @@ -491,13 +494,15 @@ EXPRESSION ::= | "{" ^OBJECT COLLECTION "}" ^ COLLECTION_EXPRESSION L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? | identifier ^OBJECT { ASSIGN ASSIGN_R }? } - | ":" ^OBJECT ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK | "::=" ^OBJECT SINGLE_EXPRESSION ^KEY_VALUE_EXPRESSION | SBRACKET ^OBJECT INDEXER_R L0_F | L1a_OOP | ASSIGN ^OBJECT ASSIGN_R | BRACKET ^OBJECT FUNCTION_R L2_F - | DOT ^OBJECT MESSAGE { L3_F | eps ^PROPERTY_OPERATION } + | DOT ^OBJECT { + MESSAGE { L3_F | eps ^PROPERTY_OPERATION } + | "&" EXT_R R3 + } | IF_DOT ^OBJECT MESSAGE? CALL_R ^IF_OPERATION ^OPERATION_TEMPLATE ^EXPRESSION OL_F | ELSE_DOT ^OBJECT MESSAGE? CALL_R ^ELSE_OPERATION ^OPERATION_TEMPLATE ^EXPRESSION OL_F | ALT_DOT ^OBJECT MESSAGE? CALL_R ^ALT_OPERATION ^OPERATION_TEMPLATE ^EXPRESSION OL_F @@ -642,20 +647,12 @@ SUB_EXPRESSION ::= 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? ")" | { DYNAMIC_DIMENSION ^ARRAY_TYPE }+ { - identifier ")" "{" ^ PARAMETER_BLOCK BLOCK ^CLOSURE ^EXPRESSION + 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 ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^EXPRESSION ")" - | L2_OOP L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? ")" - | L3_OOP L3_OP* { - ":" identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^EXPRESSION - | 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? - | L9_OP - | eps } TUPLE_R? ")" + | ":" ^^OBJECT ^^EXPRESSION TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^EXPRESSION ")" + | 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? ")" | L4_OOP L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? ")" | L5_OOP L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? ")" | L6_OOP L7_OP* L8_OP? L9_OP? TUPLE_R? ")" @@ -711,18 +708,9 @@ SUB_EXPRESSION ::= | TUPLE_OR ")" | ")" ^OBJECT } - | ":" ^OBJECT ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^EXPRESSION ")" | SBRACKET ^OBJECT INDEXER_R L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? ")" | L2_OOP L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? TUPLE_R? ")" - | L3_OOP L3_OP* { - ":" identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^EXPRESSION - | 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? - | L9_OP - | eps } 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? ")" | ELSE_DOT ^OBJECT MESSAGE? CALL_R ^ELSE_OPERATION ^OPERATION_TEMPLATE ^EXPRESSION OL_F TUPLE_R? ")" | ALT_DOT ^OBJECT MESSAGE? CALL_R ^ALT_OPERATION ^OPERATION_TEMPLATE ^EXPRESSION OL_F TUPLE_R? ")" @@ -763,6 +751,10 @@ SUB_EXPRESSION ::= | "$len" SINGLE_EXPRESSION ^LEN_OPERATION ")" | "$size" SINGLE_EXPRESSION ^SIZE_OPERATION ")" | "{" BLOCK ^CLOSURE SUB_L_F ")" + | "::" identifier ^OBJECT LESS TEMPLATE_ARG { "," TEMPLATE_ARG }* ">" ^TEMPLATE_TYPE identifier ^OBJECT ^EXPRESSION { + { "," EXPRESSION }+ ")" "{" ^ PARAMETER_BLOCK BLOCK ^CLOSURE ^EXPRESSION + | ")" "{" ^ PARAMETER_BLOCK BLOCK ^CLOSURE ^EXPRESSION + } | BRACKET SUB_EXPRESSION SUB_L_F ")"; SUB_SINGLE_EXPRESSION ::= @@ -1021,7 +1013,6 @@ RI_F ::= L_F ::= L0_OP+ L2_OP* L3_OP* L4_OP* L5_OP* L6_OP? L7_OP* L8_OP? L9_OP? - | ":" ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK | 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? @@ -1030,6 +1021,7 @@ L_F ::= | L7_OP+ L8_OP? L9_OP? | L8_OP | L9_OP + | identifier ":" ^^EXPRESSION TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^ EXPRESSION | eps; SUB_L_F ::= @@ -1057,6 +1049,7 @@ OL_F ::= L0_F ::= L0_OP L0_F + | identifier ":" ^^EXPRESSION TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^ EXPRESSION | L1a_OP | L1_OP | L2_OP L2_F @@ -1071,8 +1064,8 @@ L0_F ::= L2_F ::= L2_OP L2_F + | identifier ":" ^^EXPRESSION TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^ EXPRESSION | DOT MESSAGE { L3_F | eps ^PROPERTY_OPERATION } - | ":" ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK | 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? @@ -1085,8 +1078,8 @@ L3_F ::= DOT ^PROPERTY_OPERATION MESSAGE { L3_F | eps ^PROPERTY_OPERATION } | ASSIGN EXPRESSION ^PROPERTY_OPERATION | BRACKET MESSAGE_R { - DOT MESSAGE { L3_F | eps ^PROPERTY_OPERATION } - | ":" ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK + DOT { MESSAGE { L3_F | eps ^PROPERTY_OPERATION } | "&" EXT_R } + | identifier ":" TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^EXPRESSION | 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? @@ -1121,6 +1114,17 @@ L3_F ::= | FNL ^PROPERTY_OPERATION FNL_R | ISNIL ^PROPERTY_OPERATION EXPRESSION ^ISNIL_OPERATION; +R3 ::= + DOT MESSAGE { L3_F | eps ^PROPERTY_OPERATION } + | identifier ":" TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK ^EXPRESSION + | 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 + | eps; + L0_OP ::= SBRACKET INDEXER_R; @@ -1145,11 +1149,14 @@ L2_OP ::= L2_OOP ::= BRACKET ^OBJECT FUNCTION_R; +EXT_R ::= + MESSAGE LESS TEMPLATE_ARG { "," TEMPLATE_ARG }* ">" BRACKET FUNCTION_R; + L3_OP ::= - DOT MESSAGE CALL_R; + DOT { MESSAGE CALL_R | "&" EXT_R }; L3_OOP ::= - DOT ^OBJECT MESSAGE CALL_R; + DOT ^OBJECT { MESSAGE CALL_R | "&" EXT_R }; L4_OP ::= STAR L4_EXPRESSION ^MUL_OPERATION @@ -1360,11 +1367,11 @@ RESEND ::= SWITCH_OPTION ::= - identifier ^ OBJECT SWITCH_CODE - | { integer | character | string } ^ OBJECT SWITCH_CODE; + identifier ^ OBJECT ":" SWITCH_CODE + | { integer | character | string } ^ OBJECT ":" SWITCH_CODE; SWITCH_LAST_OPTION ::= - "!" SWITCH_CODE; + "!" ":" SWITCH_CODE; SWITCH_CODE ::= "{" BLOCK; diff --git a/doc/api/extensions-routines-stex-summary.html b/doc/api/extensions-routines-stex-summary.html new file mode 100644 index 0000000000..99272c2476 --- /dev/null +++ b/doc/api/extensions-routines-stex-summary.html @@ -0,0 +1,54 @@ + + + + +ELENA Standard Library 6.4: Module extensions'routines'stex + + + + + +
+ +
+ +ELENA Standard Library
6.3 +
+
+
+
+

+Module extensions'routines'stex +

+
+
+
+
+
+
    +
+
+
+ +
+ +ELENA Standard Library
6.3 +
+
+
+ + diff --git a/doc/api/extensions-routines-stex.html b/doc/api/extensions-routines-stex.html new file mode 100644 index 0000000000..00d7036bc9 --- /dev/null +++ b/doc/api/extensions-routines-stex.html @@ -0,0 +1,42 @@ + + + + +ELENA Standard Library 6.4: Module extensions'routines'stex + + + + + +
+ +
+ +ELENA Standard Library
6.3 +
+
+
+
+ +
+ +ELENA Standard Library
6.3 +
+
+
+ + diff --git a/doc/api/extensions-summary.html b/doc/api/extensions-summary.html index 98533435c2..d7cb912064 100644 --- a/doc/api/extensions-summary.html +++ b/doc/api/extensions-summary.html @@ -71,11 +71,11 @@

-byteArrayExConvertor +ByteArrayExConvertor
-public singleton byteArrayExConvertor
+public singleton ByteArrayExConvertor @@ -89,11 +89,11 @@

-intConvertExt +IntConvertExt
-public singleton intConvertExt
+public singleton IntConvertExt @@ -107,11 +107,11 @@

-intmatrixExConvertor +IntmatrixExConvertor
-public singleton intmatrixExConvertor
+public singleton IntmatrixExConvertor diff --git a/doc/api/extensions.html b/doc/api/extensions.html index b3415c2375..13a05b2f75 100644 --- a/doc/api/extensions.html +++ b/doc/api/extensions.html @@ -270,20 +270,20 @@

Constructor / Static Method Summary


- +
extensions'
-

byteArrayExConvertor

+

ByteArrayExConvertor



-public singleton byteArrayExConvertor
+public singleton ByteArrayExConvertor
    @@ -292,7 +292,7 @@

    byteArrayExConvertor

    • -extensions'byteArrayExConvertor
    • +extensions'ByteArrayExConvertor
@@ -368,20 +368,20 @@

Method Summary


- +
extensions'
-

intConvertExt

+

IntConvertExt



-public singleton intConvertExt
+public singleton IntConvertExt
    @@ -390,7 +390,7 @@

    intConvertExt

    • -extensions'intConvertExt
    • +extensions'IntConvertExt
@@ -554,20 +554,20 @@

Method Summary


- +
extensions'
-

intmatrixExConvertor

+

IntmatrixExConvertor



-public singleton intmatrixExConvertor
+public singleton IntmatrixExConvertor
    @@ -576,7 +576,7 @@

    intmatrixExConvertor

    • -extensions'intmatrixExConvertor
    • +extensions'IntmatrixExConvertor
diff --git a/doc/api/system-io.html b/doc/api/system-io.html index 0f8bf95600..a2101056b7 100644 --- a/doc/api/system-io.html +++ b/doc/api/system-io.html @@ -1279,20 +1279,29 @@

Constructor / Static Method Summary

-readContentTo(String path, TextBuilder output) +saveContent(String path, String content, Encoder encoder) + + +readContentTo(String path, TextBuilder output) + + + + + + String readContent(String path) - + WideString @@ -1301,7 +1310,7 @@

Constructor / Static Method Summary

- + File diff --git a/doc/api/system-summary.html b/doc/api/system-summary.html index 3df7b5917c..4ff759c954 100644 --- a/doc/api/system-summary.html +++ b/doc/api/system-summary.html @@ -274,20 +274,20 @@

-byteArrayConvertor +ByteArrayConvertor
-public singleton byteArrayConvertor
+public singleton ByteArrayConvertor

-byteConvertor +ByteConvertor
-public singleton byteConvertor
+public singleton ByteConvertor @@ -312,11 +312,11 @@

-charConvertor +CharConvertor
-public singleton charConvertor
+public singleton CharConvertor @@ -705,11 +705,11 @@

-intConvertor +IntConvertor
-public singleton intConvertor
+public singleton IntConvertor @@ -761,11 +761,11 @@

-longConvertor +LongConvertor
-public singleton longConvertor
+public singleton LongConvertor @@ -808,11 +808,11 @@

-mssgConvertor +MssgConvertor
-public singleton mssgConvertor
+public singleton MssgConvertor @@ -882,11 +882,11 @@

-realConvertor +RealConvertor
-public singleton realConvertor
+public singleton RealConvertor @@ -919,11 +919,11 @@

-sbyteConvertor +SByteConvertor
-public singleton sbyteConvertor
+public singleton SByteConvertor @@ -938,20 +938,20 @@

-shortArrayConvertor +ShortArrayConvertor
-public singleton shortArrayConvertor
+public singleton ShortArrayConvertor -shortConvertor +ShortConvertor
-public singleton shortConvertor
+public singleton ShortConvertor @@ -1003,11 +1003,11 @@

-stringConvertor +StringConvertor
-public singleton stringConvertor
+public singleton StringConvertor @@ -1039,11 +1039,11 @@

-uintConvertor +UIntConvertor
-public singleton uintConvertor
+public singleton UIntConvertor @@ -1067,11 +1067,11 @@

-ushortConvertor +UShortConvertor
-public singleton ushortConvertor
+public singleton UShortConvertor @@ -1106,11 +1106,11 @@

-wideConvertor +WideConvertor
-public singleton wideConvertor
+public singleton WideConvertor diff --git a/doc/api/system.html b/doc/api/system.html index 1522dfdba8..ad5ef41e7e 100644 --- a/doc/api/system.html +++ b/doc/api/system.html @@ -3122,20 +3122,20 @@

Method Summary


- +
system'
-

byteArrayConvertor

+

ByteArrayConvertor



-public singleton byteArrayConvertor
+public singleton ByteArrayConvertor
    @@ -3144,7 +3144,7 @@

    byteArrayConvertor

    • -system'byteArrayConvertor
    • +system'ByteArrayConvertor
@@ -3171,20 +3171,20 @@

Method Summary


- +
system'
-

byteConvertor

+

ByteConvertor



-public singleton byteConvertor
+public singleton ByteConvertor
    @@ -3193,7 +3193,7 @@

    byteConvertor

    • -system'byteConvertor
    • +system'ByteConvertor
@@ -4397,20 +4397,20 @@

Method Summary


- +
system'
-

charConvertor

+

CharConvertor



-public singleton charConvertor
+public singleton CharConvertor
    @@ -4419,7 +4419,7 @@

    charConvertor

    • -system'charConvertor
    • +system'CharConvertor
@@ -8404,20 +8404,20 @@

Method Summary


- +
system'
-

intConvertor

+

IntConvertor



-public singleton intConvertor
+public singleton IntConvertor
    @@ -8426,7 +8426,7 @@

    intConvertor

    • -system'intConvertor
    • +system'IntConvertor
@@ -8498,7 +8498,7 @@

Method Summary

IntNumber -convert(CharValue ch) +convert(UShortNumber n) @@ -8507,7 +8507,7 @@

Method Summary

IntNumber -convert(LongNumber l) +convert(CharValue ch) @@ -8516,7 +8516,7 @@

Method Summary

IntNumber -convert(RealNumber r) +convert(LongNumber l) @@ -8525,7 +8525,7 @@

Method Summary

IntNumber -convert(String s, IntNumber radix) +convert(RealNumber r) @@ -8534,7 +8534,7 @@

Method Summary

IntNumber -convert(String s) +convert(String s, IntNumber radix) @@ -8543,7 +8543,7 @@

Method Summary

IntNumber -convert(WideString s, IntNumber radix) +convert(String s) @@ -8552,6 +8552,15 @@

Method Summary

IntNumber +convert(WideString s, IntNumber radix) + + + + + + +IntNumber + convert(WideString s) @@ -10152,20 +10161,20 @@

Method Summary


- +
system'
-

longConvertor

+

LongConvertor



-public singleton longConvertor
+public singleton LongConvertor
    @@ -10174,7 +10183,7 @@

    longConvertor

    • -system'longConvertor
    • +system'LongConvertor
@@ -11730,20 +11739,20 @@

Constructor / Static Method Summary


- +
system'
-

mssgConvertor

+

MssgConvertor



-public singleton mssgConvertor
+public singleton MssgConvertor
    @@ -11752,7 +11761,7 @@

    mssgConvertor

    • -system'mssgConvertor
    • +system'MssgConvertor
@@ -12777,20 +12786,20 @@

Method Summary


- +
system'
-

realConvertor

+

RealConvertor



-public singleton realConvertor
+public singleton RealConvertor
    @@ -12799,7 +12808,7 @@

    realConvertor

    • -system'realConvertor
    • +system'RealConvertor
@@ -14213,20 +14222,20 @@

Method Summary


- +
system'
-

sbyteConvertor

+

SByteConvertor



-public singleton sbyteConvertor
+public singleton SByteConvertor
    @@ -14235,7 +14244,7 @@

    sbyteConvertor

    • -system'sbyteConvertor
    • +system'SByteConvertor
@@ -15102,20 +15111,20 @@

Method Summary


- +
system'
-

shortArrayConvertor

+

ShortArrayConvertor



-public singleton shortArrayConvertor
+public singleton ShortArrayConvertor
    @@ -15124,7 +15133,7 @@

    shortArrayConvertor

    • -system'shortArrayConvertor
    • +system'ShortArrayConvertor
@@ -15151,20 +15160,20 @@

Method Summary


- +
system'
-

shortConvertor

+

ShortConvertor



-public singleton shortConvertor
+public singleton ShortConvertor
    @@ -15173,7 +15182,7 @@

    shortConvertor

    • -system'shortConvertor
    • +system'ShortConvertor
@@ -17298,20 +17307,20 @@

Extension Summary


- +
system'
-

stringConvertor

+

StringConvertor



-public singleton stringConvertor
+public singleton StringConvertor
    @@ -17320,7 +17329,7 @@

    stringConvertor

    • -system'stringConvertor
    • +system'StringConvertor
@@ -17767,20 +17776,20 @@

Constructor / Static Method Summary


- +
system'
-

uintConvertor

+

UIntConvertor



-public singleton uintConvertor
+public singleton UIntConvertor
    @@ -17789,7 +17798,7 @@

    uintConvertor

    • -system'uintConvertor
    • +system'UIntConvertor
@@ -19107,32 +19116,63 @@

Static Property Summary

+ +
    +
  • +

    Conversion Summary

    + + + + + + + @@ -19140,7 +19180,15 @@

    Conversion Summary

    +WideString + + + + @@ -19189,20 +19237,20 @@

    Method Summary


    - +
    system'
    -

    ushortConvertor

    +

    UShortConvertor



    -public singleton ushortConvertor
    +public singleton UShortConvertor
      @@ -19211,7 +19259,7 @@

      ushortConvertor

      • -system'ushortConvertor
      • +system'UShortConvertor
    @@ -20485,20 +20533,20 @@

    Method Summary


    - +
    system'
    -

    wideConvertor

    +

    WideConvertor



    -public singleton wideConvertor
    +public singleton WideConvertor
      @@ -20507,7 +20555,7 @@

      wideConvertor

      • -system'wideConvertor
      • +system'WideConvertor
    diff --git a/doc/tech/bytecode60.txt b/doc/tech/bytecode60.txt index 295e35599f..0e13c81fec 100644 --- a/doc/tech/bytecode60.txt +++ b/doc/tech/bytecode60.txt @@ -64,6 +64,8 @@ ELENA byte codes (or ecodes) bload - index := byte([acc]) + convl - index => long:index + get i - acc[i] => acc lload - long:index := long:[acc] @@ -184,8 +186,6 @@ ELENA byte codes (or ecodes) attach - include the exluded managed frame link; should immediately preceed open opcode - convl - index => long:index - dalloc - sp += index ; reserve and fill with zeros; new sp value is aligned to 2 in x86-64 mode @@ -529,3 +529,5 @@ ELENA byte codes (or ecodes) xlabel dp:i, r - set a handler to the specified address / label + xnop - align the following label to CPU optimized jump alignment + diff --git a/doc/todo.txt b/doc/todo.txt index e2cdb16077..972f40f7b4 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -5,34 +5,37 @@ In development: [development] ### EPIC: elena 6.5 ### - === Iteration 34 === + === Iteration 34 (21.10) === -------------------------------------- dev: - upndown (connector) - #496 - - toArray extension method (parameterized method extensions) - - #676 - - #622 (http client) + - #622 gen: - lpad : generate a code based on a record maint: - - #689 - unit tests : bt optimization - test binary file operations - - test encoders with files - 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 / linux + - review pi performance (must < 6) port: tools: - #658 : connect with ldbg from VSCode prom: posting weekly -------------------------------------- + * http client + * test linix versions + * test all x86 examples (net) * x86-64 : mta - main sample sandbox2 - * forms : review warnings - * test all examples : db + * x86-64 mta - sandbox2 : fix GC issue + * review if using xnop impoves performance (pi & anagram samples) + * validate bsredirect (on several examples) - if it is better with nop or not -------------------------------------- - * fix x86-64 : mta - sandbox2 + * new opcode xnop - if the jump alignment optimization is on, the follow command is alligned to 16bit offset ### EPIC: elena 6.6 ### diff --git a/elenasrc3/common/common.h b/elenasrc3/common/common.h index dfe006427a..c035292e05 100644 --- a/elenasrc3/common/common.h +++ b/elenasrc3/common/common.h @@ -3,7 +3,7 @@ // // This file contains the common templates, classes, // structures, functions and constants -// (C)2021-2022, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef COMMON_H @@ -106,4 +106,31 @@ namespace elena_lang #define DEFAULT_STR (elena_lang::ustr_t)nullptr +namespace elena_lang +{ + // --- ExceptionBase --- + class ExceptionBase {}; + + class AbortError : ExceptionBase {}; + + // --- InternalError --- + struct InternalError : ExceptionBase + { + int messageCode; + int arg; + + InternalError(int messageCode) + { + this->messageCode = messageCode; + this->arg = 0; + } + + InternalError(int messageCode, int arg) + { + this->messageCode = messageCode; + this->arg = arg; + } + }; +} + #endif // COMMON_H diff --git a/elenasrc3/common/config.cpp b/elenasrc3/common/config.cpp index 74c7036f50..14eaabb530 100644 --- a/elenasrc3/common/config.cpp +++ b/elenasrc3/common/config.cpp @@ -62,6 +62,14 @@ void ConfigFile :: appendSetting(ustr_t xpath, ustr_t value) else node.setContent(value); } +void ConfigFile :: removeSetting(ustr_t xpath) +{ + XmlNode node = _tree.selectNode(xpath); + if (!node.isNotFound()) { + node.remove(); + } +} + void ConfigFile :: create() { _tree.loadXml(""); diff --git a/elenasrc3/common/config.h b/elenasrc3/common/config.h index d9e6cab206..66c5ff4057 100644 --- a/elenasrc3/common/config.h +++ b/elenasrc3/common/config.h @@ -132,6 +132,8 @@ namespace elena_lang void appendSetting(ustr_t xpath, ustr_t value); + void removeSetting(ustr_t xpath); + void create(); bool load(path_t path, FileEncoding encoding); diff --git a/elenasrc3/common/dump.cpp b/elenasrc3/common/dump.cpp index e822de41f8..a5735cc086 100644 --- a/elenasrc3/common/dump.cpp +++ b/elenasrc3/common/dump.cpp @@ -22,6 +22,8 @@ MemoryDump :: MemoryDump() _total = SECTION_PAGE_SIZE; _buffer = realloc(nullptr, SECTION_PAGE_SIZE); + + assert(_buffer != nullptr); } MemoryDump :: MemoryDump(pos_t capacity) @@ -30,6 +32,8 @@ MemoryDump :: MemoryDump(pos_t capacity) _total = capacity; _buffer = realloc(nullptr, capacity); + + assert(_buffer != nullptr); } MemoryDump :: MemoryDump(const MemoryDump& copy) @@ -54,6 +58,7 @@ void MemoryDump :: reserve(pos_t size) _buffer = newBuffer; _total = newSize; } + else throw InternalError(errFailedMemoryAllocation); } } diff --git a/elenasrc3/common/dump.h b/elenasrc3/common/dump.h index 2e1d1dc569..5e06989079 100644 --- a/elenasrc3/common/dump.h +++ b/elenasrc3/common/dump.h @@ -11,6 +11,8 @@ namespace elena_lang { + constexpr auto errFailedMemoryAllocation = -16; + // --- MemoryDump --- class MemoryDump : public MemoryBase diff --git a/elenasrc3/common/lists.h b/elenasrc3/common/lists.h index 5a995c7fcd..f87c002ae1 100644 --- a/elenasrc3/common/lists.h +++ b/elenasrc3/common/lists.h @@ -2763,6 +2763,8 @@ namespace elena_lang { Key key; T item; + + CachedItem() = default; }; class CachedMemoryMapIterator diff --git a/elenasrc3/common/tree.h b/elenasrc3/common/tree.h index 6c9351f389..5f46bfab8b 100644 --- a/elenasrc3/common/tree.h +++ b/elenasrc3/common/tree.h @@ -127,7 +127,11 @@ namespace elena_lang pos_t position = stringWriter.position(); - stringWriter.writeString(strArgument, getlength_pos(strArgument) + 1); + pos_t len = getlength_pos(strArgument); + if (len > 0) { + stringWriter.writeString(strArgument, len + 1); + } + else stringWriter.writeByte(0); return position; } @@ -485,7 +489,7 @@ namespace elena_lang { NodeRecord* record = (NodeRecord*)_tree->_body.get(_position); if (record->child != INVALID_POS) { - NodeArg arg(argument, INVALID_POS); + NodeArg arg((ref_t)argument, INVALID_POS); pos_t child = _tree->injectChild(_position, key, arg); @@ -494,6 +498,51 @@ namespace elena_lang else return appendChild(key, argument); } + // enclose the node with a new one + Node encloseNode(Key key, int argument = 0) + { + NodeRecord* record = (NodeRecord*)_tree->_body.get(_position); + + _tree->injectChild(_position, this->key, this->arg); + + this->key = key; + this->arg = { (ref_t)argument, INVALID_POS }; + + _tree->save(_position, this->key, this->arg); + + return *this; + } + + Node mergeNodes(Node& child) + { + NodeRecord* targetRecord = (NodeRecord*)_tree->_body.get(_position); + NodeRecord* sourceRecord = (NodeRecord*)_tree->_body.get(child._position); + + // exclude the child from the children + Node previous = child.prevNode(); + NodeRecord* prevRecord = previous.eol() ? nullptr : (NodeRecord*)_tree->_body.get(previous._position); + if (!prevRecord) { + Node childParent = child.parentNode(); + NodeRecord* childParentRecord = (NodeRecord*)_tree->_body.get(childParent._position); + + childParentRecord->child = sourceRecord->next; + } + else prevRecord->next = sourceRecord->next; + + // append the source to the current node + sourceRecord->parent = _position; + sourceRecord->next = INVALID_POS; + + Node lastChild = this->lastChild(); + if (!lastChild.eol()) { + NodeRecord* lastRecord = (NodeRecord*)_tree->_body.get(lastChild._position); + lastRecord->next = child._position; + } + else targetRecord->child = child._position; + + return *this; + } + bool eol() const { return _position == INVALID_POS; @@ -646,6 +695,11 @@ namespace elena_lang return Node::read(_tree, _current); } + Tree* getOwner() + { + return _tree; + } + void clear() { _tree->clear(); @@ -670,6 +724,12 @@ namespace elena_lang } }; + + bool isTreeNode(Node node) + { + return this == node._tree; + } + Node readRoot() { return _body.length() != 0 ? Node::read(this, 0u) : Node(); diff --git a/elenasrc3/elc/clicommon.h b/elenasrc3/elc/clicommon.h index 65ea1e9411..7a766c4a11 100644 --- a/elenasrc3/elc/clicommon.h +++ b/elenasrc3/elc/clicommon.h @@ -313,6 +313,7 @@ class ModuleScopeBase : public SectionScopeBase Map cachedEmbeddableArrays; Map cachedStacksafeArgs; Map cachedWrappers; + Map cachedClosed; virtual bool isStandardOne() = 0; virtual bool withValidation() = 0; @@ -373,7 +374,8 @@ class ModuleScopeBase : public SectionScopeBase cachedEmbeddableStructs(false), cachedEmbeddableArrays(false), cachedStacksafeArgs(false), - cachedWrappers(false) + cachedWrappers(false), + cachedClosed(false) { this->module = module; this->debugModule = debugModule; @@ -550,6 +552,9 @@ class SyntaxWriterBase virtual void newNode(parse_key_t key, ustr_t arg) = 0; virtual void injectNode(parse_key_t key) = 0; virtual void renameNode(parse_key_t key) = 0; + virtual void mergeRChildren(parse_key_t key) = 0; + virtual void mergeLChildren(parse_key_t key) = 0; + virtual void encloseLastChild(parse_key_t key) = 0; virtual void appendTerminal(parse_key_t key, ustr_t value, LineInfo lineInfo) = 0; diff --git a/elenasrc3/elc/cliconst.h b/elenasrc3/elc/cliconst.h index 78e78838fd..ef12c3b64c 100644 --- a/elenasrc3/elc/cliconst.h +++ b/elenasrc3/elc/cliconst.h @@ -13,7 +13,7 @@ namespace elena_lang { - #define ELC_REVISION_NUMBER 0x005B + #define ELC_REVISION_NUMBER 0x0069 #if defined _M_IX86 || _M_X64 @@ -30,6 +30,7 @@ namespace elena_lang // --- Information messages --- constexpr auto ELC_GREETING = "ELENA Command-line compiler %d.%d.%d (C)2005-2024 by Aleksey Rakov, ELENA-LANG Org\n"; constexpr auto ELC_STARTING = "\nProject: %s, Platform: %s, Target type: %s"; + constexpr auto ELC_STRICT_MODE = "Strict type enforcing is on"; constexpr auto ELC_PROFILE_INFO = "Project profile: %s"; constexpr auto ELC_CLEANING = "Cleaning up"; constexpr auto ELC_LINKING = "Linking..\n"; @@ -50,7 +51,7 @@ namespace elena_lang 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 -xm[-] - turn on / off auto loading module extension list\n -xp[-] - turn on / off generation of the parameter meta info"; + 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 -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"; diff --git a/elenasrc3/elc/codeblocks/elc_amd64.mak b/elenasrc3/elc/codeblocks/elc_amd64.mak index 68097e3a82..c0654f50ba 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 +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 all: release @@ -148,6 +148,9 @@ $(OBJDIR_RELEASE)/__/linux/elflinker64.o: ../linux/elflinker64.cpp $(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 diff --git a/elenasrc3/elc/codeblocks/elc_arm64.mak b/elenasrc3/elc/codeblocks/elc_arm64.mak index 4c0928b0d7..75d0e8200d 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 +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 all: release @@ -157,6 +157,9 @@ $(OBJDIR_RELEASE)/__/source.o: ../source.cpp $(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 + clean_release: rm -f $(OBJ_RELEASE) $(OUT_RELEASE) rm -rf $(OBJDIR_RELEASE)/__ diff --git a/elenasrc3/elc/codeblocks/elc_i386.mak b/elenasrc3/elc/codeblocks/elc_i386.mak index 1ccd3b7cc9..7fc4d678d6 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 +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 all: release @@ -160,6 +160,9 @@ $(OBJDIR_RELEASE)/__/source.o: ../source.cpp $(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 + clean_release: rm -f $(OBJ_RELEASE) $(OUT_RELEASE) rm -rf $(OBJDIR_RELEASE)/__ diff --git a/elenasrc3/elc/codeblocks/elc_linux_x86.cbp b/elenasrc3/elc/codeblocks/elc_linux_x86.cbp index c888056492..45935abd1a 100644 --- a/elenasrc3/elc/codeblocks/elc_linux_x86.cbp +++ b/elenasrc3/elc/codeblocks/elc_linux_x86.cbp @@ -102,6 +102,8 @@ + + @@ -139,12 +141,18 @@ + + + + + + diff --git a/elenasrc3/elc/codeblocks/elc_ppc64le.mak b/elenasrc3/elc/codeblocks/elc_ppc64le.mak index 50af70d1c8..1c8cbb0918 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 +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 all: release @@ -142,6 +142,9 @@ $(OBJDIR_RELEASE)/__/linux/elflinker64.o: ../linux/elflinker64.cpp $(OBJDIR_RELEASE)/__/linux/elfppclinker64.o: ../linux/elfppclinker64.cpp $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c ../linux/elfppclinker64.cpp -o $(OBJDIR_RELEASE)/__/linux/elfppclinker64.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 diff --git a/elenasrc3/elc/codeimage.cpp b/elenasrc3/elc/codeimage.cpp index 60c105feb0..819aea189c 100644 --- a/elenasrc3/elc/codeimage.cpp +++ b/elenasrc3/elc/codeimage.cpp @@ -87,7 +87,7 @@ TargetImage :: TargetImage(PlatformType systemTarget, ForwardResolverBase* resol dummyModule, dummyModule->mapReference(resolver->resolveForward(START_FORWARD)), 0}); MemoryDump tapeSymbol; - generateAutoSymbol(dummyModule, tapeSymbol); + generateAutoSymbol(dummyModule, tapeSymbol, true); addr_t vaddress = linker.resolveTemporalByteCode(tapeSymbol, dummyModule); mapReference(STARTUP_ENTRY, vaddress, mskSymbolRef); @@ -198,7 +198,7 @@ void TargetImage :: prepareImage(ustr_t ns) debugWriter.writeString(ns); } -void TargetImage :: generateAutoSymbol(ModuleBase* module, MemoryDump& tapeSymbol) +void TargetImage :: generateAutoSymbol(ModuleBase* module, MemoryDump& tapeSymbol, bool withExtFrame) { // fill the list of virtual references ModuleInfoList symbolList({}); @@ -209,5 +209,5 @@ void TargetImage :: generateAutoSymbol(ModuleBase* module, MemoryDump& tapeSymbo } }); - ByteCodeUtil::generateAutoSymbol(symbolList, module, tapeSymbol); + ByteCodeUtil::generateAutoSymbol(symbolList, module, tapeSymbol, withExtFrame); } diff --git a/elenasrc3/elc/codeimage.h b/elenasrc3/elc/codeimage.h index a8caf7f372..a045cfcee7 100644 --- a/elenasrc3/elc/codeimage.h +++ b/elenasrc3/elc/codeimage.h @@ -71,7 +71,7 @@ namespace elena_lang return _stackReserved; } - void generateAutoSymbol(ModuleBase* module, MemoryDump& tapeSymbol); + void generateAutoSymbol(ModuleBase* module, MemoryDump& tapeSymbol, bool withExtFrame); TargetImage(PlatformType systemTarget, ForwardResolverBase* resolver, LibraryLoaderBase* loader, JITCompilerBase* (*jitCompilerFactory)(LibraryLoaderBase*, PlatformType), diff --git a/elenasrc3/elc/compiler.cpp b/elenasrc3/elc/compiler.cpp index aaf1942b3d..f10c2b5690 100644 --- a/elenasrc3/elc/compiler.cpp +++ b/elenasrc3/elc/compiler.cpp @@ -1887,6 +1887,7 @@ Compiler::Compiler( _verbose = false; _noValidation = false; _withDebugInfo = true; + _strictTypeEnforcing = false; _trackingUnassigned = false; @@ -2154,8 +2155,6 @@ bool Compiler::importTemplate(Scope& scope, SyntaxNode node, SyntaxNode target, bool Compiler::includeBlock(Scope& scope, SyntaxNode node, SyntaxNode target) { - TypeAttributes attributes = {}; - bool textBlock = false; declareIncludeAttributes(scope, node, textBlock); if (!textBlock) @@ -2230,7 +2229,7 @@ bool Compiler::importPropertyTemplate(Scope& scope, SyntaxNode node, ustr_t post return true; } -ustr_t Compiler::retrieveDictionaryOwner(Scope& scope, ustr_t properName, ustr_t defaultPrefix, EAttr mode) +ustr_t Compiler :: retrieveDictionaryOwner(Scope& scope, ustr_t properName, ustr_t defaultPrefix, EAttr mode) { if (EAttrs::test(mode, EAttr::StrongResolved)) return defaultPrefix; @@ -2245,6 +2244,10 @@ ustr_t Compiler::retrieveDictionaryOwner(Scope& scope, ustr_t properName, ustr_t return *it; } + if (nsScope->parent) { + return retrieveDictionaryOwner(*nsScope->parent, properName, defaultPrefix, mode); + } + return defaultPrefix; } @@ -2256,15 +2259,15 @@ void Compiler::declareDictionary(Scope& scope, SyntaxNode node, Visibility visib if (superMode) { switch (level) { - case Scope::ScopeLevel::Class: - level = Scope::ScopeLevel::Namespace; - break; - case Scope::ScopeLevel::Method: - case Scope::ScopeLevel::Field: - level = Scope::ScopeLevel::Class; - break; - default: - break; + case Scope::ScopeLevel::Class: + level = Scope::ScopeLevel::Namespace; + break; + case Scope::ScopeLevel::Method: + case Scope::ScopeLevel::Field: + level = Scope::ScopeLevel::Class; + break; + default: + break; } } @@ -2967,7 +2970,7 @@ void Compiler :: declareByRefHandler(SyntaxNode classNode, SyntaxKey methodType, } else { handlerInfo.hints |= (ref_t)MethodHint::Indexed; - handlerInfo.hints |= (ref_t)MethodHint::Normal; + handlerInfo.hints |= test(info.header.flags, elSealed) ? (ref_t)MethodHint::Sealed : (ref_t)MethodHint::Normal; if (MethodInfo::checkVisibility(methodInfo, MethodHint::Protected)) { handlerInfo.hints |= (ref_t)MethodHint::Protected; } @@ -3211,8 +3214,10 @@ void Compiler::generateClassFlags(ClassScope& scope, ref_t declaredFlags) { scope.info.header.flags |= declaredFlags; - if (test(scope.info.header.flags, elExtension)) + if (test(scope.info.header.flags, elExtension)) { + scope.info.header.flags |= elSealed; scope.addAttribute(ClassAttribute::ExtensionRef, scope.extensionClassRef); + } } void Compiler::generateClassStaticField(ClassScope& scope, SyntaxNode node, FieldAttributes& attrs) @@ -3229,7 +3234,6 @@ void Compiler::generateClassStaticField(ClassScope& scope, SyntaxNode node, Fiel TypeInfo typeInfo = attrs.typeInfo; bool isConst = attrs.isConstant; - ref_t flags = scope.info.header.flags; if (attrs.size < 0) { if (!attrs.inlineArray) { @@ -3610,34 +3614,34 @@ void Compiler::declareSymbolMetaInfo(SymbolScope& 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); - break; - case SyntaxKey::MetaExpression: - { - MetaScope metaScope(&scope, Scope::ScopeLevel::Symbol); + case SyntaxKey::InlineTemplate: + if (!importInlineTemplate(scope, current, INLINE_PREFIX, node)) + scope.raiseError(errUnknownTemplate, node); + break; + case SyntaxKey::MetaExpression: + { + MetaScope metaScope(&scope, Scope::ScopeLevel::Symbol); - evalStatement(metaScope, current); - break; - } - case SyntaxKey::MetaDictionary: - declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Field, false); - break; - case SyntaxKey::SharedMetaDictionary: - declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Field, true); - break; - //case SyntaxKey::Name: - //case SyntaxKey::Type: - //case SyntaxKey::ArrayType: - //case SyntaxKey::TemplateType: - //case SyntaxKey::Attribute: - //case SyntaxKey::Dimension: - //case SyntaxKey::EOP: - // break; - default: - // scope.raiseError(errInvalidSyntax, node); - break; + evalStatement(metaScope, current); + break; + } + case SyntaxKey::MetaDictionary: + declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Field, false); + break; + case SyntaxKey::SharedMetaDictionary: + declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Field, true); + break; + //case SyntaxKey::Name: + //case SyntaxKey::Type: + //case SyntaxKey::ArrayType: + //case SyntaxKey::TemplateType: + //case SyntaxKey::Attribute: + //case SyntaxKey::Dimension: + //case SyntaxKey::EOP: + // break; + default: + // scope.raiseError(errInvalidSyntax, node); + break; } current = current.nextNode(); @@ -3992,8 +3996,6 @@ void Compiler :: declareVMTMessage(MethodScope& scope, SyntaxNode node, bool wit // if it is an explicit constant conversion if (constantConversion) { - NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); - addExtensionMessage(scope, scope.message, scope.getClassRef(), scope.message, scope.getClassVisibility() != Visibility::Public); } @@ -4079,7 +4081,7 @@ void Compiler::inheritStaticMethods(ClassScope& scope, SyntaxNode classNode) if (!methodInfo.inherited && MethodInfo::checkType(methodInfo, MethodHint::Sealed) && MethodScope::checkHint(methodInfo, MethodHint::Static)) { - scope.info.attributes.add({ it.key(), ClassAttribute::SealedStatic }, scope.reference); + scope.info.attributes.add({ key, ClassAttribute::SealedStatic }, scope.reference); } } } @@ -4283,7 +4285,7 @@ ObjectInfo Compiler::evalPropertyOperation(Interpreter& interpreter, Scope& scop CheckMethodResult result = {}; bool found = _logic->resolveCallType(*scope.moduleScope, resolveStrongType(scope, loperand.typeInfo), message, result); - if (result.constRef) { + if (found && result.constRef) { NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); return nsScope->defineObjectInfo(result.constRef, EAttr::None, true); @@ -4336,7 +4338,6 @@ ObjectInfo Compiler::evalCollection(Interpreter& interpreter, Scope& scope, Synt } ArgumentsInfo arguments; - EAttr paramMode = EAttr::Parameter; while (current != SyntaxKey::None) { if (current == SyntaxKey::Expression) { auto argInfo = evalExpression(interpreter, scope, current, ignoreErrors); @@ -4559,7 +4560,7 @@ int Compiler::defineFieldSize(Scope& scope, ObjectInfo info) auto f_it = classScope->info.fields.start(); while (!f_it.eof()) { auto fieldInfo = *f_it; - if (fieldInfo.offset == info.reference) + if (fieldInfo.offset == (int)info.reference) break; ++f_it; @@ -4707,26 +4708,26 @@ void Compiler::declareSymbolAttributes(SymbolScope& scope, SyntaxNode node, bool SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { switch (current.key) { - case SyntaxKey::Attribute: - if (!_logic->validateSymbolAttribute(current.arg.value, scope.visibility, constant, scope.type)) { - current.setArgumentValue(0); // HOTFIX : to prevent duplicate warnings - scope.raiseWarning(WARNING_LEVEL_1, wrnInvalidHint, current); - } - break; - case SyntaxKey::Type: - case SyntaxKey::ArrayType: - case SyntaxKey::TemplateType: - if (!identifierDeclarationMode) { - auto typeInfo = resolveStrongTypeAttribute(scope, current, true, false); - scope.info.typeRef = typeInfo.typeRef; + case SyntaxKey::Attribute: + if (!_logic->validateSymbolAttribute(current.arg.value, scope.visibility, constant, scope.type)) { + current.setArgumentValue(0); // HOTFIX : to prevent duplicate warnings + scope.raiseWarning(WARNING_LEVEL_1, wrnInvalidHint, current); + } + break; + case SyntaxKey::Type: + case SyntaxKey::ArrayType: + case SyntaxKey::TemplateType: + if (!identifierDeclarationMode) { + auto typeInfo = resolveStrongTypeAttribute(scope, current, true, false); + scope.info.typeRef = typeInfo.typeRef; - if (typeInfo.nillable) - scope.raiseError(errInvalidOperation, node); - } + if (typeInfo.nillable) + scope.raiseError(errInvalidOperation, node); + } - break; - default: - break; + break; + default: + break; } current = current.nextNode(); @@ -5406,21 +5407,21 @@ void Compiler::declareTemplateAttributes(Scope& scope, SyntaxNode node, SyntaxNode current = objectMode ? node.nextNode() : node.firstChild(); while (current != SyntaxKey::None) { switch (current.key) { - case SyntaxKey::Attribute: - if (!_logic->validateTypeScopeAttribute(current.arg.reference, attributes)) - scope.raiseWarning(WARNING_LEVEL_1, wrnInvalidHint, current); - break; - case SyntaxKey::TemplateArg: - case SyntaxKey::Type: - case SyntaxKey::TemplateType: - { - auto typeInfo = resolveStrongTypeAttribute(scope, current, declarationMode, attributes.mssgNameLiteral); - parameters.add(typeInfo.typeRef); + case SyntaxKey::Attribute: + if (!_logic->validateTypeScopeAttribute(current.arg.reference, attributes)) + scope.raiseWarning(WARNING_LEVEL_1, wrnInvalidHint, current); + break; + case SyntaxKey::TemplateArg: + case SyntaxKey::Type: + case SyntaxKey::TemplateType: + { + auto typeInfo = resolveStrongTypeAttribute(scope, current, declarationMode, attributes.mssgNameLiteral); + parameters.add(typeInfo.typeRef); - break; - } - default: - break; + break; + } + default: + break; } current = current.nextNode(); @@ -5492,8 +5493,6 @@ ref_t Compiler::resolveTypeTemplate(Scope& scope, SyntaxNode node, if (!templateRef) scope.raiseError(errUnknownClass, terminalNode); - NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); - return _templateProcessor->generateClassTemplate(*scope.moduleScope, templateRef, parameters, declarationMode, nullptr); } @@ -5556,8 +5555,6 @@ ref_t Compiler::resolveStateMachine(Scope& scope, ref_t templateRef, ref_t eleme } else templateReference = scope.moduleScope->mapFullReference(*smName, true); - NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); - return _templateProcessor->generateClassTemplate(*scope.moduleScope, templateReference, parameters, false, nullptr); } @@ -5637,52 +5634,52 @@ TypeInfo Compiler::resolveTypeAttribute(Scope& scope, SyntaxNode node, TypeAttri { TypeInfo typeInfo = {}; switch (node.key) { - case SyntaxKey::TemplateArg: - typeInfo = resolveTypeAttribute(scope, node.firstChild(), attributes, declarationMode, allowRole); - break; - case SyntaxKey::Type: - { - if (node.arg.reference) - return { node.arg.reference }; + case SyntaxKey::TemplateArg: + typeInfo = resolveTypeAttribute(scope, node.firstChild(), attributes, declarationMode, allowRole); + break; + case SyntaxKey::Type: + { + if (node.arg.reference) + return { node.arg.reference }; - SyntaxNode current = node.firstChild(); - if (current == SyntaxKey::Type || current == SyntaxKey::ArrayType || current == SyntaxKey::NullableType) { - // !! should be refactored - typeInfo = resolveTypeAttribute(scope, current, attributes, declarationMode, allowRole); - } - else if (current == SyntaxKey::TemplateType) { - typeInfo.typeRef = 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 + SyntaxNode current = node.firstChild(); + if (current == SyntaxKey::Type || current == SyntaxKey::ArrayType || current == SyntaxKey::NullableType) { + // !! should be refactored + typeInfo = resolveTypeAttribute(scope, current, attributes, declarationMode, allowRole); + } + else if (current == SyntaxKey::TemplateType) { typeInfo.typeRef = resolveTypeTemplate(scope, current, attributes, declarationMode); } - else typeInfo.typeRef = resolveTypeIdentifier(scope, current.identifier(), current.key, declarationMode, allowRole); + 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); + } + else typeInfo.typeRef = resolveTypeIdentifier(scope, current.identifier(), current.key, declarationMode, allowRole); + } + else assert(false); + break; } - else assert(false); - break; - } - case SyntaxKey::TemplateType: - typeInfo.typeRef = resolveTypeTemplate(scope, node, attributes, declarationMode); - break; - case SyntaxKey::ArrayType: - { - typeInfo = resolveTypeScope(scope, node, attributes, declarationMode, allowRole); + case SyntaxKey::TemplateType: + typeInfo.typeRef = resolveTypeTemplate(scope, node, attributes, declarationMode); + break; + case SyntaxKey::ArrayType: + { + typeInfo = resolveTypeScope(scope, node, attributes, declarationMode, allowRole); - if (attributes.variadicOne) - scope.raiseError(errInvalidOperation, node); - break; - } - case SyntaxKey::NullableType: - typeInfo = resolveTypeScope(scope, node, attributes, declarationMode, allowRole); - break; - default: - if (SyntaxTree::test(node.key, SyntaxKey::TerminalMask)) { - typeInfo.typeRef = resolveTypeIdentifier(scope, node.identifier(), node.key, declarationMode, allowRole); + if (attributes.variadicOne) + scope.raiseError(errInvalidOperation, node); + break; } - else assert(false); - break; + case SyntaxKey::NullableType: + typeInfo = resolveTypeScope(scope, node, attributes, declarationMode, allowRole); + break; + default: + if (SyntaxTree::test(node.key, SyntaxKey::TerminalMask)) { + typeInfo.typeRef = resolveTypeIdentifier(scope, node.identifier(), node.key, declarationMode, allowRole); + } + else assert(false); + break; } validateType(scope, typeInfo.typeRef, node, declarationMode); @@ -6142,7 +6139,7 @@ bool Compiler::evalAccumClassConstant(ustr_t constName, ClassScope& scope, Synta else constInfo.reference = mapClassConst(scope.moduleScope, scope.reference); auto fieldInfo = *(collectionInfo.fields.start()); - ref_t elementTypeRef = resolveStrongType(scope, { fieldInfo.typeInfo.elementRef }); + /*ref_t elementTypeRef = */resolveStrongType(scope, { fieldInfo.typeInfo.elementRef }); ObjectInfo value = evalExpression(interpreter, scope, node); if (value.kind == ObjectKind::Symbol && value.reference == scope.reference) { @@ -6500,6 +6497,10 @@ mssg_t Compiler::mapMessage(Scope& scope, SyntaxNode current, bool propertyMode, current = current.nextNode(); } + // HOTFIX : skip tempalte args + while (current == SyntaxKey::TemplateArg) + current = current.nextNode(); + pos_t argCount = 1; while (current != SyntaxKey::None) { argCount++; @@ -6556,8 +6557,6 @@ ref_t Compiler :: compileExtensionDispatcher(BuildTreeWriter& writer, NamespaceS targets.add(extInfo.value2, extInfo.value1); } - - _logic->injectMethodOverloadList(this, *scope.moduleScope, MethodHint::Sealed, genericMessage | FUNCTION_MESSAGE, methods, classScope.info.attributes, &targets, targetResolver, ClassAttribute::OverloadList); @@ -6591,8 +6590,8 @@ ref_t Compiler :: compileExtensionDispatcher(BuildTreeWriter& writer, NamespaceS return extRef; } -ref_t Compiler::mapExtension(BuildTreeWriter& writer, Scope& scope, mssg_t& message, ref_t& implicitSignatureRef, - ObjectInfo object, int& stackSafeAttr) +ref_t Compiler :: mapExtension(BuildTreeWriter& writer, Scope& scope, MessageCallContext& context, + ObjectInfo object, mssg_t& resolvedMessage, int& stackSafeAttr) { NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); @@ -6601,34 +6600,41 @@ ref_t Compiler::mapExtension(BuildTreeWriter& writer, Scope& scope, mssg_t& mess objectRef = scope.moduleScope->buildins.superReference; } - if (implicitSignatureRef) { + if (context.templateArgCount > 0) { + // auto generate extension template for explicitly defined strong-typed signature + for (auto it = nsScope->extensionTemplates.getIt(context.weakMessage); !it.eof(); it = nsScope->extensionTemplates.nextIt(context.weakMessage, it)) { + _logic->resolveExtensionTemplateByTemplateArgs(*scope.moduleScope, this, *it, + *nsScope->nsName, context.templateArgCount, context.templateArgs, nsScope->outerExtensionList ? nsScope->outerExtensionList : &nsScope->extensions); + } + } + else if (context.implicitSignatureRef) { // auto generate extension template for strong-typed signature - for (auto it = nsScope->extensionTemplates.getIt(message); !it.eof(); it = nsScope->extensionTemplates.nextIt(message, it)) { + for (auto it = nsScope->extensionTemplates.getIt(context.weakMessage); !it.eof(); it = nsScope->extensionTemplates.nextIt(context.weakMessage, it)) { _logic->resolveExtensionTemplate(*scope.moduleScope, this, *it, - implicitSignatureRef, *nsScope->nsName, nsScope->outerExtensionList ? nsScope->outerExtensionList : &nsScope->extensions); + context.implicitSignatureRef, *nsScope->nsName, nsScope->outerExtensionList ? nsScope->outerExtensionList : &nsScope->extensions); } } // check extensions - auto it = nsScope->extensions.getIt(message); + auto it = nsScope->extensions.getIt(context.weakMessage); if (!it.eof()) { // generate an extension signature ref_t signatures[ARG_COUNT] = {}; - size_t signatureLen = scope.module->resolveSignature(implicitSignatureRef, signatures); + size_t signatureLen = scope.module->resolveSignature(context.implicitSignatureRef, signatures); for (size_t i = signatureLen; i > 0; i--) signatures[i] = signatures[i - 1]; signatures[0] = objectRef; signatureLen++; - size_t argCount = getArgCount(message); + size_t argCount = getArgCount(context.weakMessage); while (signatureLen < argCount) { signatures[signatureLen] = scope.moduleScope->buildins.superReference; signatureLen++; } scope.module->mapSignature(signatures, signatureLen, false); - mssg_t resolvedMessage = 0; + resolvedMessage = 0; ref_t resolvedExtRef = 0; int resolvedStackSafeAttr = 0; int counter = 0; @@ -6657,17 +6663,16 @@ ref_t Compiler::mapExtension(BuildTreeWriter& writer, Scope& scope, mssg_t& mess } counter++; - it = nsScope->extensions.nextIt(message, it); + it = nsScope->extensions.nextIt(context.weakMessage, it); } if (resolvedMessage) { - if (counter > 1 && (implicitSignatureRef == 0 && getArgCount(message) > 1)) { + if (counter > 1 && (context.implicitSignatureRef == 0 && getArgCount(context.weakMessage) > 1)) { // HOTFIX : does not resolve an ambigous extension for a weak message // excluding messages without arguments } else { // if we are lucky - use the resolved one - message = resolvedMessage; stackSafeAttr = resolvedStackSafeAttr; return resolvedExtRef; @@ -6675,15 +6680,15 @@ ref_t Compiler::mapExtension(BuildTreeWriter& writer, Scope& scope, mssg_t& mess } // bad luck - we have to generate run-time extension dispatcher - implicitSignatureRef = 0; - ref_t extRef = nsScope->extensionDispatchers.get(message); + context.implicitSignatureRef = 0; + ref_t extRef = nsScope->extensionDispatchers.get(context.weakMessage); if (extRef == INVALID_REF) { - extRef = compileExtensionDispatcher(writer, *nsScope, message, 0); + extRef = compileExtensionDispatcher(writer, *nsScope, context.weakMessage, 0); - nsScope->extensionDispatchers.add(message, extRef); + nsScope->extensionDispatchers.add(context.weakMessage, extRef); } - message |= FUNCTION_MESSAGE; + resolvedMessage = context.weakMessage |=FUNCTION_MESSAGE; return extRef; } @@ -6712,6 +6717,15 @@ inline SyntaxNode findMessageNode(SyntaxNode node) return node.findChild(SyntaxKey::Message); } +inline SyntaxNode findFunctionNode(SyntaxNode node) +{ + if (node != SyntaxKey::Object) + node = node.firstChild(); + + SyntaxNode terminal = node.firstChild(SyntaxKey::TerminalMask); + return terminal; +} + void Compiler::addBreakpoint(BuildTreeWriter& writer, SyntaxNode node, BuildKey bpKey) { SyntaxNode terminal = node.firstChild(SyntaxKey::TerminalMask); @@ -6729,12 +6743,12 @@ void Compiler::addBreakpoint(BuildTreeWriter& writer, SyntaxNode node, BuildKey bool invalidObjectMode(ObjectInfo info) { switch (info.mode) { - case TargetMode::None: - case TargetMode::Conditional: - case TargetMode::Weak: - return false; - default: - return true; + case TargetMode::None: + case TargetMode::Conditional: + case TargetMode::Weak: + return false; + default: + return true; } } @@ -6874,12 +6888,12 @@ ObjectInfo Compiler::mapMessageConstant(Scope& scope, SyntaxNode node, ref_t act Interpreter interpreter(scope.moduleScope, _logic); ObjectInfo retVal = evalExpression(interpreter, scope, node.findChild(SyntaxKey::Expression)); switch (retVal.kind) { - case ObjectKind::IntLiteral: - argCount = retVal.extra; - break; - default: - scope.raiseError(errCannotEval, node); - break; + case ObjectKind::IntLiteral: + argCount = retVal.extra; + break; + default: + scope.raiseError(errCannotEval, node); + break; } mssg_t message = encodeMessage(actionRef, argCount, 0); @@ -6890,19 +6904,19 @@ ObjectInfo Compiler::mapMessageConstant(Scope& scope, SyntaxNode node, ref_t act return { ObjectKind::MssgLiteral, { V_MESSAGE }, constRef }; } -ObjectInfo Compiler::mapExtMessageConstant(Scope& scope, SyntaxNode node, ref_t actionRef, ref_t extension) +ObjectInfo Compiler :: mapExtMessageConstant(Scope& scope, SyntaxNode node, ref_t actionRef, ref_t extension) { pos_t argCount = 0; Interpreter interpreter(scope.moduleScope, _logic); ObjectInfo retVal = evalExpression(interpreter, scope, node.findChild(SyntaxKey::Expression)); switch (retVal.kind) { - case ObjectKind::IntLiteral: - argCount = retVal.extra; - break; - default: - scope.raiseError(errCannotEval, node); - break; + case ObjectKind::IntLiteral: + argCount = retVal.extra; + break; + default: + scope.raiseError(errCannotEval, node); + break; } mssg_t message = encodeMessage(actionRef, argCount, 0); @@ -6910,7 +6924,8 @@ ObjectInfo Compiler::mapExtMessageConstant(Scope& scope, SyntaxNode node, ref_t ByteCodeUtil::resolveMessageName(messageName, scope.module, message); size_t index = (*messageName).find('['); - assert(index != NOTFOUND_POS); // !! temporal + if (index == NOTFOUND_POS) + scope.raiseError(errInvalidOperation, node); ustr_t extRefName = scope.moduleScope->resolveFullName(extension); messageName.insert(">", index); @@ -6924,14 +6939,14 @@ ObjectInfo Compiler::mapExtMessageConstant(Scope& scope, SyntaxNode node, ref_t ref_t constType = V_EXTMESSAGE64; switch (scope.moduleScope->ptrSize) { - case 4: - constType = V_EXTMESSAGE64; - break; - case 8: - constType = V_EXTMESSAGE128; - break; - default: - break; + case 4: + constType = V_EXTMESSAGE64; + break; + case 8: + constType = V_EXTMESSAGE128; + break; + default: + break; } return { ObjectKind::ExtMssgLiteral, { constType, extension }, constRef }; @@ -7227,28 +7242,28 @@ ObjectInfo Compiler::convertIntLiteral(ExprScope& scope, SyntaxNode node, Object { bool invalid = false; switch (targetRef) { - case V_UINT8: - invalid = source.extra < 0 || source.extra > 255; - break; - case V_INT8: - invalid = source.extra < INT8_MIN || source.extra > INT8_MAX; - break; - case V_INT16: - invalid = source.extra < INT16_MIN || source.extra > INT16_MAX; - break; - case V_UINT16: - invalid = source.extra < 0 || source.extra > 65535; - break; - case V_INT64: - source.kind = ObjectKind::LongLiteral; - break; - case V_FLOAT64: - source.kind = ObjectKind::Float64Literal; - source.reference = mapFloat64Const(scope.module, source.extra); - break; - default: - invalid = true; - break; + case V_UINT8: + invalid = source.extra < 0 || source.extra > 255; + break; + case V_INT8: + invalid = source.extra < INT8_MIN || source.extra > INT8_MAX; + break; + case V_INT16: + invalid = source.extra < INT16_MIN || source.extra > INT16_MAX; + break; + case V_UINT16: + invalid = source.extra < 0 || source.extra > 65535; + break; + case V_INT64: + source.kind = ObjectKind::LongLiteral; + break; + case V_FLOAT64: + source.kind = ObjectKind::Float64Literal; + source.reference = mapFloat64Const(scope.module, source.extra); + break; + default: + invalid = true; + break; } if (invalid) { @@ -7336,8 +7351,6 @@ ref_t Compiler::resolveTupleClass(Scope& scope, SyntaxNode node, ArgumentsInfo& if (!templateReference) scope.raiseError(errInvalidOperation, node); - NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); - return _templateProcessor->generateClassTemplate(*scope.moduleScope, templateReference, parameters, false, nullptr); } @@ -7977,10 +7990,11 @@ void Compiler::compileStaticInitializerMethod(BuildTreeWriter& writer, ClassScop ArgumentsInfo args; + MessageCallContext context = { scope.moduleScope->buildins.static_init_message, 0 }; MessageResolution resolution = { true, scope.moduleScope->buildins.static_init_message }; - expression.compileMessageOperation(node, mapClassSymbol(scope, scope.reference), resolution, - 0, args, EAttr::None, nullptr); + expression.compileMessageCall(node, mapClassSymbol(scope, scope.reference), context, resolution, + args, EAttr::None, nullptr); } nestedWriter.appendNode(BuildKey::CloseFrame); @@ -8085,13 +8099,12 @@ ObjectInfo Compiler::compileRedirect(BuildTreeWriter& writer, CodeScope& codeSco arguments.add(methodScope->mapParameter(it.key(), EAttr::None)); } - ref_t signRef = getSignature(codeScope.module, messageRef); - + MessageCallContext context = { messageRef, getSignature(codeScope.module, messageRef) }; MessageResolution resolution = { true, messageRef }; - _logic->setSignatureStacksafe(*codeScope.moduleScope, signRef, resolution.stackSafeAttr); + _logic->setSignatureStacksafe(*codeScope.moduleScope, context.implicitSignatureRef, resolution.stackSafeAttr); - ObjectInfo retVal = expression.compileMessageOperation({}, target, resolution, - signRef, arguments, EAttr::None, &updatedOuterArgs); + ObjectInfo retVal = expression.compileMessageCall({}, target, context, resolution, + arguments, EAttr::None, &updatedOuterArgs); if (outputRef) { expression.convertObject(node, expression.saveToTempLocal(retVal), outputRef, true, false, false, false); @@ -8152,40 +8165,41 @@ ObjectInfo Compiler::compileResendCode(BuildTreeWriter& writer, CodeScope& codeS } } + MessageCallContext context = {}; Expression expression(this, codeScope, writer); ArgumentsInfo arguments; ArgumentsInfo updatedOuterArgs; - mssg_t messageRef = mapMessage(codeScope, current, propertyMode, codeScope.isExtension(), false); + context.weakMessage = mapMessage(codeScope, current, propertyMode, codeScope.isExtension(), false); int resolvedNillableArgs = 0; mssg_t resolvedMessage = _logic->resolveSingleDispatch(*codeScope.moduleScope, - retrieveType(codeScope, source), messageRef, isSelfCall(source), resolvedNillableArgs); + retrieveType(codeScope, source), context.weakMessage, isSelfCall(source), resolvedNillableArgs); ref_t expectedSignRef = 0; if (resolvedMessage) codeScope.module->resolveAction(getAction(resolvedMessage), expectedSignRef); - if (!test(messageRef, FUNCTION_MESSAGE)) + if (!test(context.weakMessage, FUNCTION_MESSAGE)) arguments.add(source); Expression::ArgumentListType argListType = Expression::ArgumentListType::Normal; - ref_t implicitSignatureRef = expression.compileMessageArguments(current, arguments, expectedSignRef, + context.implicitSignatureRef = expression.compileMessageArguments(current, arguments, expectedSignRef, EAttr::NoPrimitives, &updatedOuterArgs, argListType, resolvedNillableArgs); EAttr opMode = EAttr::CheckShortCircle; if (argListType == Expression::ArgumentListType::VariadicArgList || argListType == Expression::ArgumentListType::VariadicArgListWithTypecasting) { - messageRef |= VARIADIC_MESSAGE; + context.weakMessage |= VARIADIC_MESSAGE; - if (getArgCount(messageRef) > 2) - messageRef = overwriteArgCount(messageRef, 2); + if (getArgCount(context.weakMessage) > 2) + context.weakMessage = overwriteArgCount(context.weakMessage, 2); opMode = opMode | ((argListType == Expression::ArgumentListType::VariadicArgList) ? EAttr::WithVariadicArg : EAttr::WithVariadicArgCast); } - retVal = expression.compileMessageOperation(node, target, messageRef, - implicitSignatureRef, arguments, opMode, &updatedOuterArgs); + retVal = expression.compileMessageCall(node, target, context, { context.weakMessage }, + arguments, opMode, &updatedOuterArgs); expression.scope.syncStack(); } @@ -8470,6 +8484,7 @@ void Compiler::compileByRefHandlerInvoker(BuildTreeWriter& writer, MethodScope& ObjectInfo tempRetVal = expression.declareTempLocal(targetRef, false); ObjectInfo target = methodScope.mapSelf(); + MessageCallContext context = { handler, 0 }; MessageResolution resolution = { true, handler }; if (methodScope.isExtension) { resolution.extensionRef = methodScope.getClassRef(); @@ -8481,11 +8496,11 @@ void Compiler::compileByRefHandlerInvoker(BuildTreeWriter& writer, MethodScope& } addOutRetVal(arguments, tempRetVal); - ref_t signRef = getSignature(codeScope.module, handler); - _logic->setSignatureStacksafe(*codeScope.moduleScope, signRef, resolution.stackSafeAttr); + context.implicitSignatureRef = getSignature(codeScope.module, handler); + _logic->setSignatureStacksafe(*codeScope.moduleScope, context.implicitSignatureRef, resolution.stackSafeAttr); - /*ObjectInfo retVal = */expression.compileMessageOperation({}, target, resolution, - signRef, arguments, EAttr::AllowPrivateCall, nullptr); + /*ObjectInfo retVal = */expression.compileMessageCall({}, target, context, resolution, + arguments, EAttr::AllowPrivateCall, nullptr); // return temp variable expression.writeObjectInfo(expression.boxArgument(tempRetVal, false, true, false)); @@ -8691,7 +8706,7 @@ void Compiler :: compileAsyncMethod(BuildTreeWriter& writer, MethodScope& scope, // declare a state machine enumerator ref_t nestedRef = scope.moduleScope->mapAnonymous(); - StatemachineClassScope smScope(&expression.scope, nestedRef, true); + StatemachineClassScope smScope(&expression.scope, nestedRef, true); ref_t baseRef = declareAsyncStatemachine(smScope, node); BuildNode buildNode = writer.CurrentNode(); @@ -8738,16 +8753,16 @@ void Compiler :: compileAsyncMethod(BuildTreeWriter& writer, MethodScope& scope, args.add(mapClassSymbol(scope, baseRef)); args.add(retVal); - mssg_t weakMessage = encodeMessage(scope.module->mapAction(PROCEED_MESSAGE, 0, false), 2, 0); + MessageCallContext context = { encodeMessage(scope.module->mapAction(PROCEED_MESSAGE, 0, false), 2, 0), 0 }; int resolvedNillableArgs = 0; MessageResolution resolution = _logic->resolveSingleDispatch(*scope.moduleScope, - retrieveType(scope, args[0]), weakMessage, false, resolvedNillableArgs); + retrieveType(scope, args[0]), context.weakMessage, false, resolvedNillableArgs); if (resolution.message) resolution.resolved = true; - retVal = expression.compileMessageOperation(node, args[0], resolution, - 0, args, EAttr::None, nullptr); + retVal = expression.compileMessageCall(node, args[0], context, resolution, + args, EAttr::None, nullptr); // return a result expression.compileConverting(node, retVal, scope.info.outputRef, @@ -8874,11 +8889,12 @@ void Compiler::callInitMethod(Expression& expression, SyntaxNode node, ClassInfo ArgumentsInfo args; args.add({ ObjectKind::Object, { reference }, 0 }); + MessageCallContext context = { expression.scope.moduleScope->buildins.init_message, 0 }; MessageResolution resolution = { true, expression.scope.moduleScope->buildins.init_message }; _logic->setSignatureStacksafe(*expression.scope.moduleScope, 0, resolution.stackSafeAttr); - expression.compileMessageOperation(node, args[0], resolution, - 0, args, EAttr::None, nullptr); + expression.compileMessageCall(node, args[0], context, resolution, + args, EAttr::None, nullptr); } } @@ -8906,7 +8922,7 @@ void Compiler::compileDefConvConstructorCode(BuildTreeWriter& writer, MethodScop createObject(writer, classScope->info, classScope->reference); } -void Compiler::compileInplaceDefConstructorCode(BuildTreeWriter& writer, SyntaxNode current, SyntaxNode methodNode, +void Compiler :: compileInplaceDefConstructorCode(BuildTreeWriter& writer, SyntaxNode current, SyntaxNode methodNode, MethodScope& scope, CodeScope& codeScope, ClassScope& classClassScope, ref_t classFlags, bool newFrame) { mssg_t privateHandler = declareInplaceConstructorHandler(scope, classClassScope); @@ -8928,11 +8944,12 @@ void Compiler::compileInplaceDefConstructorCode(BuildTreeWriter& writer, SyntaxN arguments.add(scope.mapParameter(it.key(), EAttr::None)); } - ref_t signRef = getSignature(scope.module, privateHandler); - _logic->setSignatureStacksafe(*scope.moduleScope, signRef, resolution.stackSafeAttr); + MessageCallContext context = { privateHandler, getSignature(scope.module, privateHandler) }; - expression.compileMessageOperation({}, target, resolution, - signRef, arguments, EAttr::AllowPrivateCall, nullptr); + _logic->setSignatureStacksafe(*scope.moduleScope, context.implicitSignatureRef, resolution.stackSafeAttr); + + expression.compileMessageCall({}, target, context, resolution, + arguments, EAttr::AllowPrivateCall, nullptr); // return the created object expression.writeObjectInfo(scope.mapSelf(), current); @@ -9372,7 +9389,6 @@ inline void mapUninqueField(ClassInfo::FieldMap& fields, IdentifierString& name, { size_t pos = name.length(); int index = 0; - ref_t ref = 0; while (true) { name[pos] = 0; name.appendUInt(index++, 16); @@ -10282,7 +10298,7 @@ inline bool isSingleDispatch(SyntaxNode node, SyntaxKey methodType, mssg_t messa else return false; } -bool Compiler::injectVirtualStrongTypedMultimethod(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, +bool Compiler :: injectVirtualStrongTypedMultimethod(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, mssg_t message, mssg_t resendMessage, TypeInfo outputInfo, Visibility visibility, bool isExtension, int nillableArgs, bool isSealed) { bool variadicOne = (getFlags(resendMessage) & PREFIX_MESSAGE_MASK) == VARIADIC_MESSAGE; @@ -10654,7 +10670,7 @@ void Compiler::injectMethodInvoker(Scope& scope, SyntaxNode classNode, mssg_t me ref_t actionRef = getAction(message); ref_t signRef = 0; - ustr_t actionName = scope.module->resolveAction(actionRef, signRef); + scope.module->resolveAction(actionRef, signRef); injectParameters(scope, methodNode, signRef, message); @@ -10677,7 +10693,7 @@ void Compiler::injectVirtualDispatchMethod(Scope& scope, SyntaxNode classNode, m ref_t actionRef = getAction(message); ref_t signRef = 0; - ustr_t actionName = scope.module->resolveAction(actionRef, signRef); + scope.module->resolveAction(actionRef, signRef); injectParameters(scope, methodNode, signRef, message); @@ -10923,68 +10939,68 @@ bool Compiler::Namespace::declareMembers(SyntaxNode node, bool& repeatMode, bool SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { switch (current.key) { - case SyntaxKey::Namespace: - { - Namespace subNamespace(compiler, &scope); - subNamespace.declareNamespace(current, false, true); - - declared |= subNamespace.declareMembers(current, repeatMode, forced); - break; - } - case SyntaxKey::Symbol: - { - Symbol symbol(compiler, &scope, current.arg.reference, scope.defaultVisibility); - if (!symbol.isDeclared()) { - compiler->declareSymbol(symbol.scope, current); + case SyntaxKey::Namespace: + { + Namespace subNamespace(compiler, &scope); + subNamespace.declareNamespace(current, false, true); - declared = true; + declared |= subNamespace.declareMembers(current, repeatMode, forced); + break; } - break; - } - case SyntaxKey::Class: - { - Class classHelper(compiler, &scope, current.arg.reference, scope.defaultVisibility); - if (!classHelper.isDeclared()) { - if (classHelper.isParentDeclared(current) || forced) { - classHelper.declare(current); + case SyntaxKey::Symbol: + { + Symbol symbol(compiler, &scope, current.arg.reference, scope.defaultVisibility); + if (!symbol.isDeclared()) { + compiler->declareSymbol(symbol.scope, current); declared = true; } - else repeatMode = true; + break; } - break; - } - case SyntaxKey::MetaExpression: - { - MetaScope metaScope(&scope, Scope::ScopeLevel::Namespace); + case SyntaxKey::Class: + { + Class classHelper(compiler, &scope, current.arg.reference, scope.defaultVisibility); + if (!classHelper.isDeclared()) { + if (classHelper.isParentDeclared(current) || forced) { + classHelper.declare(current); - compiler->evalStatement(metaScope, current); - current.setKey(SyntaxKey::Idle); - break; - } - case SyntaxKey::Template: - case SyntaxKey::ExtensionTemplate: - { - TemplateScope templateScope(&scope, 0, scope.defaultVisibility); - compiler->declareTemplateClass(templateScope, current); - break; - } - case SyntaxKey::TemplateCode: - case SyntaxKey::InlineTemplateExpr: - { - TemplateScope templateScope(&scope, 0, scope.defaultVisibility); - compiler->declareTemplateCode(templateScope, current); - break; - } - case SyntaxKey::MetaDictionary: - compiler->declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Namespace, false); - break; - case SyntaxKey::SharedMetaDictionary: - compiler->declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Namespace, true); - break; - default: - // to make compiler happy - break; + declared = true; + } + else repeatMode = true; + } + break; + } + case SyntaxKey::MetaExpression: + { + MetaScope metaScope(&scope, Scope::ScopeLevel::Namespace); + + compiler->evalStatement(metaScope, current); + current.setKey(SyntaxKey::Idle); + break; + } + case SyntaxKey::Template: + case SyntaxKey::ExtensionTemplate: + { + TemplateScope templateScope(&scope, 0, scope.defaultVisibility); + compiler->declareTemplateClass(templateScope, current); + break; + } + case SyntaxKey::TemplateCode: + case SyntaxKey::InlineTemplateExpr: + { + TemplateScope templateScope(&scope, 0, scope.defaultVisibility); + compiler->declareTemplateCode(templateScope, current); + break; + } + case SyntaxKey::MetaDictionary: + compiler->declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Namespace, false); + break; + case SyntaxKey::SharedMetaDictionary: + compiler->declareDictionary(scope, current, Visibility::Public, Scope::ScopeLevel::Namespace, true); + break; + default: + // to make compiler happy + break; } current = current.nextNode(); @@ -11680,7 +11696,8 @@ ObjectInfo Compiler::Expression::compileInterpolation(SyntaxNode node) } else scope.raiseError(errInvalidOperation, node); - return compileMessageOperation(node, source, messageRef, 0, arguments, EAttr::StrongResolved | EAttr::NoExtension, nullptr); + MessageCallContext context = { messageRef, 0 }; + return compileMessageCall(node, source, context, messageRef, arguments, EAttr::StrongResolved | EAttr::NoExtension, nullptr); } ObjectInfo Compiler::Expression :: compileObject(SyntaxNode node, ExpressionAttribute mode, ArgumentsInfo* updatedOuterArgs) @@ -11761,7 +11778,7 @@ bool Compiler::Expression :: checkValidity(ObjectInfo target, MessageResolution& return checkValidity(target, result, allowPrivateCall); } - return false; + return false; } bool Compiler::Expression :: checkValidity(ObjectInfo target, CheckMethodResult& result, bool allowPrivateCall) @@ -11781,9 +11798,9 @@ bool Compiler::Expression :: checkValidity(ObjectInfo target, CheckMethodResult& if (compiler->_logic->isInternalOp(*scope.moduleScope, compiler->resolveStrongType(scope, target.typeInfo))) { return true; } - if (test(scope.getClassFlags(), elTemplatebased) - && compiler->_logic->isTemplateInternalOp(*scope.moduleScope, scope.getClassRef(), - compiler->resolveStrongType(scope, target.typeInfo))) + if (test(scope.getClassFlags(), elTemplatebased) + && compiler->_logic->isTemplateInternalOp(*scope.moduleScope, scope.getClassRef(), + compiler->resolveStrongType(scope, target.typeInfo))) { return true; } @@ -11802,26 +11819,40 @@ ObjectInfo Compiler::Expression :: compileMessageOperationR(SyntaxNode node, Syn { ObjectInfo retVal = {}; - mssg_t messageRef = compiler->mapMessage(scope, messageNode, propertyMode, + ref_t templateArgs[ARG_COUNT]; + MessageCallContext callContext = {}; + + callContext.weakMessage = compiler->mapMessage(scope, messageNode, propertyMode, source.kind == ObjectKind::Extension, probeMode); - if (propertyMode || !test(messageRef, FUNCTION_MESSAGE)) + if (propertyMode || !test(callContext.weakMessage, FUNCTION_MESSAGE)) arguments.add(source); + if (messageNode.nextNode() == SyntaxKey::TemplateArg) { + messageNode = messageNode.nextNode(); + while (messageNode == SyntaxKey::TemplateArg) { + templateArgs[callContext.templateArgCount++] = compiler->resolveStrongTypeAttribute(scope, messageNode, false, false).typeRef; + + messageNode = messageNode.nextNode(); + } + + callContext.templateArgs = templateArgs; + } + mssg_t resolvedMessage = 0; int resolvedNillableArgs = 0; EAttr paramMode = EAttr::NoPrimitives; if (source.mode != TargetMode::Weak) { resolvedMessage = compiler->_logic->resolveSingleDispatch(*scope.moduleScope, - compiler->retrieveType(scope, source), messageRef, isSelfCall(source), resolvedNillableArgs); + compiler->retrieveType(scope, source), callContext.weakMessage, isSelfCall(source), resolvedNillableArgs); if (!resolvedMessage && !ignoreVariadics) { - ref_t variadicMssg = resolveVariadicMessage(scope, messageRef); + ref_t variadicMssg = resolveVariadicMessage(scope, callContext.weakMessage); resolvedMessage = compiler->_logic->resolveSingleDispatch(*scope.moduleScope, compiler->retrieveType(scope, source), variadicMssg, isSelfCall(source), resolvedNillableArgs); if (resolvedMessage) { - messageRef = variadicMssg; + callContext.weakMessage = variadicMssg; paramMode = paramMode | EAttr::WithVariadicArg; } } @@ -11833,17 +11864,17 @@ ObjectInfo Compiler::Expression :: compileMessageOperationR(SyntaxNode node, Syn scope.module->resolveAction(getAction(resolvedMessage), expectedSignRef); ArgumentListType argListType = ArgumentListType::Normal; - ref_t implicitSignatureRef = compileMessageArguments(messageNode, arguments, expectedSignRef, paramMode, + callContext.implicitSignatureRef = compileMessageArguments(messageNode, arguments, expectedSignRef, paramMode, updatedOuterArgs, argListType, resolvedNillableArgs); EAttr opMode = EAttr::None; if (argListType == ArgumentListType::VariadicArgList || argListType == ArgumentListType::VariadicArgListWithTypecasting) { - messageRef |= VARIADIC_MESSAGE; + callContext.weakMessage |= VARIADIC_MESSAGE; opMode = argListType == Expression::ArgumentListType::VariadicArgList ? EAttr::WithVariadicArg : EAttr::WithVariadicArgCast; } - auto byRefResolution = resolveByRefHandler(source, expectedRef, messageRef, implicitSignatureRef, + auto byRefResolution = resolveByRefHandler(source, expectedRef, callContext, EAttrs::test(attrs, EAttr::NoExtension)); if (byRefResolution.resolved && checkValidity(source, byRefResolution, false)) { ObjectInfo tempRetVal = declareTempLocal(expectedRef, false); @@ -11853,13 +11884,13 @@ ObjectInfo Compiler::Expression :: compileMessageOperationR(SyntaxNode node, Syn if (tempRetVal.kind == ObjectKind::TempLocalAddress) writer->appendNode(BuildKey::ByRefOpMark, tempRetVal.argument); - compileMessageOperation(node, source, byRefResolution, - implicitSignatureRef, arguments, opMode, updatedOuterArgs); + compileMessageCall(node, source, callContext, byRefResolution, + arguments, opMode, updatedOuterArgs); retVal = tempRetVal; } - else retVal = compileMessageOperation(node, source, messageRef, - implicitSignatureRef, arguments, opMode, updatedOuterArgs); + else retVal = compileMessageCall(node, source, callContext, callContext.weakMessage, + arguments, opMode, updatedOuterArgs); return retVal; } @@ -11899,7 +11930,7 @@ bool Compiler::Expression::isDirectMethodCall(SyntaxNode& node) return false; } -ObjectInfo Compiler::Expression::compileMessageOperation(SyntaxNode node, +ObjectInfo Compiler::Expression :: compileMessageOperation(SyntaxNode node, ref_t expectedRef, ExpressionAttribute attrs) { ObjectInfo retVal = { }; @@ -12037,9 +12068,12 @@ ObjectInfo Compiler::Expression::compileSpecialOperation(SyntaxNode node, int op void Compiler::Expression :: compileAsyncOperation(SyntaxNode node, bool valueExpected) { StatemachineClassScope* smScope = Scope::getScope(scope, Scope::ScopeLevel::Statemachine); - if (!smScope) + if (!smScope) { scope.raiseError(errInvalidOperation, node); + return; // !! should never reach it; added to make the compiler happy + } + ObjectInfo contextField = smScope->mapContextField(); ObjectInfo currentField = smScope->mapCurrentField(); @@ -12072,7 +12106,6 @@ void Compiler::Expression :: compileAsyncOperation(SyntaxNode node, bool valueEx void Compiler::Expression :: compileYieldOperation(SyntaxNode node) { - CodeScope* codeScope = Scope::getScope(scope, Scope::ScopeLevel::Code); MethodScope* methodScope = Scope::getScope(scope, Scope::ScopeLevel::Method); StatemachineClassScope* smScope = Scope::getScope(scope, Scope::ScopeLevel::Statemachine); @@ -12351,8 +12384,9 @@ ObjectInfo Compiler::Expression::typecastObject(SyntaxNode node, ObjectInfo sour ArgumentsInfo arguments; arguments.add(source); - ObjectInfo retVal = compileMessageOperation(node, source, typecastMssg, - 0, arguments, EAttr::None, nullptr); + MessageCallContext context = { typecastMssg, 0 }; + ObjectInfo retVal = compileMessageCall(node, source, context, typecastMssg, + arguments, EAttr::None, nullptr); // NOTE : typecasting message is guaranteed to return the instance of the target type retVal.typeInfo = { targetRef }; @@ -12860,9 +12894,12 @@ ObjectInfo Compiler::Expression::compileCollection(SyntaxNode node, ExpressionAt ObjectInfo Compiler::Expression::compileClosureOperation(SyntaxNode node, ref_t targetRef) { ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class); - if (!classScope) + if (!classScope) { scope.raiseError(errInvalidOperation, node); + return {}; // !! shouild never reach it; added to make the compiler happy + } + // check the message name mssg_t targetMessage = 0; ustr_t methodName; @@ -13022,8 +13059,9 @@ ObjectInfo Compiler::Expression::compileTupleAssigning(SyntaxNode node) ref_t actionRef = scope.module->mapAction(REFER_MESSAGE, 0, false); mssg_t getter = encodeMessage(actionRef, 2, 0); - ObjectInfo sourceVar = compileMessageOperation(node, exprVal, getter, - 0, arguments, EAttr::None, nullptr); + MessageCallContext context = { getter, 0 }; + ObjectInfo sourceVar = compileMessageCall(node, exprVal, context, getter, + arguments, EAttr::None, nullptr); bool nillableOp = false; compileAssigningOp(targetVar, sourceVar, nillableOp); @@ -13062,7 +13100,8 @@ ObjectInfo Compiler::Expression::validateObject(SyntaxNode node, ObjectInfo retV ObjectInfo Compiler::Expression::compileNewOp(SyntaxNode node, ObjectInfo source, ref_t signRef, ArgumentsInfo& arguments) { - mssg_t messageRef = 0; + MessageCallContext context = { 0, signRef }; + if (source.kind == ObjectKind::ConstantLiteral) { IdentifierString valueStr(scope.module->resolveConstant(source.reference)); IdentifierString postfix; @@ -13081,14 +13120,14 @@ ObjectInfo Compiler::Expression::compileNewOp(SyntaxNode node, ObjectInfo source NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); auto constInfo = nsScope->extensions.get(conversionMssg); if (constInfo.value1) { - messageRef = constInfo.value2; + context.weakMessage = constInfo.value2; source = compiler->mapClassSymbol(scope, constInfo.value1); } else scope.raiseError(errInvalidOperation, node); } - else messageRef = overwriteArgCount(scope.moduleScope->buildins.constructor_message, arguments.count_pos()); + else context.weakMessage = overwriteArgCount(scope.moduleScope->buildins.constructor_message, arguments.count_pos()); - ObjectInfo retVal = compileMessageOperation(node, source, messageRef, signRef, arguments, EAttr::StrongResolved | EAttr::NoExtension, nullptr); + ObjectInfo retVal = compileMessageCall(node, source, context, context.weakMessage, arguments, EAttr::StrongResolved | EAttr::NoExtension | EAttr::CheckShortCircle, nullptr); if (arguments.count_pos() < 2 && (source.kind == ObjectKind::Class || source.kind == ObjectKind::ClassSelf)) { pos_t argCount = arguments.count_pos() + 1; @@ -13209,18 +13248,18 @@ ObjectInfo Compiler::Expression::compileExternalOp(SyntaxNode node, ref_t extern ref_t intArgType = 0; BuildKey intArgOp = BuildKey::None; switch (scope.moduleScope->ptrSize) { - case 4: - intArgType = V_INT32; - intArgOp = BuildKey::SavingNInStack; - break; - case 8: - retType = { V_INT64 }; - intArgType = V_INT64; - intArgOp = BuildKey::SavingLInStack; - break; - default: - assert(false); - break; + case 4: + intArgType = V_INT32; + intArgOp = BuildKey::SavingNInStack; + break; + case 8: + retType = { V_INT64 }; + intArgType = V_INT64; + intArgOp = BuildKey::SavingLInStack; + break; + default: + assert(false); + break; } for (pos_t i = count; i > 0; i--) { @@ -13470,41 +13509,41 @@ ObjectInfo Compiler::Expression::convertObject(SyntaxNode node, ObjectInfo sourc if (!withoutBoxing && conversionRoutine.result == ConversionResult::BoxingRequired) { // if it is implcitily compatible switch (source.kind) { - case ObjectKind::TempLocalAddress: - case ObjectKind::LocalAddress: - case ObjectKind::IntLiteral: - case ObjectKind::MssgLiteral: - case ObjectKind::CharacterLiteral: - case ObjectKind::RefLocal: - case ObjectKind::ParamReference: - source.typeInfo.typeRef = targetRef; - break; - case ObjectKind::SelfBoxableLocal: - case ObjectKind::ParamAddress: - if (source.mode == TargetMode::Conditional && source.typeInfo.typeRef != targetRef) { - source.mode = TargetMode::None; + case ObjectKind::TempLocalAddress: + case ObjectKind::LocalAddress: + case ObjectKind::IntLiteral: + case ObjectKind::MssgLiteral: + case ObjectKind::CharacterLiteral: + case ObjectKind::RefLocal: + case ObjectKind::ParamReference: source.typeInfo.typeRef = targetRef; + break; + case ObjectKind::SelfBoxableLocal: + case ObjectKind::ParamAddress: + if (source.mode == TargetMode::Conditional && source.typeInfo.typeRef != targetRef) { + source.mode = TargetMode::None; + source.typeInfo.typeRef = targetRef; - return source; - } - else source.typeInfo.typeRef = targetRef; - break; - default: - if (source.kind == ObjectKind::SelfLocal && source.mode == TargetMode::ArrayContent) { - source.typeInfo.typeRef = targetRef; - source.kind = ObjectKind::SelfBoxableLocal; - } - else return boxArgument(source, false, true, false, targetRef); + return source; + } + else source.typeInfo.typeRef = targetRef; + break; + default: + if (source.kind == ObjectKind::SelfLocal && source.mode == TargetMode::ArrayContent) { + source.typeInfo.typeRef = targetRef; + source.kind = ObjectKind::SelfBoxableLocal; + } + else return boxArgument(source, false, true, false, targetRef); } } else if (conversionRoutine.result == ConversionResult::VariadicBoxingRequired) { switch (source.kind) { - case ObjectKind::VArgParam: - source.typeInfo.typeRef = targetRef; - break; - default: - assert(false); - break; + case ObjectKind::VArgParam: + source.typeInfo.typeRef = targetRef; + break; + default: + assert(false); + break; } } else if (conversionRoutine.result == ConversionResult::Conversion) { @@ -13549,8 +13588,10 @@ ObjectInfo Compiler::Expression::convertObject(SyntaxNode node, ObjectInfo sourc } Compiler::MessageResolution Compiler::Expression :: resolveByRefHandler(ObjectInfo source, ref_t expectedRef, - mssg_t weakMessage, ref_t& signatureRef, bool noExtensions) + MessageCallContext& context, bool noExtensions) { + MessageCallContext byRefContext = context; + if (source.mode == TargetMode::Weak) return {}; @@ -13558,7 +13599,7 @@ Compiler::MessageResolution Compiler::Expression :: resolveByRefHandler(ObjectIn pos_t argCount = 0; ref_t actionRef = 0, flags = 0; - decodeMessage(weakMessage, actionRef, argCount, flags); + decodeMessage(context.weakMessage, actionRef, argCount, flags); // HOTFIX : ignore variadic message if ((flags & PREFIX_MESSAGE_MASK) == VARIADIC_MESSAGE) @@ -13566,8 +13607,8 @@ Compiler::MessageResolution Compiler::Expression :: resolveByRefHandler(ObjectIn if (expectedRef != 0 && targetRef != 0) { // try to resolve the weak message - MessageResolution resolution = resolveMessageAtCompileTime(source, weakMessage, - signatureRef, noExtensions, true, true); + MessageResolution resolution = resolveMessageAtCompileTime(source, byRefContext, + noExtensions, true, true); if (resolution.resolved || argCount == 1) { ref_t resolvedFlags = resolution.resolved ? getFlags(resolution.message) : flags; @@ -13583,7 +13624,7 @@ Compiler::MessageResolution Compiler::Expression :: resolveByRefHandler(ObjectIn if (resolution.byRefHandler && compiler->_logic->isSignatureCompatible(*scope.moduleScope, byRefMessage, resolution.byRefHandler)) { byRefMessage = resolution.byRefHandler; - scope.module->resolveAction(getAction(byRefMessage), signatureRef); + scope.module->resolveAction(getAction(byRefMessage), byRefContext.implicitSignatureRef); resolution.resolved = true; } @@ -13592,7 +13633,7 @@ Compiler::MessageResolution Compiler::Expression :: resolveByRefHandler(ObjectIn CheckMethodResult dummy = {}; if (compiler->_logic->resolveCallType(*scope.moduleScope, byRefTarget, byRefMessage, dummy)) { // NOTE : the original signature is extended with byref handler - signatureRef = compiler->_logic->defineByRefSignature(*scope.moduleScope, signatureRef, byRefType);; + byRefContext.implicitSignatureRef = compiler->_logic->defineByRefSignature(*scope.moduleScope, byRefContext.implicitSignatureRef, byRefType);; resolution.resolved = true; } @@ -13604,23 +13645,24 @@ Compiler::MessageResolution Compiler::Expression :: resolveByRefHandler(ObjectIn // NOTE : the stack safe attributes are resolved again the target signature compiler->_logic->setSignatureStacksafe(*scope.moduleScope, byRefSignature, resolution.stackSafeAttr); + context = byRefContext; return resolution; } } - else if (signatureRef) { + else if (byRefContext.implicitSignatureRef) { // otherwise check if there is a byref handler if at lease a signature exists ref_t dummySignRef = 0; ustr_t actionName = scope.module->resolveAction(actionRef, dummySignRef); ref_t byRefType = compiler->resolveStrongType(scope, { V_OUTWRAPPER, expectedRef }); - ref_t byRefSignature = compiler->_logic->defineByRefSignature(*scope.moduleScope, signatureRef, byRefType); + ref_t byRefSignature = compiler->_logic->defineByRefSignature(*scope.moduleScope, byRefContext.implicitSignatureRef, byRefType); ref_t byRefMessage = encodeMessage(scope.module->mapAction(actionName, byRefSignature, false), argCount + 1, flags); CheckMethodResult dummy = {}; if (compiler->_logic->resolveCallType(*scope.moduleScope, targetRef, byRefMessage, dummy)) { // NOTE : the original signature is extended with byref handler - signatureRef = compiler->_logic->defineByRefSignature(*scope.moduleScope, signatureRef, byRefType);; + byRefContext.implicitSignatureRef = compiler->_logic->defineByRefSignature(*scope.moduleScope, byRefContext.implicitSignatureRef, byRefType); resolution.resolved = true; resolution.message = byRefMessage; @@ -13628,6 +13670,7 @@ Compiler::MessageResolution Compiler::Expression :: resolveByRefHandler(ObjectIn // NOTE : the stack safe attributes are resolved again the target signature compiler->_logic->setSignatureStacksafe(*scope.moduleScope, byRefSignature, resolution.stackSafeAttr); + context = byRefContext; return resolution; } } @@ -13654,7 +13697,62 @@ ObjectInfo Compiler::Expression::declareTempLocal(ref_t typeRef, bool dynamicOnl } } -ObjectInfo Compiler::Expression :: compileMessageOperation(SyntaxNode node, ObjectInfo target, MessageResolution resolution, ref_t implicitSignatureRef, +void Compiler::Expression :: handleUnsupportedMessageCall(SyntaxNode node, mssg_t message, ref_t targetRef, bool weakTarget, bool strongResolved) +{ + if (strongResolved) { + if (getAction(message) == getAction(scope.moduleScope->buildins.constructor_message)) { + scope.raiseError(errUnknownDefConstructor, node); + } + else scope.raiseError(errUnknownMessage, findMessageNode(node)); + } + else { + SyntaxNode messageNode = findMessageNode(node); + if (weakTarget/* || ignoreWarning*/) { + // ignore warning for super class / type-less one + } + else if (messageNode == SyntaxKey::None) { + if (compiler->_verbose) { + showContextInfo(message, targetRef); + } + + if ((message & PREFIX_MESSAGE_MASK) == CONVERSION_MESSAGE) { + if (compiler->_strictTypeEnforcing && compiler->_logic->isClosedClass(*scope.moduleScope, targetRef)) { + scope.raiseError(errUnknownTypecast, node); + } + else scope.raiseWarning(WARNING_LEVEL_1, wrnUnknownTypecast, node); + } + else if (message == scope.moduleScope->buildins.refer_message) { + if (compiler->_strictTypeEnforcing && compiler->_logic->isClosedClass(*scope.moduleScope, targetRef)) { + scope.raiseError(errUnsupportedOperator, node); + } + else scope.raiseWarning(WARNING_LEVEL_1, wrnUnsupportedOperator, node); + } + else if (compiler->_strictTypeEnforcing && compiler->_logic->isClosedClass(*scope.moduleScope, targetRef)) { + scope.raiseError(errUnknownFunction, node); + } + else scope.raiseWarning(WARNING_LEVEL_1, wrnUnknownFunction, node); + } + else { + if (compiler->_verbose) { + IdentifierString messageName; + ByteCodeUtil::resolveMessageName(messageName, scope.module, message); + + compiler->_errorProcessor->info(infoUnknownMessage, *messageName); + + ustr_t name = scope.module->resolveReference(targetRef); + if (!name.empty()) + compiler->_errorProcessor->info(infoTargetClass, name); + } + + if (compiler->_strictTypeEnforcing && compiler->_logic->isClosedClass(*scope.moduleScope, targetRef)) { + scope.raiseError(errUnknownMessage, messageNode); + } + else scope.raiseWarning(WARNING_LEVEL_1, wrnUnknownMessage, messageNode); + } + } +} + +ObjectInfo Compiler::Expression :: compileMessageCall(SyntaxNode node, ObjectInfo target, MessageCallContext& context, MessageResolution resolution, ArgumentsInfo& arguments, ExpressionAttributes mode, ArgumentsInfo* updatedOuterArgs) { bool vargCastingRequired = EAttrs::testAndExclude(mode.attrs, EAttr::WithVariadicArgCast); @@ -13667,8 +13765,7 @@ ObjectInfo Compiler::Expression :: compileMessageOperation(SyntaxNode node, Obje BuildKey operation = BuildKey::CallOp; if (!resolution.resolved) { - resolution = resolveMessageAtCompileTime(target, resolution.message, - implicitSignatureRef, + resolution = resolveMessageAtCompileTime(target, context, EAttrs::testAndExclude(mode.attrs, EAttr::NoExtension), false); } @@ -13719,7 +13816,7 @@ ObjectInfo Compiler::Expression :: compileMessageOperation(SyntaxNode node, Obje if (target.kind == ObjectKind::ConstructorSelf) { scope.raiseError(errRedirectToItself, node); } - else scope.raiseWarning(WARNING_LEVEL_1, wrnCallingItself, findMessageNode(node)); + else scope.raiseWarning(WARNING_LEVEL_1, wrnCallingItself, functionMode ? findFunctionNode(node) : findMessageNode(node)); } break; @@ -13740,50 +13837,12 @@ ObjectInfo Compiler::Expression :: compileMessageOperation(SyntaxNode node, Obje } } else if (targetRef) { - if (EAttrs::test(mode.attrs, EAttr::StrongResolved)) { - if (getAction(resolution.message) == getAction(scope.moduleScope->buildins.constructor_message)) { - scope.raiseError(errUnknownDefConstructor, node); - } - else scope.raiseError(errUnknownMessage, findMessageNode(node)); - } - else { - bool weakTarget = targetRef == scope.moduleScope->buildins.superReference || result.withCustomDispatcher || target.mode == TargetMode::Weak; - - SyntaxNode messageNode = findMessageNode(node); - if (weakTarget/* || ignoreWarning*/) { - // ignore warning for super class / type-less one - } - else if (messageNode == SyntaxKey::None) { - if (compiler->_verbose) { - showContextInfo(resolution.message, targetRef); - } - - if ((resolution.message & PREFIX_MESSAGE_MASK) == CONVERSION_MESSAGE) { - scope.raiseWarning(WARNING_LEVEL_1, wrnUnknownTypecast, node); - } - else if (resolution.message == scope.moduleScope->buildins.refer_message) { - scope.raiseWarning(WARNING_LEVEL_1, wrnUnsupportedOperator, node); - } - else scope.raiseWarning(WARNING_LEVEL_1, wrnUnknownFunction, node); - } - else { - if (compiler->_verbose) { - IdentifierString messageName; - ByteCodeUtil::resolveMessageName(messageName, scope.module, resolution.message); - - compiler->_errorProcessor->info(infoUnknownMessage, *messageName); - - ustr_t name = scope.module->resolveReference(targetRef); - if (!name.empty()) - compiler->_errorProcessor->info(infoTargetClass, name); - } - - scope.raiseWarning(WARNING_LEVEL_1, wrnUnknownMessage, messageNode); - } + handleUnsupportedMessageCall(node, resolution.message, targetRef, + targetRef == scope.moduleScope->buildins.superReference || result.withCustomDispatcher || target.mode == TargetMode::Weak, + EAttrs::test(mode.attrs, EAttr::StrongResolved)); - // treat it as a weak reference - targetRef = 0; - } + // treat it as a weak reference + targetRef = 0; } if (target.kind == ObjectKind::SuperLocal) { @@ -13878,7 +13937,6 @@ ObjectInfo Compiler::Expression::compileOperation(SyntaxNode node, SyntaxNode rn inode = lnode.nextNode(); } - BuildKey op = BuildKey::None; ObjectInfo loperand = compile(lnode, 0, EAttr::Parameter | EAttr::RetValExpected | EAttr::LookaheadExprMode, &updatedOuterArgs); ObjectInfo roperand = {}; @@ -14226,9 +14284,9 @@ ObjectInfo Compiler::Expression::compileWeakOperation(SyntaxNode node, ref_t* ar else arguments[i - 1] = arguments[i]; } - ref_t signRef = (!weakSignature && argLen > 1) ? scope.module->mapSignature(arguments, argLen - 1, false) : 0; + MessageCallContext context = { message, (!weakSignature && argLen > 1) ? scope.module->mapSignature(arguments, argLen - 1, false) : 0 }; - auto byRefResolution = resolveByRefHandler(loperand, expectedRef, message, signRef, true); + auto byRefResolution = resolveByRefHandler(loperand, expectedRef, context, true); if (byRefResolution.resolved && checkValidity(loperand, byRefResolution, false)) { ObjectInfo tempRetVal = declareTempLocal(expectedRef, false); @@ -14237,13 +14295,13 @@ ObjectInfo Compiler::Expression::compileWeakOperation(SyntaxNode node, ref_t* ar if (tempRetVal.kind == ObjectKind::TempLocalAddress) writer->appendNode(BuildKey::ByRefOpMark, tempRetVal.argument); - compileMessageOperation(node, loperand, byRefResolution, - signRef, messageArguments, EAttr::None, updatedOuterArgs); + compileMessageCall(node, loperand, context, byRefResolution, + messageArguments, EAttr::None, updatedOuterArgs); retVal = tempRetVal; } - else retVal = compileMessageOperation(node, loperand, { message }, - signRef, messageArguments, EAttr::NoExtension, updatedOuterArgs); + else retVal = compileMessageCall(node, loperand, context, { context.weakMessage }, + messageArguments, EAttr::NoExtension, updatedOuterArgs); return retVal; } @@ -14472,15 +14530,16 @@ ObjectInfo Compiler::Expression::compileBranchingOperation(SyntaxNode node, Obje else retVal = compileBranchingOperands(rnode, r2node, retValExpected, withoutDebugInfo); } else { - mssg_t message = 0; + MessageCallContext context = {}; + if (rnode != SyntaxKey::ClosureBlock && r2node != SyntaxKey::None) { - message = scope.moduleScope->buildins.iif_message; + context.weakMessage = scope.moduleScope->buildins.iif_message; roperand = compile(rnode, 0, EAttr::Parameter, updatedOuterArgs); roperand2 = compile(r2node, 0, EAttr::Parameter, updatedOuterArgs); } else { - message = compiler->resolveOperatorMessage(scope.moduleScope, operatorId); + context.weakMessage = compiler->resolveOperatorMessage(scope.moduleScope, operatorId); roperand = compileClosure(rnode, 0, EAttr::None, updatedOuterArgs); roperand2 = compileClosure(r2node, 0, EAttr::None, updatedOuterArgs); @@ -14493,9 +14552,9 @@ ObjectInfo Compiler::Expression::compileBranchingOperation(SyntaxNode node, Obje messageArguments.add(roperand2); } - ref_t signRef = scope.module->mapSignature(arguments, argLen, false); + context.implicitSignatureRef = scope.module->mapSignature(arguments, argLen, false); - retVal = compileMessageOperation(node, loperand, message, signRef, messageArguments, EAttr::NoExtension, updatedOuterArgs); + retVal = compileMessageCall(node, loperand, context, context.weakMessage, messageArguments, EAttr::NoExtension, updatedOuterArgs); } // HOTFIX : to compenstate the closed statement above @@ -14570,11 +14629,8 @@ ObjectInfo Compiler::Expression::compileBranchingOperands(SyntaxNode rnode, Synt ObjectInfo Compiler::Expression::compileTernaryOperands(SyntaxNode rnode, SyntaxNode r2node, BuildNode& opNode, bool withoutDebugInfo) { - CodeScope* codeScope = Scope::getScope(scope, Scope::ScopeLevel::Code); - writer->newNode(BuildKey::Tape); - bool oldWithRet = codeScope->withRetStatement; ObjectInfo lexpr = compile(rnode, 0, EAttr::RetValExpected, nullptr); writeObjectInfo(lexpr); @@ -14621,7 +14677,7 @@ ObjectInfo Compiler::Expression::compileMessageOperationR(ObjectInfo target, Syn return arguments[0]; } - else return convertObject(messageNode, arguments[0], targetRef, false, true, false, true); + else return convertObject(messageNode, arguments[0], targetRef, false, true, false, arguments[0].mode == TargetMode::Weak); } else scope.raiseError(errInvalidOperation, messageNode); break; @@ -14955,20 +15011,20 @@ ObjectInfo Compiler::Expression::allocateResult(ref_t resultRef) return {}; // NOTE : should never be reached } -Compiler::MessageResolution Compiler::Expression :: resolveMessageAtCompileTime(ObjectInfo target, mssg_t weakMessage, ref_t implicitSignatureRef, +Compiler::MessageResolution Compiler::Expression :: resolveMessageAtCompileTime(ObjectInfo target, MessageCallContext& messageContext, bool ignoreExtensions, bool ignoreVariadics, bool checkByRefHandler) { MessageResolution resolution = {}; if (target.mode == TargetMode::Weak) - return { weakMessage }; + return { messageContext.weakMessage }; ref_t targetRef = compiler->resolveStrongType(scope, target.typeInfo); // try to resolve the message as is int resolvedStackSafeAttr = 0; - resolution.message = compiler->_logic->resolveMultimethod(*scope.moduleScope, weakMessage, targetRef, - implicitSignatureRef, resolvedStackSafeAttr, isSelfCall(target)); + resolution.message = compiler->_logic->resolveMultimethod(*scope.moduleScope, messageContext.weakMessage, targetRef, + messageContext.implicitSignatureRef, resolvedStackSafeAttr, isSelfCall(target)); if (resolution.message != 0) { resolution.resolved = true; resolution.stackSafeAttr = resolvedStackSafeAttr; @@ -14983,8 +15039,8 @@ Compiler::MessageResolution Compiler::Expression :: resolveMessageAtCompileTime( if (targetRef && !ignoreVariadics) { resolvedStackSafeAttr = 0; resolution.message = compiler->_logic->resolveMultimethod(*scope.moduleScope, - resolveVariadicMessage(scope, weakMessage), - targetRef, implicitSignatureRef, resolvedStackSafeAttr, isSelfCall(target)); + resolveVariadicMessage(scope, messageContext.weakMessage), + targetRef, messageContext.implicitSignatureRef, resolvedStackSafeAttr, isSelfCall(target)); if (resolution.message != 0) { resolution.resolved = true; @@ -15001,8 +15057,8 @@ Compiler::MessageResolution Compiler::Expression :: resolveMessageAtCompileTime( // check the existing extensions if allowed // if the object handles the weak message - do not use extensions CheckMethodResult dummy = {}; - if (compiler->_logic->resolveCallType(*scope.moduleScope, targetRef, weakMessage, dummy)) { - resolution.message = weakMessage; + if (compiler->_logic->resolveCallType(*scope.moduleScope, targetRef, messageContext.weakMessage, dummy)) { + resolution.message = messageContext.weakMessage; if (checkByRefHandler) { resolution.byRefHandler = dummy.byRefHandler; } @@ -15011,9 +15067,9 @@ Compiler::MessageResolution Compiler::Expression :: resolveMessageAtCompileTime( } resolvedStackSafeAttr = 0; - resolution.message = weakMessage; - ref_t extensionRef = compiler->mapExtension(*writer, scope, resolution.message, implicitSignatureRef, - target, resolvedStackSafeAttr); + resolution.message = messageContext.weakMessage; + ref_t extensionRef = compiler->mapExtension(*writer, scope, messageContext, + target, resolution.message, resolvedStackSafeAttr); if (extensionRef != 0) { // if there is an extension to handle the compile-time resolved message - use it resolution.resolved = true; @@ -15026,20 +15082,18 @@ Compiler::MessageResolution Compiler::Expression :: resolveMessageAtCompileTime( } // HOTFIX : do not check variadic message for the properties - if ((weakMessage & PREFIX_MESSAGE_MASK) == PROPERTY_MESSAGE) - return { weakMessage }; - - // check if the extension handles the variadic message - mssg_t variadicMessage = resolveVariadicMessage(scope, weakMessage); + if ((messageContext.weakMessage & PREFIX_MESSAGE_MASK) == PROPERTY_MESSAGE) + return { messageContext.weakMessage }; + // check if the extension handles the variadic message + MessageCallContext variadicContext = { resolveVariadicMessage(scope, messageContext.weakMessage), messageContext.implicitSignatureRef }; resolvedStackSafeAttr = 0; - extensionRef = compiler->mapExtension(*writer, scope, variadicMessage, implicitSignatureRef, - target, resolvedStackSafeAttr); + extensionRef = compiler->mapExtension(*writer, scope, variadicContext, + target, resolution.message, resolvedStackSafeAttr); if (extensionRef != 0) { // if there is an extension to handle the compile-time resolved message - use it resolution.resolved = true; resolution.stackSafeAttr = resolvedStackSafeAttr; - resolution.message = variadicMessage; resolution.extensionRef = extensionRef; if (checkByRefHandler) resolution.byRefHandler = compiler->_logic->retrieveByRefHandler(*scope.moduleScope, extensionRef, resolution.message); @@ -15049,8 +15103,8 @@ Compiler::MessageResolution Compiler::Expression :: resolveMessageAtCompileTime( } else if (checkByRefHandler) { CheckMethodResult dummy = {}; - if (compiler->_logic->resolveCallType(*scope.moduleScope, targetRef, weakMessage, dummy)) { - resolution.message = weakMessage; + if (compiler->_logic->resolveCallType(*scope.moduleScope, targetRef, messageContext.weakMessage, dummy)) { + resolution.message = messageContext.weakMessage; resolution.byRefHandler = dummy.byRefHandler; return resolution; @@ -15058,7 +15112,7 @@ Compiler::MessageResolution Compiler::Expression :: resolveMessageAtCompileTime( } // otherwise - use the weak message - return { weakMessage }; + return { messageContext.weakMessage }; } bool Compiler::Expression::validateShortCircle(mssg_t message, ObjectInfo target) @@ -15134,7 +15188,7 @@ void Compiler::Expression::writeMessageArguments(ObjectInfo& target, writer->appendNode(BuildKey::Index, lenLocal.argument); writer->closeNode(); - if (argType == ArgumentListType::VariadicArgListWithTypecasting) { + if (argType == ArgumentListType::VariadicArgListWithTypecasting && arguments[counter].typeInfo.elementRef != scope.moduleScope->buildins.superReference) { // if we need to typecast the each item of the variadic argument list ObjectInfo tempLocal = declareTempLocal(scope.moduleScope->buildins.intReference, false); mssg_t typecastMssg = mapTypecasting(scope.module, arguments[counter].typeInfo.elementRef); @@ -15627,7 +15681,7 @@ void Compiler::Expression::compileConverting(SyntaxNode node, ObjectInfo source, // --- Compiler::MetaExpression --- Compiler::MetaExpression::MetaExpression(Compiler* compiler, Scope* scope, Interpreter* interpreter) - : CommonHelper(compiler), scope(scope), interpreter(interpreter) + : CommonHelper(compiler), interpreter(interpreter), scope(scope) { } @@ -15754,7 +15808,7 @@ ObjectInfo Compiler::MetaExpression::generateNestedConstant(SyntaxNode node) // --- Compiler::NestedClass --- Compiler::NestedClass::NestedClass(Compiler* compiler, Expression& expr, ref_t nestedRef, BuildTreeWriter& writer) - : CommonHelper(compiler), scope(&expr.scope, nestedRef), writer(&writer) + : CommonHelper(compiler), writer(&writer), scope(&expr.scope, nestedRef) { } @@ -16036,8 +16090,6 @@ ref_t Compiler::LambdaClosure :: resolveClosure(mssg_t closureMessage, ref_t out } else templateReference = scope.moduleScope->mapFullReference(*closureName, true); - NamespaceScope* nsScope = Scope::getScope(scope, Scope::ScopeLevel::Namespace); - return compiler->_templateProcessor->generateClassTemplate(*scope.moduleScope, templateReference, parameters, false, nullptr); } @@ -16078,4 +16130,4 @@ ref_t Compiler::LambdaClosure::declareClosureParameters(MethodScope& methodScope ref_t actionRef = methodScope.moduleScope->module->mapAction(*messageStr, signRef, false); return encodeMessage(actionRef, paramCount, flags); -} \ No newline at end of file +} diff --git a/elenasrc3/elc/compiler.h b/elenasrc3/elc/compiler.h index 6c6462226f..2eae5dd827 100644 --- a/elenasrc3/elc/compiler.h +++ b/elenasrc3/elc/compiler.h @@ -46,7 +46,7 @@ namespace elena_lang ClassSelf, // NOTE : used for the constructor resend operation // it is a message self argument - ConstructorSelf, + ConstructorSelf, Method, Object, Singleton, @@ -142,7 +142,7 @@ namespace elena_lang bool operator ==(ObjectInfo& val) const { - return (this->kind == val.kind && this->reference == val.reference && this->typeInfo.typeRef == val.typeInfo.typeRef + return (this->kind == val.kind && this->reference == val.reference && this->typeInfo.typeRef == val.typeInfo.typeRef && this->typeInfo.elementRef == val.typeInfo.elementRef); } @@ -384,7 +384,7 @@ namespace elena_lang else { return nullptr; } - } + } virtual void markAsAssigned(ObjectInfo object) {} @@ -456,7 +456,7 @@ namespace elena_lang if (parent) { this->module = parent->module; this->moduleScope = parent->moduleScope; - this->compilerLogic = compilerLogic; + this->compilerLogic = parent->compilerLogic; } else { this->module = nullptr; @@ -679,7 +679,7 @@ namespace elena_lang virtual ObjectInfo mapField(ustr_t identifier, ExpressionAttribute attr); ObjectInfo mapPrivateField(ustr_t identifier, ExpressionAttribute attr); - + ObjectInfo mapIdentifier(ustr_t identifier, bool referenceOne, ExpressionAttribute attr) override; ObjectInfo mapDictionary(ustr_t identifier, bool referenceOne, ExpressionAttribute mode) override; @@ -996,7 +996,7 @@ namespace elena_lang ref_t isSealed(bool ownerClass = true) { ClassScope* scope = Scope::getScope(*this, ownerClass ? ScopeLevel::OwnerClass : ScopeLevel::Class); - + return scope ? test(scope->info.header.flags, elSealed) : false; } ref_t isExtension(bool ownerClass = true) @@ -1133,6 +1133,25 @@ namespace elena_lang } }; + struct MessageCallContext + { + mssg_t weakMessage; + ref_t implicitSignatureRef; + pos_t templateArgCount; + ref_t* templateArgs; + + MessageCallContext() + : weakMessage(0), implicitSignatureRef(0), templateArgCount(0), templateArgs(nullptr) + { + + } + MessageCallContext(mssg_t weakMessage, ref_t implicitSignatureRef) + : weakMessage(weakMessage), implicitSignatureRef(implicitSignatureRef), templateArgCount(0), templateArgs(nullptr) + { + + } + }; + struct TerminalAttributes { bool variableMode; @@ -1347,7 +1366,9 @@ namespace elena_lang ObjectInfo convertObject(SyntaxNode node, ObjectInfo source, ref_t targetRef, bool dynamicRequired, bool withoutBoxing, bool nillable, bool directConversion); - ObjectInfo compileMessageOperation(SyntaxNode node, ObjectInfo target, MessageResolution resolution, ref_t implicitSignatureRef, + void handleUnsupportedMessageCall(SyntaxNode node, mssg_t message, ref_t targetRef, bool weakTarget, bool strongResolved); + + ObjectInfo compileMessageCall(SyntaxNode node, ObjectInfo target, MessageCallContext& context, MessageResolution resolution, ArgumentsInfo& arguments, ExpressionAttributes mode, ArgumentsInfo* updatedOuterArgs); ObjectInfo compileOperation(SyntaxNode loperand, SyntaxNode roperand, int operatorId, ref_t expectedRef); @@ -1357,11 +1378,11 @@ namespace elena_lang ObjectInfo compileBranchingOperation(SyntaxNode node, ObjectInfo loperand, SyntaxNode rnode, SyntaxNode r2node, int operatorId, ArgumentsInfo* updatedOuterArgs, bool retValExpected, bool withoutDebugInfo); - ref_t compileMessageArguments(SyntaxNode current, ArgumentsInfo& arguments, ref_t expectedSignRef, ExpressionAttribute mode, + ref_t compileMessageArguments(SyntaxNode current, ArgumentsInfo& arguments, ref_t expectedSignRef, ExpressionAttribute mode, ArgumentsInfo* updatedOuterArgs, ArgumentListType& argListType, int nillableArgs); - MessageResolution resolveByRefHandler(ObjectInfo source, ref_t expectedRef, mssg_t weakMessage, ref_t& signatureRef, bool noExtensions); - MessageResolution resolveMessageAtCompileTime(ObjectInfo target, mssg_t weakMessage, ref_t implicitSignatureRef, bool ignoreExtensions, + MessageResolution resolveByRefHandler(ObjectInfo source, ref_t expectedRef, MessageCallContext& context, bool noExtensions); + MessageResolution resolveMessageAtCompileTime(ObjectInfo target, MessageCallContext& messageContext, bool ignoreExtensions, bool ignoreVariadics, bool checkByRefHandler = false); ObjectInfo declareTempLocal(ref_t typeRef, bool dynamicOnly = true); @@ -1405,7 +1426,7 @@ namespace elena_lang void showContextInfo(mssg_t message, ref_t targetRef); - void writeMessageArguments(ObjectInfo& target, mssg_t message, ArgumentsInfo& arguments, ObjectInfo& lenLocal, + void writeMessageArguments(ObjectInfo& target, mssg_t message, ArgumentsInfo& arguments, ObjectInfo& lenLocal, int& stackSafeAttr, bool targetOverridden, bool found, ArgumentListType argType, bool stackSafe); void convertIntLiteralForOperation(SyntaxNode node, int operatorId, ArgumentsInfo& messageArguments); @@ -1495,6 +1516,7 @@ namespace elena_lang bool _verbose; bool _noValidation; bool _withDebugInfo; + bool _strictTypeEnforcing; void addTypeInfo(Scope& scope, SyntaxNode node, SyntaxKey key, TypeInfo typeInfo); @@ -1523,12 +1545,12 @@ namespace elena_lang ref_t mapTemplateType(Scope& scope, SyntaxNode terminal, pos_t parameterCount); - ref_t mapExtension(BuildTreeWriter& writer, Scope& scope, mssg_t& resolvedMessage, ref_t& implicitSignatureRef, - ObjectInfo object, int& stackSafeAttr); - + ref_t mapExtension(BuildTreeWriter& writer, Scope& scope, MessageCallContext& context, + ObjectInfo object, mssg_t& resolvedMessage, int& stackSafeAttr); + mssg_t defineMultimethod(Scope& scope, mssg_t messageRef, bool extensionMode); - void declareTemplateAttributes(Scope& scope, SyntaxNode node, TemplateTypeList& parameters, + void declareTemplateAttributes(Scope& scope, SyntaxNode node, TemplateTypeList& parameters, TypeAttributes& attributes, bool declarationMode, bool objectMode); void declareIncludeAttributes(Scope& scope, SyntaxNode node, bool& textBlock); @@ -1543,7 +1565,7 @@ namespace elena_lang TypeInfo resolveStrongTypeInfo(Scope& scope, TypeInfo typeInfo, bool declarationMode = false); ref_t retrieveType(Scope& scope, ObjectInfo info); - ref_t resolveTypeIdentifier(Scope& scope, ustr_t identifier, SyntaxKey type, + ref_t resolveTypeIdentifier(Scope& scope, ustr_t identifier, SyntaxKey type, bool declarationMode, bool allowRole); ref_t resolveTypeTemplate(Scope& scope, SyntaxNode node, TypeAttributes& attributes, bool declarationMode, bool objectMode = false); @@ -1564,7 +1586,7 @@ namespace elena_lang bool declarationMode, bool allowRole); TypeInfo resolveStrongTypeAttribute(Scope& scope, SyntaxNode node, bool declarationMode, bool allowRole); - ref_t retrieveTemplate(NamespaceScope& scope, SyntaxNode node, List& parameters, + ref_t retrieveTemplate(NamespaceScope& scope, SyntaxNode node, List& parameters, ustr_t prefix, SyntaxKey argKey, ustr_t postFix); ref_t retrieveBlock(NamespaceScope& scope, SyntaxNode node); @@ -1595,7 +1617,7 @@ namespace elena_lang void declareClassAttributes(ClassScope& scope, SyntaxNode node, ref_t& fldeclaredFlagsags); void declareTemplateAttributes(TemplateScope& scope, SyntaxNode node, IdentifierString& postfix); - void declareSymbolAttributes(SymbolScope& scope, SyntaxNode node, bool identifierDeclarationMode); + void declareSymbolAttributes(SymbolScope& scope, SyntaxNode node, bool identifierDeclarationMode); void declareFieldAttributes(ClassScope& scope, SyntaxNode node, FieldAttributes& mode); void declareMethodAttributes(MethodScope& scope, SyntaxNode node, bool exensionMode); void declareArgumentAttributes(MethodScope& scope, SyntaxNode node, TypeInfo& typeInfo, bool declarationMode); @@ -1604,7 +1626,7 @@ namespace elena_lang static ustr_t retrieveDictionaryOwner(Scope& scope, ustr_t properName, ustr_t defaultPrefix, ExpressionAttribute mode); - void declareDictionary(Scope& scope, SyntaxNode node, Visibility visibility, + void declareDictionary(Scope& scope, SyntaxNode node, Visibility visibility, Scope::ScopeLevel level, bool shareMode); void declareVMT(ClassScope& scope, SyntaxNode node, bool& withConstructors, bool& withDefaultConstructor, @@ -1624,7 +1646,7 @@ namespace elena_lang InheritResult inheritClass(ClassScope& scope, ref_t parentRef/*, bool ignoreFields*/, bool ignoreSealed); - void checkMethodDuplicates(ClassScope& scope, SyntaxNode node, mssg_t message, + void checkMethodDuplicates(ClassScope& scope, SyntaxNode node, mssg_t message, mssg_t publicMessage, bool protectedOne, bool internalOne); void checkUnassignedVariables(MethodScope& scope, SyntaxNode node); @@ -1635,7 +1657,7 @@ namespace elena_lang void verifyMultimethods(Scope& scope, SyntaxNode node, SyntaxKey methodKey, ClassInfo& info, VirtualMethodList& implicitMultimethods); - bool generateClassField(ClassScope& scope, FieldAttributes& attrs, ustr_t name, int sizeHint, + bool generateClassField(ClassScope& scope, FieldAttributes& attrs, ustr_t name, int sizeHint, TypeInfo typeInfo, bool singleField); void declareFieldMetaInfo(FieldScope& scope, SyntaxNode node); @@ -1643,23 +1665,23 @@ namespace elena_lang void generateClassFlags(ClassScope& scope, ref_t declaredFlags); void generateParamNameInfo(ClassScope& scope, SyntaxNode node, mssg_t message); - void generateMethodAttributes(ClassScope& scope, SyntaxNode node, + void generateMethodAttributes(ClassScope& scope, SyntaxNode node, MethodInfo& methodInfo, bool abstractBased); void generateMethodDeclaration(ClassScope& scope, SyntaxNode node, bool closed, bool hideDuplicate); void generateMethodDeclarations(ClassScope& scope, SyntaxNode node, SyntaxKey methodKey, bool closed); DeclResult checkAndGenerateClassField(ClassScope& scope, SyntaxNode node, ustr_t name, FieldAttributes& attrs, bool singleField); void generateClassStaticField(ClassScope& scope, SyntaxNode node, FieldAttributes& attrs); - void generateClassFields(ClassScope& scope, SyntaxNode node, bool singleField); + void generateClassFields(ClassScope& scope, SyntaxNode node, bool singleField); 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 declareClassParent(ref_t parentRef, ClassScope& scope, SyntaxNode node); + void declareClassParent(ref_t parentRef, ClassScope& scope, SyntaxNode node); int resolveArraySize(Scope& scope, SyntaxNode node); - void declareParameter(MethodScope& scope, SyntaxNode node, bool withoutWeakMessages, + void declareParameter(MethodScope& scope, SyntaxNode node, bool withoutWeakMessages, bool declarationMode, bool& variadicMode, bool& weakSignature, bool& noSignature, pos_t& paramCount, ref_t* signature, size_t& signatureLen, bool& nillable); @@ -1681,7 +1703,7 @@ namespace elena_lang void declareMethod(MethodScope& scope, SyntaxNode node, bool abstractMode, bool staticNotAllowed, bool yieldMethodNotAllowed); - void declareSymbol(SymbolScope& scope, SyntaxNode node); + void declareSymbol(SymbolScope& scope, SyntaxNode node); void copyParentNamespaceExtensions(NamespaceScope& source, NamespaceScope& target); @@ -1690,7 +1712,7 @@ namespace elena_lang void inheritStaticMethods(ClassScope& scope, SyntaxNode classNode); - void addExtensionMessage(Scope& scope, mssg_t message, ref_t extRef, mssg_t strongMessage, + void addExtensionMessage(Scope& scope, mssg_t message, ref_t extRef, mssg_t strongMessage, bool internalOne); void addExtensionTemplateMessage(Scope& scope, mssg_t message, ustr_t pattern, bool internalOne); @@ -1718,21 +1740,21 @@ namespace elena_lang bool evalClassConstant(ustr_t constName, ClassScope& scope, SyntaxNode node, ObjectInfo& constInfo); bool evalAccumClassConstant(ustr_t constName, ClassScope& scope, SyntaxNode node, ObjectInfo& constInfo); - ref_t compileExtensionDispatcher(BuildTreeWriter& writer, NamespaceScope& scope, mssg_t genericMessage, + ref_t compileExtensionDispatcher(BuildTreeWriter& writer, NamespaceScope& scope, mssg_t genericMessage, ref_t outputRef); - void writeParameterDebugInfo(BuildTreeWriter& writer, Scope& scope, int size, TypeInfo typeInfo, + void writeParameterDebugInfo(BuildTreeWriter& writer, Scope& scope, int size, TypeInfo typeInfo, ustr_t name, int index); void writeMethodDebugInfo(BuildTreeWriter& writer, MethodScope& scope); void writeMessageInfo(BuildTreeWriter& writer, MethodScope& scope); void compileInlineInitializing(BuildTreeWriter& writer, ClassScope& classScope, SyntaxNode node); - + static ObjectInfo convertIntLiteral(ExprScope& scope, SyntaxNode node, ObjectInfo source, ref_t targetRef, bool ignoreError = false); bool compileSymbolConstant(SymbolScope& scope, ObjectInfo retVal); - ObjectInfo defineTerminalInfo(Scope& scope, SyntaxNode node, TypeInfo declaredTypeInfo, + ObjectInfo defineTerminalInfo(Scope& scope, SyntaxNode node, TypeInfo declaredTypeInfo, TerminalAttributes& terminalAttrs, bool& invalid, ExpressionAttribute attrs); ObjectInfo mapStringConstant(Scope& scope, SyntaxNode node); @@ -1748,21 +1770,21 @@ namespace elena_lang ObjectInfo mapExtMessageConstant(Scope& scope, SyntaxNode node, ref_t actionRef, ref_t extension); ObjectInfo mapObject(Scope& scope, SyntaxNode node, ExpressionAttributes mode); - - ObjectInfo compileRootExpression(BuildTreeWriter& writer, CodeScope& scope, SyntaxNode node, + + ObjectInfo compileRootExpression(BuildTreeWriter& writer, CodeScope& scope, SyntaxNode node, ExpressionAttribute mode); - ObjectInfo compileRetExpression(BuildTreeWriter& writer, CodeScope& scope, SyntaxNode node, + ObjectInfo compileRetExpression(BuildTreeWriter& writer, CodeScope& scope, SyntaxNode node, ExpressionAttribute mode); ObjectInfo compileNestedExpression(BuildTreeWriter& writer, InlineClassScope& scope, ExprScope& ownerScope, ExpressionAttribute mode, ArgumentsInfo* updatedOuterArgs); - void compileMultidispatch(BuildTreeWriter& writer, CodeScope& codeScope, ClassScope& classcope, + void compileMultidispatch(BuildTreeWriter& writer, CodeScope& codeScope, ClassScope& classcope, SyntaxNode node, bool implicitMode); void compileDirectResendCode(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node); void compileDispatchCode(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node); void compileDispatchProberCode(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node); void compileConstructorDispatchCode(BuildTreeWriter& writer, CodeScope& codeScope, ClassScope& classClassScope, SyntaxNode node); - void compileByRefHandlerInvoker(BuildTreeWriter& writer, MethodScope& scope, CodeScope& codeScope, + void compileByRefHandlerInvoker(BuildTreeWriter& writer, MethodScope& scope, CodeScope& codeScope, mssg_t handler, ref_t targetRef); void compileRedirectDispatcher(BuildTreeWriter& writer, MethodScope& scope, CodeScope& codeScope, SyntaxNode node, @@ -1773,7 +1795,7 @@ namespace elena_lang ObjectInfo compileRedirect(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node, ref_t outputRef); ObjectInfo compileCode(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node, bool closureMode, bool noDebugInfoMode = false); - void beginMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node, BuildKey scopeKey, + void beginMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node, BuildKey scopeKey, bool withDebugInfo); void endMethod(BuildTreeWriter& writer, MethodScope& scope); @@ -1794,7 +1816,7 @@ namespace elena_lang void compileByRefRedirectHandler(BuildTreeWriter& writer, MethodScope& invokerScope, SyntaxNode node, mssg_t byRefHandler); - void compileDispatcherMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node, + void compileDispatcherMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node, bool withGenerics, bool withOpenArgGenerics); void compileInitializerMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode classNode); void compileStaticInitializerMethod(BuildTreeWriter& writer, ClassScope& scope, SyntaxNode classNode); @@ -1805,10 +1827,10 @@ namespace elena_lang void compileMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node); void compileYieldMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node); void compileAsyncMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node); - void compileConstructor(BuildTreeWriter& writer, MethodScope& scope, ClassScope& classClassScope, + void compileConstructor(BuildTreeWriter& writer, MethodScope& scope, ClassScope& classClassScope, SyntaxNode node, bool abstractMode); void compileCustomDispatcher(BuildTreeWriter& writer, ClassScope& scope); - void compileNestedClass(BuildTreeWriter& writer, ClassScope& scope, SyntaxNode node, ref_t parentRef); + void compileNestedClass(BuildTreeWriter& writer, ClassScope& scope, SyntaxNode node, ref_t parentRef); void compileStatemachineClass(BuildTreeWriter& writer, StatemachineClassScope& scope, SyntaxNode node, ref_t parentRef); void compileVMT(BuildTreeWriter& writer, ClassScope& scope, SyntaxNode node, @@ -1833,7 +1855,7 @@ namespace elena_lang void validateType(Scope& scope, ref_t typeRef, SyntaxNode node, bool ignoreUndeclared); void injectVirtualCode(SyntaxNode classNode, ClassScope& scope, bool interfaceBased); - void injectVirtualMultimethod(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, + void injectVirtualMultimethod(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, ref_t targetRef, ClassInfo& info, mssg_t multiMethod, int nillableArgs); void injectVirtualMethods(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, @@ -1843,21 +1865,21 @@ namespace elena_lang void injectInitializer(SyntaxNode classNode, SyntaxKey methodType, mssg_t message); - bool injectVirtualStrongTypedMultimethod(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, + bool injectVirtualStrongTypedMultimethod(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, mssg_t message, mssg_t resendMessage, TypeInfo outputInfo, Visibility visibility, bool isExtension, int nillableArgs, bool isSealed); bool injectVirtualStrongTypedVariadicMultimethod(SyntaxNode classNode, SyntaxKey methodType, ModuleScopeBase& scope, mssg_t message, mssg_t resendMessage, ref_t outputRef, Visibility visibility, bool isExtension); - void injectVirtualMultimethod(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, + void injectVirtualMultimethod(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, ref_t targetRef, ClassInfo& classInfo, mssg_t message, bool inherited, TypeInfo outputInfo, Visibility visibility, int nillableArgs); void injectVirtualMultimethod(SyntaxNode classNode, SyntaxKey methodType, Scope& scope, mssg_t message, mssg_t resendMessage, ref_t resendTarget, TypeInfo outputInfo, Visibility visibility, bool isExtension, bool isSealed); - void injectVirtualTryDispatch(SyntaxNode classNode, SyntaxKey methodType, ClassInfo& info, + void injectVirtualTryDispatch(SyntaxNode classNode, SyntaxKey methodType, ClassInfo& info, mssg_t message, mssg_t dispatchMessage, bool inherited); void injectVirtualTryDispatch(SyntaxNode classNode, SyntaxKey methodType, mssg_t message, mssg_t dispatchMessage, ref_t resendTarget); - void injectDefaultConstructor(ClassScope& scope, SyntaxNode node, + void injectDefaultConstructor(ClassScope& scope, SyntaxNode node, bool protectedOne, bool withClearOption); void addVariableInfo(BuildNode node, Scope& codeScope, ustr_t name, Parameter& parameter); @@ -1873,7 +1895,7 @@ namespace elena_lang void callInitMethod(Expression& expression, SyntaxNode node, ClassInfo& info, ref_t reference); - void generateOverloadListMember(ModuleScopeBase& scope, ref_t listRef, ref_t classRef, + void generateOverloadListMember(ModuleScopeBase& scope, ref_t listRef, ref_t classRef, mssg_t messageRef, MethodHint type) override; void createPackageInfo(ModuleScopeBase* moduleScope, ManifestInfo& manifestInfo); @@ -1900,6 +1922,15 @@ namespace elena_lang _evaluateOp = flag; } + bool checkStrictTypeFlag() + { + return _strictTypeEnforcing; + } + void setStrictTypeFlag(bool flag) + { + _strictTypeEnforcing = flag; + } + void setVerboseOn() { _verbose = true; @@ -1923,18 +1954,18 @@ namespace elena_lang void injectVirtualReturningMethod(Scope& scope, SyntaxNode classNode, mssg_t message, ustr_t retVar, TypeInfo outputTypeInfo); - ref_t resolvePrimitiveType(ModuleScopeBase& moduleScope, TypeInfo typeInfo, + ref_t resolvePrimitiveType(ModuleScopeBase& moduleScope, TypeInfo typeInfo, bool declarationMode = false) override; - ref_t generateExtensionTemplate(ModuleScopeBase& scope, ref_t templateRef, size_t argumentLen, ref_t* arguments, + ref_t generateExtensionTemplate(ModuleScopeBase& scope, ref_t templateRef, size_t argumentLen, ref_t* arguments, ustr_t ns, ExtensionMap* outerExtensionList) override; Compiler( PresenterBase* presenter, - ErrorProcessor* errorProcessor, + ErrorProcessor* errorProcessor, TemplateProssesorBase* templateProcessor, CompilerLogic* compilerLogic); }; } -#endif \ No newline at end of file +#endif diff --git a/elenasrc3/elc/compilerlogic.cpp b/elenasrc3/elc/compilerlogic.cpp index 3a3826a00c..af9d854732 100644 --- a/elenasrc3/elc/compilerlogic.cpp +++ b/elenasrc3/elc/compilerlogic.cpp @@ -120,7 +120,7 @@ constexpr Op Operations[OperationLength] = { BNOT_OPERATOR_ID, BuildKey::IntSOp, V_INT32, 0, 0, V_INT32 }, - { + { NEGATE_OPERATOR_ID, BuildKey::IntSOp, V_INT32, 0, 0, V_INT32 }, { @@ -483,9 +483,9 @@ constexpr Op Operations[OperationLength] = { MUL_OPERATOR_ID, BuildKey::ShortOp, V_UINT16, V_UINT16, 0, V_UINT16 }, - { + { DIV_OPERATOR_ID, BuildKey::ShortOp, V_UINT16, V_UINT16, 0, V_UINT16 - }, + }, { ADD_ASSIGN_OPERATOR_ID, BuildKey::ShortOp, V_UINT16, V_UINT16, 0, 0 }, @@ -1194,7 +1194,7 @@ bool CompilerLogic :: validateMessage(ModuleScopeBase& scope, ref_t hints, mssg_ } // const attribute can be applied only to a get-property - if (testMethodHint(hints, MethodHint::Constant) + if (testMethodHint(hints, MethodHint::Constant) && ((message & PREFIX_MESSAGE_MASK) != PROPERTY_MESSAGE && getArgCount(message) > 1)) { return false; @@ -1477,6 +1477,28 @@ bool CompilerLogic :: isWrapper(ClassInfo& info) && !test(info.header.flags, elDynamicRole); } +bool CompilerLogic ::isClosedClass(ModuleScopeBase& scope, ref_t reference) +{ + if (scope.cachedClosed.exist(reference)) + return scope.cachedClosed.get(reference); + + ClassInfo info; + if (defineClassInfo(scope, info, reference, true)) { + auto retVal = isClosedClass(info); + + scope.cachedClosed.add(reference, retVal); + + return retVal; + } + + return false; +} + +bool CompilerLogic :: isClosedClass(ClassInfo& info) +{ + return test(info.header.flags, elClosed); +} + bool CompilerLogic :: isMultiMethod(ClassInfo& info, MethodInfo& methodInfo) { return test(methodInfo.hints, (ref_t)MethodHint::Multimethod); @@ -1523,7 +1545,7 @@ void CompilerLogic :: tweakClassFlags(ModuleScopeBase& scope, ref_t classRef, Cl info.header.flags |= elDebugArray; } } - + if (isEmbeddableArray(info)) { auto inner = *info.fields.start(); switch (inner.typeInfo.typeRef) { @@ -1594,7 +1616,7 @@ void CompilerLogic :: tweakClassFlags(ModuleScopeBase& scope, ref_t classRef, Cl void CompilerLogic :: tweakPrimitiveClassFlags(ClassInfo& info, ref_t classRef) { - + } void CompilerLogic :: writeTypeMapEntry(MemoryBase* section, ustr_t key, ref_t reference) @@ -1733,7 +1755,7 @@ void CompilerLogic :: writeExtMessageEntry(MemoryBase* section, mssg_t message, writer.writeString(pattern); } -bool CompilerLogic :: readExtMessageEntry(ModuleBase* extModule, MemoryBase* section, ExtensionMap& map, +bool CompilerLogic :: readExtMessageEntry(ModuleBase* extModule, MemoryBase* section, ExtensionMap& map, ExtensionTemplateMap& extensionTemplates, ModuleScopeBase* scope) { bool importMode = extModule != scope->module; @@ -1766,7 +1788,7 @@ bool CompilerLogic :: readExtMessageEntry(ModuleBase* extModule, MemoryBase* sec return true; } -bool CompilerLogic :: defineClassInfo(ModuleScopeBase& scope, ClassInfo& info, ref_t reference, +bool CompilerLogic :: defineClassInfo(ModuleScopeBase& scope, ClassInfo& info, ref_t reference, bool headerOnly, bool fieldsOnly) { if (isPrimitiveRef(reference) && !headerOnly) { @@ -2044,7 +2066,7 @@ inline ref_t getSignature(ModuleScopeBase& scope, mssg_t message) return signRef; } -bool CompilerLogic :: isSignatureCompatible(ModuleScopeBase& scope, ModuleBase* targetModule, ref_t targetSignature, +bool CompilerLogic :: isSignatureCompatible(ModuleScopeBase& scope, ModuleBase* targetModule, ref_t targetSignature, ref_t* sourceSignatures, size_t sourceLen) { ref_t targetSignatures[ARG_COUNT]; @@ -2066,7 +2088,7 @@ bool CompilerLogic :: isSignatureCompatible(ModuleScopeBase& scope, ModuleBase* return true; } -bool CompilerLogic :: isSignatureCompatible(ModuleScopeBase& scope, ref_t targetSignature, +bool CompilerLogic :: isSignatureCompatible(ModuleScopeBase& scope, ref_t targetSignature, ref_t* sourceSignatures, size_t sourceLen) { ref_t targetSignatures[ARG_COUNT]; @@ -2094,7 +2116,7 @@ bool CompilerLogic :: isSignatureCompatible(ModuleScopeBase& scope, mssg_t targe return isSignatureCompatible(scope, getSignature(scope, targetMessage), sourceSignatures, len); } -bool CompilerLogic :: isMessageCompatibleWithSignature(ModuleScopeBase& scope, ref_t targetRef, +bool CompilerLogic :: isMessageCompatibleWithSignature(ModuleScopeBase& scope, ref_t targetRef, mssg_t targetMessage, ref_t* sourceSignature, size_t len, int& stackSafeAttr) { ref_t targetSignRef = getSignature(scope, targetMessage); @@ -2135,7 +2157,7 @@ void CompilerLogic :: setSignatureStacksafe(ModuleScopeBase& scope, ref_t target } } -void CompilerLogic :: setSignatureStacksafe(ModuleScopeBase& scope, ModuleBase* targetModule, +void CompilerLogic :: setSignatureStacksafe(ModuleScopeBase& scope, ModuleBase* targetModule, ref_t targetSignature, int& stackSafeAttr) { ref_t targetSignatures[ARG_COUNT]; @@ -2184,7 +2206,7 @@ inline ref_t mapWeakSignature(ModuleScopeBase& scope, int counter) return scope.module->mapSignature(signatures, signatureLen, false); } -mssg_t CompilerLogic :: resolveMultimethod(ModuleScopeBase& scope, mssg_t weakMessage, ref_t targetRef, +mssg_t CompilerLogic :: resolveMultimethod(ModuleScopeBase& scope, mssg_t weakMessage, ref_t targetRef, ref_t implicitSignatureRef, int& stackSafeAttr, bool selfCall) { if (!targetRef) @@ -2243,8 +2265,8 @@ mssg_t CompilerLogic :: resolveMultimethod(ModuleScopeBase& scope, mssg_t weakMe } } else { - if (isSignatureCompatible(scope, sectionInfo.module, - argSign, signatures, signatureLen)) + if (isSignatureCompatible(scope, sectionInfo.module, + argSign, signatures, signatureLen)) { setSignatureStacksafe(scope, sectionInfo.module, argSign, stackSafeAttr); @@ -2274,14 +2296,14 @@ mssg_t CompilerLogic :: retrieveDynamicConvertor(ModuleScopeBase& scope, ref_t t return 0; } -mssg_t CompilerLogic :: retrieveImplicitConstructor(ModuleScopeBase& scope, ref_t targetRef, ref_t signRef, +mssg_t CompilerLogic :: retrieveImplicitConstructor(ModuleScopeBase& scope, ref_t targetRef, ref_t signRef, pos_t signLen, int& stackSafeAttrs) { ref_t classClassRef = getClassClassRef(scope, targetRef); mssg_t messageRef = overwriteArgCount(scope.buildins.constructor_message, signLen); // try to resolve implicit multi-method - mssg_t resolvedMessage = resolveMultimethod(scope, messageRef, classClassRef, + mssg_t resolvedMessage = resolveMultimethod(scope, messageRef, classClassRef, signRef, stackSafeAttrs, false); if (resolvedMessage) @@ -2292,7 +2314,7 @@ mssg_t CompilerLogic :: retrieveImplicitConstructor(ModuleScopeBase& scope, ref_ return 0; } -ConversionRoutine CompilerLogic :: retrieveConversionRoutine(CompilerBase* compiler, ModuleScopeBase& scope, ustr_t ns, +ConversionRoutine CompilerLogic :: retrieveConversionRoutine(CompilerBase* compiler, ModuleScopeBase& scope, ustr_t ns, ref_t targetRef, TypeInfo sourceInfo, bool directConversion) { ClassInfo info; @@ -2390,12 +2412,12 @@ bool CompilerLogic :: checkMethod(ClassInfo& info, mssg_t message, CheckMethodRe result.kind = methodInfo.hints & (ref_t)MethodHint::Mask; if (result.kind == (ref_t)MethodHint::Normal) { // check if the normal method can be called directly / semi-directly - if (test(info.header.flags, elSealed)) { - result.kind = (ref_t)MethodHint::Sealed; // mark it as sealed - because the class is sealed - } - else if (MethodInfo::checkHint(methodInfo, MethodHint::Indexed)) { + if (MethodInfo::checkHint(methodInfo, MethodHint::Indexed)) { result.kind = (ref_t)MethodHint::ByIndex; } + else if (test(info.header.flags, elSealed)) { + result.kind = (ref_t)MethodHint::Sealed; // mark it as sealed - because the class is sealed + } else if (test(info.header.flags, elClosed)) { result.kind = (ref_t)MethodHint::Fixed; // mark it as fixed - because the class is closed } @@ -2479,7 +2501,7 @@ bool CompilerLogic :: isMessageSupported(ClassInfo& info, mssg_t message, CheckM return false; } -bool CompilerLogic :: resolveCallType(ModuleScopeBase& scope, ref_t classRef, mssg_t message, +bool CompilerLogic :: resolveCallType(ModuleScopeBase& scope, ref_t classRef, mssg_t message, CheckMethodResult& result) { if (!classRef) @@ -2544,7 +2566,7 @@ inline ustr_t resolveActionName(ModuleBase* module, mssg_t message) return module->resolveAction(getAction(message), signRef); } -ref_t CompilerLogic :: generateOverloadList(CompilerBase* compiler, ModuleScopeBase& scope, MethodHint callType, ClassInfo::MethodMap& methods, +ref_t CompilerLogic :: generateOverloadList(CompilerBase* compiler, ModuleScopeBase& scope, MethodHint callType, ClassInfo::MethodMap& methods, mssg_t message, void* param, ref_t(*resolve)(void*, ref_t)) { // create a new overload list @@ -2689,7 +2711,7 @@ mssg_t CompilerLogic :: resolveFunctionSingleDispatch(ModuleScopeBase& scope, re ClassInfo info; if (defineClassInfo(scope, info, reference)) { ref_t actionRef = scope.module->mapAction(INVOKE_MESSAGE, 0, true); - for (int i = 0; i < ARG_COUNT; i++) { + for (pos_t i = 0; i < ARG_COUNT; i++) { mssg_t weakMessage = encodeMessage(actionRef, i, FUNCTION_MESSAGE); if (info.methods.exist(weakMessage)) @@ -2736,7 +2758,7 @@ inline void decodeClassName(IdentifierString& signature) else signature.replaceAll('@', '\'', 0); } -ref_t CompilerLogic :: resolveExtensionTemplate(ModuleScopeBase& scope, CompilerBase* compiler, ustr_t pattern, ref_t signatureRef, +ref_t CompilerLogic :: resolveExtensionTemplate(ModuleScopeBase& scope, CompilerBase* compiler, ustr_t pattern, ref_t signatureRef, ustr_t ns, ExtensionMap* outerExtensionList) { size_t argumentLen = 0; @@ -2745,16 +2767,19 @@ ref_t CompilerLogic :: resolveExtensionTemplate(ModuleScopeBase& scope, Compiler scope.module->resolveSignature(signatureRef, signatures); // matching pattern with the provided signature - size_t i = pattern.find('.') + 2; + size_t i = pattern.find('.') ; // define an argument length size_t argLenPos = pattern.findSub(0, '#', i, NOTFOUND_POS); if (i != NOTFOUND_POS) { + i += 2; + String tmp; tmp.copy(pattern + argLenPos + 1, i - argLenPos - 3); argumentLen = tmp.toInt(); } + else i = getlength(pattern); IdentifierString templateName(pattern, i - 2); ref_t templateRef = scope.mapFullReference(*templateName, true); @@ -2865,6 +2890,31 @@ ref_t CompilerLogic :: resolveExtensionTemplate(ModuleScopeBase& scope, Compiler return 0; } +ref_t CompilerLogic :: resolveExtensionTemplateByTemplateArgs(ModuleScopeBase& scope, CompilerBase* compiler, ustr_t pattern, + ustr_t ns, size_t argumentLen, ref_t* arguments, ExtensionMap* outerExtensionList) +{ + // matching pattern with the provided signature + size_t i = pattern.find('.'); + + // define an argument length + size_t argLenPos = pattern.findSub(0, '#', i, NOTFOUND_POS); + if (i != NOTFOUND_POS) { + i += 2; + + String tmp; + tmp.copy(pattern + argLenPos + 1, i - argLenPos - 3); + + if(argumentLen != tmp.toInt()) + return 0; + } + else return 0; + + IdentifierString templateName(pattern, i - 2); + ref_t templateRef = scope.mapFullReference(*templateName, true); + + return compiler->generateExtensionTemplate(scope, templateRef, argumentLen, arguments, ns, outerExtensionList); +} + bool CompilerLogic :: isNumericType(ModuleScopeBase& scope, ref_t& reference) { if (isCompatible(scope, { V_INT8 }, { reference }, false)) { @@ -2882,7 +2932,8 @@ bool CompilerLogic :: isNumericType(ModuleScopeBase& scope, ref_t& reference) return true; } - if (isCompatible(scope, { V_INT64 }, { reference }, false)) { + if (isCompatible(scope, { V_INT64 }, { reference }, false) && !isCompatible(scope, { V_PTR64 }, { reference }, false)) { + // HOTFIX : ignore pointer reference = V_INT64; return true; @@ -3020,7 +3071,7 @@ ref_t CompilerLogic :: loadClassInfo(ClassInfo& info, ModuleInfo& moduleInfo, Mo return moduleInfo.reference; } -void CompilerLogic :: importClassInfo(ClassInfo& copy, ClassInfo& target, ModuleBase* exporter, +void CompilerLogic :: importClassInfo(ClassInfo& copy, ClassInfo& target, ModuleBase* exporter, ModuleBase* importer, bool headerOnly, bool inheritMode) { target.header = copy.header; diff --git a/elenasrc3/elc/compilerlogic.h b/elenasrc3/elc/compilerlogic.h index 88bca2bfe9..287167c938 100644 --- a/elenasrc3/elc/compilerlogic.h +++ b/elenasrc3/elc/compilerlogic.h @@ -140,6 +140,9 @@ namespace elena_lang bool isStacksafeArg(ModuleScopeBase& scope, ref_t reference); bool isStacksafeArg(ClassInfo& info); + bool isClosedClass(ClassInfo& info); + bool isClosedClass(ModuleScopeBase& scope, ref_t reference); + bool isMultiMethod(ClassInfo& info, MethodInfo& methodInfo); bool isValidOp(int operatorId, const int* validOperators, size_t len); @@ -217,6 +220,8 @@ namespace elena_lang virtual ref_t resolveExtensionTemplate(ModuleScopeBase& scope, CompilerBase* compiler, ustr_t pattern, ref_t signatureRef, ustr_t ns, ExtensionMap* outerExtensionList); + virtual ref_t resolveExtensionTemplateByTemplateArgs(ModuleScopeBase& scope, CompilerBase* compiler, ustr_t pattern, + ustr_t ns, size_t argumentLen, ref_t* arguments, ExtensionMap* outerExtensionList); bool isValidType(ModuleScopeBase& scope, ref_t classReference, bool ignoreUndeclared); diff --git a/elenasrc3/elc/compiling.cpp b/elenasrc3/elc/compiling.cpp index 0c9ab3d363..726083cc56 100644 --- a/elenasrc3/elc/compiling.cpp +++ b/elenasrc3/elc/compiling.cpp @@ -237,7 +237,7 @@ ref_t CompilingProcess::TemplateGenerator :: generateTemplateName(ModuleScopeBas return moduleScope.mapTemplateIdentifier(*name, visibility, alreadyDeclared, false); } -ref_t CompilingProcess::TemplateGenerator :: declareTemplateName(ModuleScopeBase& moduleScope, Visibility visibility, +ref_t CompilingProcess::TemplateGenerator :: declareTemplateName(ModuleScopeBase& moduleScope, Visibility visibility, ref_t templateRef, List& parameters) { ModuleBase* module = moduleScope.module; @@ -324,9 +324,9 @@ CompilingProcess :: CompilingProcess(path_t appPath, path_t exeExtension, JITSettings defaultCoreSettings, JITCompilerBase* (*compilerFactory)(LibraryLoaderBase*, PlatformType) ) : + _appPath(appPath), _templateGenerator(this), - _forwards(nullptr), - _appPath(appPath) + _forwards(nullptr) { _exeExtension = exeExtension; _modulePrologName = modulePrologName; @@ -419,11 +419,8 @@ void CompilingProcess :: parseFileUserDefinedGrammar(SyntaxWriterBase* syntaxWri try { // based on the target type generate the syntax tree for the file - PathString fullPath(projectPath); - fullPath.combine(path); - SyntaxTree derivationTree; - parser.parse(*fullPath, derivationTree); + parser.parse(path, derivationTree); syntaxWriter->saveTree(derivationTree); } @@ -502,7 +499,7 @@ void CompilingProcess :: parseModule(ProjectEnvironment& env, } } -bool CompilingProcess :: compileModule(ModuleScopeBase& moduleScope, SyntaxTree& source, BuildTree& target, +bool CompilingProcess :: compileModule(ModuleScopeBase& moduleScope, SyntaxTree& source, BuildTree& target, ExtensionMap* outerExtensionList) { bool nothingToCompile = _compiler->declare(&moduleScope, source, outerExtensionList); @@ -534,7 +531,7 @@ void CompilingProcess :: generateModule(ModuleScopeBase& moduleScope, BuildTree& } } -bool CompilingProcess :: buildSyntaxTree(ModuleScopeBase& moduleScope, SyntaxTree* syntaxTree, bool templateMode, +bool CompilingProcess :: buildSyntaxTree(ModuleScopeBase& moduleScope, SyntaxTree* syntaxTree, bool templateMode, ExtensionMap* outerExtensionList) { // generating build tree @@ -559,9 +556,9 @@ bool CompilingProcess :: buildModule(ProjectEnvironment& env, forwardResolver, _libraryProvider.createModule(module_it.name()), moduleSettings.debugMode ? _libraryProvider.createDebugModule(module_it.name()) : nullptr, - moduleSettings.stackAlingment, - moduleSettings.rawStackAlingment, - moduleSettings.ehTableEntrySize, + moduleSettings.stackAlingment, + moduleSettings.rawStackAlingment, + moduleSettings.ehTableEntrySize, minimalArgList, ptrSize, module_it.hints()); @@ -631,6 +628,9 @@ void CompilingProcess :: configurate(Project& project) bool evalOpFlag = project.BoolSetting(ProjectOption::EvaluateOp, DEFAULT_EVALUATE_OP); _compiler->setEvaluateOp(evalOpFlag); + bool strictTypeFlag = project.BoolSetting(ProjectOption::StrictTypeEnforcing, DEFAULT_STRICT_TYPE_ENFORCING); + _compiler->setStrictTypeFlag(strictTypeFlag); + // load program forwards for (auto it = _forwards.start(); !it.eof(); ++it) { ustr_t f = *it; @@ -688,7 +688,7 @@ void CompilingProcess :: compile(ProjectBase& project, freeobj(module_it); - _presenter->print(compiled + _presenter->print(compiled ? ELC_SUCCESSFUL_COMPILATION : ELC_IDLE_COMPILATION); } @@ -806,6 +806,9 @@ int CompilingProcess :: build(Project& project, if (!profile.empty()) _presenter->printLine(ELC_PROFILE_INFO, profile); + if (_compiler->checkStrictTypeFlag()) + _presenter->printLine(ELC_STRICT_MODE); + // Cleaning up _presenter->printLine(ELC_CLEANING); cleanUp(project); diff --git a/elenasrc3/elc/derivation.cpp b/elenasrc3/elc/derivation.cpp index ff3d33aa29..aa3e64db2b 100644 --- a/elenasrc3/elc/derivation.cpp +++ b/elenasrc3/elc/derivation.cpp @@ -43,7 +43,7 @@ inline ustr_t retrievePath(SyntaxNode node) return ""; } -void SyntaxTreeBuilder :: flushNode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushNode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxTree::copyNewNode(writer, node); @@ -54,7 +54,7 @@ void SyntaxTreeBuilder :: flushNode(SyntaxTreeWriter& writer, Scope& scope, Synt writer.closeNode(); } -void SyntaxTreeBuilder :: flushCollection(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushCollection(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -64,7 +64,7 @@ void SyntaxTreeBuilder :: flushCollection(SyntaxTreeWriter& writer, Scope& scope } } -void SyntaxTreeBuilder :: flushNamespace(SyntaxTreeWriter& writer, SyntaxNode node) +void SyntaxTreeBuilder :: flushNamespace(SyntaxTreeWriter& writer, SyntaxNode& node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -187,7 +187,7 @@ void SyntaxTreeBuilder :: parseStatement(SyntaxTreeWriter& writer, Scope& scope, scope.nestedLevel -= 0x100; } -void SyntaxTreeBuilder :: generateTemplateStatement(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: generateTemplateStatement(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { List arguments({}); List parameters({}); @@ -243,7 +243,8 @@ void SyntaxTreeBuilder :: generateTemplateExpression(SyntaxTreeWriter& writer, S SyntaxTreeWriter tempWriter(tempTree); tempWriter.newNode(SyntaxKey::Idle); - flushExpression(tempWriter, scope, node.firstChild(SyntaxKey::ScopeMask)); + SyntaxNode child = node.firstChild(SyntaxKey::ScopeMask); + flushExpression(tempWriter, scope, child); parameters.add(tempWriter.CurrentNode().firstChild()); tempWriter.closeNode(); @@ -278,7 +279,7 @@ void SyntaxTreeBuilder :: generateTemplateExpression(SyntaxTreeWriter& writer, S } } -void SyntaxTreeBuilder :: flushIdentifier(SyntaxTreeWriter& writer, SyntaxNode identNode, bool ignoreTerminalInfo) +void SyntaxTreeBuilder :: flushIdentifier(SyntaxTreeWriter& writer, SyntaxNode& identNode, bool ignoreTerminalInfo) { SyntaxTree::copyNewNode(writer, identNode); @@ -288,7 +289,7 @@ void SyntaxTreeBuilder :: flushIdentifier(SyntaxTreeWriter& writer, SyntaxNode i writer.closeNode(); } -void SyntaxTreeBuilder :: flushL6AsTemplateArg(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushL6AsTemplateArg(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(SyntaxKey::TemplateArg); @@ -306,7 +307,7 @@ void SyntaxTreeBuilder :: flushL6AsTemplateArg(SyntaxTreeWriter& writer, Scope& writer.closeNode(); } -void SyntaxTreeBuilder :: flushTemplateType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool exprMode) +void SyntaxTreeBuilder :: flushTemplateType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool exprMode) { if (exprMode) { SyntaxNode objNode = node.findChild(SyntaxKey::Object); @@ -365,7 +366,7 @@ void SyntaxTreeBuilder :: flushTemplateType(SyntaxTreeWriter& writer, Scope& sco } } -void SyntaxTreeBuilder :: flushArrayType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool exprMode, int nestLevel) +void SyntaxTreeBuilder :: flushArrayType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool exprMode, int nestLevel) { SyntaxNode current = node.firstChild(); @@ -397,7 +398,7 @@ void SyntaxTreeBuilder :: flushArrayType(SyntaxTreeWriter& writer, Scope& scope, } } -void SyntaxTreeBuilder :: flushResend(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushResend(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); @@ -437,7 +438,7 @@ void SyntaxTreeBuilder :: flushResend(SyntaxTreeWriter& writer, Scope& scope, Sy writer.closeNode(); } -void SyntaxTreeBuilder :: flushObject(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushObject(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); @@ -502,7 +503,7 @@ void SyntaxTreeBuilder :: flushObject(SyntaxTreeWriter& writer, Scope& scope, Sy writer.closeNode(); } -void SyntaxTreeBuilder :: flushNested(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushNested(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); @@ -525,7 +526,7 @@ void SyntaxTreeBuilder :: flushNested(SyntaxTreeWriter& writer, Scope& scope, Sy writer.closeNode(); } -void SyntaxTreeBuilder :: flushMessage(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushMessage(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); @@ -539,7 +540,7 @@ void SyntaxTreeBuilder :: flushMessage(SyntaxTreeWriter& writer, Scope& scope, S writer.closeNode(); } -void SyntaxTreeBuilder :: generateTemplateOperation(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: generateTemplateOperation(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { List arguments({}); List parameters({}); @@ -568,7 +569,8 @@ void SyntaxTreeBuilder :: generateTemplateOperation(SyntaxTreeWriter& writer, Sc SyntaxTreeWriter tempWriter(tempTree); tempWriter.newNode(SyntaxKey::Idle); - flushObject(tempWriter, scope, op.firstChild(SyntaxKey::Object)); + SyntaxNode objNode = op.firstChild(SyntaxKey::Object); + flushObject(tempWriter, scope, objNode); arguments.add(tempWriter.CurrentNode().firstChild()); tempWriter.closeNode(); @@ -592,7 +594,7 @@ void SyntaxTreeBuilder :: generateTemplateOperation(SyntaxTreeWriter& writer, Sc } } -void SyntaxTreeBuilder :: flushNullable(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushNullable(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode objNode = node.firstChild(); SyntaxNode current = objNode.nextNode(); @@ -650,6 +652,9 @@ void SyntaxTreeBuilder :: flushExpressionMember(SyntaxTreeWriter& writer, Scope& case SyntaxKey::NullableType: flushNullable(writer, scope, current); break; + case SyntaxKey::TemplateArg: + flushTemplateArg(writer, scope, current, true); + break; case SyntaxKey::interpolate: flushNode(writer, scope, current); break; @@ -668,7 +673,7 @@ void SyntaxTreeBuilder :: flushExpressionMember(SyntaxTreeWriter& writer, Scope& } } -void SyntaxTreeBuilder :: flushExpressionCollection(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushExpressionCollection(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -678,7 +683,7 @@ void SyntaxTreeBuilder :: flushExpressionCollection(SyntaxTreeWriter& writer, Sc } } -void SyntaxTreeBuilder :: flushExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); @@ -687,7 +692,7 @@ void SyntaxTreeBuilder :: flushExpression(SyntaxTreeWriter& writer, Scope& scope writer.closeNode(); } -void SyntaxTreeBuilder :: flushDictionary(SyntaxTreeWriter& writer, SyntaxNode node) +void SyntaxTreeBuilder :: flushDictionary(SyntaxTreeWriter& writer, SyntaxNode& node) { writer.newNode(node.key); @@ -697,7 +702,7 @@ void SyntaxTreeBuilder :: flushDictionary(SyntaxTreeWriter& writer, SyntaxNode n writer.closeNode(); } -void SyntaxTreeBuilder :: flushTupleType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, ref_t& attributeCategory) +void SyntaxTreeBuilder :: flushTupleType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, ref_t& attributeCategory) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -709,7 +714,7 @@ void SyntaxTreeBuilder :: flushTupleType(SyntaxTreeWriter& writer, Scope& scope, } } -void SyntaxTreeBuilder :: flushDescriptor(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool withNameNode, +void SyntaxTreeBuilder :: flushDescriptor(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool withNameNode, bool typeDescriptor, bool exprMode) { SyntaxNode nameNode = node.lastChild(SyntaxKey::TerminalMask); @@ -803,7 +808,7 @@ void SyntaxTreeBuilder :: flushDescriptor(SyntaxTreeWriter& writer, Scope& scope } } -bool SyntaxTreeBuilder :: flushAttribute(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, +bool SyntaxTreeBuilder :: flushAttribute(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, ref_t& previusCategory, bool allowType, int arrayNestLevel) { bool typeExpr = false; @@ -847,7 +852,7 @@ bool SyntaxTreeBuilder :: flushAttribute(SyntaxTreeWriter& writer, Scope& scope, return typeExpr; } -void SyntaxTreeBuilder :: flushTypeAttribute(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, +void SyntaxTreeBuilder :: flushTypeAttribute(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, ref_t& previusCategory, bool allowType, bool onlyChildren) { if (!onlyChildren) @@ -856,7 +861,8 @@ void SyntaxTreeBuilder :: flushTypeAttribute(SyntaxTreeWriter& writer, Scope& sc SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { if (current == SyntaxKey::ArrayType) { - flushAttribute(writer, scope, current.firstChild(), previusCategory, allowType, 1); + SyntaxNode attrNode = current.firstChild(); + flushAttribute(writer, scope, attrNode, previusCategory, allowType, 1); } else if (current == SyntaxKey::TemplateType) { flushTemplateType(writer, scope, current, false); @@ -870,7 +876,7 @@ void SyntaxTreeBuilder :: flushTypeAttribute(SyntaxTreeWriter& writer, Scope& sc writer.closeNode(); } -void SyntaxTreeBuilder :: flushTemplateArg(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool allowType) +void SyntaxTreeBuilder :: flushTemplateArg(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool allowType) { writer.newNode(SyntaxKey::TemplateArg); @@ -914,7 +920,7 @@ void SyntaxTreeBuilder :: flushTemplateArg(SyntaxTreeWriter& writer, Scope& scop writer.closeNode(); } -void SyntaxTreeBuilder :: flushTemplageExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, +void SyntaxTreeBuilder :: flushTemplageExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, SyntaxKey type, bool allowType) { writer.newNode(type); @@ -939,7 +945,7 @@ void SyntaxTreeBuilder :: flushTemplageExpression(SyntaxTreeWriter& writer, Scop writer.closeNode(); } -void SyntaxTreeBuilder :: flushClassMemberPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node/*, bool ignorePostfix*/) +void SyntaxTreeBuilder :: flushClassMemberPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node/*, bool ignorePostfix*/) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -964,7 +970,7 @@ void SyntaxTreeBuilder :: flushClassMemberPostfixes(SyntaxTreeWriter& writer, Sc } } -void SyntaxTreeBuilder :: flushParentTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushParentTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); @@ -981,7 +987,7 @@ void SyntaxTreeBuilder :: flushParentTemplate(SyntaxTreeWriter& writer, Scope& s writer.closeNode(); } -void SyntaxTreeBuilder :: flushEnumTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushEnumTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); @@ -1001,7 +1007,7 @@ void SyntaxTreeBuilder :: flushEnumTemplate(SyntaxTreeWriter& writer, Scope& sco writer.closeNode(); } -void SyntaxTreeBuilder :: flushParent(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushParent(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { ref_t attributeCategory = V_CATEGORY_MAX; @@ -1025,7 +1031,7 @@ void SyntaxTreeBuilder :: flushParent(SyntaxTreeWriter& writer, Scope& scope, Sy } } -void SyntaxTreeBuilder :: flushSymbolPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushSymbolPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -1037,13 +1043,14 @@ void SyntaxTreeBuilder :: flushSymbolPostfixes(SyntaxTreeWriter& writer, Scope& } } -void SyntaxTreeBuilder :: flushClassPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushClassPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { if (current.key == SyntaxKey::Postfix) { if (current.firstChild() == SyntaxKey::InlinePostfix) { - flushTemplageExpression(writer, scope, current.firstChild(), SyntaxKey::InlineTemplate, false); + SyntaxNode childNode = current.firstChild(); + flushTemplageExpression(writer, scope, childNode, SyntaxKey::InlineTemplate, false); } else { writer.newNode(SyntaxKey::Parent); @@ -1063,22 +1070,22 @@ void SyntaxTreeBuilder :: flushClassPostfixes(SyntaxTreeWriter& writer, Scope& s } } -void SyntaxTreeBuilder :: flushStatement(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushStatement(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { flushExpression(writer, scope, node); } -void SyntaxTreeBuilder :: flushMethodMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushMethodMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool exprMode) { writer.newNode(node.key); - flushDescriptor(writer, scope, node); + flushDescriptor(writer, scope, node, true, false, exprMode); //flushImports(scope, node); writer.closeNode(); } -void SyntaxTreeBuilder :: flushExpressionAsDescriptor(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushExpressionAsDescriptor(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -1092,7 +1099,7 @@ void SyntaxTreeBuilder :: flushExpressionAsDescriptor(SyntaxTreeWriter& writer, } -void SyntaxTreeBuilder :: flushParameterBlock(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushParameterBlock(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -1107,7 +1114,7 @@ void SyntaxTreeBuilder :: flushParameterBlock(SyntaxTreeWriter& writer, Scope& s } } -void SyntaxTreeBuilder :: flushMethodCode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushMethodCode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); @@ -1134,14 +1141,14 @@ void SyntaxTreeBuilder :: flushMethodCode(SyntaxTreeWriter& writer, Scope& scope writer.closeNode(); } -void SyntaxTreeBuilder :: flushClosure(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushClosure(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { if (current == SyntaxKey::Parameter) { - flushMethodMember(writer, scope, current); + flushMethodMember(writer, scope, current, true); } else if (current == SyntaxKey::ParameterBlock) { flushParameterBlock(writer, scope, current); @@ -1157,7 +1164,7 @@ void SyntaxTreeBuilder :: flushClosure(SyntaxTreeWriter& writer, Scope& scope, S writer.closeNode(); } -void SyntaxTreeBuilder :: flushMethod(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushMethod(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { if (scope.type != ScopeType::Unknown) { ustr_t path = retrievePath(writer.CurrentNode()); @@ -1211,7 +1218,7 @@ bool ifTypeRelatedExists(SyntaxNode node) return false; } -void SyntaxTreeBuilder :: copyType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: copyType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -1223,7 +1230,7 @@ void SyntaxTreeBuilder :: copyType(SyntaxTreeWriter& writer, Scope& scope, Synta } } -void SyntaxTreeBuilder :: copyHeader(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool includeType) +void SyntaxTreeBuilder :: copyHeader(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool includeType) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -1307,7 +1314,7 @@ inline void copyFunctionAttributes(SyntaxTreeWriter& writer, SyntaxNode node) } } -void SyntaxTreeBuilder :: flushClassMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool functionMode) +void SyntaxTreeBuilder :: flushClassMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool functionMode) { writer.newNode(node.key); @@ -1367,7 +1374,8 @@ void SyntaxTreeBuilder :: flushClassMember(SyntaxTreeWriter& writer, Scope& scop flushCollection(writer, scope, nameNode); writer.closeNode(); - flushExpression(writer, scope, node.findChild(member.key).firstChild()); + SyntaxNode exprNode = node.findChild(member.key).firstChild(); + flushExpression(writer, scope, exprNode); break; } case SyntaxKey::Dimension: @@ -1380,7 +1388,7 @@ void SyntaxTreeBuilder :: flushClassMember(SyntaxTreeWriter& writer, Scope& scop writer.closeNode(); } -void SyntaxTreeBuilder :: flushClass(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool functionMode) +void SyntaxTreeBuilder :: flushClass(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool functionMode) { flushClassPostfixes(writer, scope, node); @@ -1401,7 +1409,7 @@ void SyntaxTreeBuilder :: flushClass(SyntaxTreeWriter& writer, Scope& scope, Syn } } -void SyntaxTreeBuilder :: flushTemplateCode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushTemplateCode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { writer.newNode(node.key); @@ -1439,7 +1447,7 @@ void SyntaxTreeBuilder :: flushTemplateCode(SyntaxTreeWriter& writer, Scope& sco writer.closeNode(); } -void SyntaxTreeBuilder :: flushTemplateArgDescr(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushTemplateArgDescr(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode identNode = node.lastChild(SyntaxKey::TerminalMask); if(!scope.arguments.add(identNode.identifier(), scope.arguments.count() + 1, true)) { @@ -1449,7 +1457,7 @@ void SyntaxTreeBuilder :: flushTemplateArgDescr(SyntaxTreeWriter& writer, Scope& SyntaxTree::copyNode(writer, node, true); } -void SyntaxTreeBuilder :: flushParameterArgDescr(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushParameterArgDescr(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode identNode = node.lastChild(SyntaxKey::TerminalMask); if (!scope.parameters.add(identNode.identifier(), scope.parameters.count() + 1, true)) { @@ -1459,7 +1467,7 @@ void SyntaxTreeBuilder :: flushParameterArgDescr(SyntaxTreeWriter& writer, Scope SyntaxTree::copyNode(writer, node, true); } -void SyntaxTreeBuilder :: flushInlineTemplatePostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushInlineTemplatePostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { SyntaxNode current = node.firstChild(); while (current != SyntaxKey::None) { @@ -1471,7 +1479,7 @@ void SyntaxTreeBuilder :: flushInlineTemplatePostfixes(SyntaxTreeWriter& writer, } } -void SyntaxTreeBuilder :: flushExpressionTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushExpressionTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { scope.type = ScopeType::ExpressionTemplate; scope.ignoreTerminalInfo = true; @@ -1498,7 +1506,7 @@ void SyntaxTreeBuilder :: flushExpressionTemplate(SyntaxTreeWriter& writer, Scop } } -void SyntaxTreeBuilder :: flushInlineTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushInlineTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { scope.type = ScopeType::InlineTemplate; scope.ignoreTerminalInfo = true; @@ -1526,7 +1534,7 @@ void SyntaxTreeBuilder :: flushInlineTemplate(SyntaxTreeWriter& writer, Scope& s } } -void SyntaxTreeBuilder :: flushTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node) +void SyntaxTreeBuilder :: flushTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node) { // load arguments SyntaxNode current = node.findChild(SyntaxKey::TemplateArg); @@ -1702,7 +1710,7 @@ SyntaxTreeBuilder::ScopeType SyntaxTreeBuilder :: defineTemplateType(SyntaxNode return type; } -void SyntaxTreeBuilder :: flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode node) +void SyntaxTreeBuilder :: flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode& node) { Scope scope(_noDebugInfo); @@ -1716,7 +1724,8 @@ void SyntaxTreeBuilder :: flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode flushSymbolPostfixes(writer, scope, node); - flushStatement(writer, scope, node.findChild(SyntaxKey::GetExpression)); + SyntaxNode exprNode = node.findChild(SyntaxKey::GetExpression); + flushStatement(writer, scope, exprNode); } else if (isTemplateDeclaration(node, writer.CurrentNode(), withComplexName)) { if (withComplexName) { @@ -1871,6 +1880,49 @@ void SyntaxTreeBuilder :: renameNode(parse_key_t key) current.setKey(SyntaxTree::fromParseKey(key)); } +void SyntaxTreeBuilder :: mergeRChildren(parse_key_t key) +{ + SyntaxNode current = _cacheWriter.CurrentNode(); + + SyntaxNode rchild = current.firstChild().nextNode(); + SyntaxNode nextRChild = rchild.nextNode(); + if (rchild != SyntaxKey::None) { + rchild.encloseNode(SyntaxTree::fromParseKey(key)); + + while (nextRChild != SyntaxKey::None) { + SyntaxNode c = nextRChild; + nextRChild = nextRChild.nextNode(); + + rchild.mergeNodes(c); + } + } +} + +void SyntaxTreeBuilder::mergeLChildren(parse_key_t key) +{ + SyntaxNode current = _cacheWriter.CurrentNode(); + + SyntaxNode lchild = current.firstChild(); + SyntaxNode nextLChild = lchild.nextNode(); + lchild.encloseNode(SyntaxTree::fromParseKey(key)); + + while (nextLChild.nextNode() != SyntaxKey::None) { + SyntaxNode c = nextLChild; + nextLChild = nextLChild.nextNode(); + + lchild.mergeNodes(c); + } +} + +void SyntaxTreeBuilder :: encloseLastChild(parse_key_t key) +{ + SyntaxNode current = _cacheWriter.CurrentNode(); + SyntaxNode lastChild = current.lastChild(); + + if (lastChild != SyntaxKey::None) + lastChild.encloseNode(SyntaxTree::fromParseKey(key)); +} + void SyntaxTreeBuilder :: closeNode() { _level--; diff --git a/elenasrc3/elc/derivation.h b/elenasrc3/elc/derivation.h index 5143257ab4..602794776a 100644 --- a/elenasrc3/elc/derivation.h +++ b/elenasrc3/elc/derivation.h @@ -146,79 +146,82 @@ namespace elena_lang void parseStatement(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode current, List& arguments, List& parameters, IdentifierString& postfix); - void generateTemplateStatement(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); + void generateTemplateStatement(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); void generateTemplateExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void generateTemplateOperation(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); + void generateTemplateOperation(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); void loadMetaSection(SyntaxNode node); void clearMetaSection(SyntaxNode node); - void flushNode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushCollection(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - - void flushL6AsTemplateArg(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushIdentifier(SyntaxTreeWriter& writer, SyntaxNode identNode, bool ignoreTerminalInfo); - void flushTemplateCode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushTemplateArgDescr(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushParameterArgDescr(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushTemplateArg(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool allowType); - void flushTemplageExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, SyntaxKey type, bool allowType); - void flushTemplateType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool exprMode = true); - void flushArrayType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool exprMode, int nestLevel = 1); - void flushMessage(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushResend(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushObject(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushNested(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushNullable(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode current); - void flushClosure(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushExpressionCollection(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushExpressionAsDescriptor(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); + void flushNode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushCollection(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + + void flushL6AsTemplateArg(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushIdentifier(SyntaxTreeWriter& writer, SyntaxNode& identNode, bool ignoreTerminalInfo); + void flushTemplateCode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushTemplateArgDescr(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushParameterArgDescr(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushTemplateArg(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool allowType); + void flushTemplageExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, SyntaxKey type, bool allowType); + void flushTemplateType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool exprMode = true); + void flushArrayType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool exprMode, int nestLevel = 1); + void flushMessage(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushResend(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushObject(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushNested(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushNullable(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& current); + void flushClosure(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushExpressionCollection(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushExpressionAsDescriptor(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); void flushExpressionMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushStatement(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushMethodCode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushTupleType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, ref_t& previusCategory); - void flushEnumTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); + void flushStatement(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushMethodCode(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushTupleType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, ref_t& previusCategory); + void flushEnumTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); - void copyHeader(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool includeType); - void copyType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); + void copyHeader(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool includeType); + void copyType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); void flushSubScopeMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, SyntaxNode headerNode); void flushSubScope(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, SyntaxNode headerNode); - void flushClassMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool functionMode = false); - void flushMethod(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushMethodMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushParameterBlock(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - bool flushAttribute(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, ref_t& previusCategory, + void flushClassMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool functionMode = false); + void flushMethod(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushMethodMember(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool exprMode = false); + void flushParameterBlock(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + bool flushAttribute(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, ref_t& previusCategory, bool allowType, int arrayNestLevel = 0); - void flushTypeAttribute(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, ref_t& previusCategory, + void flushTypeAttribute(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, ref_t& previusCategory, bool allowType, bool onlyChildren = false); - void flushInlineTemplatePostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushClassMemberPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node/*, bool ignorePostfix*/); - void flushClassPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushSymbolPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushParent(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushParentTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - - void flushDescriptor(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool withNameNode = true, + void flushInlineTemplatePostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushClassMemberPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node/*, bool ignorePostfix*/); + void flushClassPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushSymbolPostfixes(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushParent(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushParentTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + + void flushDescriptor(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool withNameNode = true, bool typeDescriptor = false, bool exprMode = false); - void flushClass(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool functionMode); - void flushInlineTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushExpressionTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node); - void flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode node); - void flushDictionary(SyntaxTreeWriter& writer, SyntaxNode node); - void flushNamespace(SyntaxTreeWriter& writer, SyntaxNode node); + void flushClass(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node, bool functionMode); + void flushInlineTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushExpressionTemplate(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode& node); + void flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode& node); + void flushDictionary(SyntaxTreeWriter& writer, SyntaxNode& node); + void flushNamespace(SyntaxTreeWriter& writer, SyntaxNode& node); void flush(SyntaxTreeWriter& writer, SyntaxNode node); - public: void newNode(parse_key_t key) override; void newNode(parse_key_t key, ustr_t arg) override; void appendTerminal(parse_key_t key, ustr_t value, LineInfo lineInfo) override; void injectNode(parse_key_t key) override; + void renameNode(parse_key_t key) override; + void mergeRChildren(parse_key_t key) override; + void mergeLChildren(parse_key_t key) override; + void encloseLastChild(parse_key_t key) override; void closeNode() override; @@ -240,6 +243,7 @@ namespace elena_lang _errorProcessor = errorProcessor; _moduleScope = moduleScope; _templateProcessor = templateProcessor; + _noDebugInfo = false; _writer.clear(); _writer.newNode(SyntaxKey::Root); diff --git a/elenasrc3/elc/errors.h b/elenasrc3/elc/errors.h index 05f996631f..b88d6d21f4 100644 --- a/elenasrc3/elc/errors.h +++ b/elenasrc3/elc/errors.h @@ -66,6 +66,9 @@ namespace elena_lang constexpr auto errMsgUnknownDefConstructor = "\n%s(%d:%d): error 184: A constructor is not defined for the class\n"; constexpr auto errMsgUnknownMessage = "\n%s(%d:%d): error 185: Message '%s' does not handled by the object\n"; constexpr auto errMsgAssigningToSelf = "\n%s(%d:%d): error 186: Cannot assign a variable '%s' to itself\n"; + constexpr auto errMsgUnknownTypecast = "\n%s(%d:%d): error 188: typecasting routine cannot be found\n"; + constexpr auto errMsgUnknownFunction = "\n%s(%d:%d): error 189: Function message does not handled by the object '%s'\n"; + constexpr auto errMsgUnsupportedOperator = "\n%s(%d:%d): error 190: operator handler is not defined for %s\n"; constexpr auto errMsgUnknownModule = "\nlinker: error 201: Unknown module '%s'\n"; constexpr auto errMsgUnresovableLink = "\nlinker: error 202: Link '%s' is not resolved\n"; @@ -115,6 +118,8 @@ namespace elena_lang constexpr auto errMsgNotImplemented = "\nNot implemented error\n"; constexpr auto errMsgCorruptedVMT = "\nVMT structure is corrupt\n"; + constexpr auto errMssgFailedMemoryAllocation = "\nnFatal error: cannot allocate the memory\n"; + constexpr auto infoMsgNewMethod = "\ninfo 701: new method %s\n"; constexpr auto infoMsgCurrentMethod = "\ninfo 702: compiling method %s\n"; constexpr auto infoMsgCurrentClass = "\ninfo 703: compiling class %s\n"; diff --git a/elenasrc3/elc/linux/constants.h b/elenasrc3/elc/linux/constants.h index 5910002334..35138ea2f1 100644 --- a/elenasrc3/elc/linux/constants.h +++ b/elenasrc3/elc/linux/constants.h @@ -12,6 +12,7 @@ namespace elena_lang { // compiler service files + constexpr auto LOCAL_DEFAULT_CONFIG = "./local.elc60.config"; constexpr auto DEFAULT_CONFIG = "/etc/elena/elc60.config"; constexpr auto DATA_PATH = "/usr/share/elena"; diff --git a/elenasrc3/elc/linux/elc.cpp b/elenasrc3/elc/linux/elc.cpp index df6f5d1dae..c5ac72551f 100644 --- a/elenasrc3/elc/linux/elc.cpp +++ b/elenasrc3/elc/linux/elc.cpp @@ -42,6 +42,7 @@ #include "constants.h" #include "messages.h" #include "linux/presenter.h" +#include "linux/pathmanager.h" #include @@ -159,13 +160,15 @@ JITCompilerBase* createJITCompiler(LibraryLoaderBase* loader, PlatformType platf } } +const char* dataFileList[] = { BC_RULES_FILE, BT_RULES_FILE, SYNTAX60_FILE }; + int main(int argc, char* argv[]) { try { bool cleanMode = false; - PathString dataPath(DATA_PATH); + PathString dataPath(PathHelper::retrievePath(dataFileList, 3, DATA_PATH)); JITSettings defaultCoreSettings = { DEFAULT_MGSIZE, DEFAULT_YGSIZE, DEFAULT_STACKRESERV, 1, true }; ErrorProcessor errorProcessor(&Presenter::getInstance()); @@ -178,7 +181,13 @@ int main(int argc, char* argv[]) process.greeting(); // Initializing... - PathString configPath(*dataPath, DEFAULT_CONFIG); + 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... diff --git a/elenasrc3/elc/linux/elfarmimage.cpp b/elenasrc3/elc/linux/elfarmimage.cpp index 7cd69b651a..a0dce6b6b3 100644 --- a/elenasrc3/elc/linux/elfarmimage.cpp +++ b/elenasrc3/elc/linux/elfarmimage.cpp @@ -90,7 +90,7 @@ void ElfARM64ImageFormatter :: fillElfData(ImageProviderBase& provider, ElfData& symtabWriter.writeQWord(0); // relocation table entry - pos_t relPosition = reltabWriter.position() - reltabOffset; + //pos_t relPosition = reltabWriter.position() - reltabOffset; reltabWriter.writeQReference(importRef, gotPosition); reltabWriter.writeQWord((symbolIndex << 32) + relocateType); reltabWriter.writeQWord(0); diff --git a/elenasrc3/elc/linux/pathmanager.cpp b/elenasrc3/elc/linux/pathmanager.cpp new file mode 100644 index 0000000000..e200111f33 --- /dev/null +++ b/elenasrc3/elc/linux/pathmanager.cpp @@ -0,0 +1,77 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains implementation of PathHelper +// used to retrieve data / config paths +// (C)2024, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#include "clicommon.h" +// -------------------------------------------------------------------------- +#include "pathmanager.h" +#include + +using namespace elena_lang; + +// --- PathHelper --- + +PathHelper::PathMap* PathHelper::pathCache = nullptr; + +inline bool loadAppPath(char* appPath, size_t len) +{ + if (readlink("/proc/self/exe", appPath, len) == -1) + return false; + + size_t index = path_t(appPath).findLast(PATH_SEPARATOR); + if (index != NOTFOUND_POS) + appPath[index] = 0; + + return true; +} + +path_t PathHelper :: retrievePath(const char* filesToLookFor[], size_t listLength, path_t defaultPath) +{ + if (pathCache && pathCache->exist(defaultPath)) + return pathCache->get(defaultPath); + + char appPath[FILENAME_MAX] = { 0 }; + if (!loadAppPath(appPath, FILENAME_MAX)) + return defaultPath; + + for (size_t i = 0; i < listLength; i++) { + PathString fullPath(appPath, filesToLookFor[i]); + + if (!PathUtil::ifExist(*fullPath)) + return defaultPath; + } + + if (!pathCache) { + pathCache = new PathMap(nullptr); + } + + pathCache->add(defaultPath, path_t(appPath).clone()); + return pathCache->get(defaultPath); +} + +path_t PathHelper :: retrieveFilePath(path_t defaultPath) +{ + if (pathCache && pathCache->exist(defaultPath)) + return pathCache->get(defaultPath); + + char appPath[FILENAME_MAX] = { 0 }; + if (!loadAppPath(appPath, FILENAME_MAX)) + return defaultPath; + + PathString fullPath(appPath); + FileNameString fileName(defaultPath, true); + fullPath.combine(*fileName); + if (!PathUtil::ifExist(*fullPath)) + return defaultPath; + + if (!pathCache) { + pathCache = new PathMap(nullptr); + } + + pathCache->add(defaultPath, (*fullPath).clone()); + return pathCache->get(defaultPath); +} diff --git a/elenasrc3/elc/linux/pathmanager.h b/elenasrc3/elc/linux/pathmanager.h new file mode 100644 index 0000000000..718761850f --- /dev/null +++ b/elenasrc3/elc/linux/pathmanager.h @@ -0,0 +1,28 @@ +//--------------------------------------------------------------------------- +// E L E N A P r o j e c t: ELENA Compiler +// +// This header contains declaration of PathHelper +// used to retrieve data / config paths +// (C)2024, by Aleksey Rakov +//--------------------------------------------------------------------------- + +#ifndef ELC_PATHMANAGER_H +#define ELC_PATHMANAGER_H + +namespace elena_lang +{ + // --- PathHelper --- + class PathHelper + { + typedef Map PathMap; + + static PathMap* pathCache; + + public: + static path_t retrievePath(const char* filesToLookFor[], size_t listLength, path_t defaultPath); + + static path_t retrieveFilePath(path_t defaultPath); + }; +} + +#endif diff --git a/elenasrc3/elc/messages.h b/elenasrc3/elc/messages.h index e568e3ca69..b1623477a5 100644 --- a/elenasrc3/elc/messages.h +++ b/elenasrc3/elc/messages.h @@ -10,7 +10,7 @@ namespace elena_lang { - constexpr auto MessageLength = 98; + constexpr auto MessageLength = 103; const Pair Messages[MessageLength] = { {errDuplicatedSymbol, errMsgDuplicatedSymbol}, @@ -81,10 +81,11 @@ namespace elena_lang {errIllegalOperation, errMsgIllegalOperation}, {errUnknownDefConstructor, errMsgUnknownDefConstructor}, {wrnUnknownMessage, wrnMsgUnknownMessage}, - {wrnUnknownDefConstructor, wrnMsgUnknownDefConstructor}, {errUnknownMessage, errMsgUnknownMessage}, + {wrnUnknownDefConstructor, wrnMsgUnknownDefConstructor}, {errInvalidConstAttr, errMsgInvalidConstAttr}, {wrnUnknownFunction, wrnMsgUnknownFunction}, + {errUnknownFunction, errMsgUnknownFunction}, {errIllegalPrivate, errMsgIllegalPrivate}, {wrnTypeInherited, wrnMsgTypeInherited}, {errTypeAlreadyDeclared, errMsgTypeAlreadyDeclared}, @@ -92,7 +93,9 @@ namespace elena_lang {errClosureError, errMsgClosureError}, {errInvalidType, errMsgInvalidType}, {wrnUnknownTypecast, wrnMsgUnknownTypecast}, + {errUnknownTypecast, errMsgUnknownTypecast}, {wrnUnsupportedOperator, wrnMsgUnsupportedOperator}, + {errUnsupportedOperator, errMsgUnsupportedOperator}, {errInvalidParserTarget, errMsgInvalidParserTarget}, {errInvalidParserTargetType, errMsgInvalidParserTargetType}, {errTLSIsNotAllowed, errMsgTLSIsNotAllowed}, @@ -110,7 +113,8 @@ namespace elena_lang {infoExptectedType, infoMssgExptectedType }, {errCBrExpectedSyntax, errMssgCBrExpectedSyntax}, {wrnAssigningNillable, wrnMssgAssigningNillable}, - {wrnReturningNillable, wrnMssgReturningNillable} + {wrnReturningNillable, wrnMssgReturningNillable}, + {errFailedMemoryAllocation, errMssgFailedMemoryAllocation}, }; } diff --git a/elenasrc3/elc/parser.cpp b/elenasrc3/elc/parser.cpp index ce0c289201..66de15f592 100644 --- a/elenasrc3/elc/parser.cpp +++ b/elenasrc3/elc/parser.cpp @@ -117,7 +117,17 @@ bool Parser :: derive(TerminalInfo& terminalInfo, ParserStack& stack, SyntaxWrit writer->newNode(current); } else { - writer->injectNode(current & ~pkInjectable); + if (current == pkTransformMark) { + current = stack.pop(); + if (current == pkTransformMark) { + current = stack.pop(); + // ^^ operation - L nodes must be merged + writer->mergeLChildren(current & ~pkInjectable); + } + // = operation - the last node must be enclosed + else writer->encloseLastChild(current & ~pkInjectable); + } + else writer->injectNode(current & ~pkInjectable); current = stack.pop(); continue; } diff --git a/elenasrc3/elc/project.cpp b/elenasrc3/elc/project.cpp index 152234f419..3a5221d3ee 100644 --- a/elenasrc3/elc/project.cpp +++ b/elenasrc3/elc/project.cpp @@ -327,6 +327,7 @@ void Project :: loadConfig(ConfigFile& config, path_t configPath, ConfigFile::No loadPathSetting(config, root, TARGET_PATH, ProjectOption::TargetPath, configPath); loadBoolSetting(config, root, AUTOEXTENSION_PATH, ProjectOption::ModuleExtensionAutoLoad); + loadBoolSetting(config, root, STRICT_TYPE_ENFORCING_PATH, ProjectOption::StrictTypeEnforcing); loadParserTargets(config, root, PARSER_TARGET_CATEGORY); @@ -369,28 +370,37 @@ void Project :: loadDefaultConfig() bool Project :: loadConfig(path_t path, ustr_t profileName, bool mainConfig) { - PathString configPath; - configPath.copySubPath(path, false); + try + { + PathString configPath; + configPath.copySubPath(path, false); - ConfigFile config; - if (config.load(path, _encoding)) { - if (mainConfig) { - _projectPath.copy(*configPath); + ConfigFile config; + if (config.load(path, _encoding)) { + if (mainConfig) { + _projectPath.copy(*configPath); - _loaded = true; + _loaded = true; - loadProfileList(config); - } + loadProfileList(config); + } - loadConfig(config, *configPath, profileName); + loadConfig(config, *configPath, profileName); - return true; + return true; + } + else { + _presenter->printPath(_presenter->getMessage(wrnInvalidConfig), path); + + return false; + } } - else { + catch (XMLException&) + { _presenter->printPath(_presenter->getMessage(wrnInvalidConfig), path); - - return false; } + + return false; } bool Project :: loadProject(path_t path, ustr_t profileName) diff --git a/elenasrc3/elc/windows/elc.cpp b/elenasrc3/elc/windows/elc.cpp index b4c7144a5f..f49d7be7cd 100644 --- a/elenasrc3/elc/windows/elc.cpp +++ b/elenasrc3/elc/windows/elc.cpp @@ -216,6 +216,9 @@ void handleOption(wchar_t* arg, IdentifierString& profile, Project& project, Com else if (arg[2] == 'p') { project.addBoolSetting(ProjectOption::GenerateParamNameInfo, arg[3] != '-'); } + else if (arg[2] == 's') { + project.addBoolSetting(ProjectOption::StrictTypeEnforcing, arg[3] != '-'); + } break; default: break; diff --git a/elenasrc3/elena-tests/bt_optimization.h b/elenasrc3/elena-tests/bt_optimization.h index 3e3174f955..53a9085118 100644 --- a/elenasrc3/elena-tests/bt_optimization.h +++ b/elenasrc3/elena-tests/bt_optimization.h @@ -12,27 +12,17 @@ namespace elena_lang { - class BTOptimization : public testing::Test + class BTOptimization : public ExprTest { protected: MemoryDump btRules; - - SyntaxTree syntaxTree; - BuildTree buildTree; - - SyntaxNode declarationNode; - SyntaxNode exprNode; - - BuildNode beforeOptimization; + BuildNode afterOptimization; - CompilerEnvironment env; - void SetUp() override; public: void runBTTest(); - void runBuildTest(bool declareOperators); }; class StructTest : public testing::Test diff --git a/elenasrc3/elena-tests/compile_tests.h b/elenasrc3/elena-tests/compile_tests.h index b68d42f64a..346fee7742 100644 --- a/elenasrc3/elena-tests/compile_tests.h +++ b/elenasrc3/elena-tests/compile_tests.h @@ -31,6 +31,12 @@ namespace elena_lang protected: void SetUp() override; }; + + class CallingIndexedMethodFromSealed : public ExprTest + { + protected: + void SetUp() override; + }; } #endif diff --git a/elenasrc3/elena-tests/scenario_consts.h b/elenasrc3/elena-tests/scenario_consts.h index 60fe19a067..5814023d70 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_IntRefeference = "class ( attribute -2147471359 () nameattr (identifier \"IntReference\" ()) field (attribute -2147475454 () type (identifier \"IntNumber\" ()) nameattr (identifier \"_value\" ())) )"; // main program body constexpr auto S_NillableIntAssigning = "class (attribute -2147467263 ()nameattr (identifier \"program\" ())attribute -2147479546 ()method (attribute -2147479540 ()code (expression (assign_operation (object (nullable (type (identifier \"IntNumber\" ()))identifier \"n\" ())expression (object (identifier \"nil\" ()))))expression (assign_operation (object (nullable (type (identifier \"IntNumber\" ()))identifier \"m\" ())expression (object (integer \"2\" ())))))))"; @@ -13,4 +14,4 @@ constexpr auto S_IntAssigningNil = "class (attribute -2147467263 ()nameattr (ide 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 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\" ())))"; diff --git a/elenasrc3/elena-tests/tests_bt_optimization.cpp b/elenasrc3/elena-tests/tests_bt_optimization.cpp index 48c16f8ba6..0583c2d9c2 100644 --- a/elenasrc3/elena-tests/tests_bt_optimization.cpp +++ b/elenasrc3/elena-tests/tests_bt_optimization.cpp @@ -117,6 +117,8 @@ constexpr auto ComplexStructSize = 24; #endif +// --- BTOptimization --- + void BTOptimization :: SetUp() { PathString appPath; @@ -128,56 +130,11 @@ void BTOptimization :: SetUp() btRules.load(btRuleReader, btRuleReader.length()); } - SyntaxTreeWriter writer(syntaxTree); - writer.appendNode(SyntaxKey::Root); + ExprTest::SetUp(); - BuildTreeWriter buildWriter(buildTree); - buildWriter.appendNode(BuildKey::Root); - - declarationNode = syntaxTree.readRoot().appendChild(SyntaxKey::Idle, 1); - exprNode = syntaxTree.readRoot().appendChild(SyntaxKey::Idle, 2); - - beforeOptimization = buildTree.readRoot().appendChild(BuildKey::Tape); afterOptimization = buildTree.readRoot().appendChild(BuildKey::Tape); } -void BTOptimization :: runBuildTest(bool declareOperators) -{ - // Arrange - ModuleScopeBase* moduleScope = env.createModuleScope(true); - moduleScope->buildins.superReference = 1; - moduleScope->buildins.intReference = 2; - moduleScope->buildins.wrapperTemplateReference = 3; - - Compiler* compiler = env.createCompiler(); - - BuildTree output; - BuildTreeWriter writer(output); - Compiler::Namespace nsScope(compiler, moduleScope, nullptr, nullptr, nullptr); - - Compiler::Class cls(nsScope, 0, Visibility::Internal); - Compiler::Method method(cls); - Compiler::Code code(method); - - // Act - nsScope.declare(declarationNode.firstChild(), true); - - if (declareOperators) - env.initializeOperators(moduleScope); - - writer.newNode(BuildKey::Tape); - Compiler::Expression expression(code, writer); - expression.compileRoot(exprNode.firstChild(), ExpressionAttribute::NoDebugInfo); - writer.closeNode(); - - // Assess - bool matched = BuildTree::compare(beforeOptimization, output.readRoot(), true); - EXPECT_TRUE(matched); - - freeobj(compiler); - freeobj(moduleScope); -} - void BTOptimization :: runBTTest() { // Arrange @@ -187,7 +144,7 @@ void BTOptimization :: runBTTest() BuildTree output; BuildTreeWriter writer(output); - BuildTree::copyNode(writer, beforeOptimization, true); + BuildTree::copyNode(writer, buildNode, true); // Act buildTreeOptimizer.proceed(output.readRoot()); @@ -267,7 +224,7 @@ void BTOptimization1_1 :: SetUp() SyntaxTreeSerializer::load(Declaration1_1, declarationNode); SyntaxTreeSerializer::load(SyntaxTree1_1, exprNode); - BuildTreeSerializer::load(BuildTree1_1, beforeOptimization); + BuildTreeSerializer::load(BuildTree1_1, buildNode); BuildTreeSerializer::load(OptimizedBuildTree1_1, afterOptimization); } @@ -280,7 +237,7 @@ void BTOptimization1_2 :: SetUp() SyntaxTreeSerializer::load(Declaration1_2, declarationNode); SyntaxTreeSerializer::load(SyntaxTree1_2, exprNode); - BuildTreeSerializer::load(BuildTree1_2, beforeOptimization); + BuildTreeSerializer::load(BuildTree1_2, buildNode); BuildTreeSerializer::load(OptimizedBuildTree1_2, afterOptimization); } @@ -293,7 +250,7 @@ void BTOptimization1_3 :: SetUp() SyntaxTreeSerializer::load(Declaration1_2, declarationNode); SyntaxTreeSerializer::load(SyntaxTree1_3, exprNode); - BuildTreeSerializer::load(BuildTree1_2, beforeOptimization); + BuildTreeSerializer::load(BuildTree1_2, buildNode); BuildTreeSerializer::load(OptimizedBuildTree1_2, afterOptimization); } @@ -306,7 +263,7 @@ void BTOptimization2 :: SetUp() SyntaxTreeSerializer::load(Declaration2, declarationNode); SyntaxTreeSerializer::load(SyntaxTree2, exprNode); - BuildTreeSerializer::load(BuildTree2, beforeOptimization); + BuildTreeSerializer::load(BuildTree2, buildNode); BuildTreeSerializer::load(OptimizedBuildTree2, afterOptimization); } @@ -319,7 +276,7 @@ void BTOptimization4 :: SetUp() SyntaxTreeSerializer::load(Declaration2, declarationNode); SyntaxTreeSerializer::load(SyntaxTree4, exprNode); - BuildTreeSerializer::load(BuildTree4, beforeOptimization); + BuildTreeSerializer::load(BuildTree4, buildNode); BuildTreeSerializer::load(OptimizedBuildTree4, afterOptimization); } diff --git a/elenasrc3/elena-tests/tests_build.cpp b/elenasrc3/elena-tests/tests_build.cpp index af48ea109d..7e2649825d 100644 --- a/elenasrc3/elena-tests/tests_build.cpp +++ b/elenasrc3/elena-tests/tests_build.cpp @@ -8,27 +8,27 @@ using namespace elena_lang; TEST_F(BTOptimization1_1, BuildTest) { - runBuildTest(false); + runBuildTest(); } TEST_F(BTOptimization1_2, BuildTest) { - runBuildTest(false); + runBuildTest(); } TEST_F(BTOptimization1_3, BuildTest) { - runBuildTest(true); + runBuildTest(false, true); } TEST_F(BTOptimization2, BuildTest) { - runBuildTest(false); + runBuildTest(); } TEST_F(BTOptimization4, BuildTest) { - runBuildTest(false); + runBuildTest(); } TEST_F(StructAlignment, BuildTest) diff --git a/elenasrc3/elena-tests/tests_common.cpp b/elenasrc3/elena-tests/tests_common.cpp index d924d1234a..404a29e5ca 100644 --- a/elenasrc3/elena-tests/tests_common.cpp +++ b/elenasrc3/elena-tests/tests_common.cpp @@ -488,3 +488,65 @@ SyntaxNode MethodScenarioTest :: findAutoGenerated(SyntaxNode classNode) return {}; } + +// --- ExprTest --- + +void ExprTest::SetUp() +{ + SyntaxTreeWriter writer(syntaxTree); + writer.appendNode(SyntaxKey::Root); + + BuildTreeWriter buildWriter(buildTree); + buildWriter.appendNode(BuildKey::Root); + + declarationNode = syntaxTree.readRoot().appendChild(SyntaxKey::Idle, 1); + exprNode = syntaxTree.readRoot().appendChild(SyntaxKey::Idle, 2); + + buildNode = buildTree.readRoot().appendChild(BuildKey::Tape); +} + + +void ExprTest :: runBuildTest(bool declareDefaultMessages, bool declareOperators) +{ + // Arrange + ModuleScopeBase* moduleScope = env.createModuleScope(true, declareDefaultMessages); + moduleScope->buildins.superReference = 1; + moduleScope->buildins.intReference = 2; + moduleScope->buildins.wrapperTemplateReference = 3; + + if (declareDefaultMessages) { + moduleScope->buildins.dispatch_message = encodeMessage( + moduleScope->module->mapAction(DISPATCH_MESSAGE, 0, false), 1, 0); + moduleScope->buildins.constructor_message = + encodeMessage(moduleScope->module->mapAction(CONSTRUCTOR_MESSAGE, 0, false), + 0, FUNCTION_MESSAGE); + } + + Compiler* compiler = env.createCompiler(); + + BuildTree output; + BuildTreeWriter writer(output); + Compiler::Namespace nsScope(compiler, moduleScope, nullptr, nullptr, nullptr); + + Compiler::Class cls(nsScope, 0, Visibility::Internal); + Compiler::Method method(cls); + Compiler::Code code(method); + + // Act + nsScope.declare(declarationNode.firstChild(), true); + + if (declareOperators) + env.initializeOperators(moduleScope); + + writer.newNode(BuildKey::Tape); + Compiler::Expression expression(code, writer); + expression.compileRoot(exprNode.firstChild(), ExpressionAttribute::NoDebugInfo); + writer.closeNode(); + + // Assess + bool matched = BuildTree::compare(buildNode, output.readRoot(), true); + EXPECT_TRUE(matched); + + freeobj(compiler); + freeobj(moduleScope); +} diff --git a/elenasrc3/elena-tests/tests_common.h b/elenasrc3/elena-tests/tests_common.h index cfeef7ebcb..7eb64f18fe 100644 --- a/elenasrc3/elena-tests/tests_common.h +++ b/elenasrc3/elena-tests/tests_common.h @@ -241,6 +241,23 @@ namespace elena_lang void SetUp() override; }; + // --- ExprTest --- + class ExprTest : public BaseFixture + { + protected: + BuildTree buildTree; + + SyntaxNode exprNode; + + BuildNode buildNode; + + protected: + void SetUp() override; + + public: + void runBuildTest(bool declareDefaultMessages = false, bool declareOperators = false); + }; + // --- MethodScenarioTest --- class MethodScenarioTest : public ScenarioTest { diff --git a/elenasrc3/elena-tests/tests_compile.cpp b/elenasrc3/elena-tests/tests_compile.cpp index 3858e7c39b..6ad4ed444b 100644 --- a/elenasrc3/elena-tests/tests_compile.cpp +++ b/elenasrc3/elena-tests/tests_compile.cpp @@ -12,6 +12,18 @@ using namespace elena_lang; constexpr auto PrivateField_Scenario1 = "class (nameattr (identifier \"A\" ())field (attribute -2147467262 ()nameattr (identifier \"_x\" ()))method (nameattr (identifier \"setX\" ())code (expression (assign_operation (object (identifier \"_x\" ())expression (object (integer \"2\" ())))))))class (nameattr 62 (identifier \"B\" ())parent (type (identifier \"A\" ()))method (nameattr (identifier \"setParentX\" ())code (expression (assign_operation (object (identifier \"_x\" ())expression (object (integer \"2\" ())))))))"; +constexpr auto CallingIndexedethodFromSealed_Scenario1 = "expression (assign_operation (object (type (identifier \"IntNumber\" ())identifier \"ret\" ())expression (message_operation (object (identifier \"Y\" ())message (identifier \"calc\" ())expression (object (integer \"3\" ())))))"; + +#ifdef _M_IX86 + +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 ())"; + +#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 ())"; + +#endif + // --- CompileScenarioTest --- void CompileScenarioTest :: SetUp() @@ -86,3 +98,33 @@ TEST_F(AccessPrivateField, AccessParentPrivateFieldTest) { runTest(4, 106); } + + +// --- 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(); + + LoadDeclarationScenario(S_DefaultNamespace_2, S_IntNumber, S_IntRefeference, IndexedClass_Scenario1); + SyntaxTreeSerializer::load(CallingIndexedethodFromSealed_Scenario1, exprNode); + + BuildTreeSerializer::load(Build_CallingIndexedethodFromSealed_Scenario1, buildNode); +} + +TEST_F(CallingIndexedMethodFromSealed, CallingIndexedMethodTest) +{ + runBuildTest(true, false); +} diff --git a/elenasrc3/elenart/elenartmachine.cpp b/elenasrc3/elenart/elenartmachine.cpp index 5b9b53fda6..38cf57bb11 100644 --- a/elenasrc3/elenart/elenartmachine.cpp +++ b/elenasrc3/elenart/elenartmachine.cpp @@ -320,7 +320,7 @@ void ELENARTMachine :: startSTA(SystemEnv* env, void* entry) __routineProvider.InitSTA(env); // executing the program - execute(env, entry); + execute(entry); // winding down system Exit(0); @@ -361,7 +361,7 @@ void ELENARTMachine :: startThread(SystemEnv* env, void* entry, int index) { void* arg = env->th_table->slots[index].arg; // executing the program - execute(env, entry, arg); + execute(entry, arg); } bool ELENARTMachine :: checkClassMessage(void* classPtr, mssg_t message) diff --git a/elenasrc3/elenart/rtcommon.h b/elenasrc3/elenart/rtcommon.h index 9aea36d0eb..871eea561e 100644 --- a/elenasrc3/elenart/rtcommon.h +++ b/elenasrc3/elenart/rtcommon.h @@ -14,7 +14,7 @@ namespace elena_lang { -#define ELENART_REVISION_NUMBER 0x0008 +#define ELENART_REVISION_NUMBER 0x0009 } diff --git a/elenasrc3/elenavm/elenavmmachine.cpp b/elenasrc3/elenavm/elenavmmachine.cpp index 872049f026..97b8920903 100644 --- a/elenasrc3/elenavm/elenavmmachine.cpp +++ b/elenasrc3/elenavm/elenavmmachine.cpp @@ -279,7 +279,7 @@ inline ref_t getCmdMask(int command) } } -bool ELENAVMMachine :: compileVMTape(MemoryReader& reader, MemoryDump& tapeSymbol, ModuleBase* dummyModule) +bool ELENAVMMachine :: compileVMTape(MemoryReader& reader, MemoryDump& tapeSymbol, ModuleBase* dummyModule, bool withSystemStartUp) { CachedList, 5> symbols; @@ -337,10 +337,14 @@ bool ELENAVMMachine :: compileVMTape(MemoryReader& reader, MemoryDump& tapeSymbo pos_t sizePlaceholder = writer.position(); writer.writePos(0); + if (withSystemStartUp) + ByteCodeUtil::write(writer, ByteCode::System, 4); + ByteCodeUtil::write(writer, ByteCode::ExtOpenIN, 2, 0); fillPreloadedSymbols(writer, dummyModule); + bool needtoFlush = true; for(size_t i = 0; i < symbols.count(); i++) { auto p = symbols[i]; ref_t mask = p.value1 & mskAnyRef; @@ -369,21 +373,27 @@ bool ELENAVMMachine :: compileVMTape(MemoryReader& reader, MemoryDump& tapeSymbo else { switch (p.value2) { case VM_ALLOC_CMD: - ByteCodeUtil::write(writer, ByteCode::XFlushSI, 0); - ByteCodeUtil::write(writer, ByteCode::XFlushSI, 1); + if (needtoFlush) { + ByteCodeUtil::write(writer, ByteCode::XFlushSI, 0); + ByteCodeUtil::write(writer, ByteCode::XFlushSI, 1); + needtoFlush = false; + } ByteCodeUtil::write(writer, ByteCode::AllocI, p.value1); break; case VM_FREE_CMD: ByteCodeUtil::write(writer, ByteCode::FreeI, p.value1); ByteCodeUtil::write(writer, ByteCode::XRefreshSI, 0); ByteCodeUtil::write(writer, ByteCode::XRefreshSI, 1); + needtoFlush = true; break; case VM_SET_ARG_CMD: ByteCodeUtil::write(writer, ByteCode::StoreSI, p.value1); + needtoFlush = true; break; case VM_SEND_MESSAGE_CMD: ByteCodeUtil::write(writer, ByteCode::MovM, p.value1); ByteCodeUtil::write(writer, ByteCode::CallVI); + needtoFlush = true; break; default: break; @@ -392,7 +402,7 @@ bool ELENAVMMachine :: compileVMTape(MemoryReader& reader, MemoryDump& tapeSymbo } ByteCodeUtil::write(writer, ByteCode::ExtCloseN); - ByteCodeUtil::write(writer, ByteCode::Quit); + ByteCodeUtil::write(writer, ByteCode::XQuit); pos_t size = writer.position() - sizePlaceholder - sizeof(pos_t); @@ -425,7 +435,7 @@ void ELENAVMMachine :: resumeVM(SystemEnv* env, void* criricalHandler) } addr_t ELENAVMMachine :: interprete(SystemEnv* env, void* tape, pos_t size, - const char* criricalHandlerReference, bool withConfiguration) + const char* criricalHandlerReference, bool withConfiguration, bool withSystemStartUp) { ByteArray tapeArray(tape, size); MemoryReader reader(&tapeArray); @@ -449,7 +459,7 @@ addr_t ELENAVMMachine :: interprete(SystemEnv* env, void* tape, pos_t size, void* address = nullptr; if (_initialized) { - if (compileVMTape(reader, tapeSymbol, dummyModule)) + if (compileVMTape(reader, tapeSymbol, dummyModule, withSystemStartUp)) address = (void*)_jitLinker->resolveTemporalByteCode(tapeSymbol, dummyModule); resumeVM(env, (void*)criricalHandler); @@ -458,7 +468,7 @@ addr_t ELENAVMMachine :: interprete(SystemEnv* env, void* tape, pos_t size, freeobj(dummyModule); if (address) - return execute(env, address); + return execute(address); return 0; } @@ -466,7 +476,7 @@ addr_t ELENAVMMachine :: interprete(SystemEnv* env, void* tape, pos_t size, void ELENAVMMachine :: startSTA(SystemEnv* env, void* tape, const char* criricalHandlerReference) { if (tape != nullptr) { - interprete(env, tape, INVALID_POS, criricalHandlerReference, true); + interprete(env, tape, INVALID_POS, criricalHandlerReference, true, false); } else { // initialize VM in terminal mode @@ -480,7 +490,7 @@ void ELENAVMMachine :: startSTA(SystemEnv* env, void* tape, const char* crirical addr_t ELENAVMMachine :: evaluate(void* tape) { - return interprete(_env, tape, INVALID_POS, nullptr, false); + return interprete(_env, tape, INVALID_POS, nullptr, false, true); } bool ELENAVMMachine :: evaluateAndReturn(void* tape, char* output, size_t maxLength, size_t& copied) @@ -571,7 +581,7 @@ addr_t ELENAVMMachine :: loadReference(ustr_t name, int command) addVMTapeEntry(tapeWriter, command, name); addVMTapeEntry(tapeWriter, VM_ENDOFTAPE_CMD); - interprete(_env, tape.get(0), tape.length(), nullptr, true); + interprete(_env, tape.get(0), tape.length(), nullptr, true, false); return emptystr(name) ? 0 : _mapper.resolveReference({ nullptr, name }, getCmdMask(command)); diff --git a/elenasrc3/elenavm/elenavmmachine.h b/elenasrc3/elenavm/elenavmmachine.h index e4a6e94130..f4d4e7a065 100644 --- a/elenasrc3/elenavm/elenavmmachine.h +++ b/elenasrc3/elenavm/elenavmmachine.h @@ -71,14 +71,14 @@ namespace elena_lang void addPackage(ustr_t packageLine); addr_t interprete(SystemEnv* env, void* tape, pos_t size, - const char* criricalHandlerReference, bool withConfiguration); + const char* criricalHandlerReference, bool withConfiguration, bool withSystemStartUp); void onNewCode(); virtual void stopVM(); bool configurateVM(MemoryReader& reader, SystemEnv* env); - bool compileVMTape(MemoryReader& reader, MemoryDump& tapeSymbol, ModuleBase* dummyModule); + bool compileVMTape(MemoryReader& reader, MemoryDump& tapeSymbol, ModuleBase* dummyModule, bool withSystemStartUp); virtual void resumeVM(SystemEnv* env, void* criricalHandler); diff --git a/elenasrc3/elenavm/vmcommon.h b/elenasrc3/elenavm/vmcommon.h index e0a0dad40d..ea3229419f 100644 --- a/elenasrc3/elenavm/vmcommon.h +++ b/elenasrc3/elenavm/vmcommon.h @@ -9,7 +9,7 @@ #ifndef VMCOMMON_H #define VMCOMMON_H -#define ELENAVM_REVISION_NUMBER 0x0006 +#define ELENAVM_REVISION_NUMBER 0x0008 namespace elena_lang { diff --git a/elenasrc3/elenavm/windows/dllmain.cpp b/elenasrc3/elenavm/windows/dllmain.cpp index 06bf125764..f594ed561b 100644 --- a/elenasrc3/elenavm/windows/dllmain.cpp +++ b/elenasrc3/elenavm/windows/dllmain.cpp @@ -112,6 +112,9 @@ void printError(int errCode) case errVMNotInitialized: printf("ELENAVM: not initialized"); break; + case errFailedMemoryAllocation: + printf("ELENAVM: cannot reserve the memory"); + break; default: printf("ELENAVM: Unknown error %d\n", errCode); break; diff --git a/elenasrc3/engine/bcwriter.cpp b/elenasrc3/engine/bcwriter.cpp index 33ec72dffa..ab3424d6ff 100644 --- a/elenasrc3/engine/bcwriter.cpp +++ b/elenasrc3/engine/bcwriter.cpp @@ -1806,7 +1806,7 @@ void breakOp(CommandTape& tape, BuildNode& node, TapeScope& tapeScope) eolLabel = loopOp.value2; } - + if (eolLabel > 0) { tape.write(ByteCode::Jump, eolLabel); } @@ -1895,7 +1895,7 @@ void unboxingAndCallMessage(CommandTape& tape, BuildNode& node, TapeScope&) // add n:index // dalloc // set sp:index - // + // // alloc i:2 // store sp:1 @@ -1903,7 +1903,7 @@ void unboxingAndCallMessage(CommandTape& tape, BuildNode& node, TapeScope&) // labStart: // load dp:tmp // xcmp dp:length - // jeq labEnd + // jeq labEnd // set fp:arg // xget @@ -2602,8 +2602,8 @@ inline bool inplaceCallOp(BuildNode lastNode) BuildNode callNode = getPrevious(markNode); BuildNode classNode = getPrevious(callNode); - if (classNode == BuildKey::ClassReference && getArgCount(callNode.arg.reference) == 0 - && getArgCount(markNode.arg.reference) == 1) + if (classNode == BuildKey::ClassReference && getArgCount(callNode.arg.reference) == 0 + && getArgCount(markNode.arg.reference) == 1) { int targetOffset = lastNode.arg.value; @@ -2848,7 +2848,7 @@ void ByteCodeWriter :: importTree(CommandTape& tape, BuildNode node, Scope& scop tape.import(importInfo.module, importInfo.section, true, scope.moduleScope->module); } -void ByteCodeWriter :: saveBranching(CommandTape& tape, BuildNode node, TapeScope& tapeScope, +void ByteCodeWriter :: saveBranching(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode, bool loopMode) { bool ifElseMode = node.arg.value == IF_ELSE_OPERATOR_ID; @@ -2908,7 +2908,7 @@ void ByteCodeWriter :: saveTernaryOp(CommandTape& tape, BuildNode node, TapeScop saveTape(tape, rnodeNode, tapeScope, paths, tapeOptMode); tape.write(ByteCode::SwapSI, 1); - + tape.write(ByteCode::CmpR, node.findChild(BuildKey::Const).arg.reference | mskVMTRef); tape.write(ByteCode::PeekSI, 1); @@ -3005,7 +3005,7 @@ void ByteCodeWriter :: saveNativeBranching(CommandTape& tape, BuildNode node, Ta void ByteCodeWriter :: saveShortCircuitOp(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode) { - int endLabel = tape.newLabel(); + tape.newLabel(); ref_t trueRef = node.findChild(BuildKey::TrueConst).arg.reference; ref_t falseRef = node.findChild(BuildKey::FalseConst).arg.reference; @@ -3040,9 +3040,10 @@ void ByteCodeWriter :: saveShortCircuitOp(CommandTape& tape, BuildNode node, Tap tape.setLabel(); } -void ByteCodeWriter :: saveLoop(CommandTape& tape, BuildNode node, TapeScope& tapeScope, +void ByteCodeWriter :: saveLoop(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode) { + //tape.write(ByteCode::XNop); int startLabel = tape.newLabel(); tape.setLabel(true); int eopLabel = tape.newLabel(); @@ -3063,11 +3064,11 @@ void ByteCodeWriter :: saveLoop(CommandTape& tape, BuildNode node, TapeScope& ta tape.releaseLabel(); } -void ByteCodeWriter :: saveCatching(CommandTape& tape, BuildNode node, TapeScope& tapeScope, +void ByteCodeWriter :: saveCatching(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode) { int retLabel = tape.newLabel(); // declare ret-end-label - tape.newLabel(); // declare end-label + tape.newLabel(); // declare end-label tape.newLabel(); // declare alternative-label tape.write(ByteCode::XHookDPR, node.arg.value, PseudoArg::CurrentLabel, mskLabelRef); @@ -3101,7 +3102,7 @@ void ByteCodeWriter :: saveCatching(CommandTape& tape, BuildNode node, TapeScope tape.write(ByteCode::StoreFI, index.arg.value); saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); tape.write(ByteCode::PeekFI, index.arg.value); - } + } tape.write(ByteCode::Jump, PseudoArg::FirstLabel); // =========================== @@ -3113,7 +3114,7 @@ void ByteCodeWriter :: saveCatching(CommandTape& tape, BuildNode node, TapeScope // jeq labSkip // load // peeksi 0 - // callvi 0 + // callvi 0 // labSkip: // unhook tape.newLabel(); @@ -3143,7 +3144,7 @@ void ByteCodeWriter :: saveFinally(CommandTape& tape, BuildNode node, TapeScope& ReferenceMap& paths, bool tapeOptMode) { int retLabel = tape.newLabel(); // declare ret-end-label - tape.newLabel(); // declare end-label + tape.newLabel(); // declare end-label tape.newLabel(); // declare alternative-label tape.write(ByteCode::XHookDPR, node.arg.value, PseudoArg::CurrentLabel, mskLabelRef); @@ -3163,7 +3164,7 @@ void ByteCodeWriter :: saveFinally(CommandTape& tape, BuildNode node, TapeScope& tape.write(ByteCode::StoreFI, index.arg.value); saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); tape.write(ByteCode::PeekFI, index.arg.value); - } + } // jump tape.write(ByteCode::Jump, PseudoArg::PreviousLabel); @@ -3183,7 +3184,7 @@ void ByteCodeWriter :: saveFinally(CommandTape& tape, BuildNode node, TapeScope& tape.write(ByteCode::StoreFI, index.arg.value); saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); tape.write(ByteCode::PeekFI, index.arg.value); - } + } tape.write(ByteCode::Jump, PseudoArg::FirstLabel); // =========================== @@ -3195,7 +3196,7 @@ void ByteCodeWriter :: saveFinally(CommandTape& tape, BuildNode node, TapeScope& // jeq labSkip // load // peeksi 0 - // callvi 0 + // callvi 0 // labSkip: // unhook @@ -3207,7 +3208,7 @@ void ByteCodeWriter :: saveFinally(CommandTape& tape, BuildNode node, TapeScope& tape.write(ByteCode::CallVI); tape.setLabel(); tape.write(ByteCode::Unhook); - + // finally-block if (finallyNode != BuildKey::None) { // store fp:index @@ -3217,9 +3218,9 @@ void ByteCodeWriter :: saveFinally(CommandTape& tape, BuildNode node, TapeScope& tape.write(ByteCode::StoreFI, index.arg.value); saveTape(tape, finallyNode, tapeScope, paths, tapeOptMode, false); tape.write(ByteCode::PeekFI, index.arg.value); - } + } - // throw + // throw tape.write(ByteCode::Throw); // eos: @@ -3331,7 +3332,7 @@ void ByteCodeWriter :: saveYielding(CommandTape& tape, BuildNode node, TapeScope tape.setLabel(); } -void ByteCodeWriter :: saveYieldDispatch(CommandTape& tape, BuildNode node, TapeScope& tapeScope, +void ByteCodeWriter :: saveYieldDispatch(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode) { // get i:0 @@ -3349,7 +3350,7 @@ void ByteCodeWriter :: saveYieldDispatch(CommandTape& tape, BuildNode node, Tape tape.setLabel(); } -inline void saveDebugSymbol(DebugSymbol symbol, int offset, ustr_t name, TapeScope& tapeScope, +inline void saveDebugSymbol(DebugSymbol symbol, int offset, ustr_t name, TapeScope& tapeScope, ustr_t className = nullptr) { DebugLineInfo info = { symbol }; @@ -3381,7 +3382,7 @@ void ByteCodeWriter :: saveVariableInfo(CommandTape& tape, BuildNode node, TapeS saveDebugSymbol(DebugSymbol::Local, current.findChild(BuildKey::Index).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::Index).arg.value, current.identifier(), tapeScope, current.findChild(BuildKey::ClassName).identifier()); break; case BuildKey::IntVariableAddress: @@ -3493,7 +3494,7 @@ void ByteCodeWriter :: saveExternOp(CommandTape& tape, BuildNode node, TapeScope includeFrame(tape, tapeScope.threadFriendly); } -void ByteCodeWriter :: saveTape(CommandTape& tape, BuildNode node, TapeScope& tapeScope, +void ByteCodeWriter :: saveTape(CommandTape& tape, BuildNode node, TapeScope& tapeScope, ReferenceMap& paths, bool tapeOptMode, bool loopMode) { bool weakLoop = loopMode; @@ -3572,7 +3573,7 @@ void ByteCodeWriter :: saveTape(CommandTape& tape, BuildNode node, TapeScope& ta _commands[(int)current.key](tape, current, tapeScope); break; } - + current = current.nextNode(); } @@ -3582,7 +3583,7 @@ void ByteCodeWriter :: saveTape(CommandTape& tape, BuildNode node, TapeScope& ta } } -void ByteCodeWriter :: saveSymbol(BuildNode node, SectionScopeBase* moduleScope, int minimalArgList, +void ByteCodeWriter :: saveSymbol(BuildNode node, SectionScopeBase* moduleScope, int minimalArgList, int ptrSize, ReferenceMap& paths, bool tapeOptMode) { auto section = moduleScope->mapSection(node.arg.reference | mskSymbolRef, false); @@ -3685,7 +3686,7 @@ inline bool isNested(BuildKey key) } } -void ByteCodeWriter :: saveProcedure(BuildNode node, Scope& scope, bool classMode, pos_t sourcePathRef, +void ByteCodeWriter :: saveProcedure(BuildNode node, Scope& scope, bool classMode, pos_t sourcePathRef, ReferenceMap& paths, bool tapeOptMode) { _buildTreeOptimizer.proceed(node.findChild(BuildKey::Tape)); @@ -3786,7 +3787,7 @@ pos_t ByteCodeWriter :: savePath(BuildNode node, Scope& scope, ReferenceMap& pat return sourcePathRef; } -void ByteCodeWriter :: saveClass(BuildNode node, SectionScopeBase* moduleScope, int minimalArgList, +void ByteCodeWriter :: saveClass(BuildNode node, SectionScopeBase* moduleScope, int minimalArgList, int ptrSize, ReferenceMap& paths, bool tapeOptMode) { // initialize bytecode writer @@ -3873,7 +3874,7 @@ void ByteCodeWriter :: saveClass(BuildNode node, SectionScopeBase* moduleScope, } } -void ByteCodeWriter :: save(BuildTree& tree, SectionScopeBase* moduleScope, +void ByteCodeWriter :: save(BuildTree& tree, SectionScopeBase* moduleScope, int minimalArgList, int ptrSize, bool tapeOptMode) { ReferenceMap paths(INVALID_POS); @@ -3995,4 +3996,4 @@ bool ByteCodeWriter::BuildTreeOptimizer :: matchTriePatterns(BuildNode node) } return false; -} \ No newline at end of file +} diff --git a/elenasrc3/engine/buildtree.h b/elenasrc3/engine/buildtree.h index f86ee9f3c9..1ecc64829e 100644 --- a/elenasrc3/engine/buildtree.h +++ b/elenasrc3/engine/buildtree.h @@ -349,6 +349,7 @@ namespace elena_lang map.add("int_real_op", BuildKey::IntRealOp); map.add("real_int_op", BuildKey::RealIntOp); map.add("direct_call_op", BuildKey::DirectCallOp); + map.add("semi_direct_call_op", BuildKey::SemiDirectCallOp); map.add("addingint", BuildKey::AddingInt); map.add("saving_index", BuildKey::SavingIndex); map.add("open_frame", BuildKey::OpenFrame); @@ -391,6 +392,7 @@ namespace elena_lang map.add("message", BuildKey::Message); map.add("reserved", BuildKey::Reserved); map.add("reserved_n", BuildKey::ReservedN); + map.add("index_table_mode", BuildKey::IndexTableMode); } }; diff --git a/elenasrc3/engine/bytecode.cpp b/elenasrc3/engine/bytecode.cpp index c1e88b20d8..363c82bcfd 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", OPCODE_UNKNOWN, OPCODE_UNKNOWN, "xquit", OPCODE_UNKNOWN, OPCODE_UNKNOWN, OPCODE_UNKNOWN, + "xfsave", "altmode", "xnop", OPCODE_UNKNOWN, "xquit", 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, OPCODE_UNKNOWN, @@ -143,7 +143,7 @@ void ByteCodeUtil :: formatMessageName(IdentifierString& messageName, ModuleBase messageName.append(actionName); if (len > 0) { messageName.append('<'); - + for (size_t i = 0; i < len; i++) { if (i != 0) messageName.append(','); @@ -271,7 +271,7 @@ mssg_t ByteCodeUtil :: resolveMessageName(ustr_t messageName, ModuleBase* module inline ref_t importRArg(ref_t arg, ModuleBase* exporter, ModuleBase* importer) { - if (arg != -1) { + if (arg != INVALID_REF) { ref_t mask = arg & mskAnyRef; switch (mask) { case mskMssgLiteralRef: @@ -301,19 +301,19 @@ void ByteCodeUtil :: importCommand(ByteCommand& command, ModuleBase* exporter, M command.arg1 = ImportHelper::importMessage(exporter, command.arg1, importer); } - if (isR2Command(command.code)) { + if (isR2Command(command.code)) { command.arg2 = importRArg(command.arg2, exporter, importer); } } -void ByteCodeUtil :: generateAutoSymbol(ModuleInfoList& symbolList, ModuleBase* module, MemoryDump& tapeSymbol) +void ByteCodeUtil :: generateAutoSymbol(ModuleInfoList& symbolList, ModuleBase* module, MemoryDump& tapeSymbol, bool withExtFrame) { MemoryWriter writer(&tapeSymbol); pos_t sizePlaceholder = writer.position(); writer.writePos(0); - ByteCodeUtil::write(writer, ByteCode::OpenIN, 2, 0); + ByteCodeUtil::write(writer, withExtFrame ? ByteCode::ExtOpenIN : ByteCode::OpenIN, 2, 0); // generate the preloaded list for (auto it = symbolList.start(); !it.eof(); ++it) { @@ -327,7 +327,7 @@ void ByteCodeUtil :: generateAutoSymbol(ModuleInfoList& symbolList, ModuleBase* else ByteCodeUtil::write(writer, ByteCode::CallR, module->mapReference(symbolName) | mskSymbolRef); } - ByteCodeUtil::write(writer, ByteCode::CloseN); + ByteCodeUtil::write(writer, withExtFrame ? ByteCode::ExtCloseN : ByteCode::CloseN); ByteCodeUtil::write(writer, ByteCode::Quit); pos_t size = writer.position() - sizePlaceholder - sizeof(pos_t); @@ -459,8 +459,8 @@ inline bool optimizeProcJumps(ByteCodeIterator it) *blocks.getIt(index) = 1; } } - else if (command.code <= ByteCode::CallExtR && command.code >= ByteCode::Nop - && command.code != ByteCode::Breakpoint) + else if (command.code <= ByteCode::CallExtR && command.code >= ByteCode::Nop + && command.code != ByteCode::Breakpoint) { switch (command.code) { case ByteCode::Throw: @@ -538,7 +538,7 @@ inline bool optimizeProcJumps(ByteCodeIterator it) importMode = false; } - bool isCommand = !importMode && (command.code <= ByteCode::CallExtR && command.code >= ByteCode::Nop + bool isCommand = !importMode && (command.code <= ByteCode::CallExtR && command.code >= ByteCode::Nop && command.code != ByteCode::Breakpoint); if (index == blockEnd) { @@ -807,7 +807,7 @@ bool ByteCodePattern :: checkLabel(ByteCodeIterator it, int label, int offset) void ByteCodeTransformer :: transform(ByteCodeIterator trans_it, ByteCodeTrieNode replacement, PatternArg& arg) { - ByteCodeIterator target_it = trans_it; + //ByteCodeIterator target_it = trans_it; ByteCodePattern pattern = replacement.Value(); while (pattern.code != ByteCode::None) { @@ -893,7 +893,7 @@ bool ByteCodeTransformer :: apply(CommandTape& commandTape) for (auto it = matched->start(); !it.eof(); ++it) { PatternArg arg = (*it).arg; auto patternNode = (*it).node; - auto pattern = patternNode.Value(); + //auto pattern = patternNode.Value(); for (auto child_it = patternNode.Children(); !child_it.eof(); ++child_it) { auto currentPatternNode = child_it.Node(); diff --git a/elenasrc3/engine/bytecode.h b/elenasrc3/engine/bytecode.h index 218c2c7330..44c57a04f1 100644 --- a/elenasrc3/engine/bytecode.h +++ b/elenasrc3/engine/bytecode.h @@ -71,6 +71,7 @@ namespace elena_lang XFSave = 0x30, AltMode = 0x31, + XNop = 0x32, XQuit = 0x34, FIAdd = 0x70, @@ -484,7 +485,7 @@ namespace elena_lang static mssg_t resolveMessage(ustr_t messageName, ModuleBase* module, bool readOnlyMode); static mssg_t resolveMessageName(ustr_t messageName, ModuleBase* module, bool readOnlyMode); - static void generateAutoSymbol(ModuleInfoList& symbolList, ModuleBase* module, MemoryDump& tapeSymbol); + static void generateAutoSymbol(ModuleInfoList& symbolList, ModuleBase* module, MemoryDump& tapeSymbol, bool withExtFrame); }; enum class ByteCodePatternType diff --git a/elenasrc3/engine/codescope.h b/elenasrc3/engine/codescope.h index 2591b6603d..fab1a760d2 100644 --- a/elenasrc3/engine/codescope.h +++ b/elenasrc3/engine/codescope.h @@ -68,8 +68,8 @@ namespace elena_lang } ReferenceMapper(ExternalMapper* externalMapper = nullptr) : - _symbolReferences(INVALID_ADDR), - _exportReferences(INVALID_ADDR), + _symbolReferences(INVALID_ADDR), + _exportReferences(INVALID_ADDR), _constReferences(INVALID_ADDR), _numberReferences(INVALID_ADDR), _literalReferences(INVALID_ADDR), @@ -87,7 +87,7 @@ namespace elena_lang _lazyReferences({}), _externalMapper(externalMapper) { - + } }; @@ -120,7 +120,7 @@ namespace elena_lang MemoryBase* getTargetDebugSection() override; ImageProvider() : - _text(), _mdata(), _adata(), _mbdata(), _rdata(), + _text(), _adata(), _mdata(), _mbdata(), _rdata(), _import(), _data(), _stat(), _tls(), _debug() { } diff --git a/elenasrc3/engine/core.h b/elenasrc3/engine/core.h index 63c18dd862..a655c34645 100644 --- a/elenasrc3/engine/core.h +++ b/elenasrc3/engine/core.h @@ -43,7 +43,6 @@ namespace elena_lang constexpr int elVMTFlagOffset64 = 0x18; // --- ELENA CORE built-in routines - constexpr ref_t INVOKER = 0x10001; constexpr ref_t GC_ALLOC = 0x10002; constexpr ref_t EXCEPTION_HANDLER = 0x10003; constexpr ref_t GC_COLLECT = 0x10004; @@ -194,7 +193,7 @@ namespace elena_lang GCTable* gc_table; ThreadContent* th_single_content; // NOTE : used only for STA ThreadTable* th_table; // NOTE : used only for MTA - void* bc_invoker; + void* reserved; void* veh_handler; pos_t gc_mg_size; pos_t gc_yg_size; @@ -209,7 +208,9 @@ namespace elena_lang { union { void* address; - int (*evaluate)(void*, void*); + int (*evaluate2)(void*, void*); + int (*evaluate1)(void*); + int (*evaluate0)(); }; Entry() diff --git a/elenasrc3/engine/elena.h b/elenasrc3/engine/elena.h index c275705e56..8446e4ffc1 100644 --- a/elenasrc3/engine/elena.h +++ b/elenasrc3/engine/elena.h @@ -549,6 +549,7 @@ namespace elena_lang virtual int getExtMessageSize() = 0; virtual void alignCode(MemoryWriter& writer, pos_t alignment, bool isText) = 0; + //virtual void alignJumpAddress(MemoryWriter& writer) = 0; virtual void compileProcedure(ReferenceHelperBase* helper, MemoryReader& bcReader, MemoryWriter& codeWriter, LabelHelperBase* lh) = 0; @@ -567,7 +568,7 @@ namespace elena_lang virtual pos_t findMethodOffset(void* entries, mssg_t message) = 0; virtual pos_t findHiddenMethodOffset(void* entries, mssg_t message) = 0; - virtual void allocateVMT(MemoryWriter& vmtWriter, pos_t flags, pos_t vmtLength, + virtual void allocateVMT(MemoryWriter& vmtWriter, pos_t flags, pos_t vmtLength, pos_t indexTableLength, pos_t staticLength, bool withOutputList) = 0; virtual void addVMTEntry(mssg_t message, addr_t codeAddress, void* targetVMT, pos_t& entryCount) = 0; virtual void addIndexEntry(mssg_t message, addr_t codeAddress, void* targetVMT, pos_t indexOffset, pos_t& indexCount) = 0; @@ -1124,6 +1125,8 @@ namespace elena_lang pos_t indexCount; ref_t flags; ref_t parentRef; + + ClassHeader() = default; }; // --- MethodEntry --- @@ -1132,6 +1135,17 @@ namespace elena_lang mssg_t message; pos_t codeOffset; ref_t outputRef; + + MethodEntry() = default; + + MethodEntry(mssg_t message, pos_t codeOffset) + : message(message), codeOffset(codeOffset), outputRef(0) + { + } + MethodEntry(mssg_t message, pos_t codeOffset, ref_t outputRef) + : message(message), codeOffset(codeOffset), outputRef(outputRef) + { + } }; // --- DebugLineInfo --- @@ -1182,30 +1196,6 @@ namespace elena_lang }; #pragma pack(pop) - // --- ExceptionBase --- - class ExceptionBase {}; - - class AbortError : ExceptionBase {}; - - // --- InternalError --- - struct InternalError : ExceptionBase - { - int messageCode; - int arg; - - InternalError(int messageCode) - { - this->messageCode = messageCode; - this->arg = 0; - } - - InternalError(int messageCode, int arg) - { - this->messageCode = messageCode; - this->arg = arg; - } - }; - // --- InternalStrError --- struct InternalStrError : ExceptionBase { diff --git a/elenasrc3/engine/elenamachine.cpp b/elenasrc3/engine/elenamachine.cpp index 4ec2fa36b1..c778444ea8 100644 --- a/elenasrc3/engine/elenamachine.cpp +++ b/elenasrc3/engine/elenamachine.cpp @@ -378,17 +378,17 @@ bool SystemRoutineProvider :: CheckMessage(MemoryBase* msection, void* classPtr, // --- ELENAMachine --- -addr_t ELENAMachine :: execute(SystemEnv* env, void* entryAddress) +addr_t ELENAMachine :: execute(void* entryAddress) { Entry entry; - entry.address = env->bc_invoker; + entry.address = entryAddress; // executing the program addr_t retVal = 0; try { - retVal = entry.evaluate(entryAddress, nullptr); + retVal = entry.evaluate0(); } catch (InternalError&) { @@ -400,12 +400,14 @@ addr_t ELENAMachine :: execute(SystemEnv* env, void* entryAddress) return retVal; } -addr_t ELENAMachine :: execute(SystemEnv* env, void* threadEntry, void* threadFunc) +addr_t ELENAMachine :: execute(void* entryAddress, void* arg) { Entry entry; - entry.address = env->bc_invoker; + entry.address = entryAddress; - addr_t retVal = entry.evaluate(threadEntry, threadFunc); + // executing the program + + addr_t retVal = entry.evaluate1(arg); return retVal; } diff --git a/elenasrc3/engine/elenamachine.h b/elenasrc3/engine/elenamachine.h index 4fcc2827fe..7d5b88996d 100644 --- a/elenasrc3/engine/elenamachine.h +++ b/elenasrc3/engine/elenamachine.h @@ -88,8 +88,8 @@ namespace elena_lang public: addr_t injectType(SystemEnv* env, void* proxy, void* srcVMTPtr, int staticLen, int nameIndex/*, addr_t* addresses, size_t length*/); - addr_t execute(SystemEnv* env, void* symbolListEntry); - addr_t execute(SystemEnv* env, void* threadEntry, void* threadFunc); + addr_t execute(void* symbolListEntry); + addr_t execute(void* symbolListEntry, void* arg); ELENAMachine() : _generatedClasses(0) diff --git a/elenasrc3/engine/jitcompiler.cpp b/elenasrc3/engine/jitcompiler.cpp index 854e45816a..fad9d5203e 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, loadNop, loadNop, loadOp, loadNop, loadNop, loadNop, + loadOp, compileAltMode, loadXNop, loadNop, loadOp, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, loadNop, @@ -83,10 +83,10 @@ constexpr ref_t coreConstants[coreConstantNumber] = }; // preloaded gc routines -constexpr int coreFunctionNumber = 7; +constexpr int coreFunctionNumber = 6; constexpr ref_t coreFunctions[coreFunctionNumber] = { - INVOKER, GC_ALLOC, EXCEPTION_HANDLER, GC_COLLECT, GC_ALLOCPERM, PREPARE, THREAD_WAIT + GC_ALLOC, EXCEPTION_HANDLER, GC_COLLECT, GC_ALLOCPERM, PREPARE, THREAD_WAIT }; // preloaded bc commands @@ -322,6 +322,13 @@ void elena_lang :: loadNop(JITCompilerScope* scope) else scope->lh->setLabel(position, *scope->codeWriter, scope->helper); } +void elena_lang :: loadXNop(JITCompilerScope* scope) +{ + //scope->compiler->alignJumpAddress(*scope->codeWriter); + + loadNop(scope); +} + void elena_lang :: loadLOp(JITCompilerScope* scope) { MemoryWriter* writer = scope->codeWriter; @@ -2604,7 +2611,7 @@ inline void loadPreloaded(JITCompilerScope& scope, LibraryLoaderBase* loader, si map.add(functions[i], (void*)(scope.helper->calculateVAddress(*scope.codeWriter, mask) & ~mskAnyRef)); } else map.add(functions[i], (void*)scope.helper->calculateVAddress(*scope.codeWriter, mask)); - + positions.add(functions[i], scope.codeWriter->position()); allocateCode(&scope, info.section->get(0)); @@ -3042,7 +3049,7 @@ void JITCompiler :: resolveLabelAddress(MemoryWriter* writer, ref_t mask, pos_t else { switch (mask) { case mskRef32: - MemoryBase::writeDWord(writer->Memory(), position, + MemoryBase::writeDWord(writer->Memory(), position, ptrToUInt32(writer->Memory()->get(writer->position()))); writer->Memory()->addReference(mskCodeRef32, position); break; @@ -3080,7 +3087,7 @@ addr_t JITCompiler :: allocateTLSIndex(ReferenceHelperBase* helper, MemoryWriter pos_t JITCompiler :: getTLSSize(MemoryBase* tlsSection) { - if (tlsSection->length() > sizeof(ThreadContent)) { + if (tlsSection && tlsSection->length() > sizeof(ThreadContent)) { return tlsSection->length() - sizeof(ThreadContent); } return 0; @@ -3375,7 +3382,7 @@ void JITCompiler32 :: addIndexEntry(mssg_t message, addr_t codeAddress, void* ta while (entries[index].message) { if (entries[index].message == message) { if (codeAddress == INVALID_ADDR) { - entries[index].address = findEntryAddress(entries, message, indexOffset); + entries[index].address = static_cast(findEntryAddress(entries, message, indexOffset)); } else entries[index].address = (pos_t)codeAddress; @@ -3387,14 +3394,14 @@ void JITCompiler32 :: addIndexEntry(mssg_t message, addr_t codeAddress, void* ta entries[index].message = message; if (codeAddress == INVALID_ADDR) { - entries[index].address = findEntryAddress(entries, message, indexOffset); + entries[index].address = static_cast(findEntryAddress(entries, message, indexOffset)); } else entries[index].address = (pos_t)codeAddress; indexCount++; } -void JITCompiler32 :: updateVMTHeader(MemoryWriter& vmtWriter, VMTFixInfo& fixInfo, +void JITCompiler32 :: updateVMTHeader(MemoryWriter& vmtWriter, VMTFixInfo& fixInfo, FieldAddressMap& staticValues, bool virtualMode) { pos_t position = vmtWriter.position(); @@ -3450,7 +3457,7 @@ void JITCompiler32 :: updateVMTHeader(MemoryWriter& vmtWriter, VMTFixInfo& fixIn } else vmtWriter.writeDWord((pos_t)*it); } - + vmtWriter.seek(position); if (fixInfo.outputListAddress) { @@ -3458,7 +3465,7 @@ void JITCompiler32 :: updateVMTHeader(MemoryWriter& vmtWriter, VMTFixInfo& fixIn vmtWriter.writeDReference(addrToUInt32(fixInfo.outputListAddress) | mskRef32, 0); } else vmtWriter.writeDWord(addrToUInt32(fixInfo.outputListAddress)); - } + } } pos_t JITCompiler32 :: addActionEntry(MemoryWriter& messageWriter, MemoryWriter& messageBodyWriter, ustr_t actionName, @@ -4195,7 +4202,7 @@ void JITCompiler64 :: updateEnvironment(MemoryBase* rdata, pos_t staticCounter, void* env = _preloaded.get(SYSTEM_ENV); if (virtualMode) { MemoryBase::writeQWord(rdata, (int64_t)env & ~mskAnyRef, staticCounter); - MemoryBase::writeQWord(rdata, (int64_t)env & ~mskAnyRef + 8, tlsSize); + MemoryBase::writeQWord(rdata, ((int64_t)env & ~mskAnyRef) + 8, tlsSize); } else { ((int64_t*)env)[0] = staticCounter; diff --git a/elenasrc3/engine/jitcompiler.h b/elenasrc3/engine/jitcompiler.h index bca32e16a6..21b34efb09 100644 --- a/elenasrc3/engine/jitcompiler.h +++ b/elenasrc3/engine/jitcompiler.h @@ -255,7 +255,7 @@ namespace elena_lang protected: int calcFrameOffset(int argument, bool extMode) override { - return (extMode ? 20 : 4) + (argument > 0 ? align(argument + 8, 4) : 0); + return (extMode ? 36 : 4) + (argument > 0 ? align(argument + 8, 4) : 0); } int calcTotalSize(int numberOfFields) override; @@ -424,6 +424,7 @@ namespace elena_lang inline void* retrieveIRCode(JITCompilerScope* scope, int arg1, int arg2); void loadNop(JITCompilerScope*); + void loadXNop(JITCompilerScope*); void loadOp(JITCompilerScope* scope); void loadSysOp(JITCompilerScope* scope); void loadLOp(JITCompilerScope* scope); diff --git a/elenasrc3/engine/langcommon.h b/elenasrc3/engine/langcommon.h index 506c94f84f..dd1eb3f5bf 100644 --- a/elenasrc3/engine/langcommon.h +++ b/elenasrc3/engine/langcommon.h @@ -12,8 +12,9 @@ namespace elena_lang { // default settings - constexpr bool DEFAULT_CONDITIONAL_BOXING = true; - constexpr bool DEFAULT_EVALUATE_OP = true; + constexpr bool DEFAULT_CONDITIONAL_BOXING = true; + constexpr bool DEFAULT_EVALUATE_OP = true; + constexpr bool DEFAULT_STRICT_TYPE_ENFORCING = false; enum MetaHint : int { @@ -109,7 +110,7 @@ namespace elena_lang { ref_t mask = info.hints & (ref_t)MethodHint::VisibilityMask; - return mask == (ref_t)hint1 || mask == (ref_t)hint2; + return mask == (ref_t)hint1 || mask == (ref_t)hint2; } static bool checkType(MethodInfo& info, MethodHint type) { @@ -209,7 +210,7 @@ namespace elena_lang pos_t inheritLevel; ClassHeader header; - pos_t size; // Object size + int size; // Object size MethodMap methods; FieldMap fields; StaticFieldMap statics; @@ -371,6 +372,9 @@ namespace elena_lang constexpr auto errUnknownDefConstructor = 184; constexpr auto errUnknownMessage = 185; constexpr auto errAssigningToSelf = 186; + constexpr auto errUnknownTypecast = 188; + constexpr auto errUnknownFunction = 189; + constexpr auto errUnsupportedOperator = 189; constexpr auto errUnknownModule = 201; constexpr auto errUnresovableLink = 202; @@ -703,7 +707,7 @@ namespace elena_lang constexpr auto FALSE_FORWARD = "$false"; // the false boolean value constexpr auto WRAPPER_FORWARD = "$ref"; // the wrapper template constexpr auto ARRAY_FORWARD = "$array"; // the array template - constexpr auto VARIADIC_ARRAY_FORWARD = "$varray"; // the array template + constexpr auto VARIADIC_ARRAY_FORWARD = "$varray"; // the array template constexpr auto MESSAGE_FORWARD = "$message"; // the message class constexpr auto MESSAGE_NAME_FORWARD = "$subject"; // the message class constexpr auto EXT_MESSAGE_FORWARD = "$ext_message"; // the extension message class @@ -734,46 +738,47 @@ namespace elena_lang 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"; - - constexpr auto COLLECTION_CATEGORY = "configuration/collection/*"; - - constexpr auto TEMPLATE_CATEGORY = "templates/*"; - constexpr auto PRIMITIVE_CATEGORY = "primitives/*"; - constexpr auto FORWARD_CATEGORY = "forwards/*"; - constexpr auto EXTERNAL_CATEGORY = "externals/*"; - constexpr auto WINAPI_CATEGORY = "winapi/*"; - constexpr auto REFERENCE_CATEGORY = "references/*"; - constexpr auto MODULE_CATEGORY = "files/*"; - constexpr auto FILE_CATEGORY = "include/*"; - constexpr auto PARSER_TARGET_CATEGORY = "targets/*"; - constexpr auto PROFILE_CATEGORY = "/profile"; - - constexpr auto LIB_PATH = "project/libpath"; - constexpr auto OUTPUT_PATH = "project/output"; - constexpr auto TARGET_PATH = "project/executable"; - constexpr auto PROJECT_TEMPLATE = "project/template"; - constexpr auto NAMESPACE_KEY = "project/namespace"; - constexpr auto DEBUGMODE_PATH = "project/debuginfo"; - constexpr auto FILE_PROLOG = "project/prolog"; - constexpr auto FILE_EPILOG = "project/epilog"; - constexpr auto MODULE_PROLOG = "project/moduleProlog"; - constexpr auto AUTOEXTENSION_PATH = "project/autoextension"; - - constexpr auto PLATFORMTYPE_KEY = "system/platform"; - - constexpr auto MGSIZE_PATH = "linker/mgsize"; - constexpr auto YGSIZE_PATH = "linker/ygsize"; - constexpr auto THREAD_COUNTER = "linker/threadcounter"; - - constexpr auto MANIFEST_NAME = "manifest/name"; - constexpr auto MANIFEST_VERSION = "manifest/version"; - constexpr auto MANIFEST_AUTHOR = "manifest/author"; - - constexpr auto RETVAL_ARG = "$retVal"; - constexpr auto PARENT_VAR = "$parent"; - constexpr auto OWNER_VAR = "$owner"; + constexpr auto CONFIG_ROOT = "configuration"; + constexpr auto PLATFORM_CATEGORY = "configuration/platform"; + + constexpr auto COLLECTION_CATEGORY = "configuration/collection/*"; + + constexpr auto TEMPLATE_CATEGORY = "templates/*"; + constexpr auto PRIMITIVE_CATEGORY = "primitives/*"; + constexpr auto FORWARD_CATEGORY = "forwards/*"; + constexpr auto EXTERNAL_CATEGORY = "externals/*"; + constexpr auto WINAPI_CATEGORY = "winapi/*"; + constexpr auto REFERENCE_CATEGORY = "references/*"; + constexpr auto MODULE_CATEGORY = "files/*"; + constexpr auto FILE_CATEGORY = "include/*"; + constexpr auto PARSER_TARGET_CATEGORY = "targets/*"; + constexpr auto PROFILE_CATEGORY = "/profile"; + + constexpr auto LIB_PATH = "project/libpath"; + constexpr auto OUTPUT_PATH = "project/output"; + constexpr auto TARGET_PATH = "project/executable"; + constexpr auto PROJECT_TEMPLATE = "project/template"; + constexpr auto NAMESPACE_KEY = "project/namespace"; + constexpr auto DEBUGMODE_PATH = "project/debuginfo"; + constexpr auto FILE_PROLOG = "project/prolog"; + constexpr auto FILE_EPILOG = "project/epilog"; + constexpr auto MODULE_PROLOG = "project/moduleProlog"; + constexpr auto AUTOEXTENSION_PATH = "project/autoextension"; + constexpr auto STRICT_TYPE_ENFORCING_PATH = "project/stricttype"; + + constexpr auto PLATFORMTYPE_KEY = "system/platform"; + + constexpr auto MGSIZE_PATH = "linker/mgsize"; + constexpr auto YGSIZE_PATH = "linker/ygsize"; + constexpr auto THREAD_COUNTER = "linker/threadcounter"; + + constexpr auto MANIFEST_NAME = "manifest/name"; + constexpr auto MANIFEST_VERSION = "manifest/version"; + constexpr auto MANIFEST_AUTHOR = "manifest/author"; + + constexpr auto RETVAL_ARG = "$retVal"; + constexpr auto PARENT_VAR = "$parent"; + constexpr auto OWNER_VAR = "$owner"; inline ustr_t getPlatformName(PlatformType type) { diff --git a/elenasrc3/engine/parsertable.h b/elenasrc3/engine/parsertable.h index fc4af7320b..2a6cea567a 100644 --- a/elenasrc3/engine/parsertable.h +++ b/elenasrc3/engine/parsertable.h @@ -21,6 +21,7 @@ namespace elena_lang constexpr parse_key_t pkTerminal = 0x02000; constexpr parse_key_t pkError = 0x04000; constexpr parse_key_t pkInjectable = 0x08000; + constexpr parse_key_t pkTransformMark = 0x09000; constexpr parse_key_t pkAnySymbolMask = 0x0F000; constexpr parse_key_t pkMaxKey = 0x0FFFF; diff --git a/elenasrc3/engine/projectbase.h b/elenasrc3/engine/projectbase.h index a582ca99b4..674c3a6bd8 100644 --- a/elenasrc3/engine/projectbase.h +++ b/elenasrc3/engine/projectbase.h @@ -70,6 +70,7 @@ namespace elena_lang MappingOutputMode, OptimizationMode, GenerateParamNameInfo, + StrictTypeEnforcing, ConditionalBoxing, EvaluateOp, diff --git a/elenasrc3/engine/syntaxtree.h b/elenasrc3/engine/syntaxtree.h index f777df3f79..02e46a69fd 100644 --- a/elenasrc3/engine/syntaxtree.h +++ b/elenasrc3/engine/syntaxtree.h @@ -273,7 +273,11 @@ namespace elena_lang static void copyNewNode(SyntaxTreeWriter& writer, SyntaxNode node) { if (node.arg.strArgPosition != INVALID_POS) { - writer.newNode(node.key, node.identifier()); + if (writer.getOwner()->isTreeNode(node)) { + IdentifierString tmp(node.identifier()); + writer.newNode(node.key, *tmp); + } + else writer.newNode(node.key, node.identifier()); } else writer.newNode(node.key, node.arg.reference); } diff --git a/elenasrc3/engine/x86helper.h b/elenasrc3/engine/x86helper.h index 9431eb7c9d..6c1e168e05 100644 --- a/elenasrc3/engine/x86helper.h +++ b/elenasrc3/engine/x86helper.h @@ -82,6 +82,9 @@ namespace elena_lang M32disp8 = 0x00110100, M32disp32 = 0x00110200, + EaxEaxDisp32 = 0x00110204, + EaxEaxDisp8 = 0x00110104, + R64 = 0x00008300, M64 = 0x00018000, M64disp8 = 0x00018100, @@ -302,23 +305,26 @@ namespace elena_lang static void writeModRM(MemoryWriter& writer, X86Operand sour, X86Operand dest) { - int prefix = ((unsigned int)dest.type & 0x300) >> 2; - // HOTFIX : to allow GS M64Disp32 - if (prefix == 0x80 && dest.prefix == SegmentPrefix::GS) { - writer.writeByte(0x14); - prefix = 0x10; + unsigned int destType = (unsigned int)dest.type; + + if (test(dest.type, X86OperandType::M64disp32) && dest.prefix == SegmentPrefix::GS) { + // HOTFIX : for direct m64 disp mode - use SIB mode + destType = 0x25000004; } - int opcode = prefix + ((char)sour.type << 3) + (char)dest.type; + int prefix = (destType & 0x300) >> 2; + int opcode = prefix + ((char)sour.type << 3) + (char)destType; writer.writeByte((unsigned char)opcode); - if ((char)dest.type == (char)X86OperandType::SIB && dest.type != X86OperandType::ESP + + if ((char)destType == (char)X86OperandType::SIB && dest.type != X86OperandType::ESP && dest.type != X86OperandType::RSP && dest.type != X86OperandType::RX12 && dest.type != X86OperandType::AH) { - int sib = (char)((unsigned int)dest.type >> 24); + int sib = (char)(destType >> 24); if (sib == 0) sib = 0x24; writer.writeByte((unsigned char)sib); } + if (test(dest.type, X86OperandType::M32disp8) || test(dest.type, X86OperandType::M8disp8) || test(dest.type, X86OperandType::M64disp8) || test(dest.type, X86OperandType::MX64disp8)) { writer.writeByte((unsigned char)dest.offset); diff --git a/elenasrc3/ide/idecommon.h b/elenasrc3/ide/idecommon.h index d8463239d0..29440554d2 100644 --- a/elenasrc3/ide/idecommon.h +++ b/elenasrc3/ide/idecommon.h @@ -24,6 +24,7 @@ namespace elena_lang constexpr auto NAMESPACE_SUB_CATEGORY = "project/namespace"; constexpr auto OPTIONS_SUB_CATEGORY = "project/options"; constexpr auto OUTPUT_SUB_CATEGORY = "project/output"; + constexpr auto STRICT_TYPE_SETTING = "project/stricttype"; constexpr auto PROFILE_CATEGORY = "/profile"; diff --git a/elenasrc3/ide/idecontroller.cpp b/elenasrc3/ide/idecontroller.cpp index 4c2b0fe9ac..b29b9cb206 100644 --- a/elenasrc3/ide/idecontroller.cpp +++ b/elenasrc3/ide/idecontroller.cpp @@ -42,6 +42,45 @@ inline ustr_t getPlatformName(PlatformType type) } } +inline int loadSetting(ConfigFile& config, ustr_t xpath, int defValue) +{ + // read target type; merge it with platform if required + ConfigFile::Node targetType = config.selectNode(xpath); + if (!targetType.isNotFound()) { + DynamicString key; + targetType.readContent(key); + + return key.toInt(); + } + else return defValue; +} + +inline void loadSetting(ConfigFile& config, ustr_t xpath, IdentifierString& retVal) +{ + // read target type; merge it with platform if required + ConfigFile::Node targetType = config.selectNode(xpath); + if (!targetType.isNotFound()) { + DynamicString key; + targetType.readContent(key); + + retVal.copy(key.str()); + } + else retVal.clear(); +} + +inline void saveSetting(ConfigFile& config, ustr_t xpath, int value) +{ + String number; + number.appendInt(value); + + config.appendSetting(xpath, number.str()); +} + +inline void removeSetting(ConfigFile& config, ustr_t xpath) +{ + config.removeSetting(xpath); +} + // --- SourceViewController --- void SourceViewController :: newSource(TextViewModelBase* model, ustr_t caption, bool included, bool autoSelect, int& status) @@ -447,6 +486,13 @@ bool ProjectController :: compileSingleFile(ProjectModel& model, int postponedAc cmdLine.append(*model.templateName); } + if (model.strictType == -1) { + cmdLine.append(" -xs"); + } + else if (model.strictType == -1) { + cmdLine.append(" -xs-"); + } + PathString curDir; curDir.append(*model.projectPath); @@ -503,6 +549,8 @@ void ProjectController :: loadConfig(ProjectModel& model, ConfigFile& config, Co model.outputPath.copy(value.str()); } + model.strictType = loadSetting(config, STRICT_TYPE_SETTING, 1); + DynamicString subNs; DynamicString path; @@ -625,6 +673,11 @@ void ProjectController :: saveConfig(ProjectModel& model, ConfigFile& config, Co else config.appendSetting(TARGET_CATEGORY, *model.target); } + if (model.strictType == FLAG_UNDEFINED) { + removeSetting(config, STRICT_TYPE_SETTING); + } + else saveSetting(config, STRICT_TYPE_SETTING, model.strictType); + // remove source files for (auto it = model.removeSources.start(); !it.eof(); ++it) { IdentifierString pathStr(*it); @@ -929,32 +982,6 @@ void ProjectController :: excludeFile(ProjectModel& model, path_t filePath) // --- IDEController --- -inline int loadSetting(ConfigFile& config, ustr_t xpath, int defValue) -{ - // read target type; merge it with platform if required - ConfigFile::Node targetType = config.selectNode(xpath); - if (!targetType.isNotFound()) { - DynamicString key; - targetType.readContent(key); - - return key.toInt(); - } - else return defValue; -} - -inline void loadSetting(ConfigFile& config, ustr_t xpath, IdentifierString& retVal) -{ - // read target type; merge it with platform if required - ConfigFile::Node targetType = config.selectNode(xpath); - if (!targetType.isNotFound()) { - DynamicString key; - targetType.readContent(key); - - retVal.copy(key.str()); - } - else retVal.clear(); -} - inline void loadRecentFiles(ConfigFile& config, ustr_t xpath, ProjectPaths& paths) { DynamicString path; @@ -988,14 +1015,6 @@ inline void loadCollectionKey(ConfigFile& config, ConfigFile::Node& rootNode, us } } -inline void saveSetting(ConfigFile& config, ustr_t xpath, int value) -{ - String number; - number.appendInt(value); - - config.appendSetting(xpath, number.str()); -} - inline void saveRecentFiles(ConfigFile& config, ustr_t xpath, ProjectPaths& paths) { for (int index = paths.count(); index > 0; index--) { diff --git a/elenasrc3/ide/ideproject.cpp b/elenasrc3/ide/ideproject.cpp index 4becd2ca5f..356b2e86b0 100644 --- a/elenasrc3/ide/ideproject.cpp +++ b/elenasrc3/ide/ideproject.cpp @@ -25,6 +25,7 @@ ProjectModel :: ProjectModel(IDEStatus* status) this->empty = true; this->started = false; this->notSaved = false; + this->strictType = FLAG_UNDEFINED; // !!NOTE : make sure the path separator should tail the path if (this->paths.librarySourceRoot[this->paths.librarySourceRoot.length() - 1] != PATH_SEPARATOR) diff --git a/elenasrc3/ide/ideproject.h b/elenasrc3/ide/ideproject.h index aa167eaa69..727ec92072 100644 --- a/elenasrc3/ide/ideproject.h +++ b/elenasrc3/ide/ideproject.h @@ -28,6 +28,8 @@ namespace elena_lang constexpr auto RECENTFILE_SETTINGS = "configuration/recent_files/path"; constexpr auto RECENTPROJECTS_SETTINGS = "configuration/recent_projects/path"; + constexpr auto FLAG_UNDEFINED = 1; + // --- Map types --- typedef List ProjectPaths; typedef List Breakpoints; @@ -62,6 +64,7 @@ namespace elena_lang bool empty; bool started; bool notSaved; + int strictType; // 1 - default, 0 - off, -1 - on PathString name; PathString projectFile; PathString projectPath; diff --git a/elenasrc3/ide/windows/Resource.h b/elenasrc3/ide/windows/Resource.h index 573677db4b..4850a6ec91 100644 --- a/elenasrc3/ide/windows/Resource.h +++ b/elenasrc3/ide/windows/Resource.h @@ -118,6 +118,7 @@ #define IDC_SETTINGS_DEBUG 856 #define IDC_SETTINGS_ARGUMENT 857 #define IDC_SETTINGS_PROFILE 858 +#define IDC_SETTINGS_STRICTTYPE 859 #define IDM_DEBUG_RUN 901 #define IDM_DEBUG_STEPOVER 902 diff --git a/elenasrc3/ide/windows/elide.rc b/elenasrc3/ide/windows/elide.rc index 61df3ad9481c2e9fac860c8b19011df4951ca58e..f8648677a6426bd1fb8b54ac8b68207e049842c4 100644 GIT binary patch delta 152 zcmZ2=m1)X#rVW1Ky1@)33`Go?49P%R0f;LZ3K&v>tW<_PhBStJpjwvb=^2#tb?P=0K>!U@=)R qN_6tS5T(g};hUH(8H^_P2T4xeSEDicLXgnpum~}b*yj8Q>mUHjDkbLt delta 46 zcmbPoooUrorVW1KlPw}PF`F}(Pwo$roGcJ+HQ6Cj49q_tqdECph{onsk*@*)n%5Dx diff --git a/elenasrc3/ide/windows/windialogs.cpp b/elenasrc3/ide/windows/windialogs.cpp index c85878c86f..52585196c0 100644 --- a/elenasrc3/ide/windows/windialogs.cpp +++ b/elenasrc3/ide/windows/windialogs.cpp @@ -266,11 +266,21 @@ 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); @@ -346,6 +356,11 @@ void ProjectSettings :: onCreate() //} //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(); } @@ -395,7 +410,16 @@ void ProjectSettings :: onOK() getText(IDC_SETTINGS_ARGUMENT, (wchar_t**)(&name), IDENTIFIER_LEN); _model->debugArguments.copy(name); - _model->notSaved = true; + 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() diff --git a/elenasrc3/ide/windows/windialogs.h b/elenasrc3/ide/windows/windialogs.h index fbffa9a213..988f38dfd7 100644 --- a/elenasrc3/ide/windows/windialogs.h +++ b/elenasrc3/ide/windows/windialogs.h @@ -95,7 +95,9 @@ namespace elena_lang 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); diff --git a/elenasrc3/tools/asmc/asmconst.h b/elenasrc3/tools/asmc/asmconst.h index fcbf4ede55..8399671644 100644 --- a/elenasrc3/tools/asmc/asmconst.h +++ b/elenasrc3/tools/asmc/asmconst.h @@ -12,7 +12,7 @@ namespace elena_lang { - #define ASM_REVISION_NUMBER 0x0005 + #define ASM_REVISION_NUMBER 0x0007 constexpr auto N_ARGUMENT1 = "__n_1"; constexpr auto N_ARGUMENT2 = "__n_2"; diff --git a/elenasrc3/tools/asmc/x86assembler.cpp b/elenasrc3/tools/asmc/x86assembler.cpp index 9030ed2e91..4fbde60660 100644 --- a/elenasrc3/tools/asmc/x86assembler.cpp +++ b/elenasrc3/tools/asmc/x86assembler.cpp @@ -1181,9 +1181,28 @@ void X86Assembler :: compileNeg(ScriptToken& tokenInfo, MemoryWriter& writer) void X86Assembler :: compileNop(ScriptToken& tokenInfo, MemoryWriter& writer) { - writer.writeByte(0x90); - - read(tokenInfo); + X86Operand sour = compileOperand(tokenInfo, nullptr); + if (sour.type != X86OperandType::Unknown) { + if (sour.type == X86OperandType::M32disp8) { + writer.writeByte(0x0F); + writer.writeByte(0x1F); + writer.writeWord(0x40); + } + else if (sour.type == X86OperandType::EaxEaxDisp8) { + writer.writeByte(0x0F); + writer.writeByte(0x1F); + writer.writeWord(0x44); + writer.writeByte(0); + } + else if (sour.type == X86OperandType::EaxEaxDisp32) { + writer.writeByte(0x0F); + writer.writeByte(0x1F); + writer.writeWord(0x84); + writer.writeDWord(0); + } + else throw SyntaxError(ASM_INVALID_COMMAND, tokenInfo.lineInfo); + } + else writer.writeByte(0x90); } void X86Assembler :: compileNot(ScriptToken& tokenInfo, MemoryWriter& writer) @@ -2845,6 +2864,11 @@ bool X86Assembler::compileROpCode(ScriptToken& tokenInfo, MemoryWriter& writer) else if (tokenInfo.compare("rep")) { compileRep(tokenInfo, writer); } + else if (tokenInfo.compare("rgw")) { + writer.writeByte(0x66); + + read(tokenInfo); + } else if (tokenInfo.compare("ret")) { compileRet(tokenInfo, writer); } diff --git a/elenasrc3/tools/ecv/ecvconst.h b/elenasrc3/tools/ecv/ecvconst.h index fa5ea6bc83..424014dc77 100644 --- a/elenasrc3/tools/ecv/ecvconst.h +++ b/elenasrc3/tools/ecv/ecvconst.h @@ -11,7 +11,7 @@ namespace elena_lang { - #define ECV_REVISION_NUMBER 0x0005 + #define ECV_REVISION_NUMBER 0x0006 constexpr auto ECV_GREETING = "ELENA command line ByteCode Viewer %d.%d.%d (C)2021-24 by Aleksey Rakov\n"; diff --git a/elenasrc3/tools/ecv/ecviewer.cpp b/elenasrc3/tools/ecv/ecviewer.cpp index 10b82a21c5..90b22b3fa9 100644 --- a/elenasrc3/tools/ecv/ecviewer.cpp +++ b/elenasrc3/tools/ecv/ecviewer.cpp @@ -1025,6 +1025,12 @@ void ByteCodeViewer :: printClass(ustr_t name, bool fullInfo, ustr_t filterMask) prefix.append(": "); prefix.append(getMethodPrefix(test(entry.message, FUNCTION_MESSAGE))); + if (_showMethodInfo) { + line.append(" ("); + line.appendHex(entry.message); + line.append("h)"); + } + printLineAndCount(*prefix, *line, row, _pageSize); } diff --git a/elenasrc3/tools/elt/eltconst.h b/elenasrc3/tools/elt/eltconst.h index f58a57e5ed..65761593e9 100644 --- a/elenasrc3/tools/elt/eltconst.h +++ b/elenasrc3/tools/elt/eltconst.h @@ -11,7 +11,7 @@ namespace elena_lang { - #define ELT_REVISION_NUMBER 0x0003 + #define ELT_REVISION_NUMBER 0x0004 constexpr auto ELT_GREETING = "ELENA command line VM terminal %d.%d.%d (C)2021-24 by Aleksey Rakov\n"; diff --git a/elenasrc3/tools/sg/sg.cpp b/elenasrc3/tools/sg/sg.cpp index f9481b3ad4..668db5bcd9 100644 --- a/elenasrc3/tools/sg/sg.cpp +++ b/elenasrc3/tools/sg/sg.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-2022, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #include "sgconst.h" @@ -225,29 +225,41 @@ int main(int argc, char* argv[]) } else if (token.compare("^")) { reader.read(token); + if (token.compare("^")) { + // NOTE : ^^ means merge lchildren + rule[rule_len++] = pkTransformMark; + rule[rule_len++] = pkTransformMark; + reader.read(token); + } + rule[rule_len++] = registerSymbol(table, *token.token, lastKey + 1, false) | pkInjectable; + } + else if (token.compare("=")) { + reader.read(token); + rule[rule_len++] = pkTransformMark; rule[rule_len++] = registerSymbol(table, *token.token, lastKey + 1, false) | pkInjectable; } - //else if (token.compare("=")) { - // reader.read(token); - - // rule[rule_len++] = registerSymbol(table, *token.token, lastKey + 1, false) | pkRenaming; - //} - //else if (token.compare("$new") || token.compare("$close")) { - // rule[rule_len++] = registerSymbol(table, *token.token, lastKey + 1, false) | pkInjectable | pkTraceble; - //} else if (token.compare("+")) { - rule[rule_len - 1] = registerPlusRule(table, rule[rule_len - 1]); + if (rule_len > 0) { + rule[rule_len - 1] = registerPlusRule(table, rule[rule_len - 1]); + } + else throw SyntaxError(SG_INVALID_RULE, token.lineInfo); } else if (token.compare("*")) { - rule[rule_len - 1] = registerStarRule(table, rule[rule_len - 1]); + if (rule_len > 0) { + rule[rule_len - 1] = registerStarRule(table, rule[rule_len - 1]); + } + else throw SyntaxError(SG_INVALID_RULE, token.lineInfo); } else if (token.compare(";")) { table.registerRule(rule, rule_len); rule_len = 0; } else if (token.compare("?")) { - rule[rule_len - 1] = registerEpsRule(table, rule[rule_len - 1]); + if (rule_len > 0) { + rule[rule_len - 1] = registerEpsRule(table, rule[rule_len - 1]); + } + else throw SyntaxError(SG_INVALID_RULE, token.lineInfo); } else if (token.compare("|")) { if (bracketIndexes.count() > 0) { diff --git a/elenasrc3/tools/sg/sgconst.h b/elenasrc3/tools/sg/sgconst.h index b68e2889dc..9044ee45a5 100644 --- a/elenasrc3/tools/sg/sgconst.h +++ b/elenasrc3/tools/sg/sgconst.h @@ -12,7 +12,7 @@ namespace elena_lang { - #define SG_REVISION_NUMBER 0x0002 + #define SG_REVISION_NUMBER 0x0003 constexpr auto SG_GREETING = "ELENA command line syntax generator %d.%d.%d (C)2005-2024 by Aleksey Rakov\n"; diff --git a/examples60/console/datetime/control.l b/examples60/console/datetime/control.l index de56cf0696..5671898b6e 100644 --- a/examples60/console/datetime/control.l +++ b/examples60/console/datetime/control.l @@ -19,11 +19,11 @@ public singleton Control auto choice := s.toInt(); choice => - 1 { ^Now.toString() } - 2 { ^UtcNow.toString() } - 3 { ^Now.Year.toString() } - 4 { ^Now.toShortTimeString() } - 7 { forward program.stop(); ^ EmptyString } - ! { ^"Invalid choice" } + 1 : { ^Now.toString() } + 2 : { ^UtcNow.toString() } + 3 : { ^Now.Year.toString() } + 4 : { ^Now.toShortTimeString() } + 7 : { forward program.stop(); ^ EmptyString } + ! : { ^"Invalid choice" } } } \ No newline at end of file diff --git a/examples60/console/helloworld/helloworld.es b/examples60/console/helloworld/helloworld.es index a3c7c40811..d508b186be 100644 --- a/examples60/console/helloworld/helloworld.es +++ b/examples60/console/helloworld/helloworld.es @@ -1,5 +1,5 @@ [[ - #define start ::= "?" <= system'console.eval&writeLine( => $literal <= ) =>; + #define start ::= "?" <= system'Console.eval&writeLine( => $literal <= ) =>; ]] ? "Hello World!!" diff --git a/examples60/console/matrix/matrix.l b/examples60/console/matrix/matrix.l index a2207d6e64..a7101acd99 100644 --- a/examples60/console/matrix/matrix.l +++ b/examples60/console/matrix/matrix.l @@ -57,7 +57,7 @@ Your choice:"; proceed(choice) { choice => - "1" { + "1" : { Console.write("Enter the order of matrix: "); var N := Console.readLine().toInt(); @@ -73,7 +73,7 @@ Your choice:"; ^ sum.toString() } - "2" { + "2" : { Console.write("Enter the order of matrix: "); var N := Console.readLine().toInt(); @@ -89,7 +89,7 @@ Your choice:"; ^ diff.toString() } - "3" { + "3" : { Console.write("Enter the order of matrix: "); var N := Console.readLine().toInt(); @@ -105,7 +105,7 @@ Your choice:"; ^ product.toString() } - "4" { + "4" : { Console.write("Enter the order of matrix: "); var N := Console.readLine().toInt(); @@ -115,7 +115,7 @@ Your choice:"; ^ matrixA.Determinant } - "5" { + "5" : { Console.write("Enter the order of matrix: "); var N := Console.readLine().toInt(); @@ -123,7 +123,7 @@ Your choice:"; ^ identity.toString() } - "6" { + "6" : { forward program.stop() } } diff --git a/examples60/console/pi2/pi2.l b/examples60/console/pi2/pi2.l index 8c6577be9e..0398a9a437 100644 --- a/examples60/console/pi2/pi2.l +++ b/examples60/console/pi2/pi2.l @@ -383,12 +383,12 @@ public program() while (x[xc] != 0) { xc := xc + 2; - Console.write(charConvertor.convert(x[xc])); + Console.write(CharConvertor.convert(x[xc])); xc := xc -4; while (x[xc] != 0) { x[xc] := x[xc] + 1; - Console.write(charConvertor.convert(x[xc])); + Console.write(CharConvertor.convert(x[xc])); while (x[xc] != 0) { x[xc] := x[xc] - 1 @@ -401,7 +401,7 @@ public program() while (x[xc] != 0) { xc := xc + 2; - Console.write(charConvertor.convert(x[xc])); + Console.write(CharConvertor.convert(x[xc])); xc := xc -2; x[xc] := x[xc] - 1 }; @@ -443,7 +443,7 @@ public program() xc := xc -8 }; x[xc] := x[xc] + 10; - Console.write(charConvertor.convert(x[xc])); + Console.write(CharConvertor.convert(x[xc])); var end := Now; diff --git a/examples60/db/sqlite/main.l b/examples60/db/sqlite/main.l index 00b4d4b5aa..a064c5411e 100644 --- a/examples60/db/sqlite/main.l +++ b/examples60/db/sqlite/main.l @@ -11,28 +11,28 @@ extension dbTestOp { printTable(tableName) { - console.printLine(tableName,":"); + Console.printLine(tableName,":"); var table := self.executeQuery("SELECT * FROM " + tableName); // Header table.fields().forEach::(fieldName) { - console.printPaddingRight(25, fieldName) + Console.printPaddingRight(25, fieldName) }; - console.printLine(); - console.printPaddingRightChar(25 * table.fieldCount(), $45, "-"); - console.printLine(); + Console.printLine(); + Console.printPaddingRightChar(25 * table.fieldCount(), $45, "-"); + Console.printLine(); // Rows table.rows().forEach::(row) { table.fields().forEach::(fieldName) { - console.printPaddingRight(25, row[fieldName]) + Console.printPaddingRight(25, row[fieldName]) }; - console.printLine() + Console.printLine() }; - console.printLine(); + Console.printLine(); } } @@ -50,28 +50,28 @@ public program() using (cnn) { - console.write("Database is being created"); + Console.write("Database is being created"); cnn.executeNonQuery("CREATE Table Movies (Name TEXT, Director TEXT, Year INTEGER)"); - console.write("."); + Console.write("."); cnn.executeNonQuery("INSERT INTO Movies (Name, Director, Year) VALUES ('The Dark Knight', 'Christopher Nolan', 2008)"); cnn.executeNonQuery("INSERT INTO Movies (Name, Director, Year) VALUES ('Cloverfield', 'Matt Reeves', 2008)"); cnn.executeNonQuery("INSERT INTO Movies (Name, Director, Year) VALUES ('Beverly Hills Chihuahua', 'Raja Gosnell', 2008)"); - console.write("."); + Console.write("."); cnn.executeNonQuery("CREATE TABLE [Users] " + "([ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " + "[client] NVARCHAR(100) NULL, " + "[date] DATE NULL " + ")"); - console.write("."); + Console.write("."); cnn.executeNonQuery("INSERT INTO Users (client, date) VALUES ('Alexandre', '2015-01-01')"); cnn.executeNonQuery("INSERT INTO Users (client, date) VALUES ('Alex', '2015-01-01')"); - console.write("."); + Console.write("."); - console.writeLine("Done") + Console.writeLine("Done") } }; @@ -79,9 +79,9 @@ public program() using (cnn) { - console.printLine("Number of table in DB: ",cnn.numberOfTable()); + Console.printLine("Number of table in DB: ",cnn.numberOfTable()); - console.writeLine("Tables:").writeLine(); + Console.writeLine("Tables:").writeLine(); cnn.tables().forEach::(tableName) { @@ -89,5 +89,5 @@ public program() } }; - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/files/textdb/textdb.l b/examples60/files/textdb/textdb.l index 2c4d8546f6..d86b8066a8 100644 --- a/examples60/files/textdb/textdb.l +++ b/examples60/files/textdb/textdb.l @@ -84,7 +84,7 @@ class Record public program() { if (Program_arguments.Length == 1) - { console.write("Please provide the path to the file to view"); AbortException.raise() }; + { Console.write("Please provide the path to the file to view"); AbortException.raise() }; var db := new List().append(new Record()); @@ -111,5 +111,5 @@ public program() // print the list db.forEach(printingLn); - console.readChar() + Console.readChar() } \ No newline at end of file diff --git a/examples60/files/textfile/textfile.l b/examples60/files/textfile/textfile.l index 5d2ce958d2..550ddf5674 100644 --- a/examples60/files/textfile/textfile.l +++ b/examples60/files/textfile/textfile.l @@ -5,9 +5,9 @@ import extensions'routines; public program() { if (Program_arguments.Length == 1) - { console.writeLine("Please provide the path to the file to view"); AbortException.raise() }; + { Console.writeLine("Please provide the path to the file to view"); AbortException.raise() }; File.assign(Program_arguments[1]).forEachLine(printingLn); - console.readChar() // wait for any key + Console.readChar() // wait for any key } \ No newline at end of file diff --git a/examples60/gui/c_a_g/calc_area_gui.l b/examples60/gui/c_a_g/calc_area_gui.l index 7cf32fc167..5a6f57f146 100644 --- a/examples60/gui/c_a_g/calc_area_gui.l +++ b/examples60/gui/c_a_g/calc_area_gui.l @@ -244,22 +244,22 @@ public class MainWindow : SDIDialog Econta4.Visible := false; index => - 0 { + 0 : { Econta1.Visible := true; Econta1.SelectedIndex := 0 } - 1 { + 1 : { Econta2.Visible := true; Econta2.SelectedIndex := 0 } - 2 { + 2 : { Econta3.Visible := true; Econta3.SelectedIndex := 0 } - 3 { + 3 : { Econta4.Visible := true; Econta4.SelectedIndex := 0 @@ -283,7 +283,7 @@ public class MainWindow : SDIDialog info.Caption := "Info: "; index => - 0 { + 0 : { valUm.Visible := true; valDois.Visible := true; letter1.Visible := true; @@ -292,13 +292,13 @@ public class MainWindow : SDIDialog letter1.Caption := "h: "; letter2.Caption := "b: "; } - 1 { + 1 : { valUm.Visible := true; letter1.Visible := true; letter1.Caption := "b: " } - 2 { + 2 : { valUm.Visible := true; valDois.Visible := true; letter1.Visible := true; @@ -307,7 +307,7 @@ public class MainWindow : SDIDialog letter1.Caption := "h: "; letter2.Caption := "b: "; } - 3 { + 3 : { valUm.Visible := true; valDois.Visible := true; letter1.Visible := true; @@ -316,7 +316,7 @@ public class MainWindow : SDIDialog letter1.Caption := "D: "; letter2.Caption := "d: "; } - 4 { + 4 : { valUm.Visible := true; valDois.Visible := true; valTres.Visible := true; @@ -328,7 +328,7 @@ public class MainWindow : SDIDialog letter2.Caption := "b: "; letter3.Caption := "h: "; } - 5 { + 5 : { valUm .Visible := true; valDois.Visible := true; valTres.Visible := true; @@ -340,7 +340,7 @@ public class MainWindow : SDIDialog letter2.Caption := "b: "; letter3.Caption := "h: "; } - 6 { + 6 : { valUm .Visible := true; valDois.Visible := true; valTres.Visible := true; @@ -352,13 +352,13 @@ public class MainWindow : SDIDialog letter2.Caption := "b: "; letter3.Caption := "h: "; } - 7 { + 7 : { valUm .Visible := true; letter1.Visible := true; letter1.Caption := "r: "; } - 8 { + 8 : { valUm .Visible := true; valDois.Visible := true; letter1.Visible := true; @@ -367,7 +367,7 @@ public class MainWindow : SDIDialog letter1.Caption := "R: "; letter2.Caption := "r: "; } - 9 { + 9 : { valUm .Visible := true; valDois.Visible := true; letter1.Visible := true; @@ -378,7 +378,7 @@ public class MainWindow : SDIDialog info.Caption := "Info: Al = Alfa ( angulo )" } - 10 { + 10 : { valUm .Visible := true; valDois.Visible := true; letter1.Visible := true; @@ -387,7 +387,7 @@ public class MainWindow : SDIDialog letter1.Caption := "B: "; letter2.Caption := "H: "; } - 11 { + 11 : { valUm .Visible := true; valDois.Visible := true; letter1.Visible := true; @@ -396,13 +396,13 @@ public class MainWindow : SDIDialog letter1.Caption := "B: "; letter2.Caption := "C: "; } - 12 { + 12 : { valUm .Visible := true; letter1.Visible := true; letter1.Caption := "A: "; } - 13 { + 13 : { valUm .Visible := true; valDois.Visible := true; valTres.Visible := true; @@ -414,7 +414,7 @@ public class MainWindow : SDIDialog letter2.Caption := "b: "; letter3.Caption := "c: "; } - 14 { + 14 : { valUm .Visible := true; valDois.Visible := true; valTres.Visible := true; @@ -437,72 +437,72 @@ public class MainWindow : SDIDialog var result := 0; (_imageList.SelectedIndex) => - 0 { + 0 : { var H := valUm.Value.toReal(); var B := valDois.Value.toReal(); result := H * B } - 1 { + 1 : { var B := valUm.Value.toReal(); result := B * B } - 2 { + 2 : { var H := valUm.Value.toReal(); var B := valDois.Value.toReal(); result := H * B } - 3 { + 3 : { var DM := valUm.Value.toReal(); var d := valDois.Value.toReal(); result := DM * d / 2 } - 4 { + 4 : { var BM := valUm.Value.toReal(); var b := valDois.Value.toReal(); var H := valTres.Value.toReal(); result := (BM + b)*H / 2 } - 5 { + 5 : { var BM := valUm.Value.toReal(); var b := valDois.Value.toReal(); var H := valTres.Value.toReal(); result := (BM + b)*H / 2 } - 6 { + 6 : { var BM := valUm.Value.toReal(); var b := valDois.Value.toReal(); var H := valTres.Value.toReal(); result := (BM + b)*H / 2 } - 7 { + 7 : { var R := valUm.Value.toReal(); result := Pi_value * R * R } - 8 { + 8 : { var RM := valUm.Value.toReal(); var r := valDois.Value.toReal(); result := Pi_value * (RM * RM - r * r); } - 9 { + 9 : { var Alfa := valUm.Value.toReal(); var R := valDois.Value.toReal(); result := Alfa * Pi_value * R * R / 360 } - 10 { + 10 : { var B := valUm.Value.toReal(); var H := valDois.Value.toReal(); result := B * H / 2; } - 11 { + 11 : { var B := valUm.Value.toReal(); var C := valDois.Value.toReal(); result := B * C / 2; } - 12 { + 12 : { var A := valUm.Value.toReal(); result := ((Pi_value.sqrt()) * A * A / 4).Rounded; } - 13 { + 13 : { var A := valUm.Value.toReal(); var B := valDois.Value.toReal(); var C := valTres.Value.toReal(); @@ -512,7 +512,7 @@ public class MainWindow : SDIDialog var val3 := P-C; result := (P * (val1 * val2 * val3)).sqrt() } - 14 { + 14 : { var Alfa := valUm.Value.toReal(); var A := valDois.Value.toReal(); var B := valTres.Value.toReal(); diff --git a/examples60/threads/threadpool/threadpool.l b/examples60/threads/threadpool/threadpool.l index 2cefcc5b8b..fc3fabeb6f 100644 --- a/examples60/threads/threadpool/threadpool.l +++ b/examples60/threads/threadpool/threadpool.l @@ -5,6 +5,6 @@ public program() int solution := program_arguments.getAtOrDefault(1, "2").toInt(); solution => - 1 { sample1() } - 2 { sample2() } + 1 : { sample1() } + 2 : { sample2() } } \ No newline at end of file diff --git a/recompile60.bat b/recompile60.bat index b8a304ab1c..a728d125ff 100644 --- a/recompile60.bat +++ b/recompile60.bat @@ -28,7 +28,7 @@ bin\elena-tests-x86.exe IF NOT %ERRORLEVEL%==0 GOTO CompilerError REM /m:2 is used to build using parallel compilation -"%InstallDir%\MSBuild\Current\Bin\MSBuild.exe" elenasrc3\elenasrc3.sln /p:configuration=release /p:Platform="x64" /m:2 +"%InstallDir%\MSBuild\Current\Bin\MSBuild.exe" elenasrc3\elenasrc3.sln /p:configuration=release /p:Platform="x64" /m:2 -restore -p:RestorePackagesConfig=true IF NOT %ERRORLEVEL%==0 GOTO CompilerError ECHO Generating data files diff --git a/src60/core/system.core_routines.esm b/src60/core/system.core_routines.esm index 177bcfc3f1..8f663844d1 100644 --- a/src60/core/system.core_routines.esm +++ b/src60/core/system.core_routines.esm @@ -7,8 +7,8 @@ define ELENA_ERR_OUT_OF_MEMORY 103h; define ELENA_ERR_STACKOVERFLOW 105h; define FUNCTION_MESSAGE 00000020h; -define PROPERTY_MESSAGE 000000C0h; -define VARIADIC_MESSAGE 00000080h; +define PROPERTY_MESSAGE 00000080h; +define VARIADIC_MESSAGE 00000040h; define PROP_ARG_MASK 000000DFh; define ARG_MASK 0000001Fh; @@ -21,9 +21,9 @@ define page_size64 32; define ptr_size32 4; define ptr_size64 8; -define get_prop_mssg 0C1h; -define set_prop_mssg 0C2h; -define variadic_mssg 080h; +define get_prop_mssg 081h; +define set_prop_mssg 082h; +define variadic_mssg 040h; define __realSize 8; @@ -775,6 +775,16 @@ procedure __uintToInt end +procedure __ushortToInt + + peek sp:1 + load + and n:0FFFFh + peek sp:2 + save + +end + procedure __realTrunc (self, r1, r2) xflush sp:0 @@ -1143,23 +1153,42 @@ procedure __byteToShort end -procedure __readIntPtr +procedure __readIntPtr(ptr, retVal) - peek sp:1 + xflush sp:0 + xflush sp:1 + + open (2),[] + peek fp:ptr + get i:0 + xstore i:0 + $load sp:0 + peek fp:retVal + $save + + close [] + +end + +procedure __readIntPtrVal + + peek sp:0 get i:0 load - peek sp:2 + peek sp:1 save + peek sp:0 end -procedure __readRealPtr +procedure __readRealPtrVal - peek sp:1 + peek sp:0 get i:0 lload - peek sp:2 + peek sp:1 lsave + peek sp:0 end @@ -2768,24 +2797,22 @@ end procedure func_invoker(arg) - xflush sp:0 - xflush sp:1 - - open (2),[] + extopen (2),[] peek fp:arg + get i:0 mov mssg:"function:#invoke[0]" call vt:0 - close [] + extclose [] quit end procedure thread_start(index) - open [arg1],[ptr,envptr,ex_struct:ex_struct_size] + extopen [arg1],[ptr,envptr,ex_struct:ex_struct_size] xloadarg fp:index @@ -2831,7 +2858,7 @@ procedure thread_start(index) call extern:ExitThreadLA (0) - close [] + extclose [] quit end diff --git a/src60/extensions/convertors.l b/src60/extensions/convertors.l index 59620319e9..0f9bb9497f 100644 --- a/src60/extensions/convertors.l +++ b/src60/extensions/convertors.l @@ -3,10 +3,10 @@ import system'collections; import system'routines; import system'calendar; -singleton stringExConvertor +singleton StringExConvertor { string convert(IntMatrix a) - = intmatrixExConvertor.toString(a); + = IntmatrixExConvertor.toString(a); string convert(Indexer it) { @@ -53,7 +53,7 @@ singleton stringExConvertor <= convert(o.indexer()); string convert(o) - = stringConvertor.convert(o); + = StringConvertor.convert(o); } // --- arrayConvertorEx --- @@ -93,7 +93,7 @@ public singleton arrayConvertorEx // --- intmatrixExConvertor --- -public singleton intmatrixExConvertor +public singleton IntmatrixExConvertor { IntMatrix convert(Array a) { @@ -158,7 +158,7 @@ public singleton intmatrixExConvertor // --- enumerableConvertor --- -singleton enumerableConvertor +singleton EnumerableConvertor { Enumerable convert(Enumerable o) = o; @@ -167,7 +167,7 @@ singleton enumerableConvertor = new Enumerable { Enumerator enumerator() = o.enumerator(); }; } -public singleton byteArrayExConvertor +public singleton ByteArrayExConvertor { byte[] convert(string s) { @@ -208,10 +208,10 @@ public singleton byteArrayExConvertor public extension stringConvertOp { string toString() - = stringExConvertor.convert(self); + = StringExConvertor.convert(self); string toString(int radix) - = stringConvertor.convert(self, radix); + = StringConvertor.convert(self, radix); } // --- intConvertOp --- @@ -219,10 +219,10 @@ public extension stringConvertOp public extension intConvertOp { int toInt() - = intConvertor.convert(self); + = IntConvertor.convert(self); int toInt(int radix) - = intConvertor.convert(self, radix); + = IntConvertor.convert(self, radix); } // --- byteConvertOp --- @@ -230,7 +230,7 @@ public extension intConvertOp public extension byteConvertOp { byte toByte() - = byteConvertor.convert(self); + = ByteConvertor.convert(self); } // --- shortConvertOp --- @@ -238,28 +238,28 @@ public extension byteConvertOp public extension shortConvertOp { short toShort() - = shortConvertor.convert(self); + = ShortConvertor.convert(self); } // --- longConvertOp --- public extension longConvertOp { long toLong() - = longConvertor.convert(self); + = LongConvertor.convert(self); } // --- realConvertOp --- public extension realConvertOp { real toReal() - = realConvertor.convert(self); + = RealConvertor.convert(self); } // --- enumerableExOp --- public extension enumerableExOp { Enumerable asEnumerable() - = enumerableConvertor.convert(self); + = EnumerableConvertor.convert(self); } // --- arrayConvertOp --- @@ -274,7 +274,7 @@ public extension arrayConvertOp public extension intArrayConvertOp { IntMatrix toIntMatrix() - = intmatrixExConvertor.convert(self); + = IntmatrixExConvertor.convert(self); } // --- convertorOp --- @@ -285,15 +285,15 @@ public extension convertorOp = new Variant(self).saveTo(target); char toChar() - = charConvertor.convert(self); + = CharConvertor.convert(self); byte[] toByteArray() - = byteArrayExConvertor.convert(self); + = ByteArrayExConvertor.convert(self); } // --- convertor --- -public singleton intConvertExt +public singleton IntConvertExt { generic(n) { diff --git a/src60/extensions/dynamic/json.l b/src60/extensions/dynamic/json.l index d5fbf277b0..e16ba7123a 100644 --- a/src60/extensions/dynamic/json.l +++ b/src60/extensions/dynamic/json.l @@ -203,9 +203,9 @@ singleton helper token := helper.readNext(e); token => - "," { token := helper.readNext(e) } - "}" { eof := true } - ! { JsonException.new().raise() } + "," : { token := helper.readNext(e) } + "}" : { eof := true } + ! : { JsonException.new().raise() } }; ^ target @@ -221,9 +221,9 @@ singleton helper token := helper.readNext(e); token => - "," { token := helper.readNext(e) } - "]" { eof := true } - ! { JsonException.new().raise() } + "," : { token := helper.readNext(e) } + "]" : { eof := true } + ! : { JsonException.new().raise() } }; ^ target diff --git a/src60/extensions/formatter.l b/src60/extensions/formatter.l index da074f45d5..4438b52f8a 100644 --- a/src60/extensions/formatter.l +++ b/src60/extensions/formatter.l @@ -12,7 +12,7 @@ singleton helper while (ch != $125) { - n := intConvertor.convert(ch); + n := IntConvertor.convert(ch); if(n >= 30h && n <= 39h) { n := n - 30h; diff --git a/src60/extensions/random.l b/src60/extensions/random.l index dd26d12fd1..aff0c0155a 100644 --- a/src60/extensions/random.l +++ b/src60/extensions/random.l @@ -48,7 +48,7 @@ public sealed struct RandomGenerator { int next := self.eval(1000000); - real retVal := realConvertor.convert(next); + real retVal := RealConvertor.convert(next); retVal := retVal / 1000000.0r; diff --git a/src60/extensions/routines/stex/convertors.l b/src60/extensions/routines/stex/convertors.l index f971795246..8db91d71b3 100644 --- a/src60/extensions/routines/stex/convertors.l +++ b/src60/extensions/routines/stex/convertors.l @@ -1,6 +1,20 @@ import system'collections; -public extension EnumConvertorOp : Enumerator +public extension EnumerableConvertorOp : Enumerator +{ + T[] toArray() + { + auto list := new List(); + + foreach(T item; in self) { + list.append(item); + }; + + ^ list.Value + } +} + +public extension EnumeratorConvertorOp : Enumerable { T[] toArray() { diff --git a/src60/forms/win32_controls.l b/src60/forms/win32_controls.l index 62ba37781b..e8537772a5 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 } @@ -173,7 +173,7 @@ public abstract class BaseWinContainer : BaseWinControl IControl retrieve(Handle handle) { if(_handle == handle) - { ^ weak self :as IControl }; + { ^ weak self as:IControl }; int len := _controls.Length; IControl current; @@ -687,14 +687,14 @@ public abstract class BasePanel : BaseWinContainer { control.Parent := self; - _controls.append(weak control :as IControl) + _controls.append(weak control as:IControl) } internal appendControlInternal(ImageList control) { control.Parent := self; - _controls.append(weak control :as IControl) + _controls.append(weak control as:IControl) } int Width @@ -935,7 +935,7 @@ public sealed class RadioButtonGroup : BasePanel, interface int height := _region.Height; if (_handle != nil) { - self.resize(_handle, width, height) + self.resize(_handle.Handle, width, height) } else self.resize(Handle.Default, width, height) } diff --git a/src60/forms/win_forms.l b/src60/forms/win_forms.l index ab62f78793..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/sqlite/common.l b/src60/sqlite/common.l index 86a0c5c547..da63b6c493 100644 --- a/src60/sqlite/common.l +++ b/src60/sqlite/common.l @@ -197,25 +197,25 @@ public sealed class DBCommand int columnType := extern sqlite3.sqlite3_column_type(_commandHandle, index); columnType => - SQLITE_INTEGER + SQLITE_INTEGER: { int val := extern sqlite3.sqlite3_column_int(_commandHandle, index); ^ val } - SQLITE_TEXT + SQLITE_TEXT: { pointer columnTextPtr := extern sqlite3.sqlite3_column_text(_commandHandle, index); ^ cast string(columnTextPtr) } - SQLITE_FLOAT + SQLITE_FLOAT: { real val := extern sqlite3.sqlite3_column_double(_commandHandle, index); ^ val } - SQLITE_BLOB + SQLITE_BLOB: { pointer blob := extern sqlite3.sqlite3_column_blob(_commandHandle, index); int len := extern sqlite3.sqlite3_column_bytes(_commandHandle, index); @@ -226,11 +226,11 @@ public sealed class DBCommand ^ arr } - SQLITE_NULL + SQLITE_NULL: { ^ nil } - ! + ! : { DBException.new("Unsupported type").raise() } diff --git a/src60/system/app.l b/src60/system/app.l index ca9cec8b81..663bbe4d4d 100644 --- a/src60/system/app.l +++ b/src60/system/app.l @@ -1,3 +1,4 @@ + // --- startUp --- public sealed class StartUpEvents diff --git a/src60/system/basic.l b/src60/system/basic.l index afd2385a67..0b91d1ea46 100644 --- a/src60/system/basic.l +++ b/src60/system/basic.l @@ -1,4 +1,3 @@ - // --- BaseValue --- public abstract class BaseValue : info("a base value") @@ -276,7 +275,7 @@ public const struct ByteNumber : IntBaseNumber, constructor(int n) : info("Creates the object with a specified value") - = byteConvertor.convert(n); + = ByteConvertor.convert(n); add(o) <= add(cast byte(o)); @@ -480,23 +479,23 @@ public const struct ByteNumber : IntBaseNumber, short cast() : info("Returns the value as a short integer") - = shortConvertor.convert(self); + = ShortConvertor.convert(self); int cast() : info("returns the value as an integer") - = intConvertor.convert(self); + = IntConvertor.convert(self); uint cast() : info("returns the value as an unsigned integer") - = uintConvertor.convert(self); + = UIntConvertor.convert(self); long cast() : info("Returns the value as a long integer") - = longConvertor.convert(self); + = LongConvertor.convert(self); real cast() : info("Returns the value as a real number") - = realConvertor.convert(self); + = RealConvertor.convert(self); byte shiftLeft(int val) : info("shifts an integer value to the left by a specified number of bits") @@ -512,7 +511,7 @@ public const struct ByteNumber : IntBaseNumber, string toPrintable() : info("returns the literal presentation") - = stringConvertor.convert(self, 10); + = StringConvertor.convert(self, 10); byte clone() : info("clones the value") @@ -547,7 +546,7 @@ public const struct SByteNumber : IntBaseNumber, constructor(int n) : info("Creates the object with a specified value") - = sbyteConvertor.convert(n); + = SByteConvertor.convert(n); add(o) <= add(cast sbyte(o)); @@ -751,23 +750,23 @@ public const struct SByteNumber : IntBaseNumber, short cast() : info("Returns the value as a short integer") - = shortConvertor.convert(self); + = ShortConvertor.convert(self); int cast() : info("returns the value as an integer") - = intConvertor.convert(self); + = IntConvertor.convert(self); uint cast() : info("returns the value as an unsigned integer") - = uintConvertor.convert(self); + = UIntConvertor.convert(self); long cast() : info("Returns the value as a long integer") - = longConvertor.convert(self); + = LongConvertor.convert(self); real cast() : info("Returns the value as a real number") - = realConvertor.convert(self); + = RealConvertor.convert(self); sbyte shiftLeft(int val) : info("shifts an integer value to the left by a specified number of bits") @@ -783,7 +782,7 @@ public const struct SByteNumber : IntBaseNumber, string toPrintable() : info("returns the literal presentation") - = stringConvertor.convert(self, 10); + = StringConvertor.convert(self, 10); sbyte clone() : info("clones the value") @@ -818,14 +817,14 @@ public const struct ShortNumber : IntBaseNumber, constructor(byte b) : info("creates the object with specified value") - = shortConvertor.convert(b); + = ShortConvertor.convert(b); constructor(sbyte b) : info("creates the object with specified value") - = shortConvertor.convert(b); + = ShortConvertor.convert(b); constructor(int n) - = shortConvertor.convert(n); + = ShortConvertor.convert(n); add(o) <= add(cast short(o)); @@ -1031,26 +1030,26 @@ public const struct ShortNumber : IntBaseNumber, byte cast() : info("Returns the byte value") - = byteConvertor.convert(self); + = ByteConvertor.convert(self); int cast() : info("Returns the integer value") - = intConvertor.convert(self); + = IntConvertor.convert(self); uint cast() : info("Returns the unsigned integer value") - = uintConvertor.convert(self); + = UIntConvertor.convert(self); long cast() : info("Returns the long integer value") - = longConvertor.convert(self); + = LongConvertor.convert(self); real cast() : info("Returns the real number value") - = realConvertor.convert(self); + = RealConvertor.convert(self); string toPrintable() - = stringConvertor.convert(self, 10); + = StringConvertor.convert(self, 10); short shiftLeft(int val) : info("shifts an integer value to the left by a specified number of bits") @@ -1106,14 +1105,14 @@ public const struct UShortNumber : IntBaseNumber, constructor(short s) : info("creates the object with specified value") - = ushortConvertor.convert(s); + = UShortConvertor.convert(s); constructor(byte b) : info("creates the object with specified value") - = ushortConvertor.convert(b); + = UShortConvertor.convert(b); constructor(int n) - = ushortConvertor.convert(n); + = UShortConvertor.convert(n); add(o) <= add(cast ushort(o)); @@ -1319,30 +1318,30 @@ public const struct UShortNumber : IntBaseNumber, byte cast() : info("Returns the byte value") - = byteConvertor.convert(self); + = ByteConvertor.convert(self); short cast() : info("Returns the signed short value") - = shortConvertor.convert(self); + = ShortConvertor.convert(self); int cast() : info("Returns the integer value") - = intConvertor.convert(self); + = IntConvertor.convert(self); uint cast() : info("Returns the unsigned integer value") - = uintConvertor.convert(self); + = UIntConvertor.convert(self); long cast() : info("Returns the long integer value") - = longConvertor.convert(self); + = LongConvertor.convert(self); real cast() : info("Returns the real number value") - = realConvertor.convert(self); + = RealConvertor.convert(self); string toPrintable() - = stringConvertor.convert(self, 10); + = StringConvertor.convert(self, 10); ushort shiftLeft(int val) : info("shifts an integer value to the left by a specified number of bits") @@ -1397,7 +1396,7 @@ public const struct IntNumber : IntBaseNumber, constructor(uint n) : info("Creates the object with specified value") - = intConvertor.convert(n); + = IntConvertor.convert(n); constructor(byte b) = b; @@ -1406,7 +1405,7 @@ public const struct IntNumber : IntBaseNumber, = s; constructor(ushort s) - = s; + = IntConvertor.convert(s); bool equal(o) { @@ -1654,26 +1653,26 @@ public const struct IntNumber : IntBaseNumber, byte cast() : info("Returns the byte value") - = byteConvertor.convert(self); + = ByteConvertor.convert(self); short cast() : info("Returns the value as a short integer") - = shortConvertor.convert(self); + = ShortConvertor.convert(self); long cast() : info("Returns the long integer") - = longConvertor.convert(self); + = LongConvertor.convert(self); real cast() : info("Returns the real number") - = realConvertor.convert(self); + = RealConvertor.convert(self); uint cast() : info("Returns the unsigned integer") = new UIntNumber(self); string toPrintable() - = stringConvertor.convert(self, 10); + = StringConvertor.convert(self, 10); int clone() : info("Clones the value") @@ -1718,17 +1717,17 @@ public sealed const struct UIntNumber : IntBaseNumber, constructor(byte b) { - _value := uintConvertor.convert(b); + _value := UIntConvertor.convert(b); } constructor(short s) { - _value := uintConvertor.convert(s); + _value := UIntConvertor.convert(s); } constructor(int n) { - _value := uintConvertor.convert(n); + _value := UIntConvertor.convert(n); } constructor(uint n) @@ -1741,12 +1740,12 @@ public sealed const struct UIntNumber : IntBaseNumber, cast u(string s) { - _value := uintConvertor.convert(s); + _value := UIntConvertor.convert(s); } cast H(string s) { - _value := uintConvertor.convert(s, 16); + _value := UIntConvertor.convert(s, 16); } static uint MinValue @@ -1762,15 +1761,15 @@ public sealed const struct UIntNumber : IntBaseNumber, string toPrintable() : info("Returns the literal presentation") - = stringConvertor.convert(self, 16); + = StringConvertor.convert(self, 16); short cast() : info("Returns the value as a short integer") - = shortConvertor.convert(self); + = ShortConvertor.convert(self); byte cast() : info("Returns the byte value") - = byteConvertor.convert(self); + = ByteConvertor.convert(self); int cast() = self; @@ -2069,39 +2068,39 @@ public sealed const struct LongNumber : IntBaseNumber, constructor(int n) : info("Creates the object with specified value") - = longConvertor.convert(n); + = LongConvertor.convert(n); constructor(uint n) : info("Creates the object with specified value") - = longConvertor.convert(n); + = LongConvertor.convert(n); constructor(short n) : info("Creates the object with specified value") - = longConvertor.convert(n); + = LongConvertor.convert(n); constructor(byte b) : info("Creates the object with specified value") - = longConvertor.convert(b); + = LongConvertor.convert(b); int cast() : info("Returns an integer value") - = intConvertor.convert(self); + = IntConvertor.convert(self); uint cast() : info("Returns an integer value") - = uintConvertor.convert(self); + = UIntConvertor.convert(self); short cast() : info("Returns an integer value") - = shortConvertor.convert(self); + = ShortConvertor.convert(self); byte cast() : info("Returns an integer value") - = byteConvertor.convert(self); + = ByteConvertor.convert(self); real cast() : info("Returns a real value") - = realConvertor.convert(self); + = RealConvertor.convert(self); bool equal(o) { @@ -2300,7 +2299,7 @@ public sealed const struct LongNumber : IntBaseNumber, = -1l * _value; string toPrintable() - = stringConvertor.convert(self, 10); + = StringConvertor.convert(self, 10); long clone() = new LongNumber(_value); @@ -2340,13 +2339,13 @@ public sealed const struct RealNumber : BaseNumber, = Pi_value; constructor(int n) - = realConvertor.convert(n); + = RealConvertor.convert(n); constructor(byte n) - = realConvertor.convert(n); + = RealConvertor.convert(n); constructor(short n) - = realConvertor.convert(n); + = RealConvertor.convert(n); constructor() : info("Creates the object with a default value (0)") @@ -2358,11 +2357,11 @@ public sealed const struct RealNumber : BaseNumber, constructor(uint n) : info("Creates the object with specified value") - = realConvertor.convert(n); + = RealConvertor.convert(n); constructor(long n) : info("Creates the object with specified value") - = realConvertor.convert(n); + = RealConvertor.convert(n); bool equal(o) { @@ -2511,7 +2510,7 @@ public sealed const struct RealNumber : BaseNumber, string toPrintable() : info("Returns the literal presentation") - = stringConvertor.convert(self); + = StringConvertor.convert(self); real clone() : info("Clones the value") @@ -2555,11 +2554,11 @@ public const struct CharValue : BaseValue, constructor load(int n) : info("Creates the object with specified numeric value") - = charConvertor.convert(n); + = CharConvertor.convert(n); get internal int Value() { - int val := intConvertor.convert(self); + int val := IntConvertor.convert(self); ^ val } @@ -2644,13 +2643,13 @@ public const struct CharValue : BaseValue, = new CharValue(self); string toPrintable() - = stringConvertor.convert(self); + = StringConvertor.convert(self); string cast() - = stringConvertor.convert(self); + = StringConvertor.convert(self); wide cast() - = wideConvertor.convert(self); + = WideConvertor.convert(self); } // --- nil constant --- diff --git a/src60/system/calendar/dates.l b/src60/system/calendar/dates.l index eeeaf4a9c8..e26faa1e5d 100644 --- a/src60/system/calendar/dates.l +++ b/src60/system/calendar/dates.l @@ -45,7 +45,7 @@ namespace calendar retVal := retVal / 864000000000l; - ^ intConvertor.convert(retVal) + ^ IntConvertor.convert(retVal) } get int Hours() @@ -54,7 +54,7 @@ namespace calendar retVal := retVal / 36000000000l; - ^ intConvertor.convert(retVal) + ^ IntConvertor.convert(retVal) } get int Minutes() @@ -63,7 +63,7 @@ namespace calendar retVal := retVal / 600000000l; - ^ intConvertor.convert(retVal) + ^ IntConvertor.convert(retVal) } get int Seconds() @@ -72,7 +72,7 @@ namespace calendar retVal := retVal / 10000000l; - ^ intConvertor.convert(retVal) + ^ IntConvertor.convert(retVal) } get long Milliseconds() diff --git a/src60/system/calendar/lnx32_datetime.l b/src60/system/calendar/lnx32_datetime.l index 0678b0f5db..c07924f0f4 100644 --- a/src60/system/calendar/lnx32_datetime.l +++ b/src60/system/calendar/lnx32_datetime.l @@ -18,10 +18,10 @@ namespace calendar long rem := nanosec - secs * 1000000000l; rem := rem / 1000l; - int tmp := intConvertor.convert(secs); + int tmp := IntConvertor.convert(secs); tv_sec := tmp; - tmp := intConvertor.convert(rem); + tmp := IntConvertor.convert(rem); tv_usec := tmp; } @@ -91,11 +91,11 @@ namespace calendar get long Value() { - long l := longConvertor.convert(tv_sec); + long l := LongConvertor.convert(tv_sec); l := l * 10000000l; - long l2 := longConvertor.convert(tv_usec); + long l2 := LongConvertor.convert(tv_usec); l2 := l2 * 10l; l := l + l2; diff --git a/src60/system/calendar/lnx64_datetime.l b/src60/system/calendar/lnx64_datetime.l index d4e7a58d1e..96c392cdee 100644 --- a/src60/system/calendar/lnx64_datetime.l +++ b/src60/system/calendar/lnx64_datetime.l @@ -274,7 +274,7 @@ namespace calendar long val := tm_usec; val /= 1000; - int nval := intConvertor.convert(val); + int nval := IntConvertor.convert(val); ^ nval } diff --git a/src60/system/collections/tuples.l b/src60/system/collections/tuples.l index 15103f558d..044c063d37 100644 --- a/src60/system/collections/tuples.l +++ b/src60/system/collections/tuples.l @@ -16,15 +16,15 @@ namespace collections at(int index) { index => - 0 { ^ Item1 } - ! { OutOfRangeException.raise() } + 0 : { ^ Item1 } + ! : { OutOfRangeException.raise() } } setAt(int index, object val) { index => - 0 { Item1 := val } - ! { OutOfRangeException.raise() } + 0 : { Item1 := val } + ! : { OutOfRangeException.raise() } } Indexer indexer() = new BaseIndexer @@ -61,17 +61,17 @@ namespace collections at(int index) { index => - 0 { ^ Item1 } - 1 { ^ Item2 } - ! { OutOfRangeException.raise() } + 0 : { ^ Item1 } + 1 : { ^ Item2 } + ! : { OutOfRangeException.raise() } } setAt(int index, object val) { index => - 0 { Item1 := val } - 1 { Item2 := val } - ! { OutOfRangeException.raise() } + 0 : { Item1 := val } + 1 : { Item2 := val } + ! : { OutOfRangeException.raise() } } Tuple cast() @@ -111,17 +111,17 @@ namespace collections at(int index) { index => - 0 { ^ Item1 } - 1 { ^ Item2 } - ! { OutOfRangeException.raise() } + 0 : { ^ Item1 } + 1 : { ^ Item2 } + ! : { OutOfRangeException.raise() } } setAt(int index, object val) { index => - 0 { Item1 := val } - 1 { Item2 := val } - ! { OutOfRangeException.raise() } + 0 : { Item1 := val } + 1 : { Item2 := val } + ! : { OutOfRangeException.raise() } } } @@ -145,19 +145,19 @@ namespace collections at(int index) { index => - 0 { ^ Item1 } - 1 { ^ Item2 } - 2 { ^ Item3 } - ! { OutOfRangeException.raise() } + 0 : { ^ Item1 } + 1 : { ^ Item2 } + 2 : { ^ Item3 } + ! : { OutOfRangeException.raise() } } setAt(int index, object val) { index => - 0 { Item1 := val } - 1 { Item2 := val } - 2 { Item3 := val } - ! { OutOfRangeException.raise() } + 0 : { Item1 := val } + 1 : { Item2 := val } + 2 : { Item3 := val } + ! : { OutOfRangeException.raise() } } Indexer indexer() = new BaseIndexer @@ -198,21 +198,21 @@ namespace collections at(int index) { index => - 0 { ^ Item1 } - 1 { ^ Item2 } - 2 { ^ Item3 } - 3 { ^ Item4 } - ! { OutOfRangeException.raise() } + 0 : { ^ Item1 } + 1 : { ^ Item2 } + 2 : { ^ Item3 } + 3 : { ^ Item4 } + ! : { OutOfRangeException.raise() } } setAt(int index, object val) { index => - 0 { Item1 := val } - 1 { Item2 := val } - 2 { Item3 := val } - 3 { Item4 := val } - ! { OutOfRangeException.raise() } + 0 : { Item1 := val } + 1 : { Item2 := val } + 2 : { Item3 := val } + 3 : { Item4 := val } + ! : { OutOfRangeException.raise() } } Indexer indexer() = new BaseIndexer @@ -255,23 +255,23 @@ namespace collections at(int index) { index => - 0 { ^ Item1 } - 1 { ^ Item2 } - 2 { ^ Item3 } - 3 { ^ Item4 } - 4 { ^ Item5 } - ! { OutOfRangeException.raise() } + 0 : { ^ Item1 } + 1 : { ^ Item2 } + 2 : { ^ Item3 } + 3 : { ^ Item4 } + 4 : { ^ Item5 } + ! : { OutOfRangeException.raise() } } setAt(int index, object val) { index => - 0 { Item1 := val } - 1 { Item2 := val } - 2 { Item3 := val } - 3 { Item4 := val } - 4 { Item5 := val } - ! { OutOfRangeException.raise() } + 0 : { Item1 := val } + 1 : { Item2 := val } + 2 : { Item3 := val } + 3 : { Item4 := val } + 4 : { Item5 := val } + ! : { OutOfRangeException.raise() } } Indexer indexer() = new BaseIndexer @@ -316,25 +316,25 @@ namespace collections at(int index) { index => - 0 { ^ Item1 } - 1 { ^ Item2 } - 2 { ^ Item3 } - 3 { ^ Item4 } - 4 { ^ Item5 } - 5 { ^ Item6 } - ! { OutOfRangeException.raise() } + 0 : { ^ Item1 } + 1 : { ^ Item2 } + 2 : { ^ Item3 } + 3 : { ^ Item4 } + 4 : { ^ Item5 } + 5 : { ^ Item6 } + ! : { OutOfRangeException.raise() } } setAt(int index, object val) { index => - 0 { Item1 := val } - 1 { Item2 := val } - 2 { Item3 := val } - 3 { Item4 := val } - 4 { Item5 := val } - 5 { Item6 := val } - ! { OutOfRangeException.raise() } + 0 : { Item1 := val } + 1 : { Item2 := val } + 2 : { Item3 := val } + 3 : { Item4 := val } + 4 : { Item5 := val } + 5 : { Item6 := val } + ! : { OutOfRangeException.raise() } } Indexer indexer() = new BaseIndexer diff --git a/src60/system/convertors.l b/src60/system/convertors.l index 4b2fa84ca8..7fba584db1 100644 --- a/src60/system/convertors.l +++ b/src60/system/convertors.l @@ -1,6 +1,6 @@ // --- byteConvertor --- -public singleton byteConvertor +public singleton ByteConvertor { convert(int n, out byte retVal) : external(system'core_routines'__intToByte); @@ -60,21 +60,21 @@ public singleton byteConvertor byte convert(real r) { - int n := intConvertor.convert(r); + int n := IntConvertor.convert(r); ^ self.convert(n); } byte convert(string s, int radix) { - int n := intConvertor.convert(s, radix); + int n := IntConvertor.convert(s, radix); ^ self.convert(n); } byte convert(wide s, int radix) { - int n := intConvertor.convert(s, radix); + int n := IntConvertor.convert(s, radix); ^ self.convert(n); } @@ -82,7 +82,7 @@ public singleton byteConvertor // --- sbyteConvertor --- -public singleton sbyteConvertor +public singleton SByteConvertor { convert(int n, out sbyte retVal) : external(system'core_routines'__intToSByte); @@ -100,7 +100,7 @@ public singleton sbyteConvertor // --- shortConvertor --- -public singleton shortConvertor +public singleton ShortConvertor { private convertInt(int n, out short retVal) : external(system'core_routines'__intToShort); @@ -140,35 +140,35 @@ public singleton shortConvertor short convert(long l) { - int n := intConvertor.convert(l); + int n := IntConvertor.convert(l); ^ self.convert(n) } short convert(real r) { - int n := intConvertor.convert(r); + int n := IntConvertor.convert(r); ^ self.convert(n) } short convert(char ch) { - int n := intConvertor.convert(ch); + int n := IntConvertor.convert(ch); ^ self.convert(n) } short convert(string s, int radix) { - int n := intConvertor.convert(s, radix); + int n := IntConvertor.convert(s, radix); ^ self.convert(n) } short convert(wide s, int radix) { - int n := intConvertor.convert(s, radix); + int n := IntConvertor.convert(s, radix); ^ self.convert(n) } @@ -176,7 +176,7 @@ public singleton shortConvertor // --- ushortConvertor --- -public singleton ushortConvertor +public singleton UShortConvertor { private convertInt(int n, out ushort retVal) : external(system'core_routines'__intToUShort); @@ -198,14 +198,15 @@ public singleton ushortConvertor } } -// --- intConvertor --- +// --- IntConvertor --- -public singleton intConvertor +public singleton IntConvertor { private convertChar(char ch, out int retVal) : external(system'core_routines'__charToInt); private convertLong(long l, out int retVal) : external(system'core_routines'__longToInt); private convertReal(real l, out int retVal) : external(system'core_routines'__realToInt); private convertUInt(uint l, out int retVal) : external(system'core_routines'__uintToInt); + private convertUShort(ushort s, out int retVal) : external(system'core_routines'__ushortToInt); int convert(o) = cast int(o); @@ -237,6 +238,13 @@ public singleton intConvertor ^ retVal } + int convert(ushort n) + { + self.convertUShort(n, out int retVal); + + ^ retVal + } + int convert(char ch) { self.convertChar(ch, out int retVal); @@ -312,9 +320,9 @@ public singleton intConvertor <= convert(s, 10); } -// --- uintConvertor --- +// --- uIntConvertor --- -public singleton uintConvertor +public singleton UIntConvertor { private copyDirectly(int n, out uint retVal) : external(system'core_routines'__intToUInt); @@ -339,18 +347,18 @@ public singleton uintConvertor { int n := b; - ^ uintConvertor.convert(n); + ^ UIntConvertor.convert(n); } uint convert(short s) { int n := s; - ^ uintConvertor.convert(n); + ^ UIntConvertor.convert(n); } uint convert(long l) { - int n := intConvertor.convert(l); + int n := IntConvertor.convert(l); ^ self.convert(n); } @@ -398,7 +406,7 @@ public singleton uintConvertor // --- longConvertor --- -public singleton longConvertor +public singleton LongConvertor { long convert(o) = cast long(o); @@ -440,7 +448,7 @@ public singleton longConvertor long convert(real r) { // !! temporal implementation - int n := intConvertor.convert(r); + int n := IntConvertor.convert(r); long l := n; @@ -449,7 +457,7 @@ public singleton longConvertor long convert(char ch) { - int n := intConvertor.convert(ch); + int n := IntConvertor.convert(ch); long l := n; @@ -522,7 +530,7 @@ public singleton longConvertor // --- realConvertor --- -public singleton realConvertor +public singleton RealConvertor { real convert(o) = cast real(o); @@ -548,7 +556,7 @@ public singleton realConvertor }; bool inverted := false; - int intPart := intConvertor.convert(intPartStr, 10); + int intPart := IntConvertor.convert(intPartStr, 10); if (intPart < 0) { intPart := -intPart; inverted := true; @@ -556,7 +564,7 @@ public singleton realConvertor real r := intPart; if (decimalPartStr != nil) { - real frac := intConvertor.convert(decimalPartStr, 10); + real frac := IntConvertor.convert(decimalPartStr, 10); for (int i := 0; i < decimalPartStr.Length; i += 1) { frac := frac * 0.1; }; @@ -571,7 +579,7 @@ public singleton realConvertor } real convert(wide w) - <= convert(stringConvertor.convert(w)); + <= convert(StringConvertor.convert(w)); real convert(byte b) { @@ -603,7 +611,7 @@ public singleton realConvertor real convert(long l) { - int n := intConvertor.convert(l); + int n := IntConvertor.convert(l); real r := n; @@ -613,7 +621,7 @@ public singleton realConvertor // --- charConvertor --- -public singleton charConvertor +public singleton CharConvertor { convert(int n, out char retVal) : external(system'core_routines'__intToChar); @@ -662,9 +670,9 @@ public singleton charConvertor = cast char(o); } -// --- stringConvertor --- +// --- StringConvertor --- -public singleton stringConvertor +public singleton StringConvertor { string convert(byte b, int radix) { @@ -943,7 +951,7 @@ public singleton stringConvertor // --- wideConvertor --- -public singleton wideConvertor +public singleton WideConvertor { wide convert(char ch) { @@ -1230,7 +1238,7 @@ public singleton wideConvertor // --- byteArrayConvertor --- -public singleton byteArrayConvertor +public singleton ByteArrayConvertor { int convert(wide sour, int sourLen, byte[] dest, int destIndex, int destLen) { @@ -1252,7 +1260,7 @@ public singleton byteArrayConvertor // --- shortArrayConvertor --- -public singleton shortArrayConvertor +public singleton ShortArrayConvertor { int convert(string sour, int sourLen, short[] dest, int destIndex, int destLen) { @@ -1274,7 +1282,7 @@ public singleton shortArrayConvertor // --- mssgConvertor --- -public singleton mssgConvertor +public singleton MssgConvertor { convert(int n, out Message retVal) : external(system'core_routines'__intToMssg); diff --git a/src60/system/dynamic/closure.l b/src60/system/dynamic/closure.l index 32ca12ea0b..95cba8e62c 100644 --- a/src60/system/dynamic/closure.l +++ b/src60/system/dynamic/closure.l @@ -122,7 +122,7 @@ public struct AllocFunction : TapeFunction constructor(string strSize) { - this size := intConvertor.convert(strSize) + this size := IntConvertor.convert(strSize) } constructor(int size) @@ -160,7 +160,7 @@ public struct LocalFunction : TapeFunction constructor(string strIndex) { - this index := intConvertor.convert(strIndex) + this index := IntConvertor.convert(strIndex) } mixin function(params object[] args) : external(system'core_routines'__local_closure); diff --git a/src60/system/dynamic/expressions/expressions.l b/src60/system/dynamic/expressions/expressions.l index 2d5e667fcc..cd7167618e 100644 --- a/src60/system/dynamic/expressions/expressions.l +++ b/src60/system/dynamic/expressions/expressions.l @@ -8,7 +8,7 @@ namespace expressions const int mode_lcl = 1; const int mode_class = 4; - symbol used : preloaded = new object[]{Expression, DynamicSingleton,DynamicExpressionSymbol,SymbolCollection}; + symbol used : preloaded = new object[]{Expression, DynamicSingleton,DynamicExpressionSymbol,SymbolCollection,LazySymbolExpression}; public class ScopeIdentifier { @@ -882,7 +882,7 @@ namespace expressions { constructor(o) { - this object := intConvertor.convert(o) + this object := IntConvertor.convert(o) } } @@ -890,9 +890,9 @@ namespace expressions { constructor(string o) { - int n := intConvertor.convert(o.Substring(1)); + int n := IntConvertor.convert(o.Substring(1)); - this object := charConvertor.convert(n) + this object := CharConvertor.convert(n) } } diff --git a/src60/system/dynamic/groups.l b/src60/system/dynamic/groups.l index c92659f413..12f524a29b 100644 --- a/src60/system/dynamic/groups.l +++ b/src60/system/dynamic/groups.l @@ -28,7 +28,7 @@ public const struct ExtensionDispatcher auto s := namespaces[i]; int sLen := s.Length; - UTF8Encoder.toByteArray(s, 0, ref sLen, tmp, tmpIndex, ref int tmpLen); + int tmpLen := UTF8Encoder.toByteArray(s, 0, ref sLen, tmp, tmpIndex, 1024); tmpIndex += tmpLen; tmp[tmpIndex] := 0; tmpIndex += 1; @@ -81,7 +81,7 @@ public const struct VariadicExtensionDispatcher auto s := namespaces[i]; int sLen := s.Length; - UTF8Encoder.toByteArray(s, 0, ref sLen, tmp, tmpIndex, ref int tmpLen); + int tmpLen := UTF8Encoder.toByteArray(s, 0, ref sLen, tmp, tmpIndex, 1024); tmpIndex += tmpLen; tmp[tmpIndex] := 0; tmpIndex += 1; diff --git a/src60/system/dynamic/reflection.l b/src60/system/dynamic/reflection.l index 77e36c833a..572e8e3239 100644 --- a/src60/system/dynamic/reflection.l +++ b/src60/system/dynamic/reflection.l @@ -13,7 +13,7 @@ public extension classROp { ifnot (tmp_array[i].anyMask(60h)) { - Message message := mssgConvertor.convert(tmp_array[i]); + Message message := MssgConvertor.convert(tmp_array[i]); list.append(message); }; @@ -35,7 +35,7 @@ public extension classROp { int count := tmp_array[i] & 01Fh; if (count == 1) { - Message message := mssgConvertor.convert(tmp_array[i]); + Message message := MssgConvertor.convert(tmp_array[i]); MessageName prop := message.MessageName; diff --git a/src60/system/extensions.l b/src60/system/extensions.l index c9ab8626bb..30fdd5b6ca 100644 --- a/src60/system/extensions.l +++ b/src60/system/extensions.l @@ -199,7 +199,7 @@ public extension byteOp : ByteNumber { var retVal := self / operand * operand; - ^ byteConvertor.convert(retVal) + ^ ByteConvertor.convert(retVal) } bool isOdd() @@ -285,7 +285,7 @@ public extension shortOp : ShortNumber { var retVal := self / operand * operand; - ^ shortConvertor.convert(retVal) + ^ ShortConvertor.convert(retVal) } bool isOdd() @@ -312,7 +312,7 @@ public extension shortOp : ShortNumber w := w & 0FF00h; w := w.shiftRight(8); - ^ byteConvertor.convert(w) + ^ ByteConvertor.convert(w) } get byte Low() @@ -320,7 +320,7 @@ public extension shortOp : ShortNumber short w := self; w := w & 0FFh; - ^ byteConvertor.convert(w) + ^ ByteConvertor.convert(w) } } @@ -428,7 +428,7 @@ public extension intOp : IntNumber w := w & 0FFFF0000h; w := w.shiftRight(8); - ^ shortConvertor.convert(w) + ^ ShortConvertor.convert(w) } get short Low() @@ -436,7 +436,7 @@ public extension intOp : IntNumber int w := self; w := w & 0FFFFh; - ^ shortConvertor.convert(w) + ^ ShortConvertor.convert(w) } } @@ -642,7 +642,7 @@ public extension longOp : LongNumber w := w & -4294967296l; w := w.shiftRight(32); - ^ intConvertor.convert(w) + ^ IntConvertor.convert(w) } get int Low() @@ -650,7 +650,7 @@ public extension longOp : LongNumber long w := self; w := w & 4294967295l; - ^ intConvertor.convert(w) + ^ IntConvertor.convert(w) } } @@ -831,7 +831,7 @@ public extension realOp : RealNumber } get int IntegerInt() - = intConvertor.convert(self.Integer); + = IntConvertor.convert(self.Integer); get real Rounded() { @@ -841,7 +841,7 @@ public extension realOp : RealNumber } get int RoundedInt() - = intConvertor.convert(self.Rounded); + = IntConvertor.convert(self.Rounded); get real Absolute() { @@ -907,7 +907,7 @@ public extension realOp : RealNumber int b := 10.power(precision); real r := a * b + 0.5r; - int c := intConvertor.convert(r.Rounded); + int c := IntConvertor.convert(r.Rounded); a := c.realDiv(b); @@ -1217,25 +1217,25 @@ public extension charOp : CharValue bool isWhitespace() { self => - $9 { ^ true } - $32 { ^ true } - $10 { ^ true } - $13 { ^ true } - $12 { ^ true }; + $9 : { ^ true } + $32 : { ^ true } + $10 : { ^ true } + $13 : { ^ true } + $12 : { ^ true }; ^ false } bool isDigit() { - int ch := intConvertor.convert(self); + int ch := IntConvertor.convert(self); ^ (ch >= 30h) && (ch <= 39h) } bool isLetter() { - int ch := intConvertor.convert(self); + int ch := IntConvertor.convert(self); if (ch >= 41h && ch <= 5Ah) { ^ true }; @@ -1254,7 +1254,7 @@ public extension charOp : CharValue bool isLToken() { - int ch := intConvertor.convert(self); + int ch := IntConvertor.convert(self); if (ch >= 41h && ch <= 5Ah) { ^ true }; diff --git a/src60/system/io/files.l b/src60/system/io/files.l index 3af6e102b0..dba97a6d2b 100644 --- a/src60/system/io/files.l +++ b/src60/system/io/files.l @@ -56,6 +56,13 @@ namespace io } } + static saveContent(string path, string content, Encoder encoder) + { + using(TextWriter writer := fileControl.writer(path, encoder)) { + writer.write(content); + } + } + static readContentTo(string path, TextBuilder output) { using(TextReader reader := fileControl.newReader(path)) { diff --git a/src60/system/io/lnx_console.l b/src60/system/io/lnx_console.l index eda24a6852..50c07fb68b 100644 --- a/src60/system/io/lnx_console.l +++ b/src60/system/io/lnx_console.l @@ -97,7 +97,7 @@ namespace io int ch := extern libc.getchar(); - byte b := byteConvertor.convert(ch); + byte b := ByteConvertor.convert(ch); buffer[i] := b; diff --git a/src60/system/io/lnx_files.l b/src60/system/io/lnx_files.l index 04dfaca013..9a7cd41354 100644 --- a/src60/system/io/lnx_files.l +++ b/src60/system/io/lnx_files.l @@ -39,15 +39,15 @@ namespace io _handle) } - read(byte[] dump, ref int retVal) + int read(byte[] dump, int length) { int n := extern libc.fread( dump, 1, - retVal, + length, _handle); - retVal := n + ^ n } int Index diff --git a/src60/system/io/streamwriter.l b/src60/system/io/streamwriter.l index 92fdf61d96..92aa1ce31a 100644 --- a/src60/system/io/streamwriter.l +++ b/src60/system/io/streamwriter.l @@ -219,7 +219,7 @@ namespace io blockLength := 32 }; - _encoder.convertTo(input, offset, ref blockLength, buffer, 0, ref bufferLength); + bufferLength := _encoder.convertTo(input, offset, ref blockLength, buffer, 0, bufferLength); _stream.write(buffer, bufferLength); diff --git a/src60/system/io/win_console.l b/src60/system/io/win_console.l index 3b724d58e8..3148071a70 100644 --- a/src60/system/io/win_console.l +++ b/src60/system/io/win_console.l @@ -143,7 +143,7 @@ namespace io subs_len := 128 }; - OEMEncoder.toByteArray(literal, index, ref subs_len, buffer, 0, ref buf_len); + buf_len := OEMEncoder.toByteArray(literal, index, ref subs_len, buffer, 0, buf_len); self.write(buffer, buf_len); diff --git a/src60/system/io/win_files.l b/src60/system/io/win_files.l index 5c919488cc..74fde6d9fc 100644 --- a/src60/system/io/win_files.l +++ b/src60/system/io/win_files.l @@ -145,6 +145,8 @@ namespace io 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) diff --git a/src60/system/math/math.l b/src60/system/math/math.l index 90f8429e13..9f92a07221 100644 --- a/src60/system/math/math.l +++ b/src60/system/math/math.l @@ -3,7 +3,7 @@ import system; namespace math { // --- mathController --- - singleton mathController + singleton MathController { absolute(byte n) = n.Absolute; @@ -39,10 +39,10 @@ namespace math = 1.0.exp(); Radian - = realConvertor.convert(self).Radian; + = RealConvertor.convert(self).Radian; Degree - = realConvertor.convert(self).Degree; + = RealConvertor.convert(self).Degree; } public extension mathOp @@ -51,16 +51,16 @@ namespace math = cast real(self).Rounded; RoundedInt - = intConvertor.convert(cast real(self).Rounded); + = IntConvertor.convert(cast real(self).Rounded); Integer = cast real(self).Integer; IntegerInt - = intConvertor.convert(cast real(self).Integer); + = IntConvertor.convert(cast real(self).Integer); mod(n) - = mathController.mod(self, n); + = MathController.mod(self, n); frac() = cast real(self).frac(); @@ -99,8 +99,8 @@ namespace math } public real Pi - = mathController.pi(); + = MathController.pi(); public real E - = mathController.e(); + = MathController.e(); } \ No newline at end of file diff --git a/src60/system/operations/advanced/operations.l b/src60/system/operations/advanced/operations.l index b4ef108432..42d523cc62 100644 --- a/src60/system/operations/advanced/operations.l +++ b/src60/system/operations/advanced/operations.l @@ -30,12 +30,12 @@ public template if::is(truePart) : __included(statements) } } -// --- expr :as T --- +// --- expr as: T --- public template as(expr) : __included(statements) = cast T(expr); -// --- expr :is T --- +// --- expr is: T --- public template is(expr) : __included(statements) = expr.instanceOf(T); diff --git a/src60/system/pointers.l b/src60/system/pointers.l index 2d83d7f3fa..cbcf332027 100644 --- a/src60/system/pointers.l +++ b/src60/system/pointers.l @@ -39,6 +39,10 @@ public sealed const struct UnsafePointer embeddable __ptr _pointer; private clear() : external(system'core_routines'__clearPtr); + private readIntPtr(out int retVal) : external(system'core_routines'__readIntPtr); + private readIntPtrValue(out int retVal) : external(system'core_routines'__readIntPtrVal); + private readRealPtrValue(out real retVal) : external(system'core_routines'__readRealPtrVal); + private assignPtr(object obj) : external(system'core_routines'__assignPtr); constructor() { @@ -52,8 +56,8 @@ public sealed const struct UnsafePointer constructor(object obj) { - if (obj :is pointer) { - _pointer := cast UnsafePointer(obj) + if (obj is: pointer) { + _pointer := cast UnsafePointer(weak obj) } else self.assignPtr(obj); } @@ -61,11 +65,6 @@ public sealed const struct UnsafePointer get constructor Default() = new UnsafePointer(); - private readIntPtr(out int retVal) : external(system'core_routines'__readIntPtr); - private readRealPtr(out real retVal) : external(system'core_routines'__readRealPtr); - - private assignPtr(object obj) : external(system'core_routines'__assignPtr); - bool isUnassigned() { ^ _pointer == 0; @@ -89,13 +88,30 @@ public sealed const struct UnsafePointer ^ retVal } - real cast() + get int Value() + { + self.readIntPtrValue(out int retVal); + + ^ retVal + } + + get retoverload real Value() { - self.readRealPtr(out real retVal); + self.readRealPtrValue(out real retVal); ^ retVal } + get retoverload string Value() + { + ^ PrimitivePointerOperations.readString(self); + } + + get retoverload wide Value() + { + ^ PrimitivePointerOperations.readWideString(self); + } + 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/primitives.l b/src60/system/primitives.l index 60a9b69e5d..afffebe900 100644 --- a/src60/system/primitives.l +++ b/src60/system/primitives.l @@ -213,14 +213,14 @@ internal singleton PrimitiveRealOperations int e := PrimitiveRealOperations.normalizeFloat(ref r); real remainder := value.Integer; - int intPart := intConvertor.convert(remainder); + int intPart := IntConvertor.convert(remainder); remainder := value - remainder; decimalPartLen := 9; remainder := remainder * 1.0e9; - int decPart := intConvertor.convert(remainder); + int decPart := IntConvertor.convert(remainder); // rounding real tmp := decPart; @@ -271,7 +271,7 @@ internal singleton PrimitiveRealOperations pointer ptr := temp; - real v := ptr; + real v := ptr.Value; retVal := v } @@ -705,7 +705,7 @@ internal singleton UTFOperations int convertUTF32_2_8(int value, byte[] dest, int index, int length) { if (value < 80h) { - byte b := intConvertor.convert(value); + byte b := IntConvertor.convert(value); dest[index] := b; @@ -719,8 +719,8 @@ internal singleton UTFOperations int n2 := value & 03Fh; n2 := n2 | 080h; - byte b1 := intConvertor.convert(n1); - byte b2 := intConvertor.convert(n2); + byte b1 := IntConvertor.convert(n1); + byte b2 := IntConvertor.convert(n2); dest[index] := b1; dest[index + 1] := b2; @@ -739,9 +739,9 @@ internal singleton UTFOperations int n3 := value & 03Fh; n3 := n3 | 080h; - byte b1 := intConvertor.convert(n1); - byte b2 := intConvertor.convert(n2); - byte b3 := intConvertor.convert(n3); + byte b1 := IntConvertor.convert(n1); + byte b2 := IntConvertor.convert(n2); + byte b3 := IntConvertor.convert(n3); dest[index] := b1; dest[index + 1] := b2; @@ -765,10 +765,10 @@ internal singleton UTFOperations int n4 := value & 03Fh; n4 := n4 | 080h; - byte b1 := intConvertor.convert(n1); - byte b2 := intConvertor.convert(n2); - byte b3 := intConvertor.convert(n3); - byte b4 := intConvertor.convert(n4); + byte b1 := IntConvertor.convert(n1); + byte b2 := IntConvertor.convert(n2); + byte b3 := IntConvertor.convert(n3); + byte b4 := IntConvertor.convert(n4); dest[index] := b1; dest[index + 1] := b2; @@ -788,7 +788,7 @@ internal singleton UTFOperations int length := 0; int n := value; if (n < 010000h) { - short s := shortConvertor.convert(n); + short s := ShortConvertor.convert(n); dest[index] := s; @@ -797,12 +797,12 @@ internal singleton UTFOperations int n2 := n $shr 10; n2 += 0D7C0h; - short tmp := shortConvertor.convert(n2); + short tmp := ShortConvertor.convert(n2); dest[index] := tmp; n := n & 03FFh; n += 0DC00h; - tmp := shortConvertor.convert(n); + tmp := ShortConvertor.convert(n); dest[index + 1] := tmp; ^ 2; diff --git a/src60/system/strings.l b/src60/system/strings.l index 9e1bf96212..717c2795a5 100644 --- a/src60/system/strings.l +++ b/src60/system/strings.l @@ -834,7 +834,7 @@ public const struct String : BaseValue, short buffer[256]; if (l < 256) { - m := shortArrayConvertor.convert(self, l, buffer, 0, 256); + m := ShortArrayConvertor.convert(self, l, buffer, 0, 256); ^ WideString.fromShortArray(0, m, buffer) }; @@ -848,7 +848,7 @@ public const struct String : BaseValue, page := 256 }; - m := shortArrayConvertor.convert(self.Substring(i,page), page, buffer, 0, 256); + m := ShortArrayConvertor.convert(self.Substring(i,page), page, buffer, 0, 256); retVal := retVal.add(WideString.fromShortArray(0, m, buffer)); @@ -1234,7 +1234,7 @@ public const struct WideString : BaseValue, byte buffer[256]; if (l < 128) { - m := byteArrayConvertor.convert(self, l, buffer, 0, 256); + m := ByteArrayConvertor.convert(self, l, buffer, 0, 256); ^ String.fromByteArray(0, m, buffer) }; @@ -1248,7 +1248,7 @@ public const struct WideString : BaseValue, page := 256 }; - m := byteArrayConvertor.convert(self.Substring(i,page), page, buffer, 0, 256); + m := ByteArrayConvertor.convert(self.Substring(i,page), page, buffer, 0, 256); retVal := retVal.add(String.fromByteArray(0, m, buffer)); @@ -1561,35 +1561,35 @@ public sealed class Variant /// Tries to convert the value to a byte number byte cast() - = byteConvertor.convert(value); + = ByteConvertor.convert(value); /// Tries to convert the value to a short integer number short cast() - = shortConvertor.convert(value); + = ShortConvertor.convert(value); /// Tries to convert the value to a character char cast() - = charConvertor.convert(value); + = CharConvertor.convert(value); /// Tries to convert the literal value to the integer number int cast() - = intConvertor.convert(value); + = IntConvertor.convert(value); /// Tries to convert the literal value to the long integer number long cast() - = longConvertor.convert(value); + = LongConvertor.convert(value); /// Tries to convert the literal value to the real number real cast() - = realConvertor.convert(value); + = RealConvertor.convert(value); /// Returns a literal value string cast() - = stringConvertor.convert(value); + = StringConvertor.convert(value); /// Returns a wide literal value wide cast() - = wideConvertor.convert(value); + = WideConvertor.convert(value); string toPrintable() => value; diff --git a/src60/system/text/encoding.l b/src60/system/text/encoding.l index b9cc9a6972..7db4535919 100644 --- a/src60/system/text/encoding.l +++ b/src60/system/text/encoding.l @@ -111,7 +111,7 @@ namespace text { char toChar(byte b) { - char retVal := charConvertor.convert(b); + char retVal := CharConvertor.convert(b); ^ retVal } @@ -138,7 +138,7 @@ namespace text { char toChar(short w) { - char retVal := charConvertor.convert(w); + char retVal := CharConvertor.convert(w); ^ retVal } diff --git a/src60/system/text/textbuffer.l b/src60/system/text/textbuffer.l index ff79144a5e..ebe5046c87 100644 --- a/src60/system/text/textbuffer.l +++ b/src60/system/text/textbuffer.l @@ -159,7 +159,7 @@ namespace text ch := s[i_val]; while (ch != $125) { - n := intConvertor.convert(ch); + n := IntConvertor.convert(ch); if(n >= 30h && n <= 39h) { n := n - 30h; @@ -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) { @@ -657,7 +657,7 @@ namespace text } insert(index, o) - <= insert(index :as IntNumber, o.toPrintable() :as WideString); + <= insert(index as:IntNumber, o.toPrintable() as:WideString); delete(int index, int length) { diff --git a/tests60/sandbox/sandbox.l b/tests60/sandbox/sandbox.l index 9ec6a551ac..5616599095 100644 --- a/tests60/sandbox/sandbox.l +++ b/tests60/sandbox/sandbox.l @@ -1,4 +1,6 @@ +sealed A; public program() { + int n := 23.1; } \ No newline at end of file diff --git a/tests60/script_tests/basic.l b/tests60/script_tests/basic.l new file mode 100644 index 0000000000..25b8a44585 --- /dev/null +++ b/tests60/script_tests/basic.l @@ -0,0 +1,12 @@ +import extensions; +import extensions'scripting; +import ltests; + +public evalTest() : testCase() +{ + var ret := lscript.interpretLine("""Hello "".add(""World"")"); + + Assert.ifEqual(ret, "Hello World"); + + console.write("."); +} diff --git a/tests60/script_tests/main.l b/tests60/script_tests/main.l new file mode 100644 index 0000000000..7c624ecebc --- /dev/null +++ b/tests60/script_tests/main.l @@ -0,0 +1,10 @@ +import ltests; + +public program() +{ + console.writeLine("--- ELENA 6 Script Functional Tests ---"); + + Engine.run(); + + console.writeLine("--- Passed ---") +} \ No newline at end of file diff --git a/tests60/script_tests/script_tests.prj b/tests60/script_tests/script_tests.prj new file mode 100644 index 0000000000..35db799ad8 --- /dev/null +++ b/tests60/script_tests/script_tests.prj @@ -0,0 +1,22 @@ + + + + script_tests.exe + + + + + script_tests64.exe + + + + script_tests + + + + + main.l + basic.l + + + \ No newline at end of file diff --git a/tests60/system_tests/basic.l b/tests60/system_tests/basic.l index 14558fcebd..c22fe2cbfd 100644 --- a/tests60/system_tests/basic.l +++ b/tests60/system_tests/basic.l @@ -939,9 +939,9 @@ public multySelectTest() : testCase() var n := 3; n => - 1 { Assert.ifTrue(n==1); } - 2 { Assert.ifTrue(n==2); } - 3 { Assert.ifTrue(n==3); }; + 1 : { Assert.ifTrue(n==1); } + 2 : { Assert.ifTrue(n==2); } + 3 : { Assert.ifTrue(n==3); }; console.write(".") } @@ -1922,7 +1922,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("."); } @@ -1974,7 +1974,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("."); } @@ -2276,3 +2276,83 @@ public variadicBoxingTest() : testCase() variadicBoxingTestset'A.validate2("a", "b", "c"); Console.write("."); } + +namespace reflectionTestset +{ + A + { + string Name : prop; + } +} + + +public reflectionTest() : testCase() +{ + reflectionTestset'A a := new reflectionTestset'A(); + + MessageName subj := mssg Name; + + subj.setPropertyValue(a, "Ivan"); + + Assert.ifEqual(subj.getPropertyValue(a), "Ivan"); + Console.write("."); +} + +namespace variadicFunctionTestset +{ + function variadicSum(params object[] args) + { + var sum := 0; + for (int i := 0; i < args.Length; i++) { + sum := sum + args[i] + }; + + ^ sum + } + + function sumAndTest(object sumToCheck, params object[] args) + { + Assert.ifEqual(variadicSum(params args), sumToCheck); + } +} + + +public variadicFunctionTest() : testCase() +{ + variadicFunctionTestset'sumAndTest(6, 1,2,3); + Console.write("."); +} + +sealed class MyIntValue +{ + int value; + + constructor(string value) + { + this value := value.toInt() + } + + int Value = value; +} + +public implicitConvertorTest() : testCase() +{ + auto v := "2" as: MyIntValue; + + Assert.ifEqual(v.Value, 2); + Console.write("."); +} + +public pointerTest() : testCase() +{ + pointer ptr := 2; + + var o := ptr; + pointer ptr2 := o; + + int v := ptr.Value; + int v2 := ptr.Value; + + Assert.ifEqual(v, 2); + Assert.ifEqual(v2, 2); +} diff --git a/tests60/system_tests/main.l b/tests60/system_tests/main.l index 3199eb1a69..830a5cc753 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 Unit Tests ---"); + console.writeLine("--- ELENA 6 API Functional Tests ---"); Engine.run();
    Modifier and TypeConversion Method
    + +String cast()
    -RealNumber +cast() +
    + +IntNumber cast()