Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Ср окт 09, 2024 04:57

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Ответить
Имя пользователя:
Заголовок:
Текст сообщения:
Введите текст вашего сообщения. Длина сообщения в символах не более: 60000

Размер шрифта:
Цвет шрифта
Настройки:
BBCode ВКЛЮЧЕН
[img] ВЫКЛЮЧЕН
[flash] ВЫКЛЮЧЕН
[url] ВКЛЮЧЕН
Смайлики ВЫКЛЮЧЕНЫ
Отключить в этом сообщении BBCode
Не преобразовывать адреса URL в ссылки
Вопрос
Теперь гостю придется вводить здесь пароль. Не от своей учетной записи, а ПАРОЛЬ ДЛЯ ГОСТЯ, получить который можно после регистрации на форуме через ЛС.:
Этот вопрос предназначен для выявления и предотвращения автоматических регистраций.
   

Обзор темы - Трансляторы Си в Форт
Автор Сообщение
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Что-то все притихли подозрительно... :)

Мой транслятор си-в-форт понемногу развивается, хотя только урывками и гораздо медленне, чем хотелось бы. На сегодня реализованы:
Код:
- объявления (auto register static extern typedef void char short int long float double signed unsigned struct enum typedef-name const volatile);
- операторы (case default expr {} if else switch while do for goto continue break return);
- выражения (, = *= /= %= += -= <<= >>= &= ^= |= ?: || && | ^ & == != < > <= >= << >> + - * / % (type-name) ++ -- & * + - ~ ! sizeof [] () . -> ++ -- id num chr str (expr));
Конечно, я изначально немного упростил себе задачу: из базовых типов реализованы только void/char/int/struct/union и массивы/указатели для всего этого безобразия, short/long/float/double/signed/unsigned пока являются синонимами int, а auto/register/static/extern/const/volatile пока игнорируются. Операторы реализованы все, но некоторые работают только в версии под мой микрофорт, а с классическим фортом работать не будут (case default switch goto continue break), точнее, можно было бы безболезненно реализовать трансляцию конструкции switch-case-break-default, но только в варианте с принудительным break после каждого case, также есть мысли по поводу прочего (goto continue break), но по большому счету версия под классический форт - это в моем случае побочная ветка, она тоже развивается параллельно с версиями под другие платформы, но некоторые сложные и неочевидные вещи поставлены на паузу :) За вчера/сегодня практически доделал инициализацию массивов и функции с переменным количеством параметров. Теперь есть возможность делать свой мини-printf:
Код:
void printc ( char c ) ;
void printn ( int n ) ;
void prints ( char * s ) ;

int va_count ( ) ;
int va_arg ( int n ) ;

void printf ( char * fmt , ... ) {
   char * p = fmt ;
   int n = 0 ;
   char c ;
   while ( c = * p ++ ) {
      if ( c == '%' ) {
         switch ( c = * p ++ ) {
            case 'c' : printc ( va_arg ( n ++ ) ) ; break ;
            case 'X' : printn ( va_arg ( n ++ ) ) ; break ;
            case 's' : prints ( va_arg ( n ++ ) ) ; break ;
            default  : printc ( c ) ;
         }
      }
      else printc ( c ) ;
   }
}

void main ( ) {
   printf ( "%c%X, %s%c" , 'H' , 0xE110 , "WORLD" , '!' ) ;
}
Выводит
Код:
HE110, WORLD!
Сейчас сделано нестандартно, но это вынужденно, т.к. препроцессора и, соответственно, макросов пока нет, но как только появятся, с переходом к стандартным va_list/va_start/va_arg/va_end никаких проблем не будет.
По большому счету, из глобальных недоделок нереализованными остались только указатели на функции и параметры/результат типа struct. А дальше можно будет приступать к препроцессору, добавлять float и т.д.
Немного забавного. Присваивание структур транслируется в что-то вроде
Код:
s0 s1 16 <memcpy>
Здесь s0, s1 - указатели на структуры, 16 - размер в байтах структуры s0, которая стоит в левой части оператора присваивания, а <memcpy> тупо пересылает указанное количество байт из одной области памяти в другую. При этом никаких проверок на соответствие типов левой и правой части оператора присваивания нет и в помине. А что же будет, если в левой части указать имя массива, а в правой, например, строку или другой массив? Правильно! :)
Код:
char msg0 [ 32 ] , msg1 [ 16 ] ;
...
msg0 = "hello, world" ;
msg1 = msg0 ;
транслируется в
Код:
msg0 "hello, world" 32 <memcpy> msg1 msg0 16 <memcpy>
Т.е. работает присваивание массивов, чего не должно быть в классическом Си. Понятно, что если добавить проверки на "скалярность" и "l-valуйность" левой части, то "проблема" решится, но пока решать "проблему" не планирую, т.к. главное, чтобы правильно написанный си-код транслировался правильно, а то, что транслируется и работает неправильный си-код, так это не смертельно :) Или вдруг я захочу сделать транслятор с языка, где можно присваивать массивы? :)
И еще забавно, что в исходнике транслятора все так же примерно полторы тысяч строк, а скомпилированный при помощи tcc транслятор весит примерно 25Kb. Т.е. оно получается достаточно компактным и не очень сложным. :) В теории транслятор уже близок к самокомпиляции, т.к. в коде активно используются printf и sprintf, а в трансляторе до сего дня не были реализованы функции с переменным числом параметров, но теперь уже это в прошлом. Если быть точным, то функции с переменным числом параметров все же были реализованы раньше, но их тело до сей поры приходилось реализовывать на "ассемблере" (точнее - на форте).

Кстати, вопрост тут возник по поводу инициализации массивов. Есть ли какой-то красивый и элегантный способ инициализации строки в Гарварде? При условии, что память программ для чтения недоступна. У меня пока тупо каждый байт строки выкладывается в нужную ячейку RAM. Или можно сделать c ... c n addr <strinit>, т.е. посимвольно выложить в стек, сверху добить ее длиной и вызвать примитив, который распихивает символы по нужным адресам, но так можно только если стек большой.
Сообщение Добавлено: Ср мар 20, 2024 01:02
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
При наличии хотя бы минимального опыта самым интересным становится выяснение, как можно запустить очередной вариант Форта. Сколько ж можно переписывать dup... Важнее выяснить, как сделан стек и как к нему обращаться. Как можно скомпилировать слово и вызвать его (машинный код? указатель на функцию? специальный токен и адресный интерпретатор?). Как взаимодействовать с операционной системой - например, файл прочитать, взяв для этого данные со стека. Как на экран что-то вывести. И так далее. А наполнение словами потом пойдет.
Сообщение Добавлено: Чт ноя 23, 2023 02:16
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
KPG писал(а):
Ссылки на то как сам делал, при некотором оформлении и собирании архивов в актуальном виде, добавлю на форум или как сейчас могу отправить в личку (с каким то попутным Форт "мусором"),
Было бы здорово, тема как раз для того и создана, чтобы сравнивать/обсуждать существующие решения и рожать свои :)

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

У меня, увы, круг интересов временно сместился с "написать транслятор си-в-форт" на "скачать и установить голый виндоус без регистрации и смс" :) Эта гадина на основном рабочем ноутбуке при отключенных интернете и обновлениях умудрилась за год с небольшим несколько раз поломаться, но при этом успешно восстанавливалась при помощи "восстановления при загрузке". А в крайний раз сломала не только свой раздел, но и раздел с Ubuntu Studio, а также соседний, где файловый архив был. Как все-таки хорошо было на XP и Win7: они могли работать десяток-другой лет и не ломались, да чего уж там, у меня до сих пор работают XP на крохе Sony Vaio P19 и Win7 на Acer Aspire 3830. Десять лет работают или больше, я даже не помню, когда на них что-то переустанавливал. И это при достаточно активном использовании. А win10 протух за год с небольшим. И бесит весь этот сговор производителей оборудования и мелкософта. Старую нормальную ось на рабочий ноутбук я, конечно, могу поставить, но драйверов, увы, не найти. Так что придется мириться с уродливой мелкософтовской поделкой. Все, ворчать закончил :)

Что касается самого транслятора, то до апокалипсиса с виндой успел прикрутить туда break/continue, но только в версию для uf \ micro forth \, а для традиционного форта еще в этом месте подумать придется.
Ну и, кстати, в итоге получается компилятор под что угодно, т.к. перелопатить uf \ micro forth \ под любую платформу не составляет труда. Например, под Dendy (NES): http://totalvacuum.ru/nescdemo.zip :)
Сообщение Добавлено: Вс ноя 19, 2023 22:35
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
KPG писал(а):
А, что в архитектуре решения, с точки зрения Фортёра, там может быть особенного?
(вижу задачу -> делаю своё решение

Архитектура конкретного транслятора как раз особенна. Как получается код, какая модель памяти, как организовано взаимодействие с ОС и т.д.
Сообщение Добавлено: Вс ноя 19, 2023 19:40
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Hishnik писал(а):
Интересно. А вот бы архитектуру этого всего, алгоритмы и идеи.

А, что в архитектуре решения, с точки зрения Фортёра, там может быть особенного?
(вижу задачу -> делаю своё решение :)

к Total Vacuum
P.S. Ссылки на то как сам делал, при некотором оформлении и собирании архивов в актуальном виде,
добавлю на форум или как сейчас могу отправить в личку (с каким то попутным Форт "мусором"),
Сообщение Добавлено: Вс ноя 19, 2023 16:12
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Интересно. А вот бы архитектуру этого всего, алгоритмы и идеи.
Сообщение Добавлено: Вс окт 29, 2023 22:58
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Небольшая демонстрация того, что пока получается: http://totalvacuum.ru/c2fdemo.zip
В вариантах под spf (32-битный int, сам spf лежит здесь же) и gforth (64-битный int, проверял в онлайне на https://www.jdoodle.com/execute-forth-online/). в каждой папке транслятор uc.exe, исходники на Си (*.c) и результат их трансляции в Форт (*.f), также имеется файт c.f, в котором собраны основные прокладки между Си и Фортом, причем в варианте для spf он подключается автоматически через included, а для gforth-online надо сначала воткнуть содержимое этого файла в редактор на сайте, а потом добавлять к нему скомпилированные тесты.

Примеры компилируются так:
Код:
uc.exe <hello.c >hello.f
Но лучше сначала вывести на экран, чтобы убедиться, что не зависает, ибо проверок на ошибки нет:
Код:
uc.exe <hello.c
Из забавного тут asm.c с примерами "ассемблерных" Форт-вставок и "ассемблерных" функций на Форте и redefine.c, где мы переопределяем операцию сложения (да, так можно, это ж транслируется в Форт! :) ), после чего начинаем получать неправильные результаты сложения, в тесте от 8cc arith.c тоже пара переопределений, но на примерно то же самое, поэтому на результат не влияет.
Препроцессор пока не начинал, комментариев, а также #include/#define пока нет, токены необходимо разделять пробелами (как в Форте :) ) Не реализовано enum/typedef/break/continue/switch/case/goto/sizeof/указатели на функции.

Некоторый затык произошел с трансляцией switch-case: т.е. я легко могу оттранслировать это в фортовский case-of-endof, но это будет неправильно, ибо не все case обязаны заканчиваться break. А кроме того, case не во всех Фортах есть. И с break/continue/goto примерно того же сорта раздумия. :)
Сообщение Добавлено: Сб окт 28, 2023 02:11
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
:) При трансляции си-в-форт неизбежно возникнут вопросы, ибо си и форт не сошлись во взглядах на некоторые вещи:
- система базовых типов, в си она чуть более развитая, обычно имеется минимум 4 целых типа 3-х и более разных размеров, а также штуки 3 float'a, а в среднестатистическом форте обычно есть целое и байт, часто есть поддержка двойных целых, опционально может присутствовать одна разновидность float, если же рассматривать форт-процессоры и форт для них, то там вполне может быть один единственный тип - целое;
- строки, в си asciiz, а в тех фортах, где не asciiz-строки, есть строки со счетчиком, т.е. при трансляции из си придется дописывать 0 ей в хвост и убирать счетчик длины из гривы;
- true, в си это 1, а в форте чаще всего -1, поэтому если подходить строго, придется при реализации логических операций, операций сравнения и т.д. накладывать маску 1 & на результат;
- кадры стека при вызове функций си, понятно, что это лишь одна из возможных реализаций, тем не менее речь о присутствии в регистровых архитектурах возможности работы с кадром стека через отдельный регистр (например, bp), а в гипотетическом стековом процессоре (внезапно) и в не менее стековом форте возможность работы со стеком таким же способом сильно ограничена: отдельного регистра нет, более того, нет команды, которая пишет в стек на произвольную глубину, т.е. pick (аналог @ для стека) есть, а аналога ! не предусмотрено;

Вроде не смертельный (возможно, неполный) перечень несовместимостей получается, с этим вполне можно жить :) На первом этапе планируется только 2 базовых типа (char и int), другие (short/long и один float) по желанию в перспективе, ну а пока они все являются синонимами типа int, со строками понятно, будет чуть медленнее, чем в форте, логические выражения тоже сделаны (строгое совпадение в этой части с си можно при желании отключить, тогда код будет работать быстрее), с аргументами и локальными переменными пока так: результат возвращается через стек данных, аргументы лежат там же, возможность их изменения в процессе работы функции отсутствует, локальные переменные лежат в отдельном массиве, если вдруг понадобится модифицировать значение аргументов, их тоже можно будет в этот же массив сложить, со структурами пока не решил, скорее всего результат и аргументы типа struct будут передаваться через этот же массив.
Сообщение Добавлено: Вс окт 15, 2023 01:40
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Безусловно, скачивать чужое не вариант. И не только потому, что скучно. Но и потому, например, что лично мне проще свое написать, чем с чужим разбираться и переделывать. Да и скачивать-то по сути нечего, всё какие-то наколенные поделки попадаются, мое в любом случае не хуже будет в итоге. Какие-то идеи подсмотреть, конечно же, интересно, но не более того :)

Пока все крутится вокруг таблицы символов. Изначально предполагалось, что это будет массив структур и что таких таблиц будет несколько. Но потом пошел по пути наименьшего сопротивления, а также держал в уме, что в перспективе код захочется переписать на Форте, поэтому на данный момент осталась одна таблица, причем не в виде массива структур, а просто несколько отдельных массивов под каждое поле. Все-таки писанины будет меньше без постоянных обращений к полям структуры. В дальнейшем переделаю через указатели, т.к. доступ к таблице по индексу тоже добавляет писанины. Поля таблицы такие:
- id - идентификатор;
- mod - модификаторы типа;
- type - номер типа;
- size - размер;
- addr - адрес для глобальных переменных/смещение для параметров функции, локальных переменных или полей структуры;
- scope - область видимости;
и т.д. Это не полный и не окончательный перечень полей: какие-то будут добавляться или удаляться в процессе. Например, для кода
Код:
struct point { int x , y , color ; } ( * f [ 10 ] ) ( char a , char b ) ;
void main ( ) { }
получается такая таблица символов:
Код:
\ ### addr size sco de typ lv stk loc mod              name \
\   0    0    0   0  0   0  0   0   0                   \
\   1    0    0   0  0   0  0   0   0                  void \
\   2    0    1   0  0   0  0   0   0                  char \
\   3    0    2   0  0   0  0   0   0                  int \
\   4    0    6   0  0   0  0   0   6 {}               struct point \
\   5    0    2   4  1   3  0   1   2                  x \
\   6    2    2   4  1   3  0   1   2                  y \
\   7    4    2   4  1   3  0   1   2                  color \
\   8    0   20   0  0   4  0   1  20 [10]*()          f \
\   9    0    1   8  0   2  0   1   0                  a \
\  10    2    1   8  0   2  0   1   0                  b \
\  11   20    0   0  0   1  0   0   0 ()               main \

По этой таблице, например, f - это массив указателей на функцию, возвращающую тип 4, а тип 4 - это структура point.

Эта таблица организована как стек, т.е. там есть push, swap, drop, но с другой стороны всегда имеем возможность изменить/прочитать любое поле по индексу в таблице. В процессе разбора выражений используется эта же таблица: подвыражения склеиваются в одну строку, в результате, например, printn ( a + b ) ; превращается в строку a @ b @ + printn, которая лежит в поле id одного из элементов таблицы, после завершения разбора каждого выражения и вывода соответствующей этому выражению строки на Форте элемент из таблицы удаляется.

Пара мыслей по поводу аргументов функций и локальных переменных. Все вычисления в Форте производятся над содержимым стека данных, поэтому желательно передавать аргументы и возвращать результат работы функции через стек данных, то же самое можно сказать про локальные переменные. Но почему-то в Форте придумали команду pick (аналог команды @ для стека) для чтения произвольной ячейки из стека, а придумать команду для записи в произвольную ячейку стека (аналог команды ! для стека) забыли. Поэтому если мы передаем аргументы через стек, то мы не имеем возможность использования их в качестве локальных переменных. Поэтому либо аргументы в стеке (без возможности их модификации), либо в массиве с локальными переменными (возможность модификации есть, но каждый раз при входе в подпрограмму придется переносить значения со стека данных в массив). Пока аргументы в стеке данных, но переделать не проблема.
Сообщение Добавлено: Вс окт 08, 2023 16:42
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Еще ведь важный вопрос - как? С точки зрения архитектуры, алгоритмов, практических подходов. Потому что на уровне "где скачать" - это как-то даже скучно.
Сообщение Добавлено: Сб окт 07, 2023 20:24
  Заголовок сообщения:  Трансляторы Си в Форт  Ответить с цитатой
Загорелся внезапно идеей сделать транслятор Си в свой uf \ micro forth \ для самодельных Форт-процессоров. На сдачу должны получиться трансляторы из Си в традиционный Форт, а также, возможно, трансляторы с других близких и не очень по синтаксису ЯВУ в Форт. В грубом приближении можно утверждать, что любая программа на Форте - это всего лишь распечатка листьев/узлов синтаксического дерева, полученного в процессе трансляции какой-нибудь написанной на ЯВУ программы. А поскольку uf \ micro forth \ у меня выступает в роли ассемблера, то предполагаю, что скорость работы скомпилированных таким транслятором программ не будет неприлично низкой даже в случае, если выхлоп такого транслятора будет не самым качественным.
Хотел оценить состояние дел в этой области на сегодня, но Гоголь-поисковик по запросу "c2forth compiler" не выдает чего-то заслуживающего внимания: пара ссылок на сайт mpe, где вроде как должен лежать их c2forth, но ссылка с их сайта на их же продукт битая, еще имеется ссылка на гитхаб, где непонятное подмножество си транслируется в некий эзотерический форт, вот вроде бы и все. Почему-то для меня это удивительно. Неужели все теперь только в условный LLVM транслируют и не заморачиваются? :)

Что касается моей поделки, то степень готовности примерно 50%: осталось подправить адресную арифметику, не реализовано несколько операторов (break, continue, goto, switch, case), из базовых типов на первом этапе будут только char и int (short/long - синонимы) (а, например, для 16-битных Форт-процессоров даже char будет синонимом int) и массивы/структуры/указатели на их основе, в перспективе добавлю float, ну и по мелочи некоторые вещи доделать нужно типа инициализации, препроцессор пока даже не начинал - это по сути отдельный язык со своим синтаксисом, начну не раньше, чем будет готов хотя бы на 90% транслятор. :)
Сообщение Добавлено: Пт окт 06, 2023 02:37

Часовой пояс: UTC + 3 часа [ Летнее время ]


cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB