F+ 2E F* ; \ складываем A и B, и умножив на 2, оператором F*, получаем периметр
Проверим. Посчитаем площадь и периметр прямоугольника со сторонами 0,2 и 0,3:
2E-1 3E-1 B3
Ok
F. F.
1.0000000 0.0600000 Ok
Сначала выводит периметр затем площадь, чтобы изменить порядок как указано в стековой нотации нужно набрать команду FSWAP перед печатью результатов, то есть:
2E-1 3E-1 B3 FSWAP F. F.
0.0600000 1.0000000 Ok
Результаты по-прежнему верны.
Вы можете спросить зачем такие сложности? Код становится универсальным, мы отделяем вычисляемую часть от метода вывода данных на экран, его можно включать в свои библиотеки, и использовать в других задачах как отдельную функцию.
Как вы уже могли заметить одно замечательное свойство Форта – его слова-функции не только принимают любое количество аргументов, но также оставляют на стеке желаемое число результатов, не каждый ЯП может этим похвастаться.
Пример 5. Здесь вычисляется объем куба и площадь его боковой поверхности. Вначале приведем работу с целочисленным аргументом.
: B5 ( A -> V S ) DUP 2DUP * * SWAP DUP * 6 * ; \ V=A^3 S=6*A^2
Поясним код:
DUP 2DUP ( A -> A A A A )
2DUP, в отличие от DUP дублирует сразу 2 верхних элемента
* * ( A A A A -> A A*A*A=A^3 )
двойное применение операции умножения дает в результате куб
SWAP ( A A^3 -> A^3 A )
SWAP просто поменял местами два верхних элемента на стеке
DUP * (A^3 A -> A^3 A*A )
возвели в квадрат число на вершине стека
6 * (A^3 A*A -> A^3 6*A^2)
и умножили его на 6, число сторон куба
Вызовем написанное слово с параметром 15 (сторона куба):
15 B5
Ok ( 3375 1350 )
3375=15*15*15 и 1350=6*15*15, все верно, слово работает корректно.
То же самое в вещественных числах:
: B5 ( A -> V S ) \ V=A^3 S=6*A^2
FDUP FDUP FDUP ( A -> A A A A ) \ 2FDUP SP-Forth не понимает
F* F* ( A A A A -> A A*A*A=A^3 )
FSWAP ( A A^3 -> A^3 A )
FDUP F* (A^3 A -> A^3 A*A )
6E F* ; (A^3 A*A -> A^3 6*A^2)
Проверим написанный код, возьмем куб со стороной 1,5:
15E-1 B5 F. F.
13.500000 3.3750000 Ok \ 6*1.5^2 = 13.5 1.5^3 = 3.375
Помните, что оператор «F.» печатает то, что лежит на вершине стека. Если вам нужен другой порядок можно применить FSWAP, так при необходимости вывести сперва объем, как в стековой нотации, можно набрать следующее:
15E-1 B5 FSWAP F. F.
3.3750000 13.500000 Ok
Пример 6. Здесь необходимо вычислить объем и площадь поверхности прямоугольного параллелепипеда, через его ребра.
: B6 ( A B C -> S V ) \ S=2*(A*B+B*C+A*C) V=A*B*C )
DUP 2OVER \ A B C -> A B C C A B
DUP 2OVER \ A B C C A B -> A B C C A B B C A
ROT * \ A B C C A B B C A -> A B C C A B C A*B
ROT ROT * + \ A B C C A B C A*B -> A B C C A (A*B+B*C)
ROT ROT * \ A B C C A A*B+B*C -> A B C (A*B+B*C) C*A
+ 2* \ A B C (A*B+B*C) C*A -> A B C (A*B+B*C+C*A)*2