На сайте hi-aga.ru вы можете скопировать текст кода программ без искажений, связанные с форматированием текста (исходник книги в формате doc), также возможны некорректное отображение номеров страниц в оглавлении (по той же причине). По ссылке hi-aga.ru вы также найдете дополнительные материалы, не вошедшие в данную книжку. Сайт будет дополняться чаше нежели книжка. Об обнаруженных ошибках, также можете сообщить по контактам на сайте.
Оглавление
0 Введение 3
1.1 BEGIN 1-10 6
1.2 BEGIN 11-20 15
1.3 BEGIN 21-30 21
1.4 BEGIN 31-40 32
2 Integer 1-30 39
3.1 Boolean 1-20 48
3.2 Boolean 21-40 67
4 If 1-30 88
5 Case 1-20 123
6 FOR 1-40 153
7 While 1-30 189
8 Литература 223
Введение
Эта книга поможет вам освоить язык программирования Форт с нуля. Синтаксис этого ЯП (Языка Программирования) настолько прост, что его практически нет. Есть только одно главное правило – все Слова (именно так называются операторы языка и определяемые пользователем слова-функции) и числа должны быть разделены между собой хотя бы одним символом пробела и/или табуляции и/или переноса строки (то есть «любой символ разделитель»).
Для кого этот сайт?
Программирование на этом языке настолько просто, что материал подойдет для детей, не говоря уже обучение, этому прекрасному виду человеческой деятельности, школьников, абитуриентов и студентов. Так что данным материалом может пользоваться любое заинтересованное лицо, независимо от возраста и рода человеческой деятельности. Сложность будет наращиваться постепенно, с нуля, с возможностью подтянуть сложные моменты и пропусков примитивов, уже подготовленными читателями.
Среда программирования SP-Forth – замечательно подойдет для наших целей. Программирование в этом консольном приложении можно начать сразу после быстрого скачивания и установки с официального сайта последней его версии (SP-Forth свободное ПО с открытым исходным кодом). Работать мы будем в режиме интерпретатора. Это значит, что после запуска системы программирования SP-Forth можно вводить команды или целую программу, после, нажав <Enter>, приложение обработает код и выдаст, предусмотренные кодом результаты. Скачивание и установка SP-Forth не должен вызвать никаких сложностей, а потому этот процесс мы здесь опустим.
Исторически сложилось, что основы программирования начинают изучать с первой программы, которая выводит на экран «Hello, World!», что по-русски означает «Здравствуй, Мир!».
Код для ЯП Форт будет следующий:
.( Hello world!)
или
S" Hello, World!" TYPE
После чего на экран будет выведено вышеупомянутое сообщение. Операторы ЯП (язык программирования) Форт <.(> и <S">: первый берет текст, следующий за ним до закрывающей скобки – ")” (признак конца строки) и печатает его на экран, второй создаёт строку адрес которой с ее длиной отправляется на стек. Затем оператор TYPE используя эти числа, адрес и его размер, как параметры также печатает сообщение. Главное «TYPE» должен идти сразу, во избежание ошибок при исполнении, это особенность работы системы. Обращайте внимание на пробелы – в форте они разделяют слова языка. Зачем нужен второй вариант, если первый проще и короче? Затем что он универсальный, так определяются в Форте строки, и они будут полезны в будущем.
Третий вариант этой же программы будет выглядеть так:
: Hello_World ." Hello, World!" ;
Hello_World
Отличие в том, что мы определяем одноименное слово, которое затем вызывается. Первые два варианта работают в режиме интерпретации, а последний, компиляции (в форт-словаре создается новое слово). Будучи универсальным, его можно вызывать многократно из различных мест программы или даже использовать сей код в своих библиотеках.
Так мы написали первую полноценную программку. Вместо Hello_World, вы его можете назвать Start или как захочется, главное придерживаться простого правила – названия должны быть информативными. Стиль программирования на ЯП Форт ничем не отличается от других языков, будет полезно в дальнейшем почитать об этом дополнительно, для правильного оформления своего кода.
Так мы определили новое слово. Определение слова начинается с двоеточия, затем идет любой символ-разделитель (пробел, табуляция или перевода строки). После идёт имя слова, которое вы сами придумаете, далее код – реализация (последовательность операторов, чисел и других уже определённых слов), разделенных пробелами. Завершается точкой с запятой, также отделенный от кода пробелом.
Начало уже положено. Первая программа курса программирования на Форте для начинающих выглядит довольно просто.
Добавим пару штрихов. Комментарии:
Принято в каждом определении нового слова после названия писать комментарий, обозначающий что слово берет со стека в качестве параметров и что оставляет на нем. Перепишем наше первое Форт-Слово:
: Hello_World ( -> ) ." Hello, World!" ; Hello_World
Так как Hello_World оставляет стек без изменений (не трогает его), то до и после стрелки ничего нет. Комментарий – это содержимое скобок.
Также существует второй способ комментирования кода до конца строки. Это символ – «\».
\ это программа, выводящая сообщение «Hello, World!»
: Hello_World ( -> ) ." Hello, World!" ;
Hello_World
Программировать самому не составляет особой сложности даже для совсем начинающих. Это вам не язык программирования С или С++. Все довольно наглядно и просто. Можно практиковать программирование онлайн или офлайн. Для первого варианта существует скрипт транслятор языка форт. Мы же будем ориентироваться на конкретный диалект – SP-Forth. Он существует для разных систем (Windows, Linux).
Обычно вторая задача при обучении программированию – это написание калькулятора. В Форте калькулятор писать не нужно, так как он поддерживает основные операции изначально, правда несколько в необычном формате, которая называется обратная польская запись или постфиксная форма записи. В математике вы привыкли писать формулы в инфиксной форме типа (1+2)*5/(4-5), где знак бинарной операции пишется между числами, к примеру в Лиспе сначала идёт операция, а затем операнд или операнды, а в форте наоборот, сперва мы отправляем на стек операнды, затем операция забирая их оттуда, выполняет действия над ними, оставляя результат там же. Стек это просто место в памяти, поддерживаемое на аппаратном уровне, следовательно, все операции над ними выполняются очень быстро, где будет хранится наши промежуточные данные.
Так будет выглядеть работа с нашим калькулятором:
Операнд1 Операнд2 Операция. То есть вместо 1+2 в Форте мы должны написать «1 2 +».
1 2 +
Ok ( 3 ) \ 1+2=3 в скобках – это содержимое стека
1 2 *
Ok ( 3 2 ) \ 1*2=2 очередной результат на вершине стека
1 2 -
Ok ( 3 2 4294967295(-1) ) \ 1-2=-1, 4294967295 – это без знаковый вариант числа -1
1 2 /
Ok ( 3 2 4294967295(-1) 0 ) \ 1/2=0 – это целочисленное деление, потому результат нуль
1 2 MOD
Ok ( 3 2 4294967295(-1) 0 1 ) \ остаток от деления 1/2
1 2 /MOD
Ok ( [7].. 4294967295(-1) 0 1 1 0 ) \ остаток от деления 1/2 и целая часть 1/2
Вы можете сказать программирование на питоне – гораздо богаче, возможностями и будете правы. Но Форт быстрее и в качестве первого языка программирования гораздо проще и легче его освоить, а самое главное понятнее. Учить программирование на паскале, на мой взгляд, уже совсем не актуально. Хотя он и хорош для изучения различных алгоритмов, но это уже не современный язык программирования, со множеством избыточных конструкций и синтаксиса.
Приведем примеры на SP-Forth.
: ^2 ( A -> A^2 ) DUP * . ; \ возведение числа в квадрат
: ^3 ( A -> A^3 ) DUP DUP * * . ; \ возведение числа в куб
: ^4 ( A -> A^4 ) DUP * DUP * . ; \ возведение числа в четвертую степень
DUP – это слово которое просто дублирует число на вершине стека.
Возведём 5 в квадрат, для этого наберём на клавиатуре:
5 ^2
25 Ok
Получаем правильный ответ. Копировать код нужно аккуратно, так при копировании первого слова, возведения в квадрат, получаем сообщение об ошибке
: ^2 ( A -> A^2 ) DUP * . ;\ возведение числа в квадрат
^ -2003 WORD OR FILE NOT FOUND
При «Копи пасте» куда-то делись символы табуляции между «;» и комментарием, вследствие видим сообщение об ошибке, из-за нарушения синтаксиса.
Также, вместо ^2, можно слово назвать **2, в стиле python:
: **2 ( A -> A^2 ) DUP * . ; \ возведение числа в квадрат
5 **2
25 Ok
В итоге получаем тот же ответ, но стилистика программы изменилась.
Для начала этого достаточно. Далее при решении конкретных задач, в среде программирования SP-Forth, процесс станет более понятным и осознанным.
BEGIN 1-10
Практику программирования начнем с задач из книги М. Э. Абрамян "1000 задач по программированию Часть I Скалярные типы данных, управляющие операторы, процедуры и функции" 2004. Автор пишет, что получить задачник можно по e-mail: mabr@math.rsu.ru или за подробностями обращайтесь к веб ресурсу ptaskbook.com. Текст задач я приводить не буду, дабы исключить плагиат. Думаю, пояснения к коду с описанием слов (функций-программ) должно быть достаточно, в противном случае обращайтесь к первоисточнику за текстом задач.
Пример 1. Итак, начнем, (для простоты вначале мы будем рассматривать все входные параметры как целые числа, далее мы перепишем код для вещественных аргументов, где об этом указано в условии задачи). Вот и решение первой задачи:
: B1 ( A -> P ) 4 * ; \ P=4*A
B – это сокращение от BEGIN, что обозначает первую группу заданий (мы и далее будем использовать такой вид названий в последующих группах заданий), затем слитно пишется номер примера. Сразу после имени в скобках пишется комментарий стековой нотации. Так принято в Форте. В данном случае Слово-функция B1 берет один параметр A (четырехбайтовое целое число и оставляет другое того же типа). A – сторона квадрата – вход функции, P – его периметр – возвращаемое функцией значение. Тело – очень короткое, просто умножает число на вершине стека на 4 (не забываем, что в Форте обратная польская нотация, сначала идут операнды, затем операция).
Теперь чтобы воспользоваться нашим словом, например, чтобы посчитать периметр квадрата со стороной 3, используем следующий код:
3 B1 .
12 Ok
Точка «.» – это стандартное форт слово, которое печатает число на вершине стека на экран.
Напомним, общий вид определения нового слова в Форте:
: Название-Слова ( стек до выполнение –> после ) Код-Тела-Функции ; \ комментарий
Пример 2. Нам нужно посчитать площадь квадрата:
: B2 ( A -> S ) DUP * ; \ S=A^2
Мы просто дублируем содержащееся на вершине стека число (для чего используем оператор языка Форт – DUP) и умножаем его на себя. Данный пример можно оформить более красиво для использования в ваших будущих программах:
: SQR ( A -> A^2 ) DUP * ; \ A^2 – вычисление квадрата числа, или
: ^2 ( A -> A^2 ) DUP * ; \ или
: **2 ( A -> A^2 ) DUP * ; \ отличие только в названии
Какой нравится, тот и можете использовать. Или все сразу, так тоже можно.
Пример 3. По сторонам прямоугольника нужно вычислить его Площадь и Периметр:
: B3 ( A B -> S P ) \ ( S=A*B P=2*(A+B) )
2DUP \ A B -> A B A B – Слово 2DUP, дублирует сразу два числа на вершине стека
* \ A B A B -> A B A*B=S – Площадь вычислен – это просто произведение сторон
ROT ROT \ A*B=S A B – оператор ROT вытаскивает 3-ий от вершины параметр на вершину
\ применив его два раза вытаскиваем A B на верх
+ 2* ; \ складываем A и B, и умножив на 2, оператором 2*, получаем периметр
Слово «2*» делает тоже самое что и два слова «2 *», только короче и проще.
В итоге на стеке мы получаем Площадь и Периметр. Чтобы напечатать результаты на экран из примеров нужно просто ввести точку с клавиатуры «.» и затем нажать «Enter». Сначала напечатается вершина, т. е. периметр, в данном примере, затем повторив действия площадь. Чтобы изменить порядок печати, можно набрать слово SWAP, который меняет местами 2 числа на вершине стека ( A B -> B A), т.е., например чтобы вычислить площадь и периметр прямоугольника со сторонами 1 и 2 введём следующее:
1 2 B3 SWAP . .
2 6 Ok
Площадь равна 1*2=2, а периметр равен 2*(1+2)=6. Слово работает корректно: площадь и периметр вычисляются соответственно стековой нотации, а выводятся по условию задачи.
Пример 4. Нужно вычислить длину круга зная его диаметр:
: B4 ( D -> L ) 314 * ; \ L=Pi*D*100
Ответ буде в 100 раз больше для целочисленных данных, таким образом избавимся от дробной части. Перепишем код, чтобы можно было работать с вещественными числами. Для этого в SP-Forth нужно подключить соответствующие библиотеки. Скопируйте и вставьте следующие две строчки:
S" lib\include\float.f" INCLUDED
S" lib\include\float2.f" INCLUDED
Но можно только вторую строчку.
Теперь чтобы ввести вещественное число, скажем 0,5, нужно набрать на клавиатуре следующее:
5E-1
До E – это мантисса (число), после экспонента (степень). Мантисса и экспонента могут быть как положительными (знак не требуется), так и отрицательными (в данном случае степень -1, что значит 10 в минус первой степени).
После ввода, вещественное число размещается на соответствующем ей стеке, поэтому мы не видим его после вывода слова Ok в скобках, так как это разные стеки для целых и вещественных чисел. Чтобы его увидеть нужно ввести «F.». Итак, чтобы проверить, что всё работает как надо, введём код:
5E-1 F.
В ответ увидим:
0.5000000 Ok
Слово «F.», аналогично, как и «.» выводит число на вершине стека на экран, только не с целочисленного, а вещественного.
Теперь мы можем переписать пример 4 для вещественных аргументов:
: B4 ( D -> L ) \ L=Pi*D
314E-2 F* ;
Посчитаем длину окружности диаметром 0,5, набрав следующее:
5E-1 B4 F. \ вызываем слово, которое считает длину и «F.» печатает ответ
1.5700000 Ok
Переделаем таким же образом первые 3 примера для случая с вещественными аргументами, сделав их более универсальными.
Пример 1:
: B1 ( A -> P ) 4E F* ; \ P=4*A
Знак «*» заменяется на «F*», четверка вводится как вещественное число (операция «F*», в отличие от «*» производит операцию над вещественными числами на вещественном стеке). Теперь проверим, посчитаем периметр квадрата со стороной 0,5:
5E-1 B1 F.
2.0000000 Ok
Ответ 2 (0,5*4=2) что является правдой.
Данный пример, так же можно преобразовать, написав в стиле:
: B1 ( A -> P ) \ P=4*A
4E F*
;
Но он настолько маленький и примитивный, что едва ли это необходимо, проще и лаконичней всё оставить на одной строчке. В более сложных и больших примерах код нужно писать структурированным, понятным и разумеется в едином стиле.
Пример 2:
: B2 ( A -> S ) FDUP F* ; \ S=A^2
Опять DUP превращается в FDUP, умножение как в первом случае. Проверим работу слова. Посчитаем площадь квадрата со стороной 0,5:
5E-1 B2 F.
0.2500000 Ok \ 0,5*0,5 = 0,25
Пример 3:
: B3 ( A B -> S P ) \ S=A*B P=2*(A+B)
FOVER FOVER \ A B -> A B A B
\ Слово FOVER, дублирует слово под вершиной стека на ее вершину т.е. по схеме (A B -> A B A)
\ Повторив его 2 раза получим ( A B -> A B A B )
F* F. \ A B A B -> A B A*B=S
\ Площадь вычислен – это просто произведение сторон
F+ 2E F* F. ; \ складываем A и B, и умножив на 2, оператором F*, получаем периметр
Проверим работу слова B3:
2E-1 3E-1 B3
0.0600000 1.0000000 Ok
Как можете увидеть ниже всё работает верно:
S = 0,2*0,3=0,06
P=2*(0,2+0,3)=2*0,5=1
0,2 и 0,3 можно вводить и в следующем виде: 0.2E и 0.3E. Самостоятельно можете убедиться, что слово «F.» выведет на экран тоже самое значение.
Универсальный вариант того же примера, если вы не хотите сразу печатать результаты обработки в слове:
: B3 ( A B -> S P ) \ S=A*B P=2*(A+B)
FOVER FOVER \ A B -> A B A B
F* \ A B A B -> A B A*B=S
\ Площадь вычислен – это просто произведение сторон
FROT FROT \ A B A*B=S -> S A B
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
Результаты по-прежнему верны.
Вы можете спросить зачем такие сложности? Код становится универсальным, мы отделяем вычисляемую часть от метода вывода данных на экран, его можно включать в свои библиотеки, и использовать в других задачах как отдельную функцию.
Как вы уже могли заметить одно замечательное свойство Форта – его слова-функции не только принимают любое количество аргументов, но также оставляют на стеке желаемое число результатов, не каждый ЯП может этим похвастаться.
Вы можете заметить, что, в примере 3, каждая строка кода сопровождается комментарием, которая поясняет изменения на стеке. Так как все операции и манипуляции, в данном примере, производятся только с вещественным стеком, мы это никак не обозначаем, когда слово будет работать с обоими стеками сразу, вещественный стек будем выделять так: «F: A B A*B=S -> S A B», изменения целочисленного стека дополнительно выделять не будем. Существует еще и стек возвратов. Будьте осторожны, любые неосторожные манипуляции приведут к некорректным результатам, в лучшем случае, в худшем вызовут сообщения об ошибке.
Так же обратите внимание, что комментарии выравниваются так чтобы они выстроились в вертикальную линию, даже те строчки, в которых нет кода, исключительно для удобства чтения.
Пример 5. Здесь вычисляется объем куба и площадь его боковой поверхности. Вначале приведем работу с целочисленным аргументом.
: B5 ( A -> V S )
DUP 2DUP \ A -> A A A A
* * \ A A A A -> A A^3
SWAP \ A A^3 -> A^3 A
На этой странице вы можете прочитать онлайн книгу «Язык программирования Форт (Forth). Решение задач по программированию. Версия 2.», автора Arsen Gonian. Данная книга имеет возрастное ограничение 12+, относится к жанру «Программирование». Произведение затрагивает такие темы, как «обучение программированию», «технология программирования». Книга «Язык программирования Форт (Forth). Решение задач по программированию. Версия 2.» была написана в 2023 и издана в 2025 году. Приятного чтения!
О проекте
О подписке