/programs/develop/oberon07/doc/Oberon07.Report_2016_05_03.pdf |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/programs/develop/oberon07/doc/x86_64.txt |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/doc/KOSLib.txt |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/doc/WinLib.txt |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/doc/x86.txt |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/doc/CC.txt |
---|
File deleted |
/programs/develop/oberon07/doc/MSP430.txt |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/doc/STM32.txt |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/tools/RVM32I.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Compiler |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/programs/develop/oberon07/Compiler.exe |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/programs/develop/oberon07/Compiler.kex |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/programs/develop/oberon07/Docs/KOSLib.txt |
---|
0,0 → 1,566 |
============================================================================== |
Библиотека (KolibriOS) |
------------------------------------------------------------------------------ |
MODULE Out - консольный вывод |
PROCEDURE Open |
формально открывает консольный вывод |
PROCEDURE Int(x, width: INTEGER) |
вывод целого числа x; |
width - количество знакомест, используемых для вывода |
PROCEDURE Real(x: REAL; width: INTEGER) |
вывод вещественного числа x в плавающем формате; |
width - количество знакомест, используемых для вывода |
PROCEDURE Char(x: CHAR) |
вывод символа x |
PROCEDURE FixReal(x: REAL; width, p: INTEGER) |
вывод вещественного числа x в фиксированном формате; |
width - количество знакомест, используемых для вывода; |
p - количество знаков после десятичной точки |
PROCEDURE Ln |
переход на следующую строку |
PROCEDURE String(s: ARRAY OF CHAR) |
вывод строки s |
------------------------------------------------------------------------------ |
MODULE In - консольный ввод |
VAR Done: BOOLEAN |
принимает значение TRUE в случае успешного выполнения |
операции ввода, иначе FALSE |
PROCEDURE Open |
формально открывает консольный ввод, |
также присваивает переменной Done значение TRUE |
PROCEDURE Int(VAR x: INTEGER) |
ввод числа типа INTEGER |
PROCEDURE Char(VAR x: CHAR) |
ввод символа |
PROCEDURE Real(VAR x: REAL) |
ввод числа типа REAL |
PROCEDURE String(VAR s: ARRAY OF CHAR) |
ввод строки |
PROCEDURE Ln |
ожидание нажатия ENTER |
------------------------------------------------------------------------------ |
MODULE Console - дополнительные процедуры консольного вывода |
CONST |
Следующие константы определяют цвет консольного вывода |
Black = 0 Blue = 1 Green = 2 |
Cyan = 3 Red = 4 Magenta = 5 |
Brown = 6 LightGray = 7 DarkGray = 8 |
LightBlue = 9 LightGreen = 10 LightCyan = 11 |
LightRed = 12 LightMagenta = 13 Yellow = 14 |
White = 15 |
PROCEDURE Cls |
очистка окна консоли |
PROCEDURE SetColor(FColor, BColor: INTEGER) |
установка цвета консольного вывода: FColor - цвет текста, |
BColor - цвет фона, возможные значения - вышеперечисленные |
константы |
PROCEDURE SetCursor(x, y: INTEGER) |
установка курсора консоли в позицию (x, y) |
PROCEDURE GetCursor(VAR x, y: INTEGER) |
записывает в параметры текущие координаты курсора консоли |
PROCEDURE GetCursorX(): INTEGER |
возвращает текущую x-координату курсора консоли |
PROCEDURE GetCursorY(): INTEGER |
возвращает текущую y-координату курсора консоли |
------------------------------------------------------------------------------ |
MODULE ConsoleLib - обертка библиотеки console.obj |
------------------------------------------------------------------------------ |
MODULE Math - математические функции |
CONST |
pi = 3.141592653589793E+00 |
e = 2.718281828459045E+00 |
PROCEDURE IsNan(x: REAL): BOOLEAN |
возвращает TRUE, если x - не число |
PROCEDURE IsInf(x: REAL): BOOLEAN |
возвращает TRUE, если x - бесконечность |
PROCEDURE sqrt(x: REAL): REAL |
квадратный корень x |
PROCEDURE exp(x: REAL): REAL |
экспонента x |
PROCEDURE ln(x: REAL): REAL |
натуральный логарифм x |
PROCEDURE sin(x: REAL): REAL |
синус x |
PROCEDURE cos(x: REAL): REAL |
косинус x |
PROCEDURE tan(x: REAL): REAL |
тангенс x |
PROCEDURE arcsin(x: REAL): REAL |
арксинус x |
PROCEDURE arccos(x: REAL): REAL |
арккосинус x |
PROCEDURE arctan(x: REAL): REAL |
арктангенс x |
PROCEDURE arctan2(y, x: REAL): REAL |
арктангенс y/x |
PROCEDURE power(base, exponent: REAL): REAL |
возведение числа base в степень exponent |
PROCEDURE log(base, x: REAL): REAL |
логарифм x по основанию base |
PROCEDURE sinh(x: REAL): REAL |
гиперболический синус x |
PROCEDURE cosh(x: REAL): REAL |
гиперболический косинус x |
PROCEDURE tanh(x: REAL): REAL |
гиперболический тангенс x |
PROCEDURE arsinh(x: REAL): REAL |
обратный гиперболический синус x |
PROCEDURE arcosh(x: REAL): REAL |
обратный гиперболический косинус x |
PROCEDURE artanh(x: REAL): REAL |
обратный гиперболический тангенс x |
PROCEDURE round(x: REAL): REAL |
округление x до ближайшего целого |
PROCEDURE frac(x: REAL): REAL; |
дробная часть числа x |
PROCEDURE floor(x: REAL): REAL |
наибольшее целое число (представление как REAL), |
не больше x: floor(1.2) = 1.0 |
PROCEDURE ceil(x: REAL): REAL |
наименьшее целое число (представление как REAL), |
не меньше x: ceil(1.2) = 2.0 |
PROCEDURE sgn(x: REAL): INTEGER |
если x > 0 возвращает 1 |
если x < 0 возвращает -1 |
если x = 0 возвращает 0 |
PROCEDURE fact(n: INTEGER): REAL |
факториал n |
------------------------------------------------------------------------------ |
MODULE Debug - вывод на доску отладки |
Интерфейс как модуль Out |
PROCEDURE Open |
открывает доску отладки |
------------------------------------------------------------------------------ |
MODULE File - работа с файловой системой |
TYPE |
FNAME = ARRAY 520 OF CHAR |
FS = POINTER TO rFS |
rFS = RECORD (* информационная структура файла *) |
subfunc, pos, hpos, bytes, buffer: INTEGER; |
name: FNAME |
END |
FD = POINTER TO rFD |
rFD = RECORD (* структура блока данных входа каталога *) |
attr: INTEGER; |
ntyp: CHAR; |
reserved: ARRAY 3 OF CHAR; |
time_create, date_create, |
time_access, date_access, |
time_modif, date_modif, |
size, hsize: INTEGER; |
name: FNAME |
END |
CONST |
SEEK_BEG = 0 |
SEEK_CUR = 1 |
SEEK_END = 2 |
PROCEDURE Load(FName: ARRAY OF CHAR; VAR size: INTEGER): INTEGER; |
Загружает в память файл с именем FName, записывает в параметр |
size размер файла, возвращает адрес загруженного файла |
или 0 (ошибка). При необходимости, распаковывает |
файл (kunpack). |
PROCEDURE GetFileInfo(FName: ARRAY OF CHAR; VAR Info: rFD): BOOLEAN |
Записывает структуру блока данных входа каталога для файла |
или папки с именем FName в параметр Info. |
При ошибке возвращает FALSE. |
PROCEDURE Exists(FName: ARRAY OF CHAR): BOOLEAN |
возвращает TRUE, если файл с именем FName существует |
PROCEDURE Close(VAR F: FS) |
освобождает память, выделенную для информационной структуры |
файла F и присваивает F значение NIL |
PROCEDURE Open(FName: ARRAY OF CHAR): FS |
возвращает указатель на информационную структуру файла с |
именем FName, при ошибке возвращает NIL |
PROCEDURE Delete(FName: ARRAY OF CHAR): BOOLEAN |
удаляет файл с именем FName, при ошибке возвращает FALSE |
PROCEDURE Seek(F: FS; Offset, Origin: INTEGER): INTEGER |
устанавливает позицию чтения-записи файла F на Offset, |
относительно Origin = (SEEK_BEG - начало файла, |
SEEK_CUR - текущая позиция, SEEK_END - конец файла), |
возвращает позицию относительно начала файла, например: |
Seek(F, 0, SEEK_END) |
устанавливает позицию на конец файла и возвращает длину |
файла; при ошибке возвращает -1 |
PROCEDURE Read(F: FS; Buffer, Count: INTEGER): INTEGER |
Читает данные из файла в память. F - указатель на |
информационную структуру файла, Buffer - адрес области |
памяти, Count - количество байт, которое требуется прочитать |
из файла; возвращает количество байт, которое было прочитано |
и соответствующим образом изменяет позицию чтения/записи в |
информационной структуре F. |
PROCEDURE Write(F: FS; Buffer, Count: INTEGER): INTEGER |
Записывает данные из памяти в файл. F - указатель на |
информационную структуру файла, Buffer - адрес области |
памяти, Count - количество байт, которое требуется записать |
в файл; возвращает количество байт, которое было записано и |
соответствующим образом изменяет позицию чтения/записи в |
информационной структуре F. |
PROCEDURE Create(FName: ARRAY OF CHAR): FS |
создает новый файл с именем FName (полное имя), возвращает |
указатель на информационную структуру файла, |
при ошибке возвращает NIL |
PROCEDURE CreateDir(DirName: ARRAY OF CHAR): BOOLEAN |
создает папку с именем DirName, все промежуточные папки |
должны существовать, при ошибке возвращает FALSE |
PROCEDURE DeleteDir(DirName: ARRAY OF CHAR): BOOLEAN |
удаляет пустую папку с именем DirName, |
при ошибке возвращает FALSE |
PROCEDURE DirExists(DirName: ARRAY OF CHAR): BOOLEAN |
возвращает TRUE, если папка с именем DirName существует |
------------------------------------------------------------------------------ |
MODULE Read - чтение основных типов данных из файла F |
Процедуры возвращают TRUE в случае успешной операции чтения и |
соответствующим образом изменяют позицию чтения/записи в |
информационной структуре F |
PROCEDURE Char(F: File.FS; VAR x: CHAR): BOOLEAN |
PROCEDURE Int(F: File.FS; VAR x: INTEGER): BOOLEAN |
PROCEDURE Real(F: File.FS; VAR x: REAL): BOOLEAN |
PROCEDURE Boolean(F: File.FS; VAR x: BOOLEAN): BOOLEAN |
PROCEDURE Set(F: File.FS; VAR x: SET): BOOLEAN |
PROCEDURE WChar(F: File.FS; VAR x: WCHAR): BOOLEAN |
------------------------------------------------------------------------------ |
MODULE Write - запись основных типов данных в файл F |
Процедуры возвращают TRUE в случае успешной операции записи и |
соответствующим образом изменяют позицию чтения/записи в |
информационной структуре F |
PROCEDURE Char(F: File.FS; x: CHAR): BOOLEAN |
PROCEDURE Int(F: File.FS; x: INTEGER): BOOLEAN |
PROCEDURE Real(F: File.FS; x: REAL): BOOLEAN |
PROCEDURE Boolean(F: File.FS; x: BOOLEAN): BOOLEAN |
PROCEDURE Set(F: File.FS; x: SET): BOOLEAN |
PROCEDURE WChar(F: File.FS; x: WCHAR): BOOLEAN |
------------------------------------------------------------------------------ |
MODULE DateTime - дата, время |
CONST ERR = -7.0E5 |
PROCEDURE Now(VAR Year, Month, Day, Hour, Min, Sec: INTEGER) |
записывает в параметры компоненты текущей системной даты и |
времени |
PROCEDURE Encode(Year, Month, Day, Hour, Min, Sec: INTEGER): REAL |
возвращает дату, полученную из компонентов |
Year, Month, Day, Hour, Min, Sec; |
при ошибке возвращает константу ERR = -7.0E5 |
PROCEDURE Decode(Date: REAL; VAR Year, Month, Day, |
Hour, Min, Sec: INTEGER): BOOLEAN |
извлекает компоненты |
Year, Month, Day, Hour, Min, Sec из даты Date; |
при ошибке возвращает FALSE |
------------------------------------------------------------------------------ |
MODULE Args - параметры программы |
VAR argc: INTEGER |
количество параметров программы, включая имя |
исполняемого файла |
PROCEDURE GetArg(n: INTEGER; VAR s: ARRAY OF CHAR) |
записывает в строку s n-й параметр программы, |
нумерация параметров от 0 до argc - 1, |
нулевой параметр -- имя исполняемого файла |
------------------------------------------------------------------------------ |
MODULE KOSAPI |
PROCEDURE sysfunc1(arg1: INTEGER): INTEGER |
PROCEDURE sysfunc2(arg1, arg2: INTEGER): INTEGER |
... |
PROCEDURE sysfunc7(arg1, arg2, ..., arg7: INTEGER): INTEGER |
Обертки для функций API ядра KolibriOS. |
arg1 .. arg7 соответствуют регистрам |
eax, ebx, ecx, edx, esi, edi, ebp; |
возвращают значение регистра eax после системного вызова. |
PROCEDURE sysfunc22(arg1, arg2: INTEGER; VAR res2: INTEGER): INTEGER |
Обертка для функций API ядра KolibriOS. |
arg1 - регистр eax, arg2 - регистр ebx, |
res2 - значение регистра ebx после системного вызова; |
возвращает значение регистра eax после системного вызова. |
PROCEDURE malloc(size: INTEGER): INTEGER |
Выделяет блок памяти. |
size - размер блока в байтах, |
возвращает адрес выделенного блока |
PROCEDURE free(ptr: INTEGER): INTEGER |
Освобождает ранее выделенный блок памяти с адресом ptr, |
возвращает 0 |
PROCEDURE realloc(ptr, size: INTEGER): INTEGER |
Перераспределяет блок памяти, |
ptr - адрес ранее выделенного блока, |
size - новый размер, |
возвращает указатель на перераспределенный блок, |
0 при ошибке |
PROCEDURE GetCommandLine(): INTEGER |
Возвращает адрес строки параметров |
PROCEDURE GetName(): INTEGER |
Возвращает адрес строки с именем программы |
PROCEDURE LoadLib(name: ARRAY OF CHAR): INTEGER |
Загружает DLL с полным именем name. Возвращает адрес таблицы |
экспорта. При ошибке возвращает 0. |
PROCEDURE GetProcAdr(name: ARRAY OF CHAR; lib: INTEGER): INTEGER |
name - имя процедуры |
lib - адрес таблицы экспорта DLL |
Возвращает адрес процедуры. При ошибке возвращает 0. |
------------------------------------------------------------------------------ |
MODULE ColorDlg - работа с диалогом "Color Dialog" |
TYPE |
Dialog = POINTER TO RECORD (* структура диалога *) |
status: INTEGER (* состояние диалога: |
0 - пользователь нажал Cancel |
1 - пользователь нажал OK |
2 - диалог открыт *) |
color: INTEGER (* выбранный цвет *) |
END |
PROCEDURE Create(draw_window: DRAW_WINDOW): Dialog |
создать диалог |
draw_window - процедура перерисовки основного окна |
(TYPE DRAW_WINDOW = PROCEDURE); |
процедура возвращает указатель на структуру диалога |
PROCEDURE Show(cd: Dialog) |
показать диалог |
cd - указатель на структуру диалога, который был создан ранее |
процедурой Create |
PROCEDURE Destroy(VAR cd: Dialog) |
уничтожить диалог |
cd - указатель на структуру диалога |
------------------------------------------------------------------------------ |
MODULE OpenDlg - работа с диалогом "Open Dialog" |
TYPE |
Dialog = POINTER TO RECORD (* структура диалога *) |
status: INTEGER (* состояние диалога: |
0 - пользователь нажал Cancel |
1 - пользователь нажал OK |
2 - диалог открыт *) |
FileName: ARRAY 4096 OF CHAR (* имя выбранного файла *) |
FilePath: ARRAY 4096 OF CHAR (* полное имя выбранного |
файла *) |
END |
PROCEDURE Create(draw_window: DRAW_WINDOW; type: INTEGER; def_path, |
filter: ARRAY OF CHAR): Dialog |
создать диалог |
draw_window - процедура перерисовки основного окна |
(TYPE DRAW_WINDOW = PROCEDURE) |
type - тип диалога |
0 - открыть |
1 - сохранить |
2 - выбрать папку |
def_path - путь по умолчанию, папка def_path будет открыта |
при первом запуске диалога |
filter - в строке записано перечисление расширений файлов, |
которые будут показаны в диалоговом окне, расширения |
разделяются символом "|", например: "ASM|TXT|INI" |
процедура возвращает указатель на структуру диалога |
PROCEDURE Show(od: Dialog; Width, Height: INTEGER) |
показать диалог |
od - указатель на структуру диалога, который был создан ранее |
процедурой Create |
Width и Height - ширина и высота диалогового окна |
PROCEDURE Destroy(VAR od: Dialog) |
уничтожить диалог |
od - указатель на структуру диалога |
------------------------------------------------------------------------------ |
MODULE kfonts - работа с kf-шрифтами |
CONST |
bold = 1 |
italic = 2 |
underline = 4 |
strike_through = 8 |
smoothing = 16 |
bpp32 = 32 |
TYPE |
TFont = POINTER TO TFont_desc (* указатель на шрифт *) |
PROCEDURE LoadFont(file_name: ARRAY OF CHAR): TFont |
загрузить шрифт из файла |
file_name имя kf-файла |
рез-т: указатель на шрифт/NIL (ошибка) |
PROCEDURE SetSize(Font: TFont; font_size: INTEGER): BOOLEAN |
установить размер шрифта |
Font указатель на шрифт |
font_size размер шрифта |
рез-т: TRUE/FALSE (ошибка) |
PROCEDURE Enabled(Font: TFont; font_size: INTEGER): BOOLEAN |
проверить, есть ли шрифт, заданного размера |
Font указатель на шрифт |
font_size размер шрифта |
рез-т: TRUE/FALSE (шрифта нет) |
PROCEDURE Destroy(VAR Font: TFont) |
выгрузить шрифт, освободить динамическую память |
Font указатель на шрифт |
Присваивает переменной Font значение NIL |
PROCEDURE TextHeight(Font: TFont): INTEGER |
получить высоту строки текста |
Font указатель на шрифт |
рез-т: высота строки текста в пикселях |
PROCEDURE TextWidth(Font: TFont; |
str, length, params: INTEGER): INTEGER |
получить ширину строки текста |
Font указатель на шрифт |
str адрес строки текста в кодировке Win-1251 |
length количество символов в строке или -1, если строка |
завершается нулем |
params параметры-флаги см. ниже |
рез-т: ширина строки текста в пикселях |
PROCEDURE TextOut(Font: TFont; |
canvas, x, y, str, length, color, params: INTEGER) |
вывести текст в буфер |
для вывода буфера в окно, использовать ф.65 или |
ф.7 (если буфер 24-битный) |
Font указатель на шрифт |
canvas адрес графического буфера |
структура буфера: |
Xsize dd |
Ysize dd |
picture rb Xsize * Ysize * 4 (32 бита) |
или Xsize * Ysize * 3 (24 бита) |
x, y координаты текста относительно левого верхнего |
угла буфера |
str адрес строки текста в кодировке Win-1251 |
length количество символов в строке или -1, если строка |
завершается нулем |
color цвет текста 0x00RRGGBB |
params параметры-флаги: |
1 жирный |
2 курсив |
4 подчеркнутый |
8 перечеркнутый |
16 применить сглаживание |
32 вывод в 32-битный буфер |
возможно использование флагов в любых сочетаниях |
------------------------------------------------------------------------------ |
MODULE RasterWorks - обертка библиотеки Rasterworks.obj |
------------------------------------------------------------------------------ |
MODULE libimg - обертка библиотеки libimg.obj |
------------------------------------------------------------------------------ |
/programs/develop/oberon07/Docs/WinLib.txt |
---|
0,0 → 1,312 |
============================================================================== |
Библиотека (Windows) |
------------------------------------------------------------------------------ |
MODULE Out - консольный вывод |
PROCEDURE Open |
открывает консольный вывод |
PROCEDURE Int(x, width: INTEGER) |
вывод целого числа x; |
width - количество знакомест, используемых для вывода |
PROCEDURE Real(x: REAL; width: INTEGER) |
вывод вещественного числа x в плавающем формате; |
width - количество знакомест, используемых для вывода |
PROCEDURE Char(x: CHAR) |
вывод символа x |
PROCEDURE FixReal(x: REAL; width, p: INTEGER) |
вывод вещественного числа x в фиксированном формате; |
width - количество знакомест, используемых для вывода; |
p - количество знаков после десятичной точки |
PROCEDURE Ln |
переход на следующую строку |
PROCEDURE String(s: ARRAY OF CHAR) |
вывод строки s (ASCII) |
PROCEDURE StringW(s: ARRAY OF WCHAR) |
вывод строки s (UTF-16) |
------------------------------------------------------------------------------ |
MODULE In - консольный ввод |
VAR Done: BOOLEAN |
принимает значение TRUE в случае успешного выполнения |
операции ввода и FALSE в противном случае |
PROCEDURE Open |
открывает консольный ввод, |
также присваивает переменной Done значение TRUE |
PROCEDURE Int(VAR x: INTEGER) |
ввод числа типа INTEGER |
PROCEDURE Char(VAR x: CHAR) |
ввод символа |
PROCEDURE Real(VAR x: REAL) |
ввод числа типа REAL |
PROCEDURE String(VAR s: ARRAY OF CHAR) |
ввод строки |
PROCEDURE Ln |
ожидание нажатия ENTER |
------------------------------------------------------------------------------ |
MODULE Console - дополнительные процедуры консольного вывода |
CONST |
Следующие константы определяют цвет консольного вывода |
Black = 0 Blue = 1 Green = 2 |
Cyan = 3 Red = 4 Magenta = 5 |
Brown = 6 LightGray = 7 DarkGray = 8 |
LightBlue = 9 LightGreen = 10 LightCyan = 11 |
LightRed = 12 LightMagenta = 13 Yellow = 14 |
White = 15 |
PROCEDURE Cls |
очистка окна консоли |
PROCEDURE SetColor(FColor, BColor: INTEGER) |
установка цвета консольного вывода: FColor - цвет текста, |
BColor - цвет фона, возможные значения - вышеперечисленные |
константы |
PROCEDURE SetCursor(x, y: INTEGER) |
установка курсора консоли в позицию (x, y) |
PROCEDURE GetCursor(VAR x, y: INTEGER) |
записывает в параметры текущие координаты курсора консоли |
PROCEDURE GetCursorX(): INTEGER |
возвращает текущую x-координату курсора консоли |
PROCEDURE GetCursorY(): INTEGER |
возвращает текущую y-координату курсора консоли |
------------------------------------------------------------------------------ |
MODULE Math - математические функции |
CONST |
pi = 3.141592653589793E+00 |
e = 2.718281828459045E+00 |
PROCEDURE IsNan(x: REAL): BOOLEAN |
возвращает TRUE, если x - не число |
PROCEDURE IsInf(x: REAL): BOOLEAN |
возвращает TRUE, если x - бесконечность |
PROCEDURE sqrt(x: REAL): REAL |
квадратный корень x |
PROCEDURE exp(x: REAL): REAL |
экспонента x |
PROCEDURE ln(x: REAL): REAL |
натуральный логарифм x |
PROCEDURE sin(x: REAL): REAL |
синус x |
PROCEDURE cos(x: REAL): REAL |
косинус x |
PROCEDURE tan(x: REAL): REAL |
тангенс x |
PROCEDURE arcsin(x: REAL): REAL |
арксинус x |
PROCEDURE arccos(x: REAL): REAL |
арккосинус x |
PROCEDURE arctan(x: REAL): REAL |
арктангенс x |
PROCEDURE arctan2(y, x: REAL): REAL |
арктангенс y/x |
PROCEDURE power(base, exponent: REAL): REAL |
возведение числа base в степень exponent |
PROCEDURE log(base, x: REAL): REAL |
логарифм x по основанию base |
PROCEDURE sinh(x: REAL): REAL |
гиперболический синус x |
PROCEDURE cosh(x: REAL): REAL |
гиперболический косинус x |
PROCEDURE tanh(x: REAL): REAL |
гиперболический тангенс x |
PROCEDURE arsinh(x: REAL): REAL |
обратный гиперболический синус x |
PROCEDURE arcosh(x: REAL): REAL |
обратный гиперболический косинус x |
PROCEDURE artanh(x: REAL): REAL |
обратный гиперболический тангенс x |
PROCEDURE round(x: REAL): REAL |
округление x до ближайшего целого |
PROCEDURE frac(x: REAL): REAL; |
дробная часть числа x |
PROCEDURE floor(x: REAL): REAL |
наибольшее целое число (представление как REAL), |
не больше x: floor(1.2) = 1.0 |
PROCEDURE ceil(x: REAL): REAL |
наименьшее целое число (представление как REAL), |
не меньше x: ceil(1.2) = 2.0 |
PROCEDURE sgn(x: REAL): INTEGER |
если x > 0 возвращает 1 |
если x < 0 возвращает -1 |
если x = 0 возвращает 0 |
PROCEDURE fact(n: INTEGER): REAL |
факториал n |
------------------------------------------------------------------------------ |
MODULE File - работа с файловой системой |
CONST |
OPEN_R = 0 |
OPEN_W = 1 |
OPEN_RW = 2 |
SEEK_BEG = 0 |
SEEK_CUR = 1 |
SEEK_END = 2 |
PROCEDURE Create(FName: ARRAY OF CHAR): INTEGER |
создает новый файл с именем FName (полное имя с путем), |
открывет файл для записи и возвращает идентификатор файла |
(целое число), в случае ошибки, возвращает -1 |
PROCEDURE Open(FName: ARRAY OF CHAR; Mode: INTEGER): INTEGER |
открывает существующий файл с именем FName (полное имя с |
путем) в режиме Mode = (OPEN_R (только чтение), OPEN_W |
(только запись), OPEN_RW (чтение и запись)), возвращает |
идентификатор файла (целое число), в случае ошибки, |
возвращает -1 |
PROCEDURE Read(F, Buffer, Count: INTEGER): INTEGER |
Читает данные из файла в память. F - числовой идентификатор |
файла, Buffer - адрес области памяти, Count - количество байт, |
которое требуется прочитать из файла; возвращает количество |
байт, которое было прочитано из файла |
PROCEDURE Write(F, Buffer, Count: INTEGER): INTEGER |
Записывает данные из памяти в файл. F - числовой идентификатор |
файла, Buffer - адрес области памяти, Count - количество байт, |
которое требуется записать в файл; возвращает количество байт, |
которое было записано в файл |
PROCEDURE Seek(F, Offset, Origin: INTEGER): INTEGER |
устанавливает позицию чтения-записи файла с идентификатором F |
на Offset, относительно Origin = (SEEK_BEG - начало файла, |
SEEK_CUR - текущая позиция, SEEK_END - конец файла), |
возвращает позицию относительно начала файла, например: |
Seek(F, 0, 2) - устанавливает позицию на конец файла и |
возвращает длину файла; при ошибке возвращает -1 |
PROCEDURE Close(F: INTEGER) |
закрывает ранее открытый файл с идентификатором F |
PROCEDURE Delete(FName: ARRAY OF CHAR): BOOLEAN |
удаляет файл с именем FName (полное имя с путем), |
возвращает TRUE, если файл успешно удален |
PROCEDURE Exists(FName: ARRAY OF CHAR): BOOLEAN |
возвращает TRUE, если файл с именем FName (полное имя) |
существует |
PROCEDURE Load(FName: ARRAY OF CHAR; VAR Size: INTEGER): INTEGER |
загружает в память существующий файл с именем FName (полное имя с |
путем), возвращает адрес памяти, куда был загружен файл, |
записывает размер файла в параметр Size; |
при ошибке возвращает 0 |
PROCEDURE CreateDir(DirName: ARRAY OF CHAR): BOOLEAN |
создает папку с именем DirName, все промежуточные папки |
должны существовать. В случае ошибки, возвращает FALSE |
PROCEDURE RemoveDir(DirName: ARRAY OF CHAR): BOOLEAN |
удаляет пустую папку с именем DirName. В случае ошибки, |
возвращает FALSE |
PROCEDURE ExistsDir(DirName: ARRAY OF CHAR): BOOLEAN |
возвращает TRUE, если папка с именем DirName существует |
------------------------------------------------------------------------------ |
MODULE DateTime - дата, время |
CONST ERR = -7.0E5 |
PROCEDURE Now(VAR Year, Month, Day, Hour, Min, Sec, MSec: INTEGER) |
возвращает в параметрах компоненты текущей системной даты и |
времени |
PROCEDURE NowEncode(): REAL; |
возвращает текущую системную дату и |
время (представление REAL) |
PROCEDURE Encode(Year, Month, Day, |
Hour, Min, Sec, MSec: INTEGER): REAL |
возвращает дату, полученную из компонентов |
Year, Month, Day, Hour, Min, Sec, MSec; |
при ошибке возвращает константу ERR = -7.0E5 |
PROCEDURE Decode(Date: REAL; VAR Year, Month, Day, |
Hour, Min, Sec, MSec: INTEGER): BOOLEAN |
извлекает компоненты |
Year, Month, Day, Hour, Min, Sec, MSec из даты Date; |
при ошибке возвращает FALSE |
------------------------------------------------------------------------------ |
MODULE Args - параметры программы |
VAR argc: INTEGER |
количество параметров программы, включая имя |
исполняемого файла |
PROCEDURE GetArg(n: INTEGER; VAR s: ARRAY OF CHAR) |
записывает в строку s n-й параметр программы, |
нумерация параметров от 0 до argc - 1, |
нулевой параметр -- имя исполняемого файла |
------------------------------------------------------------------------------ |
MODULE Utils - разное |
PROCEDURE Utf8To16(source: ARRAY OF CHAR; |
VAR dest: ARRAY OF CHAR): INTEGER; |
преобразует символы строки source из кодировки UTF-8 в |
кодировку UTF-16, результат записывает в строку dest, |
возвращает количество 16-битных символов, записанных в dest |
PROCEDURE PutSeed(seed: INTEGER) |
Инициализация генератора случайных чисел целым числом seed |
PROCEDURE Rnd(range: INTEGER): INTEGER |
Целые случайные числа в диапазоне 0 <= x < range |
------------------------------------------------------------------------------ |
MODULE WINAPI - привязки к некоторым API-функциям Windows |
/programs/develop/oberon07/Docs/x86.txt |
---|
0,0 → 1,358 |
Компилятор языка программирования Oberon-07/16 для i486 |
Windows/Linux/KolibriOS. |
------------------------------------------------------------------------------ |
Параметры командной строки |
Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или |
UTF-8 с BOM-сигнатурой. |
Выход - испоняемый файл формата PE32, ELF или MENUET01/MSCOFF. |
Параметры: |
1) имя главного модуля |
2) тип приложения |
"win32con" - Windows console |
"win32gui" - Windows GUI |
"win32dll" - Windows DLL |
"linux32exe" - Linux ELF-EXEC |
"linux32so" - Linux ELF-SO |
"kosexe" - KolibriOS |
"kosdll" - KolibriOS DLL |
3) необязательные параметры-ключи |
-out <file_name> имя результирующего файла; по умолчанию, |
совпадает с именем главного модуля, но с другим расширением |
(соответствует типу исполняемого файла) |
-stk <size> размер стэка в мегабайтах (по умолчанию 2 Мб, |
допустимо от 1 до 32 Мб) |
-nochk <"ptibcwra"> отключить проверки при выполнении (см. ниже) |
-ver <major.minor> версия программы (только для kosdll) |
параметр -nochk задается в виде строки из символов: |
"p" - указатели |
"t" - типы |
"i" - индексы |
"b" - неявное приведение INTEGER к BYTE |
"c" - диапазон аргумента функции CHR |
"w" - диапазон аргумента функции WCHR |
"r" - эквивалентно "bcw" |
"a" - все проверки |
Порядок символов может быть любым. Наличие в строке того или иного |
символа отключает соответствующую проверку. |
Например: -nochk it - отключить проверку индексов и охрану типа. |
-nochk a - отключить все отключаемые проверки. |
Например: |
Compiler.exe "C:\example.ob07" win32con -out "C:\example.exe" -stk 1 |
Compiler.exe "C:\example.ob07" win32dll -out "C:\example.dll" |
Compiler.exe "C:\example.ob07" win32gui -out "C:\example.exe" -stk 4 |
Compiler.exe "C:\example.ob07" win32con -out "C:\example.exe" -nochk pti |
Compiler.kex "/tmp0/1/example.ob07" kosexe -out "/tmp0/1/example.kex" -stk 4 |
Compiler.kex "/tmp0/1/example.ob07" kosdll -out "/tmp0/1/mydll.obj" -ver 2.7 |
Compiler.exe "C:\example.ob07" linux32exe -out "C:\example" -stk 1 -nochk a |
В случае успешной компиляции, компилятор передает код завершения 0, иначе 1. |
При работе компилятора в KolibriOS, код завершения не передается. |
------------------------------------------------------------------------------ |
Отличия от оригинала |
1. Расширен псевдомодуль SYSTEM |
2. В идентификаторах допускается символ "_" |
3. Добавлены системные флаги |
4. Усовершенствован оператор CASE (добавлены константные выражения в |
метках вариантов и необязательная ветка ELSE) |
5. Расширен набор стандартных процедур |
6. Семантика охраны/проверки типа уточнена для нулевого указателя |
7. Добавлены однострочные комментарии (начинаются с пары символов "//") |
8. Разрешено наследование от типа-указателя |
9. Добавлен синтаксис для импорта процедур из внешних библиотек |
10. "Строки" можно заключать также в одиночные кавычки: 'строка' |
11. Добавлен тип WCHAR |
------------------------------------------------------------------------------ |
Особенности реализации |
1. Основные типы |
Тип Диапазон значений Размер, байт |
INTEGER -2147483648 .. 2147483647 4 |
REAL 4.94E-324 .. 1.70E+308 8 |
CHAR символ ASCII (0X .. 0FFX) 1 |
BOOLEAN FALSE, TRUE 1 |
SET множество из целых чисел {0 .. 31} 4 |
BYTE 0 .. 255 1 |
WCHAR символ юникода (0X .. 0FFFFX) 2 |
2. Максимальная длина идентификаторов - 1024 символов |
3. Максимальная длина строковых констант - 1024 символов (UTF-8) |
4. Максимальная размерность открытых массивов - 5 |
5. Процедура NEW заполняет нулями выделенный блок памяти |
6. Глобальные и локальные переменные инициализируются нулями |
7. В отличие от многих Oberon-реализаций, сборщик мусора и динамическая |
модульность отсутствуют |
8. Тип BYTE в выражениях всегда приводится к INTEGER |
9. Контроль переполнения значений выражений не производится |
10. Ошибки времени выполнения: |
1 ASSERT(x), при x = FALSE |
2 разыменование нулевого указателя |
3 целочисленное деление на неположительное число |
4 вызов процедуры через процедурную переменную с нулевым значением |
5 ошибка охраны типа |
6 нарушение границ массива |
7 непредусмотренное значение выражения в операторе CASE |
8 ошибка копирования массивов v := x, если LEN(v) < LEN(x) |
9 CHR(x), если (x < 0) OR (x > 255) |
10 WCHR(x), если (x < 0) OR (x > 65535) |
11 неявное приведение x:INTEGER к v:BYTE, если (x < 0) OR (x > 255) |
------------------------------------------------------------------------------ |
Псевдомодуль SYSTEM |
Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры, |
ошибки при использовании процедур псевдомодуля SYSTEM могут привести к |
повреждению данных времени выполнения и аварийному завершению программы. |
PROCEDURE ADR(v: любой тип): INTEGER |
v - переменная или процедура; |
возвращает адрес v |
PROCEDURE SADR(x: строковая константа (CHAR UTF-8)): INTEGER |
возвращает адрес x |
PROCEDURE WSADR(x: строковая константа (WCHAR)): INTEGER |
возвращает адрес x |
PROCEDURE SIZE(T): INTEGER |
возвращает размер типа T |
PROCEDURE TYPEID(T): INTEGER |
T - тип-запись или тип-указатель, |
возвращает номер типа в таблице типов-записей |
PROCEDURE INF(): REAL |
возвращает специальное вещественное значение "бесконечность" |
PROCEDURE GET(a: INTEGER; |
VAR v: любой основной тип, PROCEDURE, POINTER) |
v := Память[a] |
PROCEDURE PUT(a: INTEGER; x: любой основной тип, PROCEDURE, POINTER) |
Память[a] := x; |
Если x: BYTE или x: WCHAR, то значение x будет расширено |
до 32 бит, для записи байтов использовать SYSTEM.PUT8, |
для WCHAR -- SYSTEM.PUT16 |
PROCEDURE PUT8(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR) |
Память[a] := младшие 8 бит (x) |
PROCEDURE PUT16(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR) |
Память[a] := младшие 16 бит (x) |
PROCEDURE MOVE(Source, Dest, n: INTEGER) |
Копирует 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(byte1, byte2,... : INTEGER) |
Вставка машинного кода, |
byte1, byte2 ... - константы в диапазоне 0..255, |
например: |
SYSTEM.CODE(08BH, 045H, 008H) (* mov eax, dword [ebp + 08h] *) |
Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях. |
------------------------------------------------------------------------------ |
Системные флаги |
При объявлении процедурных типов и глобальных процедур, после ключевого |
слова PROCEDURE может быть указан флаг соглашения о вызове: [stdcall], |
[ccall], [ccall16], [windows], [linux]. Например: |
PROCEDURE [ccall] MyProc (x, y, z: INTEGER): INTEGER; |
Если указан флаг [ccall16], то принимается соглашение ccall, но перед |
вызовом указатель стэка будет выравнен по границе 16 байт. |
Флаг [windows] - синоним для [stdcall], [linux] - синоним для [ccall16]. |
Знак "-" после имени флага ([stdcall-], [linux-], ...) означает, что |
результат процедуры можно игнорировать (не допускается для типа REAL). |
При объявлении типов-записей, после ключевого слова RECORD может быть |
указан флаг [noalign]. Флаг [noalign] означает отсутствие выравнивания полей |
записи. Записи с системным флагом не могут иметь базовый тип и не могут быть |
базовыми типами для других записей. |
Для использования системных флагов, требуется импортировать SYSTEM. |
------------------------------------------------------------------------------ |
Оператор CASE |
Синтаксис оператора CASE: |
CaseStatement = |
CASE Expression OF Сase {"|" Сase} |
[ELSE StatementSequence] END. |
Case = [CaseLabelList ":" StatementSequence]. |
CaseLabelList = CaseLabels {"," CaseLabels}. |
CaseLabels = ConstExpression [".." ConstExpression]. |
Например: |
CASE x OF |
|-1: DoSomething1 |
| 1: DoSomething2 |
| 0: DoSomething3 |
ELSE |
DoSomething4 |
END |
В метках вариантов можно использовать константные выражения, ветка ELSE |
необязательна. Если значение x не соответствует ни одному варианту и ELSE |
отсутствует, то программа прерывается с ошибкой времени выполнения. |
------------------------------------------------------------------------------ |
Тип WCHAR |
Тип WCHAR добавлен в язык для удобной поддежки юникода. Для типов WCHAR и |
ARRAY OF WCHAR допускаются все те же операции, как для типов CHAR и |
ARRAY OF CHAR, за исключением встроенной процедуры CHR, которая возвращает |
только тип CHAR. Для получения значения типа WCHAR, следует использовать |
процедуру WCHR вместо CHR. Для правильной работы с типом, необходимо сохранять |
исходный код в кодировке UTF-8 c BOM. |
------------------------------------------------------------------------------ |
Проверка и охрана типа нулевого указателя |
Оригинальное сообщение о языке не определяет поведение программы при |
выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих |
Oberon-реализациях выполнение такой операции приводит к ошибке времени |
выполнения. В данной реализации охрана типа нулевого указателя не приводит к |
ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет |
значительно сократить частоту применения охраны типа. |
------------------------------------------------------------------------------ |
Дополнительные стандартные процедуры |
DISPOSE (VAR v: любой_указатель) |
Освобождает память, выделенную процедурой NEW для |
динамической переменной v^, и присваивает переменной v |
значение NIL. |
COPY (x: ARRAY OF CHAR/WCHAR; VAR v: ARRAY OF CHAR/WCHAR); |
v := x; |
Если LEN(v) < LEN(x), то строка x будет скопирована |
не полностью |
LSR (x, n: INTEGER): INTEGER |
Логический сдвиг x на n бит вправо. |
MIN (a, b: INTEGER): INTEGER |
Минимум из двух значений. |
MAX (a, b: INTEGER): INTEGER |
Максимум из двух значений. |
BITS (x: INTEGER): SET |
Интерпретирует x как значение типа SET. |
Выполняется на этапе компиляции. |
LENGTH (s: ARRAY OF CHAR/WCHAR): INTEGER |
Длина 0X-завершенной строки s, без учета символа 0X. |
Если символ 0X отсутствует, функция возвращает длину |
массива s. s не может быть константой. |
WCHR (n: INTEGER): WCHAR |
Преобразование типа, аналогично CHR(n: INTEGER): CHAR |
------------------------------------------------------------------------------ |
Импортированные процедуры |
Синтаксис импорта: |
PROCEDURE [callconv, "library", "function"] proc_name (FormalParam): Type; |
- callconv -- соглашение о вызове |
- "library" -- имя файла динамической библиотеки |
- "function" -- имя импортируемой процедуры |
например: |
PROCEDURE [windows, "kernel32.dll", "ExitProcess"] exit (code: INTEGER); |
PROCEDURE [stdcall, "Console.obj", "con_exit"] exit (bCloseWindow: BOOLEAN); |
В конце объявления может быть добавлено (необязательно) "END proc_name;" |
Объявления импортированных процедур должны располагаться в глобальной |
области видимости модуля после объявления переменных, вместе с объявлением |
"обычных" процедур, от которых импортированные отличаются только отсутствием |
тела процедуры. В остальном, к таким процедурам применимы те же правила: |
их можно вызвать, присвоить процедурной переменной или получить адрес. |
Так как импортированная процедура всегда имеет явное указание соглашения о |
вызове, то совместимый процедурный тип тоже должен быть объявлен с указанием |
соглашения о вызове: |
VAR |
ExitProcess: PROCEDURE [windows] (code: INTEGER); |
con_exit: PROCEDURE [stdcall] (bCloseWindow: BOOLEAN); |
В KolibriOS импортировать процедуры можно только из библиотек, размещенных |
в /rd/1/lib. Импортировать и вызывать функции инициализации библиотек |
(lib_init, START) при этом не нужно. |
Для Linux, импортированные процедуры не реализованы. |
------------------------------------------------------------------------------ |
Скрытые параметры процедур |
Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке |
формальных параметров, но учитываются компилятором при трансляции вызовов. |
Это возможно в следующих случаях: |
1. Процедура имеет формальный параметр открытый массив: |
PROCEDURE Proc (x: ARRAY OF ARRAY OF REAL); |
Вызов транслируется так: |
Proc(LEN(x), LEN(x[0]), SYSTEM.ADR(x)) |
2. Процедура имеет формальный параметр-переменную типа RECORD: |
PROCEDURE Proc (VAR x: Rec); |
Вызов транслируется так: |
Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x)) |
------------------------------------------------------------------------------ |
Модуль RTL |
Все программы неявно используют модуль RTL. Компилятор транслирует |
некоторые операции (проверка и охрана типа, сравнение строк, сообщения об |
ошибках времени выполнения и др.) как вызовы процедур этого модуля. Не |
следует вызывать эти процедуры явно. |
Сообщения об ошибках времени выполнения выводятся в диалоговых окнах |
(Windows), в терминал (Linux), на доску отладки (KolibriOS). |
------------------------------------------------------------------------------ |
Модуль API |
Существуют несколько реализаций модуля API (для различных ОС). |
Как и модуль RTL, модуль API не предназначен для прямого использования. |
Он обеспечивает связь RTL с ОС. |
------------------------------------------------------------------------------ |
Генерация исполняемых файлов DLL |
Разрешается экспортировать только процедуры. Для этого, процедура должна |
находиться в главном модуле программы, и ее имя должно быть отмечено символом |
экспорта ("*"). KolibriOS DLL всегда экспортируют идентификаторы "version" |
(версия программы) и "lib_init" - адрес процедуры инициализации DLL: |
PROCEDURE [stdcall] lib_init (): INTEGER |
Эта процедура должна быть вызвана перед использованием DLL. |
Процедура всегда возвращает 1. |
/programs/develop/oberon07/Docs/x86_64.txt |
---|
0,0 → 1,346 |
Компилятор языка программирования Oberon-07/16 для x86_64 |
Windows/Linux |
------------------------------------------------------------------------------ |
Параметры командной строки |
Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или |
UTF-8 с BOM-сигнатурой. |
Выход - испоняемый файл формата PE32+ или ELF64. |
Параметры: |
1) имя главного модуля |
2) тип приложения |
"win64con" - Windows64 console |
"win64gui" - Windows64 GUI |
"win64dll" - Windows64 DLL |
"linux64exe" - Linux ELF64-EXEC |
"linux64so" - Linux ELF64-SO |
3) необязательные параметры-ключи |
-out <file_name> имя результирующего файла; по умолчанию, |
совпадает с именем главного модуля, но с другим расширением |
(соответствует типу исполняемого файла) |
-stk <size> размер стэка в мегабайтах (по умолчанию 2 Мб, |
допустимо от 1 до 32 Мб) |
-nochk <"ptibcwra"> отключить проверки при выполнении |
параметр -nochk задается в виде строки из символов: |
"p" - указатели |
"t" - типы |
"i" - индексы |
"b" - неявное приведение INTEGER к BYTE |
"c" - диапазон аргумента функции CHR |
"w" - диапазон аргумента функции WCHR |
"r" - эквивалентно "bcw" |
"a" - все проверки |
Порядок символов может быть любым. Наличие в строке того или иного |
символа отключает соответствующую проверку. |
Например: -nochk it - отключить проверку индексов и охрану типа. |
-nochk a - отключить все отключаемые проверки. |
Например: |
Compiler.exe "C:\example.ob07" win64con -out "C:\example.exe" -stk 1 |
Compiler.exe "C:\example.ob07" win64dll -out "C:\example.dll" -nochk pti |
Compiler "source/Compiler.ob07" linux64exe -out "source/Compiler" -nochk a |
В случае успешной компиляции, компилятор передает код завершения 0, иначе 1. |
------------------------------------------------------------------------------ |
Отличия от оригинала |
1. Расширен псевдомодуль SYSTEM |
2. В идентификаторах допускается символ "_" |
3. Добавлены системные флаги |
4. Усовершенствован оператор CASE (добавлены константные выражения в |
метках вариантов и необязательная ветка ELSE) |
5. Расширен набор стандартных процедур |
6. Семантика охраны/проверки типа уточнена для нулевого указателя |
7. Добавлены однострочные комментарии (начинаются с пары символов "//") |
8. Разрешено наследование от типа-указателя |
9. Добавлен синтаксис для импорта процедур из внешних библиотек |
10. "Строки" можно заключать также в одиночные кавычки: 'строка' |
11. Добавлен тип WCHAR |
------------------------------------------------------------------------------ |
Особенности реализации |
1. Основные типы |
Тип Диапазон значений Размер, байт |
INTEGER -9223372036854775808 .. 9223372036854775807 8 |
REAL 4.94E-324 .. 1.70E+308 8 |
CHAR символ ASCII (0X .. 0FFX) 1 |
BOOLEAN FALSE, TRUE 1 |
SET множество из целых чисел {0 .. 63} 8 |
BYTE 0 .. 255 1 |
WCHAR символ юникода (0X .. 0FFFFX) 2 |
2. Максимальная длина идентификаторов - 1024 символов |
3. Максимальная длина строковых констант - 1024 символов (UTF-8) |
4. Максимальная размерность открытых массивов - 5 |
5. Процедура NEW заполняет нулями выделенный блок памяти |
6. Глобальные и локальные переменные инициализируются нулями |
7. В отличие от многих Oberon-реализаций, сборщик мусора и динамическая |
модульность отсутствуют |
8. Тип BYTE в выражениях всегда приводится к INTEGER |
9. Контроль переполнения значений выражений не производится |
10. Ошибки времени выполнения: |
1 ASSERT(x), при x = FALSE |
2 разыменование нулевого указателя |
3 целочисленное деление на неположительное число |
4 вызов процедуры через процедурную переменную с нулевым значением |
5 ошибка охраны типа |
6 нарушение границ массива |
7 непредусмотренное значение выражения в операторе CASE |
8 ошибка копирования массивов v := x, если LEN(v) < LEN(x) |
9 CHR(x), если (x < 0) OR (x > 255) |
10 WCHR(x), если (x < 0) OR (x > 65535) |
11 неявное приведение x:INTEGER к v:BYTE, если (x < 0) OR (x > 255) |
------------------------------------------------------------------------------ |
Псевдомодуль SYSTEM |
Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры, |
ошибки при использовании процедур псевдомодуля SYSTEM могут привести к |
повреждению данных времени выполнения и аварийному завершению программы. |
PROCEDURE ADR(v: любой тип): INTEGER |
v - переменная или процедура; |
возвращает адрес v |
PROCEDURE SADR(x: строковая константа (CHAR UTF-8)): INTEGER |
возвращает адрес x |
PROCEDURE WSADR(x: строковая константа (WCHAR)): INTEGER |
возвращает адрес x |
PROCEDURE SIZE(T): INTEGER |
возвращает размер типа T |
PROCEDURE TYPEID(T): INTEGER |
T - тип-запись или тип-указатель, |
возвращает номер типа в таблице типов-записей |
PROCEDURE INF(): REAL |
возвращает специальное вещественное значение "бесконечность" |
PROCEDURE GET(a: INTEGER; |
VAR v: любой основной тип, PROCEDURE, POINTER) |
v := Память[a] |
PROCEDURE PUT(a: INTEGER; x: любой основной тип, PROCEDURE, POINTER) |
Память[a] := x; |
Если x: BYTE или x: WCHAR, то значение x будет расширено |
до 64 бит, для записи байтов использовать SYSTEM.PUT8, |
для WCHAR -- SYSTEM.PUT16 |
PROCEDURE PUT8(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR) |
Память[a] := младшие 8 бит (x) |
PROCEDURE PUT16(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR) |
Память[a] := младшие 16 бит (x) |
PROCEDURE PUT32(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR) |
Память[a] := младшие 32 бит (x) |
PROCEDURE MOVE(Source, Dest, n: INTEGER) |
Копирует 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(byte1, byte2,... : BYTE) |
Вставка машинного кода, |
byte1, byte2 ... - константы в диапазоне 0..255, |
например: |
SYSTEM.CODE(048H,08BH,045H,010H) (* mov rax,qword[rbp+16] *) |
Также, в модуле SYSTEM определен тип CARD32 (4 байта). Для типа CARD32 не |
допускаются никакие явные операции, за исключением присваивания. |
Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях. |
------------------------------------------------------------------------------ |
Системные флаги |
При объявлении процедурных типов и глобальных процедур, после ключевого |
слова PROCEDURE может быть указан флаг соглашения о вызове: [win64], [systemv], |
[windows], [linux]. |
Например: |
PROCEDURE [win64] MyProc (x, y, z: INTEGER): INTEGER; |
Флаг [windows] - синоним для [win64], [linux] - синоним для [systemv]. |
Знак "-" после имени флага ([win64-], [linux-], ...) означает, что |
результат процедуры можно игнорировать (не допускается для типа REAL). |
Если флаг не указан, то принимается внутреннее соглашение о вызове. |
[win64] и [systemv] используются для связи с операционной системой и внешними |
приложениями. |
При объявлении типов-записей, после ключевого слова RECORD может быть |
указан флаг [noalign]. Флаг [noalign] означает отсутствие выравнивания полей |
записи. Записи с системным флагом не могут иметь базовый тип и не могут быть |
базовыми типами для других записей. |
Для использования системных флагов, требуется импортировать SYSTEM. |
------------------------------------------------------------------------------ |
Оператор CASE |
Синтаксис оператора CASE: |
CaseStatement = |
CASE Expression OF Сase {"|" Сase} |
[ELSE StatementSequence] END. |
Case = [CaseLabelList ":" StatementSequence]. |
CaseLabelList = CaseLabels {"," CaseLabels}. |
CaseLabels = ConstExpression [".." ConstExpression]. |
Например: |
CASE x OF |
|-1: DoSomething1 |
| 1: DoSomething2 |
| 0: DoSomething3 |
ELSE |
DoSomething4 |
END |
В метках вариантов можно использовать константные выражения, ветка ELSE |
необязательна. Если значение x не соответствует ни одному варианту и ELSE |
отсутствует, то программа прерывается с ошибкой времени выполнения. |
------------------------------------------------------------------------------ |
Тип WCHAR |
Тип WCHAR добавлен в язык для удобной поддежки юникода. Для типов WCHAR и |
ARRAY OF WCHAR допускаются все те же операции, как для типов CHAR и |
ARRAY OF CHAR, за исключением встроенной процедуры CHR, которая возвращает |
только тип CHAR. Для получения значения типа WCHAR, следует использовать |
процедуру WCHR вместо CHR. Для правильной работы с типом, необходимо сохранять |
исходный код в кодировке UTF-8 c BOM. |
------------------------------------------------------------------------------ |
Проверка и охрана типа нулевого указателя |
Оригинальное сообщение о языке не определяет поведение программы при |
выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих |
Oberon-реализациях выполнение такой операции приводит к ошибке времени |
выполнения. В данной реализации охрана типа нулевого указателя не приводит к |
ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет |
значительно сократить частоту применения охраны типа. |
------------------------------------------------------------------------------ |
Дополнительные стандартные процедуры |
DISPOSE (VAR v: любой_указатель) |
Освобождает память, выделенную процедурой NEW для |
динамической переменной v^, и присваивает переменной v |
значение NIL. |
COPY (x: ARRAY OF CHAR/WCHAR; VAR v: ARRAY OF CHAR/WCHAR); |
v := x; |
Если LEN(v) < LEN(x), то строка x будет скопирована |
не полностью |
LSR (x, n: INTEGER): INTEGER |
Логический сдвиг x на n бит вправо. |
MIN (a, b: INTEGER): INTEGER |
Минимум из двух значений. |
MAX (a, b: INTEGER): INTEGER |
Максимум из двух значений. |
BITS (x: INTEGER): SET |
Интерпретирует x как значение типа SET. |
Выполняется на этапе компиляции. |
LENGTH (s: ARRAY OF CHAR/WCHAR): INTEGER |
Длина 0X-завершенной строки s, без учета символа 0X. |
Если символ 0X отсутствует, функция возвращает длину |
массива s. s не может быть константой. |
WCHR (n: INTEGER): WCHAR |
Преобразование типа, аналогично CHR(n: INTEGER): CHAR |
------------------------------------------------------------------------------ |
Импортированные процедуры |
Синтаксис импорта: |
PROCEDURE [callconv, "library", "function"] proc_name (FormalParam): Type; |
- callconv -- соглашение о вызове |
- "library" -- имя файла динамической библиотеки |
- "function" -- имя импортируемой процедуры |
например: |
PROCEDURE [win64, "kernel32.dll", "ExitProcess"] exit (code: INTEGER); |
В конце объявления может быть добавлено (необязательно) "END proc_name;" |
Объявления импортированных процедур должны располагаться в глобальной |
области видимости модуля после объявления переменных, вместе с объявлением |
"обычных" процедур, от которых импортированные отличаются только отсутствием |
тела процедуры. В остальном, к таким процедурам применимы те же правила: |
их можно вызвать, присвоить процедурной переменной или получить адрес. |
Так как импортированная процедура всегда имеет явное указание соглашения о |
вызове, то совместимый процедурный тип тоже должен быть объявлен с указанием |
соглашения о вызове: |
VAR |
ExitProcess: PROCEDURE [win64] (code: INTEGER); |
Для Linux, импортированные процедуры не реализованы. |
------------------------------------------------------------------------------ |
Скрытые параметры процедур |
Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке |
формальных параметров, но учитываются компилятором при трансляции вызовов. |
Это возможно в следующих случаях: |
1. Процедура имеет формальный параметр открытый массив: |
PROCEDURE Proc (x: ARRAY OF ARRAY OF REAL); |
Вызов транслируется так: |
Proc(LEN(x), LEN(x[0]), SYSTEM.ADR(x)) |
2. Процедура имеет формальный параметр-переменную типа RECORD: |
PROCEDURE Proc (VAR x: Rec); |
Вызов транслируется так: |
Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x)) |
------------------------------------------------------------------------------ |
Модуль RTL |
Все программы неявно используют модуль RTL. Компилятор транслирует |
некоторые операции (проверка и охрана типа, сравнение строк, сообщения об |
ошибках времени выполнения и др.) как вызовы процедур этого модуля. Не |
следует вызывать эти процедуры явно. |
Сообщения об ошибках времени выполнения выводятся в диалоговых окнах |
(Windows), в терминал (Linux). |
------------------------------------------------------------------------------ |
Модуль API |
Существуют несколько реализаций модуля API (для различных ОС). |
Как и модуль RTL, модуль API не предназначен для прямого использования. |
Он обеспечивает связь RTL с ОС. |
------------------------------------------------------------------------------ |
Генерация исполняемых файлов DLL |
Разрешается экспортировать только процедуры. Для этого, процедура должна |
находиться в главном модуле программы, ее имя должно быть отмечено символом |
экспорта ("*") и должно быть указано соглашение о вызове. |
/programs/develop/oberon07/Docs/Oberon07.Report_2016_05_03.pdf |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/programs/develop/oberon07/GitHub.url |
---|
0,0 → 1,2 |
[InternetShortcut] |
URL=https://github.com/AntKrotov/oberon-07-compiler |
/programs/develop/oberon07/Lib/STM32CM3/FPU.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/STM32CM3/RTL.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/RVM32I/FPU.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/RVM32I/HOST.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/RVM32I/RTL.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/RVM32I/Trap.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/RVM32I/Out.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Math/MathRound.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Math/Rand.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Math/MathStat.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Math/RandExt.ob07 |
---|
File deleted |
/programs/develop/oberon07/Lib/Math/MathBits.ob07 |
---|
File deleted |
/programs/develop/oberon07/Lib/Math/CMath.ob07 |
---|
File deleted |
/programs/develop/oberon07/Lib/MSP430/MSP430.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/KolibriOS/API.ob07 |
---|
12,8 → 12,6 |
CONST |
eol* = 0DX + 0AX; |
MAX_SIZE = 16 * 400H; |
HEAP_SIZE = 1 * 100000H; |
35,8 → 33,9 |
CriticalSection: CRITICAL_SECTION; |
_import*, multi: BOOLEAN; |
import*, multi: BOOLEAN; |
eol*: ARRAY 3 OF CHAR; |
base*: INTEGER; |
285,24 → 284,24 |
BEGIN |
OutString("import error: "); |
IF K.imp_error.error = 1 THEN |
OutString("can't load '"); OutString(K.imp_error.lib) |
OutString("can't load "); OutString(K.imp_error.lib) |
ELSIF K.imp_error.error = 2 THEN |
OutString("not found '"); OutString(K.imp_error.proc); OutString("' in '"); OutString(K.imp_error.lib) |
OutString("not found "); OutString(K.imp_error.proc); OutString(" in "); OutString(K.imp_error.lib) |
END; |
OutString("'"); |
OutLn |
END imp_error; |
PROCEDURE init* (import_, code: INTEGER); |
PROCEDURE init* (_import, code: INTEGER); |
BEGIN |
multi := FALSE; |
eol[0] := 0DX; eol[1] := 0AX; eol[2] := 0X; |
base := code - SizeOfHeader; |
K.sysfunc2(68, 11); |
InitializeCriticalSection(CriticalSection); |
K._init; |
_import := (K.dll_Load(import_) = 0) & (K.imp_error.error = 0); |
IF ~_import THEN |
import := (K.dll_Load(_import) = 0) & (K.imp_error.error = 0); |
IF ~import THEN |
imp_error |
END |
END init; |
/programs/develop/oberon07/Lib/KolibriOS/ColorDlg.ob07 |
---|
1,5 → 1,5 |
(* |
Copyright 2016, 2018, 2020 Anton Krotov |
Copyright 2016, 2018 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 |
24,7 → 24,7 |
DRAW_WINDOW = PROCEDURE; |
TDialog = RECORD |
_type, |
type, |
procinfo, |
com_area_name, |
com_area, |
61,7 → 61,7 |
IF res # NIL THEN |
res.s_com_area_name := "FFFFFFFF_color_dlg"; |
res.com_area := 0; |
res._type := 0; |
res.type := 0; |
res.color_type := 0; |
res.procinfo := sys.ADR(res.procinf[0]); |
res.com_area_name := sys.ADR(res.s_com_area_name[0]); |
/programs/develop/oberon07/Lib/KolibriOS/HOST.ob07 |
---|
13,7 → 13,7 |
CONST |
slash* = "/"; |
eol* = 0DX + 0AX; |
OS* = "KOS"; |
bit_depth* = RTL.bit_depth; |
maxint* = RTL.maxint; |
24,8 → 24,6 |
TYPE |
DAYS = ARRAY 12, 31, 2 OF INTEGER; |
FNAME = ARRAY 520 OF CHAR; |
FS = POINTER TO rFS; |
54,11 → 52,11 |
Console: BOOLEAN; |
days: DAYS; |
Params: ARRAY MAX_PARAM, 2 OF INTEGER; |
argc*: INTEGER; |
eol*: ARRAY 3 OF CHAR; |
maxreal*: REAL; |
275,10 → 273,6 |
END FileOpen; |
PROCEDURE chmod* (FName: ARRAY OF CHAR); |
END chmod; |
PROCEDURE GetTickCount* (): INTEGER; |
RETURN K.sysfunc2(26, 9) |
END GetTickCount; |
388,9 → 382,9 |
s[j] := c; |
INC(j) |
END; |
INC(i) |
END |
INC(i); |
END; |
END; |
s[j] := 0X |
END GetArg; |
414,9 → 408,9 |
END isRelative; |
PROCEDURE UnixTime* (): INTEGER; |
PROCEDURE now* (VAR year, month, day, hour, min, sec: INTEGER); |
VAR |
date, time, year, month, day, hour, min, sec: INTEGER; |
date, time: INTEGER; |
BEGIN |
date := K.sysfunc1(29); |
452,26 → 446,22 |
sec := (time MOD 16) * 10 + sec; |
time := time DIV 16; |
INC(year, 2000) |
year := year + 2000 |
END now; |
RETURN ((year - 1970) * 365 + days[month - 1, day - 1, ORD(year DIV 4 = 0)] + (year - 1969) DIV 4) * 86400 + hour * 3600 + min * 60 + sec |
PROCEDURE UnixTime* (): INTEGER; |
RETURN 0 |
END UnixTime; |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
BEGIN |
SYSTEM.GET32(SYSTEM.ADR(x), a); |
SYSTEM.GET32(SYSTEM.ADR(x) + 4, b) |
RETURN a |
END splitf; |
PROCEDURE d2s* (x: REAL): INTEGER; |
VAR |
h, l, s, e: INTEGER; |
BEGIN |
e := splitf(x, l, h); |
SYSTEM.GET(SYSTEM.ADR(x), l); |
SYSTEM.GET(SYSTEM.ADR(x) + 4, h); |
s := ASR(h, 31) MOD 2; |
e := (h DIV 100000H) MOD 2048; |
490,7 → 480,7 |
l := 0 |
ELSIF e = 2047 THEN |
e := 1151; |
IF (h MOD 100000H # 0) OR (BITS(l) * {0..31} # {}) THEN |
IF (h MOD 100000H # 0) OR (l # 0) THEN |
h := 80000H; |
l := 0 |
END |
501,55 → 491,21 |
END d2s; |
PROCEDURE init (VAR days: DAYS); |
VAR |
i, j, n0, n1: INTEGER; |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
BEGIN |
SYSTEM.GET(SYSTEM.ADR(x), a); |
SYSTEM.GET(SYSTEM.ADR(x) + 4, b) |
RETURN a |
END splitf; |
FOR i := 0 TO 11 DO |
FOR j := 0 TO 30 DO |
days[i, j, 0] := 0; |
days[i, j, 1] := 0; |
END |
END; |
days[ 1, 28, 0] := -1; |
FOR i := 0 TO 1 DO |
days[ 1, 29, i] := -1; |
days[ 1, 30, i] := -1; |
days[ 3, 30, i] := -1; |
days[ 5, 30, i] := -1; |
days[ 8, 30, i] := -1; |
days[10, 30, i] := -1; |
END; |
n0 := 0; |
n1 := 0; |
FOR i := 0 TO 11 DO |
FOR j := 0 TO 30 DO |
IF days[i, j, 0] = 0 THEN |
days[i, j, 0] := n0; |
INC(n0) |
END; |
IF days[i, j, 1] = 0 THEN |
days[i, j, 1] := n1; |
INC(n1) |
END |
END |
END; |
BEGIN |
eol[0] := 0DX; eol[1] := 0AX; eol[2] := 0X; |
maxreal := 1.9; |
PACK(maxreal, 1023); |
Console := API._import; |
Console := API.import; |
IF Console THEN |
con_init(-1, -1, -1, -1, SYSTEM.SADR("Oberon-07 for KolibriOS")) |
END; |
ParamParse |
END init; |
BEGIN |
init(days) |
END HOST. |
/programs/develop/oberon07/Lib/KolibriOS/Math.ob07 |
---|
1,8 → 1,18 |
(* |
BSD 2-Clause License |
Copyright 2013, 2014, 2018, 2019 Anton Krotov |
Copyright (c) 2013-2014, 2018-2020 Anton Krotov |
All rights reserved. |
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 <http://www.gnu.org/licenses/>. |
*) |
MODULE Math; |
225,16 → 235,6 |
END frac; |
PROCEDURE sqri* (x: INTEGER): INTEGER; |
RETURN x * x |
END sqri; |
PROCEDURE sqrr* (x: REAL): REAL; |
RETURN x * x |
END sqrr; |
PROCEDURE arcsin* (x: REAL): REAL; |
RETURN arctan2(x, sqrt(1.0 - x * x)) |
END arcsin; |
349,40 → 349,6 |
END power; |
PROCEDURE ipower* (base: REAL; exponent: INTEGER): REAL; |
VAR |
i: INTEGER; |
a: REAL; |
BEGIN |
a := 1.0; |
IF base # 0.0 THEN |
IF exponent # 0 THEN |
IF exponent < 0 THEN |
base := 1.0 / base |
END; |
i := ABS(exponent); |
WHILE i > 0 DO |
WHILE ~ODD(i) DO |
i := LSR(i, 1); |
base := sqrr(base) |
END; |
DEC(i); |
a := a * base |
END |
ELSE |
a := 1.0 |
END |
ELSE |
ASSERT(exponent > 0); |
a := 0.0 |
END |
RETURN a |
END ipower; |
PROCEDURE sgn* (x: REAL): INTEGER; |
VAR |
res: INTEGER; |
415,36 → 381,4 |
END fact; |
PROCEDURE DegToRad* (x: REAL): REAL; |
RETURN x * (pi / 180.0) |
END DegToRad; |
PROCEDURE RadToDeg* (x: REAL): REAL; |
RETURN x * (180.0 / pi) |
END RadToDeg; |
(* Return hypotenuse of triangle *) |
PROCEDURE hypot* (x, y: REAL): REAL; |
VAR |
a: REAL; |
BEGIN |
x := ABS(x); |
y := ABS(y); |
IF x > y THEN |
a := x * sqrt(1.0 + sqrr(y / x)) |
ELSE |
IF x > 0.0 THEN |
a := y * sqrt(1.0 + sqrr(x / y)) |
ELSE |
a := y |
END |
END |
RETURN a |
END hypot; |
END Math. |
/programs/develop/oberon07/Lib/KolibriOS/OpenDlg.ob07 |
---|
1,5 → 1,5 |
(* |
Copyright 2016, 2018, 2020 Anton Krotov |
Copyright 2016, 2018 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 |
24,7 → 24,7 |
DRAW_WINDOW = PROCEDURE; |
TDialog = RECORD |
_type, |
type, |
procinfo, |
com_area_name, |
com_area, |
66,7 → 66,7 |
END |
END Show; |
PROCEDURE Create*(draw_window: DRAW_WINDOW; _type: INTEGER; def_path, filter: ARRAY OF CHAR): Dialog; |
PROCEDURE Create*(draw_window: DRAW_WINDOW; type: INTEGER; def_path, filter: ARRAY OF CHAR): Dialog; |
VAR res: Dialog; n, i: INTEGER; |
PROCEDURE replace(VAR str: ARRAY OF CHAR; c1, c2: CHAR); |
88,7 → 88,7 |
IF res.filter_area # NIL THEN |
res.s_com_area_name := "FFFFFFFF_open_dialog"; |
res.com_area := 0; |
res._type := _type; |
res.type := type; |
res.draw_window := draw_window; |
COPY(def_path, res.s_dir_default_path); |
COPY(filter, res.filter_area.filter); |
/programs/develop/oberon07/Lib/KolibriOS/RTL.ob07 |
---|
372,29 → 372,33 |
PROCEDURE IntToStr (x: INTEGER; VAR str: ARRAY OF CHAR); |
VAR |
i, a: INTEGER; |
i, a, b: INTEGER; |
c: CHAR; |
BEGIN |
i := 0; |
a := x; |
REPEAT |
INC(i); |
a := a DIV 10 |
UNTIL a = 0; |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
str[i] := 0X; |
REPEAT |
DEC(i); |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10 |
UNTIL x = 0 |
a := 0; |
b := i - 1; |
WHILE a < b DO |
c := str[a]; |
str[a] := str[b]; |
str[b] := c; |
INC(a); |
DEC(b) |
END; |
str[i] := 0X |
END IntToStr; |
PROCEDURE append (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); |
VAR |
n1, n2: INTEGER; |
n1, n2, i, j: INTEGER; |
BEGIN |
n1 := LENGTH(s1); |
402,12 → 406,19 |
ASSERT(n1 + n2 < LEN(s1)); |
SYSTEM.MOVE(SYSTEM.ADR(s2[0]), SYSTEM.ADR(s1[n1]), n2); |
s1[n1 + n2] := 0X |
i := 0; |
j := n1; |
WHILE i < n2 DO |
s1[j] := s2[i]; |
INC(i); |
INC(j) |
END; |
s1[j] := 0X |
END append; |
PROCEDURE [stdcall] _error* (modnum, _module, err, line: INTEGER); |
PROCEDURE [stdcall] _error* (module, err, line: INTEGER); |
VAR |
s, temp: ARRAY 1024 OF CHAR; |
426,9 → 437,11 |
|11: s := "BYTE out of range" |
END; |
append(s, API.eol + "module: "); PCharToStr(_module, temp); append(s, temp); |
append(s, API.eol + "line: "); IntToStr(line, temp); append(s, temp); |
append(s, API.eol); |
append(s, "module: "); PCharToStr(module, temp); append(s, temp); append(s, API.eol); |
append(s, "line: "); IntToStr(line, temp); append(s, temp); |
API.DebugMsg(SYSTEM.ADR(s[0]), name); |
API.exit_thread(0) |
/programs/develop/oberon07/Lib/KolibriOS/libimg.ob07 |
---|
1,5 → 1,5 |
(* |
Copyright 2016, 2018, 2020 KolibriOS team |
Copyright 2016, 2018 KolibriOS team |
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 |
203,7 → 203,7 |
img_create *: PROCEDURE (width, height, _type: INTEGER): INTEGER; |
img_create *: PROCEDURE (width, height, type: INTEGER): INTEGER; |
(* |
;;------------------------------------------------------------------------------------------------;; |
;? creates an Image structure and initializes some its fields ;; |
/programs/develop/oberon07/Lib/Linux32/File.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Linux32/In.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Linux32/Args.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Linux32/API.ob07 |
---|
12,34 → 12,54 |
CONST |
eol* = 0AX; |
RTLD_LAZY* = 1; |
BIT_DEPTH* = 32; |
RTLD_LAZY = 1; |
TYPE |
SOFINI = PROCEDURE; |
TP* = ARRAY 2 OF INTEGER; |
SOFINI* = PROCEDURE; |
VAR |
MainParam*, libc*: INTEGER; |
eol*: ARRAY 2 OF CHAR; |
MainParam*: INTEGER; |
libc*, librt*: INTEGER; |
dlopen* : PROCEDURE [linux] (filename, flag: INTEGER): INTEGER; |
dlsym* : PROCEDURE [linux] (handle, symbol: INTEGER): INTEGER; |
exit*, |
exit_thread* : PROCEDURE [linux] (code: INTEGER); |
puts : PROCEDURE [linux] (pStr: INTEGER); |
malloc : PROCEDURE [linux] (size: INTEGER): INTEGER; |
free : PROCEDURE [linux] (ptr: INTEGER); |
stdout*, |
stdin*, |
stderr* : INTEGER; |
malloc* : PROCEDURE [linux] (size: INTEGER): INTEGER; |
free* : PROCEDURE [linux] (ptr: INTEGER); |
_exit* : PROCEDURE [linux] (code: INTEGER); |
puts* : PROCEDURE [linux] (pStr: INTEGER); |
fwrite*, |
fread* : PROCEDURE [linux] (buffer, bytes, blocks, file: INTEGER): INTEGER; |
fopen* : PROCEDURE [linux] (fname, fmode: INTEGER): INTEGER; |
fclose* : PROCEDURE [linux] (file: INTEGER): INTEGER; |
clock_gettime* : PROCEDURE [linux] (clock_id: INTEGER; VAR tp: TP): INTEGER; |
time* : PROCEDURE [linux] (ptr: INTEGER): INTEGER; |
fini: SOFINI; |
PROCEDURE putc* (c: CHAR); |
VAR |
res: INTEGER; |
BEGIN |
res := fwrite(SYSTEM.ADR(c), 1, 1, stdout) |
END putc; |
PROCEDURE DebugMsg* (lpText, lpCaption: INTEGER); |
BEGIN |
puts(lpCaption); |
74,7 → 94,7 |
END _DISPOSE; |
PROCEDURE GetSym (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER); |
PROCEDURE GetProcAdr (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER); |
VAR |
sym: INTEGER; |
82,7 → 102,7 |
sym := dlsym(lib, SYSTEM.ADR(name[0])); |
ASSERT(sym # 0); |
SYSTEM.PUT(VarAdr, sym) |
END GetSym; |
END GetProcAdr; |
PROCEDURE init* (sp, code: INTEGER); |
91,16 → 111,42 |
SYSTEM.GET(code - 1000H - SYSTEM.SIZE(INTEGER) * 2, dlopen); |
SYSTEM.GET(code - 1000H - SYSTEM.SIZE(INTEGER), dlsym); |
MainParam := sp; |
eol := 0AX; |
libc := dlopen(SYSTEM.SADR("libc.so.6"), RTLD_LAZY); |
GetSym(libc, "exit", SYSTEM.ADR(exit_thread)); |
exit := exit_thread; |
GetSym(libc, "puts", SYSTEM.ADR(puts)); |
GetSym(libc, "malloc", SYSTEM.ADR(malloc)); |
GetSym(libc, "free", SYSTEM.ADR(free)); |
GetProcAdr(libc, "malloc", SYSTEM.ADR(malloc)); |
GetProcAdr(libc, "free", SYSTEM.ADR(free)); |
GetProcAdr(libc, "exit", SYSTEM.ADR(_exit)); |
GetProcAdr(libc, "stdout", SYSTEM.ADR(stdout)); |
GetProcAdr(libc, "stdin", SYSTEM.ADR(stdin)); |
GetProcAdr(libc, "stderr", SYSTEM.ADR(stderr)); |
SYSTEM.GET(stdout - SYSTEM.SIZE(INTEGER), stdout); |
SYSTEM.GET(stdin - SYSTEM.SIZE(INTEGER), stdin); |
SYSTEM.GET(stderr - SYSTEM.SIZE(INTEGER), stderr); |
GetProcAdr(libc, "puts", SYSTEM.ADR(puts)); |
GetProcAdr(libc, "fwrite", SYSTEM.ADR(fwrite)); |
GetProcAdr(libc, "fread", SYSTEM.ADR(fread)); |
GetProcAdr(libc, "fopen", SYSTEM.ADR(fopen)); |
GetProcAdr(libc, "fclose", SYSTEM.ADR(fclose)); |
GetProcAdr(libc, "time", SYSTEM.ADR(time)); |
librt := dlopen(SYSTEM.SADR("librt.so.1"), RTLD_LAZY); |
GetProcAdr(librt, "clock_gettime", SYSTEM.ADR(clock_gettime)) |
END init; |
PROCEDURE exit* (code: INTEGER); |
BEGIN |
_exit(code) |
END exit; |
PROCEDURE exit_thread* (code: INTEGER); |
BEGIN |
_exit(code) |
END exit_thread; |
PROCEDURE dllentry* (hinstDLL, fdwReason, lpvReserved: INTEGER): INTEGER; |
RETURN 0 |
END dllentry; |
/programs/develop/oberon07/Lib/Linux32/HOST.ob07 |
---|
13,42 → 13,25 |
CONST |
slash* = "/"; |
eol* = 0AX; |
OS* = "LINUX"; |
bit_depth* = RTL.bit_depth; |
maxint* = RTL.maxint; |
minint* = RTL.minint; |
RTLD_LAZY = 1; |
TYPE |
TP = ARRAY 2 OF INTEGER; |
VAR |
maxreal*: REAL; |
argc: INTEGER; |
libc, librt: INTEGER; |
eol*: ARRAY 2 OF CHAR; |
stdout: INTEGER; |
maxreal*: REAL; |
fread, fwrite : PROCEDURE [linux] (buffer, bytes, blocks, file: INTEGER): INTEGER; |
fopen : PROCEDURE [linux] (fname, fmode: INTEGER): INTEGER; |
fclose : PROCEDURE [linux] (file: INTEGER): INTEGER; |
_chmod : PROCEDURE [linux] (fname: INTEGER; mode: SET): INTEGER; |
time : PROCEDURE [linux] (ptr: INTEGER): INTEGER; |
clock_gettime : PROCEDURE [linux] (clock_id: INTEGER; VAR tp: TP): INTEGER; |
exit : PROCEDURE [linux] (code: INTEGER); |
PROCEDURE ExitProcess* (code: INTEGER); |
BEGIN |
exit(code) |
API.exit(code) |
END ExitProcess; |
92,7 → 75,7 |
res: INTEGER; |
BEGIN |
res := fread(SYSTEM.ADR(Buffer[0]), 1, bytes, F); |
res := API.fread(SYSTEM.ADR(Buffer[0]), 1, bytes, F); |
IF res <= 0 THEN |
res := -1 |
END |
106,7 → 89,7 |
res: INTEGER; |
BEGIN |
res := fwrite(SYSTEM.ADR(Buffer[0]), 1, bytes, F); |
res := API.fwrite(SYSTEM.ADR(Buffer[0]), 1, bytes, F); |
IF res <= 0 THEN |
res := -1 |
END |
116,45 → 99,34 |
PROCEDURE FileCreate* (FName: ARRAY OF CHAR): INTEGER; |
RETURN fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("wb")) |
RETURN API.fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("wb")) |
END FileCreate; |
PROCEDURE FileClose* (File: INTEGER); |
BEGIN |
File := fclose(File) |
File := API.fclose(File) |
END FileClose; |
PROCEDURE chmod* (FName: ARRAY OF CHAR); |
VAR |
res: INTEGER; |
BEGIN |
res := _chmod(SYSTEM.ADR(FName[0]), {0, 2..8}) (* rwxrwxr-x *) |
END chmod; |
PROCEDURE FileOpen* (FName: ARRAY OF CHAR): INTEGER; |
RETURN fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("rb")) |
RETURN API.fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("rb")) |
END FileOpen; |
PROCEDURE OutChar* (c: CHAR); |
VAR |
res: INTEGER; |
BEGIN |
res := fwrite(SYSTEM.ADR(c), 1, 1, stdout) |
API.putc(c) |
END OutChar; |
PROCEDURE GetTickCount* (): INTEGER; |
VAR |
tp: TP; |
tp: API.TP; |
res: INTEGER; |
BEGIN |
IF clock_gettime(0, tp) = 0 THEN |
IF API.clock_gettime(0, tp) = 0 THEN |
res := tp[0] * 100 + tp[1] DIV 10000000 |
ELSE |
res := 0 |
169,25 → 141,22 |
END isRelative; |
PROCEDURE now* (VAR year, month, day, hour, min, sec: INTEGER); |
END now; |
PROCEDURE UnixTime* (): INTEGER; |
RETURN time(0) |
RETURN API.time(0) |
END UnixTime; |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
BEGIN |
SYSTEM.GET32(SYSTEM.ADR(x), a); |
SYSTEM.GET32(SYSTEM.ADR(x) + 4, b) |
RETURN a |
END splitf; |
PROCEDURE d2s* (x: REAL): INTEGER; |
VAR |
h, l, s, e: INTEGER; |
BEGIN |
e := splitf(x, l, h); |
SYSTEM.GET(SYSTEM.ADR(x), l); |
SYSTEM.GET(SYSTEM.ADR(x) + 4, h); |
s := ASR(h, 31) MOD 2; |
e := (h DIV 100000H) MOD 2048; |
206,7 → 175,7 |
l := 0 |
ELSIF e = 2047 THEN |
e := 1151; |
IF (h MOD 100000H # 0) OR (BITS(l) * {0..31} # {}) THEN |
IF (h MOD 100000H # 0) OR (l # 0) THEN |
h := 80000H; |
l := 0 |
END |
217,32 → 186,23 |
END d2s; |
PROCEDURE GetSym (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER); |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
VAR |
sym: INTEGER; |
res: INTEGER; |
BEGIN |
sym := API.dlsym(lib, SYSTEM.ADR(name[0])); |
ASSERT(sym # 0); |
SYSTEM.PUT(VarAdr, sym) |
END GetSym; |
a := 0; |
b := 0; |
SYSTEM.MOVE(SYSTEM.ADR(x), SYSTEM.ADR(a), 4); |
SYSTEM.MOVE(SYSTEM.ADR(x) + 4, SYSTEM.ADR(b), 4); |
SYSTEM.GET(SYSTEM.ADR(x), res) |
RETURN res |
END splitf; |
BEGIN |
eol := 0AX; |
maxreal := 1.9; |
PACK(maxreal, 1023); |
SYSTEM.GET(API.MainParam, argc); |
libc := API.libc; |
GetSym(libc, "fread", SYSTEM.ADR(fread)); |
GetSym(libc, "fwrite", SYSTEM.ADR(fwrite)); |
GetSym(libc, "fopen", SYSTEM.ADR(fopen)); |
GetSym(libc, "fclose", SYSTEM.ADR(fclose)); |
GetSym(libc, "chmod", SYSTEM.ADR(_chmod)); |
GetSym(libc, "time", SYSTEM.ADR(time)); |
GetSym(libc, "exit", SYSTEM.ADR(exit)); |
GetSym(libc, "stdout", SYSTEM.ADR(stdout)); SYSTEM.GET(stdout - SYSTEM.SIZE(INTEGER), stdout); |
librt := API.dlopen(SYSTEM.SADR("librt.so.1"), RTLD_LAZY); |
GetSym(librt, "clock_gettime", SYSTEM.ADR(clock_gettime)) |
SYSTEM.GET(API.MainParam, argc) |
END HOST. |
/programs/develop/oberon07/Lib/Linux32/LINAPI.ob07 |
---|
7,17 → 7,19 |
MODULE LINAPI; |
IMPORT SYSTEM, API, Libdl; |
IMPORT SYSTEM, API; |
TYPE |
TP* = ARRAY 2 OF INTEGER; |
SOFINI* = PROCEDURE; |
TP* = API.TP; |
SOFINI* = API.SOFINI; |
VAR |
argc*, envc*: INTEGER; |
libc*, librt*: INTEGER; |
stdout*, |
37,6 → 39,37 |
clock_gettime* : PROCEDURE [linux] (clock_id: INTEGER; VAR tp: TP): INTEGER; |
PROCEDURE GetArg* (n: INTEGER; VAR s: ARRAY OF CHAR); |
VAR |
i, len, ptr: INTEGER; |
c: CHAR; |
BEGIN |
i := 0; |
len := LEN(s) - 1; |
IF (0 <= n) & (n <= argc + envc) & (n # argc) & (len > 0) THEN |
SYSTEM.GET(API.MainParam + (n + 1) * SYSTEM.SIZE(INTEGER), ptr); |
REPEAT |
SYSTEM.GET(ptr, c); |
s[i] := c; |
INC(i); |
INC(ptr) |
UNTIL (c = 0X) OR (i = len) |
END; |
s[i] := 0X |
END GetArg; |
PROCEDURE GetEnv* (n: INTEGER; VAR s: ARRAY OF CHAR); |
BEGIN |
IF (0 <= n) & (n < envc) THEN |
GetArg(n + argc + 1, s) |
ELSE |
s[0] := 0X |
END |
END GetEnv; |
PROCEDURE SetFini* (ProcFini: SOFINI); |
BEGIN |
API.SetFini(ProcFini) |
43,38 → 76,42 |
END SetFini; |
PROCEDURE GetSym (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER); |
PROCEDURE init; |
VAR |
sym: INTEGER; |
ptr: INTEGER; |
BEGIN |
sym := Libdl.sym(lib, name); |
ASSERT(sym # 0); |
SYSTEM.PUT(VarAdr, sym) |
END GetSym; |
IF API.MainParam # 0 THEN |
envc := -1; |
SYSTEM.GET(API.MainParam, argc); |
REPEAT |
SYSTEM.GET(API.MainParam + (envc + argc + 3) * SYSTEM.SIZE(INTEGER), ptr); |
INC(envc) |
UNTIL ptr = 0 |
ELSE |
envc := 0; |
argc := 0 |
END; |
PROCEDURE init; |
BEGIN |
libc := API.libc; |
GetSym(libc, "exit", SYSTEM.ADR(exit)); |
GetSym(libc, "puts", SYSTEM.ADR(puts)); |
GetSym(libc, "malloc", SYSTEM.ADR(malloc)); |
GetSym(libc, "free", SYSTEM.ADR(free)); |
GetSym(libc, "fread", SYSTEM.ADR(fread)); |
GetSym(libc, "fwrite", SYSTEM.ADR(fwrite)); |
GetSym(libc, "fopen", SYSTEM.ADR(fopen)); |
GetSym(libc, "fclose", SYSTEM.ADR(fclose)); |
GetSym(libc, "time", SYSTEM.ADR(time)); |
stdout := API.stdout; |
stdin := API.stdin; |
stderr := API.stderr; |
GetSym(libc, "stdout", SYSTEM.ADR(stdout)); SYSTEM.GET(stdout - SYSTEM.SIZE(INTEGER), stdout); |
GetSym(libc, "stdin", SYSTEM.ADR(stdin)); SYSTEM.GET(stdin - SYSTEM.SIZE(INTEGER), stdin); |
GetSym(libc, "stderr", SYSTEM.ADR(stderr)); SYSTEM.GET(stderr - SYSTEM.SIZE(INTEGER), stderr); |
malloc := API.malloc; |
free := API.free; |
exit := API._exit; |
puts := API.puts; |
fwrite := API.fwrite; |
fread := API.fread; |
fopen := API.fopen; |
fclose := API.fclose; |
time := API.time; |
librt := Libdl.open("librt.so.1", Libdl.LAZY); |
librt := API.librt; |
GetSym(librt, "clock_gettime", SYSTEM.ADR(clock_gettime)) |
clock_gettime := API.clock_gettime |
END init; |
/programs/develop/oberon07/Lib/Linux32/Math.ob07 |
---|
1,8 → 1,18 |
(* |
BSD 2-Clause License |
Copyright 2013, 2014, 2018, 2019 Anton Krotov |
Copyright (c) 2013-2014, 2018-2020 Anton Krotov |
All rights reserved. |
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 <http://www.gnu.org/licenses/>. |
*) |
MODULE Math; |
225,16 → 235,6 |
END frac; |
PROCEDURE sqri* (x: INTEGER): INTEGER; |
RETURN x * x |
END sqri; |
PROCEDURE sqrr* (x: REAL): REAL; |
RETURN x * x |
END sqrr; |
PROCEDURE arcsin* (x: REAL): REAL; |
RETURN arctan2(x, sqrt(1.0 - x * x)) |
END arcsin; |
349,40 → 349,6 |
END power; |
PROCEDURE ipower* (base: REAL; exponent: INTEGER): REAL; |
VAR |
i: INTEGER; |
a: REAL; |
BEGIN |
a := 1.0; |
IF base # 0.0 THEN |
IF exponent # 0 THEN |
IF exponent < 0 THEN |
base := 1.0 / base |
END; |
i := ABS(exponent); |
WHILE i > 0 DO |
WHILE ~ODD(i) DO |
i := LSR(i, 1); |
base := sqrr(base) |
END; |
DEC(i); |
a := a * base |
END |
ELSE |
a := 1.0 |
END |
ELSE |
ASSERT(exponent > 0); |
a := 0.0 |
END |
RETURN a |
END ipower; |
PROCEDURE sgn* (x: REAL): INTEGER; |
VAR |
res: INTEGER; |
415,36 → 381,4 |
END fact; |
PROCEDURE DegToRad* (x: REAL): REAL; |
RETURN x * (pi / 180.0) |
END DegToRad; |
PROCEDURE RadToDeg* (x: REAL): REAL; |
RETURN x * (180.0 / pi) |
END RadToDeg; |
(* Return hypotenuse of triangle *) |
PROCEDURE hypot* (x, y: REAL): REAL; |
VAR |
a: REAL; |
BEGIN |
x := ABS(x); |
y := ABS(y); |
IF x > y THEN |
a := x * sqrt(1.0 + sqrr(y / x)) |
ELSE |
IF x > 0.0 THEN |
a := y * sqrt(1.0 + sqrr(x / y)) |
ELSE |
a := y |
END |
END |
RETURN a |
END hypot; |
END Math. |
/programs/develop/oberon07/Lib/Linux32/Out.ob07 |
---|
1,77 → 1,277 |
(* |
BSD 2-Clause License |
Copyright 2013, 2014, 2017, 2018, 2019 Anton Krotov |
Copyright (c) 2020, Anton Krotov |
All rights reserved. |
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 <http://www.gnu.org/licenses/>. |
*) |
MODULE Out; |
IMPORT SYSTEM, Libdl; |
IMPORT sys := SYSTEM, API; |
CONST |
d = 1.0 - 5.0E-12; |
VAR |
printf1: PROCEDURE [linux] (fmt: INTEGER; x: INTEGER); |
printf2: PROCEDURE [linux] (fmt: INTEGER; width, x: INTEGER); |
printf3: PROCEDURE [linux] (fmt: INTEGER; width, precision: INTEGER; x: REAL); |
Realp: PROCEDURE (x: REAL; width: INTEGER); |
PROCEDURE Char* (x: CHAR); |
BEGIN |
printf1(SYSTEM.SADR("%c"), ORD(x)) |
API.putc(x) |
END Char; |
PROCEDURE String* (s: ARRAY OF CHAR); |
VAR |
i: INTEGER; |
BEGIN |
printf2(SYSTEM.SADR("%.*s"), LENGTH(s), SYSTEM.ADR(s[0])) |
i := 0; |
WHILE (i < LEN(s)) & (s[i] # 0X) DO |
Char(s[i]); |
INC(i) |
END |
END String; |
PROCEDURE Ln*; |
PROCEDURE WriteInt(x, n: INTEGER); |
VAR i: INTEGER; a: ARRAY 16 OF CHAR; neg: BOOLEAN; |
BEGIN |
printf1(SYSTEM.SADR("%s"), SYSTEM.SADR(0AX)) |
END Ln; |
i := 0; |
IF n < 1 THEN |
n := 1 |
END; |
IF x < 0 THEN |
x := -x; |
DEC(n); |
neg := TRUE |
END; |
REPEAT |
a[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
WHILE n > i DO |
Char(" "); |
DEC(n) |
END; |
IF neg THEN |
Char("-") |
END; |
REPEAT |
DEC(i); |
Char(a[i]) |
UNTIL i = 0 |
END WriteInt; |
PROCEDURE IsNan(AValue: REAL): BOOLEAN; |
VAR h, l: SET; |
BEGIN |
sys.GET(sys.ADR(AValue), l); |
sys.GET(sys.ADR(AValue) + 4, h) |
RETURN (h * {20..30} = {20..30}) & ((h * {0..19} # {}) OR (l * {0..31} # {})) |
END IsNan; |
PROCEDURE IsInf(x: REAL): BOOLEAN; |
RETURN ABS(x) = sys.INF() |
END IsInf; |
PROCEDURE Int* (x, width: INTEGER); |
VAR i: INTEGER; |
BEGIN |
printf2(SYSTEM.SADR("%*d"), width, x) |
IF x # 80000000H THEN |
WriteInt(x, width) |
ELSE |
FOR i := 12 TO width DO |
Char(20X) |
END; |
String("-2147483648") |
END |
END Int; |
PROCEDURE OutInf(x: REAL; width: INTEGER); |
VAR s: ARRAY 5 OF CHAR; i: INTEGER; |
BEGIN |
IF IsNan(x) THEN |
s := "Nan"; |
INC(width) |
ELSIF IsInf(x) & (x > 0.0) THEN |
s := "+Inf" |
ELSIF IsInf(x) & (x < 0.0) THEN |
s := "-Inf" |
END; |
FOR i := 1 TO width - 4 DO |
Char(" ") |
END; |
String(s) |
END OutInf; |
PROCEDURE Ln*; |
BEGIN |
Char(0AX) |
END Ln; |
PROCEDURE _FixReal(x: REAL; width, p: INTEGER); |
VAR e, len, i: INTEGER; y: REAL; minus: BOOLEAN; |
BEGIN |
IF IsNan(x) OR IsInf(x) THEN |
OutInf(x, width) |
ELSIF p < 0 THEN |
Realp(x, width) |
ELSE |
len := 0; |
minus := FALSE; |
IF x < 0.0 THEN |
minus := TRUE; |
INC(len); |
x := ABS(x) |
END; |
e := 0; |
WHILE x >= 10.0 DO |
x := x / 10.0; |
INC(e) |
END; |
IF e >= 0 THEN |
len := len + e + p + 1; |
IF x > 9.0 + d THEN |
INC(len) |
END; |
IF p > 0 THEN |
INC(len) |
END; |
ELSE |
len := len + p + 2 |
END; |
FOR i := 1 TO width - len DO |
Char(" ") |
END; |
IF minus THEN |
Char("-") |
END; |
y := x; |
WHILE (y < 1.0) & (y # 0.0) DO |
y := y * 10.0; |
DEC(e) |
END; |
IF e < 0 THEN |
IF x - FLT(FLOOR(x)) > d THEN |
Char("1"); |
x := 0.0 |
ELSE |
Char("0"); |
x := x * 10.0 |
END |
ELSE |
WHILE e >= 0 DO |
IF x - FLT(FLOOR(x)) > d THEN |
IF x > 9.0 THEN |
String("10") |
ELSE |
Char(CHR(FLOOR(x) + ORD("0") + 1)) |
END; |
x := 0.0 |
ELSE |
Char(CHR(FLOOR(x) + ORD("0"))); |
x := (x - FLT(FLOOR(x))) * 10.0 |
END; |
DEC(e) |
END |
END; |
IF p > 0 THEN |
Char(".") |
END; |
WHILE p > 0 DO |
IF x - FLT(FLOOR(x)) > d THEN |
Char(CHR(FLOOR(x) + ORD("0") + 1)); |
x := 0.0 |
ELSE |
Char(CHR(FLOOR(x) + ORD("0"))); |
x := (x - FLT(FLOOR(x))) * 10.0 |
END; |
DEC(p) |
END |
END |
END _FixReal; |
PROCEDURE Real* (x: REAL; width: INTEGER); |
VAR e, n, i: INTEGER; minus: BOOLEAN; |
BEGIN |
printf3(SYSTEM.SADR("%*.*E"), width, MAX(MIN(width - 8, 15), 1), x) |
Realp := Real; |
IF IsNan(x) OR IsInf(x) THEN |
OutInf(x, width) |
ELSE |
e := 0; |
n := 0; |
IF width > 23 THEN |
n := width - 23; |
width := 23 |
ELSIF width < 9 THEN |
width := 9 |
END; |
width := width - 5; |
IF x < 0.0 THEN |
x := -x; |
minus := TRUE |
ELSE |
minus := FALSE |
END; |
WHILE x >= 10.0 DO |
x := x / 10.0; |
INC(e) |
END; |
WHILE (x < 1.0) & (x # 0.0) DO |
x := x * 10.0; |
DEC(e) |
END; |
IF x > 9.0 + d THEN |
x := 1.0; |
INC(e) |
END; |
FOR i := 1 TO n DO |
Char(" ") |
END; |
IF minus THEN |
x := -x |
END; |
_FixReal(x, width, width - 3); |
Char("E"); |
IF e >= 0 THEN |
Char("+") |
ELSE |
Char("-"); |
e := ABS(e) |
END; |
IF e < 100 THEN |
Char("0") |
END; |
IF e < 10 THEN |
Char("0") |
END; |
Int(e, 0) |
END |
END Real; |
PROCEDURE FixReal* (x: REAL; width, precision: INTEGER); |
PROCEDURE FixReal*(x: REAL; width, p: INTEGER); |
BEGIN |
printf3(SYSTEM.SADR("%*.*f"), width, precision, x) |
Realp := Real; |
_FixReal(x, width, p) |
END FixReal; |
PROCEDURE Open*; |
END Open; |
PROCEDURE init; |
VAR |
libc, printf: INTEGER; |
BEGIN |
libc := Libdl.open("libc.so.6", Libdl.LAZY); |
ASSERT(libc # 0); |
printf := Libdl.sym(libc, "printf"); |
ASSERT(printf # 0); |
SYSTEM.PUT(SYSTEM.ADR(printf1), printf); |
SYSTEM.PUT(SYSTEM.ADR(printf2), printf); |
SYSTEM.PUT(SYSTEM.ADR(printf3), printf); |
END init; |
BEGIN |
init |
END Out. |
/programs/develop/oberon07/Lib/Linux32/RTL.ob07 |
---|
372,29 → 372,33 |
PROCEDURE IntToStr (x: INTEGER; VAR str: ARRAY OF CHAR); |
VAR |
i, a: INTEGER; |
i, a, b: INTEGER; |
c: CHAR; |
BEGIN |
i := 0; |
a := x; |
REPEAT |
INC(i); |
a := a DIV 10 |
UNTIL a = 0; |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
str[i] := 0X; |
REPEAT |
DEC(i); |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10 |
UNTIL x = 0 |
a := 0; |
b := i - 1; |
WHILE a < b DO |
c := str[a]; |
str[a] := str[b]; |
str[b] := c; |
INC(a); |
DEC(b) |
END; |
str[i] := 0X |
END IntToStr; |
PROCEDURE append (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); |
VAR |
n1, n2: INTEGER; |
n1, n2, i, j: INTEGER; |
BEGIN |
n1 := LENGTH(s1); |
402,12 → 406,19 |
ASSERT(n1 + n2 < LEN(s1)); |
SYSTEM.MOVE(SYSTEM.ADR(s2[0]), SYSTEM.ADR(s1[n1]), n2); |
s1[n1 + n2] := 0X |
i := 0; |
j := n1; |
WHILE i < n2 DO |
s1[j] := s2[i]; |
INC(i); |
INC(j) |
END; |
s1[j] := 0X |
END append; |
PROCEDURE [stdcall] _error* (modnum, _module, err, line: INTEGER); |
PROCEDURE [stdcall] _error* (module, err, line: INTEGER); |
VAR |
s, temp: ARRAY 1024 OF CHAR; |
426,9 → 437,11 |
|11: s := "BYTE out of range" |
END; |
append(s, API.eol + "module: "); PCharToStr(_module, temp); append(s, temp); |
append(s, API.eol + "line: "); IntToStr(line, temp); append(s, temp); |
append(s, API.eol); |
append(s, "module: "); PCharToStr(module, temp); append(s, temp); append(s, API.eol); |
append(s, "line: "); IntToStr(line, temp); append(s, temp); |
API.DebugMsg(SYSTEM.ADR(s[0]), name); |
API.exit_thread(0) |
/programs/develop/oberon07/Lib/Linux64/File.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Linux64/In.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Linux64/Args.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Linux64/API.ob07 |
---|
12,34 → 12,54 |
CONST |
eol* = 0AX; |
RTLD_LAZY* = 1; |
BIT_DEPTH* = 64; |
RTLD_LAZY = 1; |
TYPE |
SOFINI = PROCEDURE; |
TP* = ARRAY 2 OF INTEGER; |
SOFINI* = PROCEDURE; |
VAR |
MainParam*, libc*: INTEGER; |
eol*: ARRAY 2 OF CHAR; |
MainParam*: INTEGER; |
libc*, librt*: INTEGER; |
dlopen* : PROCEDURE [linux] (filename, flag: INTEGER): INTEGER; |
dlsym* : PROCEDURE [linux] (handle, symbol: INTEGER): INTEGER; |
exit*, |
exit_thread* : PROCEDURE [linux] (code: INTEGER); |
puts : PROCEDURE [linux] (pStr: INTEGER); |
malloc : PROCEDURE [linux] (size: INTEGER): INTEGER; |
free : PROCEDURE [linux] (ptr: INTEGER); |
stdout*, |
stdin*, |
stderr* : INTEGER; |
malloc* : PROCEDURE [linux] (size: INTEGER): INTEGER; |
free* : PROCEDURE [linux] (ptr: INTEGER); |
_exit* : PROCEDURE [linux] (code: INTEGER); |
puts* : PROCEDURE [linux] (pStr: INTEGER); |
fwrite*, |
fread* : PROCEDURE [linux] (buffer, bytes, blocks, file: INTEGER): INTEGER; |
fopen* : PROCEDURE [linux] (fname, fmode: INTEGER): INTEGER; |
fclose* : PROCEDURE [linux] (file: INTEGER): INTEGER; |
clock_gettime* : PROCEDURE [linux] (clock_id: INTEGER; VAR tp: TP): INTEGER; |
time* : PROCEDURE [linux] (ptr: INTEGER): INTEGER; |
fini: SOFINI; |
PROCEDURE putc* (c: CHAR); |
VAR |
res: INTEGER; |
BEGIN |
res := fwrite(SYSTEM.ADR(c), 1, 1, stdout) |
END putc; |
PROCEDURE DebugMsg* (lpText, lpCaption: INTEGER); |
BEGIN |
puts(lpCaption); |
74,7 → 94,7 |
END _DISPOSE; |
PROCEDURE GetSym (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER); |
PROCEDURE GetProcAdr (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER); |
VAR |
sym: INTEGER; |
82,7 → 102,7 |
sym := dlsym(lib, SYSTEM.ADR(name[0])); |
ASSERT(sym # 0); |
SYSTEM.PUT(VarAdr, sym) |
END GetSym; |
END GetProcAdr; |
PROCEDURE init* (sp, code: INTEGER); |
91,16 → 111,42 |
SYSTEM.GET(code - 1000H - SYSTEM.SIZE(INTEGER) * 2, dlopen); |
SYSTEM.GET(code - 1000H - SYSTEM.SIZE(INTEGER), dlsym); |
MainParam := sp; |
eol := 0AX; |
libc := dlopen(SYSTEM.SADR("libc.so.6"), RTLD_LAZY); |
GetSym(libc, "exit", SYSTEM.ADR(exit_thread)); |
exit := exit_thread; |
GetSym(libc, "puts", SYSTEM.ADR(puts)); |
GetSym(libc, "malloc", SYSTEM.ADR(malloc)); |
GetSym(libc, "free", SYSTEM.ADR(free)); |
GetProcAdr(libc, "malloc", SYSTEM.ADR(malloc)); |
GetProcAdr(libc, "free", SYSTEM.ADR(free)); |
GetProcAdr(libc, "exit", SYSTEM.ADR(_exit)); |
GetProcAdr(libc, "stdout", SYSTEM.ADR(stdout)); |
GetProcAdr(libc, "stdin", SYSTEM.ADR(stdin)); |
GetProcAdr(libc, "stderr", SYSTEM.ADR(stderr)); |
SYSTEM.GET(stdout - SYSTEM.SIZE(INTEGER), stdout); |
SYSTEM.GET(stdin - SYSTEM.SIZE(INTEGER), stdin); |
SYSTEM.GET(stderr - SYSTEM.SIZE(INTEGER), stderr); |
GetProcAdr(libc, "puts", SYSTEM.ADR(puts)); |
GetProcAdr(libc, "fwrite", SYSTEM.ADR(fwrite)); |
GetProcAdr(libc, "fread", SYSTEM.ADR(fread)); |
GetProcAdr(libc, "fopen", SYSTEM.ADR(fopen)); |
GetProcAdr(libc, "fclose", SYSTEM.ADR(fclose)); |
GetProcAdr(libc, "time", SYSTEM.ADR(time)); |
librt := dlopen(SYSTEM.SADR("librt.so.1"), RTLD_LAZY); |
GetProcAdr(librt, "clock_gettime", SYSTEM.ADR(clock_gettime)) |
END init; |
PROCEDURE exit* (code: INTEGER); |
BEGIN |
_exit(code) |
END exit; |
PROCEDURE exit_thread* (code: INTEGER); |
BEGIN |
_exit(code) |
END exit_thread; |
PROCEDURE dllentry* (hinstDLL, fdwReason, lpvReserved: INTEGER): INTEGER; |
RETURN 0 |
END dllentry; |
/programs/develop/oberon07/Lib/Linux64/HOST.ob07 |
---|
13,42 → 13,25 |
CONST |
slash* = "/"; |
eol* = 0AX; |
OS* = "LINUX"; |
bit_depth* = RTL.bit_depth; |
maxint* = RTL.maxint; |
minint* = RTL.minint; |
RTLD_LAZY = 1; |
TYPE |
TP = ARRAY 2 OF INTEGER; |
VAR |
maxreal*: REAL; |
argc: INTEGER; |
libc, librt: INTEGER; |
eol*: ARRAY 2 OF CHAR; |
stdout: INTEGER; |
maxreal*: REAL; |
fread, fwrite : PROCEDURE [linux] (buffer, bytes, blocks, file: INTEGER): INTEGER; |
fopen : PROCEDURE [linux] (fname, fmode: INTEGER): INTEGER; |
fclose : PROCEDURE [linux] (file: INTEGER): INTEGER; |
_chmod : PROCEDURE [linux] (fname: INTEGER; mode: SET): INTEGER; |
time : PROCEDURE [linux] (ptr: INTEGER): INTEGER; |
clock_gettime : PROCEDURE [linux] (clock_id: INTEGER; VAR tp: TP): INTEGER; |
exit : PROCEDURE [linux] (code: INTEGER); |
PROCEDURE ExitProcess* (code: INTEGER); |
BEGIN |
exit(code) |
API.exit(code) |
END ExitProcess; |
92,7 → 75,7 |
res: INTEGER; |
BEGIN |
res := fread(SYSTEM.ADR(Buffer[0]), 1, bytes, F); |
res := API.fread(SYSTEM.ADR(Buffer[0]), 1, bytes, F); |
IF res <= 0 THEN |
res := -1 |
END |
106,7 → 89,7 |
res: INTEGER; |
BEGIN |
res := fwrite(SYSTEM.ADR(Buffer[0]), 1, bytes, F); |
res := API.fwrite(SYSTEM.ADR(Buffer[0]), 1, bytes, F); |
IF res <= 0 THEN |
res := -1 |
END |
116,45 → 99,34 |
PROCEDURE FileCreate* (FName: ARRAY OF CHAR): INTEGER; |
RETURN fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("wb")) |
RETURN API.fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("wb")) |
END FileCreate; |
PROCEDURE FileClose* (File: INTEGER); |
BEGIN |
File := fclose(File) |
File := API.fclose(File) |
END FileClose; |
PROCEDURE chmod* (FName: ARRAY OF CHAR); |
VAR |
res: INTEGER; |
BEGIN |
res := _chmod(SYSTEM.ADR(FName[0]), {0, 2..8}) (* rwxrwxr-x *) |
END chmod; |
PROCEDURE FileOpen* (FName: ARRAY OF CHAR): INTEGER; |
RETURN fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("rb")) |
RETURN API.fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("rb")) |
END FileOpen; |
PROCEDURE OutChar* (c: CHAR); |
VAR |
res: INTEGER; |
BEGIN |
res := fwrite(SYSTEM.ADR(c), 1, 1, stdout) |
API.putc(c) |
END OutChar; |
PROCEDURE GetTickCount* (): INTEGER; |
VAR |
tp: TP; |
tp: API.TP; |
res: INTEGER; |
BEGIN |
IF clock_gettime(0, tp) = 0 THEN |
IF API.clock_gettime(0, tp) = 0 THEN |
res := tp[0] * 100 + tp[1] DIV 10000000 |
ELSE |
res := 0 |
169,31 → 141,22 |
END isRelative; |
PROCEDURE now* (VAR year, month, day, hour, min, sec: INTEGER); |
END now; |
PROCEDURE UnixTime* (): INTEGER; |
RETURN time(0) |
RETURN API.time(0) |
END UnixTime; |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
BEGIN |
a := 0; |
b := 0; |
SYSTEM.GET32(SYSTEM.ADR(x), a); |
SYSTEM.GET32(SYSTEM.ADR(x) + 4, b); |
SYSTEM.GET(SYSTEM.ADR(x), res) |
RETURN res |
END splitf; |
PROCEDURE d2s* (x: REAL): INTEGER; |
VAR |
h, l, s, e: INTEGER; |
BEGIN |
e := splitf(x, l, h); |
SYSTEM.GET(SYSTEM.ADR(x), l); |
SYSTEM.GET(SYSTEM.ADR(x) + 4, h); |
s := ASR(h, 31) MOD 2; |
e := (h DIV 100000H) MOD 2048; |
223,32 → 186,23 |
END d2s; |
PROCEDURE GetSym (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER); |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
VAR |
sym: INTEGER; |
res: INTEGER; |
BEGIN |
sym := API.dlsym(lib, SYSTEM.ADR(name[0])); |
ASSERT(sym # 0); |
SYSTEM.PUT(VarAdr, sym) |
END GetSym; |
a := 0; |
b := 0; |
SYSTEM.MOVE(SYSTEM.ADR(x), SYSTEM.ADR(a), 4); |
SYSTEM.MOVE(SYSTEM.ADR(x) + 4, SYSTEM.ADR(b), 4); |
SYSTEM.GET(SYSTEM.ADR(x), res) |
RETURN res |
END splitf; |
BEGIN |
eol := 0AX; |
maxreal := 1.9; |
PACK(maxreal, 1023); |
SYSTEM.GET(API.MainParam, argc); |
libc := API.libc; |
GetSym(libc, "fread", SYSTEM.ADR(fread)); |
GetSym(libc, "fwrite", SYSTEM.ADR(fwrite)); |
GetSym(libc, "fopen", SYSTEM.ADR(fopen)); |
GetSym(libc, "fclose", SYSTEM.ADR(fclose)); |
GetSym(libc, "chmod", SYSTEM.ADR(_chmod)); |
GetSym(libc, "time", SYSTEM.ADR(time)); |
GetSym(libc, "exit", SYSTEM.ADR(exit)); |
GetSym(libc, "stdout", SYSTEM.ADR(stdout)); SYSTEM.GET(stdout - SYSTEM.SIZE(INTEGER), stdout); |
librt := API.dlopen(SYSTEM.SADR("librt.so.1"), RTLD_LAZY); |
GetSym(librt, "clock_gettime", SYSTEM.ADR(clock_gettime)) |
SYSTEM.GET(API.MainParam, argc) |
END HOST. |
/programs/develop/oberon07/Lib/Linux64/LINAPI.ob07 |
---|
7,17 → 7,19 |
MODULE LINAPI; |
IMPORT SYSTEM, API, Libdl; |
IMPORT SYSTEM, API; |
TYPE |
TP* = ARRAY 2 OF INTEGER; |
SOFINI* = PROCEDURE; |
TP* = API.TP; |
SOFINI* = API.SOFINI; |
VAR |
argc*, envc*: INTEGER; |
libc*, librt*: INTEGER; |
stdout*, |
37,6 → 39,37 |
clock_gettime* : PROCEDURE [linux] (clock_id: INTEGER; VAR tp: TP): INTEGER; |
PROCEDURE GetArg* (n: INTEGER; VAR s: ARRAY OF CHAR); |
VAR |
i, len, ptr: INTEGER; |
c: CHAR; |
BEGIN |
i := 0; |
len := LEN(s) - 1; |
IF (0 <= n) & (n <= argc + envc) & (n # argc) & (len > 0) THEN |
SYSTEM.GET(API.MainParam + (n + 1) * SYSTEM.SIZE(INTEGER), ptr); |
REPEAT |
SYSTEM.GET(ptr, c); |
s[i] := c; |
INC(i); |
INC(ptr) |
UNTIL (c = 0X) OR (i = len) |
END; |
s[i] := 0X |
END GetArg; |
PROCEDURE GetEnv* (n: INTEGER; VAR s: ARRAY OF CHAR); |
BEGIN |
IF (0 <= n) & (n < envc) THEN |
GetArg(n + argc + 1, s) |
ELSE |
s[0] := 0X |
END |
END GetEnv; |
PROCEDURE SetFini* (ProcFini: SOFINI); |
BEGIN |
API.SetFini(ProcFini) |
43,38 → 76,42 |
END SetFini; |
PROCEDURE GetSym (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER); |
PROCEDURE init; |
VAR |
sym: INTEGER; |
ptr: INTEGER; |
BEGIN |
sym := Libdl.sym(lib, name); |
ASSERT(sym # 0); |
SYSTEM.PUT(VarAdr, sym) |
END GetSym; |
IF API.MainParam # 0 THEN |
envc := -1; |
SYSTEM.GET(API.MainParam, argc); |
REPEAT |
SYSTEM.GET(API.MainParam + (envc + argc + 3) * SYSTEM.SIZE(INTEGER), ptr); |
INC(envc) |
UNTIL ptr = 0 |
ELSE |
envc := 0; |
argc := 0 |
END; |
PROCEDURE init; |
BEGIN |
libc := API.libc; |
GetSym(libc, "exit", SYSTEM.ADR(exit)); |
GetSym(libc, "puts", SYSTEM.ADR(puts)); |
GetSym(libc, "malloc", SYSTEM.ADR(malloc)); |
GetSym(libc, "free", SYSTEM.ADR(free)); |
GetSym(libc, "fread", SYSTEM.ADR(fread)); |
GetSym(libc, "fwrite", SYSTEM.ADR(fwrite)); |
GetSym(libc, "fopen", SYSTEM.ADR(fopen)); |
GetSym(libc, "fclose", SYSTEM.ADR(fclose)); |
GetSym(libc, "time", SYSTEM.ADR(time)); |
stdout := API.stdout; |
stdin := API.stdin; |
stderr := API.stderr; |
GetSym(libc, "stdout", SYSTEM.ADR(stdout)); SYSTEM.GET(stdout - SYSTEM.SIZE(INTEGER), stdout); |
GetSym(libc, "stdin", SYSTEM.ADR(stdin)); SYSTEM.GET(stdin - SYSTEM.SIZE(INTEGER), stdin); |
GetSym(libc, "stderr", SYSTEM.ADR(stderr)); SYSTEM.GET(stderr - SYSTEM.SIZE(INTEGER), stderr); |
malloc := API.malloc; |
free := API.free; |
exit := API._exit; |
puts := API.puts; |
fwrite := API.fwrite; |
fread := API.fread; |
fopen := API.fopen; |
fclose := API.fclose; |
time := API.time; |
librt := Libdl.open("librt.so.1", Libdl.LAZY); |
librt := API.librt; |
GetSym(librt, "clock_gettime", SYSTEM.ADR(clock_gettime)) |
clock_gettime := API.clock_gettime |
END init; |
/programs/develop/oberon07/Lib/Linux64/Math.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2019-2020, Anton Krotov |
Copyright (c) 2019, Anton Krotov |
All rights reserved. |
*) |
12,32 → 12,22 |
CONST |
pi* = 3.1415926535897932384626433832795028841972E0; |
e* = 2.7182818284590452353602874713526624977572E0; |
e *= 2.71828182845904523; |
pi *= 3.14159265358979324; |
ln2 *= 0.693147180559945309; |
ZERO = 0.0E0; |
ONE = 1.0E0; |
HALF = 0.5E0; |
TWO = 2.0E0; |
sqrtHalf = 0.70710678118654752440E0; |
eps = 5.5511151E-17; |
ln2Inv = 1.44269504088896340735992468100189213E0; |
piInv = ONE / pi; |
Limit = 1.0536712E-8; |
piByTwo = pi / TWO; |
eps = 1.0E-16; |
MaxCosArg = 1000000.0 * pi; |
expoMax = 1023; |
expoMin = 1 - expoMax; |
VAR |
LnInfinity, LnSmall, large, miny: REAL; |
Exp: ARRAY 710 OF REAL; |
PROCEDURE [stdcall64] sqrt* (x: REAL): REAL; |
BEGIN |
ASSERT(x >= ZERO); |
ASSERT(x >= 0.0); |
SYSTEM.CODE( |
0F2H, 0FH, 51H, 45H, 10H, (* sqrtsd xmm0, qword[rbp + 10h] *) |
05DH, (* pop rbp *) |
48,314 → 38,179 |
END sqrt; |
PROCEDURE sqri* (x: INTEGER): INTEGER; |
RETURN x * x |
END sqri; |
PROCEDURE sqrr* (x: REAL): REAL; |
RETURN x * x |
END sqrr; |
PROCEDURE exp* (x: REAL): REAL; |
CONST |
c1 = 0.693359375E0; |
c2 = -2.1219444005469058277E-4; |
P0 = 0.249999999999999993E+0; |
P1 = 0.694360001511792852E-2; |
P2 = 0.165203300268279130E-4; |
Q1 = 0.555538666969001188E-1; |
Q2 = 0.495862884905441294E-3; |
e25 = 1.284025416687741484; (* exp(0.25) *) |
VAR |
xn, g, p, q, z: REAL; |
a, s, res: REAL; |
neg: BOOLEAN; |
n: INTEGER; |
BEGIN |
IF x > LnInfinity THEN |
x := SYSTEM.INF() |
ELSIF x < LnSmall THEN |
x := ZERO |
ELSIF ABS(x) < eps THEN |
x := ONE |
neg := x < 0.0; |
IF neg THEN |
x := -x |
END; |
IF x < FLT(LEN(Exp)) THEN |
res := Exp[FLOOR(x)]; |
x := x - FLT(FLOOR(x)); |
WHILE x >= 0.25 DO |
res := res * e25; |
x := x - 0.25 |
END |
ELSE |
IF x >= ZERO THEN |
n := FLOOR(ln2Inv * x + HALF) |
ELSE |
n := FLOOR(ln2Inv * x - HALF) |
res := SYSTEM.INF(); |
x := 0.0 |
END; |
xn := FLT(n); |
g := (x - xn * c1) - xn * c2; |
z := g * g; |
p := ((P2 * z + P1) * z + P0) * g; |
q := (Q2 * z + Q1) * z + HALF; |
x := HALF + p / (q - p); |
PACK(x, n + 1) |
n := 0; |
a := 1.0; |
s := 1.0; |
REPEAT |
INC(n); |
a := a * x / FLT(n); |
s := s + a |
UNTIL a < eps; |
IF neg THEN |
res := 1.0 / (res * s) |
ELSE |
res := res * s |
END |
RETURN x |
RETURN res |
END exp; |
PROCEDURE ln* (x: REAL): REAL; |
CONST |
c1 = 355.0E0 / 512.0E0; |
c2 = -2.121944400546905827679E-4; |
P0 = -0.64124943423745581147E+2; |
P1 = 0.16383943563021534222E+2; |
P2 = -0.78956112887491257267E+0; |
Q0 = -0.76949932108494879777E+3; |
Q1 = 0.31203222091924532844E+3; |
Q2 = -0.35667977739034646171E+2; |
VAR |
zn, zd, r, z, w, p, q, xn: REAL; |
a, x2, res: REAL; |
n: INTEGER; |
BEGIN |
ASSERT(x > ZERO); |
ASSERT(x > 0.0); |
UNPK(x, n); |
x := x * HALF; |
IF x > sqrtHalf THEN |
zn := x - ONE; |
zd := x * HALF + HALF; |
INC(n) |
ELSE |
zn := x - HALF; |
zd := zn * HALF + HALF |
END; |
x := (x - 1.0) / (x + 1.0); |
x2 := x * x; |
res := x + FLT(n) * (ln2 * 0.5); |
n := 1; |
z := zn / zd; |
w := z * z; |
q := ((w + Q2) * w + Q1) * w + Q0; |
p := w * ((P2 * w + P1) * w + P0); |
r := z + z * (p / q); |
xn := FLT(n) |
REPEAT |
INC(n, 2); |
x := x * x2; |
a := x / FLT(n); |
res := res + a |
UNTIL a < eps |
RETURN (xn * c2 + r) + xn * c1 |
RETURN res * 2.0 |
END ln; |
PROCEDURE power* (base, exponent: REAL): REAL; |
BEGIN |
ASSERT(base > ZERO) |
ASSERT(base > 0.0) |
RETURN exp(exponent * ln(base)) |
END power; |
PROCEDURE ipower* (base: REAL; exponent: INTEGER): REAL; |
VAR |
i: INTEGER; |
a: REAL; |
BEGIN |
a := 1.0; |
IF base # 0.0 THEN |
IF exponent # 0 THEN |
IF exponent < 0 THEN |
base := 1.0 / base |
END; |
i := ABS(exponent); |
WHILE i > 0 DO |
WHILE ~ODD(i) DO |
i := LSR(i, 1); |
base := sqrr(base) |
END; |
DEC(i); |
a := a * base |
END |
ELSE |
a := 1.0 |
END |
ELSE |
ASSERT(exponent > 0); |
a := 0.0 |
END |
RETURN a |
END ipower; |
PROCEDURE log* (base, x: REAL): REAL; |
BEGIN |
ASSERT(base > ZERO); |
ASSERT(x > ZERO) |
ASSERT(base > 0.0); |
ASSERT(x > 0.0) |
RETURN ln(x) / ln(base) |
END log; |
PROCEDURE SinCos (x, y, sign: REAL): REAL; |
CONST |
ymax = 210828714; |
c1 = 3.1416015625E0; |
c2 = -8.908910206761537356617E-6; |
r1 = -0.16666666666666665052E+0; |
r2 = 0.83333333333331650314E-2; |
r3 = -0.19841269841201840457E-3; |
r4 = 0.27557319210152756119E-5; |
r5 = -0.25052106798274584544E-7; |
r6 = 0.16058936490371589114E-9; |
r7 = -0.76429178068910467734E-12; |
r8 = 0.27204790957888846175E-14; |
PROCEDURE cos* (x: REAL): REAL; |
VAR |
a, res: REAL; |
n: INTEGER; |
xn, f, x1, g: REAL; |
BEGIN |
ASSERT(y < FLT(ymax)); |
n := FLOOR(y * piInv + HALF); |
xn := FLT(n); |
IF ODD(n) THEN |
sign := -sign |
END; |
x := ABS(x); |
IF x # y THEN |
xn := xn - HALF |
END; |
ASSERT(x <= MaxCosArg); |
x1 := FLT(FLOOR(x)); |
f := ((x1 - xn * c1) + (x - x1)) - xn * c2; |
x := x - FLT( FLOOR(x / (2.0 * pi)) ) * (2.0 * pi); |
x := x * x; |
res := 0.0; |
a := 1.0; |
n := -1; |
IF ABS(f) < Limit THEN |
x := sign * f |
ELSE |
g := f * f; |
g := (((((((r8 * g + r7) * g + r6) * g + r5) * g + r4) * g + r3) * g + r2) * g + r1) * g; |
g := f + f * g; |
x := sign * g |
END |
REPEAT |
INC(n, 2); |
res := res + a; |
a := -a * x / FLT(n*n + n) |
UNTIL ABS(a) < eps |
RETURN x |
END SinCos; |
RETURN res |
END cos; |
PROCEDURE sin* (x: REAL): REAL; |
BEGIN |
IF x < ZERO THEN |
x := SinCos(x, -x, -ONE) |
ELSE |
x := SinCos(x, x, ONE) |
END |
RETURN x |
ASSERT(ABS(x) <= MaxCosArg); |
x := cos(x) |
RETURN sqrt(1.0 - x * x) |
END sin; |
PROCEDURE cos* (x: REAL): REAL; |
RETURN SinCos(x, ABS(x) + piByTwo, ONE) |
END cos; |
PROCEDURE tan* (x: REAL): REAL; |
VAR |
s, c: REAL; |
BEGIN |
s := sin(x); |
c := sqrt(ONE - s * s); |
x := ABS(x) / (TWO * pi); |
x := x - FLT(FLOOR(x)); |
IF (0.25 < x) & (x < 0.75) THEN |
c := -c |
END |
RETURN s / c |
ASSERT(ABS(x) <= MaxCosArg); |
x := cos(x) |
RETURN sqrt(1.0 - x * x) / x |
END tan; |
PROCEDURE arctan2* (y, x: REAL): REAL; |
CONST |
P0 = 0.216062307897242551884E+3; P1 = 0.3226620700132512059245E+3; |
P2 = 0.13270239816397674701E+3; P3 = 0.1288838303415727934E+2; |
Q0 = 0.2160623078972426128957E+3; Q1 = 0.3946828393122829592162E+3; |
Q2 = 0.221050883028417680623E+3; Q3 = 0.3850148650835119501E+2; |
Sqrt3 = 1.7320508075688772935E0; |
PROCEDURE arcsin* (x: REAL): REAL; |
PROCEDURE arctan (x: REAL): REAL; |
VAR |
atan, z, z2, p, q: REAL; |
yExp, xExp, Quadrant: INTEGER; |
z, p, k: REAL; |
BEGIN |
IF ABS(x) < miny THEN |
ASSERT(ABS(y) >= miny); |
atan := piByTwo |
ELSE |
z := y; |
UNPK(z, yExp); |
z := x; |
UNPK(z, xExp); |
p := x / (x * x + 1.0); |
z := p * x; |
x := 0.0; |
k := 0.0; |
IF yExp - xExp >= expoMax - 3 THEN |
atan := piByTwo |
ELSIF yExp - xExp < expoMin + 3 THEN |
atan := ZERO |
ELSE |
IF ABS(y) > ABS(x) THEN |
z := ABS(x / y); |
Quadrant := 2 |
ELSE |
z := ABS(y / x); |
Quadrant := 0 |
END; |
REPEAT |
k := k + 2.0; |
x := x + p; |
p := p * k * z / (k + 1.0) |
UNTIL p < eps |
IF z > TWO - Sqrt3 THEN |
z := (z * Sqrt3 - ONE) / (Sqrt3 + z); |
INC(Quadrant) |
END; |
RETURN x |
END arctan; |
IF ABS(z) < Limit THEN |
atan := z |
ELSE |
z2 := z * z; |
p := (((P3 * z2 + P2) * z2 + P1) * z2 + P0) * z; |
q := (((z2 + Q3) * z2 + Q2) * z2 + Q1) * z2 + Q0; |
atan := p / q |
END; |
CASE Quadrant OF |
|0: |
|1: atan := atan + pi / 6.0 |
|2: atan := piByTwo - atan |
|3: atan := pi / 3.0 - atan |
END |
END; |
BEGIN |
ASSERT(ABS(x) <= 1.0); |
IF x < ZERO THEN |
atan := pi - atan |
IF ABS(x) >= 0.707 THEN |
x := 0.5 * pi - arctan(sqrt(1.0 - x * x) / x) |
ELSE |
x := arctan(x / sqrt(1.0 - x * x)) |
END |
END; |
IF y < ZERO THEN |
atan := -atan |
END |
RETURN atan |
END arctan2; |
PROCEDURE arcsin* (x: REAL): REAL; |
BEGIN |
ASSERT(ABS(x) <= ONE) |
RETURN arctan2(x, sqrt(ONE - x * x)) |
RETURN x |
END arcsin; |
PROCEDURE arccos* (x: REAL): REAL; |
BEGIN |
ASSERT(ABS(x) <= ONE) |
RETURN arctan2(sqrt(ONE - x * x), x) |
ASSERT(ABS(x) <= 1.0) |
RETURN 0.5 * pi - arcsin(x) |
END arccos; |
PROCEDURE arctan* (x: REAL): REAL; |
RETURN arctan2(x, ONE) |
RETURN arcsin(x / sqrt(1.0 + x * x)) |
END arctan; |
362,7 → 217,7 |
PROCEDURE sinh* (x: REAL): REAL; |
BEGIN |
x := exp(x) |
RETURN (x - ONE / x) * HALF |
RETURN (x - 1.0 / x) * 0.5 |
END sinh; |
369,7 → 224,7 |
PROCEDURE cosh* (x: REAL): REAL; |
BEGIN |
x := exp(x) |
RETURN (x + ONE / x) * HALF |
RETURN (x + 1.0 / x) * 0.5 |
END cosh; |
376,12 → 231,12 |
PROCEDURE tanh* (x: REAL): REAL; |
BEGIN |
IF x > 15.0 THEN |
x := ONE |
x := 1.0 |
ELSIF x < -15.0 THEN |
x := -ONE |
x := -1.0 |
ELSE |
x := exp(TWO * x); |
x := (x - ONE) / (x + ONE) |
x := exp(2.0 * x); |
x := (x - 1.0) / (x + 1.0) |
END |
RETURN x |
389,21 → 244,21 |
PROCEDURE arsinh* (x: REAL): REAL; |
RETURN ln(x + sqrt(x * x + ONE)) |
RETURN ln(x + sqrt(x * x + 1.0)) |
END arsinh; |
PROCEDURE arcosh* (x: REAL): REAL; |
BEGIN |
ASSERT(x >= ONE) |
RETURN ln(x + sqrt(x * x - ONE)) |
ASSERT(x >= 1.0) |
RETURN ln(x + sqrt(x * x - 1.0)) |
END arcosh; |
PROCEDURE artanh* (x: REAL): REAL; |
BEGIN |
ASSERT(ABS(x) < ONE) |
RETURN HALF * ln((ONE + x) / (ONE - x)) |
ASSERT(ABS(x) < 1.0) |
RETURN 0.5 * ln((1.0 + x) / (1.0 - x)) |
END artanh; |
412,9 → 267,9 |
res: INTEGER; |
BEGIN |
IF x > ZERO THEN |
IF x > 0.0 THEN |
res := 1 |
ELSIF x < ZERO THEN |
ELSIF x < 0.0 THEN |
res := -1 |
ELSE |
res := 0 |
429,7 → 284,7 |
res: REAL; |
BEGIN |
res := ONE; |
res := 1.0; |
WHILE n > 1 DO |
res := res * FLT(n); |
DEC(n) |
439,42 → 294,18 |
END fact; |
PROCEDURE DegToRad* (x: REAL): REAL; |
RETURN x * (pi / 180.0) |
END DegToRad; |
PROCEDURE RadToDeg* (x: REAL): REAL; |
RETURN x * (180.0 / pi) |
END RadToDeg; |
(* Return hypotenuse of triangle *) |
PROCEDURE hypot* (x, y: REAL): REAL; |
PROCEDURE init; |
VAR |
a: REAL; |
i: INTEGER; |
BEGIN |
x := ABS(x); |
y := ABS(y); |
IF x > y THEN |
a := x * sqrt(1.0 + sqrr(y / x)) |
ELSE |
IF x > 0.0 THEN |
a := y * sqrt(1.0 + sqrr(x / y)) |
ELSE |
a := y |
Exp[0] := 1.0; |
FOR i := 1 TO LEN(Exp) - 1 DO |
Exp[i] := Exp[i - 1] * e |
END |
END |
END init; |
RETURN a |
END hypot; |
BEGIN |
large := 1.9; |
PACK(large, expoMax); |
miny := ONE / large; |
LnInfinity := ln(large); |
LnSmall := ln(miny); |
init |
END Math. |
/programs/develop/oberon07/Lib/Linux64/Out.ob07 |
---|
1,87 → 1,276 |
(* |
BSD 2-Clause License |
Copyright 2013, 2014, 2017, 2018, 2019 Anton Krotov |
Copyright (c) 2020, Anton Krotov |
All rights reserved. |
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 <http://www.gnu.org/licenses/>. |
*) |
MODULE Out; |
IMPORT SYSTEM, Libdl; |
IMPORT sys := SYSTEM, API; |
CONST |
d = 1.0 - 5.0E-12; |
VAR |
printf1: PROCEDURE [linux] (fmt: INTEGER; x: INTEGER); |
printf2: PROCEDURE [linux] (fmt: INTEGER; width, x: INTEGER); |
printf3: PROCEDURE [linux] (fmt: INTEGER; width, precision, x: INTEGER); |
Realp: PROCEDURE (x: REAL; width: INTEGER); |
PROCEDURE Char* (x: CHAR); |
BEGIN |
printf1(SYSTEM.SADR("%c"), ORD(x)) |
API.putc(x) |
END Char; |
PROCEDURE String* (s: ARRAY OF CHAR); |
VAR |
i: INTEGER; |
BEGIN |
printf2(SYSTEM.SADR("%.*s"), LENGTH(s), SYSTEM.ADR(s[0])) |
i := 0; |
WHILE (i < LEN(s)) & (s[i] # 0X) DO |
Char(s[i]); |
INC(i) |
END |
END String; |
PROCEDURE Ln*; |
PROCEDURE WriteInt(x, n: INTEGER); |
VAR i: INTEGER; a: ARRAY 24 OF CHAR; neg: BOOLEAN; |
BEGIN |
printf1(SYSTEM.SADR("%s"), SYSTEM.SADR(0AX)) |
END Ln; |
i := 0; |
IF n < 1 THEN |
n := 1 |
END; |
IF x < 0 THEN |
x := -x; |
DEC(n); |
neg := TRUE |
END; |
REPEAT |
a[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
WHILE n > i DO |
Char(" "); |
DEC(n) |
END; |
IF neg THEN |
Char("-") |
END; |
REPEAT |
DEC(i); |
Char(a[i]) |
UNTIL i = 0 |
END WriteInt; |
PROCEDURE IsNan(AValue: REAL): BOOLEAN; |
VAR s: SET; |
BEGIN |
sys.GET(sys.ADR(AValue), s) |
RETURN (s * {52..62} = {52..62}) & ((s * {32..51} # {}) OR (s * {0..31} # {})) |
END IsNan; |
PROCEDURE IsInf(x: REAL): BOOLEAN; |
RETURN ABS(x) = sys.INF() |
END IsInf; |
PROCEDURE Int* (x, width: INTEGER); |
VAR i: INTEGER; |
BEGIN |
printf2(SYSTEM.SADR("%*lld"), width, x) |
IF x # 80000000H THEN |
WriteInt(x, width) |
ELSE |
FOR i := 12 TO width DO |
Char(20X) |
END; |
String("-2147483648") |
END |
END Int; |
PROCEDURE OutInf(x: REAL; width: INTEGER); |
VAR s: ARRAY 5 OF CHAR; i: INTEGER; |
BEGIN |
IF IsNan(x) THEN |
s := "Nan"; |
INC(width) |
ELSIF IsInf(x) & (x > 0.0) THEN |
s := "+Inf" |
ELSIF IsInf(x) & (x < 0.0) THEN |
s := "-Inf" |
END; |
FOR i := 1 TO width - 4 DO |
Char(" ") |
END; |
String(s) |
END OutInf; |
PROCEDURE intval (x: REAL): INTEGER; |
VAR |
i: INTEGER; |
PROCEDURE Ln*; |
BEGIN |
Char(0AX) |
END Ln; |
PROCEDURE _FixReal(x: REAL; width, p: INTEGER); |
VAR e, len, i: INTEGER; y: REAL; minus: BOOLEAN; |
BEGIN |
SYSTEM.GET(SYSTEM.ADR(x), i) |
RETURN i |
END intval; |
IF IsNan(x) OR IsInf(x) THEN |
OutInf(x, width) |
ELSIF p < 0 THEN |
Realp(x, width) |
ELSE |
len := 0; |
minus := FALSE; |
IF x < 0.0 THEN |
minus := TRUE; |
INC(len); |
x := ABS(x) |
END; |
e := 0; |
WHILE x >= 10.0 DO |
x := x / 10.0; |
INC(e) |
END; |
IF e >= 0 THEN |
len := len + e + p + 1; |
IF x > 9.0 + d THEN |
INC(len) |
END; |
IF p > 0 THEN |
INC(len) |
END; |
ELSE |
len := len + p + 2 |
END; |
FOR i := 1 TO width - len DO |
Char(" ") |
END; |
IF minus THEN |
Char("-") |
END; |
y := x; |
WHILE (y < 1.0) & (y # 0.0) DO |
y := y * 10.0; |
DEC(e) |
END; |
IF e < 0 THEN |
IF x - FLT(FLOOR(x)) > d THEN |
Char("1"); |
x := 0.0 |
ELSE |
Char("0"); |
x := x * 10.0 |
END |
ELSE |
WHILE e >= 0 DO |
IF x - FLT(FLOOR(x)) > d THEN |
IF x > 9.0 THEN |
String("10") |
ELSE |
Char(CHR(FLOOR(x) + ORD("0") + 1)) |
END; |
x := 0.0 |
ELSE |
Char(CHR(FLOOR(x) + ORD("0"))); |
x := (x - FLT(FLOOR(x))) * 10.0 |
END; |
DEC(e) |
END |
END; |
IF p > 0 THEN |
Char(".") |
END; |
WHILE p > 0 DO |
IF x - FLT(FLOOR(x)) > d THEN |
Char(CHR(FLOOR(x) + ORD("0") + 1)); |
x := 0.0 |
ELSE |
Char(CHR(FLOOR(x) + ORD("0"))); |
x := (x - FLT(FLOOR(x))) * 10.0 |
END; |
DEC(p) |
END |
END |
END _FixReal; |
PROCEDURE Real* (x: REAL; width: INTEGER); |
VAR e, n, i: INTEGER; minus: BOOLEAN; |
BEGIN |
printf3(SYSTEM.SADR("%*.*E"), width, MAX(MIN(width - 8, 15), 1), intval(x)) |
Realp := Real; |
IF IsNan(x) OR IsInf(x) THEN |
OutInf(x, width) |
ELSE |
e := 0; |
n := 0; |
IF width > 23 THEN |
n := width - 23; |
width := 23 |
ELSIF width < 9 THEN |
width := 9 |
END; |
width := width - 5; |
IF x < 0.0 THEN |
x := -x; |
minus := TRUE |
ELSE |
minus := FALSE |
END; |
WHILE x >= 10.0 DO |
x := x / 10.0; |
INC(e) |
END; |
WHILE (x < 1.0) & (x # 0.0) DO |
x := x * 10.0; |
DEC(e) |
END; |
IF x > 9.0 + d THEN |
x := 1.0; |
INC(e) |
END; |
FOR i := 1 TO n DO |
Char(" ") |
END; |
IF minus THEN |
x := -x |
END; |
_FixReal(x, width, width - 3); |
Char("E"); |
IF e >= 0 THEN |
Char("+") |
ELSE |
Char("-"); |
e := ABS(e) |
END; |
IF e < 100 THEN |
Char("0") |
END; |
IF e < 10 THEN |
Char("0") |
END; |
Int(e, 0) |
END |
END Real; |
PROCEDURE FixReal* (x: REAL; width, precision: INTEGER); |
PROCEDURE FixReal*(x: REAL; width, p: INTEGER); |
BEGIN |
printf3(SYSTEM.SADR("%*.*f"), width, precision, intval(x)) |
Realp := Real; |
_FixReal(x, width, p) |
END FixReal; |
PROCEDURE Open*; |
END Open; |
PROCEDURE init; |
VAR |
libc, printf: INTEGER; |
BEGIN |
libc := Libdl.open("libc.so.6", Libdl.LAZY); |
ASSERT(libc # 0); |
printf := Libdl.sym(libc, "printf"); |
ASSERT(printf # 0); |
SYSTEM.PUT(SYSTEM.ADR(printf1), printf); |
SYSTEM.PUT(SYSTEM.ADR(printf2), printf); |
SYSTEM.PUT(SYSTEM.ADR(printf3), printf); |
END init; |
BEGIN |
init |
END Out. |
/programs/develop/oberon07/Lib/Linux64/RTL.ob07 |
---|
350,29 → 350,33 |
PROCEDURE IntToStr (x: INTEGER; VAR str: ARRAY OF CHAR); |
VAR |
i, a: INTEGER; |
i, a, b: INTEGER; |
c: CHAR; |
BEGIN |
i := 0; |
a := x; |
REPEAT |
INC(i); |
a := a DIV 10 |
UNTIL a = 0; |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
str[i] := 0X; |
REPEAT |
DEC(i); |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10 |
UNTIL x = 0 |
a := 0; |
b := i - 1; |
WHILE a < b DO |
c := str[a]; |
str[a] := str[b]; |
str[b] := c; |
INC(a); |
DEC(b) |
END; |
str[i] := 0X |
END IntToStr; |
PROCEDURE append (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); |
VAR |
n1, n2: INTEGER; |
n1, n2, i, j: INTEGER; |
BEGIN |
n1 := LENGTH(s1); |
380,12 → 384,19 |
ASSERT(n1 + n2 < LEN(s1)); |
SYSTEM.MOVE(SYSTEM.ADR(s2[0]), SYSTEM.ADR(s1[n1]), n2); |
s1[n1 + n2] := 0X |
i := 0; |
j := n1; |
WHILE i < n2 DO |
s1[j] := s2[i]; |
INC(i); |
INC(j) |
END; |
s1[j] := 0X |
END append; |
PROCEDURE [stdcall64] _error* (modnum, _module, err, line: INTEGER); |
PROCEDURE [stdcall64] _error* (module, err, line: INTEGER); |
VAR |
s, temp: ARRAY 1024 OF CHAR; |
404,9 → 415,11 |
|11: s := "BYTE out of range" |
END; |
append(s, API.eol + "module: "); PCharToStr(_module, temp); append(s, temp); |
append(s, API.eol + "line: "); IntToStr(line, temp); append(s, temp); |
append(s, API.eol); |
append(s, "module: "); PCharToStr(module, temp); append(s, temp); append(s, API.eol); |
append(s, "line: "); IntToStr(line, temp); append(s, temp); |
API.DebugMsg(SYSTEM.ADR(s[0]), name); |
API.exit_thread(0) |
/programs/develop/oberon07/Lib/Windows32/API.ob07 |
---|
12,8 → 12,6 |
CONST |
eol* = 0DX + 0AX; |
SectionAlignment = 1000H; |
DLL_PROCESS_ATTACH = 1; |
21,10 → 19,7 |
DLL_THREAD_DETACH = 3; |
DLL_PROCESS_DETACH = 0; |
KERNEL = "kernel32.dll"; |
USER = "user32.dll"; |
TYPE |
DLL_ENTRY* = PROCEDURE (hinstDLL, fdwReason, lpvReserved: INTEGER); |
32,6 → 27,7 |
VAR |
eol*: ARRAY 3 OF CHAR; |
base*: INTEGER; |
heap: INTEGER; |
40,14 → 36,15 |
thread_attach: DLL_ENTRY; |
PROCEDURE [windows-, KERNEL, ""] ExitProcess (code: INTEGER); |
PROCEDURE [windows-, KERNEL, ""] ExitThread (code: INTEGER); |
PROCEDURE [windows-, KERNEL, ""] GetProcessHeap (): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] HeapAlloc (hHeap, dwFlags, dwBytes: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] HeapFree (hHeap, dwFlags, lpMem: INTEGER); |
PROCEDURE [windows-, USER, ""] MessageBoxA (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "ExitProcess"] ExitProcess (code: INTEGER); |
PROCEDURE [windows-, "kernel32.dll", "ExitThread"] ExitThread (code: INTEGER); |
PROCEDURE [windows-, "kernel32.dll", "GetProcessHeap"] GetProcessHeap (): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "HeapAlloc"] HeapAlloc (hHeap, dwFlags, dwBytes: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "HeapFree"] HeapFree(hHeap, dwFlags, lpMem: INTEGER); |
PROCEDURE [windows-, "user32.dll", "MessageBoxA"] MessageBoxA (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE DebugMsg* (lpText, lpCaption: INTEGER); |
BEGIN |
MessageBoxA(0, lpText, lpCaption, 16) |
71,6 → 68,7 |
process_detach := NIL; |
thread_detach := NIL; |
thread_attach := NIL; |
eol[0] := 0DX; eol[1] := 0AX; eol[2] := 0X; |
base := code - SectionAlignment; |
heap := GetProcessHeap() |
END init; |
/programs/develop/oberon07/Lib/Windows32/Args.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2019-2020, Anton Krotov |
Copyright (c) 2019, Anton Krotov |
All rights reserved. |
*) |
54,7 → 54,7 |
BEGIN |
p := WINAPI.GetCommandLineA(); |
p := WINAPI.GetCommandLine(); |
cond := 0; |
count := 0; |
WHILE (count < MAX_PARAM) & (cond # 6) DO |
/programs/develop/oberon07/Lib/Windows32/Console.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2019-2020, Anton Krotov |
Copyright (c) 2019, Anton Krotov |
All rights reserved. |
*) |
48,7 → 48,7 |
BEGIN |
WINAPI.GetConsoleScreenBufferInfo(hConsoleOutput, ScrBufInfo); |
fill := ORD(ScrBufInfo.dwSize.X) * ORD(ScrBufInfo.dwSize.Y); |
WINAPI.FillConsoleOutputCharacterA(hConsoleOutput, 20H, fill, 0, SYSTEM.ADR(fill)); |
WINAPI.FillConsoleOutputCharacter(hConsoleOutput, 20H, fill, 0, SYSTEM.ADR(fill)); |
WINAPI.FillConsoleOutputAttribute(hConsoleOutput, ORD(ScrBufInfo.wAttributes), fill, 0, SYSTEM.ADR(fill)); |
SetCursor(0, 0) |
END Cls; |
/programs/develop/oberon07/Lib/Windows32/DateTime.ob07 |
---|
1,13 → 1,13 |
(* |
BSD 2-Clause License |
Copyright (c) 2019-2020, Anton Krotov |
Copyright (c) 2019, Anton Krotov |
All rights reserved. |
*) |
MODULE DateTime; |
IMPORT WINAPI, SYSTEM; |
IMPORT WINAPI; |
CONST |
116,29 → 116,6 |
END NowEncode; |
PROCEDURE NowUnixTime* (): INTEGER; |
RETURN WINAPI.time(0) |
END NowUnixTime; |
PROCEDURE UnixTime* (Year, Month, Day, Hour, Min, Sec: INTEGER): INTEGER; |
VAR |
t: WINAPI.tm; |
BEGIN |
DEC(Year, 1900); |
DEC(Month); |
SYSTEM.GET(SYSTEM.ADR(Sec), t.sec); |
SYSTEM.GET(SYSTEM.ADR(Min), t.min); |
SYSTEM.GET(SYSTEM.ADR(Hour), t.hour); |
SYSTEM.GET(SYSTEM.ADR(Day), t.mday); |
SYSTEM.GET(SYSTEM.ADR(Month), t.mon); |
SYSTEM.GET(SYSTEM.ADR(Year), t.year); |
RETURN WINAPI.mktime(t) |
END UnixTime; |
PROCEDURE init; |
VAR |
day, year, month, i: INTEGER; |
/programs/develop/oberon07/Lib/Windows32/File.ob07 |
---|
1,13 → 1,13 |
(* |
BSD 2-Clause License |
Copyright (c) 2019-2020, Anton Krotov |
Copyright (c) 2019, Anton Krotov |
All rights reserved. |
*) |
MODULE File; |
IMPORT SYSTEM, WINAPI, API; |
IMPORT SYSTEM, WINAPI; |
CONST |
20,14 → 20,12 |
VAR |
FindData: WINAPI.TWin32FindData; |
Handle: INTEGER; |
attr: SET; |
BEGIN |
Handle := WINAPI.FindFirstFileA(SYSTEM.ADR(FName[0]), FindData); |
Handle := WINAPI.FindFirstFile(SYSTEM.ADR(FName[0]), FindData); |
IF Handle # -1 THEN |
WINAPI.FindClose(Handle); |
SYSTEM.GET32(SYSTEM.ADR(FindData.dwFileAttributes), attr); |
IF 4 IN attr THEN |
IF 4 IN FindData.dwFileAttributes THEN |
Handle := -1 |
END |
END |
37,12 → 35,12 |
PROCEDURE Delete* (FName: ARRAY OF CHAR): BOOLEAN; |
RETURN WINAPI.DeleteFileA(SYSTEM.ADR(FName[0])) # 0 |
RETURN WINAPI.DeleteFile(SYSTEM.ADR(FName[0])) # 0 |
END Delete; |
PROCEDURE Create* (FName: ARRAY OF CHAR): INTEGER; |
RETURN WINAPI.CreateFileA(SYSTEM.ADR(FName[0]), 0C0000000H, 0, NIL, 2, 80H, 0) |
RETURN WINAPI.CreateFile(SYSTEM.ADR(FName[0]), 0C0000000H, 0, NIL, 2, 80H, 0) |
END Create; |
67,11 → 65,13 |
PROCEDURE Read* (F, Buffer, Count: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
res, n: INTEGER; |
BEGIN |
IF WINAPI.ReadFile(F, Buffer, Count, SYSTEM.ADR(res), NIL) = 0 THEN |
IF WINAPI.ReadFile(F, Buffer, Count, SYSTEM.ADR(n), NIL) = 0 THEN |
res := -1 |
ELSE |
res := n |
END |
RETURN res |
80,11 → 80,13 |
PROCEDURE Write* (F, Buffer, Count: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
res, n: INTEGER; |
BEGIN |
IF WINAPI.WriteFile(F, Buffer, Count, SYSTEM.ADR(res), NIL) = 0 THEN |
IF WINAPI.WriteFile(F, Buffer, Count, SYSTEM.ADR(n), NIL) = 0 THEN |
res := -1 |
ELSE |
res := n |
END |
RETURN res |
102,10 → 104,11 |
IF F # -1 THEN |
Size := Seek(F, 0, SEEK_END); |
n := Seek(F, 0, SEEK_BEG); |
res := API._NEW(Size); |
res := WINAPI.GlobalAlloc(64, Size); |
IF (res = 0) OR (Read(F, res, Size) # Size) THEN |
IF res # 0 THEN |
res := API._DISPOSE(res); |
WINAPI.GlobalFree(Size); |
res := 0; |
Size := 0 |
END |
END; |
117,7 → 120,7 |
PROCEDURE RemoveDir* (DirName: ARRAY OF CHAR): BOOLEAN; |
RETURN WINAPI.RemoveDirectoryA(SYSTEM.ADR(DirName[0])) # 0 |
RETURN WINAPI.RemoveDirectory(SYSTEM.ADR(DirName[0])) # 0 |
END RemoveDir; |
126,13 → 129,13 |
Code: SET; |
BEGIN |
Code := WINAPI.GetFileAttributesA(SYSTEM.ADR(DirName[0])) |
Code := WINAPI.GetFileAttributes(SYSTEM.ADR(DirName[0])) |
RETURN (Code # {0..31}) & (4 IN Code) |
END ExistsDir; |
PROCEDURE CreateDir* (DirName: ARRAY OF CHAR): BOOLEAN; |
RETURN WINAPI.CreateDirectoryA(SYSTEM.ADR(DirName[0]), NIL) # 0 |
RETURN WINAPI.CreateDirectory(SYSTEM.ADR(DirName[0]), NIL) # 0 |
END CreateDir; |
/programs/develop/oberon07/Lib/Windows32/HOST.ob07 |
---|
13,7 → 13,7 |
CONST |
slash* = "\"; |
eol* = 0DX + 0AX; |
OS* = "WINDOWS"; |
bit_depth* = RTL.bit_depth; |
maxint* = RTL.maxint; |
59,7 → 59,20 |
END; |
TSystemTime = RECORD |
Year, |
Month, |
DayOfWeek, |
Day, |
Hour, |
Min, |
Sec, |
MSec: WCHAR |
END; |
VAR |
hConsoleOutput: INTEGER; |
67,6 → 80,8 |
Params: ARRAY MAX_PARAM, 2 OF INTEGER; |
argc: INTEGER; |
eol*: ARRAY 3 OF CHAR; |
maxreal*: REAL; |
101,13 → 116,13 |
PROCEDURE [windows-, "kernel32.dll", "GetCurrentDirectoryA"] |
_GetCurrentDirectory (nBufferLength, lpBuffer: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetSystemTime"] |
_GetSystemTime (T: TSystemTime); |
PROCEDURE [windows-, "kernel32.dll", "ExitProcess"] |
_ExitProcess (code: INTEGER); |
PROCEDURE [ccall, "msvcrt.dll", "time"] |
_time (ptr: INTEGER): INTEGER; |
PROCEDURE ExitProcess* (code: INTEGER); |
BEGIN |
_ExitProcess(code) |
200,11 → 215,13 |
PROCEDURE FileRead* (F: INTEGER; VAR Buffer: ARRAY OF CHAR; bytes: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
res, n: INTEGER; |
BEGIN |
IF _ReadFile(F, SYSTEM.ADR(Buffer[0]), bytes, res, NIL) = 0 THEN |
IF _ReadFile(F, SYSTEM.ADR(Buffer[0]), bytes, n, NIL) = 0 THEN |
res := -1 |
ELSE |
res := n |
END |
RETURN res |
213,11 → 230,13 |
PROCEDURE FileWrite* (F: INTEGER; Buffer: ARRAY OF BYTE; bytes: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
res, n: INTEGER; |
BEGIN |
IF _WriteFile(F, SYSTEM.ADR(Buffer[0]), bytes, res, NIL) = 0 THEN |
IF _WriteFile(F, SYSTEM.ADR(Buffer[0]), bytes, n, NIL) = 0 THEN |
res := -1 |
ELSE |
res := n |
END |
RETURN res |
250,10 → 269,6 |
END FileOpen; |
PROCEDURE chmod* (FName: ARRAY OF CHAR); |
END chmod; |
PROCEDURE OutChar* (c: CHAR); |
VAR |
count: INTEGER; |
277,25 → 292,33 |
END isRelative; |
PROCEDURE now* (VAR year, month, day, hour, min, sec: INTEGER); |
VAR |
T: TSystemTime; |
BEGIN |
_GetSystemTime(T); |
year := ORD(T.Year); |
month := ORD(T.Month); |
day := ORD(T.Day); |
hour := ORD(T.Hour); |
min := ORD(T.Min); |
sec := ORD(T.Sec) |
END now; |
PROCEDURE UnixTime* (): INTEGER; |
RETURN _time(0) |
RETURN 0 |
END UnixTime; |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
BEGIN |
SYSTEM.GET32(SYSTEM.ADR(x), a); |
SYSTEM.GET32(SYSTEM.ADR(x) + 4, b) |
RETURN a |
END splitf; |
PROCEDURE d2s* (x: REAL): INTEGER; |
VAR |
h, l, s, e: INTEGER; |
BEGIN |
e := splitf(x, l, h); |
SYSTEM.GET(SYSTEM.ADR(x), l); |
SYSTEM.GET(SYSTEM.ADR(x) + 4, h); |
s := ASR(h, 31) MOD 2; |
e := (h DIV 100000H) MOD 2048; |
314,7 → 337,7 |
l := 0 |
ELSIF e = 2047 THEN |
e := 1151; |
IF (h MOD 100000H # 0) OR (BITS(l) * {0..31} # {}) THEN |
IF (h MOD 100000H # 0) OR (l # 0) THEN |
h := 80000H; |
l := 0 |
END |
325,7 → 348,22 |
END d2s; |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
BEGIN |
a := 0; |
b := 0; |
SYSTEM.MOVE(SYSTEM.ADR(x), SYSTEM.ADR(a), 4); |
SYSTEM.MOVE(SYSTEM.ADR(x) + 4, SYSTEM.ADR(b), 4); |
SYSTEM.GET(SYSTEM.ADR(x), res) |
RETURN res |
END splitf; |
BEGIN |
eol[0] := 0DX; eol[1] := 0AX; eol[2] := 0X; |
maxreal := 1.9; |
PACK(maxreal, 1023); |
hConsoleOutput := _GetStdHandle(-11); |
/programs/develop/oberon07/Lib/Windows32/In.ob07 |
---|
1,80 → 1,289 |
(* |
BSD 2-Clause License |
Copyright 2013, 2017, 2018 Anton Krotov |
Copyright (c) 2020, Anton Krotov |
All rights reserved. |
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 <http://www.gnu.org/licenses/>. |
*) |
MODULE In; |
IMPORT SYSTEM; |
IMPORT sys := SYSTEM, WINAPI; |
TYPE |
CONST |
STRING = ARRAY 260 OF CHAR; |
MAX_LEN = 1024; |
VAR |
Done*: BOOLEAN; |
hConsoleInput: INTEGER; |
s: ARRAY MAX_LEN + 4 OF CHAR; |
PROCEDURE digit(ch: CHAR): BOOLEAN; |
RETURN (ch >= "0") & (ch <= "9") |
END digit; |
PROCEDURE [ccall, "msvcrt.dll", ""] sscanf (buf: INTEGER; fmt: INTEGER; adr: INTEGER): INTEGER; |
PROCEDURE [windows, "kernel32.dll", ""] GetStdHandle (nStdHandle: INTEGER): INTEGER; |
PROCEDURE [windows, "kernel32.dll", ""] ReadConsoleA (hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, lpReserved: INTEGER); |
PROCEDURE CheckInt(s: STRING; VAR first, last: INTEGER; VAR neg: BOOLEAN; Point: BOOLEAN): BOOLEAN; |
VAR i: INTEGER; |
BEGIN |
i := 0; |
neg := FALSE; |
WHILE (s[i] <= 20X) & (s[i] # 0X) DO |
INC(i) |
END; |
IF s[i] = "-" THEN |
neg := TRUE; |
INC(i) |
ELSIF s[i] = "+" THEN |
INC(i) |
END; |
first := i; |
WHILE digit(s[i]) DO |
INC(i) |
END; |
last := i |
RETURN ((s[i] <= 20X) OR (Point & (s[i] = "."))) & digit(s[first]) |
END CheckInt; |
PROCEDURE IsMinInt(str: STRING; pos: INTEGER): BOOLEAN; |
VAR i: INTEGER; min: STRING; |
BEGIN |
i := 0; |
min := "2147483648"; |
WHILE (min[i] # 0X) & (str[i] # 0X) & (min[i] = str[i + pos]) DO |
INC(i) |
END |
RETURN i = 10 |
END IsMinInt; |
PROCEDURE String* (VAR str: ARRAY OF CHAR); |
VAR |
count: INTEGER; |
PROCEDURE StrToInt(str: STRING; VAR err: BOOLEAN): INTEGER; |
CONST maxINT = 7FFFFFFFH; |
VAR i, n, res: INTEGER; flag, neg: BOOLEAN; |
BEGIN |
res := 0; |
flag := CheckInt(str, i, n, neg, FALSE); |
err := ~flag; |
IF flag & neg & IsMinInt(str, i) THEN |
flag := FALSE; |
neg := FALSE; |
res := 80000000H |
END; |
WHILE flag & digit(str[i]) DO |
IF res > maxINT DIV 10 THEN |
err := TRUE; |
flag := FALSE; |
res := 0 |
ELSE |
res := res * 10; |
IF res > maxINT - (ORD(str[i]) - ORD("0")) THEN |
err := TRUE; |
flag := FALSE; |
res := 0 |
ELSE |
res := res + (ORD(str[i]) - ORD("0")); |
INC(i) |
END |
END |
END; |
IF neg THEN |
res := -res |
END |
RETURN res |
END StrToInt; |
PROCEDURE Space(s: STRING): BOOLEAN; |
VAR i: INTEGER; |
BEGIN |
ReadConsoleA(hConsoleInput, SYSTEM.ADR(s[0]), MAX_LEN, SYSTEM.ADR(count), 0); |
IF (s[count - 1] = 0AX) & (s[count - 2] = 0DX) THEN |
DEC(count, 2) |
i := 0; |
WHILE (s[i] # 0X) & (s[i] <= 20X) DO |
INC(i) |
END |
RETURN s[i] = 0X |
END Space; |
PROCEDURE CheckReal(s: STRING; VAR n: INTEGER; VAR neg: BOOLEAN): BOOLEAN; |
VAR i: INTEGER; Res: BOOLEAN; |
BEGIN |
Res := CheckInt(s, n, i, neg, TRUE); |
IF Res THEN |
IF s[i] = "." THEN |
INC(i); |
WHILE digit(s[i]) DO |
INC(i) |
END; |
s[count] := 0X; |
COPY(s, str); |
str[LEN(str) - 1] := 0X; |
Done := TRUE |
END String; |
IF (s[i] = "D") OR (s[i] = "E") OR (s[i] = "d") OR (s[i] = "e") THEN |
INC(i); |
IF (s[i] = "+") OR (s[i] = "-") THEN |
INC(i) |
END; |
Res := digit(s[i]); |
WHILE digit(s[i]) DO |
INC(i) |
END |
END |
END |
END |
RETURN Res & (s[i] <= 20X) |
END CheckReal; |
PROCEDURE StrToFloat(str: STRING; VAR err: BOOLEAN): REAL; |
CONST maxDBL = 1.69E308; maxINT = 7FFFFFFFH; |
VAR i, scale: INTEGER; res, m, d: REAL; minus, neg: BOOLEAN; |
PROCEDURE Int* (VAR x: INTEGER); |
PROCEDURE part1(VAR res, d: REAL; VAR i: INTEGER; str: STRING): BOOLEAN; |
BEGIN |
String(s); |
Done := sscanf(SYSTEM.ADR(s[0]), SYSTEM.SADR("%d"), SYSTEM.ADR(x)) = 1 |
END Int; |
res := 0.0; |
d := 1.0; |
WHILE digit(str[i]) DO |
res := res * 10.0 + FLT(ORD(str[i]) - ORD("0")); |
INC(i) |
END; |
IF str[i] = "." THEN |
INC(i); |
WHILE digit(str[i]) DO |
d := d / 10.0; |
res := res + FLT(ORD(str[i]) - ORD("0")) * d; |
INC(i) |
END |
END |
RETURN str[i] # 0X |
END part1; |
PROCEDURE part2(VAR i, scale: INTEGER; VAR m, res: REAL; VAR minus, err: BOOLEAN; str: STRING): BOOLEAN; |
BEGIN |
INC(i); |
m := 10.0; |
minus := FALSE; |
IF str[i] = "+" THEN |
INC(i) |
ELSIF str[i] = "-" THEN |
minus := TRUE; |
INC(i); |
m := 0.1 |
END; |
scale := 0; |
err := FALSE; |
WHILE ~err & digit(str[i]) DO |
IF scale > maxINT DIV 10 THEN |
err := TRUE; |
res := 0.0 |
ELSE |
scale := scale * 10; |
IF scale > maxINT - (ORD(str[i]) - ORD("0")) THEN |
err := TRUE; |
res := 0.0 |
ELSE |
scale := scale + (ORD(str[i]) - ORD("0")); |
INC(i) |
END |
END |
END |
RETURN ~err |
END part2; |
PROCEDURE Real* (VAR x: REAL); |
PROCEDURE part3 (VAR err, minus: BOOLEAN; VAR scale: INTEGER; VAR res, m: REAL); |
VAR i: INTEGER; |
BEGIN |
String(s); |
Done := sscanf(SYSTEM.ADR(s[0]), SYSTEM.SADR("%lf"), SYSTEM.ADR(x)) = 1 |
END Real; |
err := FALSE; |
IF scale = maxINT THEN |
err := TRUE; |
res := 0.0 |
END; |
i := 1; |
WHILE ~err & (i <= scale) DO |
IF ~minus & (res > maxDBL / m) THEN |
err := TRUE; |
res := 0.0 |
ELSE |
res := res * m; |
INC(i) |
END |
END |
END part3; |
BEGIN |
IF CheckReal(str, i, neg) THEN |
IF part1(res, d, i, str) & part2(i, scale, m, res, minus, err, str) THEN |
part3(err, minus, scale, res, m) |
END; |
IF neg THEN |
res := -res |
END |
ELSE |
res := 0.0; |
err := TRUE |
END |
RETURN res |
END StrToFloat; |
PROCEDURE String*(VAR s: ARRAY OF CHAR); |
VAR count, i: INTEGER; str: STRING; |
BEGIN |
WINAPI.ReadConsole(hConsoleInput, sys.ADR(str[0]), 256, sys.ADR(count), 0); |
IF (str[count - 1] = 0AX) & (str[count - 2] = 0DX) THEN |
DEC(count, 2) |
END; |
str[256] := 0X; |
str[count] := 0X; |
i := 0; |
WHILE (i < LEN(s) - 1) & (i < LEN(str)) & (str[i] # 0X) DO |
s[i] := str[i]; |
INC(i) |
END; |
s[i] := 0X; |
Done := TRUE |
END String; |
PROCEDURE Char* (VAR x: CHAR); |
VAR str: STRING; |
BEGIN |
String(s); |
x := s[0] |
String(str); |
x := str[0]; |
Done := TRUE |
END Char; |
PROCEDURE Ln*; |
VAR str: STRING; |
BEGIN |
String(s) |
String(str); |
Done := TRUE |
END Ln; |
PROCEDURE Real*(VAR x: REAL); |
VAR str: STRING; err: BOOLEAN; |
BEGIN |
err := FALSE; |
REPEAT |
String(str) |
UNTIL ~Space(str); |
x := StrToFloat(str, err); |
Done := ~err |
END Real; |
PROCEDURE Int*(VAR x: INTEGER); |
VAR str: STRING; err: BOOLEAN; |
BEGIN |
err := FALSE; |
REPEAT |
String(str) |
UNTIL ~Space(str); |
x := StrToInt(str, err); |
Done := ~err |
END Int; |
PROCEDURE Open*; |
BEGIN |
hConsoleInput := GetStdHandle(-10); |
hConsoleInput := WINAPI.GetStdHandle(-10); |
Done := TRUE |
END Open; |
END In. |
/programs/develop/oberon07/Lib/Windows32/Math.ob07 |
---|
1,8 → 1,18 |
(* |
BSD 2-Clause License |
Copyright 2013, 2014, 2018, 2019 Anton Krotov |
Copyright (c) 2013-2014, 2018-2020 Anton Krotov |
All rights reserved. |
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 <http://www.gnu.org/licenses/>. |
*) |
MODULE Math; |
225,16 → 235,6 |
END frac; |
PROCEDURE sqri* (x: INTEGER): INTEGER; |
RETURN x * x |
END sqri; |
PROCEDURE sqrr* (x: REAL): REAL; |
RETURN x * x |
END sqrr; |
PROCEDURE arcsin* (x: REAL): REAL; |
RETURN arctan2(x, sqrt(1.0 - x * x)) |
END arcsin; |
349,40 → 349,6 |
END power; |
PROCEDURE ipower* (base: REAL; exponent: INTEGER): REAL; |
VAR |
i: INTEGER; |
a: REAL; |
BEGIN |
a := 1.0; |
IF base # 0.0 THEN |
IF exponent # 0 THEN |
IF exponent < 0 THEN |
base := 1.0 / base |
END; |
i := ABS(exponent); |
WHILE i > 0 DO |
WHILE ~ODD(i) DO |
i := LSR(i, 1); |
base := sqrr(base) |
END; |
DEC(i); |
a := a * base |
END |
ELSE |
a := 1.0 |
END |
ELSE |
ASSERT(exponent > 0); |
a := 0.0 |
END |
RETURN a |
END ipower; |
PROCEDURE sgn* (x: REAL): INTEGER; |
VAR |
res: INTEGER; |
415,36 → 381,4 |
END fact; |
PROCEDURE DegToRad* (x: REAL): REAL; |
RETURN x * (pi / 180.0) |
END DegToRad; |
PROCEDURE RadToDeg* (x: REAL): REAL; |
RETURN x * (180.0 / pi) |
END RadToDeg; |
(* Return hypotenuse of triangle *) |
PROCEDURE hypot* (x, y: REAL): REAL; |
VAR |
a: REAL; |
BEGIN |
x := ABS(x); |
y := ABS(y); |
IF x > y THEN |
a := x * sqrt(1.0 + sqrr(y / x)) |
ELSE |
IF x > 0.0 THEN |
a := y * sqrt(1.0 + sqrr(x / y)) |
ELSE |
a := y |
END |
END |
RETURN a |
END hypot; |
END Math. |
/programs/develop/oberon07/Lib/Windows32/Out.ob07 |
---|
1,77 → 1,280 |
(* |
BSD 2-Clause License |
Copyright 2013, 2014, 2017, 2018 Anton Krotov |
Copyright (c) 2020, Anton Krotov |
All rights reserved. |
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 <http://www.gnu.org/licenses/>. |
*) |
MODULE Out; |
IMPORT SYSTEM; |
IMPORT sys := SYSTEM, WINAPI; |
CONST |
d = 1.0 - 5.0E-12; |
VAR |
hConsoleOutput: INTEGER; |
Realp: PROCEDURE (x: REAL; width: INTEGER); |
PROCEDURE [ccall, "msvcrt.dll", "printf"] printf1 (fmt: INTEGER; x: INTEGER); |
PROCEDURE [ccall, "msvcrt.dll", "printf"] printf2 (fmt: INTEGER; width, x: INTEGER); |
PROCEDURE [ccall, "msvcrt.dll", "printf"] printf3 (fmt: INTEGER; width, precision: INTEGER; x: REAL); |
PROCEDURE String*(s: ARRAY OF CHAR); |
VAR count: INTEGER; |
BEGIN |
WINAPI.WriteFile(hConsoleOutput, sys.ADR(s[0]), LENGTH(s), sys.ADR(count), NIL) |
END String; |
PROCEDURE [windows, "kernel32.dll", ""] |
WriteConsoleW (hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved: INTEGER); |
PROCEDURE StringW*(s: ARRAY OF WCHAR); |
VAR count: INTEGER; |
BEGIN |
WINAPI.WriteConsoleW(hConsoleOutput, sys.ADR(s[0]), LENGTH(s), sys.ADR(count), 0) |
END StringW; |
PROCEDURE [windows, "kernel32.dll", ""] |
GetStdHandle (nStdHandle: INTEGER): INTEGER; |
PROCEDURE Char* (x: CHAR); |
VAR count: INTEGER; |
BEGIN |
printf1(SYSTEM.SADR("%c"), ORD(x)) |
WINAPI.WriteFile(hConsoleOutput, sys.ADR(x), 1, sys.ADR(count), NIL) |
END Char; |
PROCEDURE WriteInt(x, n: INTEGER); |
VAR i: INTEGER; a: ARRAY 16 OF CHAR; neg: BOOLEAN; |
BEGIN |
i := 0; |
IF n < 1 THEN |
n := 1 |
END; |
IF x < 0 THEN |
x := -x; |
DEC(n); |
neg := TRUE |
END; |
REPEAT |
a[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
WHILE n > i DO |
Char(" "); |
DEC(n) |
END; |
IF neg THEN |
Char("-") |
END; |
REPEAT |
DEC(i); |
Char(a[i]) |
UNTIL i = 0 |
END WriteInt; |
PROCEDURE StringW* (s: ARRAY OF WCHAR); |
PROCEDURE IsNan(AValue: REAL): BOOLEAN; |
VAR h, l: SET; |
BEGIN |
WriteConsoleW(hConsoleOutput, SYSTEM.ADR(s[0]), LENGTH(s), 0, 0) |
END StringW; |
sys.GET(sys.ADR(AValue), l); |
sys.GET(sys.ADR(AValue) + 4, h) |
RETURN (h * {20..30} = {20..30}) & ((h * {0..19} # {}) OR (l * {0..31} # {})) |
END IsNan; |
PROCEDURE IsInf(x: REAL): BOOLEAN; |
RETURN ABS(x) = sys.INF() |
END IsInf; |
PROCEDURE String* (s: ARRAY OF CHAR); |
PROCEDURE Int*(x, width: INTEGER); |
VAR i: INTEGER; |
BEGIN |
printf2(SYSTEM.SADR("%.*s"), LENGTH(s), SYSTEM.ADR(s[0])) |
END String; |
IF x # 80000000H THEN |
WriteInt(x, width) |
ELSE |
FOR i := 12 TO width DO |
Char(20X) |
END; |
String("-2147483648") |
END |
END Int; |
PROCEDURE OutInf(x: REAL; width: INTEGER); |
VAR s: ARRAY 5 OF CHAR; i: INTEGER; |
BEGIN |
IF IsNan(x) THEN |
s := "Nan"; |
INC(width) |
ELSIF IsInf(x) & (x > 0.0) THEN |
s := "+Inf" |
ELSIF IsInf(x) & (x < 0.0) THEN |
s := "-Inf" |
END; |
FOR i := 1 TO width - 4 DO |
Char(" ") |
END; |
String(s) |
END OutInf; |
PROCEDURE Ln*; |
BEGIN |
printf1(SYSTEM.SADR("%s"), SYSTEM.SADR(CHR(13) + CHR(10))) |
Char(0DX); |
Char(0AX) |
END Ln; |
PROCEDURE Int* (x, width: INTEGER); |
PROCEDURE _FixReal(x: REAL; width, p: INTEGER); |
VAR e, len, i: INTEGER; y: REAL; minus: BOOLEAN; |
BEGIN |
printf2(SYSTEM.SADR("%*d"), width, x) |
END Int; |
IF IsNan(x) OR IsInf(x) THEN |
OutInf(x, width) |
ELSIF p < 0 THEN |
Realp(x, width) |
ELSE |
len := 0; |
minus := FALSE; |
IF x < 0.0 THEN |
minus := TRUE; |
INC(len); |
x := ABS(x) |
END; |
e := 0; |
WHILE x >= 10.0 DO |
x := x / 10.0; |
INC(e) |
END; |
IF e >= 0 THEN |
len := len + e + p + 1; |
IF x > 9.0 + d THEN |
INC(len) |
END; |
IF p > 0 THEN |
INC(len) |
END; |
ELSE |
len := len + p + 2 |
END; |
FOR i := 1 TO width - len DO |
Char(" ") |
END; |
IF minus THEN |
Char("-") |
END; |
y := x; |
WHILE (y < 1.0) & (y # 0.0) DO |
y := y * 10.0; |
DEC(e) |
END; |
IF e < 0 THEN |
IF x - FLT(FLOOR(x)) > d THEN |
Char("1"); |
x := 0.0 |
ELSE |
Char("0"); |
x := x * 10.0 |
END |
ELSE |
WHILE e >= 0 DO |
IF x - FLT(FLOOR(x)) > d THEN |
IF x > 9.0 THEN |
String("10") |
ELSE |
Char(CHR(FLOOR(x) + ORD("0") + 1)) |
END; |
x := 0.0 |
ELSE |
Char(CHR(FLOOR(x) + ORD("0"))); |
x := (x - FLT(FLOOR(x))) * 10.0 |
END; |
DEC(e) |
END |
END; |
IF p > 0 THEN |
Char(".") |
END; |
WHILE p > 0 DO |
IF x - FLT(FLOOR(x)) > d THEN |
Char(CHR(FLOOR(x) + ORD("0") + 1)); |
x := 0.0 |
ELSE |
Char(CHR(FLOOR(x) + ORD("0"))); |
x := (x - FLT(FLOOR(x))) * 10.0 |
END; |
DEC(p) |
END |
END |
END _FixReal; |
PROCEDURE Real* (x: REAL; width: INTEGER); |
VAR e, n, i: INTEGER; minus: BOOLEAN; |
BEGIN |
printf3(SYSTEM.SADR("%*.*E"), width, MAX(MIN(width - 8, 15), 1), x) |
Realp := Real; |
IF IsNan(x) OR IsInf(x) THEN |
OutInf(x, width) |
ELSE |
e := 0; |
n := 0; |
IF width > 23 THEN |
n := width - 23; |
width := 23 |
ELSIF width < 9 THEN |
width := 9 |
END; |
width := width - 5; |
IF x < 0.0 THEN |
x := -x; |
minus := TRUE |
ELSE |
minus := FALSE |
END; |
WHILE x >= 10.0 DO |
x := x / 10.0; |
INC(e) |
END; |
WHILE (x < 1.0) & (x # 0.0) DO |
x := x * 10.0; |
DEC(e) |
END; |
IF x > 9.0 + d THEN |
x := 1.0; |
INC(e) |
END; |
FOR i := 1 TO n DO |
Char(" ") |
END; |
IF minus THEN |
x := -x |
END; |
_FixReal(x, width, width - 3); |
Char("E"); |
IF e >= 0 THEN |
Char("+") |
ELSE |
Char("-"); |
e := ABS(e) |
END; |
IF e < 100 THEN |
Char("0") |
END; |
IF e < 10 THEN |
Char("0") |
END; |
Int(e, 0) |
END |
END Real; |
PROCEDURE FixReal* (x: REAL; width, precision: INTEGER); |
PROCEDURE FixReal*(x: REAL; width, p: INTEGER); |
BEGIN |
printf3(SYSTEM.SADR("%*.*f"), width, precision, x) |
Realp := Real; |
_FixReal(x, width, p) |
END FixReal; |
PROCEDURE Open*; |
BEGIN |
hConsoleOutput := GetStdHandle(-11) |
hConsoleOutput := WINAPI.GetStdHandle(-11) |
END Open; |
END Out. |
/programs/develop/oberon07/Lib/Windows32/RTL.ob07 |
---|
372,29 → 372,33 |
PROCEDURE IntToStr (x: INTEGER; VAR str: ARRAY OF CHAR); |
VAR |
i, a: INTEGER; |
i, a, b: INTEGER; |
c: CHAR; |
BEGIN |
i := 0; |
a := x; |
REPEAT |
INC(i); |
a := a DIV 10 |
UNTIL a = 0; |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
str[i] := 0X; |
REPEAT |
DEC(i); |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10 |
UNTIL x = 0 |
a := 0; |
b := i - 1; |
WHILE a < b DO |
c := str[a]; |
str[a] := str[b]; |
str[b] := c; |
INC(a); |
DEC(b) |
END; |
str[i] := 0X |
END IntToStr; |
PROCEDURE append (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); |
VAR |
n1, n2: INTEGER; |
n1, n2, i, j: INTEGER; |
BEGIN |
n1 := LENGTH(s1); |
402,12 → 406,19 |
ASSERT(n1 + n2 < LEN(s1)); |
SYSTEM.MOVE(SYSTEM.ADR(s2[0]), SYSTEM.ADR(s1[n1]), n2); |
s1[n1 + n2] := 0X |
i := 0; |
j := n1; |
WHILE i < n2 DO |
s1[j] := s2[i]; |
INC(i); |
INC(j) |
END; |
s1[j] := 0X |
END append; |
PROCEDURE [stdcall] _error* (modnum, _module, err, line: INTEGER); |
PROCEDURE [stdcall] _error* (module, err, line: INTEGER); |
VAR |
s, temp: ARRAY 1024 OF CHAR; |
426,9 → 437,11 |
|11: s := "BYTE out of range" |
END; |
append(s, API.eol + "module: "); PCharToStr(_module, temp); append(s, temp); |
append(s, API.eol + "line: "); IntToStr(line, temp); append(s, temp); |
append(s, API.eol); |
append(s, "module: "); PCharToStr(module, temp); append(s, temp); append(s, API.eol); |
append(s, "line: "); IntToStr(line, temp); append(s, temp); |
API.DebugMsg(SYSTEM.ADR(s[0]), name); |
API.exit_thread(0) |
/programs/develop/oberon07/Lib/Windows32/UnixTime.ob07 |
---|
0,0 → 1,64 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
MODULE UnixTime; |
VAR |
days: ARRAY 12, 31, 2 OF INTEGER; |
PROCEDURE init; |
VAR |
i, j, k, n0, n1: INTEGER; |
BEGIN |
FOR i := 0 TO 11 DO |
FOR j := 0 TO 30 DO |
days[i, j, 0] := 0; |
days[i, j, 1] := 0; |
END |
END; |
days[ 1, 28, 0] := -1; |
FOR k := 0 TO 1 DO |
days[ 1, 29, k] := -1; |
days[ 1, 30, k] := -1; |
days[ 3, 30, k] := -1; |
days[ 5, 30, k] := -1; |
days[ 8, 30, k] := -1; |
days[10, 30, k] := -1; |
END; |
n0 := 0; |
n1 := 0; |
FOR i := 0 TO 11 DO |
FOR j := 0 TO 30 DO |
IF days[i, j, 0] = 0 THEN |
days[i, j, 0] := n0; |
INC(n0) |
END; |
IF days[i, j, 1] = 0 THEN |
days[i, j, 1] := n1; |
INC(n1) |
END |
END |
END |
END init; |
PROCEDURE time* (year, month, day, hour, min, sec: INTEGER): INTEGER; |
RETURN ((year - 1970) * 365 + days[month - 1, day - 1, ORD(year DIV 4 = 0)] + (year - 1969) DIV 4) * 86400 + hour * 3600 + min * 60 + sec |
END time; |
BEGIN |
init |
END UnixTime. |
/programs/develop/oberon07/Lib/Windows32/Utils.ob07 |
---|
0,0 → 1,76 |
(* |
Copyright 2013, 2017, 2018, 2020 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 <http://www.gnu.org/licenses/>. |
*) |
MODULE Utils; |
IMPORT WINAPI; |
PROCEDURE PutSeed*(seed: INTEGER); |
BEGIN |
WINAPI.srand(seed) |
END PutSeed; |
PROCEDURE Rnd*(range : INTEGER): INTEGER; |
RETURN WINAPI.rand() MOD range |
END Rnd; |
PROCEDURE Utf8To16*(source: ARRAY OF CHAR; VAR dest: ARRAY OF CHAR): INTEGER; |
VAR i, j, L, u, N: INTEGER; |
BEGIN |
L := LEN(source); |
N := LEN(dest); |
N := N - N MOD 2 - 1; |
i := 0; |
j := 0; |
WHILE (i < L) & (j < N) & (source[i] # 0X) DO |
CASE source[i] OF |
|00X..7FX: u := ORD(source[i]); |
|0C1X..0DFX: |
u := LSL(ORD(source[i]) - 0C0H, 6); |
IF i + 1 < L THEN |
u := u + ROR(LSL(ORD(source[i + 1]), 26), 26); |
INC(i) |
END |
|0E1X..0EFX: |
u := LSL(ORD(source[i]) - 0E0H, 12); |
IF i + 1 < L THEN |
u := u + ROR(LSL(ORD(source[i + 1]), 26), 20); |
INC(i) |
END; |
IF i + 1 < L THEN |
u := u + ROR(LSL(ORD(source[i + 1]), 26), 26); |
INC(i) |
END |
(* |0F1X..0F7X: |
|0F9X..0FBX: |
|0FDX:*) |
ELSE |
END; |
INC(i); |
dest[j] := CHR(u MOD 256); |
INC(j); |
dest[j] := CHR(u DIV 256); |
INC(j); |
END; |
IF j < N THEN |
dest[j] := 0X; |
dest[j + 1] := 0X |
END |
RETURN j DIV 2 |
END Utf8To16; |
END Utils. |
/programs/develop/oberon07/Lib/Windows32/WINAPI.ob07 |
---|
14,11 → 14,7 |
OFS_MAXPATHNAME* = 128; |
KERNEL = "kernel32.dll"; |
USER = "user32.dll"; |
MSVCRT = "msvcrt.dll"; |
TYPE |
DLL_ENTRY* = API.DLL_ENTRY; |
60,27 → 56,13 |
END; |
tm* = RECORD |
sec*, |
min*, |
hour*, |
mday*, |
mon*, |
year*, |
wday*, |
yday*, |
isdst*: SYSTEM.CARD32 |
END; |
PSecurityAttributes* = POINTER TO TSecurityAttributes; |
TSecurityAttributes* = RECORD |
nLength*: SYSTEM.CARD32; |
nLength*: INTEGER; |
lpSecurityDescriptor*: INTEGER; |
bInheritHandle*: SYSTEM.CARD32 (* BOOL *) |
bInheritHandle*: INTEGER |
END; |
87,32 → 69,29 |
TFileTime* = RECORD |
dwLowDateTime*, |
dwHighDateTime*: SYSTEM.CARD32 |
dwHighDateTime*: INTEGER |
END; |
TWin32FindData* = RECORD |
dwFileAttributes*: SYSTEM.CARD32; |
dwFileAttributes*: SET; |
ftCreationTime*: TFileTime; |
ftLastAccessTime*: TFileTime; |
ftLastWriteTime*: TFileTime; |
nFileSizeHigh*: SYSTEM.CARD32; |
nFileSizeLow*: SYSTEM.CARD32; |
dwReserved0*: SYSTEM.CARD32; |
dwReserved1*: SYSTEM.CARD32; |
nFileSizeHigh*: INTEGER; |
nFileSizeLow*: INTEGER; |
dwReserved0*: INTEGER; |
dwReserved1*: INTEGER; |
cFileName*: STRING; |
cAlternateFileName*: ARRAY 14 OF CHAR; |
dwFileType*: SYSTEM.CARD32; |
dwCreatorType*: SYSTEM.CARD32; |
wFinderFlags*: WCHAR |
cAlternateFileName*: ARRAY 14 OF CHAR |
END; |
OFSTRUCT* = RECORD |
cBytes*: BYTE; |
fFixedDisk*: BYTE; |
cBytes*: CHAR; |
fFixedDisk*: CHAR; |
nErrCode*: WCHAR; |
Reserved1*: WCHAR; |
Reserved2*: WCHAR; |
126,95 → 105,133 |
Internal*: INTEGER; |
InternalHigh*: INTEGER; |
Offset*: SYSTEM.CARD32; |
OffsetHigh*: SYSTEM.CARD32; |
Offset*: INTEGER; |
OffsetHigh*: INTEGER; |
hEvent*: INTEGER |
END; |
PROCEDURE [windows-, KERNEL, ""] SetConsoleCursorPosition* (hConsoleOutput, dwCursorPosition: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "SetConsoleCursorPosition"] |
SetConsoleCursorPosition* (hConsoleOutput, dwCursorPosition: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetConsoleScreenBufferInfo* (hConsoleOutput: INTEGER; ConsoleScreenBufferInfo: TConsoleScreenBufferInfo): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetConsoleScreenBufferInfo"] |
GetConsoleScreenBufferInfo* (hConsoleOutput: INTEGER; ConsoleScreenBufferInfo: TConsoleScreenBufferInfo): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] FillConsoleOutputCharacterA* (hConsoleOutput, cCaracter, nLength, dwWriteCoord, lpNumberOfCharsWritten: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "FillConsoleOutputCharacterA"] |
FillConsoleOutputCharacter* (hConsoleOutput, cCaracter, nLength, dwWriteCoord, lpNumberOfCharsWritten: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] FillConsoleOutputAttribute* (hConsoleOutput, wAttribute, nLength, dwWriteCoord, lpNumberOfAttrsWritten: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "FillConsoleOutputAttribute"] |
FillConsoleOutputAttribute* (hConsoleOutput, wAttribute, nLength, dwWriteCoord, lpNumberOfAttrsWritten: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] SetConsoleTextAttribute* (hConsoleOutput, wAttributes: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "SetConsoleTextAttribute"] |
SetConsoleTextAttribute* (hConsoleOutput, wAttributes: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetStdHandle* (nStdHandle: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetStdHandle"] |
GetStdHandle* (nStdHandle: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetLocalTime* (T: TSystemTime); |
PROCEDURE [windows-, "kernel32.dll", "GetLocalTime"] |
GetLocalTime* (T: TSystemTime); |
PROCEDURE [windows-, KERNEL, ""] RemoveDirectoryA* (lpPathName: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "RemoveDirectoryA"] |
RemoveDirectory* (lpPathName: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetFileAttributesA* (lpPathName: INTEGER): SET; |
PROCEDURE [windows-, "kernel32.dll", "GetFileAttributesA"] |
GetFileAttributes* (lpPathName: INTEGER): SET; |
PROCEDURE [windows-, KERNEL, ""] CreateDirectoryA* (lpPathName: INTEGER; lpSecurityAttributes: PSecurityAttributes): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "CreateDirectoryA"] |
CreateDirectory* (lpPathName: INTEGER; lpSecurityAttributes: PSecurityAttributes): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] FindFirstFileA* (lpFileName: INTEGER; lpFindFileData: TWin32FindData): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "FindFirstFileA"] |
FindFirstFile* (lpFileName: INTEGER; lpFindFileData: TWin32FindData): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] DeleteFileA* (lpFileName: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "DeleteFileA"] |
DeleteFile* (lpFileName: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] FindClose* (hFindFile: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "FindClose"] |
FindClose* (hFindFile: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] CloseHandle* (hObject: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "CloseHandle"] |
CloseHandle* (hObject: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] CreateFileA* ( |
PROCEDURE [windows-, "kernel32.dll", "CreateFileA"] |
CreateFile* ( |
lpFileName, dwDesiredAccess, dwShareMode: INTEGER; |
lpSecurityAttributes: PSecurityAttributes; |
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] OpenFile* (lpFileName: INTEGER; lpReOpenBuff: OFSTRUCT; uStyle: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "OpenFile"] |
OpenFile* (lpFileName: INTEGER; lpReOpenBuff: OFSTRUCT; uStyle: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] SetFilePointer* (hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "SetFilePointer"] |
SetFilePointer* (hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] ReadFile* (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "ReadFile"] |
ReadFile* (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] WriteFile* (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "WriteFile"] |
WriteFile* (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] ReadConsoleA* (hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, lpReserved: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "ReadConsoleA"] |
ReadConsole* (hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, lpReserved: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetCommandLineA* (): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetCommandLineA"] |
GetCommandLine* (): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GlobalAlloc* (uFlags, dwBytes: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GlobalAlloc"] |
GlobalAlloc* (uFlags, dwBytes: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GlobalFree* (hMem: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GlobalFree"] |
GlobalFree* (hMem: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] WriteConsoleW* (hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "WriteConsoleW"] |
WriteConsoleW* (hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] ExitProcess* (code: INTEGER); |
PROCEDURE [windows-, "kernel32.dll", "ExitProcess"] |
ExitProcess* (code: INTEGER); |
PROCEDURE [windows-, KERNEL, ""] WriteConsoleA* (hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "WriteConsoleA"] |
WriteConsole* (hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetTickCount* (): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetTickCount"] |
GetTickCount* (): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] Sleep* (dwMilliseconds: INTEGER); |
PROCEDURE [windows-, "kernel32.dll", "Sleep"] |
Sleep* (dwMilliseconds: INTEGER); |
PROCEDURE [windows-, KERNEL, ""] FreeLibrary* (hLibModule: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "FreeLibrary"] |
FreeLibrary* (hLibModule: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetProcAddress* (hModule, name: INTEGER): INTEGER; |
PROCEDURE [ccall, "msvcrt.dll", "rand"] |
rand* (): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] LoadLibraryA* (name: INTEGER): INTEGER; |
PROCEDURE [ccall, "msvcrt.dll", "srand"] |
srand* (seed: INTEGER); |
PROCEDURE [windows-, KERNEL, ""] AllocConsole* (): BOOLEAN; |
PROCEDURE [windows-, "user32.dll", "MessageBoxA"] |
MessageBoxA* (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] FreeConsole* (): BOOLEAN; |
PROCEDURE [windows-, "user32.dll", "MessageBoxW"] |
MessageBox* (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE [windows-, USER, ""] MessageBoxA* (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE [windows-, USER, ""] MessageBoxW* (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE [windows-, USER, ""] CreateWindowExA* ( |
PROCEDURE [windows-, "user32.dll", "CreateWindowExA"] |
CreateWindowEx* ( |
dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, |
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam: INTEGER): INTEGER; |
PROCEDURE [ccall-, MSVCRT, ""] time* (ptr: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetProcAddress"] |
GetProcAddress* (hModule, name: INTEGER): INTEGER; |
PROCEDURE [ccall-, MSVCRT, ""] mktime* (time: tm): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "LoadLibraryA"] |
LoadLibraryA* (name: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "AllocConsole"] |
AllocConsole* (): BOOLEAN; |
PROCEDURE [windows-, "kernel32.dll", "FreeConsole"] |
FreeConsole* (): BOOLEAN; |
PROCEDURE SetDllEntry* (process_detach, thread_detach, thread_attach: DLL_ENTRY); |
BEGIN |
API.SetDll(process_detach, thread_detach, thread_attach) |
/programs/develop/oberon07/Lib/Windows64/File.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Windows64/Args.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Lib/Windows64/API.ob07 |
---|
12,8 → 12,6 |
CONST |
eol* = 0DX + 0AX; |
SectionAlignment = 1000H; |
DLL_PROCESS_ATTACH = 1; |
21,10 → 19,7 |
DLL_THREAD_DETACH = 3; |
DLL_PROCESS_DETACH = 0; |
KERNEL = "kernel32.dll"; |
USER = "user32.dll"; |
TYPE |
DLL_ENTRY* = PROCEDURE (hinstDLL, fdwReason, lpvReserved: INTEGER); |
32,6 → 27,7 |
VAR |
eol*: ARRAY 3 OF CHAR; |
base*: INTEGER; |
heap: INTEGER; |
40,14 → 36,15 |
thread_attach: DLL_ENTRY; |
PROCEDURE [windows-, KERNEL, ""] ExitProcess (code: INTEGER); |
PROCEDURE [windows-, KERNEL, ""] ExitThread (code: INTEGER); |
PROCEDURE [windows-, KERNEL, ""] GetProcessHeap (): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] HeapAlloc (hHeap, dwFlags, dwBytes: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] HeapFree (hHeap, dwFlags, lpMem: INTEGER); |
PROCEDURE [windows-, USER, ""] MessageBoxA (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "ExitProcess"] ExitProcess (code: INTEGER); |
PROCEDURE [windows-, "kernel32.dll", "ExitThread"] ExitThread (code: INTEGER); |
PROCEDURE [windows-, "kernel32.dll", "GetProcessHeap"] GetProcessHeap (): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "HeapAlloc"] HeapAlloc (hHeap, dwFlags, dwBytes: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "HeapFree"] HeapFree(hHeap, dwFlags, lpMem: INTEGER); |
PROCEDURE [windows-, "user32.dll", "MessageBoxA"] MessageBoxA (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE DebugMsg* (lpText, lpCaption: INTEGER); |
BEGIN |
MessageBoxA(0, lpText, lpCaption, 16) |
71,6 → 68,7 |
process_detach := NIL; |
thread_detach := NIL; |
thread_attach := NIL; |
eol[0] := 0DX; eol[1] := 0AX; eol[2] := 0X; |
base := code - SectionAlignment; |
heap := GetProcessHeap() |
END init; |
/programs/develop/oberon07/Lib/Windows64/Console.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2019-2020, Anton Krotov |
Copyright (c) 2019, Anton Krotov |
All rights reserved. |
*) |
48,7 → 48,7 |
BEGIN |
WINAPI.GetConsoleScreenBufferInfo(hConsoleOutput, ScrBufInfo); |
fill := ORD(ScrBufInfo.dwSize.X) * ORD(ScrBufInfo.dwSize.Y); |
WINAPI.FillConsoleOutputCharacterA(hConsoleOutput, 20H, fill, 0, SYSTEM.ADR(fill)); |
WINAPI.FillConsoleOutputCharacter(hConsoleOutput, 20H, fill, 0, SYSTEM.ADR(fill)); |
WINAPI.FillConsoleOutputAttribute(hConsoleOutput, ORD(ScrBufInfo.wAttributes), fill, 0, SYSTEM.ADR(fill)); |
SetCursor(0, 0) |
END Cls; |
/programs/develop/oberon07/Lib/Windows64/DateTime.ob07 |
---|
1,13 → 1,13 |
(* |
BSD 2-Clause License |
Copyright (c) 2019-2020, Anton Krotov |
Copyright (c) 2019, Anton Krotov |
All rights reserved. |
*) |
MODULE DateTime; |
IMPORT WINAPI, SYSTEM; |
IMPORT WINAPI; |
CONST |
116,29 → 116,6 |
END NowEncode; |
PROCEDURE NowUnixTime* (): INTEGER; |
RETURN WINAPI.time(0) |
END NowUnixTime; |
PROCEDURE UnixTime* (Year, Month, Day, Hour, Min, Sec: INTEGER): INTEGER; |
VAR |
t: WINAPI.tm; |
BEGIN |
DEC(Year, 1900); |
DEC(Month); |
SYSTEM.GET(SYSTEM.ADR(Sec), t.sec); |
SYSTEM.GET(SYSTEM.ADR(Min), t.min); |
SYSTEM.GET(SYSTEM.ADR(Hour), t.hour); |
SYSTEM.GET(SYSTEM.ADR(Day), t.mday); |
SYSTEM.GET(SYSTEM.ADR(Month), t.mon); |
SYSTEM.GET(SYSTEM.ADR(Year), t.year); |
RETURN WINAPI.mktime(t) |
END UnixTime; |
PROCEDURE init; |
VAR |
day, year, month, i: INTEGER; |
/programs/develop/oberon07/Lib/Windows64/HOST.ob07 |
---|
13,7 → 13,7 |
CONST |
slash* = "\"; |
eol* = 0DX + 0AX; |
OS* = "WINDOWS"; |
bit_depth* = RTL.bit_depth; |
maxint* = RTL.maxint; |
59,7 → 59,20 |
END; |
TSystemTime = RECORD |
Year, |
Month, |
DayOfWeek, |
Day, |
Hour, |
Min, |
Sec, |
MSec: WCHAR |
END; |
VAR |
hConsoleOutput: INTEGER; |
67,6 → 80,8 |
Params: ARRAY MAX_PARAM, 2 OF INTEGER; |
argc: INTEGER; |
eol*: ARRAY 3 OF CHAR; |
maxreal*: REAL; |
101,13 → 116,13 |
PROCEDURE [windows-, "kernel32.dll", "GetCurrentDirectoryA"] |
_GetCurrentDirectory (nBufferLength, lpBuffer: INTEGER): INTEGER; |
PROCEDURE [windows, "kernel32.dll", "ExitProcess"] |
PROCEDURE [windows-, "kernel32.dll", "GetSystemTime"] |
_GetSystemTime (T: TSystemTime); |
PROCEDURE [windows-, "kernel32.dll", "ExitProcess"] |
_ExitProcess (code: INTEGER); |
PROCEDURE [windows, "msvcrt.dll", "time"] |
_time (ptr: INTEGER): INTEGER; |
PROCEDURE ExitProcess* (code: INTEGER); |
BEGIN |
_ExitProcess(code) |
200,11 → 215,13 |
PROCEDURE FileRead* (F: INTEGER; VAR Buffer: ARRAY OF CHAR; bytes: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
res, n: INTEGER; |
BEGIN |
IF _ReadFile(F, SYSTEM.ADR(Buffer[0]), bytes, res, NIL) = 0 THEN |
IF _ReadFile(F, SYSTEM.ADR(Buffer[0]), bytes, n, NIL) = 0 THEN |
res := -1 |
ELSE |
res := n |
END |
RETURN res |
213,11 → 230,13 |
PROCEDURE FileWrite* (F: INTEGER; Buffer: ARRAY OF BYTE; bytes: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
res, n: INTEGER; |
BEGIN |
IF _WriteFile(F, SYSTEM.ADR(Buffer[0]), bytes, res, NIL) = 0 THEN |
IF _WriteFile(F, SYSTEM.ADR(Buffer[0]), bytes, n, NIL) = 0 THEN |
res := -1 |
ELSE |
res := n |
END |
RETURN res |
250,10 → 269,6 |
END FileOpen; |
PROCEDURE chmod* (FName: ARRAY OF CHAR); |
END chmod; |
PROCEDURE OutChar* (c: CHAR); |
VAR |
count: INTEGER; |
277,31 → 292,33 |
END isRelative; |
PROCEDURE UnixTime* (): INTEGER; |
RETURN _time(0) |
END UnixTime; |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
PROCEDURE now* (VAR year, month, day, hour, min, sec: INTEGER); |
VAR |
res: INTEGER; |
T: TSystemTime; |
BEGIN |
a := 0; |
b := 0; |
SYSTEM.GET32(SYSTEM.ADR(x), a); |
SYSTEM.GET32(SYSTEM.ADR(x) + 4, b); |
SYSTEM.GET(SYSTEM.ADR(x), res) |
RETURN res |
END splitf; |
_GetSystemTime(T); |
year := ORD(T.Year); |
month := ORD(T.Month); |
day := ORD(T.Day); |
hour := ORD(T.Hour); |
min := ORD(T.Min); |
sec := ORD(T.Sec) |
END now; |
PROCEDURE UnixTime* (): INTEGER; |
RETURN 0 |
END UnixTime; |
PROCEDURE d2s* (x: REAL): INTEGER; |
VAR |
h, l, s, e: INTEGER; |
BEGIN |
e := splitf(x, l, h); |
SYSTEM.GET(SYSTEM.ADR(x), l); |
SYSTEM.GET(SYSTEM.ADR(x) + 4, h); |
s := ASR(h, 31) MOD 2; |
e := (h DIV 100000H) MOD 2048; |
331,7 → 348,22 |
END d2s; |
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
BEGIN |
a := 0; |
b := 0; |
SYSTEM.MOVE(SYSTEM.ADR(x), SYSTEM.ADR(a), 4); |
SYSTEM.MOVE(SYSTEM.ADR(x) + 4, SYSTEM.ADR(b), 4); |
SYSTEM.GET(SYSTEM.ADR(x), res) |
RETURN res |
END splitf; |
BEGIN |
eol[0] := 0DX; eol[1] := 0AX; eol[2] := 0X; |
maxreal := 1.9; |
PACK(maxreal, 1023); |
hConsoleOutput := _GetStdHandle(-11); |
/programs/develop/oberon07/Lib/Windows64/In.ob07 |
---|
1,75 → 1,291 |
(* |
BSD 2-Clause License |
Copyright 2013, 2017, 2018, 2019 Anton Krotov |
Copyright (c) 2020, Anton Krotov |
All rights reserved. |
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 <http://www.gnu.org/licenses/>. |
*) |
MODULE In; |
IMPORT SYSTEM; |
IMPORT sys := SYSTEM; |
TYPE |
CONST |
STRING = ARRAY 260 OF CHAR; |
MAX_LEN = 1024; |
VAR |
Done*: BOOLEAN; |
hConsoleInput: INTEGER; |
s: ARRAY MAX_LEN + 4 OF CHAR; |
PROCEDURE [windows-, "kernel32.dll", "GetStdHandle"] |
GetStdHandle (nStdHandle: INTEGER): INTEGER; |
PROCEDURE [windows, "msvcrt.dll", ""] sscanf (buf: INTEGER; fmt: INTEGER; adr: INTEGER): INTEGER; |
PROCEDURE [windows, "kernel32.dll", ""] GetStdHandle (nStdHandle: INTEGER): INTEGER; |
PROCEDURE [windows, "kernel32.dll", ""] ReadConsoleA (hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, lpReserved: INTEGER); |
PROCEDURE [windows-, "kernel32.dll", "ReadConsoleA"] |
ReadConsole (hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, lpReserved: INTEGER): INTEGER; |
PROCEDURE digit(ch: CHAR): BOOLEAN; |
RETURN (ch >= "0") & (ch <= "9") |
END digit; |
PROCEDURE String* (VAR str: ARRAY OF CHAR); |
VAR |
count: INTEGER; |
PROCEDURE CheckInt(s: STRING; VAR first, last: INTEGER; VAR neg: BOOLEAN; Point: BOOLEAN): BOOLEAN; |
VAR i: INTEGER; |
BEGIN |
i := 0; |
neg := FALSE; |
WHILE (s[i] <= 20X) & (s[i] # 0X) DO |
INC(i) |
END; |
IF s[i] = "-" THEN |
neg := TRUE; |
INC(i) |
ELSIF s[i] = "+" THEN |
INC(i) |
END; |
first := i; |
WHILE digit(s[i]) DO |
INC(i) |
END; |
last := i |
RETURN ((s[i] <= 20X) OR (Point & (s[i] = "."))) & digit(s[first]) |
END CheckInt; |
PROCEDURE IsMinInt(str: STRING; pos: INTEGER): BOOLEAN; |
VAR i: INTEGER; min: STRING; |
BEGIN |
ReadConsoleA(hConsoleInput, SYSTEM.ADR(s[0]), MAX_LEN, SYSTEM.ADR(count), 0); |
IF (s[count - 1] = 0AX) & (s[count - 2] = 0DX) THEN |
DEC(count, 2) |
i := 0; |
min := "2147483648"; |
WHILE (min[i] # 0X) & (str[i] # 0X) & (min[i] = str[i + pos]) DO |
INC(i) |
END |
RETURN i = 10 |
END IsMinInt; |
PROCEDURE StrToInt(str: STRING; VAR err: BOOLEAN): INTEGER; |
CONST maxINT = 7FFFFFFFH; |
VAR i, n, res: INTEGER; flag, neg: BOOLEAN; |
BEGIN |
res := 0; |
flag := CheckInt(str, i, n, neg, FALSE); |
err := ~flag; |
IF flag & neg & IsMinInt(str, i) THEN |
flag := FALSE; |
neg := FALSE; |
res := 80000000H |
END; |
s[count] := 0X; |
COPY(s, str); |
str[LEN(str) - 1] := 0X; |
Done := TRUE |
END String; |
WHILE flag & digit(str[i]) DO |
IF res > maxINT DIV 10 THEN |
err := TRUE; |
flag := FALSE; |
res := 0 |
ELSE |
res := res * 10; |
IF res > maxINT - (ORD(str[i]) - ORD("0")) THEN |
err := TRUE; |
flag := FALSE; |
res := 0 |
ELSE |
res := res + (ORD(str[i]) - ORD("0")); |
INC(i) |
END |
END |
END; |
IF neg THEN |
res := -res |
END |
RETURN res |
END StrToInt; |
PROCEDURE Space(s: STRING): BOOLEAN; |
VAR i: INTEGER; |
BEGIN |
i := 0; |
WHILE (s[i] # 0X) & (s[i] <= 20X) DO |
INC(i) |
END |
RETURN s[i] = 0X |
END Space; |
PROCEDURE Int* (VAR x: INTEGER); |
PROCEDURE CheckReal(s: STRING; VAR n: INTEGER; VAR neg: BOOLEAN): BOOLEAN; |
VAR i: INTEGER; Res: BOOLEAN; |
BEGIN |
String(s); |
Done := sscanf(SYSTEM.ADR(s[0]), SYSTEM.SADR("%lld"), SYSTEM.ADR(x)) = 1 |
END Int; |
Res := CheckInt(s, n, i, neg, TRUE); |
IF Res THEN |
IF s[i] = "." THEN |
INC(i); |
WHILE digit(s[i]) DO |
INC(i) |
END; |
IF (s[i] = "D") OR (s[i] = "E") OR (s[i] = "d") OR (s[i] = "e") THEN |
INC(i); |
IF (s[i] = "+") OR (s[i] = "-") THEN |
INC(i) |
END; |
Res := digit(s[i]); |
WHILE digit(s[i]) DO |
INC(i) |
END |
END |
END |
END |
RETURN Res & (s[i] <= 20X) |
END CheckReal; |
PROCEDURE StrToFloat(str: STRING; VAR err: BOOLEAN): REAL; |
CONST maxDBL = 1.69E308; maxINT = 7FFFFFFFH; |
VAR i, scale: INTEGER; res, m, d: REAL; minus, neg: BOOLEAN; |
PROCEDURE Real* (VAR x: REAL); |
PROCEDURE part1(VAR res, d: REAL; VAR i: INTEGER; str: STRING): BOOLEAN; |
BEGIN |
String(s); |
Done := sscanf(SYSTEM.ADR(s[0]), SYSTEM.SADR("%lf"), SYSTEM.ADR(x)) = 1 |
END Real; |
res := 0.0; |
d := 1.0; |
WHILE digit(str[i]) DO |
res := res * 10.0 + FLT(ORD(str[i]) - ORD("0")); |
INC(i) |
END; |
IF str[i] = "." THEN |
INC(i); |
WHILE digit(str[i]) DO |
d := d / 10.0; |
res := res + FLT(ORD(str[i]) - ORD("0")) * d; |
INC(i) |
END |
END |
RETURN str[i] # 0X |
END part1; |
PROCEDURE part2(VAR i, scale: INTEGER; VAR m, res: REAL; VAR minus, err: BOOLEAN; str: STRING): BOOLEAN; |
BEGIN |
INC(i); |
m := 10.0; |
minus := FALSE; |
IF str[i] = "+" THEN |
INC(i) |
ELSIF str[i] = "-" THEN |
minus := TRUE; |
INC(i); |
m := 0.1 |
END; |
scale := 0; |
err := FALSE; |
WHILE ~err & digit(str[i]) DO |
IF scale > maxINT DIV 10 THEN |
err := TRUE; |
res := 0.0 |
ELSE |
scale := scale * 10; |
IF scale > maxINT - (ORD(str[i]) - ORD("0")) THEN |
err := TRUE; |
res := 0.0 |
ELSE |
scale := scale + (ORD(str[i]) - ORD("0")); |
INC(i) |
END |
END |
END |
RETURN ~err |
END part2; |
PROCEDURE part3 (VAR err, minus: BOOLEAN; VAR scale: INTEGER; VAR res, m: REAL); |
VAR i: INTEGER; |
BEGIN |
err := FALSE; |
IF scale = maxINT THEN |
err := TRUE; |
res := 0.0 |
END; |
i := 1; |
WHILE ~err & (i <= scale) DO |
IF ~minus & (res > maxDBL / m) THEN |
err := TRUE; |
res := 0.0 |
ELSE |
res := res * m; |
INC(i) |
END |
END |
END part3; |
BEGIN |
IF CheckReal(str, i, neg) THEN |
IF part1(res, d, i, str) & part2(i, scale, m, res, minus, err, str) THEN |
part3(err, minus, scale, res, m) |
END; |
IF neg THEN |
res := -res |
END |
ELSE |
res := 0.0; |
err := TRUE |
END |
RETURN res |
END StrToFloat; |
PROCEDURE String*(VAR s: ARRAY OF CHAR); |
VAR count, i: INTEGER; str: STRING; |
BEGIN |
ReadConsole(hConsoleInput, sys.ADR(str[0]), 256, sys.ADR(count), 0); |
IF (str[count - 1] = 0AX) & (str[count - 2] = 0DX) THEN |
DEC(count, 2) |
END; |
str[256] := 0X; |
str[count] := 0X; |
i := 0; |
WHILE (i < LEN(s) - 1) & (i < LEN(str)) & (str[i] # 0X) DO |
s[i] := str[i]; |
INC(i) |
END; |
s[i] := 0X; |
Done := TRUE |
END String; |
PROCEDURE Char* (VAR x: CHAR); |
VAR str: STRING; |
BEGIN |
String(s); |
x := s[0] |
String(str); |
x := str[0]; |
Done := TRUE |
END Char; |
PROCEDURE Ln*; |
VAR str: STRING; |
BEGIN |
String(s) |
String(str); |
Done := TRUE |
END Ln; |
PROCEDURE Real*(VAR x: REAL); |
VAR str: STRING; err: BOOLEAN; |
BEGIN |
err := FALSE; |
REPEAT |
String(str) |
UNTIL ~Space(str); |
x := StrToFloat(str, err); |
Done := ~err |
END Real; |
PROCEDURE Int*(VAR x: INTEGER); |
VAR str: STRING; err: BOOLEAN; |
BEGIN |
err := FALSE; |
REPEAT |
String(str) |
UNTIL ~Space(str); |
x := StrToInt(str, err); |
Done := ~err |
END Int; |
PROCEDURE Open*; |
BEGIN |
hConsoleInput := GetStdHandle(-10); |
76,5 → 292,4 |
Done := TRUE |
END Open; |
END In. |
/programs/develop/oberon07/Lib/Windows64/Math.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2019-2020, Anton Krotov |
Copyright (c) 2019, Anton Krotov |
All rights reserved. |
*) |
12,32 → 12,22 |
CONST |
pi* = 3.1415926535897932384626433832795028841972E0; |
e* = 2.7182818284590452353602874713526624977572E0; |
e *= 2.71828182845904523; |
pi *= 3.14159265358979324; |
ln2 *= 0.693147180559945309; |
ZERO = 0.0E0; |
ONE = 1.0E0; |
HALF = 0.5E0; |
TWO = 2.0E0; |
sqrtHalf = 0.70710678118654752440E0; |
eps = 5.5511151E-17; |
ln2Inv = 1.44269504088896340735992468100189213E0; |
piInv = ONE / pi; |
Limit = 1.0536712E-8; |
piByTwo = pi / TWO; |
eps = 1.0E-16; |
MaxCosArg = 1000000.0 * pi; |
expoMax = 1023; |
expoMin = 1 - expoMax; |
VAR |
LnInfinity, LnSmall, large, miny: REAL; |
Exp: ARRAY 710 OF REAL; |
PROCEDURE [stdcall64] sqrt* (x: REAL): REAL; |
BEGIN |
ASSERT(x >= ZERO); |
ASSERT(x >= 0.0); |
SYSTEM.CODE( |
0F2H, 0FH, 51H, 45H, 10H, (* sqrtsd xmm0, qword[rbp + 10h] *) |
05DH, (* pop rbp *) |
48,314 → 38,179 |
END sqrt; |
PROCEDURE sqri* (x: INTEGER): INTEGER; |
RETURN x * x |
END sqri; |
PROCEDURE sqrr* (x: REAL): REAL; |
RETURN x * x |
END sqrr; |
PROCEDURE exp* (x: REAL): REAL; |
CONST |
c1 = 0.693359375E0; |
c2 = -2.1219444005469058277E-4; |
P0 = 0.249999999999999993E+0; |
P1 = 0.694360001511792852E-2; |
P2 = 0.165203300268279130E-4; |
Q1 = 0.555538666969001188E-1; |
Q2 = 0.495862884905441294E-3; |
e25 = 1.284025416687741484; (* exp(0.25) *) |
VAR |
xn, g, p, q, z: REAL; |
a, s, res: REAL; |
neg: BOOLEAN; |
n: INTEGER; |
BEGIN |
IF x > LnInfinity THEN |
x := SYSTEM.INF() |
ELSIF x < LnSmall THEN |
x := ZERO |
ELSIF ABS(x) < eps THEN |
x := ONE |
neg := x < 0.0; |
IF neg THEN |
x := -x |
END; |
IF x < FLT(LEN(Exp)) THEN |
res := Exp[FLOOR(x)]; |
x := x - FLT(FLOOR(x)); |
WHILE x >= 0.25 DO |
res := res * e25; |
x := x - 0.25 |
END |
ELSE |
IF x >= ZERO THEN |
n := FLOOR(ln2Inv * x + HALF) |
ELSE |
n := FLOOR(ln2Inv * x - HALF) |
res := SYSTEM.INF(); |
x := 0.0 |
END; |
xn := FLT(n); |
g := (x - xn * c1) - xn * c2; |
z := g * g; |
p := ((P2 * z + P1) * z + P0) * g; |
q := (Q2 * z + Q1) * z + HALF; |
x := HALF + p / (q - p); |
PACK(x, n + 1) |
n := 0; |
a := 1.0; |
s := 1.0; |
REPEAT |
INC(n); |
a := a * x / FLT(n); |
s := s + a |
UNTIL a < eps; |
IF neg THEN |
res := 1.0 / (res * s) |
ELSE |
res := res * s |
END |
RETURN x |
RETURN res |
END exp; |
PROCEDURE ln* (x: REAL): REAL; |
CONST |
c1 = 355.0E0 / 512.0E0; |
c2 = -2.121944400546905827679E-4; |
P0 = -0.64124943423745581147E+2; |
P1 = 0.16383943563021534222E+2; |
P2 = -0.78956112887491257267E+0; |
Q0 = -0.76949932108494879777E+3; |
Q1 = 0.31203222091924532844E+3; |
Q2 = -0.35667977739034646171E+2; |
VAR |
zn, zd, r, z, w, p, q, xn: REAL; |
a, x2, res: REAL; |
n: INTEGER; |
BEGIN |
ASSERT(x > ZERO); |
ASSERT(x > 0.0); |
UNPK(x, n); |
x := x * HALF; |
IF x > sqrtHalf THEN |
zn := x - ONE; |
zd := x * HALF + HALF; |
INC(n) |
ELSE |
zn := x - HALF; |
zd := zn * HALF + HALF |
END; |
x := (x - 1.0) / (x + 1.0); |
x2 := x * x; |
res := x + FLT(n) * (ln2 * 0.5); |
n := 1; |
z := zn / zd; |
w := z * z; |
q := ((w + Q2) * w + Q1) * w + Q0; |
p := w * ((P2 * w + P1) * w + P0); |
r := z + z * (p / q); |
xn := FLT(n) |
REPEAT |
INC(n, 2); |
x := x * x2; |
a := x / FLT(n); |
res := res + a |
UNTIL a < eps |
RETURN (xn * c2 + r) + xn * c1 |
RETURN res * 2.0 |
END ln; |
PROCEDURE power* (base, exponent: REAL): REAL; |
BEGIN |
ASSERT(base > ZERO) |
ASSERT(base > 0.0) |
RETURN exp(exponent * ln(base)) |
END power; |
PROCEDURE ipower* (base: REAL; exponent: INTEGER): REAL; |
VAR |
i: INTEGER; |
a: REAL; |
BEGIN |
a := 1.0; |
IF base # 0.0 THEN |
IF exponent # 0 THEN |
IF exponent < 0 THEN |
base := 1.0 / base |
END; |
i := ABS(exponent); |
WHILE i > 0 DO |
WHILE ~ODD(i) DO |
i := LSR(i, 1); |
base := sqrr(base) |
END; |
DEC(i); |
a := a * base |
END |
ELSE |
a := 1.0 |
END |
ELSE |
ASSERT(exponent > 0); |
a := 0.0 |
END |
RETURN a |
END ipower; |
PROCEDURE log* (base, x: REAL): REAL; |
BEGIN |
ASSERT(base > ZERO); |
ASSERT(x > ZERO) |
ASSERT(base > 0.0); |
ASSERT(x > 0.0) |
RETURN ln(x) / ln(base) |
END log; |
PROCEDURE SinCos (x, y, sign: REAL): REAL; |
CONST |
ymax = 210828714; |
c1 = 3.1416015625E0; |
c2 = -8.908910206761537356617E-6; |
r1 = -0.16666666666666665052E+0; |
r2 = 0.83333333333331650314E-2; |
r3 = -0.19841269841201840457E-3; |
r4 = 0.27557319210152756119E-5; |
r5 = -0.25052106798274584544E-7; |
r6 = 0.16058936490371589114E-9; |
r7 = -0.76429178068910467734E-12; |
r8 = 0.27204790957888846175E-14; |
PROCEDURE cos* (x: REAL): REAL; |
VAR |
a, res: REAL; |
n: INTEGER; |
xn, f, x1, g: REAL; |
BEGIN |
ASSERT(y < FLT(ymax)); |
n := FLOOR(y * piInv + HALF); |
xn := FLT(n); |
IF ODD(n) THEN |
sign := -sign |
END; |
x := ABS(x); |
IF x # y THEN |
xn := xn - HALF |
END; |
ASSERT(x <= MaxCosArg); |
x1 := FLT(FLOOR(x)); |
f := ((x1 - xn * c1) + (x - x1)) - xn * c2; |
x := x - FLT( FLOOR(x / (2.0 * pi)) ) * (2.0 * pi); |
x := x * x; |
res := 0.0; |
a := 1.0; |
n := -1; |
IF ABS(f) < Limit THEN |
x := sign * f |
ELSE |
g := f * f; |
g := (((((((r8 * g + r7) * g + r6) * g + r5) * g + r4) * g + r3) * g + r2) * g + r1) * g; |
g := f + f * g; |
x := sign * g |
END |
REPEAT |
INC(n, 2); |
res := res + a; |
a := -a * x / FLT(n*n + n) |
UNTIL ABS(a) < eps |
RETURN x |
END SinCos; |
RETURN res |
END cos; |
PROCEDURE sin* (x: REAL): REAL; |
BEGIN |
IF x < ZERO THEN |
x := SinCos(x, -x, -ONE) |
ELSE |
x := SinCos(x, x, ONE) |
END |
RETURN x |
ASSERT(ABS(x) <= MaxCosArg); |
x := cos(x) |
RETURN sqrt(1.0 - x * x) |
END sin; |
PROCEDURE cos* (x: REAL): REAL; |
RETURN SinCos(x, ABS(x) + piByTwo, ONE) |
END cos; |
PROCEDURE tan* (x: REAL): REAL; |
VAR |
s, c: REAL; |
BEGIN |
s := sin(x); |
c := sqrt(ONE - s * s); |
x := ABS(x) / (TWO * pi); |
x := x - FLT(FLOOR(x)); |
IF (0.25 < x) & (x < 0.75) THEN |
c := -c |
END |
RETURN s / c |
ASSERT(ABS(x) <= MaxCosArg); |
x := cos(x) |
RETURN sqrt(1.0 - x * x) / x |
END tan; |
PROCEDURE arctan2* (y, x: REAL): REAL; |
CONST |
P0 = 0.216062307897242551884E+3; P1 = 0.3226620700132512059245E+3; |
P2 = 0.13270239816397674701E+3; P3 = 0.1288838303415727934E+2; |
Q0 = 0.2160623078972426128957E+3; Q1 = 0.3946828393122829592162E+3; |
Q2 = 0.221050883028417680623E+3; Q3 = 0.3850148650835119501E+2; |
Sqrt3 = 1.7320508075688772935E0; |
PROCEDURE arcsin* (x: REAL): REAL; |
PROCEDURE arctan (x: REAL): REAL; |
VAR |
atan, z, z2, p, q: REAL; |
yExp, xExp, Quadrant: INTEGER; |
z, p, k: REAL; |
BEGIN |
IF ABS(x) < miny THEN |
ASSERT(ABS(y) >= miny); |
atan := piByTwo |
ELSE |
z := y; |
UNPK(z, yExp); |
z := x; |
UNPK(z, xExp); |
p := x / (x * x + 1.0); |
z := p * x; |
x := 0.0; |
k := 0.0; |
IF yExp - xExp >= expoMax - 3 THEN |
atan := piByTwo |
ELSIF yExp - xExp < expoMin + 3 THEN |
atan := ZERO |
ELSE |
IF ABS(y) > ABS(x) THEN |
z := ABS(x / y); |
Quadrant := 2 |
ELSE |
z := ABS(y / x); |
Quadrant := 0 |
END; |
REPEAT |
k := k + 2.0; |
x := x + p; |
p := p * k * z / (k + 1.0) |
UNTIL p < eps |
IF z > TWO - Sqrt3 THEN |
z := (z * Sqrt3 - ONE) / (Sqrt3 + z); |
INC(Quadrant) |
END; |
RETURN x |
END arctan; |
IF ABS(z) < Limit THEN |
atan := z |
ELSE |
z2 := z * z; |
p := (((P3 * z2 + P2) * z2 + P1) * z2 + P0) * z; |
q := (((z2 + Q3) * z2 + Q2) * z2 + Q1) * z2 + Q0; |
atan := p / q |
END; |
CASE Quadrant OF |
|0: |
|1: atan := atan + pi / 6.0 |
|2: atan := piByTwo - atan |
|3: atan := pi / 3.0 - atan |
END |
END; |
BEGIN |
ASSERT(ABS(x) <= 1.0); |
IF x < ZERO THEN |
atan := pi - atan |
IF ABS(x) >= 0.707 THEN |
x := 0.5 * pi - arctan(sqrt(1.0 - x * x) / x) |
ELSE |
x := arctan(x / sqrt(1.0 - x * x)) |
END |
END; |
IF y < ZERO THEN |
atan := -atan |
END |
RETURN atan |
END arctan2; |
PROCEDURE arcsin* (x: REAL): REAL; |
BEGIN |
ASSERT(ABS(x) <= ONE) |
RETURN arctan2(x, sqrt(ONE - x * x)) |
RETURN x |
END arcsin; |
PROCEDURE arccos* (x: REAL): REAL; |
BEGIN |
ASSERT(ABS(x) <= ONE) |
RETURN arctan2(sqrt(ONE - x * x), x) |
ASSERT(ABS(x) <= 1.0) |
RETURN 0.5 * pi - arcsin(x) |
END arccos; |
PROCEDURE arctan* (x: REAL): REAL; |
RETURN arctan2(x, ONE) |
RETURN arcsin(x / sqrt(1.0 + x * x)) |
END arctan; |
362,7 → 217,7 |
PROCEDURE sinh* (x: REAL): REAL; |
BEGIN |
x := exp(x) |
RETURN (x - ONE / x) * HALF |
RETURN (x - 1.0 / x) * 0.5 |
END sinh; |
369,7 → 224,7 |
PROCEDURE cosh* (x: REAL): REAL; |
BEGIN |
x := exp(x) |
RETURN (x + ONE / x) * HALF |
RETURN (x + 1.0 / x) * 0.5 |
END cosh; |
376,12 → 231,12 |
PROCEDURE tanh* (x: REAL): REAL; |
BEGIN |
IF x > 15.0 THEN |
x := ONE |
x := 1.0 |
ELSIF x < -15.0 THEN |
x := -ONE |
x := -1.0 |
ELSE |
x := exp(TWO * x); |
x := (x - ONE) / (x + ONE) |
x := exp(2.0 * x); |
x := (x - 1.0) / (x + 1.0) |
END |
RETURN x |
389,21 → 244,21 |
PROCEDURE arsinh* (x: REAL): REAL; |
RETURN ln(x + sqrt(x * x + ONE)) |
RETURN ln(x + sqrt(x * x + 1.0)) |
END arsinh; |
PROCEDURE arcosh* (x: REAL): REAL; |
BEGIN |
ASSERT(x >= ONE) |
RETURN ln(x + sqrt(x * x - ONE)) |
ASSERT(x >= 1.0) |
RETURN ln(x + sqrt(x * x - 1.0)) |
END arcosh; |
PROCEDURE artanh* (x: REAL): REAL; |
BEGIN |
ASSERT(ABS(x) < ONE) |
RETURN HALF * ln((ONE + x) / (ONE - x)) |
ASSERT(ABS(x) < 1.0) |
RETURN 0.5 * ln((1.0 + x) / (1.0 - x)) |
END artanh; |
412,9 → 267,9 |
res: INTEGER; |
BEGIN |
IF x > ZERO THEN |
IF x > 0.0 THEN |
res := 1 |
ELSIF x < ZERO THEN |
ELSIF x < 0.0 THEN |
res := -1 |
ELSE |
res := 0 |
429,7 → 284,7 |
res: REAL; |
BEGIN |
res := ONE; |
res := 1.0; |
WHILE n > 1 DO |
res := res * FLT(n); |
DEC(n) |
439,42 → 294,18 |
END fact; |
PROCEDURE DegToRad* (x: REAL): REAL; |
RETURN x * (pi / 180.0) |
END DegToRad; |
PROCEDURE RadToDeg* (x: REAL): REAL; |
RETURN x * (180.0 / pi) |
END RadToDeg; |
(* Return hypotenuse of triangle *) |
PROCEDURE hypot* (x, y: REAL): REAL; |
PROCEDURE init; |
VAR |
a: REAL; |
i: INTEGER; |
BEGIN |
x := ABS(x); |
y := ABS(y); |
IF x > y THEN |
a := x * sqrt(1.0 + sqrr(y / x)) |
ELSE |
IF x > 0.0 THEN |
a := y * sqrt(1.0 + sqrr(x / y)) |
ELSE |
a := y |
Exp[0] := 1.0; |
FOR i := 1 TO LEN(Exp) - 1 DO |
Exp[i] := Exp[i - 1] * e |
END |
END |
END init; |
RETURN a |
END hypot; |
BEGIN |
large := 1.9; |
PACK(large, expoMax); |
miny := ONE / large; |
LnInfinity := ln(large); |
LnSmall := ln(miny); |
init |
END Math. |
/programs/develop/oberon07/Lib/Windows64/Out.ob07 |
---|
1,86 → 1,308 |
(* |
BSD 2-Clause License |
Copyright 2013, 2014, 2017, 2018, 2019 Anton Krotov |
Copyright (c) 2020, Anton Krotov |
All rights reserved. |
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 <http://www.gnu.org/licenses/>. |
*) |
MODULE Out; |
IMPORT SYSTEM; |
IMPORT sys := SYSTEM; |
CONST |
d = 1.0 - 5.0E-12; |
TYPE |
POverlapped* = POINTER TO OVERLAPPED; |
OVERLAPPED* = RECORD |
Internal*: INTEGER; |
InternalHigh*: INTEGER; |
Offset*: INTEGER; |
OffsetHigh*: INTEGER; |
hEvent*: INTEGER |
END; |
VAR |
hConsoleOutput: INTEGER; |
Realp: PROCEDURE (x: REAL; width: INTEGER); |
PROCEDURE [windows, "msvcrt.dll", "printf"] printf1 (fmt: INTEGER; x: INTEGER); |
PROCEDURE [windows, "msvcrt.dll", "printf"] printf2 (fmt: INTEGER; width, x: INTEGER); |
PROCEDURE [windows, "msvcrt.dll", "printf"] printf3 (fmt: INTEGER; width, precision, x: INTEGER); |
PROCEDURE [windows, "kernel32.dll", ""] |
WriteConsoleW (hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved: INTEGER); |
PROCEDURE [windows, "kernel32.dll", ""] |
PROCEDURE [windows-, "kernel32.dll", "GetStdHandle"] |
GetStdHandle (nStdHandle: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "WriteFile"] |
WriteFile (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "WriteConsoleW"] |
WriteConsoleW (hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved: INTEGER): INTEGER; |
PROCEDURE Char* (x: CHAR); |
VAR count: INTEGER; |
BEGIN |
printf1(SYSTEM.SADR("%c"), ORD(x)) |
WriteFile(hConsoleOutput, sys.ADR(x), 1, sys.ADR(count), NIL) |
END Char; |
PROCEDURE StringW* (s: ARRAY OF WCHAR); |
VAR count: INTEGER; |
BEGIN |
WriteConsoleW(hConsoleOutput, SYSTEM.ADR(s[0]), LENGTH(s), 0, 0) |
WriteConsoleW(hConsoleOutput, sys.ADR(s[0]), LENGTH(s), sys.ADR(count), 0) |
END StringW; |
PROCEDURE String* (s: ARRAY OF CHAR); |
VAR len, i: INTEGER; |
BEGIN |
printf2(SYSTEM.SADR("%.*s"), LENGTH(s), SYSTEM.ADR(s[0])) |
len := LENGTH(s); |
FOR i := 0 TO len - 1 DO |
Char(s[i]) |
END |
END String; |
PROCEDURE WriteInt(x, n: INTEGER); |
VAR i: INTEGER; a: ARRAY 32 OF CHAR; neg: BOOLEAN; |
BEGIN |
i := 0; |
IF n < 1 THEN |
n := 1 |
END; |
IF x < 0 THEN |
x := -x; |
DEC(n); |
neg := TRUE |
END; |
REPEAT |
a[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
WHILE n > i DO |
Char(" "); |
DEC(n) |
END; |
IF neg THEN |
Char("-") |
END; |
REPEAT |
DEC(i); |
Char(a[i]) |
UNTIL i = 0 |
END WriteInt; |
PROCEDURE Ln*; |
PROCEDURE IsNan(AValue: REAL): BOOLEAN; |
VAR s: SET; |
BEGIN |
printf1(SYSTEM.SADR("%s"), SYSTEM.SADR(CHR(13) + CHR(10))) |
END Ln; |
sys.GET(sys.ADR(AValue), s) |
RETURN (s * {52..62} = {52..62}) & ((s * {32..51} # {}) OR (s * {0..31} # {})) |
END IsNan; |
PROCEDURE IsInf(x: REAL): BOOLEAN; |
RETURN ABS(x) = sys.INF() |
END IsInf; |
PROCEDURE Int* (x, width: INTEGER); |
VAR i, minInt: INTEGER; |
BEGIN |
printf2(SYSTEM.SADR("%*lld"), width, x) |
minInt := 1; |
minInt := ROR(minInt, 1); |
IF x # minInt THEN |
WriteInt(x, width) |
ELSE |
FOR i := 21 TO width DO |
Char(20X) |
END; |
String("-9223372036854775808") |
END |
END Int; |
PROCEDURE OutInf(x: REAL; width: INTEGER); |
VAR s: ARRAY 5 OF CHAR; i: INTEGER; |
BEGIN |
IF IsNan(x) THEN |
s := "Nan"; |
INC(width) |
ELSIF IsInf(x) & (x > 0.0) THEN |
s := "+Inf" |
ELSIF IsInf(x) & (x < 0.0) THEN |
s := "-Inf" |
END; |
FOR i := 1 TO width - 4 DO |
Char(" ") |
END; |
String(s) |
END OutInf; |
PROCEDURE intval (x: REAL): INTEGER; |
VAR |
i: INTEGER; |
PROCEDURE Ln*; |
BEGIN |
Char(0DX); |
Char(0AX) |
END Ln; |
PROCEDURE _FixReal(x: REAL; width, p: INTEGER); |
VAR e, len, i: INTEGER; y: REAL; minus: BOOLEAN; |
BEGIN |
SYSTEM.GET(SYSTEM.ADR(x), i) |
RETURN i |
END intval; |
IF IsNan(x) OR IsInf(x) THEN |
OutInf(x, width) |
ELSIF p < 0 THEN |
Realp(x, width) |
ELSE |
len := 0; |
minus := FALSE; |
IF x < 0.0 THEN |
minus := TRUE; |
INC(len); |
x := ABS(x) |
END; |
e := 0; |
WHILE x >= 10.0 DO |
x := x / 10.0; |
INC(e) |
END; |
IF e >= 0 THEN |
len := len + e + p + 1; |
IF x > 9.0 + d THEN |
INC(len) |
END; |
IF p > 0 THEN |
INC(len) |
END; |
ELSE |
len := len + p + 2 |
END; |
FOR i := 1 TO width - len DO |
Char(" ") |
END; |
IF minus THEN |
Char("-") |
END; |
y := x; |
WHILE (y < 1.0) & (y # 0.0) DO |
y := y * 10.0; |
DEC(e) |
END; |
IF e < 0 THEN |
IF x - FLT(FLOOR(x)) > d THEN |
Char("1"); |
x := 0.0 |
ELSE |
Char("0"); |
x := x * 10.0 |
END |
ELSE |
WHILE e >= 0 DO |
IF x - FLT(FLOOR(x)) > d THEN |
IF x > 9.0 THEN |
String("10") |
ELSE |
Char(CHR(FLOOR(x) + ORD("0") + 1)) |
END; |
x := 0.0 |
ELSE |
Char(CHR(FLOOR(x) + ORD("0"))); |
x := (x - FLT(FLOOR(x))) * 10.0 |
END; |
DEC(e) |
END |
END; |
IF p > 0 THEN |
Char(".") |
END; |
WHILE p > 0 DO |
IF x - FLT(FLOOR(x)) > d THEN |
Char(CHR(FLOOR(x) + ORD("0") + 1)); |
x := 0.0 |
ELSE |
Char(CHR(FLOOR(x) + ORD("0"))); |
x := (x - FLT(FLOOR(x))) * 10.0 |
END; |
DEC(p) |
END |
END |
END _FixReal; |
PROCEDURE Real* (x: REAL; width: INTEGER); |
VAR e, n, i: INTEGER; minus: BOOLEAN; |
BEGIN |
printf3(SYSTEM.SADR("%*.*E"), width, MAX(MIN(width - 8, 15), 1), intval(x)) |
Realp := Real; |
IF IsNan(x) OR IsInf(x) THEN |
OutInf(x, width) |
ELSE |
e := 0; |
n := 0; |
IF width > 23 THEN |
n := width - 23; |
width := 23 |
ELSIF width < 9 THEN |
width := 9 |
END; |
width := width - 5; |
IF x < 0.0 THEN |
x := -x; |
minus := TRUE |
ELSE |
minus := FALSE |
END; |
WHILE x >= 10.0 DO |
x := x / 10.0; |
INC(e) |
END; |
WHILE (x < 1.0) & (x # 0.0) DO |
x := x * 10.0; |
DEC(e) |
END; |
IF x > 9.0 + d THEN |
x := 1.0; |
INC(e) |
END; |
FOR i := 1 TO n DO |
Char(" ") |
END; |
IF minus THEN |
x := -x |
END; |
_FixReal(x, width, width - 3); |
Char("E"); |
IF e >= 0 THEN |
Char("+") |
ELSE |
Char("-"); |
e := ABS(e) |
END; |
IF e < 100 THEN |
Char("0") |
END; |
IF e < 10 THEN |
Char("0") |
END; |
Int(e, 0) |
END |
END Real; |
PROCEDURE FixReal* (x: REAL; width, precision: INTEGER); |
PROCEDURE FixReal*(x: REAL; width, p: INTEGER); |
BEGIN |
printf3(SYSTEM.SADR("%*.*f"), width, precision, intval(x)) |
Realp := Real; |
_FixReal(x, width, p) |
END FixReal; |
PROCEDURE Open*; |
BEGIN |
hConsoleOutput := GetStdHandle(-11) |
END Open; |
END Out. |
/programs/develop/oberon07/Lib/Windows64/RTL.ob07 |
---|
350,29 → 350,33 |
PROCEDURE IntToStr (x: INTEGER; VAR str: ARRAY OF CHAR); |
VAR |
i, a: INTEGER; |
i, a, b: INTEGER; |
c: CHAR; |
BEGIN |
i := 0; |
a := x; |
REPEAT |
INC(i); |
a := a DIV 10 |
UNTIL a = 0; |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
str[i] := 0X; |
REPEAT |
DEC(i); |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10 |
UNTIL x = 0 |
a := 0; |
b := i - 1; |
WHILE a < b DO |
c := str[a]; |
str[a] := str[b]; |
str[b] := c; |
INC(a); |
DEC(b) |
END; |
str[i] := 0X |
END IntToStr; |
PROCEDURE append (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); |
VAR |
n1, n2: INTEGER; |
n1, n2, i, j: INTEGER; |
BEGIN |
n1 := LENGTH(s1); |
380,12 → 384,19 |
ASSERT(n1 + n2 < LEN(s1)); |
SYSTEM.MOVE(SYSTEM.ADR(s2[0]), SYSTEM.ADR(s1[n1]), n2); |
s1[n1 + n2] := 0X |
i := 0; |
j := n1; |
WHILE i < n2 DO |
s1[j] := s2[i]; |
INC(i); |
INC(j) |
END; |
s1[j] := 0X |
END append; |
PROCEDURE [stdcall64] _error* (modnum, _module, err, line: INTEGER); |
PROCEDURE [stdcall64] _error* (module, err, line: INTEGER); |
VAR |
s, temp: ARRAY 1024 OF CHAR; |
404,9 → 415,11 |
|11: s := "BYTE out of range" |
END; |
append(s, API.eol + "module: "); PCharToStr(_module, temp); append(s, temp); |
append(s, API.eol + "line: "); IntToStr(line, temp); append(s, temp); |
append(s, API.eol); |
append(s, "module: "); PCharToStr(module, temp); append(s, temp); append(s, API.eol); |
append(s, "line: "); IntToStr(line, temp); append(s, temp); |
API.DebugMsg(SYSTEM.ADR(s[0]), name); |
API.exit_thread(0) |
/programs/develop/oberon07/Lib/Windows64/UnixTime.ob07 |
---|
0,0 → 1,64 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
MODULE UnixTime; |
VAR |
days: ARRAY 12, 31, 2 OF INTEGER; |
PROCEDURE init; |
VAR |
i, j, k, n0, n1: INTEGER; |
BEGIN |
FOR i := 0 TO 11 DO |
FOR j := 0 TO 30 DO |
days[i, j, 0] := 0; |
days[i, j, 1] := 0; |
END |
END; |
days[ 1, 28, 0] := -1; |
FOR k := 0 TO 1 DO |
days[ 1, 29, k] := -1; |
days[ 1, 30, k] := -1; |
days[ 3, 30, k] := -1; |
days[ 5, 30, k] := -1; |
days[ 8, 30, k] := -1; |
days[10, 30, k] := -1; |
END; |
n0 := 0; |
n1 := 0; |
FOR i := 0 TO 11 DO |
FOR j := 0 TO 30 DO |
IF days[i, j, 0] = 0 THEN |
days[i, j, 0] := n0; |
INC(n0) |
END; |
IF days[i, j, 1] = 0 THEN |
days[i, j, 1] := n1; |
INC(n1) |
END |
END |
END |
END init; |
PROCEDURE time* (year, month, day, hour, min, sec: INTEGER): INTEGER; |
RETURN ((year - 1970) * 365 + days[month - 1, day - 1, ORD(year DIV 4 = 0)] + (year - 1969) DIV 4) * 86400 + hour * 3600 + min * 60 + sec |
END time; |
BEGIN |
init |
END UnixTime. |
/programs/develop/oberon07/Lib/Windows64/WINAPI.ob07 |
---|
14,11 → 14,7 |
OFS_MAXPATHNAME* = 128; |
KERNEL = "kernel32.dll"; |
USER = "user32.dll"; |
MSVCRT = "msvcrt.dll"; |
TYPE |
DLL_ENTRY* = API.DLL_ENTRY; |
60,27 → 56,13 |
END; |
tm* = RECORD |
sec*, |
min*, |
hour*, |
mday*, |
mon*, |
year*, |
wday*, |
yday*, |
isdst*: SYSTEM.CARD32 |
END; |
PSecurityAttributes* = POINTER TO TSecurityAttributes; |
TSecurityAttributes* = RECORD |
nLength*: SYSTEM.CARD32; |
nLength*: INTEGER; |
lpSecurityDescriptor*: INTEGER; |
bInheritHandle*: SYSTEM.CARD32 (* BOOL *) |
bInheritHandle*: INTEGER |
END; |
87,32 → 69,14 |
TFileTime* = RECORD |
dwLowDateTime*, |
dwHighDateTime*: SYSTEM.CARD32 |
dwHighDateTime*: INTEGER |
END; |
TWin32FindData* = RECORD |
dwFileAttributes*: SYSTEM.CARD32; |
ftCreationTime*: TFileTime; |
ftLastAccessTime*: TFileTime; |
ftLastWriteTime*: TFileTime; |
nFileSizeHigh*: SYSTEM.CARD32; |
nFileSizeLow*: SYSTEM.CARD32; |
dwReserved0*: SYSTEM.CARD32; |
dwReserved1*: SYSTEM.CARD32; |
cFileName*: STRING; |
cAlternateFileName*: ARRAY 14 OF CHAR; |
dwFileType*: SYSTEM.CARD32; |
dwCreatorType*: SYSTEM.CARD32; |
wFinderFlags*: WCHAR |
END; |
OFSTRUCT* = RECORD |
cBytes*: BYTE; |
fFixedDisk*: BYTE; |
cBytes*: CHAR; |
fFixedDisk*: CHAR; |
nErrCode*: WCHAR; |
Reserved1*: WCHAR; |
Reserved2*: WCHAR; |
126,95 → 90,77 |
Internal*: INTEGER; |
InternalHigh*: INTEGER; |
Offset*: SYSTEM.CARD32; |
OffsetHigh*: SYSTEM.CARD32; |
Offset*: INTEGER; |
OffsetHigh*: INTEGER; |
hEvent*: INTEGER |
END; |
PROCEDURE [windows-, KERNEL, ""] SetConsoleCursorPosition* (hConsoleOutput, dwCursorPosition: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "SetConsoleCursorPosition"] |
SetConsoleCursorPosition* (hConsoleOutput, dwCursorPosition: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetConsoleScreenBufferInfo* (hConsoleOutput: INTEGER; ConsoleScreenBufferInfo: TConsoleScreenBufferInfo): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetConsoleScreenBufferInfo"] |
GetConsoleScreenBufferInfo* (hConsoleOutput: INTEGER; ConsoleScreenBufferInfo: TConsoleScreenBufferInfo): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] FillConsoleOutputCharacterA* (hConsoleOutput, cCaracter, nLength, dwWriteCoord, lpNumberOfCharsWritten: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "FillConsoleOutputCharacterA"] |
FillConsoleOutputCharacter* (hConsoleOutput, cCaracter, nLength, dwWriteCoord, lpNumberOfCharsWritten: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] FillConsoleOutputAttribute* (hConsoleOutput, wAttribute, nLength, dwWriteCoord, lpNumberOfAttrsWritten: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "FillConsoleOutputAttribute"] |
FillConsoleOutputAttribute* (hConsoleOutput, wAttribute, nLength, dwWriteCoord, lpNumberOfAttrsWritten: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] SetConsoleTextAttribute* (hConsoleOutput, wAttributes: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "SetConsoleTextAttribute"] |
SetConsoleTextAttribute* (hConsoleOutput, wAttributes: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetStdHandle* (nStdHandle: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetStdHandle"] |
GetStdHandle* (nStdHandle: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] CloseHandle* (hObject: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "CloseHandle"] |
CloseHandle* (hObject: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] WriteFile* (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "WriteFile"] |
WriteFile* (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] ReadFile* (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "ReadFile"] |
ReadFile* (hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetCommandLineA* (): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetCommandLineA"] |
GetCommandLine* (): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GlobalAlloc* (uFlags, dwBytes: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GlobalAlloc"] |
GlobalAlloc* (uFlags, dwBytes: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GlobalFree* (hMem: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GlobalFree"] |
GlobalFree* (hMem: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] ExitProcess* (code: INTEGER); |
PROCEDURE [windows-, "kernel32.dll", "ExitProcess"] |
ExitProcess* (code: INTEGER); |
PROCEDURE [windows-, KERNEL, ""] GetTickCount* (): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetTickCount"] |
GetTickCount* (): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] Sleep* (dwMilliseconds: INTEGER); |
PROCEDURE [windows-, "kernel32.dll", "Sleep"] |
Sleep* (dwMilliseconds: INTEGER); |
PROCEDURE [windows-, KERNEL, ""] FreeLibrary* (hLibModule: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "FreeLibrary"] |
FreeLibrary* (hLibModule: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetProcAddress* (hModule, name: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "GetProcAddress"] |
GetProcAddress* (hModule, name: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] LoadLibraryA* (name: INTEGER): INTEGER; |
PROCEDURE [windows-, "kernel32.dll", "LoadLibraryA"] |
LoadLibraryA* (name: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] AllocConsole* (): BOOLEAN; |
PROCEDURE [windows-, "kernel32.dll", "AllocConsole"] |
AllocConsole* (): BOOLEAN; |
PROCEDURE [windows-, KERNEL, ""] FreeConsole* (): BOOLEAN; |
PROCEDURE [windows-, "kernel32.dll", "FreeConsole"] |
FreeConsole* (): BOOLEAN; |
PROCEDURE [windows-, KERNEL, ""] GetLocalTime* (T: TSystemTime); |
PROCEDURE [windows-, "kernel32.dll", "GetLocalTime"] |
GetLocalTime* (T: TSystemTime); |
PROCEDURE [windows-, KERNEL, ""] RemoveDirectoryA* (lpPathName: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] GetFileAttributesA* (lpPathName: INTEGER): SET; |
PROCEDURE [windows-, KERNEL, ""] CreateDirectoryA* (lpPathName: INTEGER; lpSecurityAttributes: PSecurityAttributes): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] FindFirstFileA* (lpFileName: INTEGER; lpFindFileData: TWin32FindData): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] DeleteFileA* (lpFileName: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] FindClose* (hFindFile: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] CreateFileA* ( |
lpFileName, dwDesiredAccess, dwShareMode: INTEGER; |
lpSecurityAttributes: PSecurityAttributes; |
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] OpenFile* (lpFileName: INTEGER; lpReOpenBuff: OFSTRUCT; uStyle: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] SetFilePointer* (hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] ReadConsoleA* (hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, lpReserved: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] WriteConsoleW* (hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved: INTEGER): INTEGER; |
PROCEDURE [windows-, KERNEL, ""] WriteConsoleA* (hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved: INTEGER): INTEGER; |
PROCEDURE [windows-, USER, ""] MessageBoxA* (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE [windows-, USER, ""] MessageBoxW* (hWnd, lpText, lpCaption, uType: INTEGER): INTEGER; |
PROCEDURE [windows-, USER, ""] CreateWindowExA* ( |
dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, |
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam: INTEGER): INTEGER; |
PROCEDURE [windows-, MSVCRT, ""] time* (ptr: INTEGER): INTEGER; |
PROCEDURE [windows-, MSVCRT, ""] mktime* (time: tm): INTEGER; |
PROCEDURE SetDllEntry* (process_detach, thread_detach, thread_attach: DLL_ENTRY); |
BEGIN |
API.SetDll(process_detach, thread_detach, thread_attach) |
/programs/develop/oberon07/Samples/STM32CM3/LCD.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/STM32CM3/TIM67.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/STM32CM3/SysTick.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/STM32CM3/Button.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/STM32CM3/Blink.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/hailst.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/MagicSquares.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/HeapSort.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/Doors.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/MultiplicationTables.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/TempConv.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/sequence012.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/postfix.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/exp.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/HelloRus.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/Hello.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Windows/Console/SierpinskiTriangle.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/Sieve.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/fact.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/SierpinskiCarpet.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Windows/Console/SpiralMatrix.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/MSP430/Blink.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/MSP430/TimerA.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/MSP430/Restart.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/MSP430/Button.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/MSP430/TwoTimers.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/MSP430/Flash.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/KolibriOS/Dialogs.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/KolibriOS/HW_con.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/KolibriOS/HW.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Samples/Linux/HW.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/filler/filler.txt |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/filler/out.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/filler/gr.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/filler/filler.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/filler/_unix.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/filler/unix.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/animation/_unix.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/animation/unix.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/animation/out.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/animation/gr.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Linux/X11/animation/animation.ob07 |
---|
File deleted |
/programs/develop/oberon07/Samples/Dialogs.ob07 |
---|
0,0 → 1,110 |
MODULE Dialogs; |
IMPORT KOSAPI, sys := SYSTEM, OpenDlg, ColorDlg; |
VAR header: ARRAY 1024 OF CHAR; back_color: INTEGER; |
PROCEDURE WindowRedrawStatus(p: INTEGER); |
BEGIN |
KOSAPI.sysfunc2(12, p) |
END WindowRedrawStatus; |
PROCEDURE DefineAndDrawWindow(x, y, w, h, color, style, hcolor, hstyle, htext: INTEGER); |
BEGIN |
KOSAPI.sysfunc6(0, x * 65536 + w, y * 65536 + h, color + LSL(style, 24), hcolor + LSL(hstyle, 24), htext) |
END DefineAndDrawWindow; |
PROCEDURE WaitForEvent(): INTEGER; |
RETURN KOSAPI.sysfunc1(10) |
END WaitForEvent; |
PROCEDURE ExitApp; |
BEGIN |
KOSAPI.sysfunc1(-1) |
END ExitApp; |
PROCEDURE pause(t: INTEGER); |
BEGIN |
KOSAPI.sysfunc2(5, t) |
END pause; |
PROCEDURE Buttons; |
PROCEDURE Button(id, X, Y, W, H: INTEGER; Caption: ARRAY OF CHAR); |
VAR n, aux: INTEGER; |
BEGIN |
n := LENGTH(Caption); |
aux := KOSAPI.sysfunc5(8, X * 65536 + W, Y * 65536 + H, id, 00C0C0C0H); |
X := X + (W - 8 * n) DIV 2; |
Y := Y + (H - 14) DIV 2; |
aux := KOSAPI.sysfunc6(4, X * 65536 + Y, LSL(48, 24), sys.ADR(Caption[0]), n, 0) |
END Button; |
BEGIN |
Button(17, 5, 5, 70, 25, "open"); |
Button(18, 85, 5, 70, 25, "color"); |
END Buttons; |
PROCEDURE draw_window; |
BEGIN |
WindowRedrawStatus(1); |
DefineAndDrawWindow(200, 200, 500, 100, back_color, 51, 0, 0, sys.ADR(header[0])); |
Buttons; |
WindowRedrawStatus(2); |
END draw_window; |
PROCEDURE OpenFile(Open: OpenDlg.Dialog); |
BEGIN |
IF Open # NIL THEN |
OpenDlg.Show(Open, 500, 450); |
WHILE Open.status = 2 DO |
pause(30) |
END; |
IF Open.status = 1 THEN |
COPY(Open.FilePath, header) |
END |
END |
END OpenFile; |
PROCEDURE SelColor(Color: ColorDlg.Dialog); |
BEGIN |
IF Color # NIL THEN |
ColorDlg.Show(Color); |
WHILE Color.status = 2 DO |
pause(30) |
END; |
IF Color.status = 1 THEN |
back_color := Color.color |
END |
END |
END SelColor; |
PROCEDURE main; |
VAR Open: OpenDlg.Dialog; Color: ColorDlg.Dialog; res, al: INTEGER; |
BEGIN |
back_color := 00FFFFFFH; |
header := "Dialogs"; |
draw_window; |
Open := OpenDlg.Create(draw_window, 0, "/rd/1", "ASM|TXT|INI"); |
Color := ColorDlg.Create(draw_window); |
WHILE TRUE DO |
CASE WaitForEvent() OF |
|1: draw_window |
|3: res := KOSAPI.sysfunc1(17); |
al := LSR(LSL(res, 24), 24); |
res := LSR(res, 8); |
IF al = 0 THEN |
CASE res OF |
| 1: ExitApp |
|17: OpenFile(Open) |
|18: SelColor(Color) |
END |
END |
ELSE |
END |
END |
END main; |
BEGIN |
main |
END Dialogs. |
/programs/develop/oberon07/Samples/HW.ob07 |
---|
0,0 → 1,50 |
MODULE HW; |
IMPORT sys := SYSTEM, KOSAPI; |
PROCEDURE WindowRedrawStatus(p: INTEGER); |
BEGIN |
KOSAPI.sysfunc2(12, p) |
END WindowRedrawStatus; |
PROCEDURE DefineAndDrawWindow(x, y, w, h, color, style, hcolor, hstyle, htext: INTEGER); |
BEGIN |
KOSAPI.sysfunc6(0, x * 65536 + w, y * 65536 + h, color + LSL(style, 24), hcolor + LSL(hstyle, 24), htext) |
END DefineAndDrawWindow; |
PROCEDURE WriteTextToWindow(x, y, color: INTEGER; text: ARRAY OF CHAR); |
BEGIN |
KOSAPI.sysfunc6(4, x * 65536 + y, color + LSL(48, 24), sys.ADR(text[0]), LENGTH(text), 0) |
END WriteTextToWindow; |
PROCEDURE WaitForEvent(): INTEGER; |
RETURN KOSAPI.sysfunc1(10) |
END WaitForEvent; |
PROCEDURE ExitApp; |
BEGIN |
KOSAPI.sysfunc1(-1) |
END ExitApp; |
PROCEDURE draw_window(header, text: ARRAY OF CHAR); |
BEGIN |
WindowRedrawStatus(1); |
DefineAndDrawWindow(200, 200, 200, 100, 0FFFFFFH, 51, 0, 0, sys.ADR(header)); |
WriteTextToWindow(10, 10, 0FF0000H, text); |
WindowRedrawStatus(2); |
END draw_window; |
PROCEDURE Main(header, text: ARRAY OF CHAR); |
BEGIN |
WHILE TRUE DO |
CASE WaitForEvent() OF |
|1: draw_window(header, text) |
|3: ExitApp |
ELSE |
END |
END |
END Main; |
BEGIN |
Main("HW", "Hello, world!") |
END HW. |
/programs/develop/oberon07/Samples/HW_con.ob07 |
---|
0,0 → 1,63 |
MODULE HW_con; |
IMPORT Out, In, Console, DateTime; |
PROCEDURE OutInt2(n: INTEGER); |
BEGIN |
ASSERT((0 <= n) & (n <= 99)); |
IF n < 10 THEN |
Out.Char("0") |
END; |
Out.Int(n, 0) |
END OutInt2; |
PROCEDURE OutMonth(n: INTEGER); |
VAR |
str: ARRAY 4 OF CHAR; |
BEGIN |
CASE n OF |
| 1: str := "jan" |
| 2: str := "feb" |
| 3: str := "mar" |
| 4: str := "apr" |
| 5: str := "may" |
| 6: str := "jun" |
| 7: str := "jul" |
| 8: str := "aug" |
| 9: str := "sep" |
|10: str := "oct" |
|11: str := "nov" |
|12: str := "dec" |
END; |
Out.String(str) |
END OutMonth; |
PROCEDURE main; |
VAR |
Year, Month, Day, Hour, Min, Sec, Msec: INTEGER; |
BEGIN |
Out.String("Hello, world!"); Out.Ln; |
Console.SetColor(Console.White, Console.Red); |
DateTime.Now(Year, Month, Day, Hour, Min, Sec, Msec); |
Out.Int(Year, 0); Out.Char("-"); |
OutMonth(Month); Out.Char("-"); |
OutInt2(Day); Out.Char(" "); |
OutInt2(Hour); Out.Char(":"); |
OutInt2(Min); Out.Char(":"); |
OutInt2(Sec) |
END main; |
BEGIN |
Console.open; |
main; |
In.Ln; |
Console.exit(TRUE) |
END HW_con. |
/programs/develop/oberon07/Source/RVM32I.ob07 |
---|
File deleted |
\ No newline at end of file |
/programs/develop/oberon07/Source/AMD64.ob07 |
---|
8,7 → 8,7 |
MODULE AMD64; |
IMPORT IL, BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS, PATHS, PROG, TARGETS, |
REG, UTILS, S := STRINGS, PE32, ELF, X86, ERRORS; |
REG, C := CONSOLE, UTILS, S := STRINGS, PE32, ELF, X86; |
CONST |
27,8 → 27,6 |
rsi = 6; |
rdi = 7; |
MAX_XMM = 5; |
je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; |
sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H; |
40,9 → 38,7 |
sBSS = BIN.PICBSS; |
sIMP = BIN.PICIMP; |
FPR_ERR = 41; |
TYPE |
COMMAND = IL.COMMAND; |
69,11 → 65,7 |
Win64RegPar: ARRAY 4 OF INTEGER; |
SystemVRegPar: ARRAY 6 OF INTEGER; |
Xmm: ARRAY 1000 OF INTEGER; |
fname: PATHS.PATH; |
PROCEDURE OutByte (b: BYTE); |
BEGIN |
X86.OutByte(b) |
104,19 → 96,24 |
END OutInt; |
PROCEDURE isByte (n: INTEGER): BOOLEAN; |
RETURN (-128 <= n) & (n <= 127) |
END isByte; |
PROCEDURE short (n: INTEGER): INTEGER; |
RETURN 2 * ORD(X86.isByte(n)) |
RETURN 2 * ORD(isByte(n)) |
END short; |
PROCEDURE long (n: INTEGER): INTEGER; |
RETURN 40H * ORD(~X86.isByte(n)) |
RETURN 40H * ORD(~isByte(n)) |
END long; |
PROCEDURE OutIntByte (n: INTEGER); |
BEGIN |
IF X86.isByte(n) THEN |
IF isByte(n) THEN |
OutByte(n MOD 256) |
ELSE |
OutInt(n) |
194,10 → 191,10 |
END and; |
PROCEDURE _or (reg1, reg2: INTEGER); (* or reg1, reg2 *) |
PROCEDURE or (reg1, reg2: INTEGER); (* or reg1, reg2 *) |
BEGIN |
oprr(09H, reg1, reg2) |
END _or; |
END or; |
PROCEDURE add (reg1, reg2: INTEGER); (* add reg1, reg2 *) |
214,12 → 211,7 |
PROCEDURE xchg (reg1, reg2: INTEGER); (* xchg reg1, reg2 *) |
BEGIN |
IF rax IN {reg1, reg2} THEN |
Rex(reg1 + reg2, 0); |
OutByte(90H + (reg1 + reg2) MOD 8) |
ELSE |
oprr(87H, reg1, reg2) |
END |
END xchg; |
278,9 → 270,17 |
PROCEDURE callimp (label: INTEGER); |
VAR |
reg: INTEGER; |
BEGIN |
OutByte2(0FFH, 15H); (* call qword[rip + label + IMP] *) |
X86.Reloc(sIMP, label) |
reg := GetAnyReg(); |
lea(reg, label, sIMP); |
IF reg >= 8 THEN (* call qword[reg] *) |
OutByte(41H) |
END; |
OutByte2(0FFH, 10H + reg MOD 8); |
drop |
END callimp; |
383,7 → 383,8 |
oprlongc(reg, n, oprr) |
ELSE |
Rex(reg, 0); |
X86.oprc(op, reg, n) |
OutByte2(81H + short(n), op + reg MOD 8); |
OutIntByte(n) |
END |
END oprc; |
418,7 → 419,7 |
PROCEDURE orrc (reg, n: INTEGER); (* or reg, n *) |
BEGIN |
oprc(0C8H, reg, n, _or) |
oprc(0C8H, reg, n, or) |
END orrc; |
439,7 → 440,7 |
push(reg2); |
drop |
ELSE |
X86.pushc(n) |
OutByte(68H + short(n)); OutIntByte(n) (* push n *) |
END |
END pushc; |
552,6 → 553,21 |
END jcc; |
PROCEDURE jmp (label: INTEGER); (* jmp label *) |
BEGIN |
X86.jmp(label) |
END jmp; |
PROCEDURE setcc (cc, reg: INTEGER); (* setcc reg8 *) |
BEGIN |
IF reg >= 8 THEN |
OutByte(41H) |
END; |
OutByte3(0FH, cc, 0C0H + reg MOD 8) |
END setcc; |
PROCEDURE shiftrc (op, reg, n: INTEGER); |
BEGIN |
Rex(reg, 0); |
813,7 → 829,7 |
cc := setnc |
END; |
OutByte2(7AH, 3 + reg DIV 8); (* jp L *) |
X86.setcc(cc, reg) |
setcc(cc, reg); |
(* L: *) |
END fcmp; |
843,7 → 859,7 |
CASE opcode OF |
|IL.opJMP: |
X86.jmp(param1) |
jmp(param1) |
|IL.opCALL, IL.opWIN64CALL, IL.opSYSVCALL: |
REG.Store(R); |
891,24 → 907,24 |
|IL.opONERR: |
pushc(param2); |
X86.jmp(param1) |
jmp(param1) |
|IL.opPUSHC: |
pushc(param2) |
|IL.opPRECALL: |
PushAll(0); |
IF (param2 # 0) & (xmm >= 0) THEN |
n := param2; |
IF (param1 # 0) & (n # 0) THEN |
subrc(rsp, 8) |
END; |
INC(Xmm[0]); |
Xmm[Xmm[0]] := xmm + 1; |
WHILE xmm >= 0 DO |
WHILE n > 0 DO |
subrc(rsp, 8); |
movsdmr(rsp, 0, xmm); |
DEC(xmm) |
DEC(xmm); |
DEC(n) |
END; |
ASSERT(xmm = -1) |
ASSERT(xmm = -1); |
PushAll(0) |
|IL.opWIN64ALIGN16: |
ASSERT(rax IN R.regs); |
926,26 → 942,27 |
push(rax) |
END |
|IL.opRESF, IL.opRES: |
ASSERT(R.top = -1); |
|IL.opRESF: |
ASSERT(xmm = -1); |
n := Xmm[Xmm[0]]; DEC(Xmm[0]); |
IF opcode = IL.opRESF THEN |
INC(xmm); |
n := param2; |
IF n > 0 THEN |
movsdmr(rsp, n * 8, 0); |
movsdmr(rsp, n * 8, xmm); |
DEC(xmm); |
INC(n) |
END; |
IF xmm + n > MAX_XMM THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
WHILE n > 0 DO |
INC(xmm); |
movsdrm(xmm, rsp, 0); |
addrc(rsp, 8); |
DEC(n) |
END |
ELSE |
GetRegA |
END; |
|IL.opRES: |
ASSERT(R.top = -1); |
GetRegA; |
n := param2; |
WHILE n > 0 DO |
INC(xmm); |
movsdrm(xmm, rsp, 0); |
1120,29 → 1137,31 |
IF reg2 # -1 THEN |
mov(reg1, reg2) |
ELSE |
movrm32(reg1, rbp, param2 * 8) |
END; |
shiftrc(shl, reg1, 32); |
shiftrc(shr, reg1, 32) |
n := param2 * 8; |
xor(reg1, reg1); |
movrm32(reg1, rbp, n) |
END |
|IL.opGLOAD64: |
reg1 := GetAnyReg(); |
Rex(0, reg1); (* mov reg1, qword[rip + param2 + BSS] *) |
OutByte2(8BH, 05H + 8 * (reg1 MOD 8)); |
X86.Reloc(sBSS, param2) |
lea(reg1, param2, sBSS); |
movrm(reg1, reg1, 0) |
|IL.opGLOAD8, IL.opGLOAD16: |
|IL.opGLOAD8: |
reg1 := GetAnyReg(); |
Rex(0, reg1); (* movzx reg1, byte/word[rip + param2 + BSS] *) |
OutByte3(0FH, 0B6H + ORD(opcode = IL.opGLOAD16), 05H + 8 * (reg1 MOD 8)); |
X86.Reloc(sBSS, param2) |
lea(reg1, param2, sBSS); |
movzx(reg1, reg1, 0, FALSE) |
|IL.opGLOAD16: |
reg1 := GetAnyReg(); |
lea(reg1, param2, sBSS); |
movzx(reg1, reg1, 0, TRUE) |
|IL.opGLOAD32: |
reg1 := GetAnyReg(); |
xor(reg1, reg1); |
lea(reg1, param2, sBSS); |
movrm32(reg1, reg1, 0); |
shiftrc(shl, reg1, 32); |
shiftrc(shr, reg1, 32) |
movrm32(reg1, reg1, 0) |
|IL.opVLOAD64: |
reg1 := GetAnyReg(); |
1158,10 → 1177,9 |
|IL.opVLOAD32: |
reg1 := GetAnyReg(); |
reg2 := GetAnyReg(); |
xor(reg1, reg1); |
movrm(reg2, rbp, param2 * 8); |
movrm32(reg1, reg2, 0); |
shiftrc(shl, reg1, 32); |
shiftrc(shr, reg1, 32); |
drop |
|IL.opLADR: |
1168,22 → 1186,14 |
n := param2 * 8; |
next := cmd.next(COMMAND); |
IF (next.opcode = IL.opSAVEF) OR (next.opcode = IL.opSAVEFI) THEN |
ASSERT(xmm >= 0); |
movsdmr(rbp, n, xmm); |
DEC(xmm); |
cmd := next |
ELSIF next.opcode = IL.opLOADF THEN |
INC(xmm); |
IF xmm > MAX_XMM THEN |
ERRORS.ErrorMsg(fname, next.param1, next.param2, FPR_ERR) |
END; |
movsdrm(xmm, rbp, n); |
cmd := next |
ELSE |
IF (next.opcode = IL.opADDC) & ~isLong(n + next.param2) THEN |
INC(n, next.param2); |
cmd := next |
END; |
reg1 := GetAnyReg(); |
Rex(0, reg1); |
OutByte2(8DH, 45H + long(n) + (reg1 MOD 8) * 8); (* lea reg1, qword[rbp+n] *) |
1191,11 → 1201,6 |
END |
|IL.opGADR: |
next := cmd.next(COMMAND); |
IF (next.opcode = IL.opADDC) & ~isLong(param2 + next.param2) THEN |
INC(param2, next.param2); |
cmd := next |
END; |
lea(GetAnyReg(), param2, sBSS) |
|IL.opVADR: |
1306,15 → 1311,15 |
cc := X86.cond(opcode); |
next := cmd.next(COMMAND); |
IF next.opcode = IL.opJNZ THEN |
IF next.opcode = IL.opJE THEN |
jcc(cc, next.param1); |
cmd := next |
ELSIF next.opcode = IL.opJZ THEN |
ELSIF next.opcode = IL.opJNE THEN |
jcc(X86.inv0(cc), next.param1); |
cmd := next |
ELSE |
reg1 := GetAnyReg(); |
X86.setcc(cc + 16, reg1); |
setcc(cc + 16, reg1); |
andrc(reg1, 1) |
END |
1337,23 → 1342,36 |
PushAll(n) |
END |
|IL.opJNZ1: |
|IL.opACC: |
IF (R.top # 0) OR (R.stk[0] # rax) THEN |
PushAll(0); |
GetRegA; |
pop(rax); |
DEC(R.pushed) |
END |
|IL.opJNZ: |
UnOp(reg1); |
test(reg1); |
jcc(jne, param1) |
|IL.opJZ: |
UnOp(reg1); |
test(reg1); |
jcc(je, param1) |
|IL.opJG: |
UnOp(reg1); |
test(reg1); |
jcc(jg, param1) |
|IL.opJNZ: |
|IL.opJE: |
UnOp(reg1); |
test(reg1); |
jcc(jne, param1); |
drop |
|IL.opJZ: |
|IL.opJNE: |
UnOp(reg1); |
test(reg1); |
jcc(je, param1); |
1370,11 → 1388,11 |
cmprc(reg1, 64); |
jcc(jb, L); |
xor(reg1, reg1); |
X86.jmp(label); |
jmp(label); |
X86.SetLabel(L); |
Rex(reg2, reg1); |
OutByte3(0FH, 0A3H, 0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); (* bt reg2, reg1 *) |
X86.setcc(setc, reg1); |
setcc(setc, reg1); |
andrc(reg1, 1); |
X86.SetLabel(label); |
drop |
1384,19 → 1402,19 |
Rex(reg1, 0); |
OutByte2(0FH, 0BAH); (* bt reg1, param2 *) |
OutByte2(0E0H + reg1 MOD 8, param2); |
X86.setcc(setc, reg1); |
setcc(setc, reg1); |
andrc(reg1, 1) |
|IL.opNOT: |
UnOp(reg1); |
test(reg1); |
X86.setcc(sete, reg1); |
setcc(sete, reg1); |
andrc(reg1, 1) |
|IL.opORD: |
UnOp(reg1); |
test(reg1); |
X86.setcc(setne, reg1); |
setcc(setne, reg1); |
andrc(reg1, 1) |
|IL.opABS: |
1421,9 → 1439,9 |
X86.SetLabel(label); |
cmprr(reg1, reg2); |
IF opcode = IL.opEQB THEN |
X86.setcc(sete, reg1) |
setcc(sete, reg1) |
ELSE |
X86.setcc(setne, reg1) |
setcc(setne, reg1) |
END; |
andrc(reg1, 1) |
1435,7 → 1453,7 |
UnOp(reg1); |
xorrc(reg1, param2) |
|IL.opADDSC: |
|IL.opADDSL, IL.opADDSR: |
UnOp(reg1); |
orrc(reg1, param2) |
1670,18 → 1688,19 |
|IL.opSUBR, IL.opSUBL: |
UnOp(reg1); |
IF param2 = 1 THEN |
n := param2; |
IF n = 1 THEN |
decr(reg1) |
ELSIF param2 = -1 THEN |
ELSIF n = -1 THEN |
incr(reg1) |
ELSIF param2 # 0 THEN |
subrc(reg1, param2) |
ELSIF n # 0 THEN |
subrc(reg1, n) |
END; |
IF opcode = IL.opSUBL THEN |
neg(reg1) |
END |
|IL.opADDC: |
|IL.opADDL, IL.opADDR: |
IF (param2 # 0) & ~isLong(param2) THEN |
UnOp(reg1); |
next := cmd.next(COMMAND); |
1832,7 → 1851,7 |
|IL.opADDS: |
BinOp(reg1, reg2); |
_or(reg1, reg2); |
or(reg1, reg2); |
drop |
|IL.opSUBS: |
1841,7 → 1860,7 |
and(reg1, reg2); |
drop |
|IL.opNOP, IL.opAND, IL.opOR: |
|IL.opNOP: |
|IL.opSWITCH: |
UnOp(reg1); |
1989,8 → 2008,8 |
reg1 := GetAnyReg(); |
CASE opcode OF |
|IL.opEQP, IL.opEQIP: X86.setcc(sete, reg1) |
|IL.opNEP, IL.opNEIP: X86.setcc(setne, reg1) |
|IL.opEQP, IL.opEQIP: setcc(sete, reg1) |
|IL.opNEP, IL.opNEIP: setcc(setne, reg1) |
END; |
andrc(reg1, 1) |
2026,8 → 2045,9 |
drop |
|IL.opCLEANUP: |
IF param2 # 0 THEN |
addrc(rsp, param2 * 8) |
n := param2 * 8; |
IF n # 0 THEN |
addrc(rsp, n) |
END |
|IL.opPOPSP: |
2036,14 → 2056,10 |
|IL.opLOADF: |
UnOp(reg1); |
INC(xmm); |
IF xmm > MAX_XMM THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
END; |
movsdrm(xmm, reg1, 0); |
drop |
|IL.opPUSHF: |
ASSERT(xmm >= 0); |
subrc(rsp, 8); |
movsdmr(rsp, 0, xmm); |
DEC(xmm) |
2051,78 → 2067,66 |
|IL.opCONSTF: |
float := cmd.float; |
INC(xmm); |
IF xmm > MAX_XMM THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
END; |
(* movsd xmm, qword ptr [rip + Numbers_Offs + Numbers_Count * 8 + DATA] *) |
OutByte(0F2H); |
IF xmm >= 8 THEN |
OutByte(44H) |
END; |
OutByte3(0FH, 10H, 05H + 8 * (xmm MOD 8)); |
X86.Reloc(sDATA, Numbers_Offs + Numbers_Count * 8); |
reg1 := GetAnyReg(); |
lea(reg1, Numbers_Offs + Numbers_Count * 8, sDATA); |
movsdrm(xmm, reg1, 0); |
drop; |
NewNumber(UTILS.splitf(float, a, b)) |
|IL.opSAVEF, IL.opSAVEFI: |
ASSERT(xmm >= 0); |
UnOp(reg1); |
movsdmr(reg1, 0, xmm); |
DEC(xmm); |
drop |
|IL.opADDF: |
ASSERT(xmm >= 1); |
|IL.opADDF, IL.opADDFI: |
opxx(58H, xmm - 1, xmm); |
DEC(xmm) |
|IL.opSUBF: |
ASSERT(xmm >= 1); |
opxx(5CH, xmm - 1, xmm); |
DEC(xmm) |
|IL.opSUBFI: |
ASSERT(xmm >= 1); |
opxx(5CH, xmm, xmm - 1); |
opxx(10H, xmm - 1, xmm); |
DEC(xmm) |
|IL.opMULF: |
ASSERT(xmm >= 1); |
opxx(59H, xmm - 1, xmm); |
DEC(xmm) |
|IL.opDIVF: |
ASSERT(xmm >= 1); |
opxx(5EH, xmm - 1, xmm); |
DEC(xmm) |
|IL.opDIVFI: |
ASSERT(xmm >= 1); |
opxx(5EH, xmm, xmm - 1); |
opxx(10H, xmm - 1, xmm); |
DEC(xmm) |
|IL.opFABS, IL.opUMINF: (* andpd/xorpd xmm, xmmword[rip + Numbers_Offs + (16) + DATA] *) |
ASSERT(xmm >= 0); |
OutByte(66H); |
IF xmm >= 8 THEN |
OutByte(44H) |
END; |
OutByte3(0FH, 54H + 3 * ORD(opcode = IL.opUMINF), 05H + (xmm MOD 8) * 8); |
X86.Reloc(sDATA, Numbers_Offs + 16 * ORD(opcode = IL.opFABS)) |
|IL.opUMINF: |
reg1 := GetAnyReg(); |
lea(reg1, Numbers_Offs, sDATA); |
OutByte3(66H, 40H + reg1 DIV 8 + (xmm DIV 8) * 4, 0FH); (* xorpd xmm, xmmword[reg1] *) |
OutByte2(57H, reg1 MOD 8 + (xmm MOD 8) * 8); |
drop |
|IL.opFABS: |
reg1 := GetAnyReg(); |
lea(reg1, Numbers_Offs + 16, sDATA); |
OutByte3(66H, 40H + reg1 DIV 8 + (xmm DIV 8) * 4, 0FH); (* andpd xmm, xmmword[reg1] *) |
OutByte2(54H, reg1 MOD 8 + (xmm MOD 8) * 8); |
drop |
|IL.opFLT: |
UnOp(reg1); |
INC(xmm); |
IF xmm > MAX_XMM THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
END; |
OutByte(0F2H); Rex(reg1, xmm); OutByte(0FH); (* cvtsi2sd xmm, reg1 *) |
OutByte2(2AH, 0C0H + (xmm MOD 8) * 8 + reg1 MOD 8); |
drop |
|IL.opFLOOR: |
ASSERT(xmm >= 0); |
reg1 := GetAnyReg(); |
subrc(rsp, 8); |
OutByte3(00FH, 0AEH, 05CH); OutByte2(024H, 004H); (* stmxcsr dword[rsp+4]; *) |
2137,22 → 2141,15 |
DEC(xmm) |
|IL.opEQF .. IL.opGEF: |
ASSERT(xmm >= 1); |
fcmp(opcode, xmm); |
DEC(xmm, 2) |
|IL.opINF: |
INC(xmm); |
IF xmm > MAX_XMM THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
END; |
(* movsd xmm, qword ptr [rip + Numbers_Offs + 32 + DATA] *) |
OutByte(0F2H); |
IF xmm >= 8 THEN |
OutByte(44H) |
END; |
OutByte3(0FH, 10H, 05H + 8 * (xmm MOD 8)); |
X86.Reloc(sDATA, Numbers_Offs + 32) |
reg1 := GetAnyReg(); |
lea(reg1, Numbers_Offs + 32, sDATA); |
movsdrm(xmm, reg1, 0); |
drop |
|IL.opPACK, IL.opPACKC: |
IF opcode = IL.opPACK THEN |
2178,7 → 2175,7 |
and(reg2, reg1); |
pop(reg1); |
_or(reg2, reg1); |
or(reg2, reg1); |
pop(reg1); |
movmr(reg1, 0, reg2); |
drop; |
2221,7 → 2218,7 |
push(reg2); |
lea(reg2, Numbers_Offs + 48, sDATA); (* {52..61} *) |
movrm(reg2, reg2, 0); |
_or(reg1, reg2); |
or(reg1, reg2); |
pop(reg2); |
Rex(reg1, 0); |
2251,20 → 2248,26 |
END |
|IL.opGLOAD64_PARAM: |
OutByte2(0FFH, 35H); (* push qword[rip + param2 + BSS] *) |
X86.Reloc(sBSS, param2) |
reg2 := GetAnyReg(); |
lea(reg2, param2, sBSS); |
movrm(reg2, reg2, 0); |
push(reg2); |
drop |
|IL.opCONST_PARAM: |
pushc(param2) |
|IL.opGLOAD32_PARAM, IL.opLOAD32_PARAM: |
IF opcode = IL.opGLOAD32_PARAM THEN |
|IL.opGLOAD32_PARAM: |
reg1 := GetAnyReg(); |
lea(reg1, param2, sBSS) |
ELSE |
UnOp(reg1) |
END; |
xor(reg1, reg1); |
lea(reg1, param2, sBSS); |
movrm32(reg1, reg1, 0); |
push(reg1); |
drop |
|IL.opLOAD32_PARAM: |
UnOp(reg1); |
movrm32(reg1, reg1, 0); |
shiftrc(shl, reg1, 32); |
shiftrc(shr, reg1, 32); |
push(reg1); |
2272,6 → 2275,7 |
|IL.opLLOAD32_PARAM: |
reg1 := GetAnyReg(); |
xor(reg1, reg1); |
reg2 := GetVarReg(param2); |
IF reg2 # -1 THEN |
mov(reg1, reg2) |
2278,8 → 2282,6 |
ELSE |
movrm32(reg1, rbp, param2 * 8) |
END; |
shiftrc(shl, reg1, 32); |
shiftrc(shr, reg1, 32); |
push(reg1); |
drop |
2311,10 → 2313,12 |
drop; |
drop |
ELSE |
(* mov qword[rip + param1 - 4 + BSS], param2 *) |
OutByte3(48H, 0C7H, 05H); |
X86.Reloc(sBSS, param1 - 4); |
OutInt(param2) |
reg2 := GetAnyReg(); |
lea(reg2, param1, sBSS); |
Rex(reg2, 0); |
OutByte2(0C7H, reg2 MOD 8); (* mov qword[reg2], param2 *) |
OutInt(param2); |
drop |
END |
|IL.opLADR_SAVE: |
2427,7 → 2431,7 |
oprr2(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), reg2, reg1) (* bts/btr reg2, reg1 *) |
ELSE |
n := param2 * 8; |
OutByte2(73H, 5 + 3 * ORD(~X86.isByte(n))); (* jnb L *) |
OutByte2(73H, 5 + 3 * ORD(~isByte(n))); (* jnb L *) |
Rex(0, reg1); |
OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8)); |
OutIntByte(n) (* bts/btr qword[rbp+n], reg1 *) |
2449,9 → 2453,6 |
OutByte(param2) |
END |
|IL.opFNAME: |
fname := cmd(IL.FNAMECMD).fname |
|IL.opLOOP, IL.opENDLOOP: |
END; |
2484,9 → 2485,10 |
push(rcx); |
CallRTL(IL._dllentry); |
test(rax); |
jcc(je, dllret); |
pushc(0) |
ELSIF target = TARGETS.Linux64 THEN |
jcc(je, dllret) |
END; |
IF target = TARGETS.Linux64 THEN |
push(rsp) |
ELSE |
pushc(0) |
2525,7 → 2527,7 |
exp: IL.EXPORT_PROC; |
PROCEDURE _import (imp: LISTS.LIST); |
PROCEDURE import (imp: LISTS.LIST); |
VAR |
lib: IL.IMPORT_LIB; |
proc: IL.IMPORT_PROC; |
2543,7 → 2545,7 |
lib := lib.next(IL.IMPORT_LIB) |
END |
END _import; |
END import; |
BEGIN |
2596,7 → 2598,7 |
exp := exp.next(IL.EXPORT_PROC) |
END; |
_import(IL.codes._import) |
import(IL.codes.import) |
END epilog; |
2629,7 → 2631,6 |
path, modname, ext: PATHS.PATH; |
BEGIN |
Xmm[0] := 0; |
tcount := CHL.Length(IL.codes.types); |
Win64RegPar[0] := rcx; |
/programs/develop/oberon07/Source/ARITH.ob07 |
---|
16,12 → 16,11 |
tBOOLEAN* = 4; tCHAR* = 5; tWCHAR* = 6; |
tSTRING* = 7; |
opEQ* = 0; opNE* = 1; opLT* = 2; opLE* = 3; opGT* = 4; opGE* = 5; |
opIN* = 6; opIS* = 7; |
TYPE |
RELATION* = ARRAY 3 OF CHAR; |
VALUE* = RECORD |
typ*: INTEGER; |
673,7 → 672,7 |
END equal; |
PROCEDURE relation* (VAR v: VALUE; v2: VALUE; op: INTEGER; VAR error: INTEGER); |
PROCEDURE relation* (VAR v: VALUE; v2: VALUE; operator: RELATION; VAR error: INTEGER); |
VAR |
res: BOOLEAN; |
682,34 → 681,36 |
res := FALSE; |
CASE op OF |
CASE operator[0] OF |
|opEQ: |
|"=": |
res := equal(v, v2, error) |
|opNE: |
|"#": |
res := ~equal(v, v2, error) |
|opLT: |
res := less(v, v2, error) |
|opLE: |
|"<": |
IF operator[1] = "=" THEN |
res := less(v, v2, error); |
IF error = 0 THEN |
res := equal(v, v2, error) OR res |
END |
ELSE |
res := less(v, v2, error) |
END |
|opGE: |
|">": |
IF operator[1] = "=" THEN |
res := ~less(v, v2, error) |
|opGT: |
ELSE |
res := less(v, v2, error); |
IF error = 0 THEN |
res := equal(v, v2, error) OR res |
END; |
res := ~res |
END |
|opIN: |
|"I": |
IF (v.typ = tINTEGER) & (v2.typ = tSET) THEN |
IF range(v, 0, UTILS.target.maxSet) THEN |
res := v.int IN v2.set |
761,20 → 762,6 |
END setInt; |
PROCEDURE concat* (VAR s: ARRAY OF CHAR; s1: ARRAY OF CHAR): BOOLEAN; |
VAR |
res: BOOLEAN; |
BEGIN |
res := LENGTH(s) + LENGTH(s1) < LEN(s); |
IF res THEN |
STRINGS.append(s, s1) |
END |
RETURN res |
END concat; |
PROCEDURE init; |
VAR |
i: INTEGER; |
/programs/develop/oberon07/Source/BIN.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2020, Anton Krotov |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
56,7 → 56,7 |
vmajor*, |
vminor*: WCHAR; |
modname*: INTEGER; |
_import*: CHL.BYTELIST; |
import*: CHL.BYTELIST; |
export*: CHL.BYTELIST; |
rel_list*: LISTS.LIST; |
imp_list*: LISTS.LIST; |
86,7 → 86,7 |
program.data := CHL.CreateByteList(); |
program.code := CHL.CreateByteList(); |
program._import := CHL.CreateByteList(); |
program.import := CHL.CreateByteList(); |
program.export := CHL.CreateByteList() |
RETURN program |
120,7 → 120,7 |
END PutData; |
PROCEDURE get32le* (_array: CHL.BYTELIST; idx: INTEGER): INTEGER; |
PROCEDURE get32le* (array: CHL.BYTELIST; idx: INTEGER): INTEGER; |
VAR |
i: INTEGER; |
x: INTEGER; |
129,7 → 129,7 |
x := 0; |
FOR i := 3 TO 0 BY -1 DO |
x := LSL(x, 8) + CHL.GetByte(_array, idx + i) |
x := LSL(x, 8) + CHL.GetByte(array, idx + i) |
END; |
IF UTILS.bit_depth = 64 THEN |
143,13 → 143,13 |
END get32le; |
PROCEDURE put32le* (_array: CHL.BYTELIST; idx: INTEGER; x: INTEGER); |
PROCEDURE put32le* (array: CHL.BYTELIST; idx: INTEGER; x: INTEGER); |
VAR |
i: INTEGER; |
BEGIN |
FOR i := 0 TO 3 DO |
CHL.SetByte(_array, idx + i, UTILS.Byte(x, i)) |
CHL.SetByte(array, idx + i, UTILS.Byte(x, i)) |
END |
END put32le; |
224,15 → 224,15 |
imp: IMPRT; |
BEGIN |
CHL.PushByte(program._import, 0); |
CHL.PushByte(program._import, 0); |
CHL.PushByte(program.import, 0); |
CHL.PushByte(program.import, 0); |
IF ODD(CHL.Length(program._import)) THEN |
CHL.PushByte(program._import, 0) |
IF ODD(CHL.Length(program.import)) THEN |
CHL.PushByte(program.import, 0) |
END; |
NEW(imp); |
imp.nameoffs := CHL.PushStr(program._import, name); |
imp.nameoffs := CHL.PushStr(program.import, name); |
imp.label := label; |
LISTS.push(program.imp_list, imp) |
END Import; |
285,18 → 285,19 |
PROCEDURE GetIProc* (program: PROGRAM; n: INTEGER): IMPRT; |
VAR |
_import, res: IMPRT; |
import: IMPRT; |
res: IMPRT; |
BEGIN |
_import := program.imp_list.first(IMPRT); |
import := program.imp_list.first(IMPRT); |
res := NIL; |
WHILE (_import # NIL) & (n >= 0) DO |
IF _import.label # 0 THEN |
res := _import; |
WHILE (import # NIL) & (n >= 0) DO |
IF import.label # 0 THEN |
res := import; |
DEC(n) |
END; |
_import := _import.next(IMPRT) |
import := import.next(IMPRT) |
END; |
ASSERT(n = -1) |
348,7 → 349,7 |
END fixup; |
PROCEDURE InitArray* (VAR _array: ARRAY OF BYTE; VAR idx: INTEGER; hex: ARRAY OF CHAR); |
PROCEDURE InitArray* (VAR array: ARRAY OF BYTE; VAR idx: INTEGER; hex: ARRAY OF CHAR); |
VAR |
i, k: INTEGER; |
374,7 → 375,7 |
k := k DIV 2; |
FOR i := 0 TO k - 1 DO |
_array[i + idx] := hexdgt(hex[2 * i]) * 16 + hexdgt(hex[2 * i + 1]) |
array[i + idx] := hexdgt(hex[2 * i]) * 16 + hexdgt(hex[2 * i + 1]) |
END; |
INC(idx, k) |
/programs/develop/oberon07/Source/CHUNKLISTS.ob07 |
---|
153,7 → 153,7 |
END GetStr; |
PROCEDURE WriteToFile* (list: BYTELIST); |
PROCEDURE WriteToFile* (file: WR.FILE; list: BYTELIST); |
VAR |
chunk: BYTECHUNK; |
160,7 → 160,7 |
BEGIN |
chunk := list.first(BYTECHUNK); |
WHILE chunk # NIL DO |
WR.Write(chunk.data, chunk.count); |
WR.Write(file, chunk.data, chunk.count); |
chunk := chunk.next(BYTECHUNK) |
END |
END WriteToFile; |
/programs/develop/oberon07/Source/Compiler.ob07 |
---|
8,7 → 8,7 |
MODULE Compiler; |
IMPORT ST := STATEMENTS, PARS, UTILS, PATHS, PROG, C := CONSOLE, |
ERRORS, STRINGS, WRITER, MSP430, THUMB, TARGETS, SCAN; |
ERRORS, STRINGS, WRITER, MSP430, THUMB, TARGETS; |
PROCEDURE keys (VAR options: PROG.OPTIONS; VAR out: PARS.PATH); |
15,7 → 15,7 |
VAR |
param: PARS.PATH; |
i, j: INTEGER; |
_end: BOOLEAN; |
end: BOOLEAN; |
value: INTEGER; |
minor, |
major: INTEGER; |
24,7 → 24,7 |
BEGIN |
out := ""; |
checking := options.checking; |
_end := FALSE; |
end := FALSE; |
i := 3; |
REPEAT |
UTILS.GetArg(i, param); |
113,19 → 113,11 |
DEC(i) |
END |
ELSIF param = "-lower" THEN |
options.lower := TRUE |
ELSIF param = "-pic" THEN |
options.pic := TRUE |
ELSIF param = "-def" THEN |
INC(i); |
UTILS.GetArg(i, param); |
SCAN.NewDef(param) |
ELSIF param = "" THEN |
_end := TRUE |
end := TRUE |
ELSE |
ERRORS.BadParam(param) |
132,7 → 124,7 |
END; |
INC(i) |
UNTIL _end; |
UNTIL end; |
options.checking := checking |
END keys; |
173,7 → 165,6 |
options.stack := 2; |
options.version := 65536; |
options.pic := FALSE; |
options.lower := FALSE; |
options.checking := ST.chkALL; |
PATHS.GetCurrentDirectory(app_path); |
212,8 → 203,6 |
C.StringLn(" -stk <size> set size of stack in Mbytes (Windows, Linux, KolibriOS)"); C.Ln; |
C.StringLn(" -nochk <'ptibcwra'> disable runtime checking (pointers, types, indexes,"); |
C.StringLn(" BYTE, CHR, WCHR)"); C.Ln; |
C.StringLn(" -lower allow lower case for keywords"); C.Ln; |
C.StringLn(" -def <identifier> define conditional compilation symbol"); C.Ln; |
C.StringLn(" -ver <major.minor> set version of program (KolibriOS DLL)"); C.Ln; |
C.StringLn(" -ram <size> set size of RAM in bytes (MSP430) or Kbytes (STM32)"); C.Ln; |
C.StringLn(" -rom <size> set size of ROM in bytes (MSP430) or Kbytes (STM32)"); C.Ln; |
237,8 → 226,6 |
ERRORS.Error(205) |
END; |
SCAN.NewDef(param); |
IF TARGETS.Select(param) THEN |
target := TARGETS.target |
ELSE |
/programs/develop/oberon07/Source/ELF.ob07 |
---|
1,13 → 1,13 |
(* |
BSD 2-Clause License |
Copyright (c) 2019-2020, Anton Krotov |
Copyright (c) 2019, Anton Krotov |
All rights reserved. |
*) |
MODULE ELF; |
IMPORT BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS, PE32, UTILS; |
IMPORT BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS; |
CONST |
85,6 → 85,9 |
END; |
FILE = WR.FILE; |
VAR |
dynamic: LISTS.LIST; |
94,38 → 97,75 |
hashtab, bucket, chain: CHL.INTLIST; |
PROCEDURE Write16 (w: WCHAR); |
PROCEDURE align (n, _align: INTEGER): INTEGER; |
BEGIN |
WR.Write16LE(ORD(w)) |
IF n MOD _align # 0 THEN |
n := n + _align - (n MOD _align) |
END |
RETURN n |
END align; |
PROCEDURE Write16 (file: FILE; w: WCHAR); |
BEGIN |
WR.Write16LE(file, ORD(w)) |
END Write16; |
PROCEDURE WritePH (ph: Elf32_Phdr); |
PROCEDURE WritePH (file: FILE; ph: Elf32_Phdr); |
BEGIN |
WR.Write32LE(ph.p_type); |
WR.Write32LE(ph.p_offset); |
WR.Write32LE(ph.p_vaddr); |
WR.Write32LE(ph.p_paddr); |
WR.Write32LE(ph.p_filesz); |
WR.Write32LE(ph.p_memsz); |
WR.Write32LE(ph.p_flags); |
WR.Write32LE(ph.p_align) |
WR.Write32LE(file, ph.p_type); |
WR.Write32LE(file, ph.p_offset); |
WR.Write32LE(file, ph.p_vaddr); |
WR.Write32LE(file, ph.p_paddr); |
WR.Write32LE(file, ph.p_filesz); |
WR.Write32LE(file, ph.p_memsz); |
WR.Write32LE(file, ph.p_flags); |
WR.Write32LE(file, ph.p_align) |
END WritePH; |
PROCEDURE WritePH64 (ph: Elf32_Phdr); |
PROCEDURE WritePH64 (file: FILE; ph: Elf32_Phdr); |
BEGIN |
WR.Write32LE(ph.p_type); |
WR.Write32LE(ph.p_flags); |
WR.Write64LE(ph.p_offset); |
WR.Write64LE(ph.p_vaddr); |
WR.Write64LE(ph.p_paddr); |
WR.Write64LE(ph.p_filesz); |
WR.Write64LE(ph.p_memsz); |
WR.Write64LE(ph.p_align) |
WR.Write32LE(file, ph.p_type); |
WR.Write32LE(file, ph.p_flags); |
WR.Write64LE(file, ph.p_offset); |
WR.Write64LE(file, ph.p_vaddr); |
WR.Write64LE(file, ph.p_paddr); |
WR.Write64LE(file, ph.p_filesz); |
WR.Write64LE(file, ph.p_memsz); |
WR.Write64LE(file, ph.p_align) |
END WritePH64; |
PROCEDURE fixup (program: BIN.PROGRAM; text, data, bss: INTEGER; amd64: BOOLEAN); |
VAR |
reloc: BIN.RELOC; |
code: CHL.BYTELIST; |
L, delta, delta0: INTEGER; |
BEGIN |
code := program.code; |
delta0 := 3 - 7 * ORD(amd64); |
reloc := program.rel_list.first(BIN.RELOC); |
WHILE reloc # NIL DO |
L := BIN.get32le(code, reloc.offset); |
delta := delta0 - reloc.offset - text; |
CASE reloc.opcode OF |
|BIN.PICDATA: BIN.put32le(code, reloc.offset, L + data + delta) |
|BIN.PICCODE: BIN.put32le(code, reloc.offset, BIN.GetLabel(program, L) + text + delta) |
|BIN.PICBSS: BIN.put32le(code, reloc.offset, L + bss + delta) |
END; |
reloc := reloc.next(BIN.RELOC) |
END |
END fixup; |
PROCEDURE NewDyn (tag, val: INTEGER); |
VAR |
dyn: Elf32_Dyn; |
231,12 → 271,14 |
ehdr: Elf32_Ehdr; |
phdr: ARRAY 16 OF Elf32_Phdr; |
i, BaseAdr, DynAdr, offset, pad, VA, symCount: INTEGER; |
i, BaseAdr, offset, pad, VA, symCount: INTEGER; |
SizeOf: RECORD header, code, data, bss: INTEGER END; |
Offset: RECORD symtab, reltab, hash, strtab: INTEGER END; |
Offset: RECORD symtab, reltab, hash, strtab, dyn: INTEGER END; |
File: FILE; |
Interpreter: ARRAY 40 OF CHAR; lenInterpreter: INTEGER; |
item: LISTS.ITEM; |
243,8 → 285,6 |
Name: ARRAY 2048 OF CHAR; |
Address: PE32.VIRTUAL_ADDR; |
BEGIN |
dynamic := LISTS.create(NIL); |
symtab := LISTS.create(NIL); |
391,12 → 431,12 |
Offset.hash := Offset.reltab + (8 + 16 * ORD(amd64)) * 2; |
Offset.strtab := Offset.hash + (symCount * 2 + 2) * 4; |
DynAdr := phdr[dyn].p_offset + BaseAdr; |
Offset.dyn := phdr[dyn].p_offset; |
item := LISTS.getidx(dynamic, 1); item(Elf32_Dyn).d_val := Offset.strtab + DynAdr; |
item := LISTS.getidx(dynamic, 3); item(Elf32_Dyn).d_val := Offset.symtab + DynAdr; |
item := LISTS.getidx(dynamic, 5); item(Elf32_Dyn).d_val := Offset.reltab + DynAdr; |
item := LISTS.getidx(dynamic, 8); item(Elf32_Dyn).d_val := Offset.hash + DynAdr; |
item := LISTS.getidx(dynamic, 1); item(Elf32_Dyn).d_val := Offset.strtab + Offset.dyn + BaseAdr; |
item := LISTS.getidx(dynamic, 3); item(Elf32_Dyn).d_val := Offset.symtab + Offset.dyn + BaseAdr; |
item := LISTS.getidx(dynamic, 5); item(Elf32_Dyn).d_val := Offset.reltab + Offset.dyn + BaseAdr; |
item := LISTS.getidx(dynamic, 8); item(Elf32_Dyn).d_val := Offset.hash + Offset.dyn + BaseAdr; |
phdr[dyn].p_filesz := Offset.strtab + CHL.Length(strtab) + 8 + 8 * ORD(amd64); |
phdr[dyn].p_memsz := phdr[dyn].p_filesz; |
410,12 → 450,12 |
phdr[header].p_offset := offset; |
phdr[header].p_vaddr := BaseAdr; |
phdr[header].p_paddr := BaseAdr; |
phdr[header].p_filesz := SizeOf.header + lenInterpreter + phdr[dyn].p_filesz; |
phdr[header].p_filesz := 244 + 156 * ORD(amd64) + lenInterpreter + phdr[dyn].p_filesz; |
phdr[header].p_memsz := phdr[header].p_filesz; |
phdr[header].p_flags := PF_R + PF_W; |
phdr[header].p_align := 1000H; |
INC(offset, phdr[header].p_filesz); |
offset := offset + phdr[header].p_filesz; |
VA := BaseAdr + offset + 1000H; |
phdr[text].p_type := 1; |
429,7 → 469,7 |
ehdr.e_entry := phdr[text].p_vaddr; |
INC(offset, phdr[text].p_filesz); |
offset := offset + phdr[text].p_filesz; |
VA := BaseAdr + offset + 2000H; |
pad := (16 - VA MOD 16) MOD 16; |
442,7 → 482,7 |
phdr[data].p_flags := PF_R + PF_W; |
phdr[data].p_align := 1000H; |
INC(offset, phdr[data].p_filesz); |
offset := offset + phdr[data].p_filesz; |
VA := BaseAdr + offset + 3000H; |
phdr[bss].p_type := 1; |
454,13 → 494,8 |
phdr[bss].p_flags := PF_R + PF_W; |
phdr[bss].p_align := 1000H; |
Address.Code := ehdr.e_entry; |
Address.Data := phdr[data].p_vaddr + pad; |
Address.Bss := WR.align(phdr[bss].p_vaddr, 16); |
Address.Import := 0; |
fixup(program, ehdr.e_entry, phdr[data].p_vaddr + pad, align(phdr[bss].p_vaddr, 16), amd64); |
PE32.fixup(program, Address, amd64); |
item := symtab.first; |
WHILE item # NIL DO |
IF item(Elf32_Sym).value # 0 THEN |
474,137 → 509,146 |
item := LISTS.getidx(dynamic, 11); item(Elf32_Dyn).d_val := BIN.GetLabel(program, fini) + ehdr.e_entry |
END; |
WR.Create(FileName); |
File := WR.Create(FileName); |
FOR i := 0 TO EI_NIDENT - 1 DO |
WR.WriteByte(ehdr.e_ident[i]) |
WR.WriteByte(File, ehdr.e_ident[i]) |
END; |
Write16(ehdr.e_type); |
Write16(ehdr.e_machine); |
Write16(File, ehdr.e_type); |
Write16(File, ehdr.e_machine); |
WR.Write32LE(ehdr.e_version); |
WR.Write32LE(File, ehdr.e_version); |
IF amd64 THEN |
WR.Write64LE(ehdr.e_entry); |
WR.Write64LE(ehdr.e_phoff); |
WR.Write64LE(ehdr.e_shoff) |
WR.Write64LE(File, ehdr.e_entry); |
WR.Write64LE(File, ehdr.e_phoff); |
WR.Write64LE(File, ehdr.e_shoff) |
ELSE |
WR.Write32LE(ehdr.e_entry); |
WR.Write32LE(ehdr.e_phoff); |
WR.Write32LE(ehdr.e_shoff) |
WR.Write32LE(File, ehdr.e_entry); |
WR.Write32LE(File, ehdr.e_phoff); |
WR.Write32LE(File, ehdr.e_shoff) |
END; |
WR.Write32LE(ehdr.e_flags); |
WR.Write32LE(File, ehdr.e_flags); |
Write16(ehdr.e_ehsize); |
Write16(ehdr.e_phentsize); |
Write16(ehdr.e_phnum); |
Write16(ehdr.e_shentsize); |
Write16(ehdr.e_shnum); |
Write16(ehdr.e_shstrndx); |
Write16(File, ehdr.e_ehsize); |
Write16(File, ehdr.e_phentsize); |
Write16(File, ehdr.e_phnum); |
Write16(File, ehdr.e_shentsize); |
Write16(File, ehdr.e_shnum); |
Write16(File, ehdr.e_shstrndx); |
IF amd64 THEN |
WritePH64(phdr[interp]); |
WritePH64(phdr[dyn]); |
WritePH64(phdr[header]); |
WritePH64(phdr[text]); |
WritePH64(phdr[data]); |
WritePH64(phdr[bss]) |
WritePH64(File, phdr[interp]); |
WritePH64(File, phdr[dyn]); |
WritePH64(File, phdr[header]); |
WritePH64(File, phdr[text]); |
WritePH64(File, phdr[data]); |
WritePH64(File, phdr[bss]) |
ELSE |
WritePH(phdr[interp]); |
WritePH(phdr[dyn]); |
WritePH(phdr[header]); |
WritePH(phdr[text]); |
WritePH(phdr[data]); |
WritePH(phdr[bss]) |
WritePH(File, phdr[interp]); |
WritePH(File, phdr[dyn]); |
WritePH(File, phdr[header]); |
WritePH(File, phdr[text]); |
WritePH(File, phdr[data]); |
WritePH(File, phdr[bss]) |
END; |
FOR i := 0 TO lenInterpreter - 1 DO |
WR.WriteByte(ORD(Interpreter[i])) |
WR.WriteByte(File, ORD(Interpreter[i])) |
END; |
i := 0; |
IF amd64 THEN |
item := dynamic.first; |
WHILE item # NIL DO |
WR.Write64LE(item(Elf32_Dyn).d_tag); |
WR.Write64LE(item(Elf32_Dyn).d_val); |
WR.Write64LE(File, item(Elf32_Dyn).d_tag); |
WR.Write64LE(File, item(Elf32_Dyn).d_val); |
item := item.next |
END; |
item := symtab.first; |
WHILE item # NIL DO |
WR.Write32LE(item(Elf32_Sym).name); |
WR.WriteByte(ORD(item(Elf32_Sym).info)); |
WR.WriteByte(ORD(item(Elf32_Sym).other)); |
Write16(item(Elf32_Sym).shndx); |
WR.Write64LE(item(Elf32_Sym).value); |
WR.Write64LE(item(Elf32_Sym).size); |
WR.Write32LE(File, item(Elf32_Sym).name); |
WR.WriteByte(File, ORD(item(Elf32_Sym).info)); |
WR.WriteByte(File, ORD(item(Elf32_Sym).other)); |
Write16(File, item(Elf32_Sym).shndx); |
WR.Write64LE(File, item(Elf32_Sym).value); |
WR.Write64LE(File, item(Elf32_Sym).size); |
item := item.next |
END; |
WR.Write64LE(phdr[dyn].p_filesz + DynAdr - 16); |
WR.Write32LE(1); |
WR.Write32LE(1); |
WR.Write64LE(0); |
WR.Write64LE(phdr[dyn].p_filesz + DynAdr - 8); |
WR.Write32LE(1); |
WR.Write32LE(2); |
WR.Write64LE(0) |
WR.Write64LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 16); |
WR.Write32LE(File, 1); |
WR.Write32LE(File, 1); |
WR.Write64LE(File, 0); |
WR.Write64LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 8); |
WR.Write32LE(File, 1); |
WR.Write32LE(File, 2); |
WR.Write64LE(File, 0); |
WR.Write32LE(File, symCount); |
WR.Write32LE(File, symCount); |
FOR i := 0 TO symCount - 1 DO |
WR.Write32LE(File, CHL.GetInt(bucket, i)) |
END; |
FOR i := 0 TO symCount - 1 DO |
WR.Write32LE(File, CHL.GetInt(chain, i)) |
END; |
CHL.WriteToFile(File, strtab); |
WR.Write64LE(File, 0); |
WR.Write64LE(File, 0) |
ELSE |
item := dynamic.first; |
WHILE item # NIL DO |
WR.Write32LE(item(Elf32_Dyn).d_tag); |
WR.Write32LE(item(Elf32_Dyn).d_val); |
WR.Write32LE(File, item(Elf32_Dyn).d_tag); |
WR.Write32LE(File, item(Elf32_Dyn).d_val); |
item := item.next |
END; |
item := symtab.first; |
WHILE item # NIL DO |
WR.Write32LE(item(Elf32_Sym).name); |
WR.Write32LE(item(Elf32_Sym).value); |
WR.Write32LE(item(Elf32_Sym).size); |
WR.WriteByte(ORD(item(Elf32_Sym).info)); |
WR.WriteByte(ORD(item(Elf32_Sym).other)); |
Write16(item(Elf32_Sym).shndx); |
WR.Write32LE(File, item(Elf32_Sym).name); |
WR.Write32LE(File, item(Elf32_Sym).value); |
WR.Write32LE(File, item(Elf32_Sym).size); |
WR.WriteByte(File, ORD(item(Elf32_Sym).info)); |
WR.WriteByte(File, ORD(item(Elf32_Sym).other)); |
Write16(File, item(Elf32_Sym).shndx); |
item := item.next |
END; |
WR.Write32LE(phdr[dyn].p_filesz + DynAdr - 8); |
WR.Write32LE(00000101H); |
WR.Write32LE(phdr[dyn].p_filesz + DynAdr - 4); |
WR.Write32LE(00000201H) |
WR.Write32LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 8); |
WR.Write32LE(File, 00000101H); |
WR.Write32LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 4); |
WR.Write32LE(File, 00000201H); |
END; |
WR.Write32LE(File, symCount); |
WR.Write32LE(File, symCount); |
WR.Write32LE(symCount); |
WR.Write32LE(symCount); |
FOR i := 0 TO symCount - 1 DO |
WR.Write32LE(CHL.GetInt(bucket, i)) |
WR.Write32LE(File, CHL.GetInt(bucket, i)) |
END; |
FOR i := 0 TO symCount - 1 DO |
WR.Write32LE(CHL.GetInt(chain, i)) |
WR.Write32LE(File, CHL.GetInt(chain, i)) |
END; |
CHL.WriteToFile(strtab); |
CHL.WriteToFile(File, strtab); |
WR.Write32LE(File, 0); |
WR.Write32LE(File, 0) |
IF amd64 THEN |
WR.Write64LE(0); |
WR.Write64LE(0) |
ELSE |
WR.Write32LE(0); |
WR.Write32LE(0) |
END; |
CHL.WriteToFile(program.code); |
CHL.WriteToFile(File, program.code); |
WHILE pad > 0 DO |
WR.WriteByte(0); |
WR.WriteByte(File, 0); |
DEC(pad) |
END; |
CHL.WriteToFile(program.data); |
WR.Close; |
UTILS.chmod(FileName) |
CHL.WriteToFile(File, program.data); |
WR.Close(File) |
END write; |
/programs/develop/oberon07/Source/ERRORS.ob07 |
---|
144,9 → 144,7 |
|114: str := "identifiers 'lib_init' and 'version' are reserved" |
|115: str := "recursive constant definition" |
|116: str := "procedure too deep nested" |
|117: str := "string expected" |
|118: str := "'$END', '$ELSE' or '$ELSIF' without '$IF'" |
|119: str := "'$IF', '$ELSIF', '$ELSE' or '$END' expected" |
|120: str := "too many formal parameters" |
|121: str := "multiply defined handler" |
|122: str := "bad divisor" |
212,7 → 210,6 |
|205: Error1("not enough parameters") |
|206: Error1("bad parameter <target>") |
|207: Error3('inputfile name extension must be "', UTILS.FILE_EXT, '"') |
|208: Error1("not enough RAM") |
END |
END Error; |
/programs/develop/oberon07/Source/FILES.ob07 |
---|
17,8 → 17,10 |
ptr: INTEGER; |
buffer: ARRAY 64*1024 OF BYTE; |
count: INTEGER |
count: INTEGER; |
chksum*: INTEGER |
END; |
VAR |
83,7 → 85,8 |
IF ptr > 0 THEN |
file := NewFile(); |
file.ptr := ptr; |
file.count := 0 |
file.count := 0; |
file.chksum := 0 |
ELSE |
file := NIL |
END |
/programs/develop/oberon07/Source/HEX.ob07 |
---|
7,48 → 7,46 |
MODULE HEX; |
IMPORT WRITER, CHL := CHUNKLISTS, UTILS; |
IMPORT FILES, WRITER, CHL := CHUNKLISTS; |
VAR |
PROCEDURE hexdgt (n: BYTE): BYTE; |
BEGIN |
IF n < 10 THEN |
n := n + ORD("0") |
ELSE |
n := n - 10 + ORD("A") |
END |
chksum: INTEGER; |
RETURN n |
END hexdgt; |
PROCEDURE Byte (byte: BYTE); |
PROCEDURE Byte (file: FILES.FILE; byte: BYTE); |
BEGIN |
WRITER.WriteByte(UTILS.hexdgt(byte DIV 16)); |
WRITER.WriteByte(UTILS.hexdgt(byte MOD 16)); |
INC(chksum, byte) |
WRITER.WriteByte(file, hexdgt(byte DIV 16)); |
WRITER.WriteByte(file, hexdgt(byte MOD 16)); |
INC(file.chksum, byte); |
END Byte; |
PROCEDURE Byte4 (a, b, c, d: BYTE); |
PROCEDURE NewLine (file: FILES.FILE); |
BEGIN |
Byte(a); |
Byte(b); |
Byte(c); |
Byte(d) |
END Byte4; |
PROCEDURE NewLine; |
BEGIN |
Byte((-chksum) MOD 256); |
chksum := 0; |
WRITER.WriteByte(0DH); |
WRITER.WriteByte(0AH) |
Byte(file, (-file.chksum) MOD 256); |
file.chksum := 0; |
WRITER.WriteByte(file, 0DH); |
WRITER.WriteByte(file, 0AH) |
END NewLine; |
PROCEDURE StartCode; |
PROCEDURE StartCode (file: FILES.FILE); |
BEGIN |
WRITER.WriteByte(ORD(":")); |
chksum := 0 |
WRITER.WriteByte(file, ORD(":")); |
file.chksum := 0 |
END StartCode; |
PROCEDURE Data* (mem: ARRAY OF BYTE; idx, cnt: INTEGER); |
PROCEDURE Data* (file: FILES.FILE; mem: ARRAY OF BYTE; idx, cnt: INTEGER); |
VAR |
i, len: INTEGER; |
55,62 → 53,74 |
BEGIN |
WHILE cnt > 0 DO |
len := MIN(cnt, 16); |
StartCode; |
Byte4(len, idx DIV 256, idx MOD 256, 0); |
StartCode(file); |
Byte(file, len); |
Byte(file, idx DIV 256); |
Byte(file, idx MOD 256); |
Byte(file, 0); |
FOR i := 1 TO len DO |
Byte(mem[idx]); |
Byte(file, mem[idx]); |
INC(idx) |
END; |
DEC(cnt, len); |
NewLine |
NewLine(file) |
END |
END Data; |
PROCEDURE ExtLA* (LA: INTEGER); |
PROCEDURE ExtLA* (file: FILES.FILE; LA: INTEGER); |
BEGIN |
ASSERT((0 <= LA) & (LA <= 0FFFFH)); |
StartCode; |
Byte4(2, 0, 0, 4); |
Byte(LA DIV 256); |
Byte(LA MOD 256); |
NewLine |
StartCode(file); |
Byte(file, 2); |
Byte(file, 0); |
Byte(file, 0); |
Byte(file, 4); |
Byte(file, LA DIV 256); |
Byte(file, LA MOD 256); |
NewLine(file) |
END ExtLA; |
PROCEDURE Data2* (mem: CHL.BYTELIST; idx, cnt, LA: INTEGER); |
PROCEDURE Data2* (file: FILES.FILE; mem: CHL.BYTELIST; idx, cnt, LA: INTEGER); |
VAR |
i, len, offset: INTEGER; |
BEGIN |
ExtLA(LA); |
ExtLA(file, LA); |
offset := 0; |
WHILE cnt > 0 DO |
ASSERT(offset <= 65536); |
IF offset = 65536 THEN |
INC(LA); |
ExtLA(LA); |
ExtLA(file, LA); |
offset := 0 |
END; |
len := MIN(cnt, 16); |
StartCode; |
Byte4(len, offset DIV 256, offset MOD 256, 0); |
StartCode(file); |
Byte(file, len); |
Byte(file, offset DIV 256); |
Byte(file, offset MOD 256); |
Byte(file, 0); |
FOR i := 1 TO len DO |
Byte(CHL.GetByte(mem, idx)); |
Byte(file, CHL.GetByte(mem, idx)); |
INC(idx); |
INC(offset) |
END; |
DEC(cnt, len); |
NewLine |
NewLine(file) |
END |
END Data2; |
PROCEDURE End*; |
PROCEDURE End* (file: FILES.FILE); |
BEGIN |
StartCode; |
Byte4(0, 0, 0, 1); |
NewLine |
StartCode(file); |
Byte(file, 0); |
Byte(file, 0); |
Byte(file, 0); |
Byte(file, 1); |
NewLine(file) |
END End; |
/programs/develop/oberon07/Source/IL.ob07 |
---|
7,11 → 7,14 |
MODULE IL; |
IMPORT LISTS, SCAN, STRINGS, CHL := CHUNKLISTS, C := COLLECTIONS, TARGETS, PATHS; |
IMPORT LISTS, SCAN, STRINGS, CHL := CHUNKLISTS, C := COLLECTIONS, TARGETS; |
CONST |
little_endian* = 0; |
big_endian* = 1; |
call_stack* = 0; |
call_win64* = 1; |
call_sysv* = 2; |
19,7 → 22,7 |
opJMP* = 0; opLABEL* = 1; opCOPYS* = 2; opGADR* = 3; opCONST* = 4; opLLOAD32* = 5; |
opCOPYA* = 6; opCASET* = 7; opMULC* = 8; opMUL* = 9; opDIV* = 10; opMOD* = 11; |
opDIVL* = 12; opMODL* = 13; opDIVR* = 14; opMODR* = 15; opUMINUS* = 16; |
opADD* = 17; opSUB* = 18; opONERR* = 19; opSUBL* = 20; opADDC* = 21; opSUBR* = 22; |
opADD* = 17; opSUB* = 18; opADDL* = 19; opSUBL* = 20; opADDR* = 21; opSUBR* = 22; |
opSAVE* = 23; opSAVEC* = 24; opSAVE8* = 25; opSAVE8C* = 26; opCHKBYTE* = 27; opDROP* = 28; |
opNOT* = 29; |
31,14 → 34,14 |
opVLOAD32* = 60; opGLOAD32* = 61; |
opJZ* = 62; opJNZ* = 63; |
opJNE* = 62; opJE* = 63; |
opSAVE32* = 64; opLLOAD8* = 65; |
opCONSTF* = 66; opLOADF* = 67; opSAVEF* = 68; opMULF* = 69; opDIVF* = 70; opDIVFI* = 71; |
opUMINF* = 72; opSAVEFI* = 73; opSUBFI* = 74; opADDF* = 75; opSUBF* = 76; |
opUMINF* = 72; opADDFI* = 73; opSUBFI* = 74; opADDF* = 75; opSUBF* = 76; |
opJNZ1* = 77; opJG* = 78; |
opACC* = 77; opJG* = 78; |
opINCCB* = 79; opDECCB* = 80; opINCB* = 81; opDECB* = 82; |
opCASEL* = 83; opCASER* = 84; opCASELR* = 85; |
52,7 → 55,7 |
opSBOOL* = 100; opSBOOLC* = 101; opNOP* = 102; |
opMULS* = 103; opMULSC* = 104; opDIVS* = 105; opDIVSC* = 106; |
opADDS* = 107; opSUBS* = 108; opERR* = 109; opSUBSL* = 110; opADDSC* = 111; opSUBSR* = 112; |
opADDS* = 107; opSUBS* = 108; opADDSL* = 109; opSUBSL* = 110; opADDSR* = 111; opSUBSR* = 112; |
opUMINS* = 113; opIN* = 114; opINL* = 115; opINR* = 116; |
opRSET* = 117; opRSETL* = 118; opRSETR* = 119; opRSET1* = 120; opLENGTH* = 121; |
62,26 → 65,27 |
opPACK* = 134; opPACKC* = 135; opUNPK* = 136; opCOPY* = 137; opENTER* = 138; opLEAVE* = 139; |
opCALL* = 140; opSAVEP* = 141; opCALLP* = 142; opEQP* = 143; opNEP* = 144; opLEAVER* = 145; |
opGET* = 146; opSAVE16* = 147; opABS* = 148; opFABS* = 149; opFLOOR* = 150; opFLT* = 151; |
opGETC* = 152; opORD* = 153; opASR* = 154; opLSL* = 155; opROR* = 156; |
opORD* = 153; opASR* = 154; opLSL* = 155; opROR* = 156; |
opASR1* = 157; opLSL1* = 158; opROR1* = 159; opASR2* = 160; opLSL2* = 161; opROR2* = 162; |
opPUSHP* = 163; opLADR* = 164; opTYPEGP* = 165; opIS* = 166; opPUSHF* = 167; opVADR* = 168; |
opPUSHT* = 169; opTYPEGR* = 170; opISREC* = 171; opCHKIDX* = 172; opPARAM* = 173; |
opCHKIDX2* = 174; opLEN* = 175; opROT* = 176; opSAVES* = 177; opSADR* = 178; opLENGTHW* = 179; |
opCHKIDX2* = 174; opLEN* = 175; opROT* = 176; opSAVES* = 177; opSADR* = 178; opERR* = 179; |
opCHR* = 180; opENDSW* = 181; opLEAVEF* = 182; opCLEANUP* = 183; opMOVE* = 184; |
opLSR* = 185; opLSR1* = 186; opLSR2* = 187; |
opMIN* = 188; opMINC* = 189; opMAX* = 190; opMAXC* = 191; opSYSVALIGN16* = 192; |
opEQB* = 193; opNEB* = 194; opINF* = 195; opWIN64ALIGN16* = 196; opVLOAD8* = 197; opGLOAD8* = 198; |
opMIN* = 188; opMINC* = 189; opMAX* = 190; opMAXC* = 191; opJNZ* = 192; |
opEQB* = 193; opNEB* = 194; opINF* = 195; opJZ* = 196; opVLOAD8* = 197; opGLOAD8* = 198; |
opLLOAD16* = 199; opVLOAD16* = 200; opGLOAD16* = 201; |
opLOAD64* = 202; opLLOAD64* = 203; opVLOAD64* = 204; opGLOAD64* = 205; opSAVE64* = 206; |
opTYPEGD* = 207; opCALLI* = 208; opPUSHIP* = 209; opSAVEIP* = 210; opEQIP* = 211; opNEIP* = 212; |
opSAVE16C* = 213; opWCHR* = 214; opHANDLER* = 215; |
opSAVE16C* = 213; opWCHR* = 214; opGETC* = 215; opLENGTHW* = 216; |
opSYSVCALL* = 216; opSYSVCALLI* = 217; opSYSVCALLP* = 218; opFNAME* = 219; |
opAND* = 220; opOR* = 221; |
opSYSVCALL* = 217; opSYSVCALLI* = 218; opSYSVCALLP* = 219; opSYSVALIGN16* = 220; opWIN64ALIGN16* = 221; |
opONERR* = 222; opSAVEFI* = 223; opHANDLER* = 224; |
opSADR_PARAM* = -1; opLOAD64_PARAM* = -2; opLLOAD64_PARAM* = -3; opGLOAD64_PARAM* = -4; |
opVADR_PARAM* = -5; opCONST_PARAM* = -6; opGLOAD32_PARAM* = -7; opLLOAD32_PARAM* = -8; |
opLOAD32_PARAM* = -9; |
150,12 → 154,6 |
END; |
FNAMECMD* = POINTER TO RECORD (COMMAND) |
fname*: PATHS.PATH |
END; |
CMDSTACK = POINTER TO RECORD |
data: ARRAY 1000 OF COMMAND; |
194,7 → 192,7 |
endcall: CMDSTACK; |
commands*: LISTS.LIST; |
export*: LISTS.LIST; |
_import*: LISTS.LIST; |
import*: LISTS.LIST; |
types*: CHL.INTLIST; |
data*: CHL.BYTELIST; |
dmin*: INTEGER; |
206,6 → 204,7 |
charoffs: ARRAY 256 OF INTEGER; |
wcharoffs: ARRAY 65536 OF INTEGER; |
fregs: INTEGER; |
wstr: ARRAY 4*1024 OF WCHAR |
END; |
213,7 → 212,7 |
VAR |
codes*: CODES; |
CPU: INTEGER; |
endianness, numRegsFloat, CPU: INTEGER; |
commands, variables: C.COLLECTION; |
344,10 → 343,10 |
i := 0; |
WHILE i < n DO |
IF TARGETS.LittleEndian THEN |
IF endianness = little_endian THEN |
PutByte(ORD(codes.wstr[i]) MOD 256); |
PutByte(ORD(codes.wstr[i]) DIV 256) |
ELSE |
ELSIF endianness = big_endian THEN |
PutByte(ORD(codes.wstr[i]) DIV 256); |
PutByte(ORD(codes.wstr[i]) MOD 256) |
END; |
374,10 → 373,10 |
INC(res) |
END; |
IF TARGETS.LittleEndian THEN |
IF endianness = little_endian THEN |
PutByte(c MOD 256); |
PutByte(c DIV 256) |
ELSE |
ELSIF endianness = big_endian THEN |
PutByte(c DIV 256); |
PutByte(c MOD 256) |
END; |
411,19 → 410,19 |
END pop; |
PROCEDURE pushBegEnd* (VAR beg, _end: COMMAND); |
PROCEDURE pushBegEnd* (VAR beg, end: COMMAND); |
BEGIN |
push(codes.begcall, beg); |
push(codes.endcall, _end); |
push(codes.endcall, end); |
beg := codes.last; |
_end := beg.next(COMMAND) |
end := beg.next(COMMAND) |
END pushBegEnd; |
PROCEDURE popBegEnd* (VAR beg, _end: COMMAND); |
PROCEDURE popBegEnd* (VAR beg, end: COMMAND); |
BEGIN |
beg := pop(codes.begcall); |
_end := pop(codes.endcall) |
end := pop(codes.endcall) |
END popBegEnd; |
495,9 → 494,6 |
ELSIF (nov.opcode = opMULC) & (old_opcode = opMULC) THEN |
cur.param2 := param2 * cur.param2 |
ELSIF (nov.opcode = opADDC) & (old_opcode = opADDC) THEN |
cur.param2 := param2 + cur.param2 |
ELSE |
old_opcode := -1 |
END |
635,10 → 631,10 |
prev := codes.last; |
not := prev.opcode = opNOT; |
IF not THEN |
IF opcode = opJNZ THEN |
opcode := opJZ |
ELSIF opcode = opJZ THEN |
opcode := opJNZ |
IF opcode = opJE THEN |
opcode := opJNE |
ELSIF opcode = opJNE THEN |
opcode := opJE |
ELSE |
not := FALSE |
END |
649,79 → 645,10 |
IF not THEN |
delete(prev) |
END |
END AddJmpCmd; |
PROCEDURE AndOrOpt* (VAR label: INTEGER); |
VAR |
cur, prev: COMMAND; |
i, op, l: INTEGER; |
jz, not: BOOLEAN; |
BEGIN |
cur := codes.last; |
not := cur.opcode = opNOT; |
IF not THEN |
cur := cur.prev(COMMAND) |
END; |
IF cur.opcode = opAND THEN |
op := opAND |
ELSIF cur.opcode = opOR THEN |
op := opOR |
ELSE |
op := -1 |
END; |
cur := codes.last; |
IF op # -1 THEN |
IF not THEN |
IF op = opAND THEN |
op := opOR |
ELSE (* op = opOR *) |
op := opAND |
END; |
prev := cur.prev(COMMAND); |
delete(cur); |
cur := prev |
END; |
FOR i := 1 TO 9 DO |
IF i = 8 THEN |
l := cur.param1 |
ELSIF i = 9 THEN |
jz := cur.opcode = opJZ |
END; |
prev := cur.prev(COMMAND); |
delete(cur); |
cur := prev |
END; |
setlast(cur); |
IF op = opAND THEN |
label := l; |
jz := ~jz |
END; |
IF jz THEN |
AddJmpCmd(opJZ, label) |
ELSE |
AddJmpCmd(opJNZ, label) |
END; |
IF op = opOR THEN |
SetLabel(l) |
END |
ELSE |
AddJmpCmd(opJZ, label) |
END; |
setlast(codes.last) |
END AndOrOpt; |
PROCEDURE OnError* (line, error: INTEGER); |
BEGIN |
AddCmd2(opONERR, codes.errlabels[error], line) |
734,7 → 661,7 |
BEGIN |
AddCmd(op, t); |
label := NewLabel(); |
AddJmpCmd(opJNZ, label); |
AddJmpCmd(opJE, label); |
OnError(line, error); |
SetLabel(label) |
END TypeGuard; |
758,6 → 685,14 |
END New; |
PROCEDURE fcmp* (opcode: INTEGER); |
BEGIN |
AddCmd(opcode, 0); |
DEC(codes.fregs, 2); |
ASSERT(codes.fregs >= 0) |
END fcmp; |
PROCEDURE not*; |
VAR |
prev: COMMAND; |
772,14 → 707,6 |
END not; |
PROCEDURE _ord*; |
BEGIN |
IF (codes.last.opcode # opAND) & (codes.last.opcode # opOR) THEN |
AddCmd0(opORD) |
END |
END _ord; |
PROCEDURE Enter* (label, params: INTEGER): COMMAND; |
VAR |
cmd: COMMAND; |
973,10 → 900,44 |
AddCmd0(opSAVEFI) |
ELSE |
AddCmd0(opSAVEF) |
END |
END; |
DEC(codes.fregs); |
ASSERT(codes.fregs >= 0) |
END savef; |
PROCEDURE pushf*; |
BEGIN |
AddCmd0(opPUSHF); |
DEC(codes.fregs); |
ASSERT(codes.fregs >= 0) |
END pushf; |
PROCEDURE loadf* (): BOOLEAN; |
BEGIN |
AddCmd0(opLOADF); |
INC(codes.fregs) |
RETURN codes.fregs < numRegsFloat |
END loadf; |
PROCEDURE inf* (): BOOLEAN; |
BEGIN |
AddCmd0(opINF); |
INC(codes.fregs) |
RETURN codes.fregs < numRegsFloat |
END inf; |
PROCEDURE fbinop* (opcode: INTEGER); |
BEGIN |
AddCmd0(opcode); |
DEC(codes.fregs); |
ASSERT(codes.fregs > 0) |
END fbinop; |
PROCEDURE saves* (offset, length: INTEGER); |
BEGIN |
AddCmd2(opSAVES, length, offset) |
993,6 → 954,22 |
END abs; |
PROCEDURE floor*; |
BEGIN |
AddCmd0(opFLOOR); |
DEC(codes.fregs); |
ASSERT(codes.fregs >= 0) |
END floor; |
PROCEDURE flt* (): BOOLEAN; |
BEGIN |
AddCmd0(opFLT); |
INC(codes.fregs) |
RETURN codes.fregs < numRegsFloat |
END flt; |
PROCEDURE shift_minmax* (op: CHAR); |
BEGIN |
CASE op OF |
1038,7 → 1015,7 |
END len; |
PROCEDURE Float* (r: REAL; line, col: INTEGER); |
PROCEDURE Float* (r: REAL); |
VAR |
cmd: COMMAND; |
1046,12 → 1023,45 |
cmd := NewCmd(); |
cmd.opcode := opCONSTF; |
cmd.float := r; |
cmd.param1 := line; |
cmd.param2 := col; |
insert(codes.last, cmd) |
insert(codes.last, cmd); |
INC(codes.fregs); |
ASSERT(codes.fregs <= numRegsFloat) |
END Float; |
PROCEDURE precall* (flt: BOOLEAN): INTEGER; |
VAR |
res: INTEGER; |
BEGIN |
res := codes.fregs; |
AddCmd2(opPRECALL, ORD(flt), res); |
codes.fregs := 0 |
RETURN res |
END precall; |
PROCEDURE resf* (fregs: INTEGER): BOOLEAN; |
BEGIN |
AddCmd(opRESF, fregs); |
codes.fregs := fregs + 1 |
RETURN codes.fregs < numRegsFloat |
END resf; |
PROCEDURE res* (fregs: INTEGER); |
BEGIN |
AddCmd(opRES, fregs); |
codes.fregs := fregs |
END res; |
PROCEDURE retf*; |
BEGIN |
DEC(codes.fregs); |
ASSERT(codes.fregs = 0) |
END retf; |
PROCEDURE drop*; |
BEGIN |
AddCmd0(opDROP) |
1058,7 → 1068,7 |
END drop; |
PROCEDURE _case* (a, b, L, R: INTEGER); |
PROCEDURE case* (a, b, L, R: INTEGER); |
VAR |
cmd: COMMAND; |
1074,19 → 1084,13 |
AddCmd2(opCASEL, a, L); |
AddCmd2(opCASER, b, R) |
END |
END _case; |
END case; |
PROCEDURE fname* (name: PATHS.PATH); |
VAR |
cmd: FNAMECMD; |
PROCEDURE caset* (a, label: INTEGER); |
BEGIN |
NEW(cmd); |
cmd.opcode := opFNAME; |
cmd.fname := name; |
insert(codes.last, cmd) |
END fname; |
AddCmd2(opCASET, label, a) |
END caset; |
PROCEDURE AddExp* (label: INTEGER; name: SCAN.LEXSTR); |
1107,7 → 1111,7 |
p: IMPORT_PROC; |
BEGIN |
lib := codes._import.first(IMPORT_LIB); |
lib := codes.import.first(IMPORT_LIB); |
WHILE (lib # NIL) & (lib.name # dll) DO |
lib := lib.next(IMPORT_LIB) |
END; |
1116,7 → 1120,7 |
NEW(lib); |
lib.name := dll; |
lib.procs := LISTS.create(NIL); |
LISTS.push(codes._import, lib) |
LISTS.push(codes.import, lib) |
END; |
p := lib.procs.first(IMPORT_PROC); |
1149,7 → 1153,7 |
lib := imp(IMPORT_PROC).lib; |
LISTS.delete(lib.procs, imp); |
IF lib.procs.first = NIL THEN |
LISTS.delete(codes._import, lib) |
LISTS.delete(codes.import, lib) |
END |
END |
END DelImport; |
1165,6 → 1169,13 |
variables := C.create(); |
CPU := pCPU; |
endianness := little_endian; |
CASE CPU OF |
|TARGETS.cpuAMD64: numRegsFloat := 6 |
|TARGETS.cpuX86: numRegsFloat := 8 |
|TARGETS.cpuMSP430: numRegsFloat := 0 |
|TARGETS.cpuTHUMB: numRegsFloat := 256 |
END; |
NEW(codes.begcall); |
codes.begcall.top := -1; |
1172,7 → 1183,7 |
codes.endcall.top := -1; |
codes.commands := LISTS.create(NIL); |
codes.export := LISTS.create(NIL); |
codes._import := LISTS.create(NIL); |
codes.import := LISTS.create(NIL); |
codes.types := CHL.CreateIntList(); |
codes.data := CHL.CreateByteList(); |
1184,6 → 1195,8 |
codes.lcount := 0; |
codes.fregs := 0; |
FOR i := 0 TO LEN(codes.charoffs) - 1 DO |
codes.charoffs[i] := -1 |
END; |
/programs/develop/oberon07/Source/KOS.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2020, Anton Krotov |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
19,6 → 19,8 |
TYPE |
FILE = WR.FILE; |
HEADER = RECORD |
menuet01: ARRAY 9 OF CHAR; |
27,19 → 29,29 |
END; |
PROCEDURE align (n, _align: INTEGER): INTEGER; |
BEGIN |
IF n MOD _align # 0 THEN |
n := n + _align - (n MOD _align) |
END |
RETURN n |
END align; |
PROCEDURE Import* (program: BIN.PROGRAM; idata: INTEGER; VAR ImportTable: CHL.INTLIST; VAR len, libcount, size: INTEGER); |
VAR |
i: INTEGER; |
imp: BIN.IMPRT; |
import: BIN.IMPRT; |
BEGIN |
libcount := 0; |
imp := program.imp_list.first(BIN.IMPRT); |
WHILE imp # NIL DO |
IF imp.label = 0 THEN |
import := program.imp_list.first(BIN.IMPRT); |
WHILE import # NIL DO |
IF import.label = 0 THEN |
INC(libcount) |
END; |
imp := imp.next(BIN.IMPRT) |
import := import.next(BIN.IMPRT) |
END; |
len := libcount * 2 + 2; |
51,29 → 63,29 |
END; |
i := 0; |
imp := program.imp_list.first(BIN.IMPRT); |
WHILE imp # NIL DO |
import := program.imp_list.first(BIN.IMPRT); |
WHILE import # NIL DO |
IF imp.label = 0 THEN |
IF import.label = 0 THEN |
CHL.SetInt(ImportTable, len, 0); |
INC(len); |
CHL.SetInt(ImportTable, i, idata + len * SIZE_OF_DWORD); |
INC(i); |
CHL.SetInt(ImportTable, i, imp.nameoffs + size + idata); |
CHL.SetInt(ImportTable, i, import.nameoffs + size + idata); |
INC(i) |
ELSE |
CHL.SetInt(ImportTable, len, imp.nameoffs + size + idata); |
imp.label := len * SIZE_OF_DWORD; |
CHL.SetInt(ImportTable, len, import.nameoffs + size + idata); |
import.label := len * SIZE_OF_DWORD; |
INC(len) |
END; |
imp := imp.next(BIN.IMPRT) |
import := import.next(BIN.IMPRT) |
END; |
CHL.SetInt(ImportTable, len, 0); |
CHL.SetInt(ImportTable, i, 0); |
CHL.SetInt(ImportTable, i + 1, 0); |
INC(len); |
INC(size, CHL.Length(program._import)) |
size := size + CHL.Length(program.import) |
END Import; |
88,7 → 100,7 |
VAR |
header: HEADER; |
base, text, data, idata, bss, offset: INTEGER; |
base, text, data, idata, bss: INTEGER; |
reloc: BIN.RELOC; |
iproc: BIN.IMPRT; |
97,6 → 109,8 |
i: INTEGER; |
File: FILE; |
ImportTable: CHL.INTLIST; |
ILen, libcount, isize: INTEGER; |
107,23 → 121,23 |
BEGIN |
base := 0; |
icount := CHL.Length(program._import); |
icount := CHL.Length(program.import); |
dcount := CHL.Length(program.data); |
ccount := CHL.Length(program.code); |
text := base + HEADER_SIZE; |
data := WR.align(text + ccount, FileAlignment); |
idata := WR.align(data + dcount, FileAlignment); |
data := align(text + ccount, FileAlignment); |
idata := align(data + dcount, FileAlignment); |
Import(program, idata, ImportTable, ILen, libcount, isize); |
bss := WR.align(idata + isize, FileAlignment); |
bss := align(idata + isize, FileAlignment); |
header.menuet01 := "MENUET01"; |
header.ver := 1; |
header.start := text; |
header.size := idata + isize - base; |
header.mem := WR.align(header.size + program.stack + program.bss + PARAM_SIZE * 2 + 4096, FileAlignment); |
header.mem := align(header.size + program.stack + program.bss + PARAM_SIZE * 2 + 4096, FileAlignment); |
header.sp := base + header.mem - PARAM_SIZE * 2; |
header.param := header.sp; |
header.path := header.param + PARAM_SIZE; |
132,74 → 146,73 |
reloc := program.rel_list.first(BIN.RELOC); |
WHILE reloc # NIL DO |
offset := reloc.offset; |
L := BIN.get32le(code, offset); |
delta := 3 - offset - text; |
L := BIN.get32le(code, reloc.offset); |
delta := 3 - reloc.offset - text; |
CASE reloc.opcode OF |
|BIN.RIMP: |
iproc := BIN.GetIProc(program, L); |
delta := idata + iproc.label |
BIN.put32le(code, reloc.offset, idata + iproc.label) |
|BIN.RBSS: |
delta := L + bss |
BIN.put32le(code, reloc.offset, L + bss) |
|BIN.RDATA: |
delta := L + data |
BIN.put32le(code, reloc.offset, L + data) |
|BIN.RCODE: |
delta := BIN.GetLabel(program, L) + text |
BIN.put32le(code, reloc.offset, BIN.GetLabel(program, L) + text) |
|BIN.PICDATA: |
INC(delta, L + data) |
BIN.put32le(code, reloc.offset, L + data + delta) |
|BIN.PICCODE: |
INC(delta, BIN.GetLabel(program, L) + text) |
BIN.put32le(code, reloc.offset, BIN.GetLabel(program, L) + text + delta) |
|BIN.PICBSS: |
INC(delta, L + bss) |
BIN.put32le(code, reloc.offset, L + bss + delta) |
|BIN.PICIMP: |
iproc := BIN.GetIProc(program, L); |
INC(delta, idata + iproc.label) |
BIN.put32le(code, reloc.offset, idata + iproc.label + delta) |
|BIN.IMPTAB: |
INC(delta, idata) |
BIN.put32le(code, reloc.offset, idata + delta) |
END; |
BIN.put32le(code, offset, delta); |
reloc := reloc.next(BIN.RELOC) |
END; |
WR.Create(FileName); |
File := WR.Create(FileName); |
FOR i := 0 TO 7 DO |
WR.WriteByte(ORD(header.menuet01[i])) |
WR.WriteByte(File, ORD(header.menuet01[i])) |
END; |
WR.Write32LE(header.ver); |
WR.Write32LE(header.start); |
WR.Write32LE(header.size); |
WR.Write32LE(header.mem); |
WR.Write32LE(header.sp); |
WR.Write32LE(header.param); |
WR.Write32LE(header.path); |
WR.Write32LE(File, header.ver); |
WR.Write32LE(File, header.start); |
WR.Write32LE(File, header.size); |
WR.Write32LE(File, header.mem); |
WR.Write32LE(File, header.sp); |
WR.Write32LE(File, header.param); |
WR.Write32LE(File, header.path); |
CHL.WriteToFile(code); |
WR.Padding(FileAlignment); |
CHL.WriteToFile(File, code); |
WR.Padding(File, FileAlignment); |
CHL.WriteToFile(program.data); |
WR.Padding(FileAlignment); |
CHL.WriteToFile(File, program.data); |
WR.Padding(File, FileAlignment); |
FOR i := 0 TO ILen - 1 DO |
WR.Write32LE(CHL.GetInt(ImportTable, i)) |
WR.Write32LE(File, CHL.GetInt(ImportTable, i)) |
END; |
CHL.WriteToFile(program._import); |
CHL.WriteToFile(File, program.import); |
WR.Close |
WR.Close(File) |
END write; |
/programs/develop/oberon07/Source/LISTS.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2020, Anton Krotov |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
32,14 → 32,17 |
IF list.first = NIL THEN |
list.first := item; |
item.prev := NIL |
list.last := item; |
item.prev := NIL; |
item.next := NIL |
ELSE |
ASSERT(list.last # NIL); |
item.prev := list.last; |
list.last.next := item |
END; |
list.last := item; |
item.next := NIL |
list.last.next := item; |
item.next := NIL; |
list.last := item |
END |
END push; |
105,13 → 108,16 |
IF prev # NIL THEN |
prev.next := nov; |
nov.prev := prev |
nov.prev := prev; |
cur.prev := nov; |
nov.next := cur |
ELSE |
nov.prev := NIL; |
cur.prev := nov; |
nov.next := cur; |
list.first := nov |
END; |
cur.prev := nov; |
nov.next := cur |
END |
END insertL; |
/programs/develop/oberon07/Source/MSCOFF.ob07 |
---|
28,30 → 28,28 |
SH = PE32.IMAGE_SECTION_HEADER; |
PROCEDURE WriteReloc (VirtualAddress, SymbolTableIndex, Type: INTEGER); |
PROCEDURE WriteReloc (File: WR.FILE; VirtualAddress, SymbolTableIndex, Type: INTEGER); |
BEGIN |
WR.Write32LE(VirtualAddress); |
WR.Write32LE(SymbolTableIndex); |
WR.Write16LE(Type) |
WR.Write32LE(File, VirtualAddress); |
WR.Write32LE(File, SymbolTableIndex); |
WR.Write16LE(File, Type) |
END WriteReloc; |
PROCEDURE Reloc (program: BIN.PROGRAM); |
PROCEDURE Reloc (program: BIN.PROGRAM; File: WR.FILE); |
VAR |
reloc: BIN.RELOC; |
offset: INTEGER; |
BEGIN |
reloc := program.rel_list.first(BIN.RELOC); |
WHILE reloc # NIL DO |
offset := reloc.offset; |
CASE reloc.opcode OF |
|BIN.RIMP, |
BIN.IMPTAB: WriteReloc(offset, 4, 6) |
|BIN.RBSS: WriteReloc(offset, 5, 6) |
|BIN.RDATA: WriteReloc(offset, 2, 6) |
|BIN.RCODE: WriteReloc(offset, 1, 6) |
BIN.IMPTAB: WriteReloc(File, reloc.offset, 4, 6) |
|BIN.RBSS: WriteReloc(File, reloc.offset, 5, 6) |
|BIN.RDATA: WriteReloc(File, reloc.offset, 2, 6) |
|BIN.RCODE: WriteReloc(File, reloc.offset, 1, 6) |
END; |
reloc := reloc.next(BIN.RELOC) |
64,7 → 62,6 |
reloc: BIN.RELOC; |
iproc: BIN.IMPRT; |
res, L: INTEGER; |
offset: INTEGER; |
code: CHL.BYTELIST; |
BEGIN |
74,17 → 71,16 |
WHILE reloc # NIL DO |
INC(res); |
offset := reloc.offset; |
IF reloc.opcode = BIN.RIMP THEN |
L := BIN.get32le(code, offset); |
L := BIN.get32le(code, reloc.offset); |
iproc := BIN.GetIProc(program, L); |
BIN.put32le(code, offset, iproc.label) |
BIN.put32le(code, reloc.offset, iproc.label) |
END; |
IF reloc.opcode = BIN.RCODE THEN |
L := BIN.get32le(code, offset); |
BIN.put32le(code, offset, BIN.GetLabel(program, L)) |
L := BIN.get32le(code, reloc.offset); |
BIN.put32le(code, reloc.offset, BIN.GetLabel(program, L)) |
END; |
reloc := reloc.next(BIN.RELOC) |
96,6 → 92,7 |
PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR; ver: INTEGER); |
VAR |
File: WR.FILE; |
exp: BIN.EXPRT; |
n, i: INTEGER; |
148,7 → 145,7 |
KOS.Import(program, 0, ImportTable, ILen, LibCount, isize); |
ExpCount := LISTS.count(program.exp_list); |
icount := CHL.Length(program._import); |
icount := CHL.Length(program.import); |
dcount := CHL.Length(program.data); |
ccount := CHL.Length(program.code); |
ecount := CHL.Length(program.export); |
222,87 → 219,91 |
FileHeader.PointerToSymbolTable := idata.PointerToRelocations + ORD(idata.NumberOfRelocations) * 10; |
WR.Create(FileName); |
File := WR.Create(FileName); |
PE32.WriteFileHeader(FileHeader); |
PE32.WriteFileHeader(File, FileHeader); |
PE32.WriteSectionHeader(flat); |
PE32.WriteSectionHeader(data); |
PE32.WriteSectionHeader(edata); |
PE32.WriteSectionHeader(idata); |
PE32.WriteSectionHeader(bss); |
PE32.WriteSectionHeader(File, flat); |
PE32.WriteSectionHeader(File, data); |
PE32.WriteSectionHeader(File, edata); |
PE32.WriteSectionHeader(File, idata); |
PE32.WriteSectionHeader(File, bss); |
CHL.WriteToFile(program.code); |
CHL.WriteToFile(program.data); |
CHL.WriteToFile(File, program.code); |
CHL.WriteToFile(File, program.data); |
exp := program.exp_list.first(BIN.EXPRT); |
WHILE exp # NIL DO |
WR.Write32LE(exp.nameoffs + edata.SizeOfRawData - ecount); |
WR.Write32LE(exp.label); |
WR.Write32LE(File, exp.nameoffs + edata.SizeOfRawData - ecount); |
WR.Write32LE(File, exp.label); |
exp := exp.next(BIN.EXPRT) |
END; |
WR.Write32LE(((ExpCount + 1) * 2 + 1) * SIZE_OF_DWORD); |
WR.Write32LE(ver); |
WR.Write32LE(File, ((ExpCount + 1) * 2 + 1) * SIZE_OF_DWORD); |
WR.Write32LE(File, ver); |
WR.Write32LE(0); |
WR.Write32LE(File, 0); |
PE32.WriteName(szversion); |
CHL.WriteToFile(program.export); |
PE32.WriteName(File, szversion); |
CHL.WriteToFile(File, program.export); |
FOR i := 0 TO ILen - 1 DO |
WR.Write32LE(CHL.GetInt(ImportTable, i)) |
WR.Write32LE(File, CHL.GetInt(ImportTable, i)) |
END; |
CHL.WriteToFile(program._import); |
CHL.WriteToFile(File, program.import); |
Reloc(program); |
Reloc(program, File); |
n := 0; |
exp := program.exp_list.first(BIN.EXPRT); |
WHILE exp # NIL DO |
WriteReloc(n, 3, 6); |
WriteReloc(File, n, 3, 6); |
INC(n, 4); |
WriteReloc(n, 1, 6); |
WriteReloc(File, n, 1, 6); |
INC(n, 4); |
exp := exp.next(BIN.EXPRT) |
END; |
WriteReloc(n, 3, 6); |
WriteReloc(File, n, 3, 6); |
FOR i := 0 TO LibCount * 2 - 1 DO |
WriteReloc(i * SIZE_OF_DWORD, 4, 6) |
i := 0; |
WHILE i < LibCount * 2 DO |
WriteReloc(File, i * SIZE_OF_DWORD, 4, 6); |
INC(i); |
WriteReloc(File, i * SIZE_OF_DWORD, 4, 6); |
INC(i) |
END; |
FOR i := LibCount * 2 TO ILen - 1 DO |
IF CHL.GetInt(ImportTable, i) # 0 THEN |
WriteReloc(i * SIZE_OF_DWORD, 4, 6) |
WriteReloc(File, i * SIZE_OF_DWORD, 4, 6) |
END |
END; |
PE32.WriteName("EXPORTS"); |
WriteReloc(0, 3, 2); |
PE32.WriteName(File, "EXPORTS"); |
WriteReloc(File, 0, 3, 2); |
PE32.WriteName(".flat"); |
WriteReloc(0, 1, 3); |
PE32.WriteName(File, ".flat"); |
WriteReloc(File, 0, 1, 3); |
PE32.WriteName(".data"); |
WriteReloc(0, 2, 3); |
PE32.WriteName(File, ".data"); |
WriteReloc(File, 0, 2, 3); |
PE32.WriteName(".edata"); |
WriteReloc(0, 3, 3); |
PE32.WriteName(File, ".edata"); |
WriteReloc(File, 0, 3, 3); |
PE32.WriteName(".idata"); |
WriteReloc(0, 4, 3); |
PE32.WriteName(File, ".idata"); |
WriteReloc(File, 0, 4, 3); |
PE32.WriteName(".bss"); |
WriteReloc(0, 5, 3); |
PE32.WriteName(File, ".bss"); |
WriteReloc(File, 0, 5, 3); |
WR.Write32LE(4); |
WR.Write32LE(File, 4); |
WR.Close |
WR.Close(File) |
END write; |
/programs/develop/oberon07/Source/MSP430.ob07 |
---|
421,7 → 421,8 |
PROCEDURE xchg (reg1, reg2: INTEGER); |
BEGIN |
Push(reg1); |
mov(reg1, reg2); |
Push(reg2); |
Pop(reg1); |
Pop(reg2) |
END xchg; |
818,7 → 819,7 |
Op2(opADD, reg2 * 256, reg1); |
drop |
|IL.opADDC: |
|IL.opADDL, IL.opADDR: |
IF param2 # 0 THEN |
UnOp(reg1); |
Op2(opADD, imm(param2), reg1) |
879,10 → 880,10 |
cc := cond(opcode); |
next := cmd.next(COMMAND); |
IF next.opcode = IL.opJNZ THEN |
IF next.opcode = IL.opJE THEN |
jcc(cc, next.param1); |
cmd := next |
ELSIF next.opcode = IL.opJZ THEN |
ELSIF next.opcode = IL.opJNE THEN |
jcc(ORD(BITS(cc) / {0}), next.param1); |
cmd := next |
ELSE |
889,32 → 890,45 |
setcc(cc, GetAnyReg()) |
END |
|IL.opNOP, IL.opAND, IL.opOR: |
|IL.opNOP: |
|IL.opCODE: |
EmitWord(param2) |
|IL.opACC: |
IF (R.top # 0) OR (R.stk[0] # ACC) THEN |
PushAll(0); |
GetRegA; |
Pop(ACC); |
DEC(R.pushed) |
END |
|IL.opDROP: |
UnOp(reg1); |
drop |
|IL.opJNZ1: |
|IL.opJNZ: |
UnOp(reg1); |
Test(reg1); |
jcc(jne, param1) |
|IL.opJZ: |
UnOp(reg1); |
Test(reg1); |
jcc(je, param1) |
|IL.opJG: |
UnOp(reg1); |
Test(reg1); |
jcc(jg, param1) |
|IL.opJNZ: |
|IL.opJE: |
UnOp(reg1); |
Test(reg1); |
jcc(jne, param1); |
drop |
|IL.opJZ: |
|IL.opJNE: |
UnOp(reg1); |
Test(reg1); |
jcc(je, param1); |
944,11 → 958,6 |
drop; |
Op2(opMOV + bw(param2 = 1), src_x(param1, SR), dst_x(0, reg2)) |
|IL.opCHKBYTE: |
BinOp(reg1, reg2); |
Op2(opCMP, imm(256), reg1); |
jcc(jb, param1) |
|IL.opCHKIDX: |
UnOp(reg1); |
Op2(opCMP, imm(param2), reg1); |
1070,7 → 1079,7 |
Op2(opBIC, reg2 * 256, reg1); |
drop |
|IL.opADDSC: |
|IL.opADDSL, IL.opADDSR: |
UnOp(reg1); |
Op2(opBIS, imm(param2), reg1) |
1180,6 → 1189,11 |
INCL(R.regs, reg1); |
ASSERT(REG.GetReg(R, reg1)) |
|IL.opCHKBYTE: |
BinOp(reg1, reg2); |
Op2(opCMP, imm(256), reg1); |
jcc(jb, param1) |
|IL.opLSL, IL.opASR, IL.opROR, IL.opLSR: |
PushAll(2); |
CASE opcode OF |
1604,7 → 1618,7 |
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS); |
VAR |
i, adr, heap, stack, TextSize, TypesSize, bits, n, val: INTEGER; |
i, adr, heap, stack, TextSize, TypesSize, bits, n: INTEGER; |
Code, Data, Bss, Free: RECORD address, size: INTEGER END; |
1612,6 → 1626,8 |
reloc: RELOC; |
file: WR.FILE; |
BEGIN |
IdxWords.src := NOWORD; |
IdxWords.dst := NOWORD; |
1671,11 → 1687,10 |
reloc := RelList.first(RELOC); |
WHILE reloc # NIL DO |
adr := reloc.WordPtr.offset * 2; |
val := reloc.WordPtr.val; |
CASE reloc.section OF |
|RCODE: PutWord(LabelOffs(val) * 2, adr) |
|RDATA: PutWord(val + Data.address, adr) |
|RBSS: PutWord(val + Bss.address, adr) |
|RCODE: PutWord(LabelOffs(reloc.WordPtr.val) * 2, adr) |
|RDATA: PutWord(reloc.WordPtr.val + Data.address, adr) |
|RBSS: PutWord(reloc.WordPtr.val + Bss.address, adr) |
END; |
reloc := reloc.next(RELOC) |
END; |
1718,13 → 1733,13 |
PutWord(LabelOffs(IV[i]) * 2, adr) |
END; |
WR.Create(outname); |
file := WR.Create(outname); |
HEX.Data(mem, Code.address, TextSize); |
HEX.Data(mem, 10000H - IntVectorSize - TypesSize, IntVectorSize + TypesSize); |
HEX.End; |
HEX.Data(file, mem, Code.address, TextSize); |
HEX.Data(file, mem, 10000H - IntVectorSize - TypesSize, IntVectorSize + TypesSize); |
HEX.End(file); |
WR.Close; |
WR.Close(file); |
INC(TextSize, IntVectorSize + TypesSize); |
INC(Bss.size, minStackSize + RTL.VarSize); |
/programs/develop/oberon07/Source/PARS.ob07 |
---|
34,7 → 34,7 |
EXPR* = RECORD |
obj*: INTEGER; |
_type*: PROG._TYPE; |
type*: PROG.TYPE_; |
value*: ARITH.VALUE; |
stproc*: INTEGER; |
readOnly*: BOOLEAN; |
44,7 → 44,7 |
STATPROC = PROCEDURE (parser: PARSER); |
EXPRPROC = PROCEDURE (parser: PARSER; VAR e: EXPR); |
RETPROC = PROCEDURE (parser: PARSER; e: EXPR; t: PROG._TYPE; pos: POSITION): BOOLEAN; |
RETPROC = PROCEDURE (parser: PARSER; e: EXPR; t: PROG.TYPE_; pos: POSITION): BOOLEAN; |
rPARSER = RECORD (C.ITEM) |
74,6 → 74,8 |
VAR |
program*: PROG.PROGRAM; |
parsers: C.COLLECTION; |
lines*, modules: INTEGER; |
131,10 → 133,10 |
BEGIN |
SCAN.Next(parser.scanner, parser.lex); |
errno := parser.lex.error; |
IF errno = 0 THEN |
IF (TARGETS.RealSize = 0) & (parser.lex.sym = SCAN.lxFLOAT) THEN |
IF (errno = 0) & (TARGETS.CPU = TARGETS.cpuMSP430) THEN |
IF parser.lex.sym = SCAN.lxFLOAT THEN |
errno := -SCAN.lxERROR13 |
ELSIF (TARGETS.BitDepth = 16) & (parser.lex.sym = SCAN.lxCHAR) & (parser.lex.value.typ = ARITH.tWCHAR) THEN |
ELSIF (parser.lex.sym = SCAN.lxCHAR) & (parser.lex.value.typ = ARITH.tWCHAR) THEN |
errno := -SCAN.lxERROR10 |
END |
END; |
182,6 → 184,7 |
|SCAN.lxSEMI: err := 24 |
|SCAN.lxRETURN: err := 38 |
|SCAN.lxMODULE: err := 21 |
|SCAN.lxSTRING: err := 66 |
END; |
check1(FALSE, parser, err) |
224,7 → 227,7 |
IF (parser.sym = SCAN.lxCOMMA) OR (parser.sym = SCAN.lxSEMI) THEN |
alias := FALSE; |
unit := PROG.getUnit(name); |
unit := PROG.getUnit(program, name); |
IF unit # NIL THEN |
check(unit.closed, pos, 31) |
247,7 → 250,7 |
unit := parser2.unit; |
destroy(parser2) |
END; |
IF unit = PROG.program.sysunit THEN |
IF unit = program.sysunit THEN |
parser.unit.sysimport := TRUE |
END; |
ident.unit := unit |
347,7 → 350,7 |
END ConstExpression; |
PROCEDURE FieldList (parser: PARSER; rec: PROG._TYPE); |
PROCEDURE FieldList (parser: PARSER; rec: PROG.TYPE_); |
VAR |
name: SCAN.IDENT; |
export: BOOLEAN; |
384,18 → 387,18 |
END FieldList; |
PROCEDURE FormalParameters (parser: PARSER; _type: PROG._TYPE); |
PROCEDURE FormalParameters (parser: PARSER; type: PROG.TYPE_); |
VAR |
ident: PROG.IDENT; |
PROCEDURE FPSection (parser: PARSER; _type: PROG._TYPE); |
PROCEDURE FPSection (parser: PARSER; type: PROG.TYPE_); |
VAR |
ident: PROG.IDENT; |
exit: BOOLEAN; |
vPar: BOOLEAN; |
dim: INTEGER; |
t0, t1: PROG._TYPE; |
t0, t1: PROG.TYPE_; |
BEGIN |
vPar := parser.sym = SCAN.lxVAR; |
407,7 → 410,7 |
exit := FALSE; |
WHILE (parser.sym = SCAN.lxIDENT) & ~exit DO |
check1(PROG.addParam(_type, parser.lex.ident, vPar), parser, 30); |
check1(PROG.addParam(type, parser.lex.ident, vPar), parser, 30); |
Next(parser); |
IF parser.sym = SCAN.lxCOMMA THEN |
ExpectSym(parser, SCAN.lxIDENT) |
424,17 → 427,17 |
ident := QIdent(parser, FALSE); |
check1(ident.typ = PROG.idTYPE, parser, 68); |
t0 := ident._type; |
t0 := ident.type; |
t1 := t0; |
WHILE dim > 0 DO |
t1 := PROG.enterType(PROG.tARRAY, -1, 0, parser.unit); |
t1 := PROG.enterType(program, PROG.tARRAY, -1, 0, parser.unit); |
t1.base := t0; |
t0 := t1; |
DEC(dim) |
END; |
PROG.setParams(_type, t1); |
PROG.setParams(type, t1); |
Next(parser); |
exit := TRUE |
ELSE |
451,10 → 454,10 |
Next(parser); |
IF (parser.sym = SCAN.lxVAR) OR (parser.sym = SCAN.lxIDENT) THEN |
FPSection(parser, _type); |
FPSection(parser, type); |
WHILE parser.sym = SCAN.lxSEMI DO |
Next(parser); |
FPSection(parser, _type) |
FPSection(parser, type) |
END |
END; |
465,12 → 468,12 |
ExpectSym(parser, SCAN.lxIDENT); |
ident := QIdent(parser, FALSE); |
check1(ident.typ = PROG.idTYPE, parser, 68); |
check1(~(ident._type.typ IN {PROG.tRECORD, PROG.tARRAY}), parser, 69); |
check1( ~(ODD(_type.call) & (ident._type.typ = PROG.tREAL)), parser, 113); |
_type.base := ident._type; |
check1(~(ident.type.typ IN {PROG.tRECORD, PROG.tARRAY}), parser, 69); |
check1( ~(ODD(type.call) & (ident.type.typ = PROG.tREAL)), parser, 113); |
type.base := ident.type; |
Next(parser) |
ELSE |
_type.base := NIL |
type.base := NIL |
END |
END |
500,8 → 503,6 |
sf := PROG.sf_linux |
ELSIF parser.lex.s = "code" THEN |
sf := PROG.sf_code |
ELSIF parser.lex.s = "oberon" THEN |
sf := PROG.sf_oberon |
ELSIF parser.lex.s = "noalign" THEN |
sf := PROG.sf_noalign |
ELSE |
508,7 → 509,7 |
check1(FALSE, parser, 124) |
END; |
check1(sf IN PROG.program.sysflags, parser, 125); |
check1(sf IN program.sysflags, parser, 125); |
IF proc THEN |
check1(sf IN PROG.proc_flags, parser, 123) |
531,12 → 532,6 |
res := PROG.systemv |
|PROG.sf_code: |
res := PROG.code |
|PROG.sf_oberon: |
IF TARGETS.OS IN {TARGETS.osWIN32, TARGETS.osLINUX32, TARGETS.osKOS} THEN |
res := PROG.default32 |
ELSIF TARGETS.OS IN {TARGETS.osWIN64, TARGETS.osLINUX64} THEN |
res := PROG.default64 |
END |
|PROG.sf_windows: |
IF TARGETS.OS = TARGETS.osWIN32 THEN |
res := PROG.stdcall |
557,34 → 552,16 |
END sysflag; |
PROCEDURE procflag (parser: PARSER; VAR _import: IL.IMPORT_PROC; isProc: BOOLEAN): INTEGER; |
PROCEDURE procflag (parser: PARSER; VAR import: IL.IMPORT_PROC; isProc: BOOLEAN): INTEGER; |
VAR |
call: INTEGER; |
dll, proc: SCAN.LEXSTR; |
pos: POSITION; |
PROCEDURE getStr (parser: PARSER; VAR name: SCAN.LEXSTR); |
VAR |
pos: POSITION; |
str: ARITH.VALUE; |
BEGIN |
getpos(parser, pos); |
ConstExpression(parser, str); |
IF str.typ = ARITH.tSTRING THEN |
name := str.string(SCAN.IDENT).s |
ELSIF str.typ = ARITH.tCHAR THEN |
ARITH.charToStr(str, name) |
ELSE |
check(FALSE, pos, 117) |
END |
END getStr; |
import := NIL; |
BEGIN |
_import := NIL; |
IF parser.sym = SCAN.lxLSQUARE THEN |
getpos(parser, pos); |
check1(parser.unit.sysimport, parser, 54); |
595,32 → 572,34 |
Next(parser); |
INC(call) |
END; |
IF isProc & (parser.sym = SCAN.lxCOMMA) THEN |
Next(parser); |
getStr(parser, dll); |
IF ~isProc THEN |
checklex(parser, SCAN.lxRSQUARE) |
END; |
IF parser.sym = SCAN.lxCOMMA THEN |
ExpectSym(parser, SCAN.lxSTRING); |
dll := parser.lex.s; |
STRINGS.UpCase(dll); |
checklex(parser, SCAN.lxCOMMA); |
ExpectSym(parser, SCAN.lxCOMMA); |
ExpectSym(parser, SCAN.lxSTRING); |
proc := parser.lex.s; |
Next(parser); |
getStr(parser, proc); |
_import := IL.AddImp(dll, proc) |
import := IL.AddImp(dll, proc) |
END; |
checklex(parser, SCAN.lxRSQUARE); |
Next(parser) |
ELSE |
CASE TARGETS.BitDepth OF |
|16: call := PROG.default16 |
|32: IF TARGETS.CPU = TARGETS.cpuX86 THEN |
|32: IF TARGETS.target = TARGETS.STM32CM3 THEN |
call := PROG.ccall |
ELSE |
call := PROG.default32 |
ELSE |
call := PROG.ccall |
END |
|64: call := PROG.default64 |
END |
END; |
IF _import # NIL THEN |
IF import # NIL THEN |
check(TARGETS.Import, pos, 70) |
END |
628,7 → 607,7 |
END procflag; |
PROCEDURE _type (parser: PARSER; VAR t: PROG._TYPE; flags: SET); |
PROCEDURE type (parser: PARSER; VAR t: PROG.TYPE_; flags: SET); |
CONST |
comma = 0; |
closed = 1; |
640,11 → 619,11 |
ident: PROG.IDENT; |
unit: PROG.UNIT; |
pos, pos2: POSITION; |
fieldType: PROG._TYPE; |
fieldType: PROG.TYPE_; |
baseIdent: SCAN.IDENT; |
a, b: INTEGER; |
RecFlag: INTEGER; |
_import: IL.IMPORT_PROC; |
import: IL.IMPORT_PROC; |
BEGIN |
unit := parser.unit; |
655,7 → 634,7 |
IF ident # NIL THEN |
check1(ident.typ = PROG.idTYPE, parser, 49); |
t := ident._type; |
t := ident.type; |
check1(t # NIL, parser, 50); |
IF closed IN flags THEN |
check1(t.closed, parser, 50) |
677,13 → 656,13 |
check(ARITH.check(arrLen), pos, 39); |
check(ARITH.getInt(arrLen) > 0, pos, 51); |
t := PROG.enterType(PROG.tARRAY, -1, ARITH.getInt(arrLen), unit); |
t := PROG.enterType(program, PROG.tARRAY, -1, ARITH.getInt(arrLen), unit); |
IF parser.sym = SCAN.lxCOMMA THEN |
_type(parser, t.base, {comma, closed}) |
type(parser, t.base, {comma, closed}) |
ELSIF parser.sym = SCAN.lxOF THEN |
Next(parser); |
_type(parser, t.base, {closed}) |
type(parser, t.base, {closed}) |
ELSE |
check1(FALSE, parser, 47) |
END; |
702,7 → 681,7 |
getpos(parser, pos2); |
Next(parser); |
t := PROG.enterType(PROG.tRECORD, 0, 0, unit); |
t := PROG.enterType(program, PROG.tRECORD, 0, 0, unit); |
t.align := 1; |
IF parser.sym = SCAN.lxLSQUARE THEN |
719,7 → 698,7 |
ExpectSym(parser, SCAN.lxIDENT); |
getpos(parser, pos); |
_type(parser, t.base, {closed}); |
type(parser, t.base, {closed}); |
check(t.base.typ IN {PROG.tRECORD, PROG.tPOINTER}, pos, 52); |
738,7 → 717,7 |
t.align := t.base.align |
END |
ELSE |
t.base := PROG.program.stTypes.tANYREC |
t.base := program.stTypes.tANYREC |
END; |
WHILE parser.sym = SCAN.lxIDENT DO |
747,7 → 726,7 |
ASSERT(parser.sym = SCAN.lxCOLON); |
Next(parser); |
_type(parser, fieldType, {closed}); |
type(parser, fieldType, {closed}); |
check(PROG.setFields(t, fieldType), pos2, 104); |
IF (fieldType.align > t.align) & ~t.noalign THEN |
777,7 → 756,7 |
ExpectSym(parser, SCAN.lxTO); |
Next(parser); |
t := PROG.enterType(PROG.tPOINTER, TARGETS.AdrSize, 0, unit); |
t := PROG.enterType(program, PROG.tPOINTER, TARGETS.AdrSize, 0, unit); |
t.align := TARGETS.AdrSize; |
getpos(parser, pos); |
786,7 → 765,7 |
baseIdent := parser.lex.ident |
END; |
_type(parser, t.base, {forward}); |
type(parser, t.base, {forward}); |
IF t.base # NIL THEN |
check(t.base.typ = PROG.tRECORD, pos, 58) |
796,15 → 775,15 |
ELSIF parser.sym = SCAN.lxPROCEDURE THEN |
NextPos(parser, pos); |
t := PROG.enterType(PROG.tPROCEDURE, TARGETS.AdrSize, 0, unit); |
t := PROG.enterType(program, PROG.tPROCEDURE, TARGETS.AdrSize, 0, unit); |
t.align := TARGETS.AdrSize; |
t.call := procflag(parser, _import, FALSE); |
t.call := procflag(parser, import, FALSE); |
FormalParameters(parser, t) |
ELSE |
check1(FALSE, parser, 49) |
END |
END _type; |
END type; |
PROCEDURE IdentDef (parser: PARSER; typ: INTEGER; VAR name: SCAN.IDENT): PROG.IDENT; |
832,7 → 811,7 |
END IdentDef; |
PROCEDURE ConstTypeDeclaration (parser: PARSER; _const: BOOLEAN); |
PROCEDURE ConstTypeDeclaration (parser: PARSER; const: BOOLEAN); |
VAR |
ident: PROG.IDENT; |
name: SCAN.IDENT; |
839,7 → 818,7 |
pos: POSITION; |
BEGIN |
IF _const THEN |
IF const THEN |
ident := IdentDef(parser, PROG.idNONE, name) |
ELSE |
ident := IdentDef(parser, PROG.idTYPE, name) |
848,7 → 827,7 |
checklex(parser, SCAN.lxEQ); |
NextPos(parser, pos); |
IF _const THEN |
IF const THEN |
ConstExpression(parser, ident.value); |
IF ident.value.typ = ARITH.tINTEGER THEN |
check(ARITH.check(ident.value), pos, 39) |
856,9 → 835,9 |
check(ARITH.check(ident.value), pos, 40) |
END; |
ident.typ := PROG.idCONST; |
ident._type := PROG.getType(ident.value.typ) |
ident.type := PROG.getType(program, ident.value.typ) |
ELSE |
_type(parser, ident._type, {}) |
type(parser, ident.type, {}) |
END; |
checklex(parser, SCAN.lxSEMI); |
871,7 → 850,7 |
VAR |
ident: PROG.IDENT; |
name: SCAN.IDENT; |
t: PROG._TYPE; |
t: PROG.TYPE_; |
BEGIN |
882,7 → 861,7 |
ExpectSym(parser, SCAN.lxIDENT) |
ELSIF parser.sym = SCAN.lxCOLON THEN |
Next(parser); |
_type(parser, t, {}); |
type(parser, t, {}); |
PROG.setVarsType(parser.unit, t); |
checklex(parser, SCAN.lxSEMI); |
Next(parser) |
916,8 → 895,8 |
label: INTEGER; |
enter: IL.COMMAND; |
call: INTEGER; |
t: PROG._TYPE; |
_import: IL.IMPORT_PROC; |
t: PROG.TYPE_; |
import: IL.IMPORT_PROC; |
endmod, b: BOOLEAN; |
fparams: SET; |
variables: LISTS.LIST; |
933,19 → 912,16 |
unit := parser.unit; |
call := procflag(parser, _import, TRUE); |
call := procflag(parser, import, TRUE); |
getpos(parser, pos); |
pos1 := pos; |
checklex(parser, SCAN.lxIDENT); |
IF _import # NIL THEN |
IF import # NIL THEN |
proc := IdentDef(parser, PROG.idIMP, name); |
proc._import := _import; |
IF _import.name = "" THEN |
_import.name := name.s |
END; |
PROG.program.procs.last(PROG.PROC)._import := _import |
proc.import := import; |
program.procs.last(PROG.PROC).import := import |
ELSE |
proc := IdentDef(parser, PROG.idPROC, name) |
END; |
952,8 → 928,8 |
check(PROG.openScope(unit, proc.proc), pos, 116); |
proc._type := PROG.enterType(PROG.tPROCEDURE, TARGETS.AdrSize, 0, unit); |
t := proc._type; |
proc.type := PROG.enterType(program, PROG.tPROCEDURE, TARGETS.AdrSize, 0, unit); |
t := proc.type; |
t.align := TARGETS.AdrSize; |
t.call := call; |
983,7 → 959,7 |
WHILE param # NIL DO |
ident := PROG.addIdent(unit, param.name, PROG.idPARAM); |
ASSERT(ident # NIL); |
ident._type := param._type; |
ident.type := param.type; |
ident.offset := param.offset; |
IF param.vPar THEN |
ident.typ := PROG.idVPAR |
991,7 → 967,7 |
param := param.next(PROG.PARAM) |
END; |
IF _import = NIL THEN |
IF import = NIL THEN |
label := IL.NewLabel(); |
proc.proc.label := label; |
proc.proc.used := handler; |
1007,11 → 983,10 |
getpos(parser, pos2); |
ConstExpression(parser, code); |
check(code.typ = ARITH.tINTEGER, pos2, 43); |
IF TARGETS.WordSize > TARGETS.InstrSize THEN |
CASE TARGETS.InstrSize OF |
|1: check(ARITH.range(code, 0, 255), pos, 42) |
|2: check(ARITH.range(code, 0, 65535), pos, 110) |
END |
IF TARGETS.CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN |
check(ARITH.range(code, 0, 255), pos2, 42) |
ELSIF TARGETS.CPU = TARGETS.cpuTHUMB THEN |
check(ARITH.range(code, 0, 65535), pos2, 110) |
END; |
IL.AddCmd(IL.opCODE, ARITH.getInt(code)); |
comma := parser.sym = SCAN.lxCOMMA; |
1026,7 → 1001,7 |
checklex(parser, SCAN.lxSEMI); |
Next(parser); |
IF _import = NIL THEN |
IF import = NIL THEN |
IF parser.main & proc.export & TARGETS.Dll THEN |
IF TARGETS.target = TARGETS.KolibriOSDLL THEN |
1040,13 → 1015,13 |
b := DeclarationSequence(parser) |
END; |
PROG.ResetLocSize; |
program.locsize := 0; |
IF call IN {PROG._win64, PROG.win64} THEN |
fparams := PROG.getFloatParamsPos(proc._type, 3, int, flt); |
enter := IL.Enter(label, LSL(ORD(fparams), 5) + MIN(proc._type.parSize, 4)) |
fparams := PROG.getFloatParamsPos(proc.type, 3, int, flt); |
enter := IL.Enter(label, LSL(ORD(fparams), 5) + MIN(proc.type.parSize, 4)) |
ELSIF call IN {PROG._systemv, PROG.systemv} THEN |
fparams := PROG.getFloatParamsPos(proc._type, PROG.MAXSYSVPARAM - 1, int, flt); |
enter := IL.Enter(label, -(LSL(ORD(fparams), 5) + proc._type.parSize)) |
fparams := PROG.getFloatParamsPos(proc.type, PROG.MAXSYSVPARAM - 1, int, flt); |
enter := IL.Enter(label, -(LSL(ORD(fparams), 5) + proc.type.parSize)) |
ELSIF codeProc THEN |
ELSE |
1067,9 → 1042,9 |
END; |
IF ~codeProc THEN |
proc.proc.leave := IL.Leave(t.base # NIL, (t.base # NIL) & (t.base.typ = PROG.tREAL), PROG.program.locsize, |
proc.proc.leave := IL.Leave(t.base # NIL, (t.base # NIL) & (t.base.typ = PROG.tREAL), program.locsize, |
t.parSize * ORD((t.call IN PROG.callee_clean_up) OR (t.call IN {PROG.systemv, PROG._systemv}))); |
enter.param2 := PROG.program.locsize; |
enter.param2 := program.locsize; |
checklex(parser, SCAN.lxEND) |
ELSE |
proc.proc.leave := IL.LeaveC() |
1076,16 → 1051,15 |
END; |
IF TARGETS.CPU = TARGETS.cpuMSP430 THEN |
check((enter.param2 * ORD(~codeProc) + proc._type.parSize) * 2 + 16 < PROG.program.options.ram, pos1, 63) |
check((enter.param2 * ORD(~codeProc) + proc.type.parSize) * 2 + 16 < program.options.ram, pos1, 63) |
END |
END; |
IF parser.sym = SCAN.lxEND THEN |
Next(parser); |
IF parser.sym = SCAN.lxIDENT THEN |
ExpectSym(parser, SCAN.lxIDENT); |
getpos(parser, pos); |
endname := parser.lex.ident; |
IF ~codeProc & (_import = NIL) THEN |
IF ~codeProc & (import = NIL) THEN |
check(endname = name, pos, 60); |
ExpectSym(parser, SCAN.lxSEMI); |
Next(parser) |
1101,14 → 1075,9 |
error(pos, 60) |
END |
END |
ELSIF parser.sym = SCAN.lxSEMI THEN |
Next(parser) |
ELSE |
checklex(parser, SCAN.lxIDENT) |
END |
END; |
IF ~codeProc & (_import = NIL) THEN |
IF ~codeProc & (import = NIL) THEN |
variables := LISTS.create(NIL); |
ELSE |
variables := NIL |
1116,7 → 1085,7 |
PROG.closeScope(unit, variables); |
IF ~codeProc & (_import = NIL) THEN |
IF ~codeProc & (import = NIL) THEN |
enter.variables := variables |
END |
1188,7 → 1157,7 |
check1(parser.lex.s = parser.modname, parser, 23) |
END; |
unit := PROG.newUnit(parser.lex.ident); |
unit := PROG.newUnit(program, parser.lex.ident); |
parser.unit := unit; |
1202,7 → 1171,9 |
INC(modules); |
CONSOLE.String("compiling "); |
CONSOLE.String("("); CONSOLE.Int(modules); CONSOLE.String(") "); |
IF TARGETS.CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuMSP430} THEN |
CONSOLE.String("("); CONSOLE.Int(modules); CONSOLE.String(") ") |
END; |
CONSOLE.String(unit.name.s); |
IF parser.unit.sysimport THEN |
CONSOLE.String(" (SYSTEM)") |
1209,10 → 1180,6 |
END; |
CONSOLE.Ln; |
IF TARGETS.CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN |
IL.fname(parser.fname) |
END; |
label := IL.NewLabel(); |
IL.AddJmpCmd(IL.opJMP, label); |
1222,7 → 1189,9 |
IL.SetLabel(errlabel); |
IL.StrAdr(name); |
IL.Param1; |
IL.AddCmd(IL.opPUSHC, modules); |
IF TARGETS.CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuMSP430} THEN |
IL.AddCmd(IL.opPUSHC, modules) |
END; |
IL.AddCmd0(IL.opERR); |
FOR errno := 1 TO LEN(IL.codes.errlabels) - 1 DO |
1316,7 → 1285,7 |
PROCEDURE init* (options: PROG.OPTIONS); |
BEGIN |
PROG.create(options); |
program := PROG.create(options); |
parsers := C.create(); |
lines := 0; |
modules := 0 |
/programs/develop/oberon07/Source/PE32.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2020, Anton Krotov |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
102,6 → 102,15 |
END; |
IMAGE_NT_HEADERS = RECORD |
Signature: ARRAY 4 OF BYTE; |
FileHeader: IMAGE_FILE_HEADER; |
OptionalHeader: IMAGE_OPTIONAL_HEADER |
END; |
IMAGE_SECTION_HEADER* = RECORD |
Name*: NAME; |
138,33 → 147,35 |
END; |
VIRTUAL_ADDR* = RECORD |
VIRTUAL_ADDR = RECORD |
Code*, Data*, Bss*, Import*: INTEGER |
Code, Data, Bss, Import: INTEGER |
END; |
FILE = WR.FILE; |
VAR |
Signature: ARRAY 4 OF BYTE; |
FileHeader: IMAGE_FILE_HEADER; |
OptionalHeader: IMAGE_OPTIONAL_HEADER; |
msdos: ARRAY 128 OF BYTE; |
PEHeader: IMAGE_NT_HEADERS; |
SectionHeaders: ARRAY 16 OF IMAGE_SECTION_HEADER; |
Relocations: LISTS.LIST; |
bit64: BOOLEAN; |
libcnt: INTEGER; |
SizeOfWord: INTEGER; |
PROCEDURE Export (program: BIN.PROGRAM; name: INTEGER; VAR ExportDir: IMAGE_EXPORT_DIRECTORY): INTEGER; |
PROCEDURE Export (program: BIN.PROGRAM; DataRVA: INTEGER; VAR ExportDir: IMAGE_EXPORT_DIRECTORY): INTEGER; |
BEGIN |
ExportDir.Characteristics := 0; |
ExportDir.TimeDateStamp := FileHeader.TimeDateStamp; |
ExportDir.TimeDateStamp := PEHeader.FileHeader.TimeDateStamp; |
ExportDir.MajorVersion := 0X; |
ExportDir.MinorVersion := 0X; |
ExportDir.Name := name; |
ExportDir.Name := program.modname + DataRVA; |
ExportDir.Base := 0; |
ExportDir.NumberOfFunctions := LISTS.count(program.exp_list); |
ExportDir.NumberOfNames := ExportDir.NumberOfFunctions; |
176,17 → 187,27 |
END Export; |
PROCEDURE align (n, _align: INTEGER): INTEGER; |
BEGIN |
IF n MOD _align # 0 THEN |
n := n + _align - (n MOD _align) |
END |
RETURN n |
END align; |
PROCEDURE GetProcCount (lib: BIN.IMPRT): INTEGER; |
VAR |
imp: BIN.IMPRT; |
import: BIN.IMPRT; |
res: INTEGER; |
BEGIN |
res := 0; |
imp := lib.next(BIN.IMPRT); |
WHILE (imp # NIL) & (imp.label # 0) DO |
import := lib.next(BIN.IMPRT); |
WHILE (import # NIL) & (import.label # 0) DO |
INC(res); |
imp := imp.next(BIN.IMPRT) |
import := import.next(BIN.IMPRT) |
END |
RETURN res |
195,7 → 216,7 |
PROCEDURE GetImportSize (imp_list: LISTS.LIST): INTEGER; |
VAR |
imp: BIN.IMPRT; |
import: BIN.IMPRT; |
proccnt: INTEGER; |
procoffs: INTEGER; |
OriginalCurrentThunk, |
204,33 → 225,33 |
BEGIN |
libcnt := 0; |
proccnt := 0; |
imp := imp_list.first(BIN.IMPRT); |
WHILE imp # NIL DO |
IF imp.label = 0 THEN |
import := imp_list.first(BIN.IMPRT); |
WHILE import # NIL DO |
IF import.label = 0 THEN |
INC(libcnt) |
ELSE |
INC(proccnt) |
END; |
imp := imp.next(BIN.IMPRT) |
import := import.next(BIN.IMPRT) |
END; |
procoffs := 0; |
imp := imp_list.first(BIN.IMPRT); |
WHILE imp # NIL DO |
IF imp.label = 0 THEN |
imp.OriginalFirstThunk := procoffs; |
imp.FirstThunk := procoffs + (GetProcCount(imp) + 1); |
OriginalCurrentThunk := imp.OriginalFirstThunk; |
CurrentThunk := imp.FirstThunk; |
INC(procoffs, (GetProcCount(imp) + 1) * 2) |
import := imp_list.first(BIN.IMPRT); |
WHILE import # NIL DO |
IF import.label = 0 THEN |
import.OriginalFirstThunk := procoffs; |
import.FirstThunk := procoffs + (GetProcCount(import) + 1); |
OriginalCurrentThunk := import.OriginalFirstThunk; |
CurrentThunk := import.FirstThunk; |
procoffs := procoffs + (GetProcCount(import) + 1) * 2 |
ELSE |
imp.OriginalFirstThunk := OriginalCurrentThunk; |
imp.FirstThunk := CurrentThunk; |
import.OriginalFirstThunk := OriginalCurrentThunk; |
import.FirstThunk := CurrentThunk; |
INC(OriginalCurrentThunk); |
INC(CurrentThunk) |
END; |
imp := imp.next(BIN.IMPRT) |
import := import.next(BIN.IMPRT) |
END |
RETURN (libcnt + 1) * 5 * SIZE_OF_DWORD + (proccnt + libcnt) * 2 * SizeOfWord |
237,40 → 258,40 |
END GetImportSize; |
PROCEDURE fixup* (program: BIN.PROGRAM; Address: VIRTUAL_ADDR; amd64: BOOLEAN); |
PROCEDURE fixup (program: BIN.PROGRAM; Address: VIRTUAL_ADDR); |
VAR |
reloc: BIN.RELOC; |
iproc: BIN.IMPRT; |
code: CHL.BYTELIST; |
L, delta, delta0, AdrImp, offset: INTEGER; |
L, delta, delta0, AdrImp: INTEGER; |
BEGIN |
AdrImp := Address.Import + (libcnt + 1) * 5 * SIZE_OF_DWORD; |
code := program.code; |
reloc := program.rel_list.first(BIN.RELOC); |
delta0 := 3 - 7 * ORD(amd64) - Address.Code; |
delta0 := 3 - 7 * ORD(bit64); |
WHILE reloc # NIL DO |
offset := reloc.offset; |
L := BIN.get32le(code, offset); |
delta := delta0 - offset; |
L := BIN.get32le(code, reloc.offset); |
delta := delta0 - reloc.offset - Address.Code; |
CASE reloc.opcode OF |
|BIN.PICDATA: |
INC(delta, L + Address.Data) |
BIN.put32le(code, reloc.offset, L + Address.Data + delta) |
|BIN.PICCODE: |
INC(delta, BIN.GetLabel(program, L) + Address.Code) |
BIN.put32le(code, reloc.offset, BIN.GetLabel(program, L) + Address.Code + delta) |
|BIN.PICBSS: |
INC(delta, L + Address.Bss) |
BIN.put32le(code, reloc.offset, L + Address.Bss + delta) |
|BIN.PICIMP: |
iproc := BIN.GetIProc(program, L); |
INC(delta, iproc.FirstThunk * SizeOfWord + AdrImp) |
BIN.put32le(code, reloc.offset, iproc.FirstThunk * SizeOfWord + AdrImp + delta) |
END; |
BIN.put32le(code, offset, delta); |
reloc := reloc.next(BIN.RELOC) |
END |
277,13 → 298,13 |
END fixup; |
PROCEDURE WriteWord (w: WORD); |
PROCEDURE WriteWord (file: FILE; w: WORD); |
BEGIN |
WR.Write16LE(ORD(w)) |
WR.Write16LE(file, ORD(w)) |
END WriteWord; |
PROCEDURE WriteName* (name: NAME); |
PROCEDURE WriteName* (File: FILE; name: NAME); |
VAR |
i, nameLen: INTEGER; |
291,12 → 312,12 |
nameLen := LENGTH(name); |
FOR i := 0 TO nameLen - 1 DO |
WR.WriteByte(ORD(name[i])) |
WR.WriteByte(File, ORD(name[i])) |
END; |
i := LEN(name) - nameLen; |
WHILE i > 0 DO |
WR.WriteByte(0); |
WR.WriteByte(File, 0); |
DEC(i) |
END |
303,7 → 324,7 |
END WriteName; |
PROCEDURE WriteSectionHeader* (h: IMAGE_SECTION_HEADER); |
PROCEDURE WriteSectionHeader* (file: FILE; h: IMAGE_SECTION_HEADER); |
VAR |
i, nameLen: INTEGER; |
311,50 → 332,50 |
nameLen := LENGTH(h.Name); |
FOR i := 0 TO nameLen - 1 DO |
WR.WriteByte(ORD(h.Name[i])) |
WR.WriteByte(file, ORD(h.Name[i])) |
END; |
i := LEN(h.Name) - nameLen; |
WHILE i > 0 DO |
WR.WriteByte(0); |
WR.WriteByte(file, 0); |
DEC(i) |
END; |
WR.Write32LE(h.VirtualSize); |
WR.Write32LE(h.VirtualAddress); |
WR.Write32LE(h.SizeOfRawData); |
WR.Write32LE(h.PointerToRawData); |
WR.Write32LE(h.PointerToRelocations); |
WR.Write32LE(h.PointerToLinenumbers); |
WR.Write32LE(file, h.VirtualSize); |
WR.Write32LE(file, h.VirtualAddress); |
WR.Write32LE(file, h.SizeOfRawData); |
WR.Write32LE(file, h.PointerToRawData); |
WR.Write32LE(file, h.PointerToRelocations); |
WR.Write32LE(file, h.PointerToLinenumbers); |
WriteWord(h.NumberOfRelocations); |
WriteWord(h.NumberOfLinenumbers); |
WriteWord(file, h.NumberOfRelocations); |
WriteWord(file, h.NumberOfLinenumbers); |
WR.Write32LE(h.Characteristics) |
WR.Write32LE(file, h.Characteristics) |
END WriteSectionHeader; |
PROCEDURE WriteFileHeader* (h: IMAGE_FILE_HEADER); |
PROCEDURE WriteFileHeader* (file: FILE; h: IMAGE_FILE_HEADER); |
BEGIN |
WriteWord(h.Machine); |
WriteWord(h.NumberOfSections); |
WriteWord(file, h.Machine); |
WriteWord(file, h.NumberOfSections); |
WR.Write32LE(h.TimeDateStamp); |
WR.Write32LE(h.PointerToSymbolTable); |
WR.Write32LE(h.NumberOfSymbols); |
WR.Write32LE(file, h.TimeDateStamp); |
WR.Write32LE(file, h.PointerToSymbolTable); |
WR.Write32LE(file, h.NumberOfSymbols); |
WriteWord(h.SizeOfOptionalHeader); |
WriteWord(h.Characteristics) |
WriteWord(file, h.SizeOfOptionalHeader); |
WriteWord(file, h.Characteristics) |
END WriteFileHeader; |
PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR; console, dll, amd64: BOOLEAN); |
VAR |
i, n, temp: INTEGER; |
i, n: INTEGER; |
Size: RECORD |
Code, Data, Bss, Import, Reloc, Export: INTEGER |
Code, Data, Bss, Stack, Import, Reloc, Export: INTEGER |
END; |
362,7 → 383,9 |
Address: VIRTUAL_ADDR; |
_import: BIN.IMPRT; |
File: FILE; |
import: BIN.IMPRT; |
ImportTable: CHL.INTLIST; |
ExportDir: IMAGE_EXPORT_DIRECTORY; |
369,93 → 392,99 |
export: BIN.EXPRT; |
PROCEDURE WriteExportDir (e: IMAGE_EXPORT_DIRECTORY); |
PROCEDURE WriteExportDir (file: FILE; e: IMAGE_EXPORT_DIRECTORY); |
BEGIN |
WR.Write32LE(e.Characteristics); |
WR.Write32LE(e.TimeDateStamp); |
WR.Write32LE(file, e.Characteristics); |
WR.Write32LE(file, e.TimeDateStamp); |
WriteWord(e.MajorVersion); |
WriteWord(e.MinorVersion); |
WriteWord(file, e.MajorVersion); |
WriteWord(file, e.MinorVersion); |
WR.Write32LE(e.Name); |
WR.Write32LE(e.Base); |
WR.Write32LE(e.NumberOfFunctions); |
WR.Write32LE(e.NumberOfNames); |
WR.Write32LE(e.AddressOfFunctions); |
WR.Write32LE(e.AddressOfNames); |
WR.Write32LE(e.AddressOfNameOrdinals) |
WR.Write32LE(file, e.Name); |
WR.Write32LE(file, e.Base); |
WR.Write32LE(file, e.NumberOfFunctions); |
WR.Write32LE(file, e.NumberOfNames); |
WR.Write32LE(file, e.AddressOfFunctions); |
WR.Write32LE(file, e.AddressOfNames); |
WR.Write32LE(file, e.AddressOfNameOrdinals) |
END WriteExportDir; |
PROCEDURE WriteOptHeader (h: IMAGE_OPTIONAL_HEADER; amd64: BOOLEAN); |
PROCEDURE WriteOptHeader (file: FILE; h: IMAGE_OPTIONAL_HEADER); |
VAR |
i: INTEGER; |
BEGIN |
WriteWord(h.Magic); |
WriteWord(file, h.Magic); |
WR.WriteByte(h.MajorLinkerVersion); |
WR.WriteByte(h.MinorLinkerVersion); |
WR.WriteByte(file, h.MajorLinkerVersion); |
WR.WriteByte(file, h.MinorLinkerVersion); |
WR.Write32LE(h.SizeOfCode); |
WR.Write32LE(h.SizeOfInitializedData); |
WR.Write32LE(h.SizeOfUninitializedData); |
WR.Write32LE(h.AddressOfEntryPoint); |
WR.Write32LE(h.BaseOfCode); |
WR.Write32LE(file, h.SizeOfCode); |
WR.Write32LE(file, h.SizeOfInitializedData); |
WR.Write32LE(file, h.SizeOfUninitializedData); |
WR.Write32LE(file, h.AddressOfEntryPoint); |
WR.Write32LE(file, h.BaseOfCode); |
IF amd64 THEN |
WR.Write64LE(h.ImageBase) |
IF bit64 THEN |
WR.Write64LE(file, h.ImageBase) |
ELSE |
WR.Write32LE(h.BaseOfData); |
WR.Write32LE(h.ImageBase) |
WR.Write32LE(file, h.BaseOfData); |
WR.Write32LE(file, h.ImageBase) |
END; |
WR.Write32LE(h.SectionAlignment); |
WR.Write32LE(h.FileAlignment); |
WR.Write32LE(file, h.SectionAlignment); |
WR.Write32LE(file, h.FileAlignment); |
WriteWord(h.MajorOperatingSystemVersion); |
WriteWord(h.MinorOperatingSystemVersion); |
WriteWord(h.MajorImageVersion); |
WriteWord(h.MinorImageVersion); |
WriteWord(h.MajorSubsystemVersion); |
WriteWord(h.MinorSubsystemVersion); |
WriteWord(file, h.MajorOperatingSystemVersion); |
WriteWord(file, h.MinorOperatingSystemVersion); |
WriteWord(file, h.MajorImageVersion); |
WriteWord(file, h.MinorImageVersion); |
WriteWord(file, h.MajorSubsystemVersion); |
WriteWord(file, h.MinorSubsystemVersion); |
WR.Write32LE(h.Win32VersionValue); |
WR.Write32LE(h.SizeOfImage); |
WR.Write32LE(h.SizeOfHeaders); |
WR.Write32LE(h.CheckSum); |
WR.Write32LE(file, h.Win32VersionValue); |
WR.Write32LE(file, h.SizeOfImage); |
WR.Write32LE(file, h.SizeOfHeaders); |
WR.Write32LE(file, h.CheckSum); |
WriteWord(h.Subsystem); |
WriteWord(h.DllCharacteristics); |
WriteWord(file, h.Subsystem); |
WriteWord(file, h.DllCharacteristics); |
IF amd64 THEN |
WR.Write64LE(h.SizeOfStackReserve); |
WR.Write64LE(h.SizeOfStackCommit); |
WR.Write64LE(h.SizeOfHeapReserve); |
WR.Write64LE(h.SizeOfHeapCommit) |
IF bit64 THEN |
WR.Write64LE(file, h.SizeOfStackReserve); |
WR.Write64LE(file, h.SizeOfStackCommit); |
WR.Write64LE(file, h.SizeOfHeapReserve); |
WR.Write64LE(file, h.SizeOfHeapCommit) |
ELSE |
WR.Write32LE(h.SizeOfStackReserve); |
WR.Write32LE(h.SizeOfStackCommit); |
WR.Write32LE(h.SizeOfHeapReserve); |
WR.Write32LE(h.SizeOfHeapCommit) |
WR.Write32LE(file, h.SizeOfStackReserve); |
WR.Write32LE(file, h.SizeOfStackCommit); |
WR.Write32LE(file, h.SizeOfHeapReserve); |
WR.Write32LE(file, h.SizeOfHeapCommit) |
END; |
WR.Write32LE(h.LoaderFlags); |
WR.Write32LE(h.NumberOfRvaAndSizes); |
WR.Write32LE(file, h.LoaderFlags); |
WR.Write32LE(file, h.NumberOfRvaAndSizes); |
FOR i := 0 TO LEN(h.DataDirectory) - 1 DO |
WR.Write32LE(h.DataDirectory[i].VirtualAddress); |
WR.Write32LE(h.DataDirectory[i].Size) |
WR.Write32LE(file, h.DataDirectory[i].VirtualAddress); |
WR.Write32LE(file, h.DataDirectory[i].Size) |
END |
END WriteOptHeader; |
PROCEDURE InitSection (VAR section: IMAGE_SECTION_HEADER; Name: NAME; VirtualSize: INTEGER; Characteristics: DWORD); |
PROCEDURE WritePEHeader (file: FILE; h: IMAGE_NT_HEADERS); |
BEGIN |
WR.Write(file, h.Signature, LEN(h.Signature)); |
WriteFileHeader(file, h.FileHeader); |
WriteOptHeader(file, h.OptionalHeader) |
END WritePEHeader; |
PROCEDURE InitSection (VAR section: IMAGE_SECTION_HEADER; Name: NAME; Characteristics: DWORD); |
BEGIN |
section.Name := Name; |
section.VirtualSize := VirtualSize; |
section.SizeOfRawData := WR.align(VirtualSize, FileAlignment); |
section.PointerToRelocations := 0; |
section.PointerToLinenumbers := 0; |
section.NumberOfRelocations := 0X; |
465,11 → 494,14 |
BEGIN |
SizeOfWord := SIZE_OF_DWORD * (ORD(amd64) + 1); |
bit64 := amd64; |
SizeOfWord := SIZE_OF_DWORD * (ORD(bit64) + 1); |
Relocations := LISTS.create(NIL); |
Size.Code := CHL.Length(program.code); |
Size.Data := CHL.Length(program.data); |
Size.Bss := program.bss; |
Size.Stack := program.stack; |
IF dll THEN |
BaseAddress := 10000000H |
477,109 → 509,123 |
BaseAddress := 400000H |
END; |
Signature[0] := 50H; |
Signature[1] := 45H; |
Signature[2] := 0; |
Signature[3] := 0; |
PEHeader.Signature[0] := 50H; |
PEHeader.Signature[1] := 45H; |
PEHeader.Signature[2] := 0; |
PEHeader.Signature[3] := 0; |
IF amd64 THEN |
FileHeader.Machine := 08664X |
PEHeader.FileHeader.Machine := 08664X |
ELSE |
FileHeader.Machine := 014CX |
PEHeader.FileHeader.Machine := 014CX |
END; |
FileHeader.NumberOfSections := WCHR(4 + ORD(dll)); |
PEHeader.FileHeader.NumberOfSections := WCHR(4 + ORD(dll)); |
FileHeader.TimeDateStamp := UTILS.UnixTime(); |
FileHeader.PointerToSymbolTable := 0H; |
FileHeader.NumberOfSymbols := 0H; |
FileHeader.SizeOfOptionalHeader := WCHR(0E0H + 10H * ORD(amd64)); |
FileHeader.Characteristics := WCHR(010EH + (20H - 100H) * ORD(amd64) + 2000H * ORD(dll)); |
PEHeader.FileHeader.TimeDateStamp := UTILS.UnixTime(); |
PEHeader.FileHeader.PointerToSymbolTable := 0H; |
PEHeader.FileHeader.NumberOfSymbols := 0H; |
PEHeader.FileHeader.SizeOfOptionalHeader := WCHR(0E0H + 10H * ORD(amd64)); |
PEHeader.FileHeader.Characteristics := WCHR(010EH + (20H - 100H) * ORD(amd64) + 2000H * ORD(dll)); |
OptionalHeader.Magic := WCHR(010BH + 100H * ORD(amd64)); |
OptionalHeader.MajorLinkerVersion := UTILS.vMajor; |
OptionalHeader.MinorLinkerVersion := UTILS.vMinor; |
OptionalHeader.SizeOfCode := WR.align(Size.Code, FileAlignment); |
OptionalHeader.SizeOfInitializedData := 0; |
OptionalHeader.SizeOfUninitializedData := 0; |
OptionalHeader.AddressOfEntryPoint := SectionAlignment; |
OptionalHeader.BaseOfCode := SectionAlignment; |
OptionalHeader.BaseOfData := OptionalHeader.BaseOfCode + WR.align(Size.Code, SectionAlignment); |
OptionalHeader.ImageBase := BaseAddress; |
OptionalHeader.SectionAlignment := SectionAlignment; |
OptionalHeader.FileAlignment := FileAlignment; |
OptionalHeader.MajorOperatingSystemVersion := 1X; |
OptionalHeader.MinorOperatingSystemVersion := 0X; |
OptionalHeader.MajorImageVersion := 0X; |
OptionalHeader.MinorImageVersion := 0X; |
OptionalHeader.MajorSubsystemVersion := 4X; |
OptionalHeader.MinorSubsystemVersion := 0X; |
OptionalHeader.Win32VersionValue := 0H; |
OptionalHeader.SizeOfImage := SectionAlignment; |
OptionalHeader.SizeOfHeaders := 400H; |
OptionalHeader.CheckSum := 0; |
OptionalHeader.Subsystem := WCHR((2 + ORD(console)) * ORD(~dll)); |
OptionalHeader.DllCharacteristics := 0040X; |
OptionalHeader.SizeOfStackReserve := 100000H; |
OptionalHeader.SizeOfStackCommit := 10000H; |
OptionalHeader.SizeOfHeapReserve := 100000H; |
OptionalHeader.SizeOfHeapCommit := 10000H; |
OptionalHeader.LoaderFlags := 0; |
OptionalHeader.NumberOfRvaAndSizes := IMAGE_NUMBEROF_DIRECTORY_ENTRIES; |
PEHeader.OptionalHeader.Magic := WCHR(010BH + 100H * ORD(amd64)); |
PEHeader.OptionalHeader.MajorLinkerVersion := UTILS.vMajor; |
PEHeader.OptionalHeader.MinorLinkerVersion := UTILS.vMinor; |
PEHeader.OptionalHeader.SizeOfCode := align(Size.Code, FileAlignment); |
PEHeader.OptionalHeader.SizeOfInitializedData := 0; |
PEHeader.OptionalHeader.SizeOfUninitializedData := 0; |
PEHeader.OptionalHeader.AddressOfEntryPoint := SectionAlignment; |
PEHeader.OptionalHeader.BaseOfCode := SectionAlignment; |
PEHeader.OptionalHeader.BaseOfData := PEHeader.OptionalHeader.BaseOfCode + align(Size.Code, SectionAlignment); |
PEHeader.OptionalHeader.ImageBase := BaseAddress; |
PEHeader.OptionalHeader.SectionAlignment := SectionAlignment; |
PEHeader.OptionalHeader.FileAlignment := FileAlignment; |
PEHeader.OptionalHeader.MajorOperatingSystemVersion := 1X; |
PEHeader.OptionalHeader.MinorOperatingSystemVersion := 0X; |
PEHeader.OptionalHeader.MajorImageVersion := 0X; |
PEHeader.OptionalHeader.MinorImageVersion := 0X; |
PEHeader.OptionalHeader.MajorSubsystemVersion := 4X; |
PEHeader.OptionalHeader.MinorSubsystemVersion := 0X; |
PEHeader.OptionalHeader.Win32VersionValue := 0H; |
PEHeader.OptionalHeader.SizeOfImage := SectionAlignment; |
PEHeader.OptionalHeader.SizeOfHeaders := 400H; |
PEHeader.OptionalHeader.CheckSum := 0; |
PEHeader.OptionalHeader.Subsystem := WCHR((2 + ORD(console)) * ORD(~dll)); |
PEHeader.OptionalHeader.DllCharacteristics := 0040X; |
PEHeader.OptionalHeader.SizeOfStackReserve := Size.Stack; |
PEHeader.OptionalHeader.SizeOfStackCommit := Size.Stack DIV 16; |
PEHeader.OptionalHeader.SizeOfHeapReserve := 100000H; |
PEHeader.OptionalHeader.SizeOfHeapCommit := 10000H; |
PEHeader.OptionalHeader.LoaderFlags := 0; |
PEHeader.OptionalHeader.NumberOfRvaAndSizes := IMAGE_NUMBEROF_DIRECTORY_ENTRIES; |
FOR i := 0 TO IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 DO |
OptionalHeader.DataDirectory[i].VirtualAddress := 0; |
OptionalHeader.DataDirectory[i].Size := 0 |
END; |
InitSection(SectionHeaders[0], ".text", Size.Code, SHC_text); |
InitSection(SectionHeaders[0], ".text", SHC_text); |
SectionHeaders[0].VirtualSize := Size.Code; |
SectionHeaders[0].VirtualAddress := SectionAlignment; |
SectionHeaders[0].PointerToRawData := OptionalHeader.SizeOfHeaders; |
SectionHeaders[0].SizeOfRawData := align(Size.Code, FileAlignment); |
SectionHeaders[0].PointerToRawData := PEHeader.OptionalHeader.SizeOfHeaders; |
InitSection(SectionHeaders[1], ".data", Size.Data, SHC_data); |
SectionHeaders[1].VirtualAddress := WR.align(SectionHeaders[0].VirtualAddress + SectionHeaders[0].VirtualSize, SectionAlignment); |
InitSection(SectionHeaders[1], ".data", SHC_data); |
SectionHeaders[1].VirtualSize := Size.Data; |
SectionHeaders[1].VirtualAddress := align(SectionHeaders[0].VirtualAddress + SectionHeaders[0].VirtualSize, SectionAlignment); |
SectionHeaders[1].SizeOfRawData := align(Size.Data, FileAlignment); |
SectionHeaders[1].PointerToRawData := SectionHeaders[0].PointerToRawData + SectionHeaders[0].SizeOfRawData; |
InitSection(SectionHeaders[2], ".bss", Size.Bss, SHC_bss); |
SectionHeaders[2].VirtualAddress := WR.align(SectionHeaders[1].VirtualAddress + SectionHeaders[1].VirtualSize, SectionAlignment); |
InitSection(SectionHeaders[2], ".bss", SHC_bss); |
SectionHeaders[2].VirtualSize := Size.Bss; |
SectionHeaders[2].VirtualAddress := align(SectionHeaders[1].VirtualAddress + SectionHeaders[1].VirtualSize, SectionAlignment); |
SectionHeaders[2].SizeOfRawData := 0; |
SectionHeaders[2].PointerToRawData := SectionHeaders[1].PointerToRawData + SectionHeaders[1].SizeOfRawData; |
SectionHeaders[2].SizeOfRawData := 0; |
Size.Import := GetImportSize(program.imp_list); |
InitSection(SectionHeaders[3], ".idata", Size.Import + CHL.Length(program._import), SHC_data); |
SectionHeaders[3].VirtualAddress := WR.align(SectionHeaders[2].VirtualAddress + SectionHeaders[2].VirtualSize, SectionAlignment); |
InitSection(SectionHeaders[3], ".idata", SHC_data); |
SectionHeaders[3].VirtualSize := Size.Import + CHL.Length(program.import); |
SectionHeaders[3].VirtualAddress := align(SectionHeaders[2].VirtualAddress + SectionHeaders[2].VirtualSize, SectionAlignment); |
SectionHeaders[3].SizeOfRawData := align(SectionHeaders[3].VirtualSize, FileAlignment); |
SectionHeaders[3].PointerToRawData := SectionHeaders[2].PointerToRawData + SectionHeaders[2].SizeOfRawData; |
Address.Code := SectionHeaders[0].VirtualAddress + OptionalHeader.ImageBase; |
Address.Data := SectionHeaders[1].VirtualAddress + OptionalHeader.ImageBase; |
Address.Bss := SectionHeaders[2].VirtualAddress + OptionalHeader.ImageBase; |
Address.Import := SectionHeaders[3].VirtualAddress + OptionalHeader.ImageBase; |
Address.Code := SectionHeaders[0].VirtualAddress + PEHeader.OptionalHeader.ImageBase; |
Address.Data := SectionHeaders[1].VirtualAddress + PEHeader.OptionalHeader.ImageBase; |
Address.Bss := SectionHeaders[2].VirtualAddress + PEHeader.OptionalHeader.ImageBase; |
Address.Import := SectionHeaders[3].VirtualAddress + PEHeader.OptionalHeader.ImageBase; |
fixup(program, Address, amd64); |
fixup(program, Address); |
IF dll THEN |
Size.Export := Export(program, SectionHeaders[1].VirtualAddress + program.modname, ExportDir); |
Size.Export := Export(program, SectionHeaders[1].VirtualAddress, ExportDir); |
InitSection(SectionHeaders[4], ".edata", Size.Export + CHL.Length(program.export), SHC_data); |
SectionHeaders[4].VirtualAddress := WR.align(SectionHeaders[3].VirtualAddress + SectionHeaders[3].VirtualSize, SectionAlignment); |
InitSection(SectionHeaders[4], ".edata", SHC_data); |
SectionHeaders[4].VirtualSize := Size.Export + CHL.Length(program.export); |
SectionHeaders[4].VirtualAddress := align(SectionHeaders[3].VirtualAddress + SectionHeaders[3].VirtualSize, SectionAlignment); |
SectionHeaders[4].SizeOfRawData := align(SectionHeaders[4].VirtualSize, FileAlignment); |
SectionHeaders[4].PointerToRawData := SectionHeaders[3].PointerToRawData + SectionHeaders[3].SizeOfRawData; |
END; |
OptionalHeader.DataDirectory[0].VirtualAddress := SectionHeaders[4].VirtualAddress; |
OptionalHeader.DataDirectory[0].Size := SectionHeaders[4].VirtualSize |
FOR i := 0 TO IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 DO |
PEHeader.OptionalHeader.DataDirectory[i].VirtualAddress := 0; |
PEHeader.OptionalHeader.DataDirectory[i].Size := 0 |
END; |
OptionalHeader.DataDirectory[1].VirtualAddress := SectionHeaders[3].VirtualAddress; |
OptionalHeader.DataDirectory[1].Size := SectionHeaders[3].VirtualSize; |
IF dll THEN |
PEHeader.OptionalHeader.DataDirectory[0].VirtualAddress := SectionHeaders[4].VirtualAddress; |
PEHeader.OptionalHeader.DataDirectory[0].Size := SectionHeaders[4].VirtualSize |
END; |
FOR i := 1 TO ORD(FileHeader.NumberOfSections) - 1 DO |
INC(OptionalHeader.SizeOfInitializedData, SectionHeaders[i].SizeOfRawData) |
PEHeader.OptionalHeader.DataDirectory[1].VirtualAddress := SectionHeaders[3].VirtualAddress; |
PEHeader.OptionalHeader.DataDirectory[1].Size := SectionHeaders[3].VirtualSize; |
FOR i := 0 TO ORD(PEHeader.FileHeader.NumberOfSections) - 1 DO |
INC(PEHeader.OptionalHeader.SizeOfInitializedData, SectionHeaders[i].SizeOfRawData) |
END; |
OptionalHeader.SizeOfUninitializedData := WR.align(SectionHeaders[2].VirtualSize, FileAlignment); |
DEC(PEHeader.OptionalHeader.SizeOfInitializedData, SectionHeaders[0].SizeOfRawData); |
DEC(PEHeader.OptionalHeader.SizeOfInitializedData, SectionHeaders[2].SizeOfRawData); |
FOR i := 0 TO ORD(FileHeader.NumberOfSections) - 1 DO |
INC(OptionalHeader.SizeOfImage, WR.align(SectionHeaders[i].VirtualSize, SectionAlignment)) |
PEHeader.OptionalHeader.SizeOfUninitializedData := align(SectionHeaders[2].VirtualSize, FileAlignment); |
FOR i := 0 TO ORD(PEHeader.FileHeader.NumberOfSections) - 1 DO |
INC(PEHeader.OptionalHeader.SizeOfImage, align(SectionHeaders[i].VirtualSize, SectionAlignment)) |
END; |
n := 0; |
588,25 → 634,23 |
BIN.InitArray(msdos, n, "0E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F"); |
BIN.InitArray(msdos, n, "742062652072756E20696E20444F53206D6F64652E0D0A240000000000000000"); |
WR.Create(FileName); |
File := WR.Create(FileName); |
WR.Write(msdos, LEN(msdos)); |
WR.Write(File, msdos, LEN(msdos)); |
WR.Write(Signature, LEN(Signature)); |
WriteFileHeader(FileHeader); |
WriteOptHeader(OptionalHeader, amd64); |
WritePEHeader(File, PEHeader); |
FOR i := 0 TO ORD(FileHeader.NumberOfSections) - 1 DO |
WriteSectionHeader(SectionHeaders[i]) |
FOR i := 0 TO ORD(PEHeader.FileHeader.NumberOfSections) - 1 DO |
WriteSectionHeader(File, SectionHeaders[i]) |
END; |
WR.Padding(FileAlignment); |
WR.Padding(File, FileAlignment); |
CHL.WriteToFile(program.code); |
WR.Padding(FileAlignment); |
CHL.WriteToFile(File, program.code); |
WR.Padding(File, FileAlignment); |
CHL.WriteToFile(program.data); |
WR.Padding(FileAlignment); |
CHL.WriteToFile(File, program.data); |
WR.Padding(File, FileAlignment); |
n := (libcnt + 1) * 5; |
ImportTable := CHL.CreateIntList(); |
616,17 → 660,17 |
END; |
i := 0; |
_import := program.imp_list.first(BIN.IMPRT); |
WHILE _import # NIL DO |
IF _import.label = 0 THEN |
CHL.SetInt(ImportTable, i + 0, _import.OriginalFirstThunk * SizeOfWord + SectionHeaders[3].VirtualAddress + n * SIZE_OF_DWORD); |
import := program.imp_list.first(BIN.IMPRT); |
WHILE import # NIL DO |
IF import.label = 0 THEN |
CHL.SetInt(ImportTable, i + 0, import.OriginalFirstThunk * SizeOfWord + SectionHeaders[3].VirtualAddress + n * SIZE_OF_DWORD); |
CHL.SetInt(ImportTable, i + 1, 0); |
CHL.SetInt(ImportTable, i + 2, 0); |
CHL.SetInt(ImportTable, i + 3, _import.nameoffs + Size.Import + SectionHeaders[3].VirtualAddress); |
CHL.SetInt(ImportTable, i + 4, _import.FirstThunk * SizeOfWord + SectionHeaders[3].VirtualAddress + n * SIZE_OF_DWORD); |
INC(i, 5) |
CHL.SetInt(ImportTable, i + 3, import.nameoffs + Size.Import + SectionHeaders[3].VirtualAddress); |
CHL.SetInt(ImportTable, i + 4, import.FirstThunk * SizeOfWord + SectionHeaders[3].VirtualAddress + n * SIZE_OF_DWORD); |
i := i + 5 |
END; |
_import := _import.next(BIN.IMPRT) |
import := import.next(BIN.IMPRT) |
END; |
CHL.SetInt(ImportTable, i + 0, 0); |
635,30 → 679,29 |
CHL.SetInt(ImportTable, i + 3, 0); |
CHL.SetInt(ImportTable, i + 4, 0); |
_import := program.imp_list.first(BIN.IMPRT); |
WHILE _import # NIL DO |
IF _import.label # 0 THEN |
temp := _import.nameoffs + Size.Import + SectionHeaders[3].VirtualAddress - 2; |
CHL.SetInt(ImportTable, _import.OriginalFirstThunk + n, temp); |
CHL.SetInt(ImportTable, _import.FirstThunk + n, temp) |
import := program.imp_list.first(BIN.IMPRT); |
WHILE import # NIL DO |
IF import.label # 0 THEN |
CHL.SetInt(ImportTable, import.OriginalFirstThunk + n, import.nameoffs + Size.Import + SectionHeaders[3].VirtualAddress - 2); |
CHL.SetInt(ImportTable, import.FirstThunk + n, import.nameoffs + Size.Import + SectionHeaders[3].VirtualAddress - 2) |
END; |
_import := _import.next(BIN.IMPRT) |
import := import.next(BIN.IMPRT) |
END; |
FOR i := 0 TO n - 1 DO |
WR.Write32LE(CHL.GetInt(ImportTable, i)) |
WR.Write32LE(File, CHL.GetInt(ImportTable, i)) |
END; |
FOR i := n TO CHL.Length(ImportTable) - 1 DO |
IF amd64 THEN |
WR.Write64LE(CHL.GetInt(ImportTable, i)) |
WR.Write64LE(File, CHL.GetInt(ImportTable, i)) |
ELSE |
WR.Write32LE(CHL.GetInt(ImportTable, i)) |
WR.Write32LE(File, CHL.GetInt(ImportTable, i)) |
END |
END; |
CHL.WriteToFile(program._import); |
WR.Padding(FileAlignment); |
CHL.WriteToFile(File, program.import); |
WR.Padding(File, FileAlignment); |
IF dll THEN |
666,29 → 709,29 |
INC(ExportDir.AddressOfNames, SectionHeaders[4].VirtualAddress); |
INC(ExportDir.AddressOfNameOrdinals, SectionHeaders[4].VirtualAddress); |
WriteExportDir(ExportDir); |
WriteExportDir(File, ExportDir); |
export := program.exp_list.first(BIN.EXPRT); |
WHILE export # NIL DO |
WR.Write32LE(export.label + SectionHeaders[0].VirtualAddress); |
WR.Write32LE(File, export.label + SectionHeaders[0].VirtualAddress); |
export := export.next(BIN.EXPRT) |
END; |
export := program.exp_list.first(BIN.EXPRT); |
WHILE export # NIL DO |
WR.Write32LE(export.nameoffs + Size.Export + SectionHeaders[4].VirtualAddress); |
WR.Write32LE(File, export.nameoffs + Size.Export + SectionHeaders[4].VirtualAddress); |
export := export.next(BIN.EXPRT) |
END; |
FOR i := 0 TO ExportDir.NumberOfFunctions - 1 DO |
WriteWord(WCHR(i)) |
WriteWord(File, WCHR(i)) |
END; |
CHL.WriteToFile(program.export); |
WR.Padding(FileAlignment) |
CHL.WriteToFile(File, program.export); |
WR.Padding(File, FileAlignment) |
END; |
WR.Close |
WR.Close(File) |
END write; |
/programs/develop/oberon07/Source/PROG.ob07 |
---|
1,13 → 1,13 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2020, Anton Krotov |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
MODULE PROG; |
IMPORT SCAN, LISTS, ARITH, ERRORS, C := COLLECTIONS, IL, UTILS, TARGETS, STRINGS; |
IMPORT SCAN, LISTS, ARITH, ERRORS, C := COLLECTIONS, IL, UTILS, TARGETS; |
CONST |
24,7 → 24,7 |
tINTEGER* = 1; tBYTE* = 2; tCHAR* = 3; tSET* = 4; |
tBOOLEAN* = 5; tREAL* = 6; tARRAY* = 7; tRECORD* = 8; |
tPOINTER* = 9; tPROCEDURE* = 10; tSTRING* = 11; tNIL* = 12; |
tCARD32* = 13; tANYREC* = 14; tWCHAR* = 15; tNONE* = 16; |
tCARD32* = 13; tANYREC* = 14; tWCHAR* = 15; |
BASICTYPES* = {tINTEGER, tBYTE, tCHAR, tSET, tBOOLEAN, tREAL, tCARD32, tWCHAR}; |
40,15 → 40,15 |
sysSADR* = 31; sysTYPEID* = 32; sysCOPY* = 33; sysINF* = 34; |
sysPUT8* = 35; sysPUT16* = 36; stCOPY* = 37; stWCHR* = 38; |
sysWSADR* = 39; sysPUT32* = 40; (*sysNOP* = 41; sysEINT* = 42; |
sysDINT* = 43;*)sysGET8* = 44; sysGET16* = 45; sysGET32* = 46; |
sysDINT* = 43;*) |
default32* = 2; _default32* = default32 + 1; |
default32* = 2; |
stdcall* = 4; _stdcall* = stdcall + 1; |
ccall* = 6; _ccall* = ccall + 1; |
ccall16* = 8; _ccall16* = ccall16 + 1; |
win64* = 10; _win64* = win64 + 1; |
stdcall64* = 12; _stdcall64* = stdcall64 + 1; |
default64* = 14; _default64* = default64 + 1; |
default64* = 14; |
systemv* = 16; _systemv* = systemv + 1; |
default16* = 18; |
code* = 20; _code* = code + 1; |
59,10 → 59,10 |
sf_stdcall* = 0; sf_stdcall64* = 1; sf_ccall* = 2; sf_ccall16* = 3; |
sf_win64* = 4; sf_systemv* = 5; sf_windows* = 6; sf_linux* = 7; |
sf_code* = 8; sf_oberon* = 9; |
sf_noalign* = 10; |
sf_code* = 8; |
sf_noalign* = 9; |
proc_flags* = {sf_stdcall, sf_stdcall64, sf_ccall, sf_ccall16, sf_win64, sf_systemv, sf_windows, sf_linux, sf_code, sf_oberon}; |
proc_flags* = {sf_stdcall, sf_stdcall64, sf_ccall, sf_ccall16, sf_win64, sf_systemv, sf_windows, sf_linux, sf_code}; |
rec_flags* = {sf_noalign}; |
STACK_FRAME = 2; |
73,7 → 73,7 |
OPTIONS* = RECORD |
version*, stack*, ram*, rom*: INTEGER; |
pic*, lower*: BOOLEAN; |
pic*: BOOLEAN; |
checking*: SET |
END; |
82,11 → 82,13 |
UNIT* = POINTER TO rUNIT; |
_TYPE* = POINTER TO rTYPE; |
PROGRAM* = POINTER TO rPROGRAM; |
TYPE_* = POINTER TO rTYPE_; |
FRWPTR* = POINTER TO RECORD (LISTS.ITEM) |
_type: _TYPE; |
type: TYPE_; |
baseIdent: SCAN.IDENT; |
linked: BOOLEAN; |
100,7 → 102,7 |
label*: INTEGER; |
used*: BOOLEAN; |
processed*: BOOLEAN; |
_import*: LISTS.ITEM; |
import*: LISTS.ITEM; |
using*: LISTS.LIST; |
enter*, |
leave*: LISTS.ITEM |
115,6 → 117,7 |
rUNIT = RECORD (LISTS.ITEM) |
program*: PROGRAM; |
name*: SCAN.IDENT; |
idents*: LISTS.LIST; |
frwPointers: LISTS.LIST; |
130,7 → 133,7 |
PARAM* = POINTER TO rPARAM; |
rTYPE = RECORD (LISTS.ITEM) |
rTYPE_ = RECORD (LISTS.ITEM) |
typ*: INTEGER; |
size*: INTEGER; |
137,7 → 140,7 |
parSize*: INTEGER; |
length*: INTEGER; |
align*: INTEGER; |
base*: _TYPE; |
base*: TYPE_; |
fields*: LISTS.LIST; |
params*: LISTS.LIST; |
unit*: UNIT; |
144,7 → 147,7 |
closed*: BOOLEAN; |
num*: INTEGER; |
call*: INTEGER; |
_import*: BOOLEAN; |
import*: BOOLEAN; |
noalign*: BOOLEAN |
END; |
151,7 → 154,7 |
rFIELD = RECORD (LISTS.ITEM) |
_type*: _TYPE; |
type*: TYPE_; |
name*: SCAN.IDENT; |
export*: BOOLEAN; |
offset*: INTEGER |
161,7 → 164,7 |
rPARAM = RECORD (LISTS.ITEM) |
name*: SCAN.IDENT; |
_type*: _TYPE; |
type*: TYPE_; |
vPar*: BOOLEAN; |
offset*: INTEGER |
172,10 → 175,10 |
name*: SCAN.IDENT; |
typ*: INTEGER; |
export*: BOOLEAN; |
_import*: LISTS.ITEM; |
import*: LISTS.ITEM; |
unit*: UNIT; |
value*: ARITH.VALUE; |
_type*: _TYPE; |
type*: TYPE_; |
stproc*: INTEGER; |
global*: BOOLEAN; |
scopeLvl*: INTEGER; |
185,7 → 188,7 |
END; |
PROGRAM = RECORD |
rPROGRAM = RECORD |
recCount: INTEGER; |
units*: LISTS.LIST; |
203,20 → 206,18 |
stTypes*: RECORD |
tINTEGER*, tBYTE*, tCHAR*, tWCHAR*, tSET*, tBOOLEAN*, tREAL*, |
tSTRING*, tNIL*, tCARD32*, tANYREC*, tNONE*: _TYPE |
tSTRING*, tNIL*, tCARD32*, tANYREC*: TYPE_ |
END |
END; |
DELIMPORT = PROCEDURE (_import: LISTS.ITEM); |
DELIMPORT = PROCEDURE (import: LISTS.ITEM); |
VAR |
LowerCase: BOOLEAN; |
idents: C.COLLECTION; |
program*: PROGRAM; |
PROCEDURE NewIdent (): IDENT; |
236,15 → 237,15 |
END NewIdent; |
PROCEDURE getOffset* (varIdent: IDENT): INTEGER; |
PROCEDURE getOffset* (program: PROGRAM; varIdent: IDENT): INTEGER; |
VAR |
size: INTEGER; |
BEGIN |
IF varIdent.offset = -1 THEN |
size := varIdent._type.size; |
size := varIdent.type.size; |
IF varIdent.global THEN |
IF UTILS.Align(program.bss, varIdent._type.align) THEN |
IF UTILS.Align(program.bss, varIdent.type.align) THEN |
IF UTILS.maxint - program.bss >= size THEN |
varIdent.offset := program.bss; |
INC(program.bss, size) |
280,7 → 281,7 |
IF (ident.typ = idVAR) & (ident.offset = -1) THEN |
ERRORS.HintMsg(ident.name.s, ident.pos.line, ident.pos.col, 0); |
IF ident.export THEN |
offset := getOffset(ident) |
offset := getOffset(unit.program, ident) |
END |
END; |
ident := ident.prev(IDENT) |
321,6 → 322,7 |
item: IDENT; |
res: BOOLEAN; |
proc: PROC; |
procs: LISTS.LIST; |
BEGIN |
ASSERT(unit # NIL); |
335,8 → 337,8 |
item.typ := typ; |
item.unit := NIL; |
item.export := FALSE; |
item._import := NIL; |
item._type := NIL; |
item.import := NIL; |
item.type := NIL; |
item.value.typ := 0; |
item.stproc := 0; |
346,12 → 348,13 |
IF item.typ IN {idPROC, idIMP} THEN |
NEW(proc); |
proc._import := NIL; |
proc.import := NIL; |
proc.label := 0; |
proc.used := FALSE; |
proc.processed := FALSE; |
proc.using := LISTS.create(NIL); |
LISTS.push(program.procs, proc); |
procs := unit.program.procs; |
LISTS.push(procs, proc); |
item.proc := proc |
END; |
390,16 → 393,16 |
END UseProc; |
PROCEDURE setVarsType* (unit: UNIT; _type: _TYPE); |
PROCEDURE setVarsType* (unit: UNIT; type: TYPE_); |
VAR |
item: IDENT; |
BEGIN |
ASSERT(_type # NIL); |
ASSERT(type # NIL); |
item := unit.idents.last(IDENT); |
WHILE (item # NIL) & (item.typ = idVAR) & (item._type = NIL) DO |
item._type := _type; |
WHILE (item # NIL) & (item.typ = idVAR) & (item.type = NIL) DO |
item.type := type; |
item := item.prev(IDENT) |
END |
END setVarsType; |
478,10 → 481,10 |
ERRORS.HintMsg(del.name.s, del.pos.line, del.pos.col, 0) |
END; |
IF (variables # NIL) & (del.typ IN {idVAR, idPARAM}) & (del.offset # -1) THEN |
IF del._type.typ IN BASICTYPES - {tREAL} + {tPOINTER, tPROCEDURE} THEN |
IF del.type.typ IN BASICTYPES - {tREAL} + {tPOINTER, tPROCEDURE} THEN |
lvar := IL.NewVar(); |
lvar.offset := del.offset; |
lvar.size := del._type.size; |
lvar.size := del.type.size; |
IF del.typ = idVAR THEN |
lvar.offset := -lvar.offset |
END; |
501,18 → 504,18 |
END closeScope; |
PROCEDURE frwPtr* (unit: UNIT; _type: _TYPE; baseIdent: SCAN.IDENT; pos: SCAN.POSITION); |
PROCEDURE frwPtr* (unit: UNIT; type: TYPE_; baseIdent: SCAN.IDENT; pos: SCAN.POSITION); |
VAR |
newptr: FRWPTR; |
BEGIN |
ASSERT(unit # NIL); |
ASSERT(_type # NIL); |
ASSERT(type # NIL); |
ASSERT(baseIdent # NIL); |
NEW(newptr); |
newptr._type := _type; |
newptr.type := type; |
newptr.baseIdent := baseIdent; |
newptr.pos := pos; |
newptr.linked := FALSE; |
536,8 → 539,8 |
ident := getIdent(unit, item.baseIdent, TRUE); |
IF (ident # NIL) THEN |
IF (ident.typ = idTYPE) & (ident._type.typ = tRECORD) THEN |
item._type.base := ident._type; |
IF (ident.typ = idTYPE) & (ident.type.typ = tRECORD) THEN |
item.type.base := ident.type; |
item.linked := TRUE |
ELSE |
item.notRecord := TRUE; |
555,7 → 558,7 |
END linkPtr; |
PROCEDURE isTypeEq* (t1, t2: _TYPE): BOOLEAN; |
PROCEDURE isTypeEq* (t1, t2: TYPE_): BOOLEAN; |
VAR |
res: BOOLEAN; |
param1, param2: LISTS.ITEM; |
573,7 → 576,7 |
res := ((t1.call = t2.call) OR (t1.call IN {code, _code}) OR (t2.call IN {code, _code})) & ((param1 # NIL) = (param2 # NIL)); |
WHILE res & (param1 # NIL) & (param2 # NIL) DO |
res := (param1(PARAM).vPar = param2(PARAM).vPar) & isTypeEq(param1(PARAM)._type, param2(PARAM)._type); |
res := (param1(PARAM).vPar = param2(PARAM).vPar) & isTypeEq(param1(PARAM).type, param2(PARAM).type); |
param1 := param1.next; |
param2 := param2.next; |
res := res & ((param1 # NIL) = (param2 # NIL)) |
591,7 → 594,7 |
END isTypeEq; |
PROCEDURE isBaseOf* (t0, t1: _TYPE): BOOLEAN; |
PROCEDURE isBaseOf* (t0, t1: TYPE_): BOOLEAN; |
VAR |
res: BOOLEAN; |
614,12 → 617,12 |
END isBaseOf; |
PROCEDURE isOpenArray* (t: _TYPE): BOOLEAN; |
PROCEDURE isOpenArray* (t: TYPE_): BOOLEAN; |
RETURN (t.typ = tARRAY) & (t.length = 0) |
END isOpenArray; |
PROCEDURE arrcomp* (src, dst: _TYPE): BOOLEAN; |
PROCEDURE arrcomp* (src, dst: TYPE_): BOOLEAN; |
RETURN (dst.typ = tARRAY) & isOpenArray(src) & |
~isOpenArray(src.base) & ~isOpenArray(dst.base) & |
isTypeEq(src.base, dst.base) |
626,7 → 629,7 |
END arrcomp; |
PROCEDURE getUnit* (name: SCAN.IDENT): UNIT; |
PROCEDURE getUnit* (program: PROGRAM; name: SCAN.IDENT): UNIT; |
VAR |
item: UNIT; |
639,7 → 642,7 |
item := item.next(UNIT) |
END; |
IF (item = NIL) & ((name.s = "SYSTEM") OR LowerCase & (name.s = "system")) THEN |
IF (item = NIL) & (name.s = "SYSTEM") THEN |
item := program.sysunit |
END |
647,40 → 650,36 |
END getUnit; |
PROCEDURE enterStTypes (unit: UNIT); |
PROCEDURE enter (unit: UNIT; name: SCAN.LEXSTR; _type: _TYPE); |
PROCEDURE enterStTypes (unit: UNIT; program: PROGRAM); |
VAR |
ident: IDENT; |
upper: SCAN.LEXSTR; |
BEGIN |
IF LowerCase THEN |
ident := addIdent(unit, SCAN.enterid(name), idTYPE); |
ident._type := _type |
END; |
upper := name; |
STRINGS.UpCase(upper); |
ident := addIdent(unit, SCAN.enterid(upper), idTYPE); |
ident._type := _type |
END enter; |
ident := addIdent(unit, SCAN.enterid("INTEGER"), idTYPE); |
ident.type := program.stTypes.tINTEGER; |
ident := addIdent(unit, SCAN.enterid("BYTE"), idTYPE); |
ident.type := program.stTypes.tBYTE; |
BEGIN |
enter(unit, "integer", program.stTypes.tINTEGER); |
enter(unit, "byte", program.stTypes.tBYTE); |
enter(unit, "char", program.stTypes.tCHAR); |
enter(unit, "set", program.stTypes.tSET); |
enter(unit, "boolean", program.stTypes.tBOOLEAN); |
ident := addIdent(unit, SCAN.enterid("CHAR"), idTYPE); |
ident.type := program.stTypes.tCHAR; |
ident := addIdent(unit, SCAN.enterid("SET"), idTYPE); |
ident.type := program.stTypes.tSET; |
ident := addIdent(unit, SCAN.enterid("BOOLEAN"), idTYPE); |
ident.type := program.stTypes.tBOOLEAN; |
IF TARGETS.RealSize # 0 THEN |
enter(unit, "real", program.stTypes.tREAL) |
ident := addIdent(unit, SCAN.enterid("REAL"), idTYPE); |
ident.type := program.stTypes.tREAL |
END; |
IF TARGETS.BitDepth >= 32 THEN |
enter(unit, "wchar", program.stTypes.tWCHAR) |
ident := addIdent(unit, SCAN.enterid("WCHAR"), idTYPE); |
ident.type := program.stTypes.tWCHAR |
END |
END enterStTypes; |
690,19 → 689,9 |
PROCEDURE EnterProc (unit: UNIT; name: SCAN.LEXSTR; proc: INTEGER); |
VAR |
ident: IDENT; |
upper: SCAN.LEXSTR; |
BEGIN |
IF LowerCase THEN |
ident := addIdent(unit, SCAN.enterid(name), idSTPROC); |
ident.stproc := proc; |
ident._type := program.stTypes.tNONE |
END; |
upper := name; |
STRINGS.UpCase(upper); |
ident := addIdent(unit, SCAN.enterid(upper), idSTPROC); |
ident.stproc := proc; |
ident._type := program.stTypes.tNONE |
ident.stproc := proc |
END EnterProc; |
709,72 → 698,64 |
PROCEDURE EnterFunc (unit: UNIT; name: SCAN.LEXSTR; func: INTEGER); |
VAR |
ident: IDENT; |
upper: SCAN.LEXSTR; |
BEGIN |
IF LowerCase THEN |
ident := addIdent(unit, SCAN.enterid(name), idSTFUNC); |
ident.stproc := func; |
ident._type := program.stTypes.tNONE |
END; |
upper := name; |
STRINGS.UpCase(upper); |
ident := addIdent(unit, SCAN.enterid(upper), idSTFUNC); |
ident.stproc := func; |
ident._type := program.stTypes.tNONE |
ident.stproc := func |
END EnterFunc; |
BEGIN |
EnterProc(unit, "assert", stASSERT); |
EnterProc(unit, "dec", stDEC); |
EnterProc(unit, "excl", stEXCL); |
EnterProc(unit, "inc", stINC); |
EnterProc(unit, "incl", stINCL); |
EnterProc(unit, "new", stNEW); |
EnterProc(unit, "copy", stCOPY); |
EnterProc(unit, "ASSERT", stASSERT); |
EnterProc(unit, "DEC", stDEC); |
EnterProc(unit, "EXCL", stEXCL); |
EnterProc(unit, "INC", stINC); |
EnterProc(unit, "INCL", stINCL); |
EnterProc(unit, "NEW", stNEW); |
EnterProc(unit, "COPY", stCOPY); |
EnterFunc(unit, "abs", stABS); |
EnterFunc(unit, "asr", stASR); |
EnterFunc(unit, "chr", stCHR); |
EnterFunc(unit, "len", stLEN); |
EnterFunc(unit, "lsl", stLSL); |
EnterFunc(unit, "odd", stODD); |
EnterFunc(unit, "ord", stORD); |
EnterFunc(unit, "ror", stROR); |
EnterFunc(unit, "bits", stBITS); |
EnterFunc(unit, "lsr", stLSR); |
EnterFunc(unit, "length", stLENGTH); |
EnterFunc(unit, "min", stMIN); |
EnterFunc(unit, "max", stMAX); |
EnterFunc(unit, "ABS", stABS); |
EnterFunc(unit, "ASR", stASR); |
EnterFunc(unit, "CHR", stCHR); |
EnterFunc(unit, "LEN", stLEN); |
EnterFunc(unit, "LSL", stLSL); |
EnterFunc(unit, "ODD", stODD); |
EnterFunc(unit, "ORD", stORD); |
EnterFunc(unit, "ROR", stROR); |
EnterFunc(unit, "BITS", stBITS); |
EnterFunc(unit, "LSR", stLSR); |
EnterFunc(unit, "LENGTH", stLENGTH); |
EnterFunc(unit, "MIN", stMIN); |
EnterFunc(unit, "MAX", stMAX); |
IF TARGETS.RealSize # 0 THEN |
EnterProc(unit, "pack", stPACK); |
EnterProc(unit, "unpk", stUNPK); |
EnterFunc(unit, "floor", stFLOOR); |
EnterFunc(unit, "flt", stFLT) |
EnterProc(unit, "PACK", stPACK); |
EnterProc(unit, "UNPK", stUNPK); |
EnterFunc(unit, "FLOOR", stFLOOR); |
EnterFunc(unit, "FLT", stFLT) |
END; |
IF TARGETS.BitDepth >= 32 THEN |
EnterFunc(unit, "wchr", stWCHR) |
EnterFunc(unit, "WCHR", stWCHR) |
END; |
IF TARGETS.Dispose THEN |
EnterProc(unit, "dispose", stDISPOSE) |
EnterProc(unit, "DISPOSE", stDISPOSE) |
END |
END enterStProcs; |
PROCEDURE newUnit* (name: SCAN.IDENT): UNIT; |
PROCEDURE newUnit* (program: PROGRAM; name: SCAN.IDENT): UNIT; |
VAR |
unit: UNIT; |
BEGIN |
ASSERT(program # NIL); |
ASSERT(name # NIL); |
NEW(unit); |
unit.program := program; |
unit.name := name; |
unit.closed := FALSE; |
unit.idents := LISTS.create(NIL); |
782,7 → 763,7 |
ASSERT(openScope(unit, NIL)); |
enterStTypes(unit); |
enterStTypes(unit, program); |
enterStProcs(unit); |
ASSERT(openScope(unit, NIL)); |
804,7 → 785,7 |
END newUnit; |
PROCEDURE getField* (self: _TYPE; name: SCAN.IDENT; unit: UNIT): FIELD; |
PROCEDURE getField* (self: TYPE_; name: SCAN.IDENT; unit: UNIT): FIELD; |
VAR |
field: FIELD; |
836,7 → 817,7 |
END getField; |
PROCEDURE addField* (self: _TYPE; name: SCAN.IDENT; export: BOOLEAN): BOOLEAN; |
PROCEDURE addField* (self: TYPE_; name: SCAN.IDENT; export: BOOLEAN): BOOLEAN; |
VAR |
field: FIELD; |
res: BOOLEAN; |
851,7 → 832,7 |
field.name := name; |
field.export := export; |
field._type := NIL; |
field.type := NIL; |
field.offset := self.size; |
LISTS.push(self.fields, field) |
861,33 → 842,33 |
END addField; |
PROCEDURE setFields* (self: _TYPE; _type: _TYPE): BOOLEAN; |
PROCEDURE setFields* (self: TYPE_; type: TYPE_): BOOLEAN; |
VAR |
item: FIELD; |
res: BOOLEAN; |
BEGIN |
ASSERT(_type # NIL); |
ASSERT(type # NIL); |
item := self.fields.first(FIELD); |
WHILE (item # NIL) & (item._type # NIL) DO |
WHILE (item # NIL) & (item.type # NIL) DO |
item := item.next(FIELD) |
END; |
res := TRUE; |
WHILE res & (item # NIL) & (item._type = NIL) DO |
item._type := _type; |
WHILE res & (item # NIL) & (item.type = NIL) DO |
item.type := type; |
IF ~self.noalign THEN |
res := UTILS.Align(self.size, _type.align) |
res := UTILS.Align(self.size, type.align) |
ELSE |
res := TRUE |
END; |
item.offset := self.size; |
res := res & (UTILS.maxint - self.size >= _type.size); |
res := res & (UTILS.maxint - self.size >= type.size); |
IF res THEN |
INC(self.size, _type.size) |
INC(self.size, type.size) |
END; |
item := item.next(FIELD) |
END |
896,7 → 877,7 |
END setFields; |
PROCEDURE getParam* (self: _TYPE; name: SCAN.IDENT): PARAM; |
PROCEDURE getParam* (self: TYPE_; name: SCAN.IDENT): PARAM; |
VAR |
item: PARAM; |
913,7 → 894,7 |
END getParam; |
PROCEDURE addParam* (self: _TYPE; name: SCAN.IDENT; vPar: BOOLEAN): BOOLEAN; |
PROCEDURE addParam* (self: TYPE_; name: SCAN.IDENT; vPar: BOOLEAN): BOOLEAN; |
VAR |
param: PARAM; |
res: BOOLEAN; |
927,7 → 908,7 |
NEW(param); |
param.name := name; |
param._type := NIL; |
param.type := NIL; |
param.vPar := vPar; |
LISTS.push(self.params, param) |
937,7 → 918,7 |
END addParam; |
PROCEDURE Dim* (t: _TYPE): INTEGER; |
PROCEDURE Dim* (t: TYPE_): INTEGER; |
VAR |
res: INTEGER; |
951,7 → 932,7 |
END Dim; |
PROCEDURE OpenBase* (t: _TYPE): _TYPE; |
PROCEDURE OpenBase* (t: TYPE_): TYPE_; |
BEGIN |
WHILE isOpenArray(t) DO t := t.base END |
RETURN t |
958,7 → 939,7 |
END OpenBase; |
PROCEDURE getFloatParamsPos* (self: _TYPE; maxoffs: INTEGER; VAR int, flt: INTEGER): SET; |
PROCEDURE getFloatParamsPos* (self: TYPE_; maxoffs: INTEGER; VAR int, flt: INTEGER): SET; |
VAR |
res: SET; |
param: PARAM; |
969,7 → 950,7 |
flt := 0; |
param := self.params.first(PARAM); |
WHILE (param # NIL) & (param.offset <= maxoffs + STACK_FRAME) DO |
IF ~param.vPar & (param._type.typ = tREAL) THEN |
IF ~param.vPar & (param.type.typ = tREAL) THEN |
INCL(res, param.offset - STACK_FRAME); |
INC(flt) |
END; |
982,7 → 963,7 |
END getFloatParamsPos; |
PROCEDURE setParams* (self: _TYPE; _type: _TYPE); |
PROCEDURE setParams* (self: TYPE_; type: TYPE_); |
VAR |
item: LISTS.ITEM; |
param: PARAM; |
989,42 → 970,42 |
word, size: INTEGER; |
BEGIN |
ASSERT(_type # NIL); |
ASSERT(type # NIL); |
word := UTILS.target.bit_depth DIV 8; |
item := self.params.first; |
WHILE (item # NIL) & (item(PARAM)._type # NIL) DO |
WHILE (item # NIL) & (item(PARAM).type # NIL) DO |
item := item.next |
END; |
WHILE (item # NIL) & (item(PARAM)._type = NIL) DO |
WHILE (item # NIL) & (item(PARAM).type = NIL) DO |
param := item(PARAM); |
param._type := _type; |
param.type := type; |
IF param.vPar THEN |
IF _type.typ = tRECORD THEN |
IF type.typ = tRECORD THEN |
size := 2 |
ELSIF isOpenArray(_type) THEN |
size := Dim(_type) + 1 |
ELSIF isOpenArray(type) THEN |
size := Dim(type) + 1 |
ELSE |
size := 1 |
END; |
param.offset := self.parSize + ORD(_type.typ = tRECORD) + Dim(_type) + STACK_FRAME; |
param.offset := self.parSize + ORD(type.typ = tRECORD) + Dim(type) + STACK_FRAME; |
INC(self.parSize, size) |
ELSE |
IF _type.typ IN {tRECORD, tARRAY} THEN |
IF isOpenArray(_type) THEN |
size := Dim(_type) + 1 |
IF type.typ IN {tRECORD, tARRAY} THEN |
IF isOpenArray(type) THEN |
size := Dim(type) + 1 |
ELSE |
size := 1 |
END |
ELSE |
size := _type.size; |
size := type.size; |
ASSERT(UTILS.Align(size, word)); |
size := size DIV word |
END; |
param.offset := self.parSize + Dim(_type) + STACK_FRAME; |
param.offset := self.parSize + Dim(type) + STACK_FRAME; |
INC(self.parSize, size) |
END; |
1034,9 → 1015,9 |
END setParams; |
PROCEDURE enterType* (typ, size, length: INTEGER; unit: UNIT): _TYPE; |
PROCEDURE enterType* (program: PROGRAM; typ, size, length: INTEGER; unit: UNIT): TYPE_; |
VAR |
t: _TYPE; |
t: TYPE_; |
BEGIN |
NEW(t); |
1057,7 → 1038,7 |
|64: t.call := default64 |
END; |
t._import := FALSE; |
t.import := FALSE; |
t.noalign := FALSE; |
t.parSize := 0; |
1077,9 → 1058,9 |
END enterType; |
PROCEDURE getType* (typ: INTEGER): _TYPE; |
PROCEDURE getType* (program: PROGRAM; typ: INTEGER): TYPE_; |
VAR |
res: _TYPE; |
res: TYPE_; |
BEGIN |
1097,7 → 1078,7 |
END getType; |
PROCEDURE createSysUnit; |
PROCEDURE createSysUnit (program: PROGRAM); |
VAR |
ident: IDENT; |
unit: UNIT; |
1106,69 → 1087,50 |
PROCEDURE EnterProc (sys: UNIT; name: SCAN.LEXSTR; idtyp, proc: INTEGER); |
VAR |
ident: IDENT; |
upper: SCAN.LEXSTR; |
BEGIN |
IF LowerCase THEN |
ident := addIdent(sys, SCAN.enterid(name), idtyp); |
ident.stproc := proc; |
ident._type := program.stTypes.tNONE; |
ident.export := TRUE |
END; |
upper := name; |
STRINGS.UpCase(upper); |
ident := addIdent(sys, SCAN.enterid(upper), idtyp); |
ident.stproc := proc; |
ident._type := program.stTypes.tNONE; |
ident.export := TRUE |
END EnterProc; |
BEGIN |
unit := newUnit(SCAN.enterid("$SYSTEM")); |
unit := newUnit(program, SCAN.enterid("$SYSTEM")); |
EnterProc(unit, "adr", idSYSFUNC, sysADR); |
EnterProc(unit, "size", idSYSFUNC, sysSIZE); |
EnterProc(unit, "sadr", idSYSFUNC, sysSADR); |
EnterProc(unit, "typeid", idSYSFUNC, sysTYPEID); |
EnterProc(unit, "ADR", idSYSFUNC, sysADR); |
EnterProc(unit, "SIZE", idSYSFUNC, sysSIZE); |
EnterProc(unit, "SADR", idSYSFUNC, sysSADR); |
EnterProc(unit, "TYPEID", idSYSFUNC, sysTYPEID); |
EnterProc(unit, "get", idSYSPROC, sysGET); |
EnterProc(unit, "get8", idSYSPROC, sysGET8); |
EnterProc(unit, "put", idSYSPROC, sysPUT); |
EnterProc(unit, "put8", idSYSPROC, sysPUT8); |
EnterProc(unit, "code", idSYSPROC, sysCODE); |
EnterProc(unit, "move", idSYSPROC, sysMOVE); |
EnterProc(unit, "GET", idSYSPROC, sysGET); |
EnterProc(unit, "PUT8", idSYSPROC, sysPUT8); |
EnterProc(unit, "PUT", idSYSPROC, sysPUT); |
EnterProc(unit, "CODE", idSYSPROC, sysCODE); |
EnterProc(unit, "MOVE", idSYSPROC, sysMOVE); |
(* |
IF program.target.sys = mConst.Target_iMSP430 THEN |
EnterProc(unit, "nop", idSYSPROC, sysNOP); |
EnterProc(unit, "eint", idSYSPROC, sysEINT); |
EnterProc(unit, "dint", idSYSPROC, sysDINT) |
EnterProc(unit, "NOP", idSYSPROC, sysNOP); |
EnterProc(unit, "EINT", idSYSPROC, sysEINT); |
EnterProc(unit, "DINT", idSYSPROC, sysDINT) |
END; |
*) |
IF TARGETS.RealSize # 0 THEN |
EnterProc(unit, "inf", idSYSFUNC, sysINF); |
EnterProc(unit, "INF", idSYSFUNC, sysINF); |
END; |
IF TARGETS.CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN |
EnterProc(unit, "copy", idSYSPROC, sysCOPY) |
EnterProc(unit, "COPY", idSYSPROC, sysCOPY) |
END; |
IF TARGETS.BitDepth >= 32 THEN |
EnterProc(unit, "wsadr", idSYSFUNC, sysWSADR); |
EnterProc(unit, "put16", idSYSPROC, sysPUT16); |
EnterProc(unit, "put32", idSYSPROC, sysPUT32); |
EnterProc(unit, "get16", idSYSPROC, sysGET16); |
EnterProc(unit, "get32", idSYSPROC, sysGET32); |
EnterProc(unit, "WSADR", idSYSFUNC, sysWSADR); |
EnterProc(unit, "PUT32", idSYSPROC, sysPUT32); |
EnterProc(unit, "PUT16", idSYSPROC, sysPUT16); |
IF LowerCase THEN |
ident := addIdent(unit, SCAN.enterid("card32"), idTYPE); |
ident._type := program.stTypes.tCARD32; |
ident := addIdent(unit, SCAN.enterid("CARD32"), idTYPE); |
ident.type := program.stTypes.tCARD32; |
ident.export := TRUE |
END; |
ident := addIdent(unit, SCAN.enterid("CARD32"), idTYPE); |
ident._type := program.stTypes.tCARD32; |
ident.export := TRUE; |
END; |
closeUnit(unit); |
1176,7 → 1138,7 |
END createSysUnit; |
PROCEDURE DelUnused* (DelImport: DELIMPORT); |
PROCEDURE DelUnused* (program: PROGRAM; DelImport: DELIMPORT); |
VAR |
proc: PROC; |
flag: BOOLEAN; |
1218,10 → 1180,10 |
WHILE proc # NIL DO |
IF ~proc.used THEN |
IF proc._import = NIL THEN |
IF proc.import = NIL THEN |
IL.delete2(proc.enter, proc.leave) |
ELSE |
DelImport(proc._import) |
DelImport(proc.import) |
END |
END; |
proc := proc.next(PROC) |
1230,28 → 1192,24 |
END DelUnused; |
PROCEDURE ResetLocSize*; |
BEGIN |
program.locsize := 0 |
END ResetLocSize; |
PROCEDURE create* (options: OPTIONS): PROGRAM; |
VAR |
program: PROGRAM; |
PROCEDURE create* (options: OPTIONS); |
BEGIN |
LowerCase := options.lower; |
SCAN.init(options.lower); |
idents := C.create(); |
UTILS.SetBitDepth(TARGETS.BitDepth, TARGETS.RealSize = 8); |
NEW(program); |
program.options := options; |
CASE TARGETS.OS OF |
|TARGETS.osWIN32: program.sysflags := {sf_oberon, sf_windows, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign} |
|TARGETS.osLINUX32: program.sysflags := {sf_oberon, sf_linux, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign} |
|TARGETS.osKOS: program.sysflags := {sf_oberon, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign} |
|TARGETS.osWIN64: program.sysflags := {sf_oberon, sf_windows, sf_stdcall64, sf_win64, sf_systemv, sf_noalign} |
|TARGETS.osLINUX64: program.sysflags := {sf_oberon, sf_linux, sf_stdcall64, sf_win64, sf_systemv, sf_noalign} |
|TARGETS.osWIN32: program.sysflags := {sf_windows, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign} |
|TARGETS.osLINUX32: program.sysflags := {sf_linux, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign} |
|TARGETS.osKOS: program.sysflags := {sf_stdcall, sf_ccall, sf_ccall16, sf_noalign} |
|TARGETS.osWIN64: program.sysflags := {sf_windows, sf_stdcall64, sf_win64, sf_systemv, sf_noalign} |
|TARGETS.osLINUX64: program.sysflags := {sf_linux, sf_stdcall64, sf_win64, sf_systemv, sf_noalign} |
|TARGETS.osNONE: program.sysflags := {sf_code} |
END; |
1262,11 → 1220,11 |
program.types := LISTS.create(NIL); |
program.procs := LISTS.create(NIL); |
program.stTypes.tINTEGER := enterType(tINTEGER, TARGETS.WordSize, 0, NIL); |
program.stTypes.tBYTE := enterType(tBYTE, 1, 0, NIL); |
program.stTypes.tCHAR := enterType(tCHAR, 1, 0, NIL); |
program.stTypes.tSET := enterType(tSET, TARGETS.WordSize, 0, NIL); |
program.stTypes.tBOOLEAN := enterType(tBOOLEAN, 1, 0, NIL); |
program.stTypes.tINTEGER := enterType(program, tINTEGER, TARGETS.WordSize, 0, NIL); |
program.stTypes.tBYTE := enterType(program, tBYTE, 1, 0, NIL); |
program.stTypes.tCHAR := enterType(program, tCHAR, 1, 0, NIL); |
program.stTypes.tSET := enterType(program, tSET, TARGETS.WordSize, 0, NIL); |
program.stTypes.tBOOLEAN := enterType(program, tBOOLEAN, 1, 0, NIL); |
program.stTypes.tINTEGER.align := TARGETS.WordSize; |
program.stTypes.tBYTE.align := 1; |
1275,24 → 1233,26 |
program.stTypes.tBOOLEAN.align := 1; |
IF TARGETS.BitDepth >= 32 THEN |
program.stTypes.tWCHAR := enterType(tWCHAR, 2, 0, NIL); |
program.stTypes.tCARD32 := enterType(tCARD32, 4, 0, NIL); |
program.stTypes.tWCHAR := enterType(program, tWCHAR, 2, 0, NIL); |
program.stTypes.tCARD32 := enterType(program, tCARD32, 4, 0, NIL); |
program.stTypes.tWCHAR.align := 2; |
program.stTypes.tCARD32.align := 4 |
END; |
IF TARGETS.RealSize # 0 THEN |
program.stTypes.tREAL := enterType(tREAL, TARGETS.RealSize, 0, NIL); |
program.stTypes.tREAL := enterType(program, tREAL, TARGETS.RealSize, 0, NIL); |
program.stTypes.tREAL.align := TARGETS.RealSize |
END; |
program.stTypes.tSTRING := enterType(tSTRING, TARGETS.WordSize, 0, NIL); |
program.stTypes.tNIL := enterType(tNIL, TARGETS.WordSize, 0, NIL); |
program.stTypes.tNONE := enterType(tNONE, 0, 0, NIL); |
program.stTypes.tANYREC := enterType(tRECORD, 0, 0, NIL); |
program.stTypes.tSTRING := enterType(program, tSTRING, TARGETS.WordSize, 0, NIL); |
program.stTypes.tNIL := enterType(program, tNIL, TARGETS.WordSize, 0, NIL); |
program.stTypes.tANYREC := enterType(program, tRECORD, 0, 0, NIL); |
program.stTypes.tANYREC.closed := TRUE; |
createSysUnit |
createSysUnit(program) |
RETURN program |
END create; |
/programs/develop/oberon07/Source/REG.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2020, Anton Krotov |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
156,7 → 156,7 |
PROCEDURE GetReg* (VAR R: REGS; reg: INTEGER): BOOLEAN; |
VAR |
free: INTEGER; |
free, n: INTEGER; |
res: BOOLEAN; |
178,8 → 178,8 |
Put(R, reg); |
res := TRUE |
ELSE |
res := InStk(R, reg) # -1; |
IF res THEN |
n := InStk(R, reg); |
IF n # -1 THEN |
free := GetFreeReg(R); |
IF free # -1 THEN |
Put(R, free); |
192,9 → 192,12 |
IF free # reg THEN |
exch(R, reg, free) |
END |
END; |
res := TRUE |
ELSE |
res := FALSE |
END |
END |
END |
RETURN res |
END GetReg; |
/programs/develop/oberon07/Source/SCAN.ob07 |
---|
1,13 → 1,13 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2020, Anton Krotov |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
MODULE SCAN; |
IMPORT TXT := TEXTDRV, AVL := AVLTREES, ARITH, S := STRINGS, ERRORS, LISTS; |
IMPORT TXT := TEXTDRV, AVL := AVLTREES, ARITH, S := STRINGS; |
CONST |
48,12 → 48,6 |
LEXSTR* = ARRAY LEXLEN OF CHAR; |
DEF = POINTER TO RECORD (LISTS.ITEM) |
ident: LEXSTR |
END; |
IDENT* = POINTER TO RECORD (AVL.DATA) |
s*: LEXSTR; |
94,11 → 88,9 |
NewIdent: IDENT; |
upto, LowerCase, _if: BOOLEAN; |
upto: BOOLEAN; |
def: LISTS.LIST; |
PROCEDURE nodecmp (a, b: AVL.DATA): INTEGER; |
RETURN ORD(a(IDENT).s > b(IDENT).s) - ORD(a(IDENT).s < b(IDENT).s) |
END nodecmp; |
174,7 → 166,7 |
VAR |
c: CHAR; |
hex: BOOLEAN; |
error, sym: INTEGER; |
error: INTEGER; |
BEGIN |
c := text.peak; |
182,7 → 174,7 |
error := 0; |
sym := lxINTEGER; |
lex.sym := lxINTEGER; |
hex := FALSE; |
WHILE S.digit(c) DO |
199,17 → 191,17 |
IF c = "H" THEN |
putchar(lex, c); |
TXT.next(text); |
sym := lxHEX |
lex.sym := lxHEX |
ELSIF c = "X" THEN |
putchar(lex, c); |
TXT.next(text); |
sym := lxCHAR |
lex.sym := lxCHAR |
ELSIF c = "." THEN |
IF hex THEN |
sym := lxERROR01 |
lex.sym := lxERROR01 |
ELSE |
c := nextc(text); |
216,9 → 208,9 |
IF c # "." THEN |
putchar(lex, "."); |
sym := lxFLOAT |
lex.sym := lxFLOAT |
ELSE |
sym := lxINTEGER; |
lex.sym := lxINTEGER; |
text.peak := 7FX; |
upto := TRUE |
END; |
243,7 → 235,7 |
c := nextc(text) |
END |
ELSE |
sym := lxERROR02 |
lex.sym := lxERROR02 |
END |
END |
251,32 → 243,31 |
END |
ELSIF hex THEN |
sym := lxERROR01 |
lex.sym := lxERROR01 |
END; |
IF lex.over & (sym >= 0) THEN |
sym := lxERROR07 |
IF lex.over & (lex.sym >= 0) THEN |
lex.sym := lxERROR07 |
END; |
IF sym = lxINTEGER THEN |
IF lex.sym = lxINTEGER THEN |
ARITH.iconv(lex.s, lex.value, error) |
ELSIF (sym = lxHEX) OR (sym = lxCHAR) THEN |
ELSIF (lex.sym = lxHEX) OR (lex.sym = lxCHAR) THEN |
ARITH.hconv(lex.s, lex.value, error) |
ELSIF sym = lxFLOAT THEN |
ELSIF lex.sym = lxFLOAT THEN |
ARITH.fconv(lex.s, lex.value, error) |
END; |
CASE error OF |
|0: |
|1: sym := lxERROR08 |
|2: sym := lxERROR09 |
|3: sym := lxERROR10 |
|4: sym := lxERROR11 |
|5: sym := lxERROR12 |
END; |
|1: lex.sym := lxERROR08 |
|2: lex.sym := lxERROR09 |
|3: lex.sym := lxERROR10 |
|4: lex.sym := lxERROR11 |
|5: lex.sym := lxERROR12 |
END |
lex.sym := sym |
END number; |
358,9 → 349,6 |
PROCEDURE delimiter (text: TXT.TEXT; VAR lex: LEX; c: CHAR); |
VAR |
sym: INTEGER; |
BEGIN |
putchar(lex, c); |
c := nextc(text); |
367,19 → 355,19 |
CASE lex.s[0] OF |
|"+": |
sym := lxPLUS |
lex.sym := lxPLUS |
|"-": |
sym := lxMINUS |
lex.sym := lxMINUS |
|"*": |
sym := lxMUL |
lex.sym := lxMUL |
|"/": |
sym := lxSLASH; |
lex.sym := lxSLASH; |
IF c = "/" THEN |
sym := lxCOMMENT; |
lex.sym := lxCOMMENT; |
REPEAT |
TXT.next(text) |
UNTIL text.eol OR text.eof |
386,93 → 374,91 |
END |
|"~": |
sym := lxNOT |
lex.sym := lxNOT |
|"&": |
sym := lxAND |
lex.sym := lxAND |
|".": |
sym := lxPOINT; |
lex.sym := lxPOINT; |
IF c = "." THEN |
sym := lxRANGE; |
lex.sym := lxRANGE; |
putchar(lex, c); |
TXT.next(text) |
END |
|",": |
sym := lxCOMMA |
lex.sym := lxCOMMA |
|";": |
sym := lxSEMI |
lex.sym := lxSEMI |
|"|": |
sym := lxBAR |
lex.sym := lxBAR |
|"(": |
sym := lxLROUND; |
lex.sym := lxLROUND; |
IF c = "*" THEN |
sym := lxCOMMENT; |
lex.sym := lxCOMMENT; |
TXT.next(text); |
comment(text) |
END |
|"[": |
sym := lxLSQUARE |
lex.sym := lxLSQUARE |
|"{": |
sym := lxLCURLY |
lex.sym := lxLCURLY |
|"^": |
sym := lxCARET |
lex.sym := lxCARET |
|"=": |
sym := lxEQ |
lex.sym := lxEQ |
|"#": |
sym := lxNE |
lex.sym := lxNE |
|"<": |
sym := lxLT; |
lex.sym := lxLT; |
IF c = "=" THEN |
sym := lxLE; |
lex.sym := lxLE; |
putchar(lex, c); |
TXT.next(text) |
END |
|">": |
sym := lxGT; |
lex.sym := lxGT; |
IF c = "=" THEN |
sym := lxGE; |
lex.sym := lxGE; |
putchar(lex, c); |
TXT.next(text) |
END |
|":": |
sym := lxCOLON; |
lex.sym := lxCOLON; |
IF c = "=" THEN |
sym := lxASSIGN; |
lex.sym := lxASSIGN; |
putchar(lex, c); |
TXT.next(text) |
END |
|")": |
sym := lxRROUND |
lex.sym := lxRROUND |
|"]": |
sym := lxRSQUARE |
lex.sym := lxRSQUARE |
|"}": |
sym := lxRCURLY |
lex.sym := lxRCURLY |
END; |
END |
lex.sym := sym |
END delimiter; |
480,110 → 466,9 |
VAR |
c: CHAR; |
PROCEDURE check (cond: BOOLEAN; text: SCANNER; lex: LEX; errno: INTEGER); |
BEGIN |
IF ~cond THEN |
ERRORS.ErrorMsg(text.fname, lex.pos.line, lex.pos.col, errno) |
END |
END check; |
PROCEDURE IsDef (str: ARRAY OF CHAR): BOOLEAN; |
VAR |
cur: DEF; |
BEGIN |
cur := def.first(DEF); |
WHILE (cur # NIL) & (cur.ident # str) DO |
cur := cur.next(DEF) |
END |
RETURN cur # NIL |
END IsDef; |
PROCEDURE Skip (text: SCANNER); |
VAR |
i: INTEGER; |
BEGIN |
i := 0; |
WHILE (i <= text.ifc) & ~text._skip[i] DO |
INC(i) |
END; |
text.skip := i <= text.ifc |
END Skip; |
PROCEDURE prep_if (text: SCANNER; VAR lex: LEX); |
VAR |
skip: BOOLEAN; |
BEGIN |
INC(text.ifc); |
text._elsif[text.ifc] := lex.sym = lxELSIF; |
IF lex.sym = lxIF THEN |
INC(text.elsec); |
text._else[text.elsec] := FALSE |
END; |
_if := TRUE; |
skip := TRUE; |
text.skip := FALSE; |
Next(text, lex); |
check(lex.sym = lxLROUND, text, lex, 64); |
Next(text, lex); |
check(lex.sym = lxIDENT, text, lex, 22); |
REPEAT |
IF IsDef(lex.s) THEN |
skip := FALSE |
END; |
Next(text, lex); |
IF lex.sym = lxBAR THEN |
Next(text, lex); |
check(lex.sym = lxIDENT, text, lex, 22) |
ELSE |
check(lex.sym = lxRROUND, text, lex, 33) |
END |
UNTIL lex.sym = lxRROUND; |
_if := FALSE; |
text._skip[text.ifc] := skip; |
Skip(text); |
Next(text, lex) |
END prep_if; |
PROCEDURE prep_end (text: SCANNER; VAR lex: LEX); |
BEGIN |
check(text.ifc > 0, text, lex, 118); |
IF lex.sym = lxEND THEN |
WHILE text._elsif[text.ifc] DO |
DEC(text.ifc) |
END; |
DEC(text.ifc); |
DEC(text.elsec) |
ELSIF (lex.sym = lxELSE) OR (lex.sym = lxELSIF) THEN |
check(~text._else[text.elsec], text, lex, 118); |
text._skip[text.ifc] := ~text._skip[text.ifc]; |
text._else[text.elsec] := lex.sym = lxELSE |
END; |
Skip(text); |
IF lex.sym = lxELSIF THEN |
prep_if(text, lex) |
ELSE |
Next(text, lex) |
END |
END prep_end; |
BEGIN |
REPEAT |
c := text.peak; |
WHILE S.space(c) DO |
605,26 → 490,8 |
string(text, lex, c) |
ELSIF delimiters[ORD(c)] THEN |
delimiter(text, lex, c) |
ELSIF c = "$" THEN |
IF S.letter(nextc(text)) THEN |
ident(text, lex); |
IF lex.sym = lxIF THEN |
IF ~_if THEN |
prep_if(text, lex) |
END |
ELSIF (lex.sym = lxEND) OR (lex.sym = lxELSE) OR (lex.sym = lxELSIF) THEN |
IF ~_if THEN |
prep_end(text, lex) |
END |
ELSE |
check(FALSE, text, lex, 119) |
END |
ELSE |
check(FALSE, text, lex, 119) |
END |
ELSIF c = 0X THEN |
lex.sym := lxEOF; |
text.skip := FALSE; |
IF text.eof THEN |
INC(lex.pos.col) |
END |
647,7 → 514,7 |
lex.error := 0 |
END |
UNTIL (lex.sym # lxCOMMENT) & ~text.skip |
UNTIL lex.sym # lxCOMMENT |
END Next; |
663,7 → 530,7 |
END close; |
PROCEDURE init* (lower: BOOLEAN); |
PROCEDURE init; |
VAR |
i: INTEGER; |
delim: ARRAY 23 OF CHAR; |
672,23 → 539,15 |
PROCEDURE enterkw (key: INTEGER; kw: LEXSTR); |
VAR |
id: IDENT; |
upper: LEXSTR; |
BEGIN |
IF LowerCase THEN |
id := enterid(kw); |
id.key := key |
END; |
upper := kw; |
S.UpCase(upper); |
id := enterid(upper); |
id.key := key |
END enterkw; |
BEGIN |
upto := FALSE; |
LowerCase := lower; |
FOR i := 0 TO 255 DO |
delimiters[i] := FALSE |
708,54 → 567,43 |
idents := NIL; |
enterkw(lxARRAY, "array"); |
enterkw(lxBEGIN, "begin"); |
enterkw(lxBY, "by"); |
enterkw(lxCASE, "case"); |
enterkw(lxCONST, "const"); |
enterkw(lxDIV, "div"); |
enterkw(lxDO, "do"); |
enterkw(lxELSE, "else"); |
enterkw(lxELSIF, "elsif"); |
enterkw(lxEND, "end"); |
enterkw(lxFALSE, "false"); |
enterkw(lxFOR, "for"); |
enterkw(lxIF, "if"); |
enterkw(lxIMPORT, "import"); |
enterkw(lxIN, "in"); |
enterkw(lxIS, "is"); |
enterkw(lxMOD, "mod"); |
enterkw(lxMODULE, "module"); |
enterkw(lxNIL, "nil"); |
enterkw(lxOF, "of"); |
enterkw(lxOR, "or"); |
enterkw(lxPOINTER, "pointer"); |
enterkw(lxPROCEDURE, "procedure"); |
enterkw(lxRECORD, "record"); |
enterkw(lxREPEAT, "repeat"); |
enterkw(lxRETURN, "return"); |
enterkw(lxTHEN, "then"); |
enterkw(lxTO, "to"); |
enterkw(lxTRUE, "true"); |
enterkw(lxTYPE, "type"); |
enterkw(lxUNTIL, "until"); |
enterkw(lxVAR, "var"); |
enterkw(lxWHILE, "while") |
enterkw(lxARRAY, "ARRAY"); |
enterkw(lxBEGIN, "BEGIN"); |
enterkw(lxBY, "BY"); |
enterkw(lxCASE, "CASE"); |
enterkw(lxCONST, "CONST"); |
enterkw(lxDIV, "DIV"); |
enterkw(lxDO, "DO"); |
enterkw(lxELSE, "ELSE"); |
enterkw(lxELSIF, "ELSIF"); |
enterkw(lxEND, "END"); |
enterkw(lxFALSE, "FALSE"); |
enterkw(lxFOR, "FOR"); |
enterkw(lxIF, "IF"); |
enterkw(lxIMPORT, "IMPORT"); |
enterkw(lxIN, "IN"); |
enterkw(lxIS, "IS"); |
enterkw(lxMOD, "MOD"); |
enterkw(lxMODULE, "MODULE"); |
enterkw(lxNIL, "NIL"); |
enterkw(lxOF, "OF"); |
enterkw(lxOR, "OR"); |
enterkw(lxPOINTER, "POINTER"); |
enterkw(lxPROCEDURE, "PROCEDURE"); |
enterkw(lxRECORD, "RECORD"); |
enterkw(lxREPEAT, "REPEAT"); |
enterkw(lxRETURN, "RETURN"); |
enterkw(lxTHEN, "THEN"); |
enterkw(lxTO, "TO"); |
enterkw(lxTRUE, "TRUE"); |
enterkw(lxTYPE, "TYPE"); |
enterkw(lxUNTIL, "UNTIL"); |
enterkw(lxVAR, "VAR"); |
enterkw(lxWHILE, "WHILE") |
END init; |
PROCEDURE NewDef* (str: ARRAY OF CHAR); |
VAR |
item: DEF; |
BEGIN |
NEW(item); |
COPY(str, item.ident); |
LISTS.push(def, item) |
END NewDef; |
BEGIN |
def := LISTS.create(NIL) |
init |
END SCAN. |
/programs/develop/oberon07/Source/STATEMENTS.ob07 |
---|
9,7 → 9,7 |
IMPORT |
PARS, PROG, SCAN, ARITH, STRINGS, LISTS, IL, X86, AMD64, MSP430, THUMB, RVM32I, |
PARS, PROG, SCAN, ARITH, STRINGS, LISTS, IL, X86, AMD64, MSP430, THUMB, |
ERRORS, UTILS, AVL := AVLTREES, CONSOLE, C := COLLECTIONS, TARGETS; |
48,7 → 48,7 |
variant, self: INTEGER; |
_type: PROG._TYPE; |
type: PROG.TYPE_; |
prev: CASE_LABEL |
75,7 → 75,7 |
CPU: INTEGER; |
tINTEGER, tBYTE, tCHAR, tWCHAR, tSET, tBOOLEAN, tREAL: PROG._TYPE; |
tINTEGER, tBYTE, tCHAR, tWCHAR, tSET, tBOOLEAN, tREAL: PROG.TYPE_; |
PROCEDURE isExpr (e: PARS.EXPR): BOOLEAN; |
89,17 → 89,17 |
PROCEDURE isBoolean (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type = tBOOLEAN) |
RETURN isExpr(e) & (e.type = tBOOLEAN) |
END isBoolean; |
PROCEDURE isInteger (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type = tINTEGER) |
RETURN isExpr(e) & (e.type = tINTEGER) |
END isInteger; |
PROCEDURE isByte (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type = tBYTE) |
RETURN isExpr(e) & (e.type = tBYTE) |
END isByte; |
109,42 → 109,42 |
PROCEDURE isReal (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type = tREAL) |
RETURN isExpr(e) & (e.type = tREAL) |
END isReal; |
PROCEDURE isSet (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type = tSET) |
RETURN isExpr(e) & (e.type = tSET) |
END isSet; |
PROCEDURE isString (e: PARS.EXPR): BOOLEAN; |
RETURN (e.obj = eCONST) & (e._type.typ IN {PROG.tSTRING, PROG.tCHAR}) |
RETURN (e.obj = eCONST) & (e.type.typ IN {PROG.tSTRING, PROG.tCHAR}) |
END isString; |
PROCEDURE isStringW (e: PARS.EXPR): BOOLEAN; |
RETURN (e.obj = eCONST) & (e._type.typ IN {PROG.tSTRING, PROG.tCHAR, PROG.tWCHAR}) |
RETURN (e.obj = eCONST) & (e.type.typ IN {PROG.tSTRING, PROG.tCHAR, PROG.tWCHAR}) |
END isStringW; |
PROCEDURE isChar (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type = tCHAR) |
RETURN isExpr(e) & (e.type = tCHAR) |
END isChar; |
PROCEDURE isCharW (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type = tWCHAR) |
RETURN isExpr(e) & (e.type = tWCHAR) |
END isCharW; |
PROCEDURE isPtr (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type.typ = PROG.tPOINTER) |
RETURN isExpr(e) & (e.type.typ = PROG.tPOINTER) |
END isPtr; |
PROCEDURE isRec (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type.typ = PROG.tRECORD) |
RETURN isExpr(e) & (e.type.typ = PROG.tRECORD) |
END isRec; |
154,27 → 154,27 |
PROCEDURE isArr (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type.typ = PROG.tARRAY) |
RETURN isExpr(e) & (e.type.typ = PROG.tARRAY) |
END isArr; |
PROCEDURE isProc (e: PARS.EXPR): BOOLEAN; |
RETURN isExpr(e) & (e._type.typ = PROG.tPROCEDURE) OR (e.obj IN {ePROC, eIMP}) |
RETURN isExpr(e) & (e.type.typ = PROG.tPROCEDURE) OR (e.obj IN {ePROC, eIMP}) |
END isProc; |
PROCEDURE isNil (e: PARS.EXPR): BOOLEAN; |
RETURN e._type.typ = PROG.tNIL |
RETURN e.type.typ = PROG.tNIL |
END isNil; |
PROCEDURE isCharArray (e: PARS.EXPR): BOOLEAN; |
RETURN isArr(e) & (e._type.base = tCHAR) |
RETURN isArr(e) & (e.type.base = tCHAR) |
END isCharArray; |
PROCEDURE isCharArrayW (e: PARS.EXPR): BOOLEAN; |
RETURN isArr(e) & (e._type.base = tWCHAR) |
RETURN isArr(e) & (e.type.base = tWCHAR) |
END isCharArrayW; |
204,7 → 204,7 |
BEGIN |
ASSERT(isString(e)); |
IF e._type = tCHAR THEN |
IF e.type = tCHAR THEN |
res := 1 |
ELSE |
res := LENGTH(e.value.string(SCAN.IDENT).s) |
237,7 → 237,7 |
BEGIN |
ASSERT(isStringW(e)); |
IF e._type.typ IN {PROG.tCHAR, PROG.tWCHAR} THEN |
IF e.type.typ IN {PROG.tCHAR, PROG.tWCHAR} THEN |
res := 1 |
ELSE |
res := _length(e.value.string(SCAN.IDENT).s) |
257,11 → 257,11 |
PROCEDURE isStringW1 (e: PARS.EXPR): BOOLEAN; |
RETURN isString(e) & (utf8strlen(e) = 1) & (strlen(e) > 1) |
RETURN (e.obj = eCONST) & isString(e) & (utf8strlen(e) = 1) & (strlen(e) > 1) |
END isStringW1; |
PROCEDURE assigncomp (e: PARS.EXPR; t: PROG._TYPE): BOOLEAN; |
PROCEDURE assigncomp (e: PARS.EXPR; t: PROG.TYPE_): BOOLEAN; |
VAR |
res: BOOLEAN; |
268,7 → 268,7 |
BEGIN |
IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN |
IF t = e._type THEN |
IF t = e.type THEN |
res := TRUE |
ELSIF isInt(e) & (t.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN |
IF (e.obj = eCONST) & (t = tBYTE) THEN |
279,10 → 279,10 |
ELSIF |
(e.obj = eCONST) & isChar(e) & (t = tWCHAR) |
OR isStringW1(e) & (t = tWCHAR) |
OR PROG.isBaseOf(t, e._type) |
OR ~PROG.isOpenArray(t) & ~PROG.isOpenArray(e._type) & PROG.isTypeEq(t, e._type) |
OR PROG.isBaseOf(t, e.type) |
OR ~PROG.isOpenArray(t) & ~PROG.isOpenArray(e.type) & PROG.isTypeEq(t, e.type) |
OR isNil(e) & (t.typ IN {PROG.tPOINTER, PROG.tPROCEDURE}) |
OR PROG.arrcomp(e._type, t) |
OR PROG.arrcomp(e.type, t) |
OR isString(e) & (t.typ = PROG.tARRAY) & (t.base = tCHAR) & (t.length > strlen(e)) |
OR isStringW(e) & (t.typ = PROG.tARRAY) & (t.base = tWCHAR) & (t.length > utf8strlen(e)) |
THEN |
331,9 → 331,9 |
END; |
offset := string.offsetW |
ELSE |
IF e._type.typ IN {PROG.tWCHAR, PROG.tCHAR} THEN |
IF e.type.typ IN {PROG.tWCHAR, PROG.tCHAR} THEN |
offset := IL.putstrW1(ARITH.Int(e.value)) |
ELSE (* e._type.typ = PROG.tSTRING *) |
ELSE (* e.type.typ = PROG.tSTRING *) |
string := e.value.string(SCAN.IDENT); |
IF string.offsetW = -1 THEN |
string.offsetW := IL.putstrW(string.s); |
358,18 → 358,8 |
END CheckRange; |
PROCEDURE Float (parser: PARS.PARSER; e: PARS.EXPR); |
PROCEDURE assign (e: PARS.EXPR; VarType: PROG.TYPE_; line: INTEGER): BOOLEAN; |
VAR |
pos: PARS.POSITION; |
BEGIN |
getpos(parser, pos); |
IL.Float(ARITH.Float(e.value), pos.line, pos.col) |
END Float; |
PROCEDURE assign (parser: PARS.PARSER; e: PARS.EXPR; VarType: PROG._TYPE; line: INTEGER): BOOLEAN; |
VAR |
res: BOOLEAN; |
label: INTEGER; |
376,7 → 366,7 |
BEGIN |
IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN |
res := TRUE; |
IF PROG.arrcomp(e._type, VarType) THEN |
IF PROG.arrcomp(e.type, VarType) THEN |
IF ~PROG.isOpenArray(VarType) THEN |
IL.Const(VarType.length) |
383,7 → 373,7 |
END; |
IL.AddCmd(IL.opCOPYA, VarType.base.size); |
label := IL.NewLabel(); |
IL.AddJmpCmd(IL.opJNZ, label); |
IL.AddJmpCmd(IL.opJE, label); |
IL.OnError(line, errCOPY); |
IL.SetLabel(label) |
424,7 → 414,7 |
END |
ELSIF isReal(e) & (VarType = tREAL) THEN |
IF e.obj = eCONST THEN |
Float(parser, e) |
IL.Float(ARITH.Float(e.value)) |
END; |
IL.savef(e.obj = eCONST) |
ELSIF isChar(e) & (VarType = tCHAR) THEN |
443,19 → 433,19 |
ELSE |
IL.AddCmd0(IL.opSAVE16) |
END |
ELSIF PROG.isBaseOf(VarType, e._type) THEN |
ELSIF PROG.isBaseOf(VarType, e.type) THEN |
IF VarType.typ = PROG.tPOINTER THEN |
IL.AddCmd0(IL.opSAVE) |
ELSE |
IL.AddCmd(IL.opCOPY, VarType.size) |
END |
ELSIF (e._type.typ = PROG.tCARD32) & (VarType.typ = PROG.tCARD32) THEN |
ELSIF (e.type.typ = PROG.tCARD32) & (VarType.typ = PROG.tCARD32) THEN |
IL.AddCmd0(IL.opSAVE32) |
ELSIF ~PROG.isOpenArray(VarType) & ~PROG.isOpenArray(e._type) & PROG.isTypeEq(VarType, e._type) THEN |
ELSIF ~PROG.isOpenArray(VarType) & ~PROG.isOpenArray(e.type) & PROG.isTypeEq(VarType, e.type) THEN |
IF e.obj = ePROC THEN |
IL.AssignProc(e.ident.proc.label) |
ELSIF e.obj = eIMP THEN |
IL.AssignImpProc(e.ident._import) |
IL.AssignImpProc(e.ident.import) |
ELSE |
IF VarType.typ = PROG.tPROCEDURE THEN |
IL.AddCmd0(IL.opSAVE) |
491,11 → 481,11 |
PROCEDURE arrcomp (e: PARS.EXPR; p: PROG.PARAM): BOOLEAN; |
VAR |
t1, t2: PROG._TYPE; |
t1, t2: PROG.TYPE_; |
BEGIN |
t1 := p._type; |
t2 := e._type; |
t1 := p.type; |
t2 := e.type; |
WHILE (t2.typ = PROG.tARRAY) & PROG.isOpenArray(t1) DO |
t1 := t1.base; |
t2 := t2.base |
505,7 → 495,7 |
END arrcomp; |
PROCEDURE ArrLen (t: PROG._TYPE; n: INTEGER): INTEGER; |
PROCEDURE ArrLen (t: PROG.TYPE_; n: INTEGER): INTEGER; |
VAR |
res: INTEGER; |
520,7 → 510,7 |
END ArrLen; |
PROCEDURE OpenArray (t, t2: PROG._TYPE); |
PROCEDURE OpenArray (t, t2: PROG.TYPE_); |
VAR |
n, d1, d2: INTEGER; |
557,8 → 547,8 |
IF p.vPar THEN |
PARS.check(isVar(e), pos, 93); |
IF p._type.typ = PROG.tRECORD THEN |
PARS.check(PROG.isBaseOf(p._type, e._type), pos, 66); |
IF p.type.typ = PROG.tRECORD THEN |
PARS.check(PROG.isBaseOf(p.type, e.type), pos, 66); |
IF e.obj = eVREC THEN |
IF e.ident # NIL THEN |
IL.AddCmd(IL.opVADR, e.ident.offset - 1) |
566,14 → 556,14 |
IL.AddCmd0(IL.opPUSHT) |
END |
ELSE |
IL.Const(e._type.num) |
IL.Const(e.type.num) |
END; |
IL.AddCmd(IL.opPARAM, 2) |
ELSIF PROG.isOpenArray(p._type) THEN |
ELSIF PROG.isOpenArray(p.type) THEN |
PARS.check(arrcomp(e, p), pos, 66); |
OpenArray(e._type, p._type) |
OpenArray(e.type, p.type) |
ELSE |
PARS.check(PROG.isTypeEq(e._type, p._type), pos, 66); |
PARS.check(PROG.isTypeEq(e.type, p.type), pos, 66); |
IL.Param1 |
END; |
PARS.check(~e.readOnly, pos, 94) |
580,16 → 570,16 |
ELSE |
PARS.check(isExpr(e) OR isProc(e), pos, 66); |
IF PROG.isOpenArray(p._type) THEN |
IF e._type.typ = PROG.tARRAY THEN |
IF PROG.isOpenArray(p.type) THEN |
IF e.type.typ = PROG.tARRAY THEN |
PARS.check(arrcomp(e, p), pos, 66); |
OpenArray(e._type, p._type) |
ELSIF isString(e) & (p._type.typ = PROG.tARRAY) & (p._type.base = tCHAR) THEN |
OpenArray(e.type, p.type) |
ELSIF isString(e) & (p.type.typ = PROG.tARRAY) & (p.type.base = tCHAR) THEN |
IL.StrAdr(String(e)); |
IL.Param1; |
IL.Const(strlen(e) + 1); |
IL.Param1 |
ELSIF isStringW(e) & (p._type.typ = PROG.tARRAY) & (p._type.base = tWCHAR) THEN |
ELSIF isStringW(e) & (p.type.typ = PROG.tARRAY) & (p.type.base = tWCHAR) THEN |
IL.StrAdr(StringW(e)); |
IL.Param1; |
IL.Const(utf8strlen(e) + 1); |
598,24 → 588,24 |
PARS.error(pos, 66) |
END |
ELSE |
PARS.check(~PROG.isOpenArray(e._type), pos, 66); |
PARS.check(assigncomp(e, p._type), pos, 66); |
PARS.check(~PROG.isOpenArray(e.type), pos, 66); |
PARS.check(assigncomp(e, p.type), pos, 66); |
IF e.obj = eCONST THEN |
IF e._type = tREAL THEN |
Float(parser, e); |
IL.AddCmd0(IL.opPUSHF) |
ELSIF e._type.typ = PROG.tNIL THEN |
IF e.type = tREAL THEN |
IL.Float(ARITH.Float(e.value)); |
IL.pushf |
ELSIF e.type.typ = PROG.tNIL THEN |
IL.Const(0); |
IL.Param1 |
ELSIF isStringW1(e) & (p._type = tWCHAR) THEN |
ELSIF isStringW1(e) & (p.type = tWCHAR) THEN |
IL.Const(StrToWChar(e.value.string(SCAN.IDENT).s)); |
IL.Param1 |
ELSIF (e._type.typ = PROG.tSTRING) OR |
(e._type.typ IN {PROG.tCHAR, PROG.tWCHAR}) & (p._type.typ = PROG.tARRAY) & (p._type.base.typ IN {PROG.tCHAR, PROG.tWCHAR}) THEN |
IF p._type.base = tCHAR THEN |
ELSIF (e.type.typ = PROG.tSTRING) OR |
(e.type.typ IN {PROG.tCHAR, PROG.tWCHAR}) & (p.type.typ = PROG.tARRAY) & (p.type.base.typ IN {PROG.tCHAR, PROG.tWCHAR}) THEN |
IF p.type.base = tCHAR THEN |
stroffs := String(e); |
IL.StrAdr(stroffs); |
IF (CPU = TARGETS.cpuMSP430) & (p._type.size - strlen(e) - 1 > MSP430.IntVectorSize) THEN |
IF (CPU = TARGETS.cpuMSP430) & (p.type.size - strlen(e) - 1 > MSP430.IntVectorSize) THEN |
ERRORS.WarningMsg(pos.line, pos.col, 0) |
END |
ELSE (* WCHAR *) |
622,7 → 612,7 |
stroffs := StringW(e); |
IL.StrAdr(stroffs) |
END; |
IL.set_dmin(stroffs + p._type.size); |
IL.set_dmin(stroffs + p.type.size); |
IL.Param1 |
ELSE |
LoadConst(e); |
633,12 → 623,12 |
IL.PushProc(e.ident.proc.label); |
IL.Param1 |
ELSIF e.obj = eIMP THEN |
IL.PushImpProc(e.ident._import); |
IL.PushImpProc(e.ident.import); |
IL.Param1 |
ELSIF isExpr(e) & (e._type = tREAL) THEN |
IL.AddCmd0(IL.opPUSHF) |
ELSIF isExpr(e) & (e.type = tREAL) THEN |
IL.pushf |
ELSE |
IF (p._type = tBYTE) & (e._type = tINTEGER) & (chkBYTE IN Options.checking) THEN |
IF (p.type = tBYTE) & (e.type = tINTEGER) & (chkBYTE IN Options.checking) THEN |
CheckRange(256, pos.line, errBYTE) |
END; |
IL.Param1 |
661,7 → 651,6 |
pos: PARS.POSITION; |
proc, |
label, |
size, |
n, i: INTEGER; |
code: ARITH.VALUE; |
wchar, |
727,8 → 716,7 |
END |
ELSE |
label := IL.NewLabel(); |
IL.not; |
IL.AndOrOpt(label); |
IL.AddJmpCmd(IL.opJE, label); |
IL.OnError(pos.line, errASSERT); |
IL.SetLabel(label) |
END |
736,7 → 724,7 |
|PROG.stINC, PROG.stDEC: |
IL.pushBegEnd(begcall, endcall); |
varparam(parser, pos, isInt, TRUE, e); |
IF e._type = tINTEGER THEN |
IF e.type = tINTEGER THEN |
IF parser.sym = SCAN.lxCOMMA THEN |
NextPos(parser, pos); |
IL.setlast(begcall); |
751,7 → 739,7 |
ELSE |
IL.AddCmd(IL.opINCC, ORD(proc = PROG.stINC) * 2 - 1) |
END |
ELSE (* e._type = tBYTE *) |
ELSE (* e.type = tBYTE *) |
IF parser.sym = SCAN.lxCOMMA THEN |
NextPos(parser, pos); |
IL.setlast(begcall); |
789,9 → 777,9 |
|PROG.stNEW: |
varparam(parser, pos, isPtr, TRUE, e); |
IF CPU = TARGETS.cpuMSP430 THEN |
PARS.check(e._type.base.size + 16 < Options.ram, pos, 63) |
PARS.check(e.type.base.size + 16 < Options.ram, pos, 63) |
END; |
IL.New(e._type.base.size, e._type.base.num) |
IL.New(e.type.base.size, e.type.base.num) |
|PROG.stDISPOSE: |
varparam(parser, pos, isPtr, TRUE, e); |
827,8 → 815,8 |
PARS.error(pos, 66) |
END; |
IF isCharArrayX(e) & ~PROG.isOpenArray(e._type) THEN |
IL.Const(e._type.length) |
IF isCharArrayX(e) & ~PROG.isOpenArray(e.type) THEN |
IL.Const(e.type.length) |
END; |
PARS.checklex(parser, SCAN.lxCOMMA); |
844,11 → 832,11 |
varparam(parser, pos, isCharArray, TRUE, e1) |
END; |
wchar := e1._type.base = tWCHAR |
wchar := e1.type.base = tWCHAR |
END; |
IF ~PROG.isOpenArray(e1._type) THEN |
IL.Const(e1._type.length) |
IF ~PROG.isOpenArray(e1.type) THEN |
IL.Const(e1.type.length) |
END; |
IL.setlast(endcall.prev(IL.COMMAND)); |
862,10 → 850,10 |
IL.Const(strlen(e) + 1) |
END |
END; |
IL.AddCmd(IL.opCOPYS, e1._type.base.size); |
IL.AddCmd(IL.opCOPYS, e1.type.base.size); |
IL.popBegEnd(begcall, endcall) |
|PROG.sysGET, PROG.sysGET8, PROG.sysGET16, PROG.sysGET32: |
|PROG.sysGET: |
PExpression(parser, e); |
PARS.check(isInt(e), pos, 66); |
PARS.checklex(parser, SCAN.lxCOMMA); |
872,25 → 860,11 |
NextPos(parser, pos); |
parser.designator(parser, e2); |
PARS.check(isVar(e2), pos, 93); |
IF proc = PROG.sysGET THEN |
PARS.check(e2._type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66) |
ELSE |
PARS.check(e2._type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tSET, PROG.tWCHAR, PROG.tCARD32}, pos, 66) |
END; |
CASE proc OF |
|PROG.sysGET: size := e2._type.size |
|PROG.sysGET8: size := 1 |
|PROG.sysGET16: size := 2 |
|PROG.sysGET32: size := 4 |
END; |
PARS.check(size <= e2._type.size, pos, 66); |
PARS.check(e2.type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66); |
IF e.obj = eCONST THEN |
IL.AddCmd2(IL.opGETC, ARITH.Int(e.value), size) |
IL.AddCmd2(IL.opGETC, ARITH.Int(e.value), e2.type.size) |
ELSE |
IL.AddCmd(IL.opGET, size) |
IL.AddCmd(IL.opGET, e2.type.size) |
END |
|PROG.sysPUT, PROG.sysPUT8, PROG.sysPUT16, PROG.sysPUT32: |
907,40 → 881,39 |
PARS.check(isExpr(e2), pos, 66); |
IF proc = PROG.sysPUT THEN |
PARS.check(e2._type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66); |
PARS.check(e2.type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66); |
IF e2.obj = eCONST THEN |
IF e2._type = tREAL THEN |
Float(parser, e2); |
IF e2.type = tREAL THEN |
IL.Float(ARITH.Float(e2.value)); |
IL.setlast(endcall.prev(IL.COMMAND)); |
IL.savef(FALSE) |
ELSE |
LoadConst(e2); |
IL.setlast(endcall.prev(IL.COMMAND)); |
IL.SysPut(e2._type.size) |
IL.SysPut(e2.type.size) |
END |
ELSE |
IL.setlast(endcall.prev(IL.COMMAND)); |
IF e2._type = tREAL THEN |
IF e2.type = tREAL THEN |
IL.savef(FALSE) |
ELSIF e2._type = tBYTE THEN |
ELSIF e2.type = tBYTE THEN |
IL.SysPut(tINTEGER.size) |
ELSE |
IL.SysPut(e2._type.size) |
IL.SysPut(e2.type.size) |
END |
END |
ELSIF (proc = PROG.sysPUT8) OR (proc = PROG.sysPUT16) OR (proc = PROG.sysPUT32) THEN |
PARS.check(e2._type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tSET, PROG.tWCHAR, PROG.tCARD32}, pos, 66); |
PARS.check(e2.type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tSET, PROG.tWCHAR, PROG.tCARD32}, pos, 66); |
IF e2.obj = eCONST THEN |
LoadConst(e2) |
END; |
IL.setlast(endcall.prev(IL.COMMAND)); |
CASE proc OF |
|PROG.sysPUT8: size := 1 |
|PROG.sysPUT16: size := 2 |
|PROG.sysPUT32: size := 4 |
END; |
IL.SysPut(size) |
|PROG.sysPUT8: IL.SysPut(1) |
|PROG.sysPUT16: IL.SysPut(2) |
|PROG.sysPUT32: IL.SysPut(4) |
END |
END; |
IL.popBegEnd(begcall, endcall) |
967,7 → 940,7 |
FOR i := 1 TO 2 DO |
parser.designator(parser, e); |
PARS.check(isVar(e), pos, 93); |
n := PROG.Dim(e._type); |
n := PROG.Dim(e.type); |
WHILE n > 0 DO |
IL.drop; |
DEC(n) |
988,11 → 961,10 |
getpos(parser, pos); |
PARS.ConstExpression(parser, code); |
PARS.check(code.typ = ARITH.tINTEGER, pos, 43); |
IF TARGETS.WordSize > TARGETS.InstrSize THEN |
CASE TARGETS.InstrSize OF |
|1: PARS.check(ARITH.range(code, 0, 255), pos, 42) |
|2: PARS.check(ARITH.range(code, 0, 65535), pos, 110) |
END |
IF CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN |
PARS.check(ARITH.range(code, 0, 255), pos, 42) |
ELSIF CPU = TARGETS.cpuTHUMB THEN |
PARS.check(ARITH.range(code, 0, 65535), pos, 110) |
END; |
IL.AddCmd(IL.opCODE, ARITH.getInt(code)); |
comma := parser.sym = SCAN.lxCOMMA; |
1019,7 → 991,7 |
END; |
e.obj := eEXPR; |
e._type := NIL |
e.type := NIL |
ELSIF e.obj IN {eSTFUNC, eSYSFUNC} THEN |
1040,7 → 1012,7 |
NextPos(parser, pos); |
PExpression(parser, e2); |
PARS.check(isInt(e2), pos, 66); |
e._type := tINTEGER; |
e.type := tINTEGER; |
IF (e.obj = eCONST) & (e2.obj = eCONST) THEN |
ASSERT(ARITH.opInt(e.value, e2.value, shift_minmax(proc))) |
ELSE |
1057,7 → 1029,7 |
|PROG.stCHR: |
PExpression(parser, e); |
PARS.check(isInt(e), pos, 66); |
e._type := tCHAR; |
e.type := tCHAR; |
IF e.obj = eCONST THEN |
ARITH.setChar(e.value, ARITH.getInt(e.value)); |
PARS.check(ARITH.check(e.value), pos, 107) |
1072,7 → 1044,7 |
|PROG.stWCHR: |
PExpression(parser, e); |
PARS.check(isInt(e), pos, 66); |
e._type := tWCHAR; |
e.type := tWCHAR; |
IF e.obj = eCONST THEN |
ARITH.setWChar(e.value, ARITH.getInt(e.value)); |
PARS.check(ARITH.check(e.value), pos, 101) |
1087,58 → 1059,58 |
|PROG.stFLOOR: |
PExpression(parser, e); |
PARS.check(isReal(e), pos, 66); |
e._type := tINTEGER; |
e.type := tINTEGER; |
IF e.obj = eCONST THEN |
PARS.check(ARITH.floor(e.value), pos, 39) |
ELSE |
IL.AddCmd0(IL.opFLOOR) |
IL.floor |
END |
|PROG.stFLT: |
PExpression(parser, e); |
PARS.check(isInt(e), pos, 66); |
e._type := tREAL; |
e.type := tREAL; |
IF e.obj = eCONST THEN |
ARITH.flt(e.value) |
ELSE |
IL.AddCmd2(IL.opFLT, pos.line, pos.col) |
PARS.check(IL.flt(), pos, 41) |
END |
|PROG.stLEN: |
cmd1 := IL.getlast(); |
varparam(parser, pos, isArr, FALSE, e); |
IF e._type.length > 0 THEN |
IF e.type.length > 0 THEN |
cmd2 := IL.getlast(); |
IL.delete2(cmd1.next, cmd2); |
IL.setlast(cmd1); |
ASSERT(ARITH.setInt(e.value, e._type.length)); |
ASSERT(ARITH.setInt(e.value, e.type.length)); |
e.obj := eCONST |
ELSE |
IL.len(PROG.Dim(e._type)) |
IL.len(PROG.Dim(e.type)) |
END; |
e._type := tINTEGER |
e.type := tINTEGER |
|PROG.stLENGTH: |
PExpression(parser, e); |
IF isCharArray(e) THEN |
IF e._type.length > 0 THEN |
IL.Const(e._type.length) |
IF e.type.length > 0 THEN |
IL.Const(e.type.length) |
END; |
IL.AddCmd0(IL.opLENGTH) |
ELSIF isCharArrayW(e) THEN |
IF e._type.length > 0 THEN |
IL.Const(e._type.length) |
IF e.type.length > 0 THEN |
IL.Const(e.type.length) |
END; |
IL.AddCmd0(IL.opLENGTHW) |
ELSE |
PARS.error(pos, 66); |
END; |
e._type := tINTEGER |
e.type := tINTEGER |
|PROG.stODD: |
PExpression(parser, e); |
PARS.check(isInt(e), pos, 66); |
e._type := tBOOLEAN; |
e.type := tBOOLEAN; |
IF e.obj = eCONST THEN |
ARITH.odd(e.value) |
ELSE |
1156,10 → 1128,10 |
END |
ELSE |
IF isBoolean(e) THEN |
IL._ord |
IL.AddCmd0(IL.opORD) |
END |
END; |
e._type := tINTEGER |
e.type := tINTEGER |
|PROG.stBITS: |
PExpression(parser, e); |
1167,12 → 1139,12 |
IF e.obj = eCONST THEN |
ARITH.bits(e.value) |
END; |
e._type := tSET |
e.type := tSET |
|PROG.sysADR: |
parser.designator(parser, e); |
IF isVar(e) THEN |
n := PROG.Dim(e._type); |
n := PROG.Dim(e.type); |
WHILE n > 0 DO |
IL.drop; |
DEC(n) |
1180,17 → 1152,17 |
ELSIF e.obj = ePROC THEN |
IL.PushProc(e.ident.proc.label) |
ELSIF e.obj = eIMP THEN |
IL.PushImpProc(e.ident._import) |
IL.PushImpProc(e.ident.import) |
ELSE |
PARS.error(pos, 108) |
END; |
e._type := tINTEGER |
e.type := tINTEGER |
|PROG.sysSADR: |
PExpression(parser, e); |
PARS.check(isString(e), pos, 66); |
IL.StrAdr(String(e)); |
e._type := tINTEGER; |
e.type := tINTEGER; |
e.obj := eEXPR |
|PROG.sysWSADR: |
1197,33 → 1169,33 |
PExpression(parser, e); |
PARS.check(isStringW(e), pos, 66); |
IL.StrAdr(StringW(e)); |
e._type := tINTEGER; |
e.type := tINTEGER; |
e.obj := eEXPR |
|PROG.sysTYPEID: |
PExpression(parser, e); |
PARS.check(e.obj = eTYPE, pos, 68); |
IF e._type.typ = PROG.tRECORD THEN |
ASSERT(ARITH.setInt(e.value, e._type.num)) |
ELSIF e._type.typ = PROG.tPOINTER THEN |
ASSERT(ARITH.setInt(e.value, e._type.base.num)) |
IF e.type.typ = PROG.tRECORD THEN |
ASSERT(ARITH.setInt(e.value, e.type.num)) |
ELSIF e.type.typ = PROG.tPOINTER THEN |
ASSERT(ARITH.setInt(e.value, e.type.base.num)) |
ELSE |
PARS.error(pos, 52) |
END; |
e.obj := eCONST; |
e._type := tINTEGER |
e.type := tINTEGER |
|PROG.sysINF: |
IL.AddCmd2(IL.opINF, pos.line, pos.col); |
PARS.check(IL.inf(), pos, 41); |
e.obj := eEXPR; |
e._type := tREAL |
e.type := tREAL |
|PROG.sysSIZE: |
PExpression(parser, e); |
PARS.check(e.obj = eTYPE, pos, 68); |
ASSERT(ARITH.setInt(e.value, e._type.size)); |
ASSERT(ARITH.setInt(e.value, e.type.size)); |
e.obj := eCONST; |
e._type := tINTEGER |
e.type := tINTEGER |
END |
1243,7 → 1215,7 |
PROCEDURE ActualParameters (parser: PARS.PARSER; VAR e: PARS.EXPR); |
VAR |
proc: PROG._TYPE; |
proc: PROG.TYPE_; |
param: LISTS.ITEM; |
e1: PARS.EXPR; |
pos: PARS.POSITION; |
1252,7 → 1224,7 |
ASSERT(parser.sym = SCAN.lxLROUND); |
IF (e.obj IN {ePROC, eIMP}) OR isExpr(e) THEN |
proc := e._type; |
proc := e.type; |
PARS.check1(proc.typ = PROG.tPROCEDURE, parser, 86); |
PARS.Next(parser); |
1279,7 → 1251,7 |
PARS.Next(parser); |
e.obj := eEXPR; |
e._type := proc.base |
e.type := proc.base |
ELSIF e.obj IN {eSTPROC, eSTFUNC, eSYSPROC, eSYSFUNC} THEN |
stProc(parser, e) |
1293,13 → 1265,13 |
PROCEDURE qualident (parser: PARS.PARSER; VAR e: PARS.EXPR); |
VAR |
ident: PROG.IDENT; |
imp: BOOLEAN; |
import: BOOLEAN; |
pos: PARS.POSITION; |
BEGIN |
PARS.checklex(parser, SCAN.lxIDENT); |
getpos(parser, pos); |
imp := FALSE; |
import := FALSE; |
ident := PROG.getIdent(parser.unit, parser.lex.ident, FALSE); |
PARS.check1(ident # NIL, parser, 48); |
IF ident.typ = PROG.idMODULE THEN |
1307,7 → 1279,7 |
PARS.ExpectSym(parser, SCAN.lxIDENT); |
ident := PROG.getIdent(ident.unit, parser.lex.ident, FALSE); |
PARS.check1((ident # NIL) & ident.export, parser, 48); |
imp := TRUE |
import := TRUE |
END; |
PARS.Next(parser); |
1317,24 → 1289,24 |
CASE ident.typ OF |
|PROG.idCONST: |
e.obj := eCONST; |
e._type := ident._type; |
e.type := ident.type; |
e.value := ident.value |
|PROG.idTYPE: |
e.obj := eTYPE; |
e._type := ident._type |
e.type := ident.type |
|PROG.idVAR: |
e.obj := eVAR; |
e._type := ident._type; |
e.readOnly := imp |
e.type := ident.type; |
e.readOnly := import |
|PROG.idPROC: |
e.obj := ePROC; |
e._type := ident._type |
e.type := ident.type |
|PROG.idIMP: |
e.obj := eIMP; |
e._type := ident._type |
e.type := ident.type |
|PROG.idVPAR: |
e._type := ident._type; |
IF e._type.typ = PROG.tRECORD THEN |
e.type := ident.type; |
IF e.type.typ = PROG.tRECORD THEN |
e.obj := eVREC |
ELSE |
e.obj := eVPAR |
1341,24 → 1313,20 |
END |
|PROG.idPARAM: |
e.obj := ePARAM; |
e._type := ident._type; |
e.readOnly := (e._type.typ IN {PROG.tRECORD, PROG.tARRAY}) |
e.type := ident.type; |
e.readOnly := (e.type.typ IN {PROG.tRECORD, PROG.tARRAY}) |
|PROG.idSTPROC: |
e.obj := eSTPROC; |
e._type := ident._type; |
e.stproc := ident.stproc |
|PROG.idSTFUNC: |
e.obj := eSTFUNC; |
e._type := ident._type; |
e.stproc := ident.stproc |
|PROG.idSYSPROC: |
e.obj := eSYSPROC; |
e._type := ident._type; |
e.stproc := ident.stproc |
|PROG.idSYSFUNC: |
PARS.check(~parser.constexp, pos, 109); |
e.obj := eSYSFUNC; |
e._type := ident._type; |
e.stproc := ident.stproc |
|PROG.idNONE: |
PARS.error(pos, 115) |
1377,12 → 1345,12 |
BEGIN |
IF load THEN |
IL.load(e._type.size) |
IL.load(e.type.size) |
END; |
IF chkPTR IN Options.checking THEN |
label := IL.NewLabel(); |
IL.AddJmpCmd(IL.opJNZ1, label); |
IL.AddJmpCmd(IL.opJNZ, label); |
IL.OnError(pos.line, error); |
IL.SetLabel(label) |
END |
1405,7 → 1373,7 |
offset, n: INTEGER; |
BEGIN |
offset := e.ident.offset; |
n := PROG.Dim(e._type); |
n := PROG.Dim(e.type); |
WHILE n >= 0 DO |
IL.AddCmd(IL.opVADR, offset); |
DEC(offset); |
1416,7 → 1384,7 |
BEGIN |
IF e.obj = eVAR THEN |
offset := PROG.getOffset(e.ident); |
offset := PROG.getOffset(PARS.program, e.ident); |
IF e.ident.global THEN |
IL.AddCmd(IL.opGADR, offset) |
ELSE |
1423,15 → 1391,15 |
IL.AddCmd(IL.opLADR, -offset) |
END |
ELSIF e.obj = ePARAM THEN |
IF (e._type.typ = PROG.tRECORD) OR ((e._type.typ = PROG.tARRAY) & (e._type.length > 0)) THEN |
IF (e.type.typ = PROG.tRECORD) OR ((e.type.typ = PROG.tARRAY) & (e.type.length > 0)) THEN |
IL.AddCmd(IL.opVADR, e.ident.offset) |
ELSIF PROG.isOpenArray(e._type) THEN |
ELSIF PROG.isOpenArray(e.type) THEN |
OpenArray(e) |
ELSE |
IL.AddCmd(IL.opLADR, e.ident.offset) |
END |
ELSIF e.obj IN {eVPAR, eVREC} THEN |
IF PROG.isOpenArray(e._type) THEN |
IF PROG.isOpenArray(e.type) THEN |
OpenArray(e) |
ELSE |
IL.AddCmd(IL.opVADR, e.ident.offset) |
1443,7 → 1411,7 |
PROCEDURE OpenIdx (parser: PARS.PARSER; pos: PARS.POSITION; e: PARS.EXPR); |
VAR |
label, offset, n, k: INTEGER; |
_type: PROG._TYPE; |
type: PROG.TYPE_; |
BEGIN |
1456,11 → 1424,11 |
IL.AddCmd(IL.opCHKIDX2, -1) |
END; |
_type := PROG.OpenBase(e._type); |
IF _type.size # 1 THEN |
IL.AddCmd(IL.opMULC, _type.size) |
type := PROG.OpenBase(e.type); |
IF type.size # 1 THEN |
IL.AddCmd(IL.opMULC, type.size) |
END; |
n := PROG.Dim(e._type) - 1; |
n := PROG.Dim(e.type) - 1; |
k := n; |
WHILE n > 0 DO |
IL.AddCmd0(IL.opMUL); |
1490,23 → 1458,23 |
WHILE parser.sym = SCAN.lxPOINT DO |
getpos(parser, pos); |
PARS.check1(isExpr(e) & (e._type.typ IN {PROG.tRECORD, PROG.tPOINTER}), parser, 73); |
IF e._type.typ = PROG.tPOINTER THEN |
PARS.check1(isExpr(e) & (e.type.typ IN {PROG.tRECORD, PROG.tPOINTER}), parser, 73); |
IF e.type.typ = PROG.tPOINTER THEN |
deref(pos, e, TRUE, errPTR) |
END; |
PARS.ExpectSym(parser, SCAN.lxIDENT); |
IF e._type.typ = PROG.tPOINTER THEN |
e._type := e._type.base; |
IF e.type.typ = PROG.tPOINTER THEN |
e.type := e.type.base; |
e.readOnly := FALSE |
END; |
field := PROG.getField(e._type, parser.lex.ident, parser.unit); |
field := PROG.getField(e.type, parser.lex.ident, parser.unit); |
PARS.check1(field # NIL, parser, 74); |
e._type := field._type; |
e.type := field.type; |
IF e.obj = eVREC THEN |
e.obj := eVPAR |
END; |
IF field.offset # 0 THEN |
IL.AddCmd(IL.opADDC, field.offset) |
IL.AddCmd(IL.opADDR, field.offset) |
END; |
PARS.Next(parser); |
e.ident := NIL |
1521,10 → 1489,10 |
PARS.check(isInt(idx), pos, 76); |
IF idx.obj = eCONST THEN |
IF e._type.length > 0 THEN |
PARS.check(ARITH.range(idx.value, 0, e._type.length - 1), pos, 83); |
IF e.type.length > 0 THEN |
PARS.check(ARITH.range(idx.value, 0, e.type.length - 1), pos, 83); |
IF ARITH.Int(idx.value) > 0 THEN |
IL.AddCmd(IL.opADDC, ARITH.Int(idx.value) * e._type.base.size) |
IL.AddCmd(IL.opADDR, ARITH.Int(idx.value) * e.type.base.size) |
END |
ELSE |
PARS.check(ARITH.range(idx.value, 0, UTILS.target.maxInt), pos, 83); |
1532,12 → 1500,12 |
OpenIdx(parser, pos, e) |
END |
ELSE |
IF e._type.length > 0 THEN |
IF e.type.length > 0 THEN |
IF chkIDX IN Options.checking THEN |
CheckRange(e._type.length, pos.line, errIDX) |
CheckRange(e.type.length, pos.line, errIDX) |
END; |
IF e._type.base.size # 1 THEN |
IL.AddCmd(IL.opMULC, e._type.base.size) |
IF e.type.base.size # 1 THEN |
IL.AddCmd(IL.opMULC, e.type.base.size) |
END; |
IL.AddCmd0(IL.opADD) |
ELSE |
1545,7 → 1513,7 |
END |
END; |
e._type := e._type.base |
e.type := e.type.base |
UNTIL parser.sym # SCAN.lxCOMMA; |
1557,15 → 1525,15 |
getpos(parser, pos); |
PARS.check1(isPtr(e), parser, 77); |
deref(pos, e, TRUE, errPTR); |
e._type := e._type.base; |
e.type := e.type.base; |
e.readOnly := FALSE; |
PARS.Next(parser); |
e.ident := NIL; |
e.obj := eVREC |
ELSIF (parser.sym = SCAN.lxLROUND) & isExpr(e) & (e._type.typ IN {PROG.tRECORD, PROG.tPOINTER}) DO |
ELSIF (parser.sym = SCAN.lxLROUND) & isExpr(e) & (e.type.typ IN {PROG.tRECORD, PROG.tPOINTER}) DO |
IF e._type.typ = PROG.tRECORD THEN |
IF e.type.typ = PROG.tRECORD THEN |
PARS.check1(e.obj = eVREC, parser, 78) |
END; |
NextPos(parser, pos); |
1572,26 → 1540,26 |
qualident(parser, t); |
PARS.check(t.obj = eTYPE, pos, 79); |
IF e._type.typ = PROG.tRECORD THEN |
PARS.check(t._type.typ = PROG.tRECORD, pos, 80); |
IF e.type.typ = PROG.tRECORD THEN |
PARS.check(t.type.typ = PROG.tRECORD, pos, 80); |
IF chkGUARD IN Options.checking THEN |
IF e.ident = NIL THEN |
IL.TypeGuard(IL.opTYPEGD, t._type.num, pos.line, errGUARD) |
IL.TypeGuard(IL.opTYPEGD, t.type.num, pos.line, errGUARD) |
ELSE |
IL.AddCmd(IL.opVADR, e.ident.offset - 1); |
IL.TypeGuard(IL.opTYPEGR, t._type.num, pos.line, errGUARD) |
IL.TypeGuard(IL.opTYPEGR, t.type.num, pos.line, errGUARD) |
END |
END; |
ELSE |
PARS.check(t._type.typ = PROG.tPOINTER, pos, 81); |
PARS.check(t.type.typ = PROG.tPOINTER, pos, 81); |
IF chkGUARD IN Options.checking THEN |
IL.TypeGuard(IL.opTYPEGP, t._type.base.num, pos.line, errGUARD) |
IL.TypeGuard(IL.opTYPEGP, t.type.base.num, pos.line, errGUARD) |
END |
END; |
PARS.check(PROG.isBaseOf(e._type, t._type), pos, 82); |
PARS.check(PROG.isBaseOf(e.type, t.type), pos, 82); |
e._type := t._type; |
e.type := t.type; |
PARS.checklex(parser, SCAN.lxRROUND); |
PARS.Next(parser) |
1601,7 → 1569,7 |
END designator; |
PROCEDURE ProcCall (e: PARS.EXPR; procType: PROG._TYPE; isfloat: BOOLEAN; parser: PARS.PARSER; pos: PARS.POSITION; CallStat: BOOLEAN); |
PROCEDURE ProcCall (e: PARS.EXPR; procType: PROG.TYPE_; isfloat: BOOLEAN; VAR fregs: INTEGER; parser: PARS.PARSER; pos: PARS.POSITION; CallStat: BOOLEAN); |
VAR |
cconv, |
parSize, |
1626,7 → 1594,7 |
fparSize := 0 |
END; |
IL.setlast(begcall); |
IL.AddCmd(IL.opPRECALL, ORD(isfloat)); |
fregs := IL.precall(isfloat); |
IF cconv IN {PROG._ccall16, PROG.ccall16} THEN |
IL.AddCmd(IL.opALIGN16, parSize) |
1638,7 → 1606,7 |
IL.setlast(endcall.prev(IL.COMMAND)); |
IF e.obj = eIMP THEN |
IL.CallImp(e.ident._import, callconv, fparSize) |
IL.CallImp(e.ident.import, callconv, fparSize) |
ELSIF e.obj = ePROC THEN |
IL.Call(e.ident.proc.label, callconv, fparSize) |
ELSIF isExpr(e) THEN |
1659,14 → 1627,11 |
IL.AddCmd(IL.opCLEANUP, parSize) |
END; |
IF CallStat THEN |
IL.AddCmd0(IL.opRES); |
IL.drop |
ELSE |
IF ~CallStat THEN |
IF isfloat THEN |
IL.AddCmd2(IL.opRESF, pos.line, pos.col) |
PARS.check(IL.resf(fregs), pos, 41) |
ELSE |
IL.AddCmd0(IL.opRES) |
IL.res(fregs) |
END |
END |
END ProcCall; |
1675,9 → 1640,12 |
PROCEDURE expression (parser: PARS.PARSER; VAR e: PARS.EXPR); |
VAR |
pos, pos0, pos1: PARS.POSITION; |
op: INTEGER; |
e1: PARS.EXPR; |
op, cmp, error: INTEGER; |
constant, eq: BOOLEAN; |
constant: BOOLEAN; |
operator: ARITH.RELATION; |
error: INTEGER; |
PROCEDURE relation (sym: INTEGER): BOOLEAN; |
1733,7 → 1701,7 |
END |
END; |
e._type := tSET; |
e.type := tSET; |
IF (e1.obj = eCONST) & (e2.obj = eCONST) THEN |
ARITH.constrSet(e.value, e1.value, e2.value); |
1764,7 → 1732,7 |
ASSERT(parser.sym = SCAN.lxLCURLY); |
e.obj := eCONST; |
e._type := tSET; |
e.type := tSET; |
ARITH.emptySet(e.value); |
PARS.Next(parser); |
1784,9 → 1752,9 |
ARITH.opSet(e.value, e1.value, "+") |
ELSE |
IF e.obj = eCONST THEN |
IL.AddCmd(IL.opADDSC, ARITH.Int(e.value)) |
IL.AddCmd(IL.opADDSL, ARITH.Int(e.value)) |
ELSIF e1.obj = eCONST THEN |
IL.AddCmd(IL.opADDSC, ARITH.Int(e1.value)) |
IL.AddCmd(IL.opADDSR, ARITH.Int(e1.value)) |
ELSE |
IL.AddCmd0(IL.opADDS) |
END; |
1805,15 → 1773,16 |
pos: PARS.POSITION; |
e1: PARS.EXPR; |
isfloat: BOOLEAN; |
fregs: INTEGER; |
PROCEDURE LoadVar (e: PARS.EXPR; parser: PARS.PARSER; pos: PARS.POSITION); |
BEGIN |
IF ~(e._type.typ IN {PROG.tRECORD, PROG.tARRAY}) THEN |
IF e._type = tREAL THEN |
IL.AddCmd2(IL.opLOADF, pos.line, pos.col) |
IF ~(e.type.typ IN {PROG.tRECORD, PROG.tARRAY}) THEN |
IF e.type = tREAL THEN |
PARS.check(IL.loadf(), pos, 41) |
ELSE |
IL.load(e._type.size) |
IL.load(e.type.size) |
END |
END |
END LoadVar; |
1825,18 → 1794,18 |
IF (sym = SCAN.lxINTEGER) OR (sym = SCAN.lxHEX) OR (sym = SCAN.lxFLOAT) OR (sym = SCAN.lxCHAR) OR (sym = SCAN.lxSTRING) THEN |
e.obj := eCONST; |
e.value := parser.lex.value; |
e._type := PROG.getType(e.value.typ); |
e.type := PROG.getType(PARS.program, e.value.typ); |
PARS.Next(parser) |
ELSIF sym = SCAN.lxNIL THEN |
e.obj := eCONST; |
e._type := PROG.program.stTypes.tNIL; |
e.type := PARS.program.stTypes.tNIL; |
PARS.Next(parser) |
ELSIF (sym = SCAN.lxTRUE) OR (sym = SCAN.lxFALSE) THEN |
e.obj := eCONST; |
ARITH.setbool(e.value, sym = SCAN.lxTRUE); |
e._type := tBOOLEAN; |
e.type := tBOOLEAN; |
PARS.Next(parser) |
ELSIF sym = SCAN.lxLCURLY THEN |
1854,12 → 1823,12 |
IF parser.sym = SCAN.lxLROUND THEN |
e1 := e; |
ActualParameters(parser, e); |
PARS.check(e._type # NIL, pos, 59); |
isfloat := e._type = tREAL; |
PARS.check(e.type # NIL, pos, 59); |
isfloat := e.type = tREAL; |
IF e1.obj IN {ePROC, eIMP} THEN |
ProcCall(e1, e1.ident._type, isfloat, parser, pos, FALSE) |
ProcCall(e1, e1.ident.type, isfloat, fregs, parser, pos, FALSE) |
ELSIF isExpr(e1) THEN |
ProcCall(e1, e1._type, isfloat, parser, pos, FALSE) |
ProcCall(e1, e1.type, isfloat, fregs, parser, pos, FALSE) |
END |
END; |
IL.popBegEnd(begcall, endcall) |
1915,7 → 1884,9 |
IF e.obj = eCONST THEN |
IL.Const(ORD(ARITH.getBool(e.value))) |
END; |
IL.AndOrOpt(label) |
IL.AddCmd0(IL.opACC); |
IL.AddJmpCmd(IL.opJZ, label); |
IL.drop |
END |
END; |
1943,11 → 1914,11 |
END |
ELSIF isReal(e) THEN |
IF e.obj = eCONST THEN |
Float(parser, e) |
IL.Float(ARITH.Float(e.value)) |
ELSIF e1.obj = eCONST THEN |
Float(parser, e1) |
IL.Float(ARITH.Float(e1.value)) |
END; |
IL.AddCmd0(IL.opMULF) |
IL.fbinop(IL.opMULF) |
ELSIF isSet(e) THEN |
IF e.obj = eCONST THEN |
IL.AddCmd(IL.opMULSC, ARITH.Int(e.value)) |
1975,13 → 1946,13 |
ELSE |
IF isReal(e) THEN |
IF e.obj = eCONST THEN |
Float(parser, e); |
IL.AddCmd0(IL.opDIVFI) |
IL.Float(ARITH.Float(e.value)); |
IL.fbinop(IL.opDIVFI) |
ELSIF e1.obj = eCONST THEN |
Float(parser, e1); |
IL.AddCmd0(IL.opDIVF) |
IL.Float(ARITH.Float(e1.value)); |
IL.fbinop(IL.opDIVF) |
ELSE |
IL.AddCmd0(IL.opDIVF) |
IL.fbinop(IL.opDIVF) |
END |
ELSIF isSet(e) THEN |
IF e.obj = eCONST THEN |
2036,24 → 2007,15 |
e.obj := eEXPR; |
IF e1.obj = eCONST THEN |
IL.Const(ORD(ARITH.getBool(e1.value))) |
END; |
IL.AddCmd0(IL.opACC) |
END |
END |
END |
END; |
IF label # -1 THEN |
label1 := IL.NewLabel(); |
IL.AddJmpCmd(IL.opJNZ, label1); |
IL.SetLabel(label); |
IL.Const(0); |
IL.drop; |
label := IL.NewLabel(); |
IL.AddJmpCmd(IL.opJMP, label); |
IL.SetLabel(label1); |
IL.Const(1); |
IL.SetLabel(label); |
IL.AddCmd0(IL.opAND) |
IL.SetLabel(label) |
END |
END term; |
2063,11 → 2025,10 |
pos: PARS.POSITION; |
op: INTEGER; |
e1: PARS.EXPR; |
s, s1: SCAN.LEXSTR; |
plus, minus: BOOLEAN; |
label, label1: INTEGER; |
label: INTEGER; |
BEGIN |
plus := parser.sym = SCAN.lxPLUS; |
2120,8 → 2081,9 |
IF e.obj = eCONST THEN |
IL.Const(ORD(ARITH.getBool(e.value))) |
END; |
IL.not; |
IL.AndOrOpt(label) |
IL.AddCmd0(IL.opACC); |
IL.AddJmpCmd(IL.opJNZ, label); |
IL.drop |
END |
END; |
2131,69 → 2093,47 |
CASE op OF |
|SCAN.lxPLUS, SCAN.lxMINUS: |
minus := op = SCAN.lxMINUS; |
IF minus THEN |
IF op = SCAN.lxPLUS THEN |
op := ORD("+") |
ELSE |
op := ORD("-") |
ELSE |
op := ORD("+") |
END; |
PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1) OR isString(e) & isString(e1) & ~minus, pos, 37); |
PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), pos, 37); |
IF (e.obj = eCONST) & (e1.obj = eCONST) THEN |
CASE e.value.typ OF |
|ARITH.tINTEGER: |
PARS.check(ARITH.opInt(e.value, e1.value, CHR(op)), pos, 39) |
|ARITH.tREAL: |
PARS.check(ARITH.opFloat(e.value, e1.value, CHR(op)), pos, 40) |
|ARITH.tSET: |
ARITH.opSet(e.value, e1.value, CHR(op)) |
|ARITH.tCHAR, ARITH.tSTRING: |
IF e.value.typ = ARITH.tCHAR THEN |
ARITH.charToStr(e.value, s) |
ELSE |
s := e.value.string(SCAN.IDENT).s |
END; |
IF e1.value.typ = ARITH.tCHAR THEN |
ARITH.charToStr(e1.value, s1) |
ELSE |
s1 := e1.value.string(SCAN.IDENT).s |
END; |
PARS.check(ARITH.concat(s, s1), pos, 5); |
e.value.string := SCAN.enterid(s); |
e.value.typ := ARITH.tSTRING; |
e._type := PROG.program.stTypes.tSTRING |
|ARITH.tINTEGER: PARS.check(ARITH.opInt(e.value, e1.value, CHR(op)), pos, 39) |
|ARITH.tREAL: PARS.check(ARITH.opFloat(e.value, e1.value, CHR(op)), pos, 40) |
|ARITH.tSET: ARITH.opSet(e.value, e1.value, CHR(op)) |
END |
ELSE |
IF isInt(e) THEN |
IF e.obj = eCONST THEN |
IL.AddCmd(IL.opADDC - ORD(minus), ARITH.Int(e.value)) |
IL.AddCmd(IL.opADDL + ORD(op = ORD("-")), ARITH.Int(e.value)) |
ELSIF e1.obj = eCONST THEN |
IL.AddCmd(IL.opADDC + ORD(minus), ARITH.Int(e1.value)) |
IL.AddCmd(IL.opADDR + ORD(op = ORD("-")), ARITH.Int(e1.value)) |
ELSE |
IL.AddCmd0(IL.opADD + ORD(minus)) |
IL.AddCmd0(IL.opADD + ORD(op = ORD("-"))) |
END |
ELSIF isReal(e) THEN |
IF e.obj = eCONST THEN |
Float(parser, e); |
IL.AddCmd0(IL.opADDF - ORD(minus)) |
IL.Float(ARITH.Float(e.value)); |
IL.fbinop(IL.opADDFI + ORD(op = ORD("-"))) |
ELSIF e1.obj = eCONST THEN |
Float(parser, e1); |
IL.AddCmd0(IL.opADDF + ORD(minus)) |
IL.Float(ARITH.Float(e1.value)); |
IL.fbinop(IL.opADDF + ORD(op = ORD("-"))) |
ELSE |
IL.AddCmd0(IL.opADDF + ORD(minus)) |
IL.fbinop(IL.opADDF + ORD(op = ORD("-"))) |
END |
ELSIF isSet(e) THEN |
IF e.obj = eCONST THEN |
IL.AddCmd(IL.opADDSC - ORD(minus), ARITH.Int(e.value)) |
IL.AddCmd(IL.opADDSL + ORD(op = ORD("-")), ARITH.Int(e.value)) |
ELSIF e1.obj = eCONST THEN |
IL.AddCmd(IL.opADDSC + ORD(minus), ARITH.Int(e1.value)) |
IL.AddCmd(IL.opADDSR + ORD(op = ORD("-")), ARITH.Int(e1.value)) |
ELSE |
IL.AddCmd0(IL.opADDS + ORD(minus)) |
IL.AddCmd0(IL.opADDS + ORD(op = ORD("-"))) |
END |
END; |
e.obj := eEXPR |
2208,24 → 2148,15 |
e.obj := eEXPR; |
IF e1.obj = eCONST THEN |
IL.Const(ORD(ARITH.getBool(e1.value))) |
END; |
IL.AddCmd0(IL.opACC) |
END |
END |
END |
END; |
IF label # -1 THEN |
label1 := IL.NewLabel(); |
IL.AddJmpCmd(IL.opJZ, label1); |
IL.SetLabel(label); |
IL.Const(1); |
IL.drop; |
label := IL.NewLabel(); |
IL.AddJmpCmd(IL.opJMP, label); |
IL.SetLabel(label1); |
IL.Const(0); |
IL.SetLabel(label); |
IL.AddCmd0(IL.opOR) |
IL.SetLabel(label) |
END |
END SimpleExpression; |
2237,14 → 2168,12 |
BEGIN |
CASE op OF |
|SCAN.lxEQ: res := ARITH.opEQ |
|SCAN.lxNE: res := ARITH.opNE |
|SCAN.lxLT: res := ARITH.opLT |
|SCAN.lxLE: res := ARITH.opLE |
|SCAN.lxGT: res := ARITH.opGT |
|SCAN.lxGE: res := ARITH.opGE |
|SCAN.lxIN: res := ARITH.opIN |
|SCAN.lxIS: res := ARITH.opIS |
|SCAN.lxEQ: res := 0 |
|SCAN.lxNE: res := 1 |
|SCAN.lxLT: res := 2 |
|SCAN.lxLE: res := 3 |
|SCAN.lxGT: res := 4 |
|SCAN.lxGE: res := 5 |
END |
RETURN res |
2257,14 → 2186,12 |
BEGIN |
CASE op OF |
|SCAN.lxEQ: res := ARITH.opEQ |
|SCAN.lxNE: res := ARITH.opNE |
|SCAN.lxLT: res := ARITH.opGT |
|SCAN.lxLE: res := ARITH.opGE |
|SCAN.lxGT: res := ARITH.opLT |
|SCAN.lxGE: res := ARITH.opLE |
|SCAN.lxIN: res := ARITH.opIN |
|SCAN.lxIS: res := ARITH.opIS |
|SCAN.lxEQ: res := 0 |
|SCAN.lxNE: res := 1 |
|SCAN.lxLT: res := 4 |
|SCAN.lxLE: res := 5 |
|SCAN.lxGT: res := 2 |
|SCAN.lxGE: res := 3 |
END |
RETURN res |
2284,11 → 2211,9 |
PROCEDURE strcmp (VAR e, e1: PARS.EXPR; op: INTEGER): BOOLEAN; |
VAR |
res: BOOLEAN; |
cmp: INTEGER; |
BEGIN |
res := TRUE; |
cmp := cmpcode(op); |
IF isString(e) & isCharArray(e1) THEN |
IL.StrAdr(String(e)); |
2295,26 → 2220,36 |
IL.Const(strlen(e) + 1); |
IL.AddCmd0(IL.opEQS + invcmpcode(op)) |
ELSIF (isString(e) OR isStringW(e)) & isCharArrayW(e1) THEN |
ELSIF isString(e) & isCharArrayW(e1) THEN |
IL.StrAdr(StringW(e)); |
IL.Const(utf8strlen(e) + 1); |
IL.AddCmd0(IL.opEQSW + invcmpcode(op)) |
ELSIF isStringW(e) & isCharArrayW(e1) THEN |
IL.StrAdr(StringW(e)); |
IL.Const(utf8strlen(e) + 1); |
IL.AddCmd0(IL.opEQSW + invcmpcode(op)) |
ELSIF isCharArray(e) & isString(e1) THEN |
IL.StrAdr(String(e1)); |
IL.Const(strlen(e1) + 1); |
IL.AddCmd0(IL.opEQS + cmp) |
IL.AddCmd0(IL.opEQS + cmpcode(op)) |
ELSIF isCharArrayW(e) & (isString(e1) OR isStringW(e1)) THEN |
ELSIF isCharArrayW(e) & isString(e1) THEN |
IL.StrAdr(StringW(e1)); |
IL.Const(utf8strlen(e1) + 1); |
IL.AddCmd0(IL.opEQSW + cmp) |
IL.AddCmd0(IL.opEQSW + cmpcode(op)) |
ELSIF isCharArrayW(e) & isStringW(e1) THEN |
IL.StrAdr(StringW(e1)); |
IL.Const(utf8strlen(e1) + 1); |
IL.AddCmd0(IL.opEQSW + cmpcode(op)) |
ELSIF isCharArrayW(e) & isCharArrayW(e1) THEN |
IL.AddCmd0(IL.opEQSW + cmp) |
IL.AddCmd0(IL.opEQSW + cmpcode(op)) |
ELSIF isCharArray(e) & isCharArray(e1) THEN |
IL.AddCmd0(IL.opEQS + cmp) |
IL.AddCmd0(IL.opEQS + cmpcode(op)) |
ELSIF isString(e) & isString(e1) THEN |
PARS.strcmp(e.value, e1.value, op) |
2332,8 → 2267,8 |
getpos(parser, pos0); |
SimpleExpression(parser, e); |
IF relation(parser.sym) THEN |
IF (isCharArray(e) OR isCharArrayW(e)) & (e._type.length # 0) THEN |
IL.Const(e._type.length) |
IF (isCharArray(e) OR isCharArrayW(e)) & (e.type.length # 0) THEN |
IL.Const(e.type.length) |
END; |
op := parser.sym; |
getpos(parser, pos); |
2342,50 → 2277,61 |
getpos(parser, pos1); |
SimpleExpression(parser, e1); |
IF (isCharArray(e1) OR isCharArrayW(e1)) & (e1._type.length # 0) THEN |
IL.Const(e1._type.length) |
IF (isCharArray(e1) OR isCharArrayW(e1)) & (e1.type.length # 0) THEN |
IL.Const(e1.type.length) |
END; |
constant := (e.obj = eCONST) & (e1.obj = eCONST); |
CASE op OF |
|SCAN.lxEQ: operator := "=" |
|SCAN.lxNE: operator := "#" |
|SCAN.lxLT: operator := "<" |
|SCAN.lxLE: operator := "<=" |
|SCAN.lxGT: operator := ">" |
|SCAN.lxGE: operator := ">=" |
|SCAN.lxIN: operator := "IN" |
|SCAN.lxIS: operator := "" |
END; |
error := 0; |
cmp := cmpcode(op); |
CASE op OF |
|SCAN.lxEQ, SCAN.lxNE: |
eq := op = SCAN.lxEQ; |
IF isInt(e) & isInt(e1) OR isSet(e) & isSet(e1) OR isChar(e) & isChar(e1) OR isCharW(e) & isCharW(e1) OR |
isCharW(e) & isChar(e1) & (e1.obj = eCONST) OR isCharW(e1) & isChar(e) & (e.obj = eCONST) OR |
isCharW(e1) & (e1.obj = eCONST) & isChar(e) & (e.obj = eCONST) OR |
isCharW(e) & (e.obj = eCONST) & isChar(e1) & (e1.obj = eCONST) OR |
isPtr(e) & isPtr(e1) & (PROG.isBaseOf(e._type, e1._type) OR PROG.isBaseOf(e1._type, e._type)) THEN |
isPtr(e) & isPtr(e1) & (PROG.isBaseOf(e.type, e1.type) OR PROG.isBaseOf(e1.type, e.type)) THEN |
IF constant THEN |
ARITH.relation(e.value, e1.value, cmp, error) |
ARITH.relation(e.value, e1.value, operator, error) |
ELSE |
IF e.obj = eCONST THEN |
IL.AddCmd(IL.opEQC + cmp, ARITH.Int(e.value)) |
IL.AddCmd(IL.opEQC + cmpcode(op), ARITH.Int(e.value)) |
ELSIF e1.obj = eCONST THEN |
IL.AddCmd(IL.opEQC + cmp, ARITH.Int(e1.value)) |
IL.AddCmd(IL.opEQC + cmpcode(op), ARITH.Int(e1.value)) |
ELSE |
IL.AddCmd0(IL.opEQ + cmp) |
IL.AddCmd0(IL.opEQ + cmpcode(op)) |
END |
END |
ELSIF isStringW1(e) & isCharW(e1) THEN |
IL.AddCmd(IL.opEQC + cmp, StrToWChar(e.value.string(SCAN.IDENT).s)) |
IL.AddCmd(IL.opEQC + cmpcode(op), StrToWChar(e.value.string(SCAN.IDENT).s)) |
ELSIF isStringW1(e1) & isCharW(e) THEN |
IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.IDENT).s)) |
IL.AddCmd(IL.opEQC + cmpcode(op), StrToWChar(e1.value.string(SCAN.IDENT).s)) |
ELSIF isBoolean(e) & isBoolean(e1) THEN |
IF constant THEN |
ARITH.relation(e.value, e1.value, cmp, error) |
ARITH.relation(e.value, e1.value, operator, error) |
ELSE |
IF e.obj = eCONST THEN |
BoolCmp(eq, ARITH.Int(e.value) # 0) |
BoolCmp(op = SCAN.lxEQ, ARITH.Int(e.value) # 0) |
ELSIF e1.obj = eCONST THEN |
BoolCmp(eq, ARITH.Int(e1.value) # 0) |
BoolCmp(op = SCAN.lxEQ, ARITH.Int(e1.value) # 0) |
ELSE |
IF eq THEN |
IF op = SCAN.lxEQ THEN |
IL.AddCmd0(IL.opEQB) |
ELSE |
IL.AddCmd0(IL.opNEB) |
2395,14 → 2341,14 |
ELSIF isReal(e) & isReal(e1) THEN |
IF constant THEN |
ARITH.relation(e.value, e1.value, cmp, error) |
ARITH.relation(e.value, e1.value, operator, error) |
ELSE |
IF e.obj = eCONST THEN |
Float(parser, e) |
IL.Float(ARITH.Float(e.value)) |
ELSIF e1.obj = eCONST THEN |
Float(parser, e1) |
IL.Float(ARITH.Float(e1.value)) |
END; |
IL.AddCmd0(IL.opEQF + cmp) |
IL.fcmp(IL.opEQF + cmpcode(op)) |
END |
ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN |
2411,7 → 2357,7 |
END |
ELSIF isPtr(e) & isNil(e1) OR isNil(e) & isPtr(e1) THEN |
IL.AddCmd0(IL.opEQC + cmp) |
IL.AddCmd0(IL.opEQC + cmpcode(op)) |
ELSIF isProc(e) & isNil(e1) THEN |
IF e.obj IN {ePROC, eIMP} THEN |
2418,9 → 2364,9 |
PARS.check(e.ident.global, pos0, 85); |
constant := TRUE; |
e.obj := eCONST; |
ARITH.setbool(e.value, ~eq) |
ARITH.setbool(e.value, op = SCAN.lxNE) |
ELSE |
IL.AddCmd0(IL.opEQC + cmp) |
IL.AddCmd0(IL.opEQC + cmpcode(op)) |
END |
ELSIF isNil(e) & isProc(e1) THEN |
2428,12 → 2374,12 |
PARS.check(e1.ident.global, pos1, 85); |
constant := TRUE; |
e.obj := eCONST; |
ARITH.setbool(e.value, ~eq) |
ARITH.setbool(e.value, op = SCAN.lxNE) |
ELSE |
IL.AddCmd0(IL.opEQC + cmp) |
IL.AddCmd0(IL.opEQC + cmpcode(op)) |
END |
ELSIF isProc(e) & isProc(e1) & PROG.isTypeEq(e._type, e1._type) THEN |
ELSIF isProc(e) & isProc(e1) & PROG.isTypeEq(e.type, e1.type) THEN |
IF e.obj = ePROC THEN |
PARS.check(e.ident.global, pos0, 85) |
END; |
2443,27 → 2389,27 |
IF (e.obj IN {ePROC, eIMP}) & (e1.obj IN {ePROC, eIMP}) THEN |
constant := TRUE; |
e.obj := eCONST; |
IF eq THEN |
IF op = SCAN.lxEQ THEN |
ARITH.setbool(e.value, e.ident = e1.ident) |
ELSE |
ARITH.setbool(e.value, e.ident # e1.ident) |
END |
ELSIF e.obj = ePROC THEN |
IL.ProcCmp(e.ident.proc.label, eq) |
IL.ProcCmp(e.ident.proc.label, op = SCAN.lxEQ) |
ELSIF e1.obj = ePROC THEN |
IL.ProcCmp(e1.ident.proc.label, eq) |
IL.ProcCmp(e1.ident.proc.label, op = SCAN.lxEQ) |
ELSIF e.obj = eIMP THEN |
IL.ProcImpCmp(e.ident._import, eq) |
IL.ProcImpCmp(e.ident.import, op = SCAN.lxEQ) |
ELSIF e1.obj = eIMP THEN |
IL.ProcImpCmp(e1.ident._import, eq) |
IL.ProcImpCmp(e1.ident.import, op = SCAN.lxEQ) |
ELSE |
IL.AddCmd0(IL.opEQ + cmp) |
IL.AddCmd0(IL.opEQ + cmpcode(op)) |
END |
ELSIF isNil(e) & isNil(e1) THEN |
constant := TRUE; |
e.obj := eCONST; |
ARITH.setbool(e.value, eq) |
ARITH.setbool(e.value, op = SCAN.lxEQ) |
ELSE |
PARS.error(pos, 37) |
2476,14 → 2422,14 |
isCharW(e) & (e.obj = eCONST) & isChar(e1) & (e1.obj = eCONST) THEN |
IF constant THEN |
ARITH.relation(e.value, e1.value, cmp, error) |
ARITH.relation(e.value, e1.value, operator, error) |
ELSE |
IF e.obj = eCONST THEN |
IL.AddCmd(IL.opEQC + invcmpcode(op), ARITH.Int(e.value)) |
ELSIF e1.obj = eCONST THEN |
IL.AddCmd(IL.opEQC + cmp, ARITH.Int(e1.value)) |
IL.AddCmd(IL.opEQC + cmpcode(op), ARITH.Int(e1.value)) |
ELSE |
IL.AddCmd0(IL.opEQ + cmp) |
IL.AddCmd0(IL.opEQ + cmpcode(op)) |
END |
END |
2491,20 → 2437,20 |
IL.AddCmd(IL.opEQC + invcmpcode(op), StrToWChar(e.value.string(SCAN.IDENT).s)) |
ELSIF isStringW1(e1) & isCharW(e) THEN |
IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.IDENT).s)) |
IL.AddCmd(IL.opEQC + cmpcode(op), StrToWChar(e1.value.string(SCAN.IDENT).s)) |
ELSIF isReal(e) & isReal(e1) THEN |
IF constant THEN |
ARITH.relation(e.value, e1.value, cmp, error) |
ARITH.relation(e.value, e1.value, operator, error) |
ELSE |
IF e.obj = eCONST THEN |
Float(parser, e); |
IL.AddCmd0(IL.opEQF + invcmpcode(op)) |
IL.Float(ARITH.Float(e.value)); |
IL.fcmp(IL.opEQF + invcmpcode(op)) |
ELSIF e1.obj = eCONST THEN |
Float(parser, e1); |
IL.AddCmd0(IL.opEQF + cmp) |
IL.Float(ARITH.Float(e1.value)); |
IL.fcmp(IL.opEQF + cmpcode(op)) |
ELSE |
IL.AddCmd0(IL.opEQF + cmp) |
IL.fcmp(IL.opEQF + cmpcode(op)) |
END |
END |
2523,7 → 2469,7 |
PARS.check(ARITH.range(e.value, 0, UTILS.target.maxSet), pos0, 56) |
END; |
IF constant THEN |
ARITH.relation(e.value, e1.value, ARITH.opIN, error) |
ARITH.relation(e.value, e1.value, operator, error) |
ELSE |
IF e.obj = eCONST THEN |
IL.AddCmd(IL.opINL, ARITH.Int(e.value)) |
2540,25 → 2486,25 |
IF isRec(e) THEN |
PARS.check(e.obj = eVREC, pos0, 78); |
PARS.check(e1._type.typ = PROG.tRECORD, pos1, 80); |
PARS.check(e1.type.typ = PROG.tRECORD, pos1, 80); |
IF e.ident = NIL THEN |
IL.TypeCheck(e1._type.num) |
IL.TypeCheck(e1.type.num) |
ELSE |
IL.AddCmd(IL.opVADR, e.ident.offset - 1); |
IL.TypeCheckRec(e1._type.num) |
IL.TypeCheckRec(e1.type.num) |
END |
ELSE |
PARS.check(e1._type.typ = PROG.tPOINTER, pos1, 81); |
IL.TypeCheck(e1._type.base.num) |
PARS.check(e1.type.typ = PROG.tPOINTER, pos1, 81); |
IL.TypeCheck(e1.type.base.num) |
END; |
PARS.check(PROG.isBaseOf(e._type, e1._type), pos1, 82) |
PARS.check(PROG.isBaseOf(e.type, e1.type), pos1, 82) |
END; |
ASSERT(error = 0); |
e._type := tBOOLEAN; |
e.type := tBOOLEAN; |
IF ~constant THEN |
e.obj := eEXPR |
2574,6 → 2520,7 |
pos: PARS.POSITION; |
line: INTEGER; |
call: BOOLEAN; |
fregs: INTEGER; |
BEGIN |
getpos(parser, pos); |
2594,7 → 2541,7 |
IL.setlast(endcall.prev(IL.COMMAND)); |
PARS.check(assign(parser, e1, e._type, line), pos, 91); |
PARS.check(assign(e1, e.type, line), pos, 91); |
IF e1.obj = ePROC THEN |
PARS.check(e1.ident.global, pos, 85) |
END; |
2604,7 → 2551,7 |
ELSIF parser.sym = SCAN.lxLROUND THEN |
e1 := e; |
ActualParameters(parser, e1); |
PARS.check((e1._type = NIL) OR ODD(e._type.call), pos, 92); |
PARS.check((e1.type = NIL) OR ODD(e.type.call), pos, 92); |
call := TRUE |
ELSE |
IF e.obj IN {eSYSPROC, eSTPROC} THEN |
2612,8 → 2559,8 |
call := FALSE |
ELSE |
PARS.check(isProc(e), pos, 86); |
PARS.check((e._type.base = NIL) OR ODD(e._type.call), pos, 92); |
PARS.check1(e._type.params.first = NIL, parser, 64); |
PARS.check((e.type.base = NIL) OR ODD(e.type.call), pos, 92); |
PARS.check1(e.type.params.first = NIL, parser, 64); |
call := TRUE |
END |
END; |
2620,9 → 2567,9 |
IF call THEN |
IF e.obj IN {ePROC, eIMP} THEN |
ProcCall(e, e.ident._type, FALSE, parser, pos, TRUE) |
ProcCall(e, e.ident.type, FALSE, fregs, parser, pos, TRUE) |
ELSIF isExpr(e) THEN |
ProcCall(e, e._type, FALSE, parser, pos, TRUE) |
ProcCall(e, e.type, FALSE, fregs, parser, pos, TRUE) |
END |
END; |
2630,7 → 2577,7 |
END ElementaryStatement; |
PROCEDURE IfStatement (parser: PARS.PARSER; _if: BOOLEAN); |
PROCEDURE IfStatement (parser: PARS.PARSER; if: BOOLEAN); |
VAR |
e: PARS.EXPR; |
pos: PARS.POSITION; |
2640,7 → 2587,7 |
BEGIN |
L := IL.NewLabel(); |
IF ~_if THEN |
IF ~if THEN |
IL.AddCmd0(IL.opLOOP); |
IL.SetLabel(L) |
END; |
2658,10 → 2605,10 |
IL.AddJmpCmd(IL.opJMP, label) |
END |
ELSE |
IL.AndOrOpt(label) |
IL.AddJmpCmd(IL.opJNE, label) |
END; |
IF _if THEN |
IF if THEN |
PARS.checklex(parser, SCAN.lxTHEN) |
ELSE |
PARS.checklex(parser, SCAN.lxDO) |
2670,25 → 2617,25 |
PARS.Next(parser); |
parser.StatSeq(parser); |
IF ~_if OR (parser.sym # SCAN.lxEND) THEN |
IL.AddJmpCmd(IL.opJMP, L) |
END; |
IL.AddJmpCmd(IL.opJMP, L); |
IL.SetLabel(label) |
UNTIL parser.sym # SCAN.lxELSIF; |
IF _if THEN |
IF if THEN |
IF parser.sym = SCAN.lxELSE THEN |
PARS.Next(parser); |
parser.StatSeq(parser) |
END; |
IL.SetLabel(L) |
ELSE |
IL.AddCmd0(IL.opENDLOOP) |
END; |
PARS.checklex(parser, SCAN.lxEND); |
IF ~if THEN |
IL.AddCmd0(IL.opENDLOOP) |
END; |
PARS.Next(parser) |
END IfStatement; |
2698,7 → 2645,6 |
e: PARS.EXPR; |
pos: PARS.POSITION; |
label: INTEGER; |
L: IL.COMMAND; |
BEGIN |
IL.AddCmd0(IL.opLOOP); |
2705,7 → 2651,6 |
label := IL.NewLabel(); |
IL.SetLabel(label); |
L := IL.getlast(); |
PARS.Next(parser); |
parser.StatSeq(parser); |
2719,8 → 2664,7 |
IL.AddJmpCmd(IL.opJMP, label) |
END |
ELSE |
IL.AndOrOpt(label); |
L.param1 := label |
IL.AddJmpCmd(IL.opJNE, label) |
END; |
IL.AddCmd0(IL.opENDLOOP) |
2780,7 → 2724,7 |
pos: PARS.POSITION; |
PROCEDURE Label (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR _type: PROG._TYPE): INTEGER; |
PROCEDURE Label (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR type: PROG.TYPE_): INTEGER; |
VAR |
a: INTEGER; |
label: PARS.EXPR; |
2789,7 → 2733,7 |
BEGIN |
getpos(parser, pos); |
_type := NIL; |
type := NIL; |
IF isChar(caseExpr) THEN |
PARS.ConstExpression(parser, value); |
2810,13 → 2754,13 |
ELSIF isRecPtr(caseExpr) THEN |
qualident(parser, label); |
PARS.check(label.obj = eTYPE, pos, 79); |
PARS.check(PROG.isBaseOf(caseExpr._type, label._type), pos, 99); |
PARS.check(PROG.isBaseOf(caseExpr.type, label.type), pos, 99); |
IF isRec(caseExpr) THEN |
a := label._type.num |
a := label.type.num |
ELSE |
a := label._type.base.num |
a := label.type.base.num |
END; |
_type := label._type |
type := label.type |
END |
RETURN a |
2823,12 → 2767,12 |
END Label; |
PROCEDURE CheckType (node: AVL.NODE; _type: PROG._TYPE; parser: PARS.PARSER; pos: PARS.POSITION); |
PROCEDURE CheckType (node: AVL.NODE; type: PROG.TYPE_; parser: PARS.PARSER; pos: PARS.POSITION); |
BEGIN |
IF node # NIL THEN |
PARS.check(~(PROG.isBaseOf(node.data(CASE_LABEL)._type, _type) OR PROG.isBaseOf(_type, node.data(CASE_LABEL)._type)), pos, 100); |
CheckType(node.left, _type, parser, pos); |
CheckType(node.right, _type, parser, pos) |
PARS.check(~(PROG.isBaseOf(node.data(CASE_LABEL).type, type) OR PROG.isBaseOf(type, node.data(CASE_LABEL).type)), pos, 100); |
CheckType(node.left, type, parser, pos); |
CheckType(node.right, type, parser, pos) |
END |
END CheckType; |
2854,12 → 2798,12 |
label.self := IL.NewLabel(); |
getpos(parser, pos1); |
range.a := Label(parser, caseExpr, label._type); |
range.a := Label(parser, caseExpr, label.type); |
IF parser.sym = SCAN.lxRANGE THEN |
PARS.check1(~isRecPtr(caseExpr), parser, 53); |
NextPos(parser, pos); |
range.b := Label(parser, caseExpr, label._type); |
range.b := Label(parser, caseExpr, label.type); |
PARS.check(range.a <= range.b, pos, 103) |
ELSE |
range.b := range.a |
2868,7 → 2812,7 |
label.range := range; |
IF isRecPtr(caseExpr) THEN |
CheckType(tree, label._type, parser, pos1) |
CheckType(tree, label.type, parser, pos1) |
END; |
tree := AVL.insert(tree, label, LabelCmp, newnode, node); |
PARS.check(newnode, pos1, 100) |
2899,10 → 2843,10 |
END CaseLabelList; |
PROCEDURE _case (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR tree: AVL.NODE; _end: INTEGER); |
PROCEDURE case (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR tree: AVL.NODE; end: INTEGER); |
VAR |
sym: INTEGER; |
t: PROG._TYPE; |
t: PROG.TYPE_; |
variant: INTEGER; |
node: AVL.NODE; |
last: IL.COMMAND; |
2915,8 → 2859,8 |
PARS.checklex(parser, SCAN.lxCOLON); |
PARS.Next(parser); |
IF isRecPtr(caseExpr) THEN |
t := caseExpr._type; |
caseExpr.ident._type := node.data(CASE_LABEL)._type |
t := caseExpr.type; |
caseExpr.ident.type := node.data(CASE_LABEL).type |
END; |
last := IL.getlast(); |
2927,16 → 2871,16 |
END; |
parser.StatSeq(parser); |
IL.AddJmpCmd(IL.opJMP, _end); |
IL.AddJmpCmd(IL.opJMP, end); |
IF isRecPtr(caseExpr) THEN |
caseExpr.ident._type := t |
caseExpr.ident.type := t |
END |
END |
END _case; |
END case; |
PROCEDURE Table (node: AVL.NODE; _else: INTEGER); |
PROCEDURE Table (node: AVL.NODE; else: INTEGER); |
VAR |
L, R: INTEGER; |
range: RANGE; |
2953,7 → 2897,7 |
IF left # NIL THEN |
L := left.data(CASE_LABEL).self |
ELSE |
L := _else |
L := else |
END; |
right := node.right; |
2960,7 → 2904,7 |
IF right # NIL THEN |
R := right.data(CASE_LABEL).self |
ELSE |
R := _else |
R := else |
END; |
last := IL.getlast(); |
2974,7 → 2918,7 |
IL.setlast(v.cmd); |
IL.SetLabel(node.data(CASE_LABEL).self); |
IL._case(range.a, range.b, L, R); |
IL.case(range.a, range.b, L, R); |
IF v.processed THEN |
IL.AddJmpCmd(IL.opJMP, node.data(CASE_LABEL).variant) |
END; |
2982,8 → 2926,8 |
IL.setlast(last); |
Table(left, _else); |
Table(right, _else) |
Table(left, else); |
Table(right, else) |
END |
END Table; |
2991,7 → 2935,8 |
PROCEDURE TableT (node: AVL.NODE); |
BEGIN |
IF node # NIL THEN |
IL.AddCmd2(IL.opCASET, node.data(CASE_LABEL).variant, node.data(CASE_LABEL).range.a); |
IL.caset(node.data(CASE_LABEL).range.a, node.data(CASE_LABEL).variant); |
TableT(node.left); |
TableT(node.right) |
END |
3000,14 → 2945,14 |
PROCEDURE ParseCase (parser: PARS.PARSER; e: PARS.EXPR; pos: PARS.POSITION); |
VAR |
table, _end, _else: INTEGER; |
table, end, else: INTEGER; |
tree: AVL.NODE; |
item: LISTS.ITEM; |
BEGIN |
LISTS.push(CaseVariants, NewVariant(0, NIL)); |
_end := IL.NewLabel(); |
_else := IL.NewLabel(); |
end := IL.NewLabel(); |
else := IL.NewLabel(); |
table := IL.NewLabel(); |
IL.AddCmd(IL.opSWITCH, ORD(isRecPtr(e))); |
IL.AddJmpCmd(IL.opJMP, table); |
3014,17 → 2959,17 |
tree := NIL; |
_case(parser, e, tree, _end); |
case(parser, e, tree, end); |
WHILE parser.sym = SCAN.lxBAR DO |
PARS.Next(parser); |
_case(parser, e, tree, _end) |
case(parser, e, tree, end) |
END; |
IL.SetLabel(_else); |
IL.SetLabel(else); |
IF parser.sym = SCAN.lxELSE THEN |
PARS.Next(parser); |
parser.StatSeq(parser); |
IL.AddJmpCmd(IL.opJMP, _end) |
IL.AddJmpCmd(IL.opJMP, end) |
ELSE |
IL.OnError(pos.line, errCASE) |
END; |
3035,14 → 2980,14 |
IF isRecPtr(e) THEN |
IL.SetLabel(table); |
TableT(tree); |
IL.AddJmpCmd(IL.opJMP, _else) |
IL.AddJmpCmd(IL.opJMP, else) |
ELSE |
tree.data(CASE_LABEL).self := table; |
Table(tree, _else) |
Table(tree, else) |
END; |
AVL.destroy(tree, DestroyLabel); |
IL.SetLabel(_end); |
IL.SetLabel(end); |
IL.AddCmd0(IL.opENDSW); |
REPEAT |
3103,13 → 3048,13 |
ident := PROG.getIdent(parser.unit, parser.lex.ident, TRUE); |
PARS.check1(ident # NIL, parser, 48); |
PARS.check1(ident.typ = PROG.idVAR, parser, 93); |
PARS.check1(ident._type = tINTEGER, parser, 97); |
PARS.check1(ident.type = tINTEGER, parser, 97); |
PARS.ExpectSym(parser, SCAN.lxASSIGN); |
NextPos(parser, pos); |
expression(parser, e); |
PARS.check(isInt(e), pos, 76); |
offset := PROG.getOffset(ident); |
offset := PROG.getOffset(PARS.program, ident); |
IF ident.global THEN |
IL.AddCmd(IL.opGADR, offset) |
3130,7 → 3075,7 |
ELSE |
IL.AddCmd(IL.opLADR, -offset) |
END; |
IL.load(ident._type.size); |
IL.load(ident.type.size); |
PARS.checklex(parser, SCAN.lxTO); |
NextPos(parser, pos2); |
3167,7 → 3112,7 |
END |
END; |
IL.AddJmpCmd(IL.opJZ, L2); |
IL.AddJmpCmd(IL.opJNE, L2); |
PARS.checklex(parser, SCAN.lxDO); |
PARS.Next(parser); |
3226,7 → 3171,7 |
END StatSeq; |
PROCEDURE chkreturn (parser: PARS.PARSER; e: PARS.EXPR; t: PROG._TYPE; pos: PARS.POSITION): BOOLEAN; |
PROCEDURE chkreturn (parser: PARS.PARSER; e: PARS.EXPR; t: PROG.TYPE_; pos: PARS.POSITION): BOOLEAN; |
VAR |
res: BOOLEAN; |
3234,20 → 3179,24 |
res := assigncomp(e, t); |
IF res THEN |
IF e.obj = eCONST THEN |
IF e._type = tREAL THEN |
Float(parser, e) |
ELSIF e._type.typ = PROG.tNIL THEN |
IF e.type = tREAL THEN |
IL.Float(ARITH.Float(e.value)) |
ELSIF e.type.typ = PROG.tNIL THEN |
IL.Const(0) |
ELSE |
LoadConst(e) |
END |
ELSIF (e._type = tINTEGER) & (t = tBYTE) & (chkBYTE IN Options.checking) THEN |
ELSIF (e.type = tINTEGER) & (t = tBYTE) & (chkBYTE IN Options.checking) THEN |
CheckRange(256, pos.line, errBYTE) |
ELSIF e.obj = ePROC THEN |
PARS.check(e.ident.global, pos, 85); |
IL.PushProc(e.ident.proc.label) |
ELSIF e.obj = eIMP THEN |
IL.PushImpProc(e.ident._import) |
IL.PushImpProc(e.ident.import) |
END; |
IF e.type = tREAL THEN |
IL.retf |
END |
END |
3267,8 → 3216,8 |
BEGIN |
id := PROG.getIdent(rtl, SCAN.enterid(name), FALSE); |
IF (id # NIL) & (id._import # NIL) THEN |
IL.set_rtl(idx, -id._import(IL.IMPORT_PROC).label); |
IF (id # NIL) & (id.import # NIL) THEN |
IL.set_rtl(idx, -id.import(IL.IMPORT_PROC).label); |
id.proc.used := TRUE |
ELSIF (id # NIL) & (id.proc # NIL) THEN |
IL.set_rtl(idx, id.proc.label); |
3280,7 → 3229,7 |
BEGIN |
rtl := PROG.program.rtl; |
rtl := PARS.program.rtl; |
ASSERT(rtl # NIL); |
getproc(rtl, "_strcmp", IL._strcmp); |
3307,7 → 3256,7 |
getproc(rtl, "_isrec", IL._isrec); |
getproc(rtl, "_dllentry", IL._dllentry); |
getproc(rtl, "_sofinit", IL._sofinit) |
ELSIF CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuRVM32I} THEN |
ELSIF CPU = TARGETS.cpuTHUMB THEN |
getproc(rtl, "_fmul", IL._fmul); |
getproc(rtl, "_fdiv", IL._fdiv); |
getproc(rtl, "_fdivi", IL._fdivi); |
3318,11 → 3267,8 |
getproc(rtl, "_floor", IL._floor); |
getproc(rtl, "_flt", IL._flt); |
getproc(rtl, "_pack", IL._pack); |
getproc(rtl, "_unpk", IL._unpk); |
IF CPU = TARGETS.cpuRVM32I THEN |
getproc(rtl, "_error", IL._error) |
getproc(rtl, "_unpk", IL._unpk) |
END |
END |
END setrtl; |
3333,13 → 3279,13 |
ext: PARS.PATH; |
BEGIN |
tINTEGER := PROG.program.stTypes.tINTEGER; |
tBYTE := PROG.program.stTypes.tBYTE; |
tCHAR := PROG.program.stTypes.tCHAR; |
tSET := PROG.program.stTypes.tSET; |
tBOOLEAN := PROG.program.stTypes.tBOOLEAN; |
tWCHAR := PROG.program.stTypes.tWCHAR; |
tREAL := PROG.program.stTypes.tREAL; |
tINTEGER := PARS.program.stTypes.tINTEGER; |
tBYTE := PARS.program.stTypes.tBYTE; |
tCHAR := PARS.program.stTypes.tCHAR; |
tSET := PARS.program.stTypes.tSET; |
tBOOLEAN := PARS.program.stTypes.tBOOLEAN; |
tWCHAR := PARS.program.stTypes.tWCHAR; |
tREAL := PARS.program.stTypes.tREAL; |
Options := options; |
CPU := TARGETS.CPU; |
3353,7 → 3299,7 |
IL.init(CPU); |
IF TARGETS.RTL THEN |
IF CPU # TARGETS.cpuMSP430 THEN |
parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn); |
IF parser.open(parser, UTILS.RTL_NAME) THEN |
parser.parse(parser); |
3381,17 → 3327,17 |
PARS.destroy(parser); |
IF PROG.program.bss > UTILS.MAX_GLOBAL_SIZE THEN |
IF PARS.program.bss > UTILS.MAX_GLOBAL_SIZE THEN |
ERRORS.Error(204) |
END; |
IF TARGETS.RTL THEN |
IF CPU # TARGETS.cpuMSP430 THEN |
setrtl |
END; |
PROG.DelUnused(IL.DelImport); |
PROG.DelUnused(PARS.program, IL.DelImport); |
IL.set_bss(PROG.program.bss); |
IL.set_bss(PARS.program.bss); |
CASE CPU OF |
|TARGETS.cpuAMD64: AMD64.CodeGen(outname, target, options) |
3398,7 → 3344,6 |
|TARGETS.cpuX86: X86.CodeGen(outname, target, options) |
|TARGETS.cpuMSP430: MSP430.CodeGen(outname, target, options) |
|TARGETS.cpuTHUMB: THUMB.CodeGen(outname, target, options) |
|TARGETS.cpuRVM32I: RVM32I.CodeGen(outname, target, options) |
END |
END compile; |
/programs/develop/oberon07/Source/STRINGS.ob07 |
---|
10,20 → 10,9 |
IMPORT UTILS; |
PROCEDURE copy* (src: ARRAY OF CHAR; VAR dst: ARRAY OF CHAR; spos, dpos, count: INTEGER); |
BEGIN |
WHILE count > 0 DO |
dst[dpos] := src[spos]; |
INC(spos); |
INC(dpos); |
DEC(count) |
END |
END copy; |
PROCEDURE append* (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); |
VAR |
n1, n2: INTEGER; |
n1, n2, i, j: INTEGER; |
BEGIN |
n1 := LENGTH(s1); |
31,14 → 20,43 |
ASSERT(n1 + n2 < LEN(s1)); |
copy(s2, s1, 0, n1, n2); |
s1[n1 + n2] := 0X |
i := 0; |
j := n1; |
WHILE i < n2 DO |
s1[j] := s2[i]; |
INC(i); |
INC(j) |
END; |
s1[j] := 0X |
END append; |
PROCEDURE reverse (VAR s: ARRAY OF CHAR); |
VAR |
i, j: INTEGER; |
a, b: CHAR; |
BEGIN |
i := 0; |
j := LENGTH(s) - 1; |
WHILE i < j DO |
a := s[i]; |
b := s[j]; |
s[i] := b; |
s[j] := a; |
INC(i); |
DEC(j) |
END |
END reverse; |
PROCEDURE IntToStr* (x: INTEGER; VAR str: ARRAY OF CHAR); |
VAR |
i, a: INTEGER; |
minus: BOOLEAN; |
BEGIN |
IF x = UTILS.minint THEN |
49,35 → 67,48 |
END |
ELSE |
minus := x < 0; |
IF minus THEN |
x := -x |
END; |
i := 0; |
IF x < 0 THEN |
x := -x; |
i := 1; |
str[0] := "-" |
a := 0; |
REPEAT |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10; |
INC(i) |
UNTIL x = 0; |
IF minus THEN |
str[i] := "-"; |
INC(i) |
END; |
a := x; |
REPEAT |
INC(i); |
a := a DIV 10 |
UNTIL a = 0; |
str[i] := 0X; |
reverse(str) |
REPEAT |
DEC(i); |
str[i] := CHR(x MOD 10 + ORD("0")); |
x := x DIV 10 |
UNTIL x = 0 |
END |
END IntToStr; |
PROCEDURE hexdgt (n: BYTE): BYTE; |
BEGIN |
IF n < 10 THEN |
n := n + ORD("0") |
ELSE |
n := n - 10 + ORD("A") |
END |
RETURN n |
END hexdgt; |
PROCEDURE IntToHex* (x: INTEGER; VAR str: ARRAY OF CHAR; n: INTEGER); |
BEGIN |
str[n] := 0X; |
WHILE n > 0 DO |
str[n - 1] := CHR(UTILS.hexdgt(x MOD 16)); |
str[n - 1] := CHR(hexdgt(x MOD 16)); |
x := x DIV 16; |
DEC(n) |
END |
84,6 → 115,17 |
END IntToHex; |
PROCEDURE copy* (src: ARRAY OF CHAR; VAR dst: ARRAY OF CHAR; spos, dpos, count: INTEGER); |
BEGIN |
WHILE count > 0 DO |
dst[dpos] := src[spos]; |
INC(spos); |
INC(dpos); |
DEC(count) |
END |
END copy; |
PROCEDURE search* (s: ARRAY OF CHAR; VAR pos: INTEGER; c: CHAR; forward: BOOLEAN); |
VAR |
length: INTEGER; |
143,10 → 185,10 |
i: INTEGER; |
BEGIN |
i := LENGTH(str) - 1; |
WHILE i >= 0 DO |
i := 0; |
WHILE (i < LEN(str)) & (str[i] # 0X) DO |
cap(str[i]); |
DEC(i) |
INC(i) |
END |
END UpCase; |
/programs/develop/oberon07/Source/TARGETS.ob07 |
---|
24,19 → 24,13 |
Linux64* = 11; |
Linux64SO* = 12; |
STM32CM3* = 13; |
RVM32I* = 14; |
cpuX86* = 0; cpuAMD64* = 1; cpuMSP430* = 2; cpuTHUMB* = 3; |
cpuRVM32I* = 4; |
osNONE* = 0; osWIN32* = 1; osWIN64* = 2; |
osLINUX32* = 3; osLINUX64* = 4; osKOS* = 5; |
noDISPOSE = {MSP430, STM32CM3, RVM32I}; |
noRTL = {MSP430}; |
TYPE |
STRING = ARRAY 32 OF CHAR; |
43,7 → 37,7 |
TARGET = RECORD |
target, CPU, OS, RealSize: INTEGER; |
target, CPU, BitDepth, OS, RealSize: INTEGER; |
ComLinePar*, LibDir, FileExt: STRING |
END; |
51,23 → 45,18 |
VAR |
Targets*: ARRAY 15 OF TARGET; |
Targets*: ARRAY 14 OF TARGET; |
CPUs: ARRAY 5 OF |
RECORD |
BitDepth, InstrSize: INTEGER; |
LittleEndian: BOOLEAN |
END; |
target*, CPU*, BitDepth*, OS*, RealSize*, WordSize*, AdrSize*, InstrSize*: INTEGER; |
target*, CPU*, BitDepth*, OS*, RealSize*, WordSize*, AdrSize*: INTEGER; |
ComLinePar*, LibDir*, FileExt*: STRING; |
Import*, Dispose*, RTL*, Dll*, LittleEndian*: BOOLEAN; |
Import*, Dispose*, Dll*: BOOLEAN; |
PROCEDURE Enter (idx, CPU, RealSize, OS: INTEGER; ComLinePar, LibDir, FileExt: STRING); |
PROCEDURE Enter (idx, CPU, BitDepth, RealSize, OS: INTEGER; ComLinePar, LibDir, FileExt: STRING); |
BEGIN |
Targets[idx].target := idx; |
Targets[idx].CPU := CPU; |
Targets[idx].BitDepth := BitDepth; |
Targets[idx].RealSize := RealSize; |
Targets[idx].OS := OS; |
Targets[idx].ComLinePar := ComLinePar; |
91,9 → 80,7 |
IF res THEN |
target := Targets[i].target; |
CPU := Targets[i].CPU; |
BitDepth := CPUs[CPU].BitDepth; |
InstrSize := CPUs[CPU].InstrSize; |
LittleEndian := CPUs[CPU].LittleEndian; |
BitDepth := Targets[i].BitDepth; |
RealSize := Targets[i].RealSize; |
OS := Targets[i].OS; |
ComLinePar := Targets[i].ComLinePar; |
101,8 → 88,7 |
FileExt := Targets[i].FileExt; |
Import := OS IN {osWIN32, osWIN64, osKOS}; |
Dispose := ~(target IN noDISPOSE); |
RTL := ~(target IN noRTL); |
Dispose := ~(target IN {MSP430, STM32CM3}); |
Dll := target IN {Linux32SO, Linux64SO, Win32DLL, Win64DLL, KolibriOSDLL}; |
WordSize := BitDepth DIV 8; |
AdrSize := WordSize |
112,34 → 98,19 |
END Select; |
PROCEDURE EnterCPU (cpu, BitDepth, InstrSize: INTEGER; LittleEndian: BOOLEAN); |
BEGIN |
CPUs[cpu].BitDepth := BitDepth; |
CPUs[cpu].InstrSize := InstrSize; |
CPUs[cpu].LittleEndian := LittleEndian |
END EnterCPU; |
BEGIN |
EnterCPU(cpuX86, 32, 1, TRUE); |
EnterCPU(cpuAMD64, 64, 1, TRUE); |
EnterCPU(cpuMSP430, 16, 2, TRUE); |
EnterCPU(cpuTHUMB, 32, 2, TRUE); |
EnterCPU(cpuRVM32I, 32, 4, TRUE); |
Enter( MSP430, cpuMSP430, 0, osNONE, "msp430", "MSP430", ".hex"); |
Enter( Win32C, cpuX86, 8, osWIN32, "win32con", "Windows32", ".exe"); |
Enter( Win32GUI, cpuX86, 8, osWIN32, "win32gui", "Windows32", ".exe"); |
Enter( Win32DLL, cpuX86, 8, osWIN32, "win32dll", "Windows32", ".dll"); |
Enter( KolibriOS, cpuX86, 8, osKOS, "kosexe", "KolibriOS", ""); |
Enter( KolibriOSDLL, cpuX86, 8, osKOS, "kosdll", "KolibriOS", ".obj"); |
Enter( Win64C, cpuAMD64, 8, osWIN64, "win64con", "Windows64", ".exe"); |
Enter( Win64GUI, cpuAMD64, 8, osWIN64, "win64gui", "Windows64", ".exe"); |
Enter( Win64DLL, cpuAMD64, 8, osWIN64, "win64dll", "Windows64", ".dll"); |
Enter( Linux32, cpuX86, 8, osLINUX32, "linux32exe", "Linux32", ""); |
Enter( Linux32SO, cpuX86, 8, osLINUX32, "linux32so", "Linux32", ".so"); |
Enter( Linux64, cpuAMD64, 8, osLINUX64, "linux64exe", "Linux64", ""); |
Enter( Linux64SO, cpuAMD64, 8, osLINUX64, "linux64so", "Linux64", ".so"); |
Enter( STM32CM3, cpuTHUMB, 4, osNONE, "stm32cm3", "STM32CM3", ".hex"); |
Enter( RVM32I, cpuRVM32I, 4, osNONE, "rvm32i", "RVM32I", ".bin"); |
Enter( MSP430, cpuMSP430, 16, 0, osNONE, "msp430", "MSP430", ".hex"); |
Enter( Win32C, cpuX86, 32, 8, osWIN32, "win32con", "Windows32", ".exe"); |
Enter( Win32GUI, cpuX86, 32, 8, osWIN32, "win32gui", "Windows32", ".exe"); |
Enter( Win32DLL, cpuX86, 32, 8, osWIN32, "win32dll", "Windows32", ".dll"); |
Enter( KolibriOS, cpuX86, 32, 8, osKOS, "kosexe", "KolibriOS", ""); |
Enter( KolibriOSDLL, cpuX86, 32, 8, osKOS, "kosdll", "KolibriOS", ".obj"); |
Enter( Win64C, cpuAMD64, 64, 8, osWIN64, "win64con", "Windows64", ".exe"); |
Enter( Win64GUI, cpuAMD64, 64, 8, osWIN64, "win64gui", "Windows64", ".exe"); |
Enter( Win64DLL, cpuAMD64, 64, 8, osWIN64, "win64dll", "Windows64", ".dll"); |
Enter( Linux32, cpuX86, 32, 8, osLINUX32, "linux32exe", "Linux32", ""); |
Enter( Linux32SO, cpuX86, 32, 8, osLINUX32, "linux32so", "Linux32", ".so"); |
Enter( Linux64, cpuAMD64, 64, 8, osLINUX64, "linux64exe", "Linux64", ""); |
Enter( Linux64SO, cpuAMD64, 64, 8, osLINUX64, "linux64so", "Linux64", ".so"); |
Enter( STM32CM3, cpuTHUMB, 32, 4, osNONE, "stm32cm3", "STM32CM3", ".hex"); |
END TARGETS. |
/programs/develop/oberon07/Source/TEXTDRV.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2020, Anton Krotov |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
28,16 → 28,9 |
CR: BOOLEAN; |
line*, col*: INTEGER; |
ifc*: INTEGER; |
elsec*: INTEGER; |
eof*: BOOLEAN; |
eol*: BOOLEAN; |
skip*: BOOLEAN; |
peak*: CHAR; |
_skip*, |
_elsif*, |
_else*: ARRAY 100 OF BOOLEAN; |
fname*: ARRAY 2048 OF CHAR |
peak*: CHAR |
END; |
168,13 → 161,8 |
text.col := 1; |
text.eof := FALSE; |
text.eol := FALSE; |
text.skip := FALSE; |
text.ifc := 0; |
text.elsec := 0; |
text._skip[0] := FALSE; |
text.peak := 0X; |
text.file := FILES.open(name); |
COPY(name, text.fname); |
IF text.file # NIL THEN |
load(text); |
init(text) |
/programs/develop/oberon07/Source/THUMB.ob07 |
---|
616,14 → 616,14 |
PROCEDURE SetIV (idx, label, CodeAdr: INTEGER); |
VAR |
l, h: LISTS.ITEM; |
l, h: ANYCODE; |
BEGIN |
l := CodeList.first; |
h := l.next; |
l := CodeList.first(ANYCODE); |
h := l.next(ANYCODE); |
WHILE idx > 0 DO |
l := h.next; |
h := l.next; |
l := h.next(ANYCODE); |
h := l.next(ANYCODE); |
DEC(idx) |
END; |
label := BIN.GetLabel(program, label) * 2 + CodeAdr + 1; |
784,9 → 784,8 |
PROCEDURE xchg (r1, r2: INTEGER); |
BEGIN |
push(r1); |
mov(r1, r2); |
pop(r2) |
push(r1); push(r2); |
pop(r1); pop(r2) |
END xchg; |
1093,7 → 1092,7 |
|IL.opCALLP: |
UnOp(r1); |
AddImm8(r1, 1); (* Thumb mode *) |
AddImm8(r1, 1); |
gen5(3, TRUE, FALSE, r1, 0); (* blx r1 *) |
drop; |
ASSERT(R.top = -1) |
1177,7 → 1176,7 |
|IL.opERR: |
call(genTrap) |
|IL.opNOP, IL.opAND, IL.opOR: |
|IL.opNOP: |
|IL.opSADR: |
reloc(GetAnyReg(), BIN.RDATA + pic, stroffs + param2) |
1348,25 → 1347,37 |
SetCC(jne, r1) |
END |
|IL.opACC: |
IF (R.top # 0) OR (R.stk[0] # ACC) THEN |
PushAll(0); |
GetRegA; |
pop(ACC); |
DEC(R.pushed) |
END |
|IL.opDROP: |
UnOp(r1); |
drop |
|IL.opJNZ1: |
|IL.opJNZ: |
UnOp(r1); |
cbnz(r1, param1) |
|IL.opJZ: |
UnOp(r1); |
cbz(r1, param1) |
|IL.opJG: |
UnOp(r1); |
Tst(r1); |
jcc(jg, param1) |
|IL.opJNZ: |
|IL.opJE: |
UnOp(r1); |
cbnz(r1, param1); |
drop |
|IL.opJZ: |
|IL.opJNE: |
UnOp(r1); |
cbz(r1, param1); |
drop |
1424,10 → 1435,10 |
cc := cond(opcode); |
next := cmd.next(COMMAND); |
IF next.opcode = IL.opJNZ THEN |
IF next.opcode = IL.opJE THEN |
jcc(cc, next.param1); |
cmd := next |
ELSIF next.opcode = IL.opJZ THEN |
ELSIF next.opcode = IL.opJNE THEN |
jcc(inv0(cc), next.param1); |
cmd := next |
ELSE |
1476,7 → 1487,7 |
END; |
drop |
|IL.opADDC: |
|IL.opADDL, IL.opADDR: |
UnOp(r1); |
AddConst(r1, param2) |
1750,7 → 1761,7 |
gen4(14, r2, r1); (* bic r1, r2 *) |
drop |
|IL.opADDSC: |
|IL.opADDSL, IL.opADDSR: |
MovConst(GetAnyReg(), param2); |
BinOp(r1, r2); |
gen4(12, r2, r1); (* orr r1, r2 *) |
2003,7 → 2014,7 |
CallRTL(IL._fdivi, 2); |
GetRegA |
|IL.opADDF: |
|IL.opADDF, IL.opADDFI: |
PushAll(2); |
CallRTL(IL._fadd, 2); |
GetRegA |
2325,6 → 2336,8 |
DataAdr, BssAdr, DataSize, BssSize, CodeSize: INTEGER; |
File: WR.FILE; |
BEGIN |
IF target = TARGETS.STM32CM3 THEN |
CortexM3 |
2374,12 → 2387,12 |
ERRORS.Error(204) |
END; |
WR.Create(outname); |
File := WR.Create(outname); |
HEX.Data2(program.code, 0, CodeSize, high(Target.FlashAdr)); |
HEX.End; |
HEX.Data2(File, program.code, 0, CodeSize, high(Target.FlashAdr)); |
HEX.End(File); |
WR.Close; |
WR.Close(File); |
C.StringLn("--------------------------------------------"); |
C.String( " rom: "); C.Int(CodeSize); C.String(" of "); C.Int(rom); C.String(" ("); C.Int(CodeSize * 100 DIV rom); C.StringLn("%)"); |
/programs/develop/oberon07/Source/UTILS.ob07 |
---|
13,17 → 13,18 |
CONST |
slash* = HOST.slash; |
eol* = HOST.eol; |
bit_depth* = HOST.bit_depth; |
maxint* = HOST.maxint; |
minint* = HOST.minint; |
OS = HOST.OS; |
min32* = -2147483647-1; |
max32* = 2147483647; |
vMajor* = 1; |
vMinor* = 43; |
vMinor* = 29; |
FILE_EXT* = ".ob07"; |
RTL_NAME* = "RTL"; |
31,10 → 32,17 |
MAX_GLOBAL_SIZE* = 1600000000; |
TYPE |
DAYS = ARRAY 12, 31, 2 OF INTEGER; |
VAR |
time*: INTEGER; |
eol*: ARRAY 3 OF CHAR; |
maxreal*: REAL; |
target*: |
53,7 → 61,9 |
bit_diff*: INTEGER; |
days: DAYS; |
PROCEDURE FileRead* (F: INTEGER; VAR Buffer: ARRAY OF CHAR; bytes: INTEGER): INTEGER; |
RETURN HOST.FileRead(F, Buffer, bytes) |
END FileRead; |
80,12 → 90,6 |
END FileOpen; |
PROCEDURE chmod* (FName: ARRAY OF CHAR); |
BEGIN |
HOST.chmod(FName) |
END chmod; |
PROCEDURE GetArg* (i: INTEGER; VAR str: ARRAY OF CHAR); |
BEGIN |
HOST.GetArg(i, str) |
130,8 → 134,25 |
END GetCurrentDirectory; |
PROCEDURE GetUnixTime* (year, month, day, hour, min, sec: INTEGER): INTEGER; |
RETURN ((year - 1970) * 365 + days[month - 1, day - 1, ORD(year DIV 4 = 0)] + (year - 1969) DIV 4) * 86400 + hour * 3600 + min * 60 + sec |
END GetUnixTime; |
PROCEDURE UnixTime* (): INTEGER; |
RETURN HOST.UnixTime() |
VAR |
year, month, day, hour, min, sec: INTEGER; |
res: INTEGER; |
BEGIN |
IF OS = "LINUX" THEN |
res := HOST.UnixTime() |
ELSE |
HOST.now(year, month, day, hour, min, sec); |
res := GetUnixTime(year, month, day, hour, min, sec) |
END |
RETURN res |
END UnixTime; |
208,19 → 229,51 |
END Log2; |
PROCEDURE hexdgt* (n: BYTE): BYTE; |
PROCEDURE init (VAR days: DAYS); |
VAR |
i, j, n0, n1: INTEGER; |
BEGIN |
IF n < 10 THEN |
INC(n, ORD("0")) |
ELSE |
INC(n, ORD("A") - 10) |
FOR i := 0 TO 11 DO |
FOR j := 0 TO 30 DO |
days[i, j, 0] := 0; |
days[i, j, 1] := 0; |
END |
END; |
RETURN n |
END hexdgt; |
days[ 1, 28, 0] := -1; |
FOR i := 0 TO 1 DO |
days[ 1, 29, i] := -1; |
days[ 1, 30, i] := -1; |
days[ 3, 30, i] := -1; |
days[ 5, 30, i] := -1; |
days[ 8, 30, i] := -1; |
days[10, 30, i] := -1; |
END; |
n0 := 0; |
n1 := 0; |
FOR i := 0 TO 11 DO |
FOR j := 0 TO 30 DO |
IF days[i, j, 0] = 0 THEN |
days[i, j, 0] := n0; |
INC(n0) |
END; |
IF days[i, j, 1] = 0 THEN |
days[i, j, 1] := n1; |
INC(n1) |
END |
END |
END |
END init; |
BEGIN |
time := GetTickCount(); |
maxreal := HOST.maxreal |
COPY(HOST.eol, eol); |
maxreal := HOST.maxreal; |
init(days) |
END UTILS. |
/programs/develop/oberon07/Source/WRITER.ob07 |
---|
1,7 → 1,7 |
(* |
BSD 2-Clause License |
Copyright (c) 2018-2020, Anton Krotov |
Copyright (c) 2018-2019, Anton Krotov |
All rights reserved. |
*) |
10,16 → 10,20 |
IMPORT FILES, ERRORS, UTILS; |
TYPE |
FILE* = FILES.FILE; |
VAR |
counter*: INTEGER; |
file: FILES.FILE; |
PROCEDURE align* (n, _align: INTEGER): INTEGER; |
PROCEDURE align (n, _align: INTEGER): INTEGER; |
BEGIN |
IF n MOD _align # 0 THEN |
INC(n, _align - (n MOD _align)) |
n := n + _align - (n MOD _align) |
END |
RETURN n |
26,7 → 30,7 |
END align; |
PROCEDURE WriteByte* (n: BYTE); |
PROCEDURE WriteByte* (file: FILE; n: BYTE); |
BEGIN |
IF FILES.WriteByte(file, n) THEN |
INC(counter) |
36,7 → 40,7 |
END WriteByte; |
PROCEDURE Write* (chunk: ARRAY OF BYTE; bytes: INTEGER); |
PROCEDURE Write* (file: FILE; chunk: ARRAY OF BYTE; bytes: INTEGER); |
VAR |
n: INTEGER; |
49,36 → 53,36 |
END Write; |
PROCEDURE Write64LE* (n: INTEGER); |
PROCEDURE Write64LE* (file: FILE; n: INTEGER); |
VAR |
i: INTEGER; |
BEGIN |
FOR i := 0 TO 7 DO |
WriteByte(UTILS.Byte(n, i)) |
WriteByte(file, UTILS.Byte(n, i)) |
END |
END Write64LE; |
PROCEDURE Write32LE* (n: INTEGER); |
PROCEDURE Write32LE* (file: FILE; n: INTEGER); |
VAR |
i: INTEGER; |
BEGIN |
FOR i := 0 TO 3 DO |
WriteByte(UTILS.Byte(n, i)) |
WriteByte(file, UTILS.Byte(n, i)) |
END |
END Write32LE; |
PROCEDURE Write16LE* (n: INTEGER); |
PROCEDURE Write16LE* (file: FILE; n: INTEGER); |
BEGIN |
WriteByte(UTILS.Byte(n, 0)); |
WriteByte(UTILS.Byte(n, 1)) |
WriteByte(file, UTILS.Byte(n, 0)); |
WriteByte(file, UTILS.Byte(n, 1)) |
END Write16LE; |
PROCEDURE Padding* (FileAlignment: INTEGER); |
PROCEDURE Padding* (file: FILE; FileAlignment: INTEGER); |
VAR |
i: INTEGER; |
85,20 → 89,20 |
BEGIN |
i := align(counter, FileAlignment) - counter; |
WHILE i > 0 DO |
WriteByte(0); |
WriteByte(file, 0); |
DEC(i) |
END |
END Padding; |
PROCEDURE Create* (FileName: ARRAY OF CHAR); |
PROCEDURE Create* (FileName: ARRAY OF CHAR): FILE; |
BEGIN |
counter := 0; |
file := FILES.create(FileName) |
counter := 0 |
RETURN FILES.create(FileName) |
END Create; |
PROCEDURE Close*; |
PROCEDURE Close* (VAR file: FILE); |
BEGIN |
FILES.close(file) |
END Close; |
/programs/develop/oberon07/Source/X86.ob07 |
---|
8,7 → 8,7 |
MODULE X86; |
IMPORT IL, REG, UTILS, LISTS, BIN, PE32, KOS, MSCOFF, ELF, PROG, |
CHL := CHUNKLISTS, PATHS, TARGETS, ERRORS; |
CHL := CHUNKLISTS, PATHS, TARGETS; |
CONST |
22,8 → 22,6 |
esp = 4; |
ebp = 5; |
MAX_FR = 7; |
sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H; |
je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; jnb = 83H; |
31,9 → 29,7 |
CODECHUNK = 8; |
FPR_ERR = 41; |
TYPE |
COMMAND = IL.COMMAND; |
96,11 → 92,7 |
tcount: INTEGER; |
FR: ARRAY 1000 OF INTEGER; |
fname: PATHS.PATH; |
PROCEDURE OutByte* (n: BYTE); |
VAR |
c: CODE; |
154,7 → 146,7 |
END OutWord; |
PROCEDURE isByte* (n: INTEGER): BOOLEAN; |
PROCEDURE isByte (n: INTEGER): BOOLEAN; |
RETURN (-128 <= n) & (n <= 127) |
END isByte; |
190,24 → 182,24 |
END shift; |
PROCEDURE oprr (op: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *) |
PROCEDURE mov (reg1, reg2: INTEGER); |
BEGIN |
OutByte2(op, 0C0H + 8 * reg2 + reg1) |
END oprr; |
OutByte2(89H, 0C0H + reg2 * 8 + reg1) (* mov reg1, reg2 *) |
END mov; |
PROCEDURE mov (reg1, reg2: INTEGER); (* mov reg1, reg2 *) |
BEGIN |
oprr(89H, reg1, reg2) |
END mov; |
PROCEDURE xchg (reg1, reg2: INTEGER); |
VAR |
regs: SET; |
PROCEDURE xchg (reg1, reg2: INTEGER); (* xchg reg1, reg2 *) |
BEGIN |
IF eax IN {reg1, reg2} THEN |
OutByte(90H + reg1 + reg2) |
ELSE |
oprr(87H, reg1, reg2) |
regs := {reg1, reg2}; |
IF regs = {eax, ecx} THEN |
OutByte(91H) (* xchg eax, ecx *) |
ELSIF regs = {eax, edx} THEN |
OutByte(92H) (* xchg eax, edx *) |
ELSIF regs = {ecx, edx} THEN |
OutByte2(87H, 0D1H) (* xchg ecx, edx *) |
END |
END xchg; |
224,24 → 216,14 |
END push; |
PROCEDURE xor (reg1, reg2: INTEGER); (* xor reg1, reg2 *) |
BEGIN |
oprr(31H, reg1, reg2) |
END xor; |
PROCEDURE movrc (reg, n: INTEGER); |
BEGIN |
IF n = 0 THEN |
xor(reg, reg) |
ELSE |
OutByte(0B8H + reg); (* mov reg, n *) |
OutInt(n) |
END |
END movrc; |
PROCEDURE pushc* (n: INTEGER); |
PROCEDURE pushc (n: INTEGER); |
BEGIN |
OutByte(68H + short(n)); (* push n *) |
OutIntByte(n) |
266,85 → 248,67 |
END not; |
PROCEDURE add (reg1, reg2: INTEGER); (* add reg1, reg2 *) |
PROCEDURE add (reg1, reg2: INTEGER); |
BEGIN |
oprr(01H, reg1, reg2) |
OutByte2(01H, 0C0H + reg2 * 8 + reg1) (* add reg1, reg2 *) |
END add; |
PROCEDURE oprc* (op, reg, n: INTEGER); |
PROCEDURE andrc (reg, n: INTEGER); |
BEGIN |
IF (reg = eax) & ~isByte(n) THEN |
CASE op OF |
|0C0H: op := 05H (* add *) |
|0E8H: op := 2DH (* sub *) |
|0F8H: op := 3DH (* cmp *) |
|0E0H: op := 25H (* and *) |
|0C8H: op := 0DH (* or *) |
|0F0H: op := 35H (* xor *) |
END; |
OutByte(op); |
OutInt(n) |
ELSE |
OutByte2(81H + short(n), op + reg MOD 8); |
OutByte2(81H + short(n), 0E0H + reg); (* and reg, n *) |
OutIntByte(n) |
END |
END oprc; |
PROCEDURE andrc (reg, n: INTEGER); (* and reg, n *) |
BEGIN |
oprc(0E0H, reg, n) |
END andrc; |
PROCEDURE orrc (reg, n: INTEGER); (* or reg, n *) |
PROCEDURE orrc (reg, n: INTEGER); |
BEGIN |
oprc(0C8H, reg, n) |
OutByte2(81H + short(n), 0C8H + reg); (* or reg, n *) |
OutIntByte(n) |
END orrc; |
PROCEDURE xorrc (reg, n: INTEGER); (* xor reg, n *) |
PROCEDURE addrc (reg, n: INTEGER); |
BEGIN |
oprc(0F0H, reg, n) |
END xorrc; |
OutByte2(81H + short(n), 0C0H + reg); (* add reg, n *) |
OutIntByte(n) |
END addrc; |
PROCEDURE addrc (reg, n: INTEGER); (* add reg, n *) |
PROCEDURE subrc (reg, n: INTEGER); |
BEGIN |
oprc(0C0H, reg, n) |
END addrc; |
OutByte2(81H + short(n), 0E8H + reg); (* sub reg, n *) |
OutIntByte(n) |
END subrc; |
PROCEDURE subrc (reg, n: INTEGER); (* sub reg, n *) |
PROCEDURE cmprr (reg1, reg2: INTEGER); |
BEGIN |
oprc(0E8H, reg, n) |
END subrc; |
OutByte2(39H, 0C0H + reg2 * 8 + reg1) (* cmp reg1, reg2 *) |
END cmprr; |
PROCEDURE cmprc (reg, n: INTEGER); (* cmp reg, n *) |
PROCEDURE cmprc (reg, n: INTEGER); |
BEGIN |
IF n = 0 THEN |
test(reg) |
ELSE |
oprc(0F8H, reg, n) |
OutByte2(81H + short(n), 0F8H + reg); (* cmp reg, n *) |
OutIntByte(n) |
END |
END cmprc; |
PROCEDURE cmprr (reg1, reg2: INTEGER); (* cmp reg1, reg2 *) |
PROCEDURE setcc (cond, reg: INTEGER); |
BEGIN |
oprr(39H, reg1, reg2) |
END cmprr; |
OutByte3(0FH, cond, 0C0H + reg) (* setcc reg *) |
END setcc; |
PROCEDURE setcc* (cc, reg: INTEGER); (* setcc reg *) |
PROCEDURE xor (reg1, reg2: INTEGER); |
BEGIN |
IF reg >= 8 THEN |
OutByte(41H) |
END; |
OutByte3(0FH, cc, 0C0H + reg MOD 8) |
END setcc; |
OutByte2(31H, 0C0H + reg2 * 8 + reg1) (* xor reg1, reg2 *) |
END xor; |
PROCEDURE ret*; |
614,7 → 578,7 |
OutByte2(0DAH, 0E9H); (* fucompp *) |
OutByte3(09BH, 0DFH, 0E0H); (* fstsw ax *) |
OutByte(09EH); (* sahf *) |
OutByte(0B8H); OutInt(0) (* mov eax, 0 *) |
movrc(eax, 0) |
END fcmp; |
730,7 → 694,7 |
VAR |
cmd, next: COMMAND; |
reg1, reg2, fr: INTEGER; |
reg1, reg2: INTEGER; |
n, a, b, label, cc: INTEGER; |
741,8 → 705,6 |
BEGIN |
cmd := IL.codes.commands.first(COMMAND); |
fr := -1; |
WHILE cmd # NIL DO |
param1 := cmd.param1; |
776,18 → 738,16 |
ASSERT(R.top = -1) |
|IL.opPRECALL: |
PushAll(0); |
IF (param2 # 0) & (fr >= 0) THEN |
n := param2; |
IF (param1 # 0) & (n # 0) THEN |
subrc(esp, 8) |
END; |
INC(FR[0]); |
FR[FR[0]] := fr + 1; |
WHILE fr >= 0 DO |
WHILE n > 0 DO |
subrc(esp, 8); |
OutByte3(0DDH, 01CH, 024H); (* fstp qword[esp] *) |
DEC(fr) |
DEC(n) |
END; |
ASSERT(fr = -1) |
PushAll(0) |
|IL.opALIGN16: |
ASSERT(eax IN R.regs); |
799,31 → 759,27 |
END; |
push(eax) |
|IL.opRESF, IL.opRES: |
|IL.opRES: |
ASSERT(R.top = -1); |
ASSERT(fr = -1); |
n := FR[FR[0]]; DEC(FR[0]); |
GetRegA; |
n := param2; |
WHILE n > 0 DO |
OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *) |
addrc(esp, 8); |
DEC(n) |
END |
IF opcode = IL.opRESF THEN |
INC(fr); |
|IL.opRESF: |
n := param2; |
IF n > 0 THEN |
OutByte3(0DDH, 5CH + long(n * 8), 24H); |
OutIntByte(n * 8); (* fstp qword[esp + n*8] *) |
DEC(fr); |
INC(n) |
END; |
IF fr + n > MAX_FR THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
END |
ELSE |
GetRegA |
END; |
WHILE n > 0 DO |
OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *) |
addrc(esp, 8); |
INC(fr); |
DEC(n) |
END |
860,12 → 816,6 |
ASSERT(R.top = -1); |
IF opcode = IL.opLEAVEF THEN |
DEC(fr) |
END; |
ASSERT(fr = -1); |
IF param1 > 0 THEN |
mov(esp, ebp) |
END; |
899,8 → 849,9 |
END |
|IL.opCLEANUP: |
IF param2 # 0 THEN |
addrc(esp, param2 * 4) |
n := param2 * 4; |
IF n # 0 THEN |
addrc(esp, n) |
END |
|IL.opPOPSP: |
912,14 → 863,9 |
|IL.opLABEL: |
SetLabel(param1) (* L: *) |
|IL.opNOP, IL.opAND, IL.opOR: |
|IL.opNOP: |
|IL.opGADR: |
next := cmd.next(COMMAND); |
IF next.opcode = IL.opADDC THEN |
INC(param2, next.param2); |
cmd := next |
END; |
reg1 := GetAnyReg(); |
IF pic THEN |
Pic(reg1, BIN.PICBSS, param2) |
929,12 → 875,7 |
END |
|IL.opLADR: |
next := cmd.next(COMMAND); |
n := param2 * 4; |
IF next.opcode = IL.opADDC THEN |
INC(n, next.param2); |
cmd := next |
END; |
OutByte2(8DH, 45H + GetAnyReg() * 8 + long(n)); (* lea reg1, dword[ebp + n] *) |
OutIntByte(n) |
966,6 → 907,7 |
drop |
|IL.opVLOAD32: |
n := param2 * 4; |
reg1 := GetAnyReg(); |
movrm(reg1, ebp, param2 * 4); |
movrm(reg1, reg1, 0) |
1037,7 → 979,7 |
add(reg1, reg2); |
drop |
|IL.opADDC: |
|IL.opADDL, IL.opADDR: |
IF param2 # 0 THEN |
UnOp(reg1); |
next := cmd.next(COMMAND); |
1068,17 → 1010,18 |
|IL.opSUB: |
BinOp(reg1, reg2); |
oprr(29H, reg1, reg2); (* sub reg1, reg2 *) |
OutByte2(29H, 0C0H + reg2 * 8 + reg1); (* sub reg1, reg2 *) |
drop |
|IL.opSUBR, IL.opSUBL: |
UnOp(reg1); |
IF param2 = 1 THEN |
n := param2; |
IF n = 1 THEN |
OutByte(48H + reg1) (* dec reg1 *) |
ELSIF param2 = -1 THEN |
ELSIF n = -1 THEN |
OutByte(40H + reg1) (* inc reg1 *) |
ELSIF param2 # 0 THEN |
subrc(reg1, param2) |
ELSIF n # 0 THEN |
subrc(reg1, n) |
END; |
IF opcode = IL.opSUBL THEN |
neg(reg1) |
1236,10 → 1179,10 |
cc := cond(opcode); |
next := cmd.next(COMMAND); |
IF next.opcode = IL.opJNZ THEN |
IF next.opcode = IL.opJE THEN |
jcc(cc, next.param1); |
cmd := next |
ELSIF next.opcode = IL.opJZ THEN |
ELSIF next.opcode = IL.opJNE THEN |
jcc(inv0(cc), next.param1); |
cmd := next |
ELSE |
1269,27 → 1212,40 |
END; |
andrc(reg1, 1) |
|IL.opACC: |
IF (R.top # 0) OR (R.stk[0] # eax) THEN |
PushAll(0); |
GetRegA; |
pop(eax); |
DEC(R.pushed) |
END |
|IL.opDROP: |
UnOp(reg1); |
drop |
|IL.opJNZ1: |
|IL.opJNZ: |
UnOp(reg1); |
test(reg1); |
jcc(jne, param1) |
|IL.opJZ: |
UnOp(reg1); |
test(reg1); |
jcc(je, param1) |
|IL.opJG: |
UnOp(reg1); |
test(reg1); |
jcc(jg, param1) |
|IL.opJNZ: |
|IL.opJE: |
UnOp(reg1); |
test(reg1); |
jcc(jne, param1); |
drop |
|IL.opJZ: |
|IL.opJNE: |
UnOp(reg1); |
test(reg1); |
jcc(je, param1); |
1433,7 → 1389,7 |
|IL.opMULS: |
BinOp(reg1, reg2); |
oprr(21H, reg1, reg2); (* and reg1, reg2 *) |
OutByte2(21H, 0C0H + reg2 * 8 + reg1); (* and reg1, reg2 *) |
drop |
|IL.opMULSC: |
1447,20 → 1403,21 |
|IL.opDIVSC: |
UnOp(reg1); |
xorrc(reg1, param2) |
OutByte2(81H + short(param2), 0F0H + reg1); (* xor reg1, n *) |
OutIntByte(param2) |
|IL.opADDS: |
BinOp(reg1, reg2); |
oprr(9H, reg1, reg2); (* or reg1, reg2 *) |
OutByte2(9H, 0C0H + reg2 * 8 + reg1); (* or reg1, reg2 *) |
drop |
|IL.opSUBS: |
BinOp(reg1, reg2); |
not(reg2); |
oprr(21H, reg1, reg2); (* and reg1, reg2 *) |
OutByte2(21H, 0C0H + reg2 * 8 + reg1); (* and reg1, reg2 *) |
drop |
|IL.opADDSC: |
|IL.opADDSL, IL.opADDSR: |
UnOp(reg1); |
orrc(reg1, param2) |
1551,15 → 1508,9 |
|IL.opMAXC, IL.opMINC: |
UnOp(reg1); |
cmprc(reg1, param2); |
label := NewLabel(); |
IF opcode = IL.opMINC THEN |
cc := jle |
ELSE |
cc := jge |
END; |
jcc(cc, label); |
movrc(reg1, param2); |
SetLabel(label) |
OutByte2(07DH + ORD(opcode = IL.opMINC), 5); (* jge/jle L *) |
movrc(reg1, param2) |
(* L: *) |
|IL.opIN, IL.opINR: |
IF opcode = IL.opINR THEN |
1873,25 → 1824,15 |
drop |
|IL.opPUSHF: |
ASSERT(fr >= 0); |
DEC(fr); |
subrc(esp, 8); |
OutByte3(0DDH, 01CH, 024H) (* fstp qword[esp] *) |
|IL.opLOADF: |
INC(fr); |
IF fr > MAX_FR THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
END; |
UnOp(reg1); |
OutByte2(0DDH, reg1); (* fld qword[reg1] *) |
drop |
|IL.opCONSTF: |
INC(fr); |
IF fr > MAX_FR THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
END; |
float := cmd.float; |
IF float = 0.0 THEN |
OutByte2(0D9H, 0EEH) (* fldz *) |
1909,55 → 1850,35 |
END |
|IL.opSAVEF, IL.opSAVEFI: |
ASSERT(fr >= 0); |
DEC(fr); |
UnOp(reg1); |
OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *) |
drop |
|IL.opADDF: |
ASSERT(fr >= 1); |
DEC(fr); |
|IL.opADDF, IL.opADDFI: |
OutByte2(0DEH, 0C1H) (* faddp st1, st *) |
|IL.opSUBF: |
ASSERT(fr >= 1); |
DEC(fr); |
OutByte2(0DEH, 0E9H) (* fsubp st1, st *) |
|IL.opSUBFI: |
ASSERT(fr >= 1); |
DEC(fr); |
OutByte2(0DEH, 0E1H) (* fsubrp st1, st *) |
|IL.opMULF: |
ASSERT(fr >= 1); |
DEC(fr); |
OutByte2(0DEH, 0C9H) (* fmulp st1, st *) |
|IL.opDIVF: |
ASSERT(fr >= 1); |
DEC(fr); |
OutByte2(0DEH, 0F9H) (* fdivp st1, st *) |
|IL.opDIVFI: |
ASSERT(fr >= 1); |
DEC(fr); |
OutByte2(0DEH, 0F1H) (* fdivrp st1, st *) |
|IL.opUMINF: |
ASSERT(fr >= 0); |
OutByte2(0D9H, 0E0H) (* fchs *) |
|IL.opFABS: |
ASSERT(fr >= 0); |
OutByte2(0D9H, 0E1H) (* fabs *) |
|IL.opFLT: |
INC(fr); |
IF fr > MAX_FR THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
END; |
UnOp(reg1); |
push(reg1); |
OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *) |
1965,8 → 1886,6 |
drop |
|IL.opFLOOR: |
ASSERT(fr >= 0); |
DEC(fr); |
subrc(esp, 8); |
OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 004H); (* fstcw word[esp+4] *) |
OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 006H); (* fstcw word[esp+6] *) |
1980,8 → 1899,6 |
addrc(esp, 4) |
|IL.opEQF: |
ASSERT(fr >= 1); |
DEC(fr, 2); |
fcmp; |
OutByte2(07AH, 003H); (* jp L *) |
setcc(sete, al) |
1988,8 → 1905,6 |
(* L: *) |
|IL.opNEF: |
ASSERT(fr >= 1); |
DEC(fr, 2); |
fcmp; |
OutByte2(07AH, 003H); (* jp L *) |
setcc(setne, al) |
1996,8 → 1911,6 |
(* L: *) |
|IL.opLTF: |
ASSERT(fr >= 1); |
DEC(fr, 2); |
fcmp; |
OutByte2(07AH, 00EH); (* jp L *) |
setcc(setc, al); |
2008,8 → 1921,6 |
(* L: *) |
|IL.opGTF: |
ASSERT(fr >= 1); |
DEC(fr, 2); |
fcmp; |
OutByte2(07AH, 00FH); (* jp L *) |
setcc(setc, al); |
2020,8 → 1931,6 |
(* L: *) |
|IL.opLEF: |
ASSERT(fr >= 1); |
DEC(fr, 2); |
fcmp; |
OutByte2(07AH, 003H); (* jp L *) |
setcc(setnc, al) |
2028,8 → 1937,6 |
(* L: *) |
|IL.opGEF: |
ASSERT(fr >= 1); |
DEC(fr, 2); |
fcmp; |
OutByte2(07AH, 010H); (* jp L *) |
setcc(setc, al); |
2041,10 → 1948,6 |
(* L: *) |
|IL.opINF: |
INC(fr); |
IF fr > MAX_FR THEN |
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
END; |
pushc(7FF00000H); |
pushc(0); |
OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *) |
2173,9 → 2076,6 |
OutIntByte(n); |
OutByte(param2) |
|IL.opFNAME: |
fname := cmd(IL.FNAMECMD).fname |
|IL.opLOOP, IL.opENDLOOP: |
END; |
2184,8 → 2084,8 |
END; |
ASSERT(R.pushed = 0); |
ASSERT(R.top = -1); |
ASSERT(fr = -1) |
ASSERT(R.top = -1) |
END translate; |
2194,9 → 2094,9 |
reg1, entry, L, dcount: INTEGER; |
BEGIN |
entry := NewLabel(); |
SetLabel(entry); |
dcount := CHL.Length(IL.codes.data); |
IF target = TARGETS.Win32DLL THEN |
push(ebp); |
2206,17 → 2106,19 |
pushm(ebp, 8); |
CallRTL(pic, IL._dllentry); |
test(eax); |
jcc(je, dllret); |
pushc(0) |
jcc(je, dllret) |
ELSIF target = TARGETS.KolibriOSDLL THEN |
SetLabel(dllinit); |
OutByte(68H); (* push IMPORT *) |
Reloc(BIN.IMPTAB, 0) |
ELSIF target = TARGETS.KolibriOS THEN |
SetLabel(dllinit) |
END; |
IF target = TARGETS.KolibriOS THEN |
reg1 := GetAnyReg(); |
Pic(reg1, BIN.IMPTAB, 0); |
push(reg1); (* push IMPORT *) |
drop |
ELSIF target = TARGETS.KolibriOSDLL THEN |
OutByte(68H); (* push IMPORT *) |
Reloc(BIN.IMPTAB, 0) |
ELSIF target = TARGETS.Linux32 THEN |
push(esp) |
ELSE |
2227,25 → 2129,39 |
reg1 := GetAnyReg(); |
Pic(reg1, BIN.PICCODE, entry); |
push(reg1); (* push CODE *) |
drop |
ELSE |
OutByte(68H); (* push CODE *) |
Reloc(BIN.RCODE, entry) |
END; |
IF pic THEN |
reg1 := GetAnyReg(); |
Pic(reg1, BIN.PICDATA, 0); |
push(reg1); (* push _data *) |
drop |
ELSE |
OutByte(68H); (* push _data *) |
Reloc(BIN.RDATA, 0) |
END; |
dcount := CHL.Length(IL.codes.data); |
pushc(tcount); |
IF pic THEN |
reg1 := GetAnyReg(); |
Pic(reg1, BIN.PICDATA, tcount * 4 + dcount); |
push(reg1); (* push _data + tcount * 4 + dcount *) |
drop |
ELSE |
OutByte(68H); (* push CODE *) |
Reloc(BIN.RCODE, entry); |
OutByte(68H); (* push _data *) |
Reloc(BIN.RDATA, 0); |
pushc(tcount); |
OutByte(68H); (* push _data + tcount * 4 + dcount *) |
Reloc(BIN.RDATA, tcount * 4 + dcount) |
END; |
CallRTL(pic, IL._init); |
IF target IN {TARGETS.Win32C, TARGETS.Win32GUI, TARGETS.Linux32} THEN |
IF target = TARGETS.Linux32 THEN |
L := NewLabel(); |
pushc(0); |
push(esp); |
2270,7 → 2186,7 |
dcount, i: INTEGER; |
PROCEDURE _import (imp: LISTS.LIST); |
PROCEDURE import (imp: LISTS.LIST); |
VAR |
lib: IL.IMPORT_LIB; |
proc: IL.IMPORT_PROC; |
2288,7 → 2204,7 |
lib := lib.next(IL.IMPORT_LIB) |
END |
END _import; |
END import; |
BEGIN |
2340,11 → 2256,12 |
exp := exp.next(IL.EXPORT_PROC) |
END; |
_import(IL.codes._import); |
import(IL.codes.import); |
IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4))); |
BIN.SetParams(program, IL.codes.bss, stack * (1024 * 1024), WCHR(ver DIV 65536), WCHR(ver MOD 65536)) |
BIN.SetParams(program, IL.codes.bss, stack * (1024 * 1024), WCHR(ver DIV 65536), WCHR(ver MOD 65536)); |
END epilog; |
2354,7 → 2271,6 |
opt: PROG.OPTIONS; |
BEGIN |
FR[0] := 0; |
tcount := CHL.Length(IL.codes.types); |
opt := options; |