forked from KolibriOS/kolibrios
fix autobuild
git-svn-id: svn://kolibrios.org@8099 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
df0d0be7d4
commit
7de0c0e61c
@ -25,9 +25,6 @@ UTF-8 с BOM-сигнатурой.
|
||||
-stk <size> размер стэка в мегабайтах (по умолчанию 2 Мб,
|
||||
допустимо от 1 до 32 Мб)
|
||||
-nochk <"ptibcwra"> отключить проверки при выполнении (см. ниже)
|
||||
-lower разрешить ключевые слова и встроенные идентификаторы в
|
||||
нижнем регистре
|
||||
-def <имя> задать символ условной компиляции
|
||||
-ver <major.minor> версия программы (только для kosdll)
|
||||
|
||||
параметр -nochk задается в виде строки из символов:
|
||||
@ -74,7 +71,6 @@ UTF-8 с BOM-сигнатурой.
|
||||
9. Добавлен синтаксис для импорта процедур из внешних библиотек
|
||||
10. "Строки" можно заключать также в одиночные кавычки: 'строка'
|
||||
11. Добавлен тип WCHAR
|
||||
12. Добавлена операция конкатенации строковых и символьных констант
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Особенности реализации
|
||||
@ -141,45 +137,25 @@ UTF-8 с BOM-сигнатурой.
|
||||
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)
|
||||
PROCEDURE PUT8(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR)
|
||||
Память[a] := младшие 8 бит (x)
|
||||
|
||||
PROCEDURE PUT16(a: INTEGER;
|
||||
x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
|
||||
PROCEDURE PUT16(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR)
|
||||
Память[a] := младшие 16 бит (x)
|
||||
|
||||
PROCEDURE PUT32(a: INTEGER;
|
||||
x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
|
||||
Память[a] := младшие 32 бит (x)
|
||||
PROCEDURE MOVE(Source, Dest, n: INTEGER)
|
||||
Копирует n байт памяти из Source в Dest,
|
||||
области Source и Dest не могут перекрываться
|
||||
|
||||
PROCEDURE COPY(VAR Source: любой тип; VAR Dest: любой тип; n: INTEGER)
|
||||
Копирует n байт памяти из Source в Dest.
|
||||
@ -192,8 +168,6 @@ UTF-8 с BOM-сигнатурой.
|
||||
например:
|
||||
SYSTEM.CODE(08BH, 045H, 008H) (* mov eax, dword [ebp + 08h] *)
|
||||
|
||||
Также, в модуле SYSTEM определен тип CARD32 (4 байта). Для типа CARD32 не
|
||||
допускаются никакие явные операции, за исключением присваивания.
|
||||
|
||||
Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
|
||||
|
||||
@ -202,7 +176,7 @@ UTF-8 с BOM-сигнатурой.
|
||||
|
||||
При объявлении процедурных типов и глобальных процедур, после ключевого
|
||||
слова PROCEDURE может быть указан флаг соглашения о вызове: [stdcall],
|
||||
[ccall], [ccall16], [windows], [linux], [oberon]. Например:
|
||||
[ccall], [ccall16], [windows], [linux]. Например:
|
||||
|
||||
PROCEDURE [ccall] MyProc (x, y, z: INTEGER): INTEGER;
|
||||
|
||||
@ -211,8 +185,6 @@ UTF-8 с BOM-сигнатурой.
|
||||
Флаг [windows] - синоним для [stdcall], [linux] - синоним для [ccall16].
|
||||
Знак "-" после имени флага ([stdcall-], [linux-], ...) означает, что
|
||||
результат процедуры можно игнорировать (не допускается для типа REAL).
|
||||
Если флаг не указан или указан флаг [oberon], то принимается внутреннее
|
||||
соглашение о вызове.
|
||||
|
||||
При объявлении типов-записей, после ключевого слова RECORD может быть
|
||||
указан флаг [noalign]. Флаг [noalign] означает отсутствие выравнивания полей
|
||||
@ -256,15 +228,6 @@ ARRAY OF CHAR, за исключением встроенной процедур
|
||||
процедуру WCHR вместо CHR. Для правильной работы с типом, необходимо сохранять
|
||||
исходный код в кодировке UTF-8 c BOM.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Конкатенация строковых и символьных констант
|
||||
|
||||
Допускается конкатенация ("+") константных строк и символов типа CHAR:
|
||||
|
||||
str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
|
||||
|
||||
newline = 0DX + 0AX;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Проверка и охрана типа нулевого указателя
|
||||
|
||||
@ -314,16 +277,15 @@ Oberon-реализациях выполнение такой операции
|
||||
|
||||
Синтаксис импорта:
|
||||
|
||||
PROCEDURE [callconv, library, function] proc_name (FormalParam): Type;
|
||||
PROCEDURE [callconv, "library", "function"] proc_name (FormalParam): Type;
|
||||
|
||||
- callconv -- соглашение о вызове
|
||||
- library -- имя файла динамической библиотеки (строковая константа)
|
||||
- function -- имя импортируемой процедуры (строковая константа), если
|
||||
указана пустая строка, то имя процедуры = proc_name
|
||||
- "library" -- имя файла динамической библиотеки
|
||||
- "function" -- имя импортируемой процедуры
|
||||
|
||||
например:
|
||||
|
||||
PROCEDURE [windows, "kernel32.dll", ""] ExitProcess (code: INTEGER);
|
||||
PROCEDURE [windows, "kernel32.dll", "ExitProcess"] exit (code: INTEGER);
|
||||
|
||||
PROCEDURE [stdcall, "Console.obj", "con_exit"] exit (bCloseWindow: BOOLEAN);
|
||||
|
||||
@ -365,8 +327,6 @@ Oberon-реализациях выполнение такой операции
|
||||
Вызов транслируется так:
|
||||
Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x))
|
||||
|
||||
Скрытые параметры необходимо учитывать при связи с внешними приложениями.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Модуль RTL
|
||||
|
||||
@ -389,11 +349,8 @@ Oberon-реализациях выполнение такой операции
|
||||
|
||||
Разрешается экспортировать только процедуры. Для этого, процедура должна
|
||||
находиться в главном модуле программы, и ее имя должно быть отмечено символом
|
||||
экспорта ("*"). Нельзя экспортировать процедуры, которые импортированы из
|
||||
других dll-библиотек.
|
||||
|
||||
KolibriOS DLL всегда экспортируют идентификаторы "version" (версия
|
||||
программы) и "lib_init" - адрес процедуры инициализации DLL:
|
||||
экспорта ("*"). KolibriOS DLL всегда экспортируют идентификаторы "version"
|
||||
(версия программы) и "lib_init" - адрес процедуры инициализации DLL:
|
||||
|
||||
PROCEDURE [stdcall] lib_init (): INTEGER
|
||||
|
@ -23,9 +23,6 @@ UTF-8 с BOM-сигнатурой.
|
||||
-stk <size> размер стэка в мегабайтах (по умолчанию 2 Мб,
|
||||
допустимо от 1 до 32 Мб)
|
||||
-nochk <"ptibcwra"> отключить проверки при выполнении
|
||||
-lower разрешить ключевые слова и встроенные идентификаторы в
|
||||
нижнем регистре
|
||||
-def <имя> задать символ условной компиляции
|
||||
|
||||
параметр -nochk задается в виде строки из символов:
|
||||
"p" - указатели
|
||||
@ -66,7 +63,6 @@ UTF-8 с BOM-сигнатурой.
|
||||
9. Добавлен синтаксис для импорта процедур из внешних библиотек
|
||||
10. "Строки" можно заключать также в одиночные кавычки: 'строка'
|
||||
11. Добавлен тип WCHAR
|
||||
12. Добавлена операция конкатенации строковых и символьных констант
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Особенности реализации
|
||||
@ -133,46 +129,29 @@ UTF-8 с BOM-сигнатурой.
|
||||
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 будет расширено
|
||||
до 64 бит, для записи байтов использовать SYSTEM.PUT8,
|
||||
для WCHAR -- SYSTEM.PUT16
|
||||
|
||||
PROCEDURE PUT8(a: INTEGER;
|
||||
x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
|
||||
PROCEDURE PUT8(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR)
|
||||
Память[a] := младшие 8 бит (x)
|
||||
|
||||
PROCEDURE PUT16(a: INTEGER;
|
||||
x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
|
||||
PROCEDURE PUT16(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR)
|
||||
Память[a] := младшие 16 бит (x)
|
||||
|
||||
PROCEDURE PUT32(a: INTEGER;
|
||||
x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
|
||||
PROCEDURE PUT32(a: INTEGER; x: INTEGER, SET, BYTE, CHAR, WCHAR)
|
||||
Память[a] := младшие 32 бит (x)
|
||||
|
||||
PROCEDURE MOVE(Source, Dest, n: INTEGER)
|
||||
Копирует n байт памяти из Source в Dest,
|
||||
области Source и Dest не могут перекрываться
|
||||
|
||||
PROCEDURE COPY(VAR Source: любой тип; VAR Dest: любой тип; n: INTEGER)
|
||||
Копирует n байт памяти из Source в Dest.
|
||||
Эквивалентно
|
||||
@ -194,8 +173,8 @@ UTF-8 с BOM-сигнатурой.
|
||||
Системные флаги
|
||||
|
||||
При объявлении процедурных типов и глобальных процедур, после ключевого
|
||||
слова PROCEDURE может быть указан флаг соглашения о вызове:
|
||||
[win64], [systemv], [windows], [linux], [oberon].
|
||||
слова PROCEDURE может быть указан флаг соглашения о вызове: [win64], [systemv],
|
||||
[windows], [linux].
|
||||
Например:
|
||||
|
||||
PROCEDURE [win64] MyProc (x, y, z: INTEGER): INTEGER;
|
||||
@ -203,9 +182,9 @@ UTF-8 с BOM-сигнатурой.
|
||||
Флаг [windows] - синоним для [win64], [linux] - синоним для [systemv].
|
||||
Знак "-" после имени флага ([win64-], [linux-], ...) означает, что
|
||||
результат процедуры можно игнорировать (не допускается для типа REAL).
|
||||
Если флаг не указан или указан флаг [oberon], то принимается внутреннее
|
||||
соглашение о вызове. [win64] и [systemv] используются для связи с
|
||||
операционной системой и внешними приложениями.
|
||||
Если флаг не указан, то принимается внутреннее соглашение о вызове.
|
||||
[win64] и [systemv] используются для связи с операционной системой и внешними
|
||||
приложениями.
|
||||
|
||||
При объявлении типов-записей, после ключевого слова RECORD может быть
|
||||
указан флаг [noalign]. Флаг [noalign] означает отсутствие выравнивания полей
|
||||
@ -249,15 +228,6 @@ ARRAY OF CHAR, за исключением встроенной процедур
|
||||
процедуру WCHR вместо CHR. Для правильной работы с типом, необходимо сохранять
|
||||
исходный код в кодировке UTF-8 c BOM.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Конкатенация строковых и символьных констант
|
||||
|
||||
Допускается конкатенация ("+") константных строк и символов типа CHAR:
|
||||
|
||||
str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
|
||||
|
||||
newline = 0DX + 0AX;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Проверка и охрана типа нулевого указателя
|
||||
|
||||
@ -307,18 +277,16 @@ Oberon-реализациях выполнение такой операции
|
||||
|
||||
Синтаксис импорта:
|
||||
|
||||
PROCEDURE [callconv, library, function] proc_name (FormalParam): Type;
|
||||
PROCEDURE [callconv, "library", "function"] proc_name (FormalParam): Type;
|
||||
|
||||
- callconv -- соглашение о вызове
|
||||
- library -- имя файла динамической библиотеки (строковая константа)
|
||||
- function -- имя импортируемой процедуры (строковая константа), если
|
||||
указана пустая строка, то имя процедуры = proc_name
|
||||
- "library" -- имя файла динамической библиотеки
|
||||
- "function" -- имя импортируемой процедуры
|
||||
|
||||
например:
|
||||
|
||||
PROCEDURE [windows, "kernel32.dll", "ExitProcess"] exit (code: INTEGER);
|
||||
PROCEDURE [win64, "kernel32.dll", "ExitProcess"] exit (code: INTEGER);
|
||||
|
||||
PROCEDURE [windows, "kernel32.dll", ""] GetTickCount (): INTEGER;
|
||||
|
||||
В конце объявления может быть добавлено (необязательно) "END proc_name;"
|
||||
|
||||
@ -333,7 +301,7 @@ Oberon-реализациях выполнение такой операции
|
||||
соглашения о вызове:
|
||||
|
||||
VAR
|
||||
ExitProcess: PROCEDURE [windows] (code: INTEGER);
|
||||
ExitProcess: PROCEDURE [win64] (code: INTEGER);
|
||||
|
||||
Для Linux, импортированные процедуры не реализованы.
|
||||
|
||||
@ -353,8 +321,6 @@ Oberon-реализациях выполнение такой операции
|
||||
Вызов транслируется так:
|
||||
Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x))
|
||||
|
||||
Скрытые параметры необходимо учитывать при связи с внешними приложениями.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Модуль RTL
|
||||
|
||||
@ -377,5 +343,4 @@ Oberon-реализациях выполнение такой операции
|
||||
|
||||
Разрешается экспортировать только процедуры. Для этого, процедура должна
|
||||
находиться в главном модуле программы, ее имя должно быть отмечено символом
|
||||
экспорта ("*") и должно быть указано соглашение о вызове. Нельзя
|
||||
экспортировать процедуры, которые импортированы из других dll-библиотек.
|
||||
экспорта ("*") и должно быть указано соглашение о вызове.
|
@ -1,36 +0,0 @@
|
||||
Условная компиляция
|
||||
|
||||
синтаксис:
|
||||
|
||||
$IF "(" ident {"|" ident} ")"
|
||||
<...>
|
||||
{$ELSIF "(" ident {"|" ident} ")"}
|
||||
<...>
|
||||
[$ELSE]
|
||||
<...>
|
||||
$END
|
||||
|
||||
где ident:
|
||||
- одно из возможных значений параметра <target> в командной строке
|
||||
- пользовательский идентификатор, переданный с ключом -def при компиляции
|
||||
|
||||
примеры:
|
||||
|
||||
$IF (win64con | win64gui | win64dll)
|
||||
OS := "WIN64";
|
||||
$ELSIF (win32con | win32gui | win32dll)
|
||||
OS := "WIN32";
|
||||
$ELSIF (linux64exe | linux64so)
|
||||
OS := "LINUX64";
|
||||
$ELSIF (linux32exe | linux32so)
|
||||
OS := "LINUX32";
|
||||
$ELSE
|
||||
OS := "UNKNOWN";
|
||||
$END
|
||||
|
||||
|
||||
$IF (CPUX86_64) (* -def CPUX86_64 *)
|
||||
bit_depth := 64;
|
||||
$ELSE
|
||||
bit_depth := 32;
|
||||
$END
|
@ -1,520 +0,0 @@
|
||||
Компилятор языка программирования Oberon-07/16 для
|
||||
микроконтроллеров MSP430x{1,2}xx.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Параметры командной строки
|
||||
|
||||
Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или
|
||||
UTF-8 с BOM-сигнатурой.
|
||||
Выход - hex-файл прошивки.
|
||||
Параметры:
|
||||
1) имя главного модуля
|
||||
2) "msp430"
|
||||
3) необязательные параметры-ключи
|
||||
-out <file_name> имя результирующего файла; по умолчанию,
|
||||
совпадает с именем главного модуля, но с расширением ".hex"
|
||||
-ram <size> размер ОЗУ в байтах (128 - 2048) по умолчанию 128
|
||||
-rom <size> размер ПЗУ в байтах (2048 - 24576) по умолчанию 2048
|
||||
-nochk <"ptibcwra"> отключить проверки при выполнении
|
||||
-lower разрешить ключевые слова и встроенные идентификаторы в
|
||||
нижнем регистре
|
||||
-def <имя> задать символ условной компиляции
|
||||
|
||||
параметр -nochk задается в виде строки из символов:
|
||||
"p" - указатели
|
||||
"t" - типы
|
||||
"i" - индексы
|
||||
"b" - неявное приведение INTEGER к BYTE
|
||||
"c" - диапазон аргумента функции CHR
|
||||
"a" - все проверки
|
||||
|
||||
Порядок символов может быть любым. Наличие в строке того или иного
|
||||
символа отключает соответствующую проверку.
|
||||
|
||||
Например: -nochk it - отключить проверку индексов и охрану типа.
|
||||
-nochk a - отключить все отключаемые проверки.
|
||||
|
||||
Например:
|
||||
|
||||
Compiler.exe "C:\example.ob07" msp430 -ram 128 -rom 4096 -nochk pti
|
||||
Compiler.exe "C:\example.ob07" msp430 -out "C:\Ex1.hex" -ram 512 -rom 16384
|
||||
|
||||
В случае успешной компиляции, компилятор передает код завершения 0, иначе 1.
|
||||
При работе компилятора в KolibriOS, код завершения не передается.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Отличия от оригинала
|
||||
|
||||
1. Расширен псевдомодуль SYSTEM
|
||||
2. В идентификаторах допускается символ "_"
|
||||
3. Усовершенствован оператор CASE (добавлены константные выражения в
|
||||
метках вариантов и необязательная ветка ELSE)
|
||||
4. Расширен набор стандартных процедур
|
||||
5. Семантика охраны/проверки типа уточнена для нулевого указателя
|
||||
6. Добавлены однострочные комментарии (начинаются с пары символов "//")
|
||||
7. Разрешено наследование от типа-указателя
|
||||
8. "Строки" можно заключать также в одиночные кавычки: 'строка'
|
||||
9. Добавлена операция конкатенации строковых и символьных констант
|
||||
10. Добавлены кодовые процедуры
|
||||
11. Не реализована вещественная арифметика
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Особенности реализации
|
||||
|
||||
1. Основные типы
|
||||
|
||||
Тип Диапазон значений Размер, байт
|
||||
|
||||
INTEGER -32768 .. 32767 2
|
||||
CHAR символ ASCII (0X .. 0FFX) 1
|
||||
BOOLEAN FALSE, TRUE 1
|
||||
SET множество из целых чисел {0 .. 15} 2
|
||||
BYTE 0 .. 255 1
|
||||
|
||||
2. Максимальная длина идентификаторов - 1024 символов
|
||||
3. Максимальная длина строковых констант - 1024 символов (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)
|
||||
11 неявное приведение x:INTEGER к v:BYTE, если (x < 0) OR (x > 255)
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Псевдомодуль SYSTEM
|
||||
|
||||
Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры,
|
||||
ошибки при использовании процедур псевдомодуля SYSTEM могут привести к
|
||||
повреждению данных времени выполнения и аварийному завершению программы.
|
||||
|
||||
PROCEDURE ADR(v: любой тип): INTEGER
|
||||
v - переменная или процедура;
|
||||
возвращает адрес v
|
||||
|
||||
PROCEDURE SADR(x: строковая константа): INTEGER
|
||||
возвращает адрес x
|
||||
|
||||
PROCEDURE SIZE(T): INTEGER
|
||||
возвращает размер типа T
|
||||
|
||||
PROCEDURE TYPEID(T): INTEGER
|
||||
T - тип-запись или тип-указатель,
|
||||
возвращает номер типа в таблице типов-записей
|
||||
|
||||
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)
|
||||
Эквивалентно
|
||||
SYSTEM.MOVE(a, SYSTEM.ADR(x), 1)
|
||||
|
||||
PROCEDURE PUT(a: INTEGER; x: любой основной тип, PROCEDURE, POINTER)
|
||||
Память[a] := x;
|
||||
Если x: BYTE, то значение x будет расширено до 16 бит,
|
||||
для записи байтов использовать SYSTEM.PUT8
|
||||
|
||||
PROCEDURE PUT8(a: INTEGER; x: INTEGER, SET, BYTE, CHAR)
|
||||
Память[a] := младшие 8 бит (x)
|
||||
|
||||
PROCEDURE CODE(word1, word2,... : INTEGER)
|
||||
Вставка машинного кода,
|
||||
word1, word2 ... - целочисленные константы (константные
|
||||
выражения) - машинные слова, например:
|
||||
SYSTEM.CODE(0D032H, 0010H) (* BIS #16, SR; CPUOFF *)
|
||||
|
||||
|
||||
Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Оператор CASE
|
||||
|
||||
Синтаксис оператора CASE:
|
||||
|
||||
CaseStatement =
|
||||
CASE Expression OF Сase {"|" Сase}
|
||||
[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
|
||||
отсутствует, то программа прерывается с ошибкой времени выполнения.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Конкатенация строковых и символьных констант
|
||||
|
||||
Допускается конкатенация ("+") константных строк и символов типа CHAR:
|
||||
|
||||
str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
|
||||
|
||||
newline = 0DX + 0AX;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Проверка и охрана типа нулевого указателя
|
||||
|
||||
Оригинальное сообщение о языке не определяет поведение программы при
|
||||
выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих
|
||||
Oberon-реализациях выполнение такой операции приводит к ошибке времени
|
||||
выполнения. В данной реализации охрана типа нулевого указателя не приводит к
|
||||
ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет
|
||||
значительно сократить частоту применения охраны типа.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Дополнительные стандартные процедуры
|
||||
|
||||
|
||||
COPY (x: ARRAY OF CHAR; VAR v: ARRAY OF CHAR);
|
||||
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): INTEGER
|
||||
Длина 0X-завершенной строки s, без учета символа 0X.
|
||||
Если символ 0X отсутствует, функция возвращает длину
|
||||
массива s. s не может быть константой.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Использование регистров общего назначения R4 - R15
|
||||
|
||||
R4 - R7: регистровый стэк (промежуточные значения выражений)
|
||||
R8 - R13: не используются
|
||||
R14: указатель кучи
|
||||
R15: используется при обработке прерываний
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Вызов процедур и кадр стэка
|
||||
|
||||
Правила вызова похожи на соглашение cdecl (x86):
|
||||
- параметры передаются через стэк справа налево
|
||||
- результат, если есть, передается через регистр R4
|
||||
- вызывающая процедура очищает стэк
|
||||
|
||||
Состояние стэка при выполнении процедуры:
|
||||
|
||||
меньшие адреса <- |var3|var2|var1|PC|arg1|arg2|arg3| -> бОльшие адреса
|
||||
|
||||
PC - значение регистра PC перед вызовом (адрес возврата)
|
||||
argX - параметры в порядке объявления (слева направо)
|
||||
varX - локальные переменные в порядке использования в процедуре
|
||||
|
||||
Размер каждого элемента в стэке (кроме локальных переменных структурных
|
||||
типов) - 1 машинное слово (2 байта). Структурные переменные (массивы и
|
||||
записи) занимают место в стэке в соответствии с их размером (с учетом
|
||||
выравнивания).
|
||||
|
||||
Размещение локальных переменных зависит от их размеров и порядка
|
||||
использования, и в общем случае неопределенно. Если переменная не
|
||||
используется явно, то компилятор не выделяет для нее место в стэке.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Скрытые параметры процедур
|
||||
|
||||
Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке
|
||||
формальных параметров, но учитываются компилятором при трансляции вызовов.
|
||||
Это возможно в следующих случаях:
|
||||
|
||||
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))
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Кодовые процедуры
|
||||
|
||||
Компилятор поддерживает процедуры, написаные в машинных кодах.
|
||||
Синтаксис:
|
||||
|
||||
PROCEDURE "[code]" имя [ (параметры): ТипРезультата ]
|
||||
МашСлово, МашСлово,... МашСлово;
|
||||
|
||||
";" после заголовка и END "имя" в конце процедуры не ставятся.
|
||||
МашСлово - целочисленная константа (в том числе и константное выражение).
|
||||
Например:
|
||||
|
||||
PROCEDURE [code] asr (n, x: INTEGER): INTEGER (* ASR(x, n) -> R4 *)
|
||||
4115H, 2, (* MOV 2(SP), R5; R5 <- n *)
|
||||
4114H, 4, (* MOV 4(SP), R4; R4 <- x *)
|
||||
0F035H, 15, (* AND #15, R5 *)
|
||||
2400H + 3, (* JZ L1 *)
|
||||
(* L2: *)
|
||||
1104H, (* RRA R4 *)
|
||||
8315H, (* SUB #1, R5 *)
|
||||
2000H + 400H - 3; (* JNZ L2 *)
|
||||
(* L1: *)
|
||||
|
||||
Компилятор автоматически добавляет к такой процедуре команду RET.
|
||||
Способ передачи параметров и результата не изменяется.
|
||||
|
||||
Кодовые процедуры можно использовать также и для добавления в программу
|
||||
константных данных:
|
||||
|
||||
PROCEDURE [code] sqr
|
||||
0, 1, 4, 9, 16, 25, 36, 49, 64, 81;
|
||||
|
||||
Получить адрес такой "процедуры": SYSTEM.ADR(sqr).
|
||||
Получить адрес n-го машинного слова: SYSTEM.ADR(sqr) + n * 2.
|
||||
|
||||
Чтобы использовать кодовые процедуры, необходимо импортировать псевдомодуль
|
||||
SYSTEM.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Обработка прерываний
|
||||
|
||||
При появлении запроса на прерывание, процессор:
|
||||
- помещает в стэк значение регистра PC
|
||||
- помещает в стэк значение регистра SR
|
||||
- очищает регистр SR
|
||||
- выполняет переход по адресу IV[priority], где
|
||||
IV - таблица векторов прерываний,
|
||||
priority - приоритет прерывания (номер элемента в таблице IV) (0..30)
|
||||
|
||||
Компилятор генерирует код обработки прерываний:
|
||||
|
||||
; IV[0] = адрес следующей команды
|
||||
PUSH #0 ; поместить в стэк приоритет прерывания
|
||||
JMP Label ; перейти к обработчику
|
||||
|
||||
; IV[1] = адрес следующей команды
|
||||
PUSH #1 ; поместить в стэк приоритет прерывания
|
||||
JMP Label ; перейти к обработчику
|
||||
|
||||
...
|
||||
; IV[priority] = адрес следующей команды
|
||||
PUSH #priority ; поместить в стэк приоритет прерывания
|
||||
JMP Label ; перейти к обработчику
|
||||
|
||||
...
|
||||
; IV[30] = адрес следующей команды
|
||||
PUSH #30 ; поместить в стэк приоритет прерывания
|
||||
|
||||
Label:
|
||||
MOV SP, R15 ; настроить R15 на структуру данных прерывания (см. далее)
|
||||
PUSH R4 ; сохранить рабочие регистры (R4 - R7)
|
||||
...
|
||||
PUSH R7
|
||||
PUSH R15 ; передать параметр interrupt в обработчик (см. далее)
|
||||
PUSH @R15 ; передать параметр priority в обработчик (см. далее)
|
||||
CALL int ; вызвать обработчик (см. далее)
|
||||
ADD #4, SP ; удалить из стэка параметры обработчика
|
||||
POP R7 ; восстановить рабочие регистры (R7 - R4)
|
||||
...
|
||||
POP R4
|
||||
ADD #2, SP ; удалить из стэка значение priority
|
||||
RETI ; возврат из прерывания (восстановить SR и PC)
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Обработка ошибок
|
||||
|
||||
В случае возникновения ошибки при выполнении программы, будет вызван общий
|
||||
обработчик ошибок, который:
|
||||
|
||||
- запрещает прерывания
|
||||
- сбрасывает стэк (во избежание переполнения в процессе обработки ошибки)
|
||||
- передает параметры в пользовательский обработчик (см. далее)
|
||||
- вызывает пользовательский обработчик (если он назначен)
|
||||
- повторно запрещает прерывания
|
||||
- выключает CPU и все тактовые сигналы
|
||||
|
||||
Если выключать CPU не требуется, то пользовательский обработчик может,
|
||||
например, перезапустить программу.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Инициализация и финализация программы
|
||||
|
||||
В начало программы компилятор вставляет код, который:
|
||||
- инициализирует регистры SP и R14
|
||||
- выключает сторожевой таймер
|
||||
- назначает пустой обработчик прерываний
|
||||
- сбрасывает обработчик ошибок
|
||||
|
||||
В конец программы добавляет команду
|
||||
BIS #16, SR; выключить CPU
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Структура ОЗУ (RAM)
|
||||
|
||||
начало -> | спец. переменные | глобальные переменные | куча/стэк | <- конец
|
||||
|
||||
Компилятор поддерживает размер ОЗУ 128..2048 байт. В нижних адресах
|
||||
располагаются специальные переменные, и далее пользовательские глобальные
|
||||
переменные. Оставшаяся часть памяти отводится для кучи и стэка (не менее 64
|
||||
байта). При старте программы, в регистр R14 записывается адрес начала области
|
||||
кучи/стэка, а регистр SP настраивается на конец ОЗУ (начало_ОЗУ + размер_ОЗУ).
|
||||
При выделении памяти процедурой NEW, значение регистра R14 увеличивается (если
|
||||
есть свободная память). Таким образом, стэк и куча растут навстречу друг
|
||||
другу. Проверка переполнения стэка не производится.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Структура ПЗУ (RОM)
|
||||
|
||||
начало -> |код|свободная область|спец. данные|векторы прерываний| <- конец
|
||||
|
||||
Компилятор поддерживает размер ПЗУ 2048..24576 байт. В верхних адресах
|
||||
располагается таблица векторов прерываний (64 байта), адреса 0FFC0H..0FFFFH.
|
||||
Непосредственно перед ней размещаются специальные данные. Программный
|
||||
код начинается с адреса (10000H - размер_ПЗУ), этот адрес является также и
|
||||
точкой входа в программу. Между кодом и спец. данными может оставаться
|
||||
свободное пространство. Если размер ПЗУ больше, чем указан при компиляции,
|
||||
то перед кодом будет свободная область. Таким способом можно зарезервировать
|
||||
нижние сегменты флэш-памяти для записи во время выполнения программы.
|
||||
|
||||
==============================================================================
|
||||
MODULE MSP430
|
||||
|
||||
CONST
|
||||
|
||||
биты регистра SR:
|
||||
|
||||
GIE = {3}
|
||||
CPUOFF = {4}
|
||||
OSCOFF = {5}
|
||||
SCG0 = {6}
|
||||
SCG1 = {7}
|
||||
|
||||
|
||||
TYPE
|
||||
|
||||
TInterrupt = RECORD priority: INTEGER; sr: SET; pc: INTEGER END
|
||||
структура данных прерывания
|
||||
|
||||
priority - приоритет прерывания:
|
||||
|
||||
адрес приоритет
|
||||
0FFFEH 31
|
||||
0FFFCH 30
|
||||
0FFFAH 29
|
||||
...
|
||||
0FFC0H 0
|
||||
|
||||
sr - сохраненное значение регистра SR
|
||||
pc - сохраненное значение регистра PC
|
||||
|
||||
|
||||
TTrapProc = PROCEDURE (modNum, modName, err, line: INTEGER);
|
||||
Процедура-обработчик ошибок.
|
||||
|
||||
modNum - номер модуля (в отчете о компиляции:
|
||||
compiling (modNum) "modName" )
|
||||
modName - адрес имени модуля
|
||||
err - номер ошибки
|
||||
line - номер строки
|
||||
|
||||
|
||||
TIntProc = PROCEDURE (priority: INTEGER; interrupt: TInterrupt)
|
||||
Процедура-обработчик прерываний.
|
||||
|
||||
priority - приоритет прерывания
|
||||
interrupt - структура данных прерывания
|
||||
|
||||
|
||||
PROCEDURE SetTrapProc (TrapProc: TTrapProc)
|
||||
Назначить обработчик ошибок.
|
||||
|
||||
|
||||
PROCEDURE SetIntProc (IntProc: TIntProc)
|
||||
Назначить обработчик прерываний.
|
||||
|
||||
Нельзя вызывать эту процедуру с параметром NIL, т. к. для экономии
|
||||
тактов, значение адреса обработчика прерываний не проверяется на NIL.
|
||||
|
||||
|
||||
PROCEDURE Restart
|
||||
Перезапустить программу.
|
||||
При этом: очищается регистр SR, повторно выполняется код инициализации
|
||||
программы (см. выше). Всё прочее состояние ОЗУ и регистров устройств
|
||||
сохраняется.
|
||||
|
||||
|
||||
PROCEDURE SetIntPC (interrupt: TInterrupt; NewPC: INTEGER)
|
||||
interrupt.pc := NewPC
|
||||
После возврата из прерывания, регистр PC получит значение NewPC.
|
||||
|
||||
|
||||
PROCEDURE SetIntSR (interrupt: TInterrupt; NewSR: SET)
|
||||
interrupt.sr := NewSR
|
||||
После возврата из прерывания, регистр SR получит значение NewSR.
|
||||
|
||||
|
||||
PROCEDURE DInt
|
||||
Запретить прерывания.
|
||||
|
||||
|
||||
PROCEDURE EInt
|
||||
Разрешить прерывания.
|
||||
|
||||
|
||||
PROCEDURE CpuOff
|
||||
Выключить CPU (установить бит CPUOFF регистра SR).
|
||||
|
||||
|
||||
PROCEDURE Halt
|
||||
Запретить прерывания, выключить CPU и все тактовые сигналы.
|
||||
|
||||
|
||||
PROCEDURE SetSR (bits: SET)
|
||||
Установить биты bits регистра SR.
|
||||
|
||||
|
||||
PROCEDURE ClrSR (bits: SET)
|
||||
Сбросить биты bits регистра SR.
|
||||
|
||||
|
||||
PROCEDURE GetFreeFlash (VAR address, size: INTEGER)
|
||||
Получить адрес и размер свободной области Flash/ROM
|
||||
(между кодом и данными).
|
||||
|
||||
|
||||
PROCEDURE Delay (n: INTEGER)
|
||||
Задержка выполнения программы на 1000*n тактов,
|
||||
но не менее чем на 2000 тактов.
|
||||
|
||||
|
||||
==============================================================================
|
@ -1,404 +0,0 @@
|
||||
Компилятор языка программирования Oberon-07/16 для
|
||||
микроконтроллеров STM32 Cortex-M3.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Параметры командной строки
|
||||
|
||||
Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или
|
||||
UTF-8 с BOM-сигнатурой.
|
||||
Выход - hex-файл прошивки.
|
||||
Параметры:
|
||||
1) имя главного модуля
|
||||
2) "stm32cm3"
|
||||
3) необязательные параметры-ключи
|
||||
-out <file_name> имя результирующего файла; по умолчанию,
|
||||
совпадает с именем главного модуля, но с расширением ".hex"
|
||||
-ram <size> размер ОЗУ в килобайтах (4 - 65536) по умолчанию 4
|
||||
-rom <size> размер ПЗУ в килобайтах (16 - 65536) по умолчанию 16
|
||||
-nochk <"ptibcwra"> отключить проверки при выполнении
|
||||
-lower разрешить ключевые слова и встроенные идентификаторы в
|
||||
нижнем регистре
|
||||
-def <имя> задать символ условной компиляции
|
||||
|
||||
параметр -nochk задается в виде строки из символов:
|
||||
"p" - указатели
|
||||
"t" - типы
|
||||
"i" - индексы
|
||||
"b" - неявное приведение INTEGER к BYTE
|
||||
"c" - диапазон аргумента функции CHR
|
||||
"w" - диапазон аргумента функции WCHR
|
||||
"r" - эквивалентно "bcw"
|
||||
"a" - все проверки
|
||||
|
||||
Порядок символов может быть любым. Наличие в строке того или иного
|
||||
символа отключает соответствующую проверку.
|
||||
|
||||
Например: -nochk it - отключить проверку индексов и охрану типа.
|
||||
-nochk a - отключить все отключаемые проверки.
|
||||
|
||||
Например:
|
||||
|
||||
Compiler.exe "C:\example.ob07" stm32cm3 -ram 32 -rom 256 -nochk pti
|
||||
Compiler.exe "C:\example.ob07" stm32cm3 -out "C:\Ex1.hex" -ram 8 -rom 32
|
||||
|
||||
В случае успешной компиляции, компилятор передает код завершения 0, иначе 1.
|
||||
При работе компилятора в KolibriOS, код завершения не передается.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Отличия от оригинала
|
||||
|
||||
1. Расширен псевдомодуль SYSTEM
|
||||
2. В идентификаторах допускается символ "_"
|
||||
3. Усовершенствован оператор CASE (добавлены константные выражения в
|
||||
метках вариантов и необязательная ветка ELSE)
|
||||
4. Расширен набор стандартных процедур
|
||||
5. Семантика охраны/проверки типа уточнена для нулевого указателя
|
||||
6. Добавлены однострочные комментарии (начинаются с пары символов "//")
|
||||
7. Разрешено наследование от типа-указателя
|
||||
8. "Строки" можно заключать также в одиночные кавычки: 'строка'
|
||||
9. Добавлен тип WCHAR
|
||||
10. Добавлена операция конкатенации строковых и символьных констант
|
||||
11. Добавлены кодовые процедуры
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Особенности реализации
|
||||
|
||||
1. Основные типы
|
||||
|
||||
Тип Диапазон значений Размер, байт
|
||||
|
||||
INTEGER -2147483648 .. 2147483647 4
|
||||
REAL 1.17E-38 .. 3.40E+38 4
|
||||
CHAR символ ASCII (0X .. 0FFX) 1
|
||||
BOOLEAN FALSE, TRUE 1
|
||||
SET множество из целых чисел {0 .. 31} 4
|
||||
BYTE 0 .. 255 1
|
||||
WCHAR символ юникода (0X .. 0FFFFX) 2
|
||||
|
||||
2. Максимальная длина идентификаторов - 1024 символов
|
||||
3. Максимальная длина строковых констант - 1024 символов (UTF-8)
|
||||
4. Максимальная размерность открытых массивов - 5
|
||||
5. Процедура NEW заполняет нулями выделенный блок памяти
|
||||
6. Локальные переменные инициализируются нулями
|
||||
7. В отличие от многих Oberon-реализаций, сборщик мусора и динамическая
|
||||
модульность отсутствуют
|
||||
8. Тип BYTE в выражениях всегда приводится к INTEGER
|
||||
9. Контроль переполнения значений выражений не производится
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Псевдомодуль SYSTEM
|
||||
|
||||
Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры,
|
||||
ошибки при использовании процедур псевдомодуля SYSTEM могут привести к
|
||||
повреждению данных времени выполнения и аварийному завершению программы.
|
||||
|
||||
PROCEDURE ADR(v: любой тип): INTEGER
|
||||
v - переменная или процедура;
|
||||
возвращает адрес v
|
||||
|
||||
PROCEDURE SADR(x: строковая константа (CHAR UTF-8)): INTEGER
|
||||
возвращает адрес x
|
||||
|
||||
PROCEDURE WSADR(x: строковая константа (WCHAR)): INTEGER
|
||||
возвращает адрес x
|
||||
|
||||
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 CODE(hword1, hword2,... : INTEGER)
|
||||
Вставка машинного кода,
|
||||
hword1, hword2 ... - константы в диапазоне 0..65535,
|
||||
например:
|
||||
SYSTEM.CODE(0BF30H) (* wfi *)
|
||||
|
||||
Также, в модуле SYSTEM определен тип CARD32 (4 байта). Для типа CARD32 не
|
||||
допускаются никакие явные операции, за исключением присваивания.
|
||||
|
||||
Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Оператор CASE
|
||||
|
||||
Синтаксис оператора CASE:
|
||||
|
||||
CaseStatement =
|
||||
CASE Expression OF Сase {"|" Сase}
|
||||
[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 c BOM.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Конкатенация строковых и символьных констант
|
||||
|
||||
Допускается конкатенация ("+") константных строк и символов типа CHAR:
|
||||
|
||||
str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
|
||||
|
||||
newline = 0DX + 0AX;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Проверка и охрана типа нулевого указателя
|
||||
|
||||
Оригинальное сообщение о языке не определяет поведение программы при
|
||||
выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих
|
||||
Oberon-реализациях выполнение такой операции приводит к ошибке времени
|
||||
выполнения. В данной реализации охрана типа нулевого указателя не приводит к
|
||||
ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет
|
||||
значительно сократить частоту применения охраны типа.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Дополнительные стандартные процедуры
|
||||
|
||||
|
||||
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
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Использование регистров общего назначения R0 - R12
|
||||
|
||||
R0 - R3: регистровый стэк (промежуточные значения выражений)
|
||||
R4 - R12: не используются
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Вызов процедур и кадр стэка
|
||||
|
||||
Правила вызова похожи на соглашение cdecl (x86):
|
||||
- параметры передаются через стэк справа налево
|
||||
- результат, если есть, передается через регистр R0
|
||||
- вызывающая процедура очищает стэк
|
||||
|
||||
Состояние стэка при выполнении процедуры:
|
||||
|
||||
меньшие адреса <- |var3|var2|var1|LR|arg1|arg2|arg3| -> бОльшие адреса
|
||||
|
||||
LR - сохраненный регистр LR (адрес возврата)
|
||||
argX - параметры в порядке объявления (слева направо)
|
||||
varX - локальные переменные в порядке использования в процедуре
|
||||
|
||||
Размер каждого элемента в стэке (кроме локальных переменных структурных
|
||||
типов) - 1 машинное слово (4 байта). Структурные переменные (массивы и
|
||||
записи) занимают место в стэке в соответствии с их размером (с учетом
|
||||
выравнивания).
|
||||
|
||||
Размещение локальных переменных зависит от их размеров и порядка
|
||||
использования, и в общем случае неопределенно. Если переменная не
|
||||
используется явно, то компилятор не выделяет для нее место в стэке.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Скрытые параметры процедур
|
||||
|
||||
Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке
|
||||
формальных параметров, но учитываются компилятором при трансляции вызовов.
|
||||
Это возможно в следующих случаях:
|
||||
|
||||
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))
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Кодовые процедуры
|
||||
|
||||
Компилятор поддерживает процедуры, написаные в машинных кодах.
|
||||
Синтаксис:
|
||||
|
||||
PROCEDURE "[code]" имя [ (параметры): ТипРезультата ]
|
||||
МашКом, МашКом,... МашКом;
|
||||
|
||||
";" после заголовка и END "имя" в конце процедуры не ставятся.
|
||||
МашКом - целочисленная константа [0..65535] (в том числе и константное
|
||||
выражение).
|
||||
|
||||
Например:
|
||||
|
||||
PROCEDURE [code] WFI
|
||||
0BF30H; (* wfi *)
|
||||
|
||||
Компилятор автоматически добавляет к такой процедуре команду возврата
|
||||
(bx LR). Способ передачи параметров и результата не изменяется. Регистр LR,
|
||||
при входе в процедуру не сохраняется.
|
||||
|
||||
Чтобы использовать кодовые процедуры, необходимо импортировать псевдомодуль
|
||||
SYSTEM.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Обработка прерываний
|
||||
|
||||
При возникновении прерывания, будет вызван обработчик (если он объявлен).
|
||||
Объявление обработчика:
|
||||
|
||||
PROCEDURE handler_name [iv]; (* процедура без параметров *)
|
||||
|
||||
iv - целочисленная константа (константное выражение), номер вектора прерывания
|
||||
в таблице векторов, iv >= 2:
|
||||
|
||||
0 начальное значение SP
|
||||
1 сброс
|
||||
...
|
||||
15 SysTick
|
||||
...
|
||||
59 TIM6
|
||||
60 TIM7
|
||||
...
|
||||
|
||||
например:
|
||||
|
||||
(* обработчик прерываний от TIM6 *)
|
||||
PROCEDURE tim6 [59];
|
||||
BEGIN
|
||||
(* код обработки *)
|
||||
END tim6;
|
||||
|
||||
Также, можно объявить общий обработчик (iv = 0), который будет вызван, если
|
||||
не назначен индивидуальный. Общий обработчик получает параметр - номер вектора
|
||||
прерывания. По значению этого параметра, обработчик должен определить источник
|
||||
прерывания и выполнить соответствующие действия:
|
||||
|
||||
PROCEDURE handler (iv: INTEGER) [0];
|
||||
BEGIN
|
||||
IF iv = 59 THEN
|
||||
(* TIM6 *)
|
||||
ELSIF iv = 60 THEN
|
||||
(* TIM7 *)
|
||||
ELSIF ....
|
||||
....
|
||||
END
|
||||
END handler;
|
||||
|
||||
В конец программы компилятор добавляет команду ожидания прерывания.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Обработка ошибок
|
||||
|
||||
В случае возникновения ошибки при выполнении программы, будет вызван
|
||||
пользовательский обработчик (если он объявлен).
|
||||
|
||||
Объявление обработчика ошибок:
|
||||
|
||||
PROCEDURE trap (modNum, modName, err, line: INTEGER) [1];
|
||||
BEGIN
|
||||
END trap;
|
||||
|
||||
где,
|
||||
modNum - номер модуля (в отчете о компиляции:
|
||||
compiling (modNum) "modName" )
|
||||
modName - адрес имени модуля
|
||||
err - код ошибки
|
||||
line - номер строки
|
||||
|
||||
Коды ошибок:
|
||||
|
||||
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)
|
||||
|
||||
После возврата из обработчика программа будет перезапущена.
|
||||
|
||||
------------------------------------------------------------------------------
|
Loading…
Reference in New Issue
Block a user