Шапка

Приложение 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: