1 (изменено: Freeman, 28.06.2020 в 20:51)

Тема: XD Pascal

Но есть вот такой проект компилятора XD Pascal, лицензия "BSD-2-Clause".
На sourceforge есть ещё такой проект того же автора, лицензия "Public Domain".

Проект при желании можно скомпилировать в Delphi 2009+
Кстати, строковой и символьный тип там объявлены как
TString и TCharacter(но я бы сделал TChar).

Я писал, что было бы полезно создать какой-то проект или утилиту, что бы можно было более серьёзно тестировать SDK KolibriOS.
Так вот, этот проект очень даже подходит.
Его можно вполне скомпилировать под KolibriOS.

Заодно будет тест для SDK.
ParamStr, ParamCount, GetMem, FreeMem, строковые функции, файловые функции.

Возможно, автору и самому это было бы интересно.
Проект на sourceforge вообще позиционируется как "small educational".

Может и нам что-то будет полезно из System
Да, там в процедуре Move неточность, не учитывается, что память Src и Dst может перекрываться.

Вот тут, кстати, переопределение AnsiChar странное, но WideChar более логичное

  AnsiChar = Char;
  PAnsiChar = PChar;
  
  WideChar = Word;
  PWideChar = ^WideChar;
WideString = array [1..MaxStrLength + 1] of WideChar;

2

Re: XD Pascal

Чем этот компилятор будет полезен в SDK? Возможностью компилировать программы из самой Колибри? Возьмет ли он наши примеры? Придерживаюсь стратегии не плодить сущности без надобности.

3

Re: XD Pascal

Вообще надо бы у автора уточнить.
Но там вроде асм-код не поддерживается и ООП тоже.

Возможностью компилировать программы из самой Колибри?

Ну да, это же компилятор.

Это полезная программа, которая могла бы собираться и работать под KolibriOS.
Разве не для этого создаётся SDK, чтобы собирать программы для KolibriOS?
А то получается куча HelloWorld-ов — это полезно, а что-то более серьёзное уже нет?
По-моему как раз наоборот(чем серьёзнее проекты, тем ценнее SDK). Ведь SDK не ради того, чтобы только вывести "hello" в консоль.

Добавлено 2020-06-29 в 00:19

Да, вот, кстати, на хабре есть статья, в которой говорится

После трёх лет полного забвения некая группа польских энтузиастов ретрокомпьютинга и любителей Atari отыскала мой компилятор.
[...]
Из моего проекта они сделали собственный компилятор Mad Pascal для архитектуры 6502.
[...]
вот уже три года Mad Pascal регулярно обновляется, на нём написано немало игр,

насчёт поддержки операторов всё же надо уточнить

Мой свежеиспечённый компилятор получил название XD Pascal. Он поддерживал все операторы Паскаля, кроме goto и with.

4 (изменено: Freeman, 01.07.2020 в 01:01)

Re: XD Pascal

Freeman пишет:

Включение XD Pascal под вопросом. Критерий для добавления в SDK — полезность в разработке и использования в Колибри. Автор DCU32Int — русский, нужно спросить у него разрешение.

Ну про XD Pascal, думаю, тоже не мешает с автором проконсультироваться, так как он свой код знает лучше.
Сейчас там нет поддержки родного формата KolibriOS, желательно ещё добавить хотя бы директиву inline(а лучше asm, конечно), иначе без извращений не получится использовать системные вызовы.

Добавлено 2020-06-30 в 15:29

Если бы поддерживалась директива inline, то можно было бы вставлять уже скомпилированный код, как это сделано в Oberon-07, например, в этом модуле используется SYSTEM.CODE(...), внутри содержится уже готовый код.

Так как это не поддерживается, то я решил сделать по-другому.
Этот пример компилируется Delphi 7

program Test;

const
  // Procedure TerminateThread
  _TerminateThread: array[0..4] of Byte = (
    $83, $C8, $FF, $CD, $40
  );

  // Function LoadLibrary(Path: PAnsiChar): Pointer; StdCall
  _LoadLibrary: array[0..20] of Byte = (
    $53, $B8, $44, $00, $00, $00, $BB, $13, $00, $00, $00, $8B, $4C, $24, $08,
    $CD, $40, $5B, $C2, $04, $00
  );

  // Function  GetProcAddress(hLib: Pointer; ProcName: PAnsiChar): Pointer; StdCall;
  _GetProcAddress: array[0..55] of Byte = (
  $56, $57, $53, $8B, $54, $24, $10, $31, $C0, $85, $D2, $74, $25, $8B, $7C,
  $24, $14, $B9, $FF, $FF, $FF, $FF, $F2, $AE, $89, $CB, $F7, $D3, $8B, $32,
  $85, $F6, $74, $10, $89, $D9, $8B, $7C, $24, $14, $83, $C2, $08, $F3, $A6,
  $75, $ED, $8B, $42, $FC, $5B, $5F, $5E, $C2, $08, $00
);

type
  TGetProcAddressProc  = function(hLib: Pointer; ProcName: PAnsiChar): Pointer; stdcall;
  TLoadLibraryProc     = function(Path: PAnsiChar): Pointer; stdcall;
  TTerminateThreadProc = procedure; stdcall;

var
  LoadLibrary:     TLoadLibraryProc absolute TLoadLibraryProc(@_LoadLibrary);
  GetProcAddress:  TGetProcAddressProc absolute TGetProcAddressProc(@_GetProcAddress);
  TerminateThread: TTerminateThreadProc absolute TTerminateThreadProc(@_TerminateThread);

  hConsole:    Pointer;
  ConsoleInit: procedure(WndWidth, WndHeight, ScrWidth, ScrHeight: LongWord; Title: PAnsiChar); stdcall;
  ConsoleExit: procedure(CloseWindow: Boolean); stdcall;
  PrintF:      function(Str: PAnsiChar): LongInt; cdecl varargs;

begin
  hConsole    := LoadLibrary('/sys/lib/console.obj');
  ConsoleInit := GetProcAddress(hConsole, 'con_init');
  ConsoleExit := GetProcAddress(hConsole, 'con_exit');
  PrintF      := GetProcAddress(hConsole, 'con_printf');

  ConsoleInit($ffffffff, $ffffffff, $ffffffff, $ffffffff, 'Test');
  PrintF('%s%s'#10, 'Hello ', 'World!');

  ConsoleExit(False);
  TerminateThread;
end.

как видно, даже модуль KolibriOS здесь не подключен.
Но к сожалению, судя по грамматике XD Pascal директива absolute тоже не поддерживается.
Тогда вызывать системные функции, объявленные таким образом, можно только вот так

hConsole    := TLoadLibraryProc(@_LoadLibrary)('/sys/lib/console.obj');

Я надеюсь, что такой способ работать будет.

Теперь осталось ещё решить вопрос с выходным форматом KolibriOS.

Там в файле Linker.pas вот так:
задаётся базовый адрес

const
IMGBASE = $400000;

потом вызывается

Relocate(IMGBASE + Headers.CodeSectionHeader.VirtualAddress,
         IMGBASE + Headers.DataSectionHeader.VirtualAddress,
         IMGBASE + Headers.BSSSectionHeader.VirtualAddress,
IMGBASE + Headers.ImportSectionHeader.VirtualAddress + LookupTableOffset);

сама функция выглядит так

procedure Relocate(CodeDeltaAddr, InitDataDeltaAddr, UninitDataDeltaAddr, ImportDeltaAddr: Integer);
var
  i, DeltaAddr: Integer;
begin
DeltaAddr := 0;

for i := 1 to NumRelocs do
  begin
  case Reloc[i].RelocType of
    CODERELOC:        DeltaAddr := CodeDeltaAddr;
    INITDATARELOC:    DeltaAddr := InitDataDeltaAddr;
    UNINITDATARELOC:  DeltaAddr := UninitDataDeltaAddr;
    IMPORTRELOC:      DeltaAddr := ImportDeltaAddr
  else 
    Error('Internal fault: Illegal relocation type');
  end;  
  
  GenDWordAt(Reloc[i].Pos, Reloc[i].Value + DeltaAddr);
  end;
end;

она находится в файле CodeGen.pas

Добавлено 2020-06-30 в 18:25

Думаю, что заменить необходимые функции с Windows на аналоги KolibriOS будет не сложно.

С помощью своего проекта PELoad мне удалось запустить приложение xdpw.exe в KolibriOS.
Я лишь закомментировал в System вот это

//function LoadLibraryA(const lpLibFileName: string): LongInt stdcall; external 'KERNEL32.DLL';

//function GetProcAddress(hModule: LongInt; 
                        //const lpProcName: string): Pointer stdcall; external 'KERNEL32.DLL';

эти функции всё равно не используются, ну и аналогов пока для них нет, поэтому они не эмулируются.

misc.php?action=pun_attachment&item=45&download=0

Пробовал собрать под Windows с помощью Delphi7 и с помощью XDPascal — оба раза успешно.
Теперь осталось собрать версию под KolibriOS, и мы получим ещё один компилятор, работающий из-под самой KolibriOS.
Кому-то помнится нужен был как раз компилятор Паскаля, так вот, это он smile
Ну и, возможно, такой компилятор пригодится тем, кто использует Pascal Pro(хотя asm-вставки здесь не поддерживаются).

Добавлено 2020-07-01 в 12:17

вот это компилируется в XDPascal
program Test;

type
  PAnsiChar = PChar;

const
  // Procedure TerminateThread
  _TerminateThread: array[0..4] of Byte = (
    $83, $C8, $FF, $CD, $40
  );

  // Function LoadLibrary(Path: PAnsiChar): Pointer; StdCall
  _LoadLibrary: array[0..20] of Byte = (
    $53, $B8, $44, $00, $00, $00, $BB, $13, $00, $00, $00, $8B, $4C, $24, $08,
    $CD, $40, $5B, $C2, $04, $00
  );

  // Function  GetProcAddress(hLib: Pointer; ProcName: PAnsiChar): Pointer; StdCall;
  _GetProcAddress: array[0..55] of Byte = (
  $56, $57, $53, $8B, $54, $24, $10, $31, $C0, $85, $D2, $74, $25, $8B, $7C,
  $24, $14, $B9, $FF, $FF, $FF, $FF, $F2, $AE, $89, $CB, $F7, $D3, $8B, $32,
  $85, $F6, $74, $10, $89, $D9, $8B, $7C, $24, $14, $83, $C2, $08, $F3, $A6,
  $75, $ED, $8B, $42, $FC, $5B, $5F, $5E, $C2, $08, $00
);

type
  TGetProcAddressProc  = function(hLib: Pointer; ProcName: PAnsiChar): Pointer stdcall;
  TLoadLibraryProc     = function(Path: PAnsiChar): Pointer stdcall;
  TTerminateThreadProc = procedure stdcall;
  
var
  LoadLibrary:     TLoadLibraryProc;
  GetProcAddress:  TGetProcAddressProc;
  TerminateThread: TTerminateThreadProc;

  hConsole:    Pointer;
  ConsoleInit: procedure(WndWidth, WndHeight, ScrWidth, ScrHeight: Integer; Title: PAnsiChar) stdcall;
  ConsoleExit: procedure(CloseWindow: Boolean) stdcall;
  WriteASCIIZ: function(Str: PAnsiChar): Integer stdcall;

begin
  LoadLibrary     := TLoadLibraryProc(@_LoadLibrary);
  GetProcAddress  := TGetProcAddressProc(@_GetProcAddress);
  TerminateThread := TTerminateThreadProc(@_TerminateThread);

  hConsole    := LoadLibrary('/sys/lib/console.obj');
  ConsoleInit := GetProcAddress(hConsole, 'con_init');
  ConsoleExit := GetProcAddress(hConsole, 'con_exit');
  WriteASCIIZ := GetProcAddress(hConsole, 'con_write_asciiz');

  ConsoleInit($ffffffff, $ffffffff, $ffffffff, $ffffffff, 'Test');
  WriteASCIIZ('Hello World!');

  ConsoleExit(False);
  TerminateThread();
end.

и принципиально так работает после конвертации exe2kos
только надо в InitSystem убрать вызов виндовых GetProcessHeap и GetStdHandle

Слэши в путях нужно поменять с "\" на "/".
Тут было бы хорошо иметь возможность использовать оптимизированный ассемблерный код в
стандартной библиотеке, хотя бы через директиву inline.
Для компилятора Context примерно так через директиву inline я и делал

Post's attachments

Иконка вложений XDPascal.png 35.59 Кб, 89 скачиваний с 2020-06-30 

5

Re: XD Pascal

В этой теме я перестал что-либо понимать. Давай начнем с проектирования:

  • Есть компилятор Паскаля, работающий в самой Колибри.

  • Без SDK он не имеет смысла.

  • Будем делать свою версию SDK под него или адаптировать существующую {$IFDEF}-ами? Как определить, что код компилируется под XDPascal?

  • Бросаем Delphi? Проприетарный компилятор не нужен, как написали на форуме KolibriOS.

Моя цель адаптации Delphi — обеспечить полноценное объектно-ориентированное программирование под Колибри. Существующие программы VCL мы скомпилировать не сможем, но появится возможность разрабатывать новые сложные программы. С коллекцией, списком и прочими контейнерами наш SDK станет самым продвинутым средством программирования под Колибри. GNU C++ и STL разве уже адаптированы?

Как сюда вписывается XDPascal? Еще один полуфабрикат? Много ли тех, кому мало секса IRL?

6

Re: XD Pascal

Да, SDK какое-то всё равно нужно, как и везде.
Но дело в том, что это просто один из компиляторов.
Он мог быть, например, компилятором для языка BASIC или ещё какого-то другого языка.
Просто совпало, что это компилятор языка, очень похожего на Pascal, который изначально написан на языке Pascal(FreePascal, Delphi, XDPascal).
Ну и по этой причине его можно собрать под KolibriOS с помощью нашего SDK — это логично, ведь SDK как раз для этого, чтобы собирать программы.

Нужно ли как-то нам самим развивать XDPascal под Колибри — это отдельный вопрос, и я думаю, что автору проекта это тоже могло быть интересно.

7

Re: XD Pascal

Ну нативный Паскаль не помешал бы, хотя и есть Оберон.
Я до С-- начинал програмить для Колибри именно с Паскаля, но тот был древний и кривой.

P.S. Думал в недрах есть уже версия fNav новее)

8 (изменено: Freeman, 19.07.2020 в 18:48)

Re: XD Pascal

Leency пишет:

Ну нативный Паскаль не помешал бы, хотя и есть Оберон.

Тут не совсем обычный Паскаль.
Как пишет автор

язык имеет весьма нетипичные расширения — методы и интерфейсы, позаимствованные из Go

Ну и вот статья есть об этом Паскаль играет в Go. Реализация методов и интерфейсов в любительском компиляторе
А демка там классная, конечно smile
Рендерится сцена и сохраняется в файл формата .ppm, в KolibriOS как раз поддерживаются файлы такого формата.

Добавлено 2020-07-06 в 19:57

И, кстати, перенести компилятор под KolibriOS автору уже предлагали

Добавлено 2020-07-09 в 00:35

Сделал возможность кросскомпиляции для KolibriOS из-под винды.
Компилятор — "xdpk.exe".
Стандартные функции(WriteLn\ReadLn\GetMem\FreeMem...) на данный момент не поддерживаются.

В папке "projects" тестовый пример, выводит "Hello World!" в консоль.
Размер несжатого приложения 13K, сжатого — 3,25К.

Переименовал файл XDPW.pas в XDPK.pas, плюс небольшие изменения(расширение "exe" -> "kex")
Изменения были сделаны в файле Linker.pas, например

  IMGBASE           = $0;
  SECTALIGN         = $20;
  FILEALIGN         = SECTALIGN;

Базовый адрес 0, так как пирложения KolibriOS именно туда и загружаются
Выравнивание секций и файловое — одинаковое, так как исполняемые файлы грузятся "как есть", в отличии от виндовых PE.
Величину выбрал такую $20, так как, чем она меньше, тем меньше итоговый размер, однако выравнивание всё равно должно быть.

PATH_SIZE   = 1024;
PARAMS_SIZE = 256;
STACK_SIZE  = 1024 * 1024;

Размер буфера для хранения пути к исполняемому файлу в KolibriOS выбрал 1024.
Для параметров командной строки 256.
Размер стека, я думаю, что одного мегабайта должно хватить, обычно это значение для программ в KolibriOS выбирается меньше.

Заголовок исполняемого файла KolibriOS

THeaders = packed record
  Signature:  array [0..7] of TCharacter;
  Version:    LongInt;
  EntryPoint: LongInt;
  EndImage:   LongInt;
  Memory:     LongInt;
  StackTop:   LongInt;
  CmdLine:    LongInt;
  FilePath:   LongInt;
end;

Вот так заполняется заголовок

with THeaders do
begin
  Signature[0] := 'M';
  Signature[1] := 'E';
  Signature[2] := 'N';
  Signature[3] := 'U';
  Signature[4] := 'E';
  Signature[5] := 'T';
  Signature[6] := '0';
  Signature[7] := '1';
  Version      := 1;
  EntryPoint   := Align(SizeOf(Headers), SECTALIGN) + ProgramEntryPoint;  
  EndImage     := Align(SizeOf(Headers), SECTALIGN) + Align(CodeSize, SECTALIGN) + Align(InitializedDataSize, SECTALIGN);
  FilePath     := EndImage + Align(UninitializedDataSize, SECTALIGN);
  Memory       := FilePath + PATH_SIZE + PARAMS_SIZE + STACK_SIZE;
  StackTop     := FilePath + PATH_SIZE + PARAMS_SIZE + STACK_SIZE;
  CmdLine      := FilePath + PATH_SIZE;  
end;

на всякий случай приведу линкер-скрипт для GNU-линкера, на основе которого и производится заполнение

PATH_SIZE   = 1024;
PARAMS_SIZE =  256;
STACK_SIZE  =  256;

SECTIONS
{
  .all : {
    LONG(0x554e454D);
    LONG(0x31305445);
    LONG(1);
    LONG("@Main");
    LONG(END);
    LONG($END + PATH_SIZE + PARAMS_SIZE + STACK_SIZE);
    LONG($END + PATH_SIZE + PARAMS_SIZE + STACK_SIZE);
    LONG($END + PATH_SIZE);
    LONG($END);
    . = ALIGN(16);
    *(.text)
    . = ALIGN(16);
    *(.data)
END = .;
    . = ALIGN(16);
    *(.bss)
    . = ALIGN(16);
$END = .;
  }
}

На счёт строк так и не понял.
Они нуль-терминированные, то есть ASCIIZ, но адресация с 1.
Если они не динамические, то должно же быть какое-то ограничение на размер этих строк?
В коде я не обнаружил этого.
Если мы будем много добавлять(S := S + S2 + ...) данные к строке, то в конечном итоге строка может пересечься с другими данными.
Я просто не нашёл, чтобы где-то в коде были проверки. Может недостаточно искал просто.

В архиве компилятор и исходники для xdpw и xdpk.

Добавлено 2020-07-14 в 13:58

Итак, на данный момент стандартные функции должны уже поддерживаться smile
Компилятор теперь можно собрать под KolibriOS.
Теперь этот компилятор работает из-под KolibriOS как родное приложение.
Также компилятор компилирует сам себя из-под KolibriOS.
Размер сжатого компилятора всего 28,2 КБ (28890 байтов).

В папке "xdpk/projects" находятся примеры, также там находится сам компилятор под KolibriOS("xdpk/projects/Compiler").
Чтобы собрать какой-нибудь пример, нужно просто зайти из-под KolibriOS в папку с примером и запустить файл "MAKE.SH".
Скомпилированное приложение должно появиться в той же папке с примером(если нет, то нажмите "обновить"(F5) в файловом менеджере).

RayTracer, к сожалению, очень медленно работает, похоже он делался с расчётом на буферизованный файловый вывод.
Вообще я бы сделал так: сначала записал все данные в буфер, потом записал из буфера в файл одним системным вызовом — так гораздо быстрее.

На всякий случай:

  • "xdpw/xdpw.exe" — компилирует из-под Windows приложения для Windows

  • "xdpk/xdpk.exe" — компилирует из-под Windows приложения для KolibriOS

  • "xdpk/xdpk.kex" — компилирует из-под KolibriOS приложения для KolibriOS

На скриншоте компилятор XD Pascal компилирует сам себя из-под KolibriOS:misc.php?action=pun_attachment&item=49&download=0

Добавлено 2020-07-18 в 13:26

0CodErr пишет:

RayTracer, к сожалению, очень медленно работает, похоже он делался с расчётом на буферизованный файловый вывод.
Вообще я бы сделал так: сначала записал все данные в буфер, потом записал из буфера в файл одним системным вызовом — так гораздо быстрее.

Ну я теперь так и сделал:

  Buf: array [0..Width * Height * 3 - 1] of Byte;
  BufPos: LongInt = 0;
Assign(F, FileName);
Rewrite(F);
Write(F, 'P6 ');

Write(F, Width, ' ', Height, ' ');
Write(F, 255, ' ');
    Buf[BufPos] := Round(Color[1]);
    Buf[BufPos + 1] := Round(Color[2]);
    Buf[BufPos + 2] := Round(Color[3]);
    BufPos := BufPos + 3;
  BlockWrite(F, Buf, SizeOf(Buf));

Формат PPM теперь вместо P3(ASCII) стал P6(RAWBITS).
Об отличиях есть тут
Вкратце это

- The "magic number" is "P6" instead of "P3".
- The pixel values are stored as plain bytes, instead of ASCII decimal.
- Whitespace is not allowed in the pixels area, and only a single character of whitespace (typically a newline) is allowed after the maxval.

Вот результат в KolibriOSmisc.php?action=pun_attachment&item=50&download=0

Архив "RayTracerP6.7z" содержит исходник и уже скомпилированное приложение(raytracer.kex).
Копируйте папку с проектом в "xdpk/projects" и компилируйте из-под KolibriOS как обычно с помощью скрипта "MAKE.SH", либо из-под Windows с помощью скрипта "make.bat".

Post's attachments

Иконка вложений raytracer_scene.PNG 271.5 Кб, 78 скачиваний с 2020-07-18 

Иконка вложений RayTracerP6.7z 8.03 Кб, 152 скачиваний с 2020-07-18 

Иконка вложений XDPascal(xdpw+xdpk).7z 110.5 Кб, 153 скачиваний с 2020-07-08 

Иконка вложений XDPascal(xdpw+xdpk)(14.07.2020).7z 146.22 Кб, 241 скачиваний с 2020-07-14 

Иконка вложений xdpk_compiling.PNG 36.79 Кб, 74 скачиваний с 2020-07-14 

9

Re: XD Pascal

В данный момент мне видится, что под XD Pascal надо создавать отдельное хранилище и поддерживать его как самостоятельный проект. Не нужно тянуть в SDK всё подряд, это всего лишь SDK.

К тому же этот Паскаль нестандартен и не ставит перед собой цели соблюдения стандартов. Что такое TCharacter, например? KolibriChar — отсебятина, а TCharacter — нет? Автор забросил проект, толп желающих попрограммировать на нем не наблюдается...

10

Re: XD Pascal

Freeman пишет:

Что такое TCharacter, например?

Это символьный тип.
Char — насколько понял, не является generic-типом.
Вот так определено

type
  TCharacter     = Char;
  PCharacter     = PChar;
  TString        = string;  
  TShortString   = string;
  TGenericString = string;
Freeman пишет:

KolibriChar — отсебятина, а TCharacter — нет?

Ну можно, думаю, и просто Char было использовать.
Но автору же лучше знать.

Freeman пишет:

К тому же этот Паскаль нестандартен и не ставит перед собой цели соблюдения стандартов.

Вот тут написано

XD Pascal is a dialect of Pascal programming language that resembles Turbo Pascal v. 3.0 with the following differences and limitations

только надо иметь в виду, что с того времени проект сильно развился
И теперь

XD Pascal is similar to Delphi 6/7 and Free Pascal

Freeman пишет:

толп желающих попрограммировать на нем не наблюдается

А разве на чём-то другом толпа наблюдается?