| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- Компилятор языка программирования 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 Мб)
- -tab <width> размер табуляции (используется для вычисления координат в
- исходном коде), по умолчанию - 4
- -nochk <"ptibcwra"> отключить проверки при выполнении (см. ниже)
- -lower разрешить ключевые слова и встроенные идентификаторы в
- нижнем регистре (по умолчанию)
- -upper только верхний регистр для ключевых слов и встроенных
- идентификаторов
- -def <имя> задать символ условной компиляции
- -ver <major.minor> версия программы (только для kosdll)
- -uses вывести список импортированных модулей
- -fa <size> выравнивание секций файла PE32 в байтах, возможные значения:
- 512, 1024, 2048, 4096. По умолчанию - 512
- параметр -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
- 12. Добавлена операция конкатенации строковых и символьных констант
- 13. Возможен импорт модулей с указанием пути и имени файла
- 14. Добавлен специальный синтаксис для условной компиляции (см. CC.txt)
- 15. Имя процедуры в конце объявления (после END) необязательно
- 16. Разрешено использовать нижний регистр для ключевых слов
- ------------------------------------------------------------------------------
- Особенности реализации
- 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. Максимальная длина идентификаторов - 255 символов
- 3. Максимальная длина строковых констант - 511 символов (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 VAL(v: любой тип; T): T
- v - переменная;
- интерпретирует v, как переменную типа T
- PROCEDURE SIZE(T): INTEGER
- возвращает размер типа T
- PROCEDURE TYPEID(T): INTEGER
- T - тип-запись или тип-указатель,
- возвращает номер типа в таблице типов-записей
- PROCEDURE INF(): REAL
- возвращает специальное вещественное значение "бесконечность"
- PROCEDURE MOVE(Source, Dest, n: INTEGER)
- Копирует n байт памяти из Source в Dest,
- области Source и Dest не могут перекрываться
- PROCEDURE GET(a: INTEGER;
- VAR v: любой основной тип, PROCEDURE, POINTER)
- v := Память[a]
- PROCEDURE GET8(a: INTEGER;
- VAR x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
- Эквивалентно
- SYSTEM.MOVE(a, SYSTEM.ADR(x), 1)
- PROCEDURE GET16(a: INTEGER;
- VAR x: INTEGER, SET, WCHAR, SYSTEM.CARD32)
- Эквивалентно
- SYSTEM.MOVE(a, SYSTEM.ADR(x), 2)
- PROCEDURE GET32(a: INTEGER; VAR x: INTEGER, SET, SYSTEM.CARD32)
- Эквивалентно
- SYSTEM.MOVE(a, SYSTEM.ADR(x), 4)
- 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, SYSTEM.CARD32)
- Память[a] := младшие 8 бит (x)
- PROCEDURE PUT16(a: INTEGER;
- x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
- Память[a] := младшие 16 бит (x)
- PROCEDURE PUT32(a: INTEGER;
- x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
- Память[a] := младшие 32 бит (x)
- 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 определен тип CARD32 (4 байта). Для типа CARD32 не
- допускаются никакие явные операции, за исключением присваивания.
- Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
- ------------------------------------------------------------------------------
- Системные флаги
- При объявлении процедурных типов и глобальных процедур, после ключевого
- слова PROCEDURE может быть указан флаг соглашения о вызове: [stdcall],
- [cdecl], [fastcall], [ccall], [windows], [linux], [oberon]. Например:
- PROCEDURE [ccall] MyProc (x, y, z: INTEGER): INTEGER;
- Если указан флаг [ccall], то принимается соглашение cdecl, но перед
- вызовом указатель стэка будет выравнен по границе 16 байт.
- Флаг [windows] - синоним для [stdcall], [linux] - синоним для [ccall].
- Знак "-" после имени флага ([stdcall-], [linux-], ...) означает, что
- результат процедуры можно игнорировать (не допускается для типа REAL).
- Если флаг не указан или указан флаг [oberon], то принимается внутреннее
- соглашение о вызове.
- При объявлении типов-записей, после ключевого слова RECORD может быть
- указан флаг [noalign]. Флаг [noalign] означает отсутствие выравнивания полей
- записи. Записи с системным флагом не могут иметь базовый тип и не могут быть
- базовыми типами для других записей.
- Для использования системных флагов, требуется импортировать SYSTEM.
- ------------------------------------------------------------------------------
- Оператор CASE
- Синтаксис оператора CASE:
- CaseStatement =
- CASE Expression OF Case {"|" Case}
- [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 с BOM.
- ------------------------------------------------------------------------------
- Конкатенация строковых и символьных констант
- Допускается конкатенация ("+") константных строк и символов типа CHAR:
- str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
- newline = 0DX + 0AX;
- ------------------------------------------------------------------------------
- Проверка и охрана типа нулевого указателя
- Оригинальное сообщение о языке не определяет поведение программы при
- выполнении охраны 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
- ------------------------------------------------------------------------------
- Импорт модулей с указанием пути и имени файла
- Примеры:
- IMPORT Math IN "./lib/math.ob07"; (* относительно текущего модуля *)
- IMPORT M1 IN "C:\lib\math.ob07"; (* абсолютный путь *)
- ------------------------------------------------------------------------------
- Импортированные процедуры
- Синтаксис импорта:
- PROCEDURE [callconv, library, function] proc_name (FormalParam): Type;
- - callconv -- соглашение о вызове
- - library -- имя файла динамической библиотеки (строковая константа)
- - function -- имя импортируемой процедуры (строковая константа), если
- указана пустая строка, то имя процедуры = proc_name
- например:
- PROCEDURE [windows, "kernel32.dll", ""] ExitProcess (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 импортировать процедуры можно только из библиотек, размещенных
- в /sys/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
- Разрешается экспортировать только процедуры. Для этого, процедура должна
- находиться в главном модуле программы, и ее имя должно быть отмечено символом
- экспорта ("*"). Нельзя экспортировать процедуры, которые импортированы из
- других dll-библиотек.
- KolibriOS DLL всегда экспортируют идентификаторы "version" (версия
- программы) и "lib_init" - адрес процедуры инициализации DLL:
- PROCEDURE [stdcall] lib_init (): INTEGER
- Эта процедура должна быть вызвана перед использованием DLL.
- Процедура всегда возвращает 1.
|