Шапка

Приложение B. Базовый словарь FORTH

Язык FORTH базируется на расширяемом интерактивном компиляторе, который создаёт код для виртуальной стековой машины с двумя стеками. Стек данных ( Data Stack ) используется для вычисления выражений и передачи аргументов. Стек возврата ( Return Stack ) хранит адреса возврата из процедур и счётчики программных циклов. Исходный текст на FORTH прямо отражает архитектуру виртуальной стековой машины и поэтому при описании выполняемых операций использует обратную польскую нотацию ( RPN ).

FORTH основывается на коллекции подпрограмм, называемых в терминологии FORTH «словами». Программа в FORTH состоит из единственного слова, которое вызывает несколько других и т.д., выстраивая структуру в форме дерева. На самом низком уровне листья дерева являются вызовом базовых слов FORTH, которые работают со стеком и выполняют арифметические действия.

Ниже даётся список базовых слов FORTH, которые можно найти в списках команд вычислительных машин, описанных в книге. Большая их часть является неотъемлемой частью любой программы для стековой машины, независимо от использованного языка ( например, сложить два верхних элемента стека или поменять их местами ). Словарь FORTH используется для сохранения преемственности с существующими стандартными словарями элементарных операций.

Каждое слово FORTH сопровождается «описанием стека» в той же строке. Схема показывает входные и выходные параметры стека данных для описываемого слова. Значения слева от «→» соответствуют входным параметрам, а справа - выходным. Список ориентирован так, чтобы самым правым элементом был самый верхний элемент стека. При обозначении элементов стека используются следующие обозначения. N1, N2.. - целые числа одинарной точности [* занимающие в стеке один элемент ] . D1, D2.. - целые числа двойной точности, которые занимают два элемента стека. ADDR обозначает адрес, который можно трактовать как указатель. FLAG - целое число, обозначающее «ЛОЖЬ» нулём, а «ИСТИНУ» - любым ненулевым значением. Более подробное описание словаря FORTH можно найти в книге Haydon, «All About Forth» ( 1983 ).

Табл. B.1 Базовый словарь FORTH

Инструкция
Стек на входе
 
Стек на выходе
Функция
Инструкция
Стек на входе
Стек на выходе
Функция
0 0 Положить целое число «0» в стек
0< N1 FLAG Возвратить FLAG «ИСТИНА», если N1 меньше нуля
0= N1 FLAG Возвратить FLAG «ИСТИНА», если N1 равно нулю
0> N1 FLAG Возвратить FLAG «ИСТИНА», если N1 больше нуля
0BRANCH N1 Если N1 равно нулю, выполнить переход по адресу, лежащему в следующей ячейке программы, в противном случае продолжить выполнение
1+ N1 N2 Прибавить 1 к N1, возвратить результат как N2
1- N1 N2 Вычесть 1 из N1, возвратить результат как N2
2+ N1 N2 Прибавить 2 к N1, возвратить результат как N2
2* N1 N2 Умножить N1 на 2, возвратить результат как N2
2/ N1 N2 Разделить N1 на 2, возвратить результат как N2
4+ N1 N2 Прибавить 4 к N1, возвратить результат как N2
< N1 N2 FLAG Возвратить FLAG «ИСТИНА», если N1 меньше чем N2
<> N1 N2 FLAG Возвратить FLAG «ИСТИНА», если N1 не равно N2
= N1 N2 FLAG Возвратить FLAG «ИСТИНА», если N1 равно N2
>R N1 Переместить N1 в стек возврата
> N1 N2 FLAG Возвратить FLAG «ИСТИНА», если N1 больше чем N2
! N1 ADDR Сохранить N1 в ячейке памяти по адресу ADDR
+ N1 N2 N3 Сложить N1 и N2, возвратить результат как N3
+! N1 ADDR Прибавить N1 к содержимому ячейки памяти по адресу ADDR
- N1 N2 N3 Вычесть N2 из N1, возвратить результат как N3
: Задать начало определения подпрограммы. Каждый раз, когда к данной подпрограмме обращается другое определение, в код вставляется примитив [CALL]
; Выполнить возврат из подпрограммы и закончить определение подпрограммы. В код вставляется примитив [EXIT]
?DUP N1
N1

N1 N1 ( N1<>0 )
N1       ( N1 = 0 )
Условное копирование. Создать копию N1, если N1 не равно нулю
@ ADDR N1 Выбрать содержимое ячейки памяти по адресу ADDR, возвратить результат как N1
ABS N1 N2 Получить абсолютное значение N1, возвратить результат как N2
AND N1 N2 N3 Выполнить поразрядное «И» N2 и N1, возвратить результат как N3
BRANCH Выполнить безусловный переход по адресу, лежащему в памяти сразу после кода команды
D! D1 ADDR Сохранить число двойной точности D1 в двух последовательных ячейках памяти, начиная с адреса ADDR
D+ D1 D2 D3 Сложить числа двойной точности D1 и D2, возвратить результат как D3
D@ ADDR D1 Выбрать из памяти, начиная с адреса ADDR, число двойной точности, возвратить результат как D1
DDROP D1 Удалить из стека число двойной точности D1
DDUP D1 D1 D1 Создать копию числа двойной точности D1
DNEGATE D1 D2 Создать дополнение до двух числа двойной точности D1, возвратить результат как D2
DROP N1 Удалить из стека N1
DSWAP D1 D2 D2 D1 Поменять местами два числа двойной точности D1 и D2
DUP N1 N1 N1 Создать в стеке копию числа N1
I N1 Выбрать из стека возврата текущее состояние счётчика активного цикла, возвратить результат как N1
I' N1 Получить предел активного цикла, возвратить результат как N1
J N1 Получить текущее состояние счётчика внешнего цикла для вложенных циклов
LEAVE Присвоить счётчику цикла в стеке возврата значение предела, чтобы вызвать выход из цикла
LIT N1 Рассматривать содержимое памяти сразу после кода команды как целое число, возвратить результат как N1
NEGATE N1 N2 Получить дополнение до двух для N1, возвратить результат как N2
NOP Ничего не делать
NOT FLAG1 FLAG2 Инвертировать значение FLAG1, возвратить результат как FLAG2. Синоним слова «0=»
OR N1 N2 N3 Получить поразрядное «ИЛИ» N2 и N1, возвратить результат как N3
OVER N1 N2 N1 N2 N1 Создать копию второго сверху элемента N1, возвратить результат как N1
PICK ... N1 ... N2 Создать копию N1-го элемента стека, возвратить результат как N2. В Forth-83, «0 PICK» эквивалентно «DUP», а «1 PICK» эквивалентно «OVER»
R> N1 Забрать верхний элемент из стека возврата, возвратить результат как N1
R@ N1 Создать копию верхнего элемента стека возврата, возвратить результат как N1
ROLL ... N1 ... N2 Забрать из стека N1-ый элемент, устранить дыру, возвратить результат как N2. В Forth-83 «1 ROLL» эквивалентно «SWAP», а «2 ROLL» эквивалентно «ROT» [* а «0 ROLL» должно быть синонимом «NOP», если я правильно понял ]
ROT N1 N2 N3 N2 N3 N1 Извлечь из стека третий сверху элемент, возвратить результат как N1
S->D N1 D2 Расширить знак элемента N1, возвратить результат как число двойной точности D2
SWAP N1 N2 N2 N1 Поменять порядок расположения N1 и N2
U< U1 U2 FLAG Возвратить FLAG «ИСТИНА», если при беззнаковом сравнении U1 меньше U2
U> U1 U2 FLAG Возвратить FLAG «ИСТИНА», если при беззнаковом сравнении U1 больше U2
U* N1 N2 D3 Выполнить беззнаковое целочисленное умножение N1 на N2, возвратить результат как беззнаковое число двойной точности D3
U/MOD D1 N2 N3 N4 Выполнить беззнаковое целочисленное деление числа двойной точности D1 на N1, возвратить результат как частное N4 и остаток N3
XOR N1 N2 N3 Выполнить поразрядное «ИСКЛЮЧАЮЩЕЕ-ИЛИ» N2 и N1, возвратить результат как N3

Previous part:

Next part: