Немного про язык программирования Форт (Forth)

02 May 2013


Краткая справка по Форту.

...

Источники информации

Man по gforth: http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/

A Beginner’s Guide to Forth: http://galileo.phys.virginia.edu/classes/551.jvn.fall01/primer.htm

Forth Research at Institut für Computersprachen (Венский технический университет): http://www.complang.tuwien.ac.at/projects/forth.html

Forth stack operators: http://wiki.laptop.org/go/Forth_stack_operators

Wikipedia: [https://en.wikipedia.org/wiki/Forth%28programming_language%29](https://en.wikipedia.org/wiki/Forth%28programming_language%29)

Установить и попробовать

Есть GNU-реализация gforth:

# apt-get install gforth

Интерпретатор работает в интерактивном режиме, окончание работы – конец файла или команда bye:

> gforth                   
Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
1 2 + . 3  ok
19 19 * 360 - . 1  ok
bye

Можно исполнять файлы:

> cat hello.ft 
: HELLO  ( -- )  CR ." Hello, world!" ; 

HELLO 

> gforth hello.ft -e bye

Hello, world!%

Команды и конструкции

Главное

Форт – язык стековый, а программы пишутся в ПОЛИЗ’е (польская инверсная запись): сначала аргументы (“существительные”), потом оператор (“глагол”). Если в результате выполнения оператора получается новое значение – оно помещается в стек и может быть использовано как операнд для следущих операторов или функций. Порядок выполнения операторов полностью определяется тем, в какой очередности они встречаются в исходном коде, скобки не нужны.

9 * ( ( 1 + 2 ) * 3 - 4 ) превращается в 9 1 2 + 3 * 4 - *

Функции

Двоеточие, пробел, имя функции, операторы (тело фунции), точка с запятой: : squared dup * ; Переводы строк – по желанию.

“Контракты”

В документации к каждой функции приводится комментарий, показывающий состояние стека до и после ее вызова, например: swap ( a b -- b a ) или drop ( a -- ). В своем коде тоже стоит писать эти “контракты”: : squared ( a -- a*a ) dup * ;

Вывод

. (точка) – забирает с вершины стека значение и печатает его

.s – печатает состояние всего стека, значения в стеке не меняются

cr – печатает перевод строки

Ввод

accept (c-addr +n1 -- +n2) – читает строку (но не более n1 символов) и записывает их по адресу c-addr. В стеке остается количество действительно считанных символов (n2).

Переменные

variable x
variable y

Прочитать переменную (переместить значение в стек): x @ Прочитать и напечатать переменную: x @ . Записать в переменную значение 5: 5 x !

Прочитать n-й символ из строки str, записать его же (для записи до вычисления индекса в стеке должно быть значение, которое записываем):

str n @ chars + c@
str n @ chars + c!

Манипуляции с стеком

Самые полезные функции:

drop ( a -- a a ) – выкидывает верхнее значение из стека

swap ( a b -- b a ) – меняет местами два верхних значения из стека

dup ( a -- a a ) – берет верхнее значение и еще раз добавляет его в стек

over ( a b -- a b a ) – берет следующее за верхним значение и еще раз добавляет его в стек

pick ( n -- x ) – берет n-е сверху значение из стека и еще раз добавляет его в стек (нумерация начинается с 0)

также см. http://wiki.laptop.org/go/Forth_stack_operators

Цитата из http://galileo.phys.virginia.edu/classes/551.jvn.fall01/primer.htm :

The words PICK and ROLL are mainly useful for dealing with deep stacks. But the current trend in Forth programming is to avoid making the stack deeper than 3 or 4 elements. A deeper stack than that is generally considered a sign that the program has been insufficiently thought out and needs to be factored.

Условный оператор

if(<cond>){<branch1>}else{<branch2>}:

<cond> if 
    <branch1>
else
    <branch2>
then

Забавно, что then в Форте – это окончание условного оператора, эдакий endif.

Циклы

for (i=0;i<10;i++){...}:

10 0 ?do
...
loop

do { ... } while (!flag);:

begin
...
<flag> 
until