До того, как писать FORTH

Перейти вниз

До того, как писать FORTH

Сообщение автор Gudleifr в Вс Сен 10, 2017 10:30 pm

Раздел, который я посвятил написанию своего FORTH, к сожалению, основывается на двух допущениях, которые были верны для меня на момент написания этого раздела, но не на момент, например, написания моих первых FORTH-систем. Более того, эти допущения и сейчас не выполняются для многих вполне заслуженных фортеров.

Я рассчитывал, что:
1. фортописатель достаточно владеет языком, на котором он собирается писать FORTH-систему, чтобы, с одной стороны понимать, что он пишет, и самому искать ошибки, а с другой - почему он отказывается от этого языка в пользу писания на FORTH;
2. фортописатель понимает взаимодействие частей FORTH системы, а не просто копирует "обязательные элементы".

Не буду настаивать на обязательности этих "тайных знаний" для каждого фортера. Попробую ответить на более простой вопрос: можно ли тренировать отдельные элементы FORTH-системы по отдельности? Можно ли получать от этого практическую пользу?

Для начала перечислю части, на которые делю FORTH. Может быть, вы не согласитесь с моим делением на процедуры: ОК, СИМВОЛ, ВЫПОЛНИТЬ, КОМПИЛИРОВАТЬ и СЛЕДУЮЩИЙ. Но я настаиваю, что деление должно проводиться при соблюдении двух Условий:
1. Деление FORTH-системы на "виртуальную машину" и "FORTH-компилятор" - ярчайшее проявление FORTH-дебилизма и, следовательно, попытка реализовать их по отдельности - тоже дурость.
2. Реализовать не сами процедуры, но структуры данных, используемые ими (например, при моем делении это: ПОТОК, ЗНАЧЕНИЕ, СТЕК и СЛОВАРЬ), тоже совершенно бесполезно.


Последний раз редактировалось: Gudleifr (Пн Дек 04, 2017 5:02 pm), всего редактировалось 3 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор Gudleifr в Вс Сен 10, 2017 10:32 pm

ПРОЦЕДУРА ОК

Первые FORTH-системы создавались Муром в те времена, когда считалось, что назначение программы - считать. Т.е. диалог - запрос у пользователя (в те времена - оператора) данных, нужных для продолжения работы, был редкостью. Никакой симметрии файлов/каналов ввода-вывода. Процедура ОК - подготовки FORTH к пользовательскому вводу - изначально очень проста: вывести "Ок" или сообщение об ошибке... и все. Ждать новую порцию данных и команд для их обработки.

К поголовному переходу на операционные системы, ориентированные на процессы, FORTH, как и BASIC, оказался совершенно не готов. Единственное, на что хватило программистов - создать консоль средствами манипулирования файлами. Дальше началась партизанщина: большинству, как и мне, хватало переназначения потоков ввода-вывода средствами операционной системы (пусть FORTH думает, что я руками набиваю, а, на самом деле, я ему заранее готовый файл подсуну). А в FORTH-стандартах прописывался "стек параметров ввода", сохраняющий переменные - текущий канал, буфер, позиция... Причем, управление этим "стеком" ошибочно приписывалось процедуре СИМВОЛ. Написание процедуры ОК стало походить на старый игровой наладонник "Ну, погоди!". Из системы сыпятся сообщения-яйца, а программа-волк должна их всех поймать.

Еще хуже стало с переходом на системы, ориентированные на сообщения - Винды всякие. Теперь ОК должна не только "ловить яйца", но и сама рисовать "волка" (диалоговое окно).

Написание процедуры ОК стало предметом курса "Операционные системы".

Как можно освоить такую технологию? Видимо, только одним способом - написать свою реал-таймовую игру. Простенького "Марио" какого-нибудь. Т.е. нужна процедура, способная обработать самые разные входные сообщения: "таймер", "новый экран", "неудачная попытка", "конец игры" (ориентируясь на средства используемой операционной системы). Самое главное, обработка всех этих ситуаций должна заканчиваться переходом в одну и ту же точку - "готов распознать полученное сообщение" - главного цикла программы. Если Вы будете распознавать "сигналы операционной системы" в одном месте, а "команды пользователя" в другом, ничего не выйдет. Сможете свести весь ввод в единообразную форму, распознаваемую в единственном месте программы? Сможете избавиться от вложенных циклов, сведя все к одному?

Практическая польза от такого упражнения, конечно, минимальна. Процедура ОК - не сила FORTH, а его слабость. Так что, вы только научитесь управлять программой из самого неудобного места (например, это может пригодиться в CGI-программировании, где диалоговые данные должны быть введены в программу при ее перезагрузке). Ну, еще, присоединитесь к легиону изобретателей универсальных интерфейсов.
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор Gudleifr в Пн Сен 11, 2017 5:19 pm

ПРОЦЕДУРА СИМВОЛ

Распознавание символов (по терминологии фортеров - слов). Из всего FORTH эта процедура проработана, лучше всего. Ведь, она самя большая и самая основополагающая. Поэтому так странно видеть старание "структурных фортеров" вынести ее за пределы "виртуальной FORTH-машины". Более того, проработаны даже отдельные ее части (их названия, правда, варьируются у разных авторов):
EXPECT или ACCEPT - логическое формирование бесконечного ПОТОКА символов (за физическое отвечает ОК);
WORD - считывание из ПОТОКА символа за символом;
FIND - поиск символа в СЛОВАРЕ;
NUMBER - попытка распознать символ, как литерал;
необязательные попытки поискать в других местах или изменить способ распознавания.

Кроме использования этих процедур в обычном порядке, часто встречаются их вызовы по отдельности для решения частных задач. Однако, упражняться в реализации этих отдельных частей совершенно не интересно. В программистской практике, они встречаются чуть более, чем постоянно. EXPECT - буферизированный ввод, WORD - работа со строками, FIND - ассоциативный массив, NUMBER - конечный автомат... Все в простейшей форме.

Где же можно встретить полезное применение СИМВОЛА? Конечно, в разнообразных интерпретаторах: от Машины Тьюринга до Lisp. Здесь важно подчеркнуть, что символами совершенно не обязательно должны быть "слова, разделенные пробелом". Win-сообщения, символы ленты Машины Тьюринга, переменные окружения, кнопки в игре... Т.е. даже если вы для тренировки напишете adventure-игру, то основное внимание надо будет уделить не парсированию команд на естественном языке, но анализу и накоплению распознаванию введенного (формированию ЗНАЧЕНИЯ - слова, оборота, предложения).
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор _KROL в Пн Сен 11, 2017 5:52 pm

Так ПРОЦЕДУРА СИМВОЛ существует как одно слово, или это набор тех самых EXPECT,WORD и т.д?

_KROL

Сообщения : 86
Дата регистрации : 2017-07-28
Возраст : 19
Откуда : Беларусь

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор Gudleifr в Пн Сен 11, 2017 6:00 pm

_KROL пишет:СИМВОЛ существует как одно слово, или это набор..?
Набор - ТЕМА #42. Если для некоторых из специфицеских ПОТОКОВ что-то и можно подсократить (или добавить), то устройство СИМВОЛА стало вполне каноническим. Другое дело, что достаточно часто этот канон мешает программисту задать себе вопрос: что же именно делает эта процедура и зачем?


Последний раз редактировалось: Gudleifr (Пт Янв 26, 2018 1:35 pm), всего редактировалось 2 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор Gudleifr в Вт Сен 12, 2017 1:26 pm

ПРОЦЕДУРА ВЫПОЛНИТЬ

Она очень проста - выполнить команду по указанному адресу или запомнить этот адрес на будущее (скомпилировать). Единственная "технология", здесь, на первый взгляд - обращение с адресом кода, как с прочими данными. Она ошибочно считается исключительной принадлежностью языков, способных к адресной арифметике, например, языка C. Кроме того, она считается неприличной в хорошем обществе и от нее не только отказались C++-программисты, но, даже, не особенно жалуют, даже, фортеры.

Необходимость этой технологии следует из золотого правила программирования (о его применении можно посмотреть в книге Броуди СПОСОБ МЫШЛЕНИЯ - ФОРТ - ТЕМА #3, АБЗАЦ #360.
1. если вещь может бы рассчитана по формуле (без жуткого роста накладных расходов) - так и сделай;
2. если одной формулой не обойтись, составь таблицу;
3. только, если и таблицы не получается - пиши сложный алгоритм.
Как раз, для удобного составления таблиц действий по п.2, адреса функций очень полезны.

И, конечно, используя простейшие трюки, таблицы действий можно создавать и без доступа к честной адресной арифметике, даже в BASIC-ах. Например, см. EXPRESSOR III - ТЕМА #14.

Так что, полезным упражнением здесь будет попытка переписать одну из своих старых программ со сложной логикой в программу с одной-двумя управляющими таблицами (как это делается, можно посмотреть у того же Броуди). Дейкстра: "С некоторой гордостью, он показал нам таблицу решений - его таблицу,- которая, как он считал, могла решить задачу..." В данном случае важнее научиться строить таблицы, чем работать с адресной арифметикой.

Заодно можно сравнить две технологии - хранения/накопления параметров функций в той же таблице и/или обращения их к общей структуре данных (это совсем не обязательно должен быть стек).

ЗАМЕЧАНИЕ 1. Дилемма выполнить/компилировать, бросающая вызов изобретательности фортеров уже долгие годы, совершенно не является чем-то окончательно важным. Возможны и более философские решения: заменить оба эти действия каким-то нейроно-подобным "возбуждением", иметь не одно текущее слово, а целую очередь "желательных к исполнению"... и т.д.

ЗАМЕЧАНИЕ 2. С этой атомарной процедурой связана еще одна философская проблема. Что оказывает большее влияние на свойства языка программирования: формат структуры данных для обмена между вызываемыми процедурами или потребности проблемной области (формат таблицы решений)? Что важнее: СТЕК или ЗНАЧЕНИЕ? Мур разрубил этот гордиев узел одним махом: и СТЕК, и ЗНАЧЕНИЕ, суть, вырожденные структуры данных, достаточные только для интерпретации ПОТОКА, следовательно, вашему языку просто не от чего зависить, кроме как от решаемой задачи.


Последний раз редактировалось: Gudleifr (Ср Дек 06, 2017 1:12 pm), всего редактировалось 1 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор Gudleifr в Вт Сен 12, 2017 8:38 pm

ПРОЦЕДУРА КОМПИЛИРОВАТЬ

И, опять, на первый взгляд, все просто. По сути, всего одна операция - "запятая" - скомпилировать ЗНАЧЕНИЕ в СЛОВАРЬ. (Для удобства есть и более мелкая - "запятая-C" - скомпилировать байт). Остальные операции компиляции - вызов несколько "запятых" подряд, например, ENTRY - для создания целиком заголовка нового слова и его привязки к ранее скомпилированным. Что тут сложного?

Трудности начинаются с рассмотрения первоначального варианта интерпретатора Мура - ТЕМА #42, АБЗАЦ #408. Тут мы видим, что символы из ПОТОКА и СЛОВАРЯ абсолютно равноправны в смысле их исполнения. Значит, именно процедура КОМПИЛИРОВАТЬ (а не ОК) является обратной к процедуре СИМВОЛ. СИМВОЛ читает ПОТОК, а КОМПИЛИРОВАТЬ пишет в подобную же структуру. Но, если в модели Дейкстры - ТЕМА #38 - СЛОВАРЬ был практически изоморфен ПОТОКУ, в реализации Мура все стало совсем плохо. СТЕК отдан нод нужды СИМВОЛ и ВЫПОЛНИТЬ - на КОМПИЛИРОВАТЬ почти ничего не остается. Все сложные обороты из нескольких слов интерпретируются самими словами, т.о. чтобы что-то подобное работало в шитом коды, надо компилировать сложные обороты, для чего процедура КОМПИЛИРОВАТЬ должна вызывать еще более сложные процедуры. Сравнение оборотов в ПОТОКЕ и шитом коде см. в таблице - ТЕМА #42, АБЗАЦ #404.

Выход один: ввести в СЛОВАРЬ специальные слова, цель которых - хранить место "дыры". Механизм оказался столь удачным, что вполне заменяет создание каких-либо структур данных. Что делает VARIABLE ? Нет, она не создает переменную. Она оставляет дыру, в которую можно будет затем скомпилировать новое значение.

Где можно попрактиковаться в компиляции кода, да еще в условиях дефицита памяти? Дык, это же игра Core Wars! Скачать пару боевых программ и попробовать их переиграть...


Последний раз редактировалось: Gudleifr (Ср Дек 06, 2017 1:15 pm), всего редактировалось 1 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор Gudleifr в Вт Сен 12, 2017 8:40 pm

ПРОЦЕДУРА СЛЕДУЮЩИЙ

Тут все, на самом деле, просто. Голову сломать нужно всего один раз - понять, как может интерпретироваться программа без наличия интерпретатора. Первые модели Дейкстры и Мура были гораздо более явно интерпретирующими, чем их потомки. Даже современные FORTH-системы с косвенным или подпрограммным шитым кодом не тянут на ту степень безумия, которая нужна для программирования в прямом шитом коде. Тут надо начинать с самого начала - с первой главы Искусства программирования Кнута. Она как раз заканчивается подпрограммами, сопрограммами и прочими интерпретаторами...
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор Gudleifr в Вт Сен 12, 2017 8:51 pm

Напоследок, нужно заметить, что многие FORTH-фичи, суть, не какие-то особенные, только ему свойственные инвенции, но давно и плодотворно используемые штуковины, только по-другому названные. Т.е. надо не столько, высунув язык от прилежания, списывать у профессионалов их решения, сколько быть готовым посмотреть на давно известные вещи с неожиданной стороны.
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор Gudleifr в Ср Сен 13, 2017 1:48 pm

Попробую пояснить, что подразумеваю под "частичным FORTH". Для примера возьму недописанную программу (на классическом C), реализующую в HTML лучшую советскую компьютерную игру "Путь к Земле" - гибрид фантастической книги с постепенно усложняющимся симулятором космических полетов. Почему я остановился только на первых главах этой игры? Очень долго не мог решить, какой интерфейс присобачить, а сейчас моя страничка издохла...

Зачем тут FORTH?

Первая особенность программы порождена ее CGI-природой: пользовательский ввод может анализироваться только при перезагрузке страницы. Т.е. на момент запуска программы программа должна получать информацию и о своем текущем состоянии, и о действиях пользователя на прошлом ходу. Т.о. асимметричный ввод - ОК-СИМВОЛ смотрится вполне естественно.
ОК информирует пользователя об игровых событиях и состоянии корабля и тут же формирует область ввода, куда пользователь может вбивать информацию о своих действиях.

Код:
/* Печать Form - перебор всех переменных всех модулей */
form()
{
   int i, j;
   printf("<h3>%s</h3>", model[mdl].s);
   printf("<table border=1>");
   for (i = 0; i < dim(module); i++) {
      if (!getkey(module[i].k))
         continue;
      printf("<tr><td><h3>%s</h3>",module[i].s);
      for (j = 0; j < dim(text); j++)
         if (module[i].n == text[j].n && getkey(text[j].k))
            printf("%s = <input name=%c%d"
               " value=%f> %s<br>",
               text[j].s, text[j].n, j,
               *text[j].v, text[j].e);
               /* name = буква (модуль) +
                  + номер (в таблице text) */
      printf("</td></tr>");
   }
   printf("</td></tr></table>");
   printf("<input type=submit value=\"Прогон\">");
   printf("<input type=hidden name=S0 value=%d>", mdl);
      /* номер модели */
   printf("<input type=hidden name=S1 value=OK>");
      /* отсутствие этого ключа при первом запуске означает,
         что считать еще нечего */
   return (0);
}

Здесь нет никаких хитростей, кроме того, что эта процедура ничего не анализирует, и тем, не менее универсальна, т.к. все определяется таблицами: model, module, text. По сути, это одна таблица "место параметра в модели", приведенная в нормальную форму (общие поля модулей и моделей вынесены в отдельные таблицы, чтобы не повторять их для каждого параметра). СЛОВАРЬ, однако.
Страшненький вид этой процедуры вызван только жуткой избыточностью HTML-формата.

Код:
/* Модель - Заголовок - Main-функция */
struct {
   char n, *s;
   int (*f)();
} model[] = {
   '0', "ЛУНОЛЕТ-1", l1,
   '1', "ЛУНОЛЕТ-2", l2,
   '2', "ЛУНОЛЕТ-3", l3,
   '3', "МНОГОСТУПЕНЧАТАЯ РАКЕТА", mr,
   '4', "МАСКОН", ms,
   '5', "ВЕРШИНА", wr,
   '6', "ОС-1", o1,
   '7', "ОС-2", o2,
   '8', "ОС-3", o3,
   '9', "ЛУНОЛЕТ-4", l4,
   'A', "КЕПЛЕР", kp,
   'B', "АТМОСФЕРА-1", a1,
   'C', "АТМОСФЕРА-2", a2,
   'D', "УГАДАЙ ТЯГОТЕНИЕ", l1
};

/* Form-модуль - Заголовок - Использование в моделях */
struct {
   char n, *s, *k;
} module[] = {
   'K', "КОРАБЛЬ", "*",   /* "*" - везде */
   'M', "ЛУНА", "-BCD",   /* "-" - кроме */
   'O', "СТАНЦИЯ", "6789",
   'E', "ЗЕМЛЯ", "ABC",
   'P', "СОСТОЯНИЕ", "*",
   'I', "ВВОД", "*"
};

/* Form-модуль - Расшифровка переменной - Ед.изм. -
   - Использование в моделях - Адрес переменной */
struct {
   char n, *s, *e, *k;
   double *v;
} text[] = {
/* 00 */   'K', "Масса", "кг", "-A", &m,
/* 01 */   'K', "Скорость истечения", "м/c", "-AC", &vt,
/* 02 */   'K', "Емкость топливных баков", "кг", "-AC", &mm,
/* 03 */   'K', "Минимальное время реакции", "с", "01", &t0,
/* 04 */   'K', "Расход", "ед./с", "0", &t1,
/* 05 */   'K', "Предельная перегрузка", "м/с2", "01D", &gm,
/* 06 */   'K', "Максимальная площадь сопротивления", "м2", "BC", &s2,
/* 07 */   'K', "Отношение макс. сопротивления к мин.", "раз", "C", &ds,
/* 08 */   'M', "Ускорение силы тяжести", "м/с2", "-ABCD", &g,
/* 09 */   'M', "Радиус", "м", "-01ABCD", &r0,
/* 10 */   'M', "Глубина маскона", "м", "4", &ya,
/* 11 */   'M', "Высота горы", "м", "5", &ya,
/* 12 */   'M', "Мощность маскона", "м/с2", "4", &ga,
/* 13 */   'M', "Полуширина горы на полувысоте", "м", "5", &xa,
/* 14 */   'M', "Радиус орбиты", "м", "9A", &rm,
/* 15 */   'M', "Удаление точки либрации от центра Луны", "м", "9A", &rl,
/* 16 */   'O', "Радиус орбиты", "м", "6789", &ro,
/* 17 */   'O', "Полувысота/радиус станции", "м", "78", &xo,
/* 18 */   'O', "Радиус площадки", "м", "7", &xx,
/* 19 */   'E', "Радиус", "м", "9ABC", &re,
/* 20 */   'E', "Ускорение силы тяжести", "м/с2", "9ABC", &ge,
/* 21 */   'E', "Характерный масштаб атмосферы", "м", "BC", &am,
/* 22 */   'E', "Плотность воздуха на уровне моря", "кг/м3", "BC", &p0,
/* 23 */   'P', "Запас топлива", "кг", "-AC", &mt,
/* 24 */   'P', "Запас", "ед.", "0", &t,
/* 25 */   'P', "Верт. координата", "м", "*", &h,
/* 26 */   'P', "Верт. скорость", "м/с", "*", &v,
/* 27 */   'P', "Гор. координата", "м", "-029ABD", &x,
/* 28 */   'P', "Долгота", "град", "29BA", &fi,
/* 29 */   'P', "Гор. скорость", "м/с", "-0D", &u,
/* 30 */   'I', "Впрыск", "кг", "-AC", &dmi,
/* 31 */   'I', "Промежуток", "с", "*", &dti,
/* 32 */   'I', "Угол", "град.", "-0BD", &ali,
/* 33 */   'I', "Реактивное ускорение", "м/с2", "D", &a
};

Пройдя через механизм перезагрузки страницы, блок информации приобретает гораздо более FORTH-образный вид - поток пар "имя=значение". Не польская запись, конечно, но некоторое управление программой нам такой язык ПОТОКА обеспечивает.

Теперь процедуре СИМВОЛ остается только декодировать, по тем же таблицам (СЛОВАРЮ), ЗНАЧЕНИЕ, описывающее полное состояние программы на текущем ходу.

Код:
/* Загрузка переданных в CGI переменных */
load()
{
   char *s, *v;
   s = strtok(getenv("QUERY_STRING"),"=");
   while (s) {
      v = strtok(NULL, "&");
      if (s[0] == 'S')
         if (s[1] == '0')
            mdl = atoi(v);
         else
            ok = 1;
      else /* буква (s[0]) роли не играет,
         важен только номер переменной */
         *text[atoi(s + 1)].v = atof(v);
      s = strtok(NULL, "=");
   }
   return 0;
}

Процедура ВЫПОЛНИТЬ сводится к сущей ерунде - вызову указанной в таблице model функции с использованием того, что накопилось в ЗНАЧЕНИИ. Никакой СТЕК нам для этого не понадобился.

Процедура СЛЕДУЮЩИЙ получилась вырожденной:

Код:
main(argn, argc)
   char *argc[];
{
   mdl = 0;
   ok = 0;
   begin();
   load();
   if (ok) {
      printf("<h3>РЕЗУЛЬТАТЫ ПРОГОНА</h3>");
      (model[mdl].f)();
   }
   form();
   end();
   return (0);
}

Однако, она должна обеспечивает исполнение алгоритма, характерного для большого числа однопользовательских компьютерных игр:



Поэтому пришлось вложить внутрь ВЫПОЛНИТЬ еще один СЛЕДУЖЩИЙ. И придумать еще один проблемно-ориентированный язык.

В зависимости от положения в алгоритме "внутренние части" космолета описываются по-разному:

Код:
/* Ввод параметров */
#define INPUT dm = dmi; dt = dti; al = ali * M_PI / 180;
/* Проверка ввода */
#define NOINPUT(X, Y) if (X) { printf(Y); return 1; }
/* Начало цикла Расчета */
#define TIMERUN ddt = 0; for (;;) { ddt += dt;
/* Авария? */
#define ALARM(X, Y) if (X) { Y(); continue; }
/* Подвид аварии: конец? */
#define STOP(X, Y) if (X) { Y(); break; }
/* Конец цикла Расчета */
#define TIMEOUT break; } printf("Прошло %fс", ddt);

Благодаря этому стало удобным описывать модели набором одних и тех же кубиков:

Код:
l1()
{
   INPUT
   NOINPUT((dt < t0), "Слишком малое время реакции")
   THRUST
   dm = fabs(dm);
   TIMERUN
      VELOCITY(v, (a - g))
      DISTANCE(h, v)
      t -= t1 * dt;
      ALARM(((mt -= dm) < 0), mtnegate)
      ALARM((h < HNEG), hnegate)
      STOP((h < HMIN), hzero)
      ALARM((mt == 0), mtzero)
      ALARM(((gma = fabs(a) - gm) > 0), greateg3)
   TIMEOUT
   return 0;
}

l3()
{
   INPUT
   NOINPUT((dt <= 0), "Слишком малое время реакции")
   NOINPUT((mt < dm), "Нет столько топлива")
   NOINPUT((dm > DMMAX), "Слишком большой расход топлива")
   mt -= dm;
   THRUST
   TIMERUN
      VELOCITY(u, (a * sin(al) - v * u / h))
      r2 = r0 / h;
      fi += (u + uu) * dt * 90. / 3.14 / h;
      VELOCITY(v, (a * cos(al) - r2 * r2 * g + u * u / h))
      DISTANCE(h, v)
      ALTITUDE(r0)
      VELOCITY1
      ALARM((h2 < HNEG), hnegate3)
      STOP((h < HMIN), hzero)
   TIMEOUT
   NOTE("Высота", h2)
   NOTE("1-ая косм.скорость", v1);
   return 0;
}

И т.д. и т.п.

Как-то так...
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор _KROL в Ср Сен 13, 2017 5:53 pm

Gudleifr пишет:Где можно попрактиковаться в компиляции кода, да еще в условиях дефицита памяти? Дык, это же игра Core Wars! Скачать пару боевых программ и попробовать их переиграть...
Ты мне прям подарок сделал! Спасибо, CodeWars не знал.

_KROL

Сообщения : 86
Дата регистрации : 2017-07-28
Возраст : 19
Откуда : Беларусь

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: До того, как писать FORTH

Сообщение автор Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения