Subversion Repositories Kolibri OS

Rev

Rev 7623 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7623 akron1 1
Компилятор языка программирования Oberon-07/16 для i486
2
                Windows/Linux/KolibriOS.
3
------------------------------------------------------------------------------
4
 
5
        Параметры командной строки
6
 
7
  Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или
8
UTF-8 с BOM-сигнатурой.
9
  Выход - испоняемый файл формата PE32, ELF или MENUET01/MSCOFF.
10
  Параметры:
11
  1) имя главного модуля
12
  2) имя результирующего файла
13
  3) тип приложения и платформа
14
      "console" - Windows console
15
      "gui" - Windows GUI
16
      "dll" - Windows DLL
17
      "kos" - KolibriOS
18
      "obj" - KolibriOS DLL
19
      "elfexe" - Linux ELF-EXEC
7693 akron1 20
      "elfso"  - Linux ELF-SO
7623 akron1 21
  4) необязательные параметры-ключи
22
      -stk  размер стэка в мегабайтах (по умолчанию 2 Мб)
23
      -base 
адрес загрузки исполняемого файла в килобайтах
24
      -ver  версия программы (только для obj)
25
      -nochk <"ptibcwra"> отключить проверки при выполнении (см. ниже)
26
 
27
      параметр -nochk задается в виде строки из символов:
28
      "p" - указатели
29
      "t" - типы
30
      "i" - индексы
31
      "b" - неявное приведение INTEGER к BYTE
32
      "c" - диапазон аргумента функции CHR
33
      "w" - диапазон аргумента функции WCHR
34
      "r" - эквивалентно "bcw"
35
      "a" - все проверки
36
 
37
      Порядок символов может быть любым. Наличие в строке того или иного
38
      символа отключает соответствующую проверку.
39
 
40
      Например: -nochk it - отключить проверку индексов и охрану типа.
41
      -nochk a - отключить все отключаемые проверки.
42
 
43
  Например:
44
 
45
  Compiler.exe "C:\example.ob07" "C:\example.exe" console -stk 1
46
  Compiler.exe "C:\example.ob07" "C:\example.dll" dll
47
  Compiler.exe "C:\example.ob07" "C:\example.exe" gui -stk 4
48
  Compiler.exe "C:\example.ob07" "C:\example.exe" console -nochk pti
49
  Compiler.kex "/tmp0/1/example.ob07" "/tmp0/1/example.kex" kos -stk 2
50
  Compiler.kex "/tmp0/1/example.ob07" "/tmp0/1/example.obj" obj -ver 2.7
51
  Compiler.exe "C:\example.ob07" "C:\example" elfexe
52
 
53
  В случае успешной компиляции, компилятор передает код завершения 0, иначе 1.
54
При работе компилятора в KolibriOS, код завершения не передается.
55
 
56
------------------------------------------------------------------------------
57
        Отличия от оригинала
58
 
59
1.      Расширен псевдомодуль SYSTEM
60
2.      В идентификаторах допускается символ "_"
61
3.      Добавлены системные флаги
62
4.      Усовершенствован оператор CASE (добавлены константные выражения в
63
        метках вариантов и необязательная ветка ELSE)
64
5.      Расширен набор стандартных процедур
65
6.      Семантика охраны/проверки типа уточнена для нулевого указателя
66
7.      Семантика DIV и MOD уточнена для отрицательных чисел
67
8.      Добавлены однострочные комментарии (начинаются с пары символов "//")
68
9.      Разрешено наследование от типа-указателя
69
10.     Добавлен синтаксис для импорта процедур из внешних библиотек
70
11.     "Строки" можно заключать также в одиночные кавычки: 'строка'
71
12.     Добавлен тип WCHAR
72
 
73
------------------------------------------------------------------------------
74
        Особенности реализации
75
 
76
1.      Основные типы
77
 
78
          Тип              Диапазон значений               Размер, байт
79
 
80
        INTEGER       -2147483648 .. 2147483647                 4
81
        REAL          4.94E-324 .. 1.70E+308                    8
82
        CHAR          символ ASCII (0X .. 0FFX)                 1
83
        BOOLEAN       FALSE, TRUE                               1
84
        SET           множество из целых чисел {0 .. 31}        4
85
        BYTE          0 .. 255                                  1
86
        WCHAR         символ юникода (0X .. 0FFFFX)             2
87
 
88
2.      Максимальная длина идентификаторов - 1024 символов
89
3.      Максимальная длина строковых констант - 1024 символов (UTF-8)
90
4.      Максимальная размерность открытых массивов - 5
91
5.      Процедура NEW заполняет нулями выделенный блок памяти
92
6.      Глобальные и локальные переменные инициализируются нулями
93
7.      В отличие от многих Oberon-реализаций, сборщик мусора и динамическая
94
        модульность отсутствуют
95
8.      Тип BYTE в выражениях всегда приводится к INTEGER
96
9.      Контроль переполнения значений выражений не производится
97
10.     Ошибки времени выполнения:
98
 
99
        - ASSERT(x), при x = FALSE
100
        - разыменование нулевого указателя
101
        - целочисленное деление на 0
102
        - вызов процедуры через процедурную переменную с нулевым значением
103
        - ошибка охраны типа
104
        - нарушение границ массива
105
        - непредусмотренное значение выражения в операторе CASE
106
        - ошибка копирования массивов v := x, если LEN(v) < LEN(x)
107
        - неявное приведение x:INTEGER к v:BYTE, если (x < 0) OR (x > 255)
108
        - CHR(x), если (x < 0) OR (x > 255)
109
        - WCHR(x), если (x < 0) OR (x > 65535)
110
 
111
------------------------------------------------------------------------------
112
        Псевдомодуль SYSTEM
113
 
114
  Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры,
115
ошибки при использовании процедур псевдомодуля SYSTEM могут привести к
116
повреждению данных времени выполнения и аварийному завершению программы.
117
 
118
        PROCEDURE ADR(v: любой тип): INTEGER
119
                v - переменная или процедура;
120
                возвращает адрес v
121
 
122
        PROCEDURE SADR(x: строковая константа (CHAR UTF-8)): INTEGER
123
                возвращает адрес x
124
 
125
        PROCEDURE WSADR(x: строковая константа (WCHAR)): INTEGER
126
                возвращает адрес x
127
 
128
        PROCEDURE SIZE(T): INTEGER
129
                возвращает размер типа T
130
 
131
        PROCEDURE TYPEID(T): INTEGER
132
                T - тип-запись или тип-указатель,
133
                возвращает номер типа в таблице типов-записей
134
 
135
        PROCEDURE INF(): REAL
136
                возвращает специальное вещественное значение "бесконечность"
137
 
138
        PROCEDURE GET(a: INTEGER;
139
                VAR v: любой основной тип, PROCEDURE, POINTER)
140
                v := Память[a]
141
 
142
        PROCEDURE PUT(a: INTEGER; x: любой основной тип, PROCEDURE, POINTER)
143
                Память[a] := x;
144
                Если x: BYTE или x: WCHAR, то значение x будет расширено
145
                до 32 бит, для записи байтов использовать SYSTEM.PUT8,
146
                для WCHAR -- SYSTEM.PUT16
147
 
7693 akron1 148
        PROCEDURE PUT8(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR)
7623 akron1 149
                Память[a] := младшие 8 бит (x)
150
 
7693 akron1 151
        PROCEDURE PUT16(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR)
7623 akron1 152
                Память[a] := младшие 16 бит (x)
153
 
154
        PROCEDURE MOVE(Source, Dest, n: INTEGER)
155
                Копирует n байт памяти из Source в Dest,
156
                области Source и Dest не могут перекрываться
157
 
158
        PROCEDURE COPY(VAR Source: любой тип; VAR Dest: любой тип; n: INTEGER)
159
                Копирует n байт памяти из Source в Dest.
160
                Эквивалентно
161
                SYSTEM.MOVE(SYSTEM.ADR(Source), SYSTEM.ADR(Dest), n)
162
 
163
        PROCEDURE CODE(byte1, byte2,... : INTEGER)
164
                Вставка машинного кода,
165
                byte1, byte2 ... - константы в диапазоне 0..255,
166
                например:
167
                SYSTEM.CODE(08BH, 045H, 008H) (* mov eax, dword [ebp + 08h] *)
168
 
169
  Также в модуле SYSTEM определен тип CARD16 (2 байта). Для типа CARD16 не
170
допускаются никакие явные операции, за исключением присваивания.
171
Преобразования CARD16 -> INTEGER и INTEGER -> CARD16 могут быть реализованы
172
так:
173
 
174
        PROCEDURE Card16ToInt (w: SYSTEM.CARD16): INTEGER;
175
        VAR i: INTEGER;
176
        BEGIN
177
            SYSTEM.PUT(SYSTEM.ADR(i), w)
178
            RETURN i
179
        END Card16ToInt;
180
 
181
        PROCEDURE IntToCard16 (i: INTEGER): SYSTEM.CARD16;
182
        VAR w: SYSTEM.CARD16;
183
        BEGIN
184
            SYSTEM.GET(SYSTEM.ADR(i), w)
185
            RETURN w
186
        END IntToCard16;
187
 
188
  Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
189
 
190
------------------------------------------------------------------------------
191
        Системные флаги
192
 
193
  При объявлении процедурных типов и глобальных процедур, после ключевого
194
слова PROCEDURE может быть указан флаг соглашения о вызове: [stdcall],
195
[ccall], [ccall16], [windows], [linux]. Например:
196
 
197
        PROCEDURE [ccall] MyProc (x, y, z: INTEGER): INTEGER;
198
 
199
  Если указан флаг [ccall16], то принимается соглашение ccall, но перед
200
вызовом указатель стэка будет выравнен по границе 16 байт.
201
  Флаг [windows] - синоним для [stdcall], [linux] - синоним для [ccall16].
202
  Знак "-" после имени флага ([stdcall-], [linux-], ...) означает, что
203
результат процедуры можно игнорировать (не допускается для типа REAL).
204
 
205
  При объявлении типов-записей, после ключевого слова RECORD может быть
206
указан флаг [noalign]. Флаг [noalign] означает отсутствие выравнивания полей
207
записи. Записи с системным флагом не могут иметь базовый тип и не могут быть
208
базовыми типами для других записей.
209
  Для использования системных флагов, требуется импортировать SYSTEM.
210
 
211
------------------------------------------------------------------------------
212
        Оператор CASE
213
 
214
  Синтаксис оператора CASE:
215
 
216
        CaseStatement =
217
                CASE Expression OF Сase {"|" Сase}
218
                        [ELSE StatementSequence] END.
219
        Case = [CaseLabelList ":" StatementSequence].
220
        CaseLabelList = CaseLabels {"," CaseLabels}.
221
        CaseLabels = ConstExpression [".." ConstExpression].
222
 
223
  Например:
224
 
225
        CASE x OF
226
        |-1:    DoSomething1
227
        | 1:    DoSomething2
228
        | 0:    DoSomething3
229
        ELSE
230
                DoSomething4
231
        END
232
 
233
  В метках вариантов можно использовать константные выражения, ветка ELSE
234
необязательна. Если значение x не соответствует ни одному варианту и ELSE
235
отсутствует, то программа прерывается с ошибкой времени выполнения.
236
 
237
------------------------------------------------------------------------------
238
        Тип WCHAR
239
 
240
  Тип WCHAR добавлен в язык для удобной поддежки юникода. Для типов WCHAR и
241
ARRAY OF WCHAR допускаются все те же операции, как для типов CHAR и
242
ARRAY OF CHAR, за исключением встроенной процедуры CHR, которая возвращает
243
только тип CHAR. Для получения значения типа WCHAR, следует использовать
244
процедуру WCHR вместо CHR. Для правильной работы с типом, необходимо сохранять
245
исходный код в кодировке UTF-8 c BOM.
246
 
247
------------------------------------------------------------------------------
248
        Проверка и охрана типа нулевого указателя
249
 
250
  Оригинальное сообщение о языке не определяет поведение программы при
251
выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих
252
Oberon-реализациях выполнение такой операции приводит к ошибке времени
253
выполнения. В данной реализации охрана типа нулевого указателя не приводит к
254
ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет
255
значительно сократить частоту применения охраны типа.
256
 
257
------------------------------------------------------------------------------
258
        Дополнительные стандартные процедуры
259
 
260
        DISPOSE (VAR v: любой_указатель)
261
                Освобождает память, выделенную процедурой NEW для
262
                динамической переменной v^, и присваивает переменной v
263
                значение NIL.
264
 
265
        COPY (x: ARRAY OF CHAR/WCHAR; VAR v: ARRAY OF CHAR/WCHAR);
266
                v := x;
267
                Если LEN(v) < LEN(x), то строка x будет скопирована
268
                не полностью
269
 
270
        LSR (x, n: INTEGER): INTEGER
271
                Логический сдвиг x на n бит вправо.
272
 
273
        MIN (a, b: INTEGER): INTEGER
274
                Минимум из двух значений.
275
 
276
        MAX (a, b: INTEGER): INTEGER
277
                Максимум из двух значений.
278
 
279
        BITS (x: INTEGER): SET
280
                Интерпретирует x как значение типа SET.
281
                Выполняется на этапе компиляции.
282
 
283
        LENGTH (s: ARRAY OF CHAR/WCHAR): INTEGER
284
                Длина 0X-завершенной строки s, без учета символа 0X.
285
                Если символ 0X отсутствует, функция возвращает длину
286
                массива s. s не может быть константой.
287
 
288
        WCHR (n: INTEGER): WCHAR
289
                Преобразование типа, аналогично CHR(n: INTEGER): CHAR
290
 
291
------------------------------------------------------------------------------
292
        DIV и MOD
293
 
294
         x         y      x DIV y   x MOD y
295
 
296
         5         3         1         2
297
        -5         3        -2         1
298
         5        -3        -2        -1
299
        -5        -3         1        -2
300
 
301
------------------------------------------------------------------------------
302
        Импортированные процедуры
303
 
304
  Синтаксис импорта:
305
 
306
  PROCEDURE [callconv, "library", "function"] proc_name (FormalParam): Type;
307
 
308
  - callconv -- соглашение о вызове
309
  - "library" -- имя файла динамической библиотеки
310
  - "function" -- имя импортируемой процедуры
311
 
312
  например:
313
 
314
  PROCEDURE [windows, "kernel32.dll", "ExitProcess"] exit (code: INTEGER);
315
 
316
  PROCEDURE [stdcall, "Console.obj", "con_exit"] exit (bCloseWindow: BOOLEAN);
317
 
318
  В конце объявления может быть добавлено (необязательно) "END proc_name;"
319
 
320
  Объявления импортированных процедур должны располагаться в глобальной
321
  области видимости модуля после объявления переменных, вместе с объявлением
322
  "обычных" процедур, от которых импортированные отличаются только отсутствием
323
  тела процедуры. В остальном, к таким процедурам применимы те же правила:
324
  их можно вызвать, присвоить процедурной переменной или получить адрес.
325
 
326
  Так как импортированная процедура всегда имеет явное указание соглашения о
327
  вызове, то совместимый процедурный тип тоже должен быть объявлен с указанием
328
  соглашения о вызове:
329
 
330
  VAR
331
      ExitProcess: PROCEDURE [windows] (code: INTEGER);
332
      con_exit:    PROCEDURE [stdcall] (bCloseWindow: BOOLEAN);
333
 
334
  В KolibriOS импортировать процедуры можно только из библиотек, размещенных
335
  в /rd/1/lib. Импортировать и вызывать функции инициализации библиотек
336
  (lib_init, START) при этом не нужно.
337
 
338
  Для Linux, импортированные процедуры не реализованы.
339
 
340
------------------------------------------------------------------------------
341
        Скрытые параметры процедур
342
 
343
  Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке
344
формальных параметров, но учитываются компилятором при трансляции вызовов.
345
Это возможно в следующих случаях:
346
 
347
1.      Процедура имеет формальный параметр открытый массив:
348
                PROCEDURE Proc (x: ARRAY OF ARRAY OF REAL);
349
        Вызов транслируется так:
350
                Proc(LEN(x), LEN(x[0]), SYSTEM.ADR(x))
351
2.      Процедура имеет формальный параметр-переменную типа RECORD:
352
                PROCEDURE Proc (VAR x: Rec);
353
        Вызов транслируется так:
354
                Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x))
355
 
356
------------------------------------------------------------------------------
357
        Модуль RTL
358
 
359
  Все программы неявно используют модуль RTL. Компилятор транслирует
360
некоторые операции (проверка и охрана типа, сравнение строк, сообщения об
361
ошибках времени выполнения и др.) как вызовы процедур этого модуля. Не
7693 akron1 362
следует явно вызывать эти процедуры, за исключением процедур SetDll и SetFini
363
если приложение компилируется как Windows DLL или Linux SO, соответственно:
7623 akron1 364
 
365
        PROCEDURE SetDll
366
            (process_detach, thread_detach, thread_attach: DLL_ENTRY);
367
        где TYPE DLL_ENTRY =
368
            PROCEDURE (hinstDLL, fdwReason, lpvReserved: INTEGER);
369
 
370
SetDll назначает процедуры process_detach, thread_detach, thread_attach
371
вызываемыми при
372
- выгрузке dll-библиотеки (process_detach)
373
- создании нового потока (thread_attach)
374
- уничтожении потока (thread_detach)
375
 
7693 akron1 376
 
377
        PROCEDURE SetFini (ProcFini: PROC);
378
        где TYPE PROC = PROCEDURE (* без параметров *)
379
 
380
SetFini назначает процедуру ProcFini вызываемой при выгрузке so-библиотеки.
381
 
382
Для прочих типов приложений, вызов процедур SetDll и SetFini не влияет на
7623 akron1 383
поведение программы.
7693 akron1 384
 
7623 akron1 385
  Сообщения об ошибках времени выполнения выводятся в диалоговых окнах
386
(Windows), в терминал (Linux), на доску отладки (KolibriOS).
387
 
388
------------------------------------------------------------------------------
389
        Модуль API
390
 
391
  Существуют несколько реализаций модуля API (для различных ОС).
392
  Как и модуль RTL, модуль API не предназначен для прямого использования.
393
Он обеспечивает связь RTL с ОС.
394
 
395
------------------------------------------------------------------------------
396
        Генерация исполняемых файлов DLL
397
 
398
  Разрешается экспортировать только процедуры. Для этого, процедура должна
399
находиться в главном модуле программы, и ее имя должно быть отмечено символом
400
экспорта ("*"). KolibriOS DLL всегда экспортируют идентификаторы "version"
401
(версия программы) и "lib_init" - адрес процедуры инициализации DLL:
402
 
403
        PROCEDURE [stdcall] lib_init (): INTEGER
404
 
405
Эта процедура должна быть вызвана перед использованием DLL.
7693 akron1 406
Процедура всегда возвращает 1.