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