Ок, значит, начнём с архитектуры (правда, я тут пивка принял, так что возможны глюки [img]biggrin.gif[/img])
Начну "с конца".
Два стека.Определение: любой выполняемый токен Форта (оператор, функция, процедура, переменная...) называется
словом. Т.е. программа состоит их слов.
1.
Стек возвратов (классический стек) - при вызове слова из текущего слова адрес места исполнения кладётся в этот стек. Всё, как и в других языках.
2.
Арифметический стек (или просто стек) - используется при выполнении арифметических операций и для передачи данных от слова к слову. Классический Форт использует обратную польскую (бесскобочную) запись для арифметических выражений.
Часто в конкретных реализациях добавляют ещё стеки (например, стек для чисел с плавающей точкой, стек для строк), а бывает, что всё хранят и в основном стеке.
Есть широкий спектр слов для работы с обеими стеками.
Дополнение: слова Форт-программы выполняются строго одно за другим (ветвления и циклы делаются также, но об этом, если интересно, попозже): каждое слово что-то берёт со стека данных, что-то с этими данными делает и кладёт снова эти данные на стек:
DROP - просто удалить число с вершины стека
DUP - продублировать число на вершине стека
+ - сложить число на вершине стека с числом, находящимся под ним и результат положить на вершину стека.
Т.е., например,
1 + - положить единицу на стек и добавить её к тому, что там было до этого. Т.е. фактически увеличить число на вершине стека на 1.
Или
DUP + - продублировать число и выполнить сложение - фактически тоже самое, что умножить его на два.
По поводу компактности.
Релизаций много (скажем, упомянутый мною SP-Forth - "чистый" компилятор - генерирует обычный машинный код под Win32). Но классический Форт имеет так называемый "шитый код" (чаще "прямой") - это когда программа в скомпилированном виде состоит не из машинных кодов, а из адресов слов, которые в свою очередь являются или Форт-словами, или уже чистым машинным кодом. Обычно размер записи под адрес слова равен разрядности шины адреса ЭВМ, так что для 16-битной ЭВМ вызов любого слова записывается в 16 бит (при вызове подпрограммы на ассемблере нужно уже минимум 24 бита - байт на код вызова, два байта на адрес) - уже выигрыш по компактности перед ассемблером. А если размер программ особенно критичен, то можно перейти и к байт-коду (как на Java). Есть ещё косвенный шитый код когда хранится не адрес процедуры, а адрес ячейки, где прописан адрес процедуры - он был очень эффективен на DEC-овской архитектуре, но сейчас практически не используется. Не смотря на кажущиеся большие затраты на вызов слов прямого шитого кода, на самом деле возможен даже прямой выигрыш перед ассемблером (блин, я четыре года не программил на асме, так что возможны ошибки):
mov ax,[bx] ;предположим, что в [bp] у нас указатель
;на исполняемое слово
add bx,2 ;запомним адрес следующего слова
jmp [ax] ;переход по этому адресу
По тактам это (не помню на счёт 8086 и 286, но с 386 - точно) выгоднее, чем call addr
На архитектурах, допускающих автоинкрементациию это делается вообще в одну команду:
jmp (r5)+;
Этими цепочками завершается каждое ассемблерное слово на Форте. Т.е. каждое слово само отвечает за передачу управления следующему. Эффективность начинает падать, когда приходится вызывать Форт-слова: в начале каждое слово должно сохранить на стек возвратов указатель исполнения предыдущего слова и запустить этот самый механизм исполнения. А в конце выполнить восстановление стека возвратов. Т.е. вызов Форт-слов происходит медленнее, чем ассемблерных слов (CODE-слов). Выход - или стараться использовать низкоуровневые слова (что ухудшает стиль программирования - об этом отдельно, если будет интересно), или писать компилятор Форта в машинный код (снижается гибкость и усложняется написание компилятора), или писать критические слова на ассемблере (падает переносимость).
К слову об ассемблере и эффективности Форта... Когда мне потребовался Форт-ассемблер под 32-х битный Форт (это был 1995-й год и готовых решений не было) я написал с нуля полноценный 32-х битный ASM для Форта за два дня. Кто-то может себе представить такое для другого языка?