Кроссплатформенные примеры скоро будут.
А чем ".obj" не устраивает? MS COFF, вроде бы... Чтобы было понятно о чём речь и как это сделать, нужен пример такого файла на FASM.
Компилятор Oberon-07
Как следует из документации:Сейчас нет возможности использовать сторонние модули при статической линковке.
Параметры:
..............
3) тип приложения и платформа
..............
"obj" - KolibriOS DLL
Если видел примеры для XDS Modula-2/Oberon-2 compiler http://board.kolibrios.org/viewtopic.php?f=33&t=2280 то там сначала получается объектный файл, затем он линкуется с другими модулями примерно так:Разрешается экспортировать только процедуры.
..............
KolibriOS DLL всегда экспортируют идентификаторы "version"
(версия программы) и "lib_init" - адрес процедуры инициализации DLL:
PROCEDURE [stdcall] lib_init (): INTEGER
Эта процедура должна быть вызвана перед использованием DLL.
Code: Select all
xc %name%.mod -objfmt=coff
ld -o %Name%.kex ^
-T ../LScript.x ^
%Name%.obj ^
../../Modules/DLL.obj ^
../../Modules/X2C.obj ^
../../Modules/InOut.obj
Теперь подсветка в HippoEDIT "поехала".akron1 wrote:- Добавлен специальный синтаксис для импорта функций из динамических библиотек.
Я пока плохо представляю, как работает статическая линковка. Если будет время и желание, то может быть сделаю раздельную компиляцию с последующей линковкой. Но видимо нескоро. Сейчас мне это кажется довольно сложным.
Если есть какие-либо идеи, то можешь предложить свой вариант синтаксиса импорта, более удобный для подсветки.0CodErr wrote:Теперь подсветка в HippoEDIT "поехала".
Ну ничего страшного, торопиться и не надоakron1 wrote:Если будет время и желание, то может быть сделаю раздельную компиляцию с последующей линковкой. Но видимо нескоро.
Если будет что — с удовольствием потестирую.
Казалось бы, банальное добавление END; решает проблемуakron1 wrote:предложить свой вариант синтаксиса импорта, более удобный для подсветки
Code: Select all
PROCEDURE [winapi, "kernel32.dll", "GetTickCount"]
_GetTickCount* (): INTEGER; END;
PROCEDURE [winapi, "kernel32.dll", "GetStdHandle"]
GetStdHandle (nStdHandle: INTEGER): INTEGER; END;
PROCEDURE [winapi, "kernel32.dll", "GetCommandLineA"]
GetCommandLine (): INTEGER; END;
PROCEDURE [winapi, "kernel32.dll", "ReadFile"]
ReadFile (hFile, Buffer, nNumberOfBytesToRW: INTEGER; VAR NumberOfBytesRW: INTEGER; lpOverlapped: POverlapped): INTEGER; END;
PROCEDURE [winapi, "kernel32.dll", "WriteFile"]
WriteFile (hFile, Buffer, nNumberOfBytesToRW: INTEGER; VAR NumberOfBytesRW: INTEGER; lpOverlapped: POverlapped): INTEGER; END;
PROCEDURE [winapi, "kernel32.dll", "CloseHandle"]
CloseHandle (hObject: INTEGER): INTEGER; END;
PROCEDURE [winapi, "kernel32.dll", "CreateFileA"]
CreateFile (
lpFileName, dwDesiredAccess, dwShareMode: INTEGER;
lpSecurityAttributes: PSecurityAttributes;
dwCreationDisposition, dwFlagsAndAttributes,
hTemplateFile: INTEGER): INTEGER; END;
PROCEDURE [winapi, "kernel32.dll", "OpenFile"]
OpenFile (lpFileName: INTEGER; lpReOpenBuff: OFSTRUCT; uStyle: INTEGER): INTEGER; END;
PROCEDURE [winapi, "kernel32.dll", "ExitProcess"]
ExitProcess* (code: INTEGER); END;
PROCEDURE [winapi, "shell32.dll", "ShellExecuteA"]
ShellExecute* (hWnd, Operation, FileName, Parameters, Directory, ShowCmd: INTEGER): INTEGER; END;
Будет ли возможность собрать те примеры(Projects.7z ) http://board.kolibrios.org/viewtopic.ph ... =45#p70389 ?akron1 wrote:Кроссплатформенные примеры скоро будут.
END, конечно, не очень красиво. Хотя, можно сделать (опционально):
Code: Select all
PROCEDURE [winapi, "kernel32.dll", "CloseHandle"]
CloseHandle* (hObject: INTEGER): INTEGER;
END CloseHandle;
Да, я поставлю заглушки для Windows Console.open, Console.exit. Вроде бы ничего лучше пока нельзя сделать. Еще надо будет сделать поддержку относительных путей, чтобы компилировать из командного файла.Будет ли возможность собрать те примеры(Projects.7z )
Это проще чем звучит. Функции выкладываются по очереди в сегмент кода, их адреса запоминаются.akron1 wrote:Я пока плохо представляю, как работает статическая линковка. Если будет время и желание, то может быть сделаю раздельную компиляцию с последующей линковкой. Но видимо нескоро. Сейчас мне это кажется довольно сложным.
На втором проходе по местам релоков прописываются полученные адреса.
Вот как сделано в tcc, всего 300 строк
Меня наоборот, пугает динамическая =)
Сделано.akron1 wrote:END, конечно, не очень красиво. Хотя, можно сделать (опционально):Code: Select all
PROCEDURE [winapi, "kernel32.dll", "CloseHandle"] CloseHandle* (hObject: INTEGER): INTEGER; END CloseHandle;
Сделано.akron1 wrote:Да, я поставлю заглушки для Windows Console.open, Console.exit. Вроде бы ничего лучше пока нельзя сделать.Будет ли возможность собрать те примеры(Projects.7z )
Сделано.akron1 wrote: Еще надо будет сделать поддержку относительных путей
Примеры прикрепил.
- Attachments
-
-
Projects.zip (13.3 KiB)Downloaded 380 times
-
Разве нельзя было инициализировать консоль внутри In.Open и Out.Open?akron1 wrote:заглушки для Windows Console.open, Console.exit. Вроде бы ничего лучше пока нельзя сделать.
Раньше ещё поддерживался Linux, теперь он поддерживаться не будет?
Ну а финализацию куда всунуть? Я так думаю, что инициализация и финализация консоли должны быть в одном модуле. Я выбрал модуль Console. Другое дело, что Console.open фактически не нужно вызывать в Windows, а In.Open и Out.Open не нужны в KolibriOS (In.Open, правда, инициализирует переменную Done, но этот код можно перенести в секцию инициализации модуля In). Я тут думаю, что может быть лучше In.Open и Out.Open вызывать из Console.open.
Тогда "кроссплатформенный" код главного модуля будет выглядеть так:
вместо
Поддержку Linux хотелось бы сделать, но пока до этого руки не доходят.
Тогда "кроссплатформенный" код главного модуля будет выглядеть так:
Code: Select all
MODULE program;
IMPORT C := Console, In, Out;
BEGIN
C.open;
C.exit(TRUE)
END program.
Code: Select all
MODULE program;
IMPORT C := Console, In, Out;
BEGIN
C.open;
In.Open;
Out.Open;
C.exit(TRUE)
END program.
Это вполне хороший вариант.akron1 wrote:Тогда "кроссплатформенный" код главного модуля будет выглядеть так:Code: Select all
MODULE program; IMPORT C := Console, In, Out; BEGIN C.open; C.exit(TRUE) END program.
Я просто думал, как бы так сделать, чтобы поменьше вызывать лишнего.
Если только неявно после выполнения основного кодаakron1 wrote:Ну а финализацию куда всунуть?
Code: Select all
IF Console.Initialized THEN
Console.exit
END;
Spoiler:
Code: Select all
<*+ MAIN *>
MODULE ackermann;
IMPORT Out, In;
VAR p1, p2, count: LONGINT;
PROCEDURE ack (m, n: LONGINT): LONGINT;
BEGIN
INC (count);
IF m=0 THEN RETURN n+1 END;
IF n=0 THEN RETURN ack (m-1, 1) END;
RETURN ack (m-1, ack (m, n-1));
END ack;
BEGIN
In.Open;
count := 0;
Out.String ("Ackermann Function Calculation"); Out.Ln;
Out.String ("------------------------------"); Out.Ln;
Out.Ln;
Out.String ("Enter first parameter (1..4): "); In.LongInt(p1);
Out.String ("Enter second parameter (1..7): "); In.LongInt(p2);
Out.Ln;
Out.String ("Ackermann ("); Out.Int (p1, 0);
Out.String (", "); Out.Int(p2, 0);
Out.String ("): ");
Out.Int (ack (p1, p2), 0);
Out.String (" ("); Out.Int (count, 0);
Out.String (" recursive calls)");
Out.Ln;
END ackermann.
Spoiler:
Code: Select all
<* MAIN+ *>
MODULE GCreport;
IMPORT SYSTEM, oberonRTS, Out;
TYPE Object = POINTER TO ObjDesc;
ObjDesc = RECORD
END;
VAR
global: Object;
count: INTEGER;
PROCEDURE Finalize(a: SYSTEM.PTR);
BEGIN
INC(count);
Out.String("Garbage Collector: "); Out.Int(count,0); Out.Ln;
global:=SYSTEM.VAL(Object,a);
oberonRTS.InstallFinalizer(Finalize,global);
END Finalize;
PROCEDURE Init;
VAR o: Object;
BEGIN
count:=0;
NEW(o);
oberonRTS.InstallFinalizer(Finalize,o);
NEW(o);
oberonRTS.InstallFinalizer(Finalize,o);
global:=o;
END Init;
BEGIN
Init;
oberonRTS.Collect;
oberonRTS.Collect;
oberonRTS.Collect;
oberonRTS.Collect;
END GCreport.
Ну при завершении программы как минимум.
Пока сделал так. Теперь можно не вызывать In.Open и Out.Open.0CodErr wrote:Это вполне хороший вариант.akron1 wrote:Тогда "кроссплатформенный" код главного модуля будет выглядеть так:Code: Select all
MODULE program; IMPORT C := Console, In, Out; BEGIN C.open; C.exit(TRUE) END program.
Я просто думал, как бы так сделать, чтобы поменьше вызывать лишнего.
Я перестроил компилятор на генерацию машинного кода с формированием исполняемых файлов (PE и MENUET01). FASM больше не нужен. Генерация obj-библиотек пока не поддерживается. Размер машинного кода стал на 15% больше (сжатый на 5%), потому что компилятор пока генерирует длинные команды переходов там, где возможны короткие.
20.11.2018
Поддержка obj-библиотек восстановлена. Также сделал генерацию позиционно-независимого кода. Для KolibriOS это не нужно, но может быть для чего-нибудь пригодится.
25.11.2018
Короткие команды переходов, отключаемый рантайм контроль типов, индексов и указателей.
20.11.2018
Поддержка obj-библиотек восстановлена. Также сделал генерацию позиционно-независимого кода. Для KolibriOS это не нужно, но может быть для чего-нибудь пригодится.
25.11.2018
Короткие команды переходов, отключаемый рантайм контроль типов, индексов и указателей.