PASCAL HP4T, НР80
ВВЕДЕНИЕ
Описанная в данном документе версия компилятора с языка паскаль НР4Т является представителем группы компиляторов с паскаля фирмы HISOFT. В той или иной степени этим описанием можно пользоваться и при работе с другими версиями, описаны основные особенности реализации паскаля на ZX-SPECTRUM, стандартный строчный редактор, а также более удобный НР80 (имеется не во всех версиях).
1. СИНТАКСИС И СЕМАНТИКА
• 1.1. ИДЕНТИФИКАТОРЫ
Допустимая длина идентификаторов не более 10 символов. Различаются маленькие и большие буквы.
• 1.2. ЧИСЛА
Целые имеют абсолютную величину не более 32767. Числа с большим значением рассматриваются как REAL. Мантисса REAL имеет длину 23 бит (т.е. 7 значащих цифр). Результаты операций с REAL — приближенные, т.е.
2.00002 - 2 о 0.00002
Максимальное число типа REAL равно 3.4Е38, минимальное
— 5.9Е-39.
Для повышенной точности следует избегать лишних нулей;
так, 0.000123456 менее точно, чем 1.23456Е-4 (0 — тоже цифра, а их может быть не более 7).
Допускается шестнадцатеричное представление числа: #03,
—FF.
• 1.3. СТРОКИ Строковым типом является ARRAY (1..N) JF CHAR, где N
— целое от 0 до 255 включительно. Литерные строки не должны содержать символ EOL (CHR(13)), в противном случае система генерирует <'ERROR*68. Символ NULL реализован не как пустая строка, а как CHR(0).
Допускается использование управляющих кодов дисплея в качестве констант:
CONST BS=CHR(10);
CR=CHR(13);
• 1.4. ОПРЕДЕЛЕНИЕ ТИПА
• Простой тип определяется через:
— идентификатор другого типа, либо
— (идентификатор , ..., идентификатор) — перечисляемый тип,либо
— константа .. константа — интервальный тип. Перечисляемый тип может иметь не более 255 элементов. Допускаются массивы массивов, массивы множеств, записи с палями типа множество и т.п.
В НР4Т используется эквивалентность имен, а не типов, следовательно, в следующем примере переменной TABELA не может быть присвоено значение переменной TABELB, т.к. они имеют разный тип:
VAR
TABELA: ARRAY [1..100] OF INTEGER;
TABELB: ARRAY [1..100] OF INTEGER;
В таком случае не вызовет ошибки следующая запись:
TYPE
TABEL = ARRAY [1..100] OF INTEGER;
VAR TABELA, TABELB: TABEL;
• 1.5. УКАЗАТЕЛИ
Имеются некоторые ограничения на использование указателей:
— не допускаются указатели на необъявленный тип. Это не относится к конструкциям типа:
TYPE
ITEM = RECORD
VALUE: INTEGER;
NEXT: INTEM END;
LINK = ITEM;
— не допускается указатель на указатель;
— указатели одного типа считаются эквивалентными, т.е.:
VAR
FIRST: LINK;
CURRENT: ITEM;
— определена константа NIT.
• 1.6. ЗАПИСИ
Допускается ключевое слово WITH для более компактного обращения к полям записи.
Тип RECORD не может иметь вариантов.
• 1.7. МАССИВЫ
Зарезервированное слово PACKED допустимо, но игнорируется, т.к. массивы уже упакованы, если переменная объявлена как
VAR
A: ARRAY [1..10] OF ARRAY [1..10] то для доступа к элементу (1,1) этого массива можно использовать: А[1] [1] или А [1,1 ].
• 1.8. МНОЖЕСТВА
Базовый тип SET (множество) может иметь до 256 элементов. Нижняя граница множества всеща равна 0, а размер множества всегда равен максимальному размеру базового типа. Таким образом SET OF CHAR всегда занимает 32 байта (возможны 255 элементов по биту на 1 элемент). SET OF 0..10 эквивалентно SET OF 0..255.
• 1.9. ОПЕРАТОР CASE
Пустой список в операторе CASE не допускается, приводит к ошибке *ERROR* 13. Операция ELSE выполняется, если сектор не обнаружен в списке констант. Если ELSE отсутствует и подходящая ветвь списка CASE не найдена, управление передается оператору, следующему за AND.
• 1.10. ОПЕРАТОР FOR
Управляющая переменная оператора FOR должна быть простой и не может являться структурной переменной или параметром.
• 1.11. ОПЕРАТОР GOTO
Оператор GOTO должен передавать управление внутри того блока, где он находится. Оператор GOTO должен находиться на одном уровне вложенности с меткой. Метка должна быть объявлена в том же блоке, где она используется. Метка может содержать от 1 до 4 цифр. Оператор GOTO не может быть использован для выхода из циклов FOR..DO, процедур или функций.
ПРЕДОПРЕДЕЛЕННЫЕ ИДЕНТИФИКАТОРЫ
• 2.1. КОНСТАНТЫ
MAXINT - максимальное целое = 32767
•- TRUE, FALSE.
" 2.2. ТИПЫ INTEGER —2 байта real — 4 байта
CHAR — расширенный ASCII... 256 символов BOOLEAN
ПРИМЕЧАНИЕ: Тип FILE не определен. Процедуры и функции как параметры не допустимы.
2.3. ПРОЦЕДУРЫ ВВОДА И ВЫВОДА
• 2.3.1. WRITE
WRITE(E) — вывод 8-битового значения Е на экране или
принтер;
CHR(8) - CTRL H — BS на дисплее (шаг назад);
CHR(12) - ctrl L — очистка экрана (CLEAR SCREEN или NEWPAGE);
CHR(13) - CTRL M — CR и LF (BK и ПС);
CHR(16) - CTRL P — переключить вывод с дисплея на принтер и наоборот.
Следующие операторы эквивалентны:
WRITE (PI, P2, ... , PN) ;
BEGIN WRITE /(PI); WRITE (P2);
. . . ; WRITE (PN) END;
Параметры PI,..., PN могут иметь один из следующих форматов:
Е Е:М E:M:N E:M:H
где E,M,N — выражения; Н — символьная константа.
Рассмотрим 5 случаев:
— Е имеет тип INTEGER: используется формат Е или Е:М — значение выражения преобразуется к типу CHARACTER STRING с последующими пробелами. Длина строки может быть увеличена (с лидирующими пробелами) при использовании параметра M, определяется общее число символов, которые должны быть выведены.
— Е имеет тип INTEGER и использован формат E:M:H; в этом случае Е выводится в шестнадцатеричном виде. Если М=1 или М-2, то выводится значение Е MOD М длиной не более М символов. Если М°3 или М-4, то выводится полное значение выражения Е длиной не более 4 символов. Если М>4, то перед числом вставляют пробелы. Например:
WRITE (1025:M:H);
если m-1, to выводится: 1
если М-2, то выводится: 01
если М-3, то выводится: 0401
если М-4, то выводится: 0401
если М-5, то выводится: 0401 “
— Е имеет тип REAL, формат Е, Е:М, E:M:N; значение Е преобразуется в строку символов, представляющую собой число типа REAL. Форма представления определяется N. Если N отсутствует, то число выводится в "научной" форме, т.е. с мантиссой и экспонентой. Минимальная длина "научного" представления равна 8 символам. Если величина М<8, то всегда будет выводиться полная длина 12 символов (если число отрицательное). Например:
WRITE (-1 .23Е10:М);
если М-7, то выводится: -1.23000Е+10
если М-в, то выводится: -1.2Е+10
если М°9, то выводится: -1.23Е+10
если М-10,то выводится: -1.230Е+10
если М-11,то выводится: -1.2300Е+10
если М-12,то выводится: -1.23000Е+10
если М=13,то выводится: -1.23000Е+10
Если использован формат E:M:N, то число Е будет выводиться с фиксированной точкой, а N будет определять число выводимых Знаков после запятой. Если N-0, то число Е будет выведено в формате INTEGER. Если Е значительно больше определяемого формата, то оно будет выводиться в "научном" виде. Например:
WRITE (1E2:6:2) : 100.0
WRITE (1E2:8:2) : 100.0
WRITE (23.455 б 1) 23.5
WRITE (23.455 4 2) 2.34550E+01
WRITE (23.455 4 0) 23
— Е имеет тип CHAR или STRING — выводится либо один символ, либо М символов с лидирующими пробелами, если это . необходимо.
— Е имеет тип BOOLEAN.
• 2.3.2. WRITELN
WRITELN переходит на новую строку, что эквивалентно
WRITE(CHR(13)).
WRITELN (P1, ..., PN) эквивалентно: BEGIN WRITE (PI,
..., PN); WRITELN END.
• 2.3.3. PAGE
Процедура PAGE эквивалентна WRITE(CHR(12)), т.е. это очистка экрана или новая страница принтера.
— 2.3.4. READ
READ — ввод данных с клавиатуры. Ввод осуществляется через буфер, который изначально содержит только символ EOL. Доступ к буферу осуществляется через текстовое окно размером один символ. Если текстовое окно указывает на EOL-MAPKEP, то перед окончанием операции ввода в буфер будет выведена новая строка с клавиатуры.
Рассмотрим процедуру РЕАО(У) при различных типах У:
— Е имеет тип CHAR. В этом случае READ(y) просто считывает символ из буфера ввода и присваивает его У. Если текстовое окно в буфере установлено на маркер EOL (символ CHR(13)), то признак EOLN будет возвращать значение TRUE и с клавиатуры будет считываться новая строка текста. При повторном выполнении процедуры READ текстовое окно будет установлено на начало новой строки.
Отметим, если EOLN=TRUE в начале программы. Это означает, что если переменная в первом READ имеет тип CHAR, то процедура READ возвратит значение CHR(13) с последующим вводом новой строки с клавиатуры. Последующее выполнение READ типа CHAR будет возвращать первый символ этой новой строки.
— V имеет тип STRING. Процедурой READ могут быть считаны строки длиной, определенной ранее типом STRING или до EOLN=TRUE. Если признак EOLN установлен до окончания ввода всех символов строки, количество которых определено типом STRING, то строка будет дополнена до полной длины символами CHR(O). Обратите внимание на замечание к предыдущему пункту.
— V имеет тип INTEGER. Максимальное число, которое может быть введено в этом случае, равно 32767.
• 2.3.5. READLN
READLN(V1, .... VN) ; эквивалентно BEGIN READ (VI. .... VN); READLN END;
READLN просто считывает новый буфер с клавиатуры. Таким образом после выполнения READLN EOLN становится равным FALSE, если следующая строка не пустая.
READLN может быть использован для пропуска пустой строки в начале выполнения объектного кода. Это полезно, если вы желаете считывать символ типа CHAR в начале программы, но ее обязательно, если вы вводите значение типа INTEGER или REAL или символ из последующей строки.
• 2.3.6. EOLN
Функция EOLN является булевой функцией и возвращает значение TRUE, если следующий вводимый символ является EOL-СИМВОЛ. В противном случае EOLN-FALSE.
• 2.3.7. INCH
Функция, читает символ с клавиатуры. Если не нажата ни одна клавиша, возвращает CHR(O). Если клавиша нажата, то возвращается символ типа CHAR, соответствующий коду нажатой клавиши.
• 2.4. ФУНКЦИИ ПРЕОБРАЗОВАНИЯ
TRUNC(X) — целая часть
TRUNC(-1.5) - -1; TRUNC(1.9) = 1;
ROUND(X) — округление
ROUND(-6.5) = -6; ROUND(11.7) - 12;
ROUND(-6.51) = -7; ROUND(23.5) - 24, ENTI ER (X) — функция возвращает наибольшее целое число, которое меньше или равно X. ENTIER(-6.5) - -7; ENTIERdl.7)
-11
ORD(X) — преобразует перечисляемый тип в INTEGER. CHR(X) — преобразует INTEGER в перечисляемый тип.
• 2.5. АРИФМЕТИЧЕСКИЕ ФУНКЦИИ
ABS<X) —модуль.
SOR(X) — квадрат.
SQRT(X) — корень.
FRAC(X) — дробная часть.
SIN(X) — синус. Результат типа REAL, X — в радианах.
COS(X) — косинус.
ТАN(Х) —тангенс.
ARCTAN(X) — арктангенс.
ЕХР(Х) — экспонента, Е=2.71828 в степени X.
LN (Х) — натуральный логарифм.
• 2.6. ДРУГИЕ ПРОЦЕДУРЫ И ФУНКЦИИ:
NEW(P) — создает динамический элемент, на который теперь указывает Р. Вместо процедуры DISPOSE используется MARK и RELEASE.
mark(v) — сохранит состояние динамически распределяемой области ("кучи") в указателе V.
RELEASE(V) —очистка "кучи" от адреса, указываемого переменной V и до конца.
INLINE(C1,C2,...) — кодовая ставка. С1,С2,„. — шестнад-цатеричные числа вида #ХХ, размещаются в последовательность
байтов.
USER(V) — вызов подпрограммы по адресу V. Для обозначения адреса, большего #7FFF (32767), необходимо использовать отрицательные значения: #СОО - -16384. Подпрограмма должна завершаться инструкцией RET.
HALT — останов программы с выдачей сообщения:
'HALT AT POXXXX',
где ХХХХ — шестнадцатеричный адрес, где стоит HALT. POKE(X.V) — помещает значение V в ячейку памяти с адресом X. Х — типа INTEGER, V — любого типа. POKE (#6000, 'А' )
— в ячейку #6000 записать #41. POKE (-16384,3.6ЕЗ)
— разместить 00 OB 80 70 по адресу #СООО.
TOUT (NAME, START, SIZE) — записывает данные на магнитофонную ленту. Первый параметр NAME должен иметь тип ARRAY[L.8] OF CHAR. SIZE байт данных выводятся на ленту начиная с адреса START (оба параметра типа INTEGER). Можно использовать реальные шестнадцатеричные адреса.
TIN(NAME, START) — читает данные с магнитной ленты (см. TOUT). TIN можно использовать для ввода текста в массив тииа CHAR.
OUT(P,C) — вывод в порт. Значение параметра Р типа INTEGER загружается в регистр ВС, символьный параметр С загружается в регистр А, выполняется команда OUT (С),А процессора Z80.
RANDOM — функция, возвращает псевдослучайное число в диапазоне 0...255. функция малоэффективна, целесообразнее в некоторых случаях использовать собственные подпрограммы.
SUCC(X) — следующее значение перечисляемого типа.
PRED(X) — предыдущее значение перечисляемого типа.
ODD(X) — функция истинна при нечетном аргументе.
ADDR(V) — функция, возвращает адрес аргумента произвольного типа.
РЕЕК(Х,Т) — чтение из памяти. Х — целое, задает адрес, торой аргумент может иметь произвольный тип, задает тип результата. Если в памяти начиная с #5000 записано: 50 61 73 63 61 6С, то:
WRITE(PEEK(#5000, ARRAYtL.6] OF CHAR)) напечатает:
PASCAL
WRITE(PEEK(#5000, CHAR)) напечатает: Р WRITE(PEEK(#5000, INTEGER)) напечатает: 24912 WRITE(PEEK(#5000, REAL)) напечатает: 2.46227Е+29 SIZE(V) — функция, возвращает размер области памяти в байтах, занимаемой переменной V;
INP (Р) — функция вводит из порта с адресом Р — аналогично OUT.
3. КОММЕНТАРИИ И ОПЦИИ КОМПИЛЯЦИИ
• 3.1. Комментарии: "(*", "*)" или фигурные скобки.
• 3.2. Опции (ключи): размещаются внутри комментариев
вслед за символом "$". Состоят из символа, за которым
следует знак "+" или "-".
Опция L — контроль листинга
L+ : печать всего листинга (по умолчанию);
L-: печать только строк, содержащих ошибки.
Опция О — контроль переполнения в операциях * и / с числами типа INTEGER во всех операциях с REAL.
0+ : производить контроль (по умолчанию)
О- : не производить контроль.
Опция С — контроль квадратуры при выполнении объектного кода. Нажатием EDIT вызывает возврат в систему с сообщением команды HALT.
С+ : контроль есть (по умолчанию);
С-: контроль отсутствует.
Опция S — контроль переполнения стека при вызове процедур и функций (по умолчанию S+). В случае переполнения стека выводится сообщение: "OUT OF RAM AT POXXXX".
Опция А — контроль границ массивов (по умолчанию А+). В случае ошибки выдается сообщение:
"INDEX TOO HIGH" или "INDEX TOO LOW".
Опция I — при выполнении операции сравнения >, <, >-, <-, над 16-разрядными целыми числами. Если аргументы делятся на число, большее MAXINT=32767, то возникает переполнение. Для правильного сравнения таких чисел необходимо использовать опцию I+ (по умолчанию). Аналогичная ситуация может возникнуть и с числами типа REAL при попытке деления на 3.4Е38.
Опция Р — переключатель принтер/экран. Используется без знака + или -. Аналогичен CTRL/P в IBM PC.
Опция F — прочитать часть программы с магнитной ленты. После имени этой опции должно через пробел идти имя файла (если имя < 8 символов, то пополняют пробелами). Текст программы из указанного файла вставляют после строки, содержащей опцию F. Позволяет экономить память.