Про ФОРТ (FORTH)

Apr 12, 2022 15:06

"Вводная" опять поменялась. Возможен оптимистичный сценарий, что QuatCore пойдёт в несколько различных приборов, разрабатываемых разными людьми. Написать код для них для всех я чисто физически не смогу, а людей, которые согласились бы писать код на незнакомом для них ассемблере к процессору незнакомой архитектуры TTA, я чего-то не наблюдаю...

Всё-таки нужно попробовать сделать компилятор с языка высокого уровня, тогда шансы на успех заметно возрастут.

Надо только выбрать, что же за язык взять. Я с начала года приглядывался к FORTH (Форт, не путать с Фортраном), но он оставил во мне смешанные чувства...


Я честно прочитал от начала до конца книжку Starting FORTH от Leo Brodie. И даже начал читать Thinking FORTH от того же автора, но осилил где-то треть, наверное.

Язык безусловно любопытный, всё в обратную польскую запись упихать - это ещё додуматься надо было :)

То, что в обычном языке выглядело бы как if X = 2 then Y = 5 (если X=2, то присвоить Y=5), в FORTH выглядит:

X @ 2 = IF 5 Y ! THEN

X - выдаёт адрес переменной X, кладёт в стек.
@ - "At", т.е "по адресу" - берёт верхнее значение в стеке (адрес переменной) и заменяет на значение, лежащее по этому адресу.
2 - кладёт в стек двойку. Теперь там лежит значение X и двойка.
= - сравнивает два верхних значения на стеке и результат (TRUE или FALSE) кладёт туда же. Теперь в стеке только это одно значение.
IF - делает ветвление на основании значения, которое УЖЕ лежит в стеке. Когда там TRUE, продолжает выполнение, иначе прыгает "после THEN". В любом случае, после IF стек пуст (точнее, там ровно столько же элементов, как и в начале этой строки, что там "ниже" лежало, мы без понятия)
5 - кладёт в стек пятёрку.
Y - кладёт в стек адрес переменной Y
! - в указанный адрес (на вершине стека) закладывает указанное значение (следующее значение в стеке).
THEN - по сути "метка", чтобы знать куда прыгать по IF. Само по себе ничего не делает.

Я в своё время радовался, что в своём QuatCore ушёл от обычных ассемблерных команд вида

OpCode Dest Src

(а то и
OpCode Dest Src1 Src2)

в пользу

MOV Dest Src

и поскольку команда всё равно ровно одна, MOV, то её и писать незачем, выходит просто

Dest Src

Хотя после того, как большинству адресов Dest дашь понятные мнемоники, вроде ADD, Acc, JMP, JL и пр, то начинает выглядеть вполне себе "по-ассемблерному" :)

Но в FORTH меня переплюнули, у них вообще каждое слово (отделённое пробелами) - это по сути своя команда, не требующая никаких аргументов, т.к она заранее знает, где лежат её аргументы - в стеке! И знает, куда положить результат - в стек!

Прочитал я много хороших слов, как это здорово, что язык очень "мелкозернистый", как можно определять свои собственные слова, и они могут совершенно разные вещи делать, что это "язык для построения своего собственного языка, заточенного под твою предметную область".

А ещё - насколько прост у него компилятор. Достаточно "в железе" реализовать несколько базовых слов, а синтаксического разбора практически и не нужно как такового. Подробности я так до конца не изучил пока, там при объявлении слов можно задать действия "на этапе компиляции" и "на этапе исполнения". Тот же IF на этапе исполнения превращается в условный переход, а вот на этапе компиляции даёт "засечку" для слова THEN, что "вот здесь лежит адрес для условного перехода. Положи сюда значение сразу после себя!" Примерно то же самое и с другими конструкциями, вроде циклов. Не нужно делать специальный парсинг, который будет изучать вложенные управляющие структуры, тут оно "само собой получится".

И действительно, когда смотришь приводимые примеры, какую-то "магию" чувствуешь, любопытно.

Но стоит только задуматься о "своих баранах" и как они будут выглядеть на FORTH - и магия куда-то исчезает...

Подумал, может, я что-то не понимаю, стал изучать программы из Journal of Forth applications, уж если они открывают код "для всеобщего обозрения", в журналах издают, там, наверное, хороший, чистый код, пример для подражания.

Взял темы, которые мне близки, стал смотреть. Да блин... Что ни говори о создании собственного языка путём добавления новых слов, но половина кода - это "обслуживание стека". Все эти DUP, DROP, OVER, ROLL, для того, чтобы нужные элементы "вытащить наверх", ненужные удалить, иногда всё продублировать, потому что ближайшая команда их "выкинет", а они нам и в дальнейшем нужны.

Глядя на этот текст, я не могу сообразить, что именно там происходит, пока не начну "исполнять программу", слово за словом, желательно, с бумажкой под рукой, чтобы записать состояние стека в каждый момент времени.

Также видно, сколько мучений появляется, если значение перестаёт умещаться в "один элемент стека". Тогда уже всё двойное.

Применительно к "моим баранам", мы попадаем из огня да в полымя! По большому счёту, FORTH - это ассемблер для стековой машины. И действительно, у меня есть идейка такую стековую машину реализовать в ПЛИС, может пригодиться кое-где, и тогда FORTH будет для неё "родным языком". Но если речь о QuatCore, то уж проще на её родном ассемблере программы писать.

Poll Язык FORTH

странные девайсы, ПЛИС, программки, работа

Previous post Next post
Up