From b6bb3d2c6289dae5d49b4cb5519b7f999a67ccda Mon Sep 17 00:00:00 2001 From: Anton Krotov Date: Thu, 2 Nov 2017 16:36:50 +0000 Subject: [PATCH] Oberon07: some extensions git-svn-id: svn://kolibrios.org@7107 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/develop/oberon07/Compiler.kex | Bin 34369 -> 34594 bytes programs/develop/oberon07/Docs/About1251.txt | 18 +- programs/develop/oberon07/Docs/About866.txt | 18 +- .../develop/oberon07/Lib/KolibriOS/API.ob07 | 47 +- .../develop/oberon07/Lib/KolibriOS/HOST.ob07 | 54 +- .../oberon07/Lib/KolibriOS/NetDevices.ob07 | 107 ++++ .../develop/oberon07/Lib/KolibriOS/RTL.ob07 | 35 +- .../develop/oberon07/Lib/Linux32/API.ob07 | 51 +- .../develop/oberon07/Lib/Linux32/RTL.ob07 | 37 +- .../develop/oberon07/Lib/Windows32/API.ob07 | 8 +- .../develop/oberon07/Lib/Windows32/HOST.ob07 | 14 +- .../develop/oberon07/Lib/Windows32/RTL.ob07 | 42 +- .../develop/oberon07/Source/Compiler.ob07 | 479 ++++++++++-------- programs/develop/oberon07/Source/DECL.ob07 | 288 ++++++----- programs/develop/oberon07/Source/ERRORS.ob07 | 4 +- programs/develop/oberon07/Source/UTILS.ob07 | 22 +- programs/develop/oberon07/Source/X86.ob07 | 12 +- 17 files changed, 698 insertions(+), 538 deletions(-) create mode 100644 programs/develop/oberon07/Lib/KolibriOS/NetDevices.ob07 diff --git a/programs/develop/oberon07/Compiler.kex b/programs/develop/oberon07/Compiler.kex index fb467c115a9cd3d773951edf38a02553f017a53c..5e9d655ecc4add336ed6b579720a412e96d7de61 100644 GIT binary patch literal 34594 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 literal 34369 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 RVT44>W|y%PpQ;f600Nci1dsp# diff --git a/programs/develop/oberon07/Docs/About1251.txt b/programs/develop/oberon07/Docs/About1251.txt index 4d530cfc06..e18eda5e1b 100644 --- a/programs/develop/oberon07/Docs/About1251.txt +++ b/programs/develop/oberon07/Docs/About1251.txt @@ -30,7 +30,6 @@ . (Windows, KolibriOS), (Linux). 2. Lib - -3. Source - ------------------------------------------------------------------------------ @@ -45,6 +44,8 @@ 7. DIV MOD 8. ( "//") 9. ARRAY RECORD ( ) +10. - +11. (TYPE A = B) ------------------------------------------------------------------------------ @@ -93,7 +94,7 @@ "" PROCEDURE GET(a: INTEGER; - VAR v: , PROCEDURE, POINTER) + VAR v: , PROCEDURE, POINTER) v := [a] PROCEDURE PUT(a: INTEGER; x: , PROCEDURE, POINTER) @@ -103,6 +104,11 @@ n Source Dest, Source Dest + PROCEDURE COPY(VAR Source: ; VAR Dest: ; n: INTEGER) + n Source Dest. + + SYSTEM.MOVE(SYSTEM.ADR(Source), SYSTEM.ADR(Dest), n) + PROCEDURE CODE(s: ARRAY OF CHAR) s - @@ -198,6 +204,12 @@ Oberon- LSR(x, n: INTEGER): INTEGER x n . + MIN(a, b: INTEGER): INTEGER + . + + MAX(a, b: INTEGER): INTEGER + . + BITS(x: INTEGER): SET x SET. . @@ -853,4 +865,6 @@ MODULE kfonts - MODULE RasterWorks - Rasterworks.obj ------------------------------------------------------------------------------ MODULE libimg - libimg.obj +------------------------------------------------------------------------------ +MODULE NetDevices - .74 ( ) ------------------------------------------------------------------------------ \ No newline at end of file diff --git a/programs/develop/oberon07/Docs/About866.txt b/programs/develop/oberon07/Docs/About866.txt index b2b16829d8..236c6ae047 100644 --- a/programs/develop/oberon07/Docs/About866.txt +++ b/programs/develop/oberon07/Docs/About866.txt @@ -30,7 +30,6 @@ ।. 饭 뢮 ᮫ (Windows, KolibriOS), ନ (Linux). 2. Lib - ⥪ 㫥 -3. Source - 室 ------------------------------------------------------------------------------ ⫨ ਣ @@ -45,6 +44,8 @@ 7. ⨪ DIV MOD 筥 ⥫ ᥫ 8. ਨ (稭 ᨬ "//") 9. 襭 ᯮ ६ ⨯ ARRAY RECORD (⮫쪮 ⥭) +10. 襭 ᫥ ⨯-㪠⥫ +11. ᥢ ⨯ (TYPE A = B) ------------------------------------------------------------------------------ ᮡ ॠ樨 @@ -93,7 +94,7 @@ 頥 ᯥ樠쭮 ⢥ 祭 "᪮筮" PROCEDURE GET(a: INTEGER; - VAR v:  ᭮ ⨯, PROCEDURE, POINTER) + VAR v:  ᭮ ⨯, PROCEDURE, POINTER) v := [a] PROCEDURE PUT(a: INTEGER; x:  ᭮ ⨯, PROCEDURE, POINTER) @@ -103,6 +104,11 @@ n Source Dest, Source Dest ४뢠 + PROCEDURE COPY(VAR Source:  ⨯; VAR Dest:  ⨯; n: INTEGER) + n Source Dest. + ⭮ + SYSTEM.MOVE(SYSTEM.ADR(Source), SYSTEM.ADR(Dest), n) + PROCEDURE CODE(s: ARRAY OF CHAR) ⠢ 設 s - ப ⠭ ⭠ @@ -198,6 +204,12 @@ Oberon-ॠ LSR(x, n: INTEGER): INTEGER ᪨ ᤢ x n ࠢ. + MIN(a, b: INTEGER): INTEGER + 祭. + + MAX(a, b: INTEGER): INTEGER + ᨬ 祭. + BITS(x: INTEGER): SET x 祭 ⨯ SET. 믮 ⠯ 樨. @@ -853,4 +865,6 @@ MODULE kfonts - ࠡ MODULE RasterWorks - ⪠ ⥪ Rasterworks.obj ------------------------------------------------------------------------------ MODULE libimg - ⪠ ⥪ libimg.obj +------------------------------------------------------------------------------ +MODULE NetDevices - ⪠ .74 (ࠡ ⥢묨 ன⢠) ------------------------------------------------------------------------------ \ No newline at end of file diff --git a/programs/develop/oberon07/Lib/KolibriOS/API.ob07 b/programs/develop/oberon07/Lib/KolibriOS/API.ob07 index 404d3ac6c1..d68a10d775 100644 --- a/programs/develop/oberon07/Lib/KolibriOS/API.ob07 +++ b/programs/develop/oberon07/Lib/KolibriOS/API.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2017 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -107,34 +107,34 @@ BEGIN ELSE temp := 0; IF heap + size >= endheap THEN - IF sysfunc2(18, 16) > ASR(HEAP_SIZE, 10) THEN - temp := sysfunc3(68, 12, HEAP_SIZE) - ELSE - temp := 0 - END; - IF temp # 0 THEN - mem_commit(temp, HEAP_SIZE); - heap := temp; - endheap := heap + HEAP_SIZE - ELSE - temp := -1 - END + IF sysfunc2(18, 16) > ASR(HEAP_SIZE, 10) THEN + temp := sysfunc3(68, 12, HEAP_SIZE) + ELSE + temp := 0 + END; + IF temp # 0 THEN + mem_commit(temp, HEAP_SIZE); + heap := temp; + endheap := heap + HEAP_SIZE + ELSE + temp := -1 + END END; IF (heap # 0) & (temp # -1) THEN - sys.PUT(heap, size); - res := heap + 4; - heap := heap + size + sys.PUT(heap, size); + res := heap + 4; + heap := heap + size ELSE - res := 0 + res := 0 END END ELSE IF sysfunc2(18, 16) > ASR(size, 10) THEN res := sysfunc3(68, 12, size); IF res # 0 THEN - mem_commit(res, size); - sys.PUT(res, size); - INC(res, 4) + mem_commit(res, size); + sys.PUT(res, size); + INC(res, 4) END ELSE res := 0 @@ -166,6 +166,11 @@ BEGIN p1 := sysfunc1(-1) END ExitProcess; +PROCEDURE ExitThread*(p1: INTEGER); +BEGIN + p1 := sysfunc1(-1) +END ExitThread; + PROCEDURE OutChar(c: CHAR); VAR res: INTEGER; BEGIN @@ -181,7 +186,7 @@ BEGIN REPEAT sys.GET(lpCaption, c); IF c # 0X THEN - OutChar(c) + OutChar(c) END; INC(lpCaption) UNTIL c = 0X; diff --git a/programs/develop/oberon07/Lib/KolibriOS/HOST.ob07 b/programs/develop/oberon07/Lib/KolibriOS/HOST.ob07 index 8e7d1d763d..012c4b40d6 100644 --- a/programs/develop/oberon07/Lib/KolibriOS/HOST.ob07 +++ b/programs/develop/oberon07/Lib/KolibriOS/HOST.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2017 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -35,46 +35,12 @@ TYPE VAR - con_init : PROCEDURE [stdcall] (wnd_width, wnd_height, scr_width, scr_height, title: INTEGER); - con_exit : PROCEDURE [stdcall] (bCloseWindow: BOOLEAN); - con_write_asciiz : PROCEDURE [stdcall] (string: INTEGER); + con_init : PROCEDURE [stdcall] (wnd_width, wnd_height, scr_width, scr_height, title: INTEGER); + con_exit : PROCEDURE [stdcall] (bCloseWindow: BOOLEAN); + con_write_asciiz : PROCEDURE [stdcall] (string: INTEGER); fsize, sec*, dsec*: INTEGER; -PROCEDURE [stdcall] sysfunc1(arg1: INTEGER): INTEGER; -BEGIN - sys.CODE("8B4508"); (* mov eax, [ebp + 08h] *) - sys.CODE("CD40"); (* int 40h *) - sys.CODE("C9"); (* leave *) - sys.CODE("C20400"); (* ret 04h *) - RETURN 0 -END sysfunc1; - -PROCEDURE [stdcall] sysfunc2(arg1, arg2: INTEGER): INTEGER; -BEGIN - sys.CODE("53"); (* push ebx *) - sys.CODE("8B4508"); (* mov eax, [ebp + 08h] *) - sys.CODE("8B5D0C"); (* mov ebx, [ebp + 0Ch] *) - sys.CODE("CD40"); (* int 40h *) - sys.CODE("5B"); (* pop ebx *) - sys.CODE("C9"); (* leave *) - sys.CODE("C20800"); (* ret 08h *) - RETURN 0 -END sysfunc2; - -PROCEDURE [stdcall] sysfunc3(arg1, arg2, arg3: INTEGER): INTEGER; -BEGIN - sys.CODE("53"); (* push ebx *) - sys.CODE("8B4508"); (* mov eax, [ebp + 08h] *) - sys.CODE("8B5D0C"); (* mov ebx, [ebp + 0Ch] *) - sys.CODE("8B4D10"); (* mov ecx, [ebp + 10h] *) - sys.CODE("CD40"); (* int 40h *) - sys.CODE("5B"); (* pop ebx *) - sys.CODE("C9"); (* leave *) - sys.CODE("C20C00"); (* ret 0Ch *) - RETURN 0 -END sysfunc3; - PROCEDURE [stdcall] sysfunc22(arg1, arg2: INTEGER; VAR res2: INTEGER): INTEGER; BEGIN sys.CODE("53"); (* push ebx *) @@ -122,7 +88,7 @@ END GetProcAdr; PROCEDURE Time*(VAR sec, dsec: INTEGER); VAR t: INTEGER; BEGIN - t := sysfunc2(26, 9); + t := API.sysfunc2(26, 9); sec := t DIV 100; dsec := t MOD 100 END Time; @@ -139,10 +105,10 @@ VAR Lib: INTEGER; BEGIN Time(sec, dsec); - Lib := sysfunc3(68, 19, sys.ADR("/rd/1/lib/console.obj")); + Lib := API.sysfunc3(68, 19, sys.ADR("/rd/1/lib/console.obj")); IF Lib # 0 THEN - GetProc(sys.ADR(con_init), "con_init"); - GetProc(sys.ADR(con_exit), "con_exit"); + GetProc(sys.ADR(con_init), "con_init"); + GetProc(sys.ADR(con_exit), "con_exit"); GetProc(sys.ADR(con_write_asciiz), "con_write_asciiz"); IF con_init # NIL THEN con_init(-1, -1, -1, -1, sys.ADR("Oberon-07/11 for KolibriOS")) @@ -155,7 +121,7 @@ BEGIN IF con_exit # NIL THEN con_exit(FALSE) END; - n := sysfunc1(-1) + API.ExitProcess(0) END ExitProcess; PROCEDURE GetCommandLine*(): INTEGER; @@ -173,7 +139,7 @@ BEGIN END GetName; PROCEDURE malloc*(size: INTEGER): INTEGER; - RETURN sysfunc3(68, 12, size) + RETURN API.sysfunc3(68, 12, size) END malloc; PROCEDURE CloseFile*(hObject: INTEGER); diff --git a/programs/develop/oberon07/Lib/KolibriOS/NetDevices.ob07 b/programs/develop/oberon07/Lib/KolibriOS/NetDevices.ob07 new file mode 100644 index 0000000000..9ed2bfacdb --- /dev/null +++ b/programs/develop/oberon07/Lib/KolibriOS/NetDevices.ob07 @@ -0,0 +1,107 @@ +(* + Copyright 2017 Anton Krotov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*) + +MODULE NetDevices; + +IMPORT sys := SYSTEM, K := KOSAPI; + + +CONST + + //net devices types + + LOOPBACK* = 0; + ETH* = 1; + SLIP* = 2; + + //Link status + + LINK_DOWN* = 0; + LINK_UNKNOWN* = 1; + LINK_FD* = 2; //full duplex flag + LINK_10M* = 4; + LINK_100M* = 8; + LINK_1G* = 12; + + +TYPE + + DEVICENAME* = ARRAY 64 OF CHAR; + + +PROCEDURE Number* (): INTEGER; + RETURN K.sysfunc2(74, -1) +END Number; + + +PROCEDURE Type* (num: INTEGER): INTEGER; + RETURN K.sysfunc2(74, num * 256) +END Type; + + +PROCEDURE Name* (num: INTEGER; VAR name: DEVICENAME): BOOLEAN; +VAR err: BOOLEAN; +BEGIN + err := K.sysfunc3(74, num * 256 + 1, sys.ADR(name[0])) = -1; + IF err THEN + name := "" + END + RETURN ~err +END Name; + + +PROCEDURE Reset* (num: INTEGER): BOOLEAN; + RETURN K.sysfunc2(74, num * 256 + 2) # -1 +END Reset; + + +PROCEDURE Stop* (num: INTEGER): BOOLEAN; + RETURN K.sysfunc2(74, num * 256 + 3) # -1 +END Stop; + + +PROCEDURE Pointer* (num: INTEGER): INTEGER; + RETURN K.sysfunc2(74, num * 256 + 4) +END Pointer; + + +PROCEDURE SentPackets* (num: INTEGER): INTEGER; + RETURN K.sysfunc2(74, num * 256 + 6) +END SentPackets; + + +PROCEDURE ReceivedPackets* (num: INTEGER): INTEGER; + RETURN K.sysfunc2(74, num * 256 + 7) +END ReceivedPackets; + + +PROCEDURE SentBytes* (num: INTEGER; VAR hValue: INTEGER): INTEGER; + RETURN K.sysfunc22(74, num * 256 + 8, hValue) +END SentBytes; + + +PROCEDURE ReceivedBytes* (num: INTEGER; VAR hValue: INTEGER): INTEGER; + RETURN K.sysfunc22(74, num * 256 + 9, hValue) +END ReceivedBytes; + + +PROCEDURE LinkStatus* (num: INTEGER): INTEGER; + RETURN K.sysfunc2(74, num * 256 + 10) +END LinkStatus; + + +END NetDevices. \ No newline at end of file diff --git a/programs/develop/oberon07/Lib/KolibriOS/RTL.ob07 b/programs/develop/oberon07/Lib/KolibriOS/RTL.ob07 index 8ce9249a8a..1a2a314fd7 100644 --- a/programs/develop/oberon07/Lib/KolibriOS/RTL.ob07 +++ b/programs/develop/oberon07/Lib/KolibriOS/RTL.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2017 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -28,6 +28,7 @@ TYPE VAR SelfName, rtab: INTEGER; CloseProc: PROC; + init: BOOLEAN; PROCEDURE [stdcall] _halt*(n: INTEGER); BEGIN @@ -116,26 +117,18 @@ BEGIN END END _arrayrot; -PROCEDURE Min(a, b: INTEGER): INTEGER; -BEGIN - IF a > b THEN - a := b - END - RETURN a -END Min; - PROCEDURE [stdcall] _length*(s: ARRAY OF CHAR): INTEGER; BEGIN sys.CODE("8B4508"); // mov eax, [ebp + 08h] sys.CODE("8B4D0C"); // mov ecx, [ebp + 0Ch] sys.CODE("48"); // dec eax - // L1: + // L1: sys.CODE("40"); // inc eax sys.CODE("803800"); // cmp byte ptr [eax], 0 sys.CODE("7403"); // jz L2 sys.CODE("E2F8"); // loop L1 sys.CODE("40"); // inc eax - // L2: + // L2: sys.CODE("2B4508"); // sub eax, [ebp + 08h] sys.CODE("C9"); // leave sys.CODE("C20800"); // ret 08h @@ -144,7 +137,7 @@ END _length; PROCEDURE [stdcall] _strcopy*(b, blen, a, alen: INTEGER); BEGIN - _savearr(Min(alen, blen), a, b); + _savearr(MIN(alen, blen), a, b); IF blen > alen THEN sys.PUT(b + alen, 0X) END @@ -153,7 +146,7 @@ END _strcopy; PROCEDURE [stdcall] _strcmp*(op: INTEGER; b, a: ARRAY OF CHAR): BOOLEAN; VAR i: INTEGER; Res: BOOLEAN; BEGIN - i := API.strncmp(sys.ADR(a), sys.ADR(b), Min(LEN(a), LEN(b))); + i := API.strncmp(sys.ADR(a), sys.ADR(b), MIN(LEN(a), LEN(b))); IF i = 0 THEN i := _length(a) - _length(b) END; @@ -252,7 +245,8 @@ BEGIN Int(code, int); StrAppend(int) END; - API.DebugMsg(sys.ADR(msg), SelfName) + API.DebugMsg(sys.ADR(msg), SelfName); + API.ExitThread(0) END _assrt; PROCEDURE [stdcall] _close*; @@ -264,11 +258,14 @@ END _close; PROCEDURE [stdcall] _init*(self, rec, gsize, gadr, esp: INTEGER); BEGIN - API.zeromem(gsize, gadr); - API.init(esp); - SelfName := self; - rtab := rec; - CloseProc := NIL + IF ~init THEN + API.zeromem(gsize, gadr); + init := TRUE; + API.init(esp); + SelfName := self; + rtab := rec; + CloseProc := NIL + END END _init; PROCEDURE SetClose*(proc: PROC); diff --git a/programs/develop/oberon07/Lib/Linux32/API.ob07 b/programs/develop/oberon07/Lib/Linux32/API.ob07 index 6ef5bd5f5a..f0ec129793 100644 --- a/programs/develop/oberon07/Lib/Linux32/API.ob07 +++ b/programs/develop/oberon07/Lib/Linux32/API.ob07 @@ -1,4 +1,4 @@ -(* +(* Copyright 2016 Anton Krotov This program is free software: you can redistribute it and/or modify @@ -27,22 +27,22 @@ VAR Param*: INTEGER; - sec* : INTEGER; - dsec* : INTEGER; - stdin* : INTEGER; - stdout* : INTEGER; - stderr* : INTEGER; - dlopen* : PROCEDURE [cdecl] (filename, flag: INTEGER): INTEGER; - dlsym* : PROCEDURE [cdecl] (handle, symbol: INTEGER): INTEGER; - _malloc* : PROCEDURE [cdecl] (size: INTEGER): INTEGER; - free* : PROCEDURE [cdecl] (ptr: INTEGER); - fopen* : PROCEDURE [cdecl] (fname, fmode: INTEGER): INTEGER; + sec* : INTEGER; + dsec* : INTEGER; + stdin* : INTEGER; + stdout* : INTEGER; + stderr* : INTEGER; + dlopen* : PROCEDURE [cdecl] (filename, flag: INTEGER): INTEGER; + dlsym* : PROCEDURE [cdecl] (handle, symbol: INTEGER): INTEGER; + _malloc* : PROCEDURE [cdecl] (size: INTEGER): INTEGER; + free* : PROCEDURE [cdecl] (ptr: INTEGER); + fopen* : PROCEDURE [cdecl] (fname, fmode: INTEGER): INTEGER; fclose*, ftell* : PROCEDURE [cdecl] (file: INTEGER): INTEGER; fwrite*, fread* : PROCEDURE [cdecl] (buffer, bytes, blocks, file: INTEGER): INTEGER; - fseek* : PROCEDURE [cdecl] (file, offset, origin: INTEGER): INTEGER; - exit* : PROCEDURE [cdecl] (code: INTEGER); - strncmp* : PROCEDURE [cdecl] (str1, str2, n: INTEGER): INTEGER; - strlen* : PROCEDURE [cdecl] (str: INTEGER): INTEGER; + fseek* : PROCEDURE [cdecl] (file, offset, origin: INTEGER): INTEGER; + exit* : PROCEDURE [cdecl] (code: INTEGER); + strncmp* : PROCEDURE [cdecl] (str1, str2, n: INTEGER): INTEGER; + strlen* : PROCEDURE [cdecl] (str: INTEGER): INTEGER; clock_gettime* : PROCEDURE [cdecl] (clock_id: INTEGER; VAR tp: TP): INTEGER; PROCEDURE [stdcall] zeromem* (size, adr: INTEGER); @@ -103,6 +103,11 @@ BEGIN exit(code) END ExitProcess; +PROCEDURE ExitThread* (code: INTEGER); +BEGIN + exit(code) +END ExitThread; + PROCEDURE GetProc(name: ARRAY OF CHAR; hMOD, adr: INTEGER); VAR H: INTEGER; BEGIN @@ -116,19 +121,19 @@ VAR lib, proc: INTEGER; BEGIN Param := esp; sys.MOVE(Param + 12, sys.ADR(dlopen), 4); - sys.MOVE(Param + 16, sys.ADR(dlsym), 4); - sys.MOVE(Param + 20, sys.ADR(exit), 4); - sys.MOVE(Param + 24, sys.ADR(stdin), 4); + sys.MOVE(Param + 16, sys.ADR(dlsym), 4); + sys.MOVE(Param + 20, sys.ADR(exit), 4); + sys.MOVE(Param + 24, sys.ADR(stdin), 4); sys.MOVE(Param + 28, sys.ADR(stdout), 4); sys.MOVE(Param + 32, sys.ADR(stderr), 4); sys.MOVE(Param + 36, sys.ADR(_malloc), 4); - sys.MOVE(Param + 40, sys.ADR(free), 4); - sys.MOVE(Param + 44, sys.ADR(fopen), 4); + sys.MOVE(Param + 40, sys.ADR(free), 4); + sys.MOVE(Param + 44, sys.ADR(fopen), 4); sys.MOVE(Param + 48, sys.ADR(fclose), 4); sys.MOVE(Param + 52, sys.ADR(fwrite), 4); - sys.MOVE(Param + 56, sys.ADR(fread), 4); - sys.MOVE(Param + 60, sys.ADR(fseek), 4); - sys.MOVE(Param + 64, sys.ADR(ftell), 4); + sys.MOVE(Param + 56, sys.ADR(fread), 4); + sys.MOVE(Param + 60, sys.ADR(fseek), 4); + sys.MOVE(Param + 64, sys.ADR(ftell), 4); lib := dlopen(sys.ADR("libc.so.6"), 1); ASSERT(lib # 0); diff --git a/programs/develop/oberon07/Lib/Linux32/RTL.ob07 b/programs/develop/oberon07/Lib/Linux32/RTL.ob07 index a6a051ec73..96eb3f82b8 100644 --- a/programs/develop/oberon07/Lib/Linux32/RTL.ob07 +++ b/programs/develop/oberon07/Lib/Linux32/RTL.ob07 @@ -1,5 +1,5 @@ -(* - Copyright 2016 Anton Krotov +(* + Copyright 2016, 2017 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -28,6 +28,7 @@ TYPE VAR SelfName, rtab: INTEGER; CloseProc: PROC; + init: BOOLEAN; PROCEDURE [stdcall] _halt*(n: INTEGER); BEGIN @@ -116,26 +117,18 @@ BEGIN END END _arrayrot; -PROCEDURE Min(a, b: INTEGER): INTEGER; -BEGIN - IF a > b THEN - a := b - END - RETURN a -END Min; - PROCEDURE [stdcall] _length*(s: ARRAY OF CHAR): INTEGER; BEGIN sys.CODE("8B4508"); // mov eax, [ebp + 08h] sys.CODE("8B4D0C"); // mov ecx, [ebp + 0Ch] sys.CODE("48"); // dec eax - // L1: + // L1: sys.CODE("40"); // inc eax sys.CODE("803800"); // cmp byte ptr [eax], 0 sys.CODE("7403"); // jz L2 sys.CODE("E2F8"); // loop L1 sys.CODE("40"); // inc eax - // L2: + // L2: sys.CODE("2B4508"); // sub eax, [ebp + 08h] sys.CODE("C9"); // leave sys.CODE("C20800"); // ret 08h @@ -144,7 +137,7 @@ END _length; PROCEDURE [stdcall] _strcopy*(b, blen, a, alen: INTEGER); BEGIN - _savearr(Min(alen, blen), a, b); + _savearr(MIN(alen, blen), a, b); IF blen > alen THEN sys.PUT(b + alen, 0X) END @@ -153,7 +146,7 @@ END _strcopy; PROCEDURE [stdcall] _strcmp*(op: INTEGER; b, a: ARRAY OF CHAR): BOOLEAN; VAR i: INTEGER; Res: BOOLEAN; BEGIN - i := API.strncmp(sys.ADR(a), sys.ADR(b), Min(LEN(a), LEN(b))); + i := API.strncmp(sys.ADR(a), sys.ADR(b), MIN(LEN(a), LEN(b))); IF i = 0 THEN i := _length(a) - _length(b) END; @@ -252,7 +245,8 @@ BEGIN Int(code, int); StrAppend(int) END; - API.DebugMsg(sys.ADR(msg), SelfName) + API.DebugMsg(sys.ADR(msg), SelfName); + API.ExitThread(0) END _assrt; PROCEDURE [stdcall] _close*; @@ -264,11 +258,14 @@ END _close; PROCEDURE [stdcall] _init*(self, rec, gsize, gadr, esp: INTEGER); BEGIN - API.zeromem(gsize, gadr); - API.init(esp); - SelfName := self; - rtab := rec; - CloseProc := NIL; + IF ~init THEN + API.zeromem(gsize, gadr); + init := TRUE; + API.init(esp); + SelfName := self; + rtab := rec; + CloseProc := NIL + END END _init; PROCEDURE SetClose*(proc: PROC); diff --git a/programs/develop/oberon07/Lib/Windows32/API.ob07 b/programs/develop/oberon07/Lib/Windows32/API.ob07 index a6aadc73b0..d06ecf3165 100644 --- a/programs/develop/oberon07/Lib/Windows32/API.ob07 +++ b/programs/develop/oberon07/Lib/Windows32/API.ob07 @@ -1,5 +1,5 @@ -(* - Copyright 2016 Anton Krotov +(* + Copyright 2016, 2017 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -25,6 +25,8 @@ VAR Free*: PROCEDURE [winapi] (hMem: INTEGER): INTEGER; MessageBoxA*: PROCEDURE [winapi] (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; ExitProcess*: PROCEDURE [winapi] (code: INTEGER); + ExitThread*: PROCEDURE [winapi] (code: INTEGER); + GetCurrentThreadId*: PROCEDURE [winapi] (): INTEGER; strncmp*: PROCEDURE [cdecl] (a, b, n: INTEGER): INTEGER; GetProcAddress*: PROCEDURE [winapi] (hModule, name: INTEGER): INTEGER; @@ -62,6 +64,8 @@ BEGIN lib := LoadLibraryA(sys.ADR("kernel32.dll")); GetProc("ExitProcess", lib, sys.ADR(ExitProcess)); + GetProc("ExitThread", lib, sys.ADR(ExitThread)); + GetProc("GetCurrentThreadId", lib, sys.ADR(GetCurrentThreadId)); GetProc("GlobalAlloc", lib, sys.ADR(Alloc)); GetProc("GlobalFree", lib, sys.ADR(Free)); diff --git a/programs/develop/oberon07/Lib/Windows32/HOST.ob07 b/programs/develop/oberon07/Lib/Windows32/HOST.ob07 index bc0788f4a0..3bfd54cbb4 100644 --- a/programs/develop/oberon07/Lib/Windows32/HOST.ob07 +++ b/programs/develop/oberon07/Lib/Windows32/HOST.ob07 @@ -1,5 +1,5 @@ -(* - Copyright 2016 Anton Krotov +(* + Copyright 2016, 2017 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -49,7 +49,6 @@ VAR ReadFile, WriteFile: PROCEDURE [winapi] (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped: INTEGER): INTEGER; GetCommandLine*: PROCEDURE [winapi] (): INTEGER; GetTickCount: PROCEDURE [winapi] (): INTEGER; - Alloc: PROCEDURE [winapi] (uFlags, dwBytes: INTEGER): INTEGER; ExitProcess*: PROCEDURE [winapi] (code: INTEGER); SetFilePointer: PROCEDURE [winapi] (hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod: INTEGER): INTEGER; @@ -71,7 +70,7 @@ BEGIN END OutString; PROCEDURE CreateFile* (FName: ARRAY OF CHAR): INTEGER; -VAR res: INTEGER; +VAR res: INTEGER; BEGIN res := _CreateFile(sys.ADR(FName[0]), 0C0000000H, 0, 0, 2, 80H, 0); IF res = -1 THEN @@ -112,12 +111,12 @@ BEGIN END Time; PROCEDURE malloc*(size: INTEGER): INTEGER; - RETURN Alloc(64, size) + RETURN API.Alloc(64, size) END malloc; PROCEDURE init*; VAR lib: INTEGER; -BEGIN +BEGIN lib := API.LoadLibraryA(sys.ADR("kernel32.dll")); GetProc("GetTickCount", lib, sys.ADR(GetTickCount)); Time(sec, dsec); @@ -128,9 +127,8 @@ BEGIN GetProc("ReadFile", lib, sys.ADR(ReadFile)); GetProc("WriteFile", lib, sys.ADR(WriteFile)); GetProc("GetCommandLineA", lib, sys.ADR(GetCommandLine)); - GetProc("ExitProcess", lib, sys.ADR(ExitProcess)); - GetProc("GlobalAlloc", lib, sys.ADR(Alloc)); GetProc("SetFilePointer", lib, sys.ADR(SetFilePointer)); + ExitProcess := API.ExitProcess; hConsoleOutput := GetStdHandle(-11) END init; diff --git a/programs/develop/oberon07/Lib/Windows32/RTL.ob07 b/programs/develop/oberon07/Lib/Windows32/RTL.ob07 index a6a051ec73..23aeacde6a 100644 --- a/programs/develop/oberon07/Lib/Windows32/RTL.ob07 +++ b/programs/develop/oberon07/Lib/Windows32/RTL.ob07 @@ -1,5 +1,5 @@ -(* - Copyright 2016 Anton Krotov +(* + Copyright 2016, 2017 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -28,6 +28,8 @@ TYPE VAR SelfName, rtab: INTEGER; CloseProc: PROC; + init: BOOLEAN; + main_thread_id: INTEGER; PROCEDURE [stdcall] _halt*(n: INTEGER); BEGIN @@ -116,26 +118,18 @@ BEGIN END END _arrayrot; -PROCEDURE Min(a, b: INTEGER): INTEGER; -BEGIN - IF a > b THEN - a := b - END - RETURN a -END Min; - PROCEDURE [stdcall] _length*(s: ARRAY OF CHAR): INTEGER; BEGIN sys.CODE("8B4508"); // mov eax, [ebp + 08h] sys.CODE("8B4D0C"); // mov ecx, [ebp + 0Ch] sys.CODE("48"); // dec eax - // L1: + // L1: sys.CODE("40"); // inc eax sys.CODE("803800"); // cmp byte ptr [eax], 0 sys.CODE("7403"); // jz L2 sys.CODE("E2F8"); // loop L1 sys.CODE("40"); // inc eax - // L2: + // L2: sys.CODE("2B4508"); // sub eax, [ebp + 08h] sys.CODE("C9"); // leave sys.CODE("C20800"); // ret 08h @@ -144,7 +138,7 @@ END _length; PROCEDURE [stdcall] _strcopy*(b, blen, a, alen: INTEGER); BEGIN - _savearr(Min(alen, blen), a, b); + _savearr(MIN(alen, blen), a, b); IF blen > alen THEN sys.PUT(b + alen, 0X) END @@ -153,7 +147,7 @@ END _strcopy; PROCEDURE [stdcall] _strcmp*(op: INTEGER; b, a: ARRAY OF CHAR): BOOLEAN; VAR i: INTEGER; Res: BOOLEAN; BEGIN - i := API.strncmp(sys.ADR(a), sys.ADR(b), Min(LEN(a), LEN(b))); + i := API.strncmp(sys.ADR(a), sys.ADR(b), MIN(LEN(a), LEN(b))); IF i = 0 THEN i := _length(a) - _length(b) END; @@ -252,7 +246,11 @@ BEGIN Int(code, int); StrAppend(int) END; - API.DebugMsg(sys.ADR(msg), SelfName) + IF API.GetCurrentThreadId() = main_thread_id THEN + API.ExitProcess(0) + ELSE + API.ExitThread(0) + END END _assrt; PROCEDURE [stdcall] _close*; @@ -264,11 +262,15 @@ END _close; PROCEDURE [stdcall] _init*(self, rec, gsize, gadr, esp: INTEGER); BEGIN - API.zeromem(gsize, gadr); - API.init(esp); - SelfName := self; - rtab := rec; - CloseProc := NIL; + IF ~init THEN + API.zeromem(gsize, gadr); + init := TRUE; + API.init(esp); + main_thread_id := API.GetCurrentThreadId(); + SelfName := self; + rtab := rec; + CloseProc := NIL + END END _init; PROCEDURE SetClose*(proc: PROC); diff --git a/programs/develop/oberon07/Source/Compiler.ob07 b/programs/develop/oberon07/Source/Compiler.ob07 index 452ba36a2e..0c6f6f6437 100644 --- a/programs/develop/oberon07/Source/Compiler.ob07 +++ b/programs/develop/oberon07/Source/Compiler.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2017 Anton Krotov This file is part of Compiler. @@ -52,10 +52,10 @@ CONST stABS = 1; stODD = 2; stLEN = 3; stLSL = 4; stASR = 5; stROR = 6; stFLOOR = 7; stFLT = 8; stORD = 9; stCHR = 10; stLONG = 11; stSHORT = 12; stINC = 13; stDEC = 14; stINCL = 15; stEXCL = 16; stCOPY = 17; stNEW = 18; stASSERT = 19; stPACK = 20; stUNPK = 21; stDISPOSE = 22; - stBITS = 23; stLSR = 24; stLENGTH = 25; + stBITS = 23; stLSR = 24; stLENGTH = 25; stMIN = 26; stMAX = 27; sysADR = 101; sysSIZE = 102; sysINF = 103; sysGET = 104; sysPUT = 105; - sysCODE = 106; sysTYPEID = 107; sysMOVE = 108; + sysCODE = 106; sysTYPEID = 107; sysMOVE = 108; sysCOPY = 109; TYPE @@ -198,11 +198,11 @@ BEGIN loc := id.Offset ELSIF (id.VarKind = DECL.paramvar) OR (id.T.tType IN TSTRUCT) THEN IF DECL.Dim(e.T) > 0 THEN - n := DECL.Dim(e.T); - FOR i := n TO 1 BY -1 DO - X86.LocalAdr(id.Offset + i * 4, bases); - X86.Load(TINTEGER) - END + n := DECL.Dim(e.T); + FOR i := n TO 1 BY -1 DO + X86.LocalAdr(id.Offset + i * 4, bases); + X86.Load(TINTEGER) + END END; X86.LocalAdr(id.Offset, bases); X86.Load(TINTEGER) @@ -219,9 +219,9 @@ BEGIN ELSIF id.T.tType = TSTRING THEN s := DECL.GetString(e.Value); IF s.Len = 1 THEN - X86.PushConst(ORD(s.Str[0])) + X86.PushConst(ORD(s.Str[0])) ELSE - X86.PushInt(s.Number) + X86.PushInt(s.Number) END END |IDPROC: @@ -249,32 +249,32 @@ BEGIN e.deref := FALSE; Assert2(e.T.tType IN TOBJECT, 105); IF e.T.tType = TPOINTER THEN - e.Read := FALSE; - LoadVar; - e.T := e.T.Base; - X86.Load(TINTEGER); - IF ~guard THEN - X86.CheckNIL - END + e.Read := FALSE; + LoadVar; + e.T := e.T.Base; + X86.Load(TINTEGER); + IF ~guard THEN + X86.CheckNIL + END END; NextCheck(lxIDENT); Coord(coord); name := SCAN.id; T := e.T; REPEAT - f := DECL.GetField(T, name); - T := T.Base + f := DECL.GetField(T, name); + T := T.Base UNTIL (f # NIL) OR (T = NIL); Assert(f # NIL, coord, 99); IF f.Unit # DECL.unit THEN - Assert(f.Export, coord, 99) + Assert(f.Export, coord, 99) END; IF glob # -1 THEN - glob := glob + f.Offset + glob := glob + f.Offset ELSIF loc # -1 THEN - loc := loc + f.Offset + loc := loc + f.Offset ELSE - X86.Field(f.Offset) + X86.Field(f.Offset) END; e.T := f.T; e.vparam := FALSE; @@ -283,29 +283,29 @@ BEGIN |lxLSquare: LoadVar; REPEAT - Assert2(e.T.tType = TARRAY, 102); - NextCoord(coord); - pExpr(e1); - IntType(e1.T, coord); - Load(e1); - IF e.T.Len = 0 THEN - BaseT := DECL.OpenBase(e.T); - X86.PushConst(BaseT.Size); - X86.OpenIdx(DECL.Dim(e.T)) - ELSE - IF e1.eType = eCONST THEN - idx := FLOOR(e1.Value); - Assert((idx >= 0) & (idx < e.T.Len), coord, 159); - IF e.T.Base.Size # 1 THEN - X86.Drop; - X86.PushConst(e.T.Base.Size * idx) - END; - X86.Idx - ELSE - X86.FixIdx(e.T.Len, e.T.Base.Size) - END - END; - e.T := e.T.Base + Assert2(e.T.tType = TARRAY, 102); + NextCoord(coord); + pExpr(e1); + IntType(e1.T, coord); + Load(e1); + IF e.T.Len = 0 THEN + BaseT := DECL.OpenBase(e.T); + X86.PushConst(BaseT.Size); + X86.OpenIdx(DECL.Dim(e.T)) + ELSE + IF e1.eType = eCONST THEN + idx := FLOOR(e1.Value); + Assert((idx >= 0) & (idx < e.T.Len), coord, 159); + IF e.T.Base.Size # 1 THEN + X86.Drop; + X86.PushConst(e.T.Base.Size * idx) + END; + X86.Idx + ELSE + X86.FixIdx(e.T.Len, e.T.Base.Size) + END + END; + e.T := e.T.Base UNTIL SCAN.tLex # lxComma; Check(lxRSquare); e.vparam := FALSE; @@ -317,7 +317,7 @@ BEGIN e.Read := FALSE; X86.Load(TINTEGER); IF ~guard THEN - X86.CheckNIL + X86.CheckNIL END; e.T := e.T.Base; e.vparam := FALSE; @@ -327,36 +327,36 @@ BEGIN |lxLRound: LoadVar; IF e.T.tType IN TOBJECT THEN - IF e.T.tType = TRECORD THEN - Assert2(e.vparam, 108) - END; - NextCheck(lxIDENT); - Coord(coord); - T := DECL.IdType(coord); - Assert(T # NIL, coord, 42); - IF e.T.tType = TRECORD THEN - Assert(T.tType = TRECORD, coord, 106) - ELSE - Assert(T.tType = TPOINTER, coord, 107) - END; - Assert(BaseOf(e.T, T), coord, 108); - e.T := T; - Check(lxRRound); - Next; - IF e.T.tType = TPOINTER THEN - IF (SCAN.tLex = lxDot) OR (SCAN.tLex = lxCaret) THEN - X86.DupLoadCheck - ELSE - X86.DupLoad - END; - guard := TRUE; - T := T.Base - ELSE - X86.LocalAdr(e.id.Offset, DECL.unit.Level - e.id.Level) - END; - X86.Guard(T.Number, FALSE) + IF e.T.tType = TRECORD THEN + Assert2(e.vparam, 108) + END; + NextCheck(lxIDENT); + Coord(coord); + T := DECL.IdType(coord); + Assert(T # NIL, coord, 42); + IF e.T.tType = TRECORD THEN + Assert(T.tType = TRECORD, coord, 106) + ELSE + Assert(T.tType = TPOINTER, coord, 107) + END; + Assert(BaseOf(e.T, T), coord, 108); + e.T := T; + Check(lxRRound); + Next; + IF e.T.tType = TPOINTER THEN + IF (SCAN.tLex = lxDot) OR (SCAN.tLex = lxCaret) THEN + X86.DupLoadCheck + ELSE + X86.DupLoad + END; + guard := TRUE; + T := T.Base + ELSE + X86.LocalAdr(e.id.Offset, DECL.unit.Level - e.id.Level) + END; + X86.Guard(T.Number, FALSE) ELSE - break := TRUE + break := TRUE END ELSE break := TRUE @@ -393,8 +393,10 @@ BEGIN pExpr(b); IntType(b.T, coord); IF b.eType = eCONST THEN - Assert(ASR(FLOOR(b.Value), 5) = 0, coord, 53); - Assert(a.Value <= b.Value, coord, 54) + Assert(ASR(FLOOR(b.Value), 5) = 0, coord, 53); + IF a.eType = eCONST THEN + Assert(a.Value <= b.Value, coord, 54) + END END; Load(b) ELSE @@ -547,10 +549,10 @@ BEGIN Load(e1); IF e1.eType = eCONST THEN IF e1.T.tType = TSTRING THEN - str := DECL.GetString(e1.Value); - e.Value := LONG(FLT(ORD(str.Str[0]))) + str := DECL.GetString(e1.Value); + e.Value := LONG(FLT(ORD(str.Str[0]))) ELSE - e.Value := e1.Value + e.Value := e1.Value END; e.eType := eCONST END; @@ -606,8 +608,8 @@ BEGIN IF e1.T.tType = TSTRING THEN str := DECL.GetString(e1.Value); IF str.Len = 1 THEN - X86.Mono(str.Number); - X86.StrMono + X86.Mono(str.Number); + X86.StrMono END; e.Value := LONG(FLT(LENGTH(str.Str))); e.eType := eCONST @@ -615,13 +617,39 @@ BEGIN Str(e1); e.T := inttype; X86.StFunc(X86.stLENGTH) + |stMIN, stMAX: + pExpr(e1); + IntType(e1.T, coord); + Load(e1); + Check(lxComma); + NextCoord(coord); + pExpr(e2); + IntType(e2.T, coord); + Load(e2); + IF (e1.eType = eCONST) & (e2.eType = eCONST) THEN + a := FLOOR(e1.Value); + b := FLOOR(e2.Value); + CASE func OF + |stMIN: a := MIN(a, b) + |stMAX: a := MAX(a, b) + ELSE + END; + e.Value := LONG(FLT(a)); + e.eType := eCONST + END; + IF func = stMIN THEN + X86.StFunc(X86.stMIN) + ELSE + X86.StFunc(X86.stMAX) + END; + e.T := inttype |sysADR: Assert((SCAN.tLex = lxIDENT) OR (SCAN.tLex = lxSTRING) OR (SCAN.tLex = lxCHX), coord, 43); IF SCAN.tLex = lxIDENT THEN Designator(e1); Assert((e1.eType = eVAR) OR (e1.eType = ePROC) OR (e1.T = strtype), coord, 43); IF e1.eType = ePROC THEN - X86.PushInt(e1.id.Number) + X86.PushInt(e1.id.Number) END ELSE pFactor(e1) @@ -629,8 +657,8 @@ BEGIN IF e1.T = strtype THEN str := DECL.GetString(e1.Value); IF str.Len = 1 THEN - X86.Drop; - X86.PushInt(str.Number) + X86.Drop; + X86.PushInt(str.Number) END END; e.T := inttype; @@ -645,7 +673,7 @@ BEGIN e.T := inttype; Assert(T.tType IN TOBJECT, coord, 47); IF T.tType = TPOINTER THEN - T := T.Base + T := T.Base END; e.Value := LONG(FLT(T.Number)); X86.PushConst(T.Number) @@ -676,9 +704,9 @@ VAR sp: INTEGER; stk: ARRAY 100, 2 OF DECL.pTYPE; VAR Res: BOOLEAN; BEGIN IF (T1.tType = TARRAY) & (T2.tType = TARRAY) & (T1.Len = 0) & (T2.Len = 0) THEN - Res := TypeComp(T1.Base, T2.Base) + Res := TypeComp(T1.Base, T2.Base) ELSE - Res := ProcTypeComp1(T1, T2) + Res := ProcTypeComp1(T1, T2) END RETURN Res END TypeComp; @@ -689,8 +717,8 @@ VAR sp: INTEGER; stk: ARRAY 100, 2 OF DECL.pTYPE; i := 0; res := FALSE; WHILE (i < sp) & ~res DO - res := ((stk[i][0] = T1) & (stk[i][1] = T2)) OR ((stk[i][0] = T2) & (stk[i][1] = T1)); - INC(i) + res := ((stk[i][0] = T1) & (stk[i][1] = T2)) OR ((stk[i][0] = T2) & (stk[i][1] = T1)); + INC(i) END RETURN res END Check; @@ -703,16 +731,16 @@ VAR sp: INTEGER; stk: ARRAY 100, 2 OF DECL.pTYPE; Res := TRUE ELSE IF (T1.tType = TPROC) & (T2.tType = TPROC) & (T1 # T2) THEN - Res := (T1.Call = T2.Call) & (T1.Fields.Count = T2.Fields.Count) & ProcTypeComp1(T1.Base, T2.Base); - fp := T1.Fields.First(DECL.FIELD); - ft := T2.Fields.First(DECL.FIELD); - WHILE Res & (fp # NIL) DO - Res := (fp.ByRef = ft.ByRef) & TypeComp(fp.T, ft.T); - fp := fp.Next(DECL.FIELD); - ft := ft.Next(DECL.FIELD) - END + Res := (T1.Call = T2.Call) & (T1.Fields.Count = T2.Fields.Count) & ProcTypeComp1(T1.Base, T2.Base); + fp := T1.Fields.First(DECL.FIELD); + ft := T2.Fields.First(DECL.FIELD); + WHILE Res & (fp # NIL) DO + Res := (fp.ByRef = ft.ByRef) & TypeComp(fp.T, ft.T); + fp := fp.Next(DECL.FIELD); + ft := ft.Next(DECL.FIELD) + END ELSE - Res := T1 = T2 + Res := T1 = T2 END END; DEC(sp) @@ -750,25 +778,25 @@ BEGIN |TARRAY: IF param THEN IF T.Len = 0 THEN - IF (T.Base.tType = TCHAR) & (e.T.tType = TSTRING) THEN - Res := TRUE - ELSE - Res := ArrComp(e.T, T) - END + IF (T.Base.tType = TCHAR) & (e.T.tType = TSTRING) THEN + Res := TRUE + ELSE + Res := ArrComp(e.T, T) + END ELSE - IF (T.Base.tType = TCHAR) & (e.T.tType = TSTRING) THEN - Res := LenString(e.Value) <= T.Len - ELSE - Res := e.T = T - END + IF (T.Base.tType = TCHAR) & (e.T.tType = TSTRING) THEN + Res := LenString(e.Value) <= T.Len + ELSE + Res := e.T = T + END END ELSE IF T.Len = 0 THEN - Res := FALSE + Res := FALSE ELSIF (T.Base.tType = TCHAR) & (e.T.tType = TSTRING) THEN - Res := LenString(e.Value) <= T.Len + Res := LenString(e.Value) <= T.Len ELSE - Res := e.T = T + Res := e.T = T END END |TRECORD: Res := BaseOf(T, e.T) @@ -789,17 +817,17 @@ BEGIN CASE T.tType OF |TINTEGER, TREAL, TLONGREAL, TCHAR, TSET, TBOOLEAN, TPOINTER, TCARD16: - Res := e.T = T + Res := e.T = T |TARRAY: - IF T.Len > 0 THEN - Res := e.T = T - ELSE - Res := ArrComp(e.T, T) - END + IF T.Len > 0 THEN + Res := e.T = T + ELSE + Res := ArrComp(e.T, T) + END |TRECORD: - Res := BaseOf(T, e.T) + Res := BaseOf(T, e.T) |TPROC: - Res := ProcTypeComp(e.T, T) + Res := ProcTypeComp(e.T, T) ELSE END ELSE @@ -826,12 +854,12 @@ BEGIN END; IF param.ByRef & (e1.T.tType = TRECORD) THEN IF e1.vparam THEN - X86.LocalAdr(e1.id.Offset - 4, DECL.unit.Level - e1.id.Level); - X86.Load(TINTEGER) + X86.LocalAdr(e1.id.Offset - 4, DECL.unit.Level - e1.id.Level); + X86.Load(TINTEGER) ELSIF e1.deref THEN - X86.DerefType(0) + X86.DerefType(0) ELSE - X86.PushConst(e1.T.Number) + X86.PushConst(e1.T.Number) END END; IF ~param.ByRef & (param.T.tType IN TFLOAT) THEN @@ -840,24 +868,24 @@ BEGIN IF (e1.T.tType = TSTRING) & (param.T.tType = TARRAY) THEN s := DECL.GetString(e1.Value); IF s.Len = 1 THEN - X86.Mono(s.Number) + X86.Mono(s.Number) END; IF param.T.Len = 0 THEN - A[0] := s.Len + 1; - X86.OpenArray(A, 1) + A[0] := s.Len + 1; + X86.OpenArray(A, 1) END END; IF (e1.T.tType = TARRAY) & (DECL.Dim(param.T) > DECL.Dim(e1.T)) THEN n := DECL.Dim(param.T) - DECL.Dim(e1.T); TA := DECL.OpenBase(e1.T); FOR i := 0 TO n - 1 DO - A[i] := TA.Len; - TA := TA.Base + A[i] := TA.Len; + TA := TA.Base END; IF DECL.Dim(e1.T) = 0 THEN - X86.OpenArray(A, n) + X86.OpenArray(A, n) ELSE - X86.ExtArray(A, n, DECL.Dim(e1.T)) + X86.ExtArray(A, n, DECL.Dim(e1.T)) END END; param := param.Next(DECL.FIELD); @@ -881,24 +909,24 @@ BEGIN Designator(e); IF e.eType = ePROC THEN IF SCAN.tLex = lxLRound THEN - Assert2(e.id.T.Base.tType # TVOID, 73); - Next; - X86.PushCall(begcall); - Call(e.id.T.Fields.First(DECL.FIELD)); - X86.EndCall; - e.eType := eEXP; - e.T := e.id.T.Base; - IF e.id.Level = 3 THEN - ccall := 0 - ELSIF e.id.Level > DECL.curBlock.Level THEN - ccall := 1 - ELSE - ccall := 2 - END; - X86.Call(e.id.Number, TRUE, e.T.tType IN TFLOAT, e.id.T.Call, ccall, e.id.Level - 3, - DECL.curBlock.Level - 3, e.id.ParamSize, DECL.curBlock.LocalSize) + Assert2(e.id.T.Base.tType # TVOID, 73); + Next; + X86.PushCall(begcall); + Call(e.id.T.Fields.First(DECL.FIELD)); + X86.EndCall; + e.eType := eEXP; + e.T := e.id.T.Base; + IF e.id.Level = 3 THEN + ccall := 0 + ELSIF e.id.Level > DECL.curBlock.Level THEN + ccall := 1 + ELSE + ccall := 2 + END; + X86.Call(e.id.Number, TRUE, e.T.tType IN TFLOAT, e.id.T.Call, ccall, e.id.Level - 3, + DECL.curBlock.Level - 3, e.id.ParamSize, DECL.curBlock.LocalSize) ELSE - X86.PushInt(e.id.Number) + X86.PushInt(e.id.Number) END ELSIF (e.eType = eVAR) & (e.T.tType = TPROC) & (SCAN.tLex = lxLRound) THEN Assert2(e.T.Base.tType # TVOID, 73); @@ -934,9 +962,9 @@ BEGIN e.Value := LONG(FLT(p)); s := DECL.GetString(e.Value); IF s.Len = 1 THEN - X86.PushConst(ORD(s.Str[0])) + X86.PushConst(ORD(s.Str[0])) ELSE - X86.PushInt(s.Number) + X86.PushInt(s.Number) END ELSE str2 := DECL.AddMono(SCAN.vCHX); @@ -1037,17 +1065,17 @@ BEGIN Assert(m # 0, coord, 48); n := log2(m); IF n = -1 THEN - X86.idivmod(Op = lxMOD) + X86.idivmod(Op = lxMOD) ELSE - X86.Drop; - IF Op = lxMOD THEN - n := ORD(-BITS(LSL(-1, n))); - X86.PushConst(n); - X86.Set(lxMult) - ELSE - X86.PushConst(n); - X86.StFunc(X86.stASR) - END + X86.Drop; + IF Op = lxMOD THEN + n := ORD(-BITS(LSL(-1, n))); + X86.PushConst(n); + X86.Set(lxMult) + ELSE + X86.PushConst(n); + X86.StFunc(X86.stASR) + END END ELSE X86.idivmod(Op = lxMOD) @@ -1146,9 +1174,9 @@ BEGIN IF (uOp = lxMinus) & (e.eType = eCONST) THEN CASE e.T.tType OF |TINTEGER: - Assert(e.Value # LONG(FLT(SCAN.minINT)), ucoord, DECL.IOVER) + Assert(e.Value # LONG(FLT(SCAN.minINT)), ucoord, DECL.IOVER) |TSET: - e.Value := -LONG(FLT(ORD(-BITS(FLOOR(e.Value))))) + e.Value := -LONG(FLT(ORD(-BITS(FLOOR(e.Value))))) ELSE END; e.Value := -e.Value @@ -1189,25 +1217,25 @@ BEGIN IF Op = lxIS THEN Assert(e.T.tType IN TOBJECT, coord, 37); IF e.T.tType = TRECORD THEN - Assert(e.vparam, coord, 37) + Assert(e.vparam, coord, 37) END; Check(lxIDENT); Coord(coord2); T := DECL.IdType(coord2); Assert(T # NIL, coord2, 42); IF e.T.tType = TRECORD THEN - Assert(T.tType = TRECORD, coord2, 106) + Assert(T.tType = TRECORD, coord2, 106) ELSE - Assert(T.tType = TPOINTER, coord2, 107) + Assert(T.tType = TPOINTER, coord2, 107) END; Assert(BaseOf(e.T, T), coord, 37); IF e.T.tType = TRECORD THEN - X86.Drop; - X86.LocalAdr(e.id.Offset, DECL.unit.Level - e.id.Level) + X86.Drop; + X86.LocalAdr(e.id.Offset, DECL.unit.Level - e.id.Level) END; Load(e); IF e.T.tType = TPOINTER THEN - T := T.Base + T := T.Base END; X86.Guard(T.Number, TRUE); e.T := booltype; @@ -1228,16 +1256,16 @@ BEGIN IF ~DECL.Const THEN CASE e.T.tType OF |TREAL, TLONGREAL: - X86.PushFlt(e.Value) + X86.PushFlt(e.Value) |TINTEGER, TSET, TBOOLEAN, TNIL: - X86.PushConst(FLOOR(e.Value)) + X86.PushConst(FLOOR(e.Value)) |TSTRING: - s := DECL.GetString(e.Value); - IF s.Len = 1 THEN - X86.PushConst(ORD(s.Str[0])) - ELSE - X86.PushInt(s.Number) - END + s := DECL.GetString(e.Value); + IF s.Len = 1 THEN + X86.PushConst(ORD(s.Str[0])) + ELSE + X86.PushInt(s.Number) + END ELSE END END @@ -1468,32 +1496,32 @@ BEGIN iValue := FLOOR(Value); Assert(iValue # 0, coord, 122); IF iValue < 0 THEN - IF proc = stINC THEN - proc := stDEC - ELSE - proc := stINC - END; - iValue := -iValue + IF proc = stINC THEN + proc := stDEC + ELSE + proc := stINC + END; + iValue := -iValue END; IF iValue # 1 THEN - X86.PushConst(iValue); - IF proc = stDEC THEN - X86.StProc(X86.stDEC) - ELSE - X86.StProc(X86.stINC) - END + X86.PushConst(iValue); + IF proc = stDEC THEN + X86.StProc(X86.stDEC) + ELSE + X86.StProc(X86.stINC) + END ELSE - IF proc = stDEC THEN - X86.StProc(X86.stDEC1) - ELSE - X86.StProc(X86.stINC1) - END + IF proc = stDEC THEN + X86.StProc(X86.stDEC1) + ELSE + X86.StProc(X86.stINC1) + END END ELSE IF proc = stDEC THEN - X86.StProc(X86.stDEC1) + X86.StProc(X86.stDEC1) ELSE - X86.StProc(X86.stINC1) + X86.StProc(X86.stINC1) END END |stINCL, stEXCL: @@ -1521,8 +1549,8 @@ BEGIN IF e1.T.tType = TSTRING THEN str := DECL.GetString(e1.Value); IF str.Len = 1 THEN - X86.Mono(str.Number); - X86.StrMono + X86.Mono(str.Number); + X86.StrMono END END; Str(e1); @@ -1571,18 +1599,18 @@ BEGIN Assert(e2.T.tType = TINTEGER, coord, 128); Assert(~e2.Read, coord, 115); IF e1.T.tType = TLONGREAL THEN - X86.StProc(X86.stUNPK) + X86.StProc(X86.stUNPK) ELSE - X86.StProc(X86.stUNPK1) + X86.StProc(X86.stUNPK1) END ELSE Expr(e2); IntType(e2.T, coord); Load(e2); IF e1.T.tType = TLONGREAL THEN - X86.StProc(X86.stPACK) + X86.StProc(X86.stPACK) ELSE - X86.StProc(X86.stPACK1) + X86.StProc(X86.stPACK1) END END |sysPUT, sysGET: @@ -1606,9 +1634,9 @@ BEGIN Expr(e2); Assert(~(e2.T.tType IN TSTRUCT), coord, 90); IF e2.T.tType = TSTRING THEN - Assert(LenString(e2.Value) = 1, coord, 94) + Assert(LenString(e2.Value) = 1, coord, 94) ELSIF e2.T.tType = TVOID THEN - e2.T := inttype + e2.T := inttype END; Load(e2); X86.Save(e2.T.tType) @@ -1636,12 +1664,29 @@ BEGIN Expr(e1); IntType(e1.T, coord); Load(e1); + |sysCOPY: + begcall := X86.current; + Designator(e1); + Assert(e1.eType = eVAR, coord, 63); + Check(lxComma); + X86.PushCall(begcall); + X86.Param; + NextCoord(coord); + Designator(e1); + Assert(e1.eType = eVAR, coord, 63); + Assert(~e1.Read, coord, 115); + Check(lxComma); + X86.EndCall; + NextCoord(coord); + Expr(e1); + IntType(e1.T, coord); + Load(e1); ELSE Assert(FALSE, coord2, 132) END; Check(lxRRound); Next; - IF proc = sysMOVE THEN + IF (proc = sysMOVE) OR (proc = sysCOPY) THEN X86.StProc(X86.sysMOVE) END END StProc; @@ -1664,21 +1709,21 @@ BEGIN X86.PushConst(e1.T.Size); X86.PushConst(e1.T.Number); IF e1.vparam THEN - X86.LocalAdr(e1.id.Offset - 4, DECL.unit.Level - e1.id.Level); - X86.Load(TINTEGER) + X86.LocalAdr(e1.id.Offset - 4, DECL.unit.Level - e1.id.Level); + X86.Load(TINTEGER) ELSIF e1.deref THEN - X86.DerefType(12) + X86.DerefType(12) ELSE - X86.PushConst(e1.T.Number) + X86.PushConst(e1.T.Number) END ELSIF e2.T.tType = TARRAY THEN X86.PushConst(e2.T.Size) ELSIF (e2.T.tType = TSTRING) & (e1.T.tType = TARRAY) THEN s := DECL.GetString(e2.Value); IF s.Len = 1 THEN - X86.Mono(s.Number) + X86.Mono(s.Number) END; - X86.PushConst(UTILS.min(s.Len + 1, e1.T.Len)) + X86.PushConst(MIN(s.Len + 1, e1.T.Len)) END; X86.Save(e1.T.tType) ELSIF e1.eType = ePROC THEN @@ -1718,7 +1763,7 @@ BEGIN Assert(AssComp(e2, e1.T, FALSE), coord, 131); Assert(~((e2.eType = ePROC) & (e2.id.Level > 3)), coord, 116); IF e2.eType = eVAR THEN - X86.Load(TPROC) + X86.Load(TPROC) END; X86.Save(TPROC) ELSE @@ -1779,19 +1824,19 @@ VAR SelfName, SelfPath, CName, CExt, FName, Path, StdPath, PROCEDURE hexdgt(c: CHAR): BOOLEAN; RETURN ("0" <= c) & (c <= "9") OR - ("A" <= c) & (c <= "F") OR - ("a" <= c) & (c <= "f") + ("A" <= c) & (c <= "F") OR + ("a" <= c) & (c <= "f") END hexdgt; PROCEDURE hex(c: CHAR): INTEGER; VAR res: INTEGER; BEGIN IF ("0" <= c) & (c <= "9") THEN - res := ORD(c) - ORD("0") + res := ORD(c) - ORD("0") ELSIF ("A" <= c) & (c <= "F") THEN - res := ORD(c) - ORD("A") + 10 + res := ORD(c) - ORD("A") + 10 ELSIF ("a" <= c) & (c <= "f") THEN - res := ORD(c) - ORD("a") + 10 + res := ORD(c) - ORD("a") + 10 END RETURN res END hex; diff --git a/programs/develop/oberon07/Source/DECL.ob07 b/programs/develop/oberon07/Source/DECL.ob07 index 07c7cdac8e..0804d5c933 100644 --- a/programs/develop/oberon07/Source/DECL.ob07 +++ b/programs/develop/oberon07/Source/DECL.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2017 Anton Krotov This file is part of Compiler. @@ -43,10 +43,10 @@ CONST stABS = 1; stODD = 2; stLEN = 3; stLSL = 4; stASR = 5; stROR = 6; stFLOOR = 7; stFLT = 8; stORD = 9; stCHR = 10; stLONG = 11; stSHORT = 12; stINC = 13; stDEC = 14; stINCL = 15; stEXCL = 16; stCOPY = 17; stNEW = 18; stASSERT = 19; stPACK = 20; stUNPK = 21; stDISPOSE = 22; - stBITS = 23; stLSR = 24; stLENGTH = 25; + stBITS = 23; stLSR = 24; stLENGTH = 25; stMIN = 26; stMAX = 27; sysADR = 101; sysSIZE = 102; sysINF = 103; sysGET = 104; sysPUT = 105; - sysCODE = 106; sysTYPEID = 107; sysMOVE = 108; + sysCODE = 106; sysTYPEID = 107; sysMOVE = 108; sysCOPY = 109; TINTEGER = 1; TREAL = 2; TLONGREAL = 3; TCHAR = 4; TSET = 5; TBOOLEAN = 6; TVOID = 7; TNIL = 8; TCARD16 = 9; TSTRING = 10; TARRAY = 11; TRECORD = 12; TPOINTER = 13; TPROC = 14; @@ -261,25 +261,25 @@ VAR code: INTEGER; BEGIN IF SCAN.tLex # key THEN CASE key OF - |lxMODULE: code := 21 - |lxIDENT: code := 22 - |lxSemi: code := 23 - |lxEND: code := 24 - |lxDot: code := 25 - |lxEQ: code := 35 - |lxRRound: code := 38 - |lxTO: code := 40 - |lxOF: code := 41 - |lxRCurly: code := 51 - |lxLRound: code := 56 - |lxComma: code := 61 - |lxTHEN: code := 98 + |lxMODULE: code := 21 + |lxIDENT: code := 22 + |lxSemi: code := 23 + |lxEND: code := 24 + |lxDot: code := 25 + |lxEQ: code := 35 + |lxRRound: code := 38 + |lxTO: code := 40 + |lxOF: code := 41 + |lxRCurly: code := 51 + |lxLRound: code := 56 + |lxComma: code := 61 + |lxTHEN: code := 98 |lxRSquare: code := 109 - |lxDO: code := 118 - |lxUNTIL: code := 119 - |lxAssign: code := 120 - |lxRETURN: code := 124 - |lxColon: code := 157 + |lxDO: code := 118 + |lxUNTIL: code := 119 + |lxAssign: code := 120 + |lxRETURN: code := 124 + |lxColon: code := 157 ELSE END; Assert2(FALSE, code) @@ -386,37 +386,39 @@ END PushSysType; PROCEDURE StIdent; BEGIN Guard; - PushStProc("ABS", stABS); - PushStProc("ASR", stASR); - PushStProc("ASSERT", stASSERT); + PushStProc("ABS", stABS); + PushStProc("ASR", stASR); + PushStProc("ASSERT", stASSERT); PushStType("BOOLEAN", TBOOLEAN); - PushStType("CHAR", TCHAR); - PushStProc("CHR", stCHR); - PushStProc("COPY", stCOPY); - PushStProc("DEC", stDEC); + PushStType("CHAR", TCHAR); + PushStProc("CHR", stCHR); + PushStProc("COPY", stCOPY); + PushStProc("DEC", stDEC); PushStProc("DISPOSE", stDISPOSE); - PushStProc("EXCL", stEXCL); - PushStProc("FLOOR", stFLOOR); - PushStProc("FLT", stFLT); - PushStProc("INC", stINC); - PushStProc("INCL", stINCL); + PushStProc("EXCL", stEXCL); + PushStProc("FLOOR", stFLOOR); + PushStProc("FLT", stFLT); + PushStProc("INC", stINC); + PushStProc("INCL", stINCL); PushStType("INTEGER", TINTEGER); - PushStProc("LEN", stLEN); - PushStProc("LSL", stLSL); - PushStProc("LONG", stLONG); + PushStProc("LEN", stLEN); + PushStProc("LSL", stLSL); + PushStProc("LONG", stLONG); PushStType("LONGREAL", TLONGREAL); - PushStProc("NEW", stNEW); - PushStProc("ODD", stODD); - PushStProc("ORD", stORD); - PushStProc("PACK", stPACK); - PushStType("REAL", TREAL); - PushStProc("ROR", stROR); - PushStType("SET", TSET); - PushStProc("SHORT", stSHORT); - PushStProc("UNPK", stUNPK); - PushStProc("BITS", stBITS); - PushStProc("LSR", stLSR); - PushStProc("LENGTH", stLENGTH); + PushStProc("NEW", stNEW); + PushStProc("ODD", stODD); + PushStProc("ORD", stORD); + PushStProc("PACK", stPACK); + PushStType("REAL", TREAL); + PushStProc("ROR", stROR); + PushStType("SET", TSET); + PushStProc("SHORT", stSHORT); + PushStProc("UNPK", stUNPK); + PushStProc("BITS", stBITS); + PushStProc("LSR", stLSR); + PushStProc("LENGTH", stLENGTH); + PushStProc("MIN", stMIN); + PushStProc("MAX", stMAX); Guard END StIdent; @@ -428,9 +430,9 @@ BEGIN WHILE (cur # NIL) & (cur.iType # IDGUARD) DO IF cur.Name = Name THEN IF (Unit # unit) & ~cur.Export THEN - res := NIL + res := NIL ELSE - res := cur + res := cur END; cur := NIL ELSE @@ -533,9 +535,9 @@ BEGIN Res := Arith(a, b, Ta, Op, coord) ELSIF Ta.tType = TSET THEN CASE Op OF - |lxPlus: Res := LONG(FLT(ORD(BITS(ai) + BITS(bi)))) + |lxPlus: Res := LONG(FLT(ORD(BITS(ai) + BITS(bi)))) |lxMinus: Res := LONG(FLT(ORD(BITS(ai) - BITS(bi)))) - |lxMult: Res := LONG(FLT(ORD(BITS(ai) * BITS(bi)))) + |lxMult: Res := LONG(FLT(ORD(BITS(ai) * BITS(bi)))) |lxSlash: Res := LONG(FLT(ORD(BITS(ai) / BITS(bi)))) ELSE END @@ -636,23 +638,23 @@ BEGIN NamePtrBase := Name; id := GetQIdent(Unit, Name); IF Unit # unit THEN - Assert2(id # NIL, 42); - Assert2(id.iType = IDTYPE, 77); - Coord(coord); - Next; - Res := id.T + Assert2(id # NIL, 42); + Assert2(id.iType = IDTYPE, 77); + Coord(coord); + Next; + Res := id.T ELSE - IF id = NIL THEN - Assert2((unit.Level = 3) & unit.typedecl, 42); - Coord(coord); - Next; - Res := NIL - ELSE - Assert2(id.iType = IDTYPE, 77); - Coord(coord); - Next; - Res := id.T - END + IF id = NIL THEN + Assert2((unit.Level = 3) & unit.typedecl, 42); + Coord(coord); + Next; + Res := NIL + ELSE + Assert2(id.iType = IDTYPE, 77); + Coord(coord); + Next; + Res := id.T + END END ELSE Assert2(FALSE, 77) @@ -689,21 +691,21 @@ BEGIN cur.T := Tf; IF Rec THEN IF Tf.Align > Tr.Align THEN - Tr.Align := Tf.Align + Tr.Align := Tf.Align END; IF Tr.Rec = record THEN - cur.Offset := FieldOffset(Tf.Align, Tr.Size); - Assert2(cur.Offset <= SCAN.maxINT - Tf.Size, 83); - Tr.Size := cur.Offset + Tf.Size + cur.Offset := FieldOffset(Tf.Align, Tr.Size); + Assert2(cur.Offset <= SCAN.maxINT - Tf.Size, 83); + Tr.Size := cur.Offset + Tf.Size ELSIF Tr.Rec = noalign THEN - cur.Offset := FieldOffset(1, Tr.Size); - Assert2(cur.Offset <= SCAN.maxINT - Tf.Size, 83); - Tr.Size := cur.Offset + Tf.Size + cur.Offset := FieldOffset(1, Tr.Size); + Assert2(cur.Offset <= SCAN.maxINT - Tf.Size, 83); + Tr.Size := cur.Offset + Tf.Size ELSIF Tr.Rec = union THEN - IF Tf.Size > Tr.Size THEN - Tr.Size := Tf.Size - END; - cur.Offset := 0 + IF Tf.Size > Tr.Size THEN + Tr.Size := Tf.Size + END; + cur.Offset := 0 END ELSE Tr.Len := Tr.Len + 4 * (ORD((Tf.tType = TRECORD) & cur.ByRef) + Dim(Tf) + ORD((Tf.tType = TLONGREAL) & ~cur.ByRef) + 1) @@ -734,7 +736,7 @@ BEGIN field := GetField(T, Name); IF field # NIL THEN IF (field.Unit = unit) OR field.Export THEN - res := FALSE + res := FALSE END END; T := T.Base @@ -744,7 +746,7 @@ END Unique; PROCEDURE notrecurs(id: BOOLEAN; T: pTYPE): BOOLEAN; RETURN ~(id & (unit.Idents.Last(IDENT).iType = IDTYPE) & (unit.Idents.Last(IDENT).T = T) & - (T.tType IN TSTRUCT)) + (T.tType IN TSTRUCT)) END notrecurs; PROCEDURE ReadFields(T: pTYPE); @@ -776,9 +778,9 @@ BEGIN Assert(notrecurs(id_T, Tf), coord, 96); SetFields(T, Tf, TRUE); IF SCAN.tLex = lxSemi THEN - NextCheck(lxIDENT) + NextCheck(lxIDENT) ELSE - Assert2(SCAN.tLex = lxEND, 86) + Assert2(SCAN.tLex = lxEND, 86) END ELSE Assert2(FALSE, 85) @@ -819,9 +821,9 @@ BEGIN ProgSize := ProgSize + UTILS.Align(ProgSize) ELSE IF cur.VarKind = 0 THEN - cur.Offset := curBlock.ParamSize - curBlock.VarSize - n + cur.Offset := curBlock.ParamSize - curBlock.VarSize - n ELSE - cur.Offset := curBlock.VarSize - 8 + 4 * (cur.Level + ORD((cur.VarKind = paramvar) & (T.tType = TRECORD))) + cur.Offset := curBlock.VarSize - 8 + 4 * (cur.Level + ORD((cur.VarKind = paramvar) & (T.tType = TRECORD))) END END; Assert2(curBlock.VarSize <= SCAN.maxINT - n, 93); @@ -901,9 +903,9 @@ BEGIN INC(curBlock.ParamCount); fp := unit.Idents.Last(IDENT); IF ByRef THEN - fp.VarKind := paramvar + fp.VarKind := paramvar ELSE - fp.VarKind := param + fp.VarKind := param END END; Next; @@ -915,7 +917,7 @@ BEGIN Assert(Dim(Tf) <= X86.ADIM, coord, 110); SetFields(T, Tf, FALSE); IF proc THEN - SetVars(Tf) + SetVars(Tf) END; cont := FALSE ELSE @@ -932,9 +934,9 @@ BEGIN REPEAT Section(T); IF SCAN.tLex = lxSemi THEN - Next + Next ELSE - break := TRUE + break := TRUE END UNTIL break END @@ -1054,6 +1056,9 @@ BEGIN Check(lxIDENT); nov.Base := IdType(coord); Assert(nov.Base # NIL, coord, 42); + IF (nov.Base.tType = TPOINTER) & (nov.Base.Base.tType = TRECORD) THEN + nov.Base := nov.Base.Base + END; Assert(nov.Base.tType = TRECORD, coord, 80); Assert(notrecurs(TRUE, nov.Base), coord, 96); nov.Size := nov.Base.Size; @@ -1194,10 +1199,16 @@ BEGIN last := unit.Idents.Last(IDENT); Check(lxEQ); Next; - NEW(NewType); - MemErr(NewType = NIL); - last.T := NewType; - T := StructType(FALSE, NewType); + + IF SCAN.tLex = lxIDENT THEN + last.T := ParseType(coord) + ELSE + NEW(NewType); + MemErr(NewType = NIL); + last.T := NewType; + T := StructType(FALSE, NewType) + END; + Check(lxSemi); Next END @@ -1210,16 +1221,16 @@ BEGIN IdentDef; PushIdent(Name, coord, IDVAR, NIL, NIL, Export, 0); IF SCAN.tLex = lxComma THEN - NextCheck(lxIDENT) + NextCheck(lxIDENT) ELSIF SCAN.tLex = lxColon THEN - NextCoord(coord); - T := ParseType(coord); - Assert(T # NIL, coord, 42); - SetVars(T); - Check(lxSemi); - Next + NextCoord(coord); + T := ParseType(coord); + Assert(T # NIL, coord, 42); + SetVars(T); + Check(lxSemi); + Next ELSE - Assert2(FALSE, 85) + Assert2(FALSE, 85) END END END; @@ -1237,8 +1248,8 @@ BEGIN id.Proc := curproc; IF id.Export & main THEN IF Platform IN {1, 6} THEN - curproc.used := TRUE; - Assert((Name # SCAN._START) & (Name # SCAN._version), coord, 133) + curproc.used := TRUE; + Assert((Name # SCAN._START) & (Name # SCAN._version), coord, 133) END; X86.ProcExport(id.Number, Name, X86.NewLabel()) END; @@ -1266,7 +1277,7 @@ BEGIN Expr(e); Assert(AssComp(e, curBlock.T.Base, FALSE), coord, 125); IF e.eType = eVAR THEN - X86.Load(e.T.tType) + X86.Load(e.T.tType) END ELSE Assert2(SCAN.tLex # lxRETURN, 123) @@ -1335,12 +1346,12 @@ VAR cond: INTEGER; coord, namecoord: SCAN.TCoord; SCAN.Backup(unit.scanner); COPY(name.Name, FName); IF ~((~self.Std & pReadModule(Path, FName, UTILS.Ext)) OR pReadModule(Std, FName, UTILS.Ext)) THEN - IF FName = "SYSTEM" THEN - unit := sys; - self.sys := TRUE - ELSE - Assert(FALSE, namecoord, 32) - END + IF FName = "SYSTEM" THEN + unit := sys; + self.sys := TRUE + ELSE + Assert(FALSE, namecoord, 32) + END END; SCAN.Recover(self.scanner); u := unit; @@ -1363,28 +1374,28 @@ BEGIN Next; CASE cond OF |0: Check(lxIDENT); - name := SCAN.id; - Coord(coord); - Coord(namecoord); - alias := name; - cond := 1 + name := SCAN.id; + Coord(coord); + Coord(namecoord); + alias := name; + cond := 1 |1: CASE SCAN.tLex OF - |lxComma: AddUnit(0) - |lxSemi: AddUnit(4); Next - |lxAssign: cond := 2 - ELSE - Assert2(FALSE, 28) - END + |lxComma: AddUnit(0) + |lxSemi: AddUnit(4); Next + |lxAssign: cond := 2 + ELSE + Assert2(FALSE, 28) + END |2: Check(lxIDENT); - name := SCAN.id; - Coord(namecoord); - cond := 3 + name := SCAN.id; + Coord(namecoord); + cond := 3 |3: CASE SCAN.tLex OF - |lxComma: AddUnit(0) - |lxSemi: AddUnit(4); Next - ELSE - Assert2(FALSE, 29) - END + |lxComma: AddUnit(0) + |lxSemi: AddUnit(4); Next + ELSE + Assert2(FALSE, 29) + END ELSE END END @@ -1409,14 +1420,15 @@ VAR temp: UNIT; BEGIN temp := unit; Header(SCAN.AddNode("SYSTEM")); - PushSysProc("ADR", sysADR); - PushSysProc("SIZE", sysSIZE); + PushSysProc("ADR", sysADR); + PushSysProc("SIZE", sysSIZE); PushSysProc("TYPEID", sysTYPEID); - PushSysProc("GET", sysGET); - PushSysProc("PUT", sysPUT); - PushSysProc("CODE", sysCODE); - PushSysProc("MOVE", sysMOVE); - PushSysProc("INF", sysINF); + PushSysProc("GET", sysGET); + PushSysProc("PUT", sysPUT); + PushSysProc("CODE", sysCODE); + PushSysProc("MOVE", sysMOVE); + PushSysProc("COPY", sysCOPY); + PushSysProc("INF", sysINF); PushSysType("CARD16", TCARD16); sys := unit; unit := temp @@ -1531,7 +1543,7 @@ VAR cur: Proc; WHILE cur # NIL DO p := cur.Proc(Proc); IF ~p.used THEN - ProcHandling(p) + ProcHandling(p) END; cur := cur.Next(IDENT) END; diff --git a/programs/develop/oberon07/Source/ERRORS.ob07 b/programs/develop/oberon07/Source/ERRORS.ob07 index 5eab9a82e8..e8bd328ea5 100644 --- a/programs/develop/oberon07/Source/ERRORS.ob07 +++ b/programs/develop/oberon07/Source/ERRORS.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2017 Anton Krotov This file is part of Compiler. @@ -200,7 +200,7 @@ BEGIN | 77: str := " 䨪 ⨯" | 78: str := " ⨯-ᨢ " | 79: str := " 'OF' ','" - | 80: str := " 䨪 ⨯-" + | 80: str := " 䨪 ⨯- ⨯-㪠⥫" | 81: str := " ⨯ ⨯-㪠⥫ " | 82: str := "⨯ १ 楤 ᨢ" | 83: str := "ࠧ ⨯ ᫨誮 " diff --git a/programs/develop/oberon07/Source/UTILS.ob07 b/programs/develop/oberon07/Source/UTILS.ob07 index b02a52ecc8..62ab03efec 100644 --- a/programs/develop/oberon07/Source/UTILS.ob07 +++ b/programs/develop/oberon07/Source/UTILS.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2017 Anton Krotov This file is part of Compiler. @@ -28,7 +28,7 @@ CONST Ext* = ".ob07"; MAX_PATH = 1024; MAX_PARAM = 1024; - Date* = 1451606400; (* 2016-01-01 *) + Date* = 1509580800; (* 2017-11-02 *) TYPE @@ -53,7 +53,7 @@ TYPE VAR Params: ARRAY MAX_PARAM, 2 OF INTEGER; - ParamCount*, Line*, Unit*: INTEGER; + ParamCount*, Line*, Unit*: INTEGER; FileName: STRING; PROCEDURE SetFile*(F: STRING); @@ -113,8 +113,8 @@ BEGIN WHILE (j < len) & (i <= Params[n, 1]) DO c := GetChar(i); IF c # 22X THEN - str[j] := c; - INC(j) + str[j] := c; + INC(j) END; INC(i) END @@ -199,14 +199,6 @@ BEGIN Line := newLine END UnitLine; -PROCEDURE min*(a, b: INTEGER): INTEGER; -BEGIN - IF a > b THEN - a := b - END - RETURN a -END min; - PROCEDURE Align*(n: INTEGER): INTEGER; RETURN (4 - n MOD 4) MOD 4 END Align; @@ -333,7 +325,7 @@ BEGIN END; Path[i + 1] := 0X END Split; - + PROCEDURE LinuxParam; VAR p, i, str: INTEGER; c: CHAR; BEGIN @@ -350,7 +342,7 @@ BEGIN Params[i, 1] := str - 1 END; DEC(ParamCount) -END LinuxParam; +END LinuxParam; PROCEDURE Time*; VAR sec, dsec: INTEGER; diff --git a/programs/develop/oberon07/Source/X86.ob07 b/programs/develop/oberon07/Source/X86.ob07 index 9d4b28cbb0..574da0bcaf 100644 --- a/programs/develop/oberon07/Source/X86.ob07 +++ b/programs/develop/oberon07/Source/X86.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2017 Anton Krotov This file is part of Compiler. @@ -36,7 +36,7 @@ CONST stDEC* = 14; stINCL* = 15; stEXCL* = 16; stCOPY* = 17; stNEW* = 18; stASSERT* = 19; stPACK* = 20; stUNPK* = 21; stDISPOSE* = 22; stFABS* = 23; stINC1* = 24; stDEC1* = 25; stASSERT1* = 26; stUNPK1* = 27; stPACK1* = 28; stLSR* = 29; - stLENGTH* = 30; + stLENGTH* = 30; stMIN* = 31; stMAX* = 32; sysMOVE* = 108; @@ -1232,7 +1232,9 @@ BEGIN |stASR: PopECX; OutCode("58D3F8"); PushEAX |stLSL: PopECX; OutCode("58D3E0"); PushEAX |stLSR: PopECX; OutCode("58D3E8"); PushEAX - |stORD: PopEDX; OutCode("85D274036A015A"); PushEDX + |stORD: PopEDX; OutCode("85D274036A015A"); PushEDX; + |stMIN: PopEDX; OutCode("3914247E025852"); + |stMAX: PopEDX; OutCode("3B14247E025852"); |stLENGTH: CallRTL(_length); PushEAX ELSE END @@ -1269,12 +1271,12 @@ BEGIN |TCHAR, TBOOLEAN: IF lastcmd.tcmd = ECMD THEN del; - OutCode("33D28A"); + OutCode("0FB6"); IntByte("55", "95", offset); PushEDX ELSE PopEDX; - OutCode("33C98A0A"); + OutCode("0FB60A"); PushECX END |TLONGREAL: