[Tech] Учимся работать с FORTH

Тема в разделе "Руководства", создана пользователем Ookami, 19 авг 2012.

  1. Ookami

    Ookami
    Архитектор
    1.242
    383
    388
    Заготовка статьи, будет наполнять по мере поступления/изучения материала. По завершению будет выложена на нашу Вики.

    Итак, начну с того, чего вы НЕ найдете в этом гайде: рецептов крафта компонентов компьютера и самых-самых основ языка (как вывести на экран, как объявить переменную). Что будет рассмотрено:
    1) Основы языка FORTH (Форт).
    2) Применение компьютера в сложных схемах.
    3) Примеры программ.

    1. Основы языка.
    Вышесказанное, при переводе на русский, означает следующее: программы на Форте пишутся в стиле Магистра Йоды. Рассмотрим простейший пример 2+2:
    Код:
    2 2 +
    Т.е. сначала мы перечисляем, с чем мы выполняем операцию, а потом - что именно мы с этим делаем. То же самое касается не только арифметических функций, но и условий, и циклов, и работы с переменными.

    2. Работа со стеком.
    Попробуем разобраться со стеком. Стек - структура данных, доступ к которой организован по принципу ЛИФО (LIFO - last in, first out), т.е. элемент, попавший в стек последним, выйдет из стека первым.

    При работе с Фортом, важно понимать порядок записи в стек и чтения из него.
    Запись в стек.
    Записывается в стек все, что не используется в текущей команде и не выводится на печать. Т.е. если мы ввели или получили в результате вычислений какое-то значение, при этом не вывели его на печать или не записали в переменную, то оно попадает в стек.
    Чтение из стека.
    Чтение из стека происходит, когда для выполнения текущей команды нужно какое-то входное значение, и оно не указано явно при вызове команды. При этом элемент из стека удаляется.
    Примеры.
    Обобщив вышенаписанное, рассмотрим примеры. Сперва запишем в стек 2 числа - 1 и 2:
    Код:
    1
    2
    .S
    
    Последняя строка выведет на экран содержимое стека. Так мы убедимся, что оба числа попали в стек, при этом, как было сказано выше, из стека они будут браться в обратном порядке - сначала 2, потом 1. Теперь сложим их, сначала с выводом результата, потом без него, и сравним состояния стека:

    Код:
    + .
    .S
    
    На экран будет выведено 3, стек пуст т.к. 1 и 2 были изъяты для выполнения сложения, а результат в стек не был записан так как его вывели на экран. Теперь еще раз введем 1 и 2 в стек и выполним второе сложение:
    Код:
    1
    2
    +
    .S
    
    Результат сложения на экране мы не увидим, но зато он у нас появился в стеке.

    Подведу итог. Если мы что-то вычисляем и результат не используем, то он попадает в стек. Если мы что-то вычисляем, но при этом не указываем значения - оные берутся из стека. При этом, если в стеке недостаточно значений, будет выведено сообщение об ошибке Empty Stack.

    3. Арифметические функции.

    4. Общение компьютера с внешним миром.
    Общение происходит через блок IO Expander, подключенный к компьютеру плоской шиной данных (Ribbon Cable), а к внешнему миру - многожильным проводом (Bundled Cable). Может обращаться к жилам по коду цвета:
    IOX@ Получить состояние шины. Возвращает сумму кодов жил, на которых в данный момент есть сигнал (например, при включенных белой и оранжевой жилах вернет 3)
    ### IOX! Установить состояние шины. Так же, суммой, т.е. если мы хотим включить белую и оранжевую жилы надо написать 3 IOX!
    ## IOXSET Включить сигнал на указанной жиле (не шине!)
    ## IOXRST Выключить сигнал на указанной жиле (не шине!)
    Часто возникает необходимость проверить состояние не всей шины, а какой-то определенной жилы. Наиболее оптимальное решение, которое удалось найти:
    Использование:
    Код:
    4 check
    Записывает в стек 1 если на указанном (4) проводе есть сигнал, и 0 если нет

    ...
    Тра-та-та, тра-та-та, мы везем с собой кота
    ...

    Суть задачи, которую хотелось бы решить в ходе данного гайда:
    Есть дверь 3х3, собранная из фреймов и 2 моторов. По обе стороны двери на полу лежат нажимные плиты. При нажатии плиты дверь открывается (поднимается), спустя 5 секунд закрывается (опускается). Как построить такую дверь и правильно подключить моторы рассказывать не буду, это данного гайда не касается. Рассмотрим, что у нас есть по факту (условие задачи):
    1. Компьютер
    2. 16-жильная шина
    3. Освещение из РП лампочек (белый провод)
    4. Нажимные плиты (оранжевый провод)
    5. Мотор для поднятия двери М1 (сиреневый провод) (magenta)
    6. Мотор для опускания двери М2 (голубой провод)

    Теперь, напишем обобщенный алгоритм действий:
    1. Ждем нажатие плиты. Если плита нажата то переходим к следующему пункту.
    2. Открываем дверь.
    3. Ждем 5 секунд.
    4. Закрываем дверь.
    5. Переходим к п.1.

    Теперь немного углубимся. Для открытия/закрытия двери мотору надо совершить 3 движения, т.е. принять 3 импульса, с интервалом 0.8 секунды (16 тиков). На практике замечено, что при коротком импульсе фреймы движутся рывками, поэтому подавать импульс мы будем длинный (12 тиков), и делать паузу 4 тика. Итак, опишем новое слово для 1 импульса по проводу, номер которого берем из стека:
    Если обозначить номер провода переменной N, то вызывать данное слово будем так:
     
    Jerubbaal, Shelf74, Towuk и ещё 1-му нравится это.