?

Log in

No account? Create an account

[sticky post] Вступление (ред1)

Моё пристанище пополнилось ещё одним моим увлечением - фортом.
Мной была написана NOVA-forth.
Можно просто, Нова.
Думаю, большая часть записей будет за Новой.
В принципе, это достаточна простая 32-битная форт-система под Винду.
Исключение составляют таблица предкомпиляции и отканые операции.
Тут буду мусолить вечносамогонные темы: развитие форта, идеи.

А также публиковать свои наработки.


Кого можно почитать в ЖЖ?
shatff история
demonada всяко разное. в ЖЖ бывает наскоками
galeneastro астрономия, пейзажи
gibajd в основном путешествия

terra_irrornita  журнал заброшен. Но у автора хороший стиль.

Расширение структур возможностью автосоздания дополнительных операций над элементами. Условно выражаясь, это методы доступа к элементам структуры.

На данный момент определены следующие методы:

  • @ получить значение из элемента;

  • ! присвоить значение элементу;

  • I увеличить значение элемента на 1;

  • D уменьшить значение элемента на 1;

  • +! добавить число к значению элемента и сохранить;

  • zero обнулить значение элемента;

  • E выполнить код, хранящийся в элементе.

Не для каждого элемента будет скомпилирован тот или иной метод. Поскольку для некоторых элементов методы не определены, или не могут существовать вообще.
К примеру, если размер элемента не равен CELL ,то метод E будет проигнорирован.

Обозначение методов это обычные константы у которых установен соответсвующий бит. Все константы перечислены в словаре flags. Но чтобы не лазить каждый раз в этот словарь данная библиотека имеет свой NOTFOUND.
Поэтому для задания методов можно перечислить обозначающие их флаги через / (обратную косую черту). Эти флаги будут объединены в одно число операцией OR.
Пример синтаксиса: !/@/E

Библиотека предоставляет слова для определения своих методов (см. слово CREATE-M). Но у методов есть ограничение, методы должны быть примитивами, поскольку они все метятся флагом INLINE . Данное ограничение было сделано для возможности определения методов во временных словарях ради последующего сокрытия деталей и экономии памяти.

Чтобы создать элемент структуры вместе методами доступа к нему используйте слово --m
Это слово работает как и -- , но дополнительно принимает битовый перечень методов в качестве первого параметра.

Пример кода:

STRUCT: weapon
CELL !/@ --m NAME
1 !/@ --m NAME-LEN
2 !/@ --m AMMO-CODE
CELL !/@/E --m FIRE-FUN
CELL !/@/zero/I/D --m AMMO
STRUCT;


Вместе со смещениями будут скомпилированы:
NAME! NAME@ AMMO++ AMMO-- FIRE-FUN-EXEC FIRE-FUN! FIRE-FUN@ и проч.

После загрузки библиотеки необходимо добавить в контекст словарь STRUCT&METHODS

Тренировка мозга

Консольное приложение, чтобы #ТренироватьМозг. Для работы архив надо распаковать.
Запускаем приложение, печатаем TRAIN и называем ЦВЕТ слова, а не слово.


Словарь цветов в файле WORDS.LANG
Можно прописать что угодно. Изменив слова в нём, можно добиться мультиязычности :)
В архиве также исходник.
скачать

Nova-forth версия VC 2

Nova-VC

обновление 2

Ядро:

Изменён алгоритм преобразования чисел в строку. Теперь преобразование начинается со старших разрядов.

Библиотеки:
Переписал библиотеку для трансляции #JSON
На этот раз все логичнее. Но #бектрекинг и откатные техники не дремлют :)

Помимо трансляции добавлены операции вставки данных.
Размер откомпилированного: 8500 байт, а с оптимизатором 6660.
Не шутка. Оптимизатор реально это сделал.

Имеется библиотека для сравнения строки с маской. Маска задаётся форт-словами (C= S= N-N ANY). Работоспособна. В процессе развития.

Основное направление действий сейчас:
JSON, HTTP-сервер, #оптимизатор, #дизассемблер, причёсывание исходников.

Nova-forth версия VC 1

Nova-VC

обновление 1

Ядро

    COMPILE, стал вектором. А это значит, что можно дополнительно влиять на последнюю стадию компиляции.
    Добавлено чтение INI-файла перед запуском системы
    Поправлена интерпретация командной строки (ранее ругался на пути с пробелами).

Библиотеки:
Создание и загрузка оверлеев. Оверлей в данном случае это временный словарь сохранённый в бинарном формате. При загрузке корректируются указатели словаря, цепочки поиска и пр.
Для корректной работы полученного оверлея код должен быть позиционно-независим.
Писалось ради интереса. Интерес пробудился на форт-форуме

Оптимизатор:
Размер подопытных библиотек уменьшился на 16 %.

Nova-forth 1.05

Нова 1.05

Кратко по новшествам:

  • интерпретация командной строки

  • новый механизм инлайна

  • портирована либа-обёртка для #MySQL от ~day

  • написан собственный вариант для работы с MySQL


По поставке: убран СПФ, ЦК на его основе и мои либы к нему

Nova-forth 1.03

https://cloud.mail.ru/public/4ENj/Sx9zaV7Sz

Изменения:
Нова может скомпилировать саму себя по исходникам.
В процессе переписал часть стекового манипулятора (в 5.1). Из-за различий версий код компилировался разный, что мешало проверить "правильность" системы. После этого живо были ликвидированы остальные несуразности.
Стоит отметить, что компиляция форт-образа ведётся Новой для работы с теми же абсолютными адресами, что и в используемом форте (т.е c 0x00402000).

Добавлена возможность сохранить наработанную форт-систему. Для этого добавлена библиотека (компилируется во врем. словарь, в форт-образ не идёт).

Добавлены слова:
MIN
MAX
SSET?
\ a1 a2 ... an n b --- a1 a2 ... an n flag проверить элемент b на вхождение в множество, вернуть флаг (-1 да, 0 нет).

Думаю, пора портировать на 64 бита.
У меня тут как раз fasm с дизассемблером завалялись :)
Обкатаю пару примитивов в фасме для работы с виндой (там fastcall), допишу форт-ассемблер, подготовлю стек. манипулятор и пр. Всё дело проверю в дизассемблере (не очень мне нравится 64бита в интеле, инструкцию порезали гады )

По идеям:

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

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

По либам:
JSON основная часть работы сделана. Уже может транслировать JSON-файлы, и просто отрезки на этом языке.
Добавлено слово DUMP

Nova-forth 1.02 май

Нова 1.02, исходники, либы, портированный COM


Что изменилось?
TRANSLATE-FILE стал пользовательским вектором.
Пользовательские вектора тоже изменились. Т.к. они определяются почти на финишной прямой, то USER-VECT-CODE определяется на среднем уровне, что позволило вывести его из параметризации. Это слово уже само отвечает за компиляцию.
Read more...Collapse )

Nova-forth 1.02

NOVA-forth версия 1.02

29.04.2018
Добавлены слова: GET-CALL и RECOMPILE . Последнее занимается (само)модификацией кода. Эти слова необходимы для реализации слов ниже.
Слова TO и FROM работают через вызов обработчиков в запрашиваемых параметрических словах. Механизм записи и получения указателя переменных теперь может быть расширен при необходимости.
Добавлено слово WINAPI:
Маленький шажок к СПФ-у - неплохой шаг к поддержке самомодификации кода.

08.04.2018
Переписано слово TASK>


https://cloud.mail.ru/public/CqRW/BUc7h2HhS

В настоящий момент портирую либу для работы с COM от ~yz. То и дело натыкаюсь на особенности СПФа
Переписал проверку нахождения инлайн-слова в разбираемом коде.
Каждый раз для проверки создаётся функция в хипе (там вызов параметрического слова и указатель на инлайн-код). После проверки функция самоудаляется. Если же слово >OPT обрубило проверочную трассу раньше, то выделенная память под функции также освобождается силами >OPT.

Дабы легче было пользоваться проверкой на развёртку, INLINE-COMPILE, в ядре было переписано.
Слово дополнительно просит функцию компилирования. И если поставить NOOP, то получим длину инлайн-слова.

Касательно проверочной трассы.
Трасса может быть большой. И каждый раз писать что-то вроде ['] >R >INLINE? ['] DUP >INLINE? NUMBER не есть хорошо.
Поэтому строим абстракцию.
Что-то вроде
: TRACE{
0
BEGIN
PASRE-NAME
2DUP S" }TRACE" COMPARE WHILE
['] ENTITY-VOCS >param @ SFIND-IN-VOC
IF
NIP LIT,
ELSE
SFIND
IF
SWAP &INLINE AND IF LIT, ['] >INLINE? COMPILE, ELSE -2003 THROW THEN
ELSE -2003 THROW THEN
THEN
1+
REPEAT
2DROP
LIT, \ n
;

Но случаи могут быть и интересней. К примеру, #оптимизация повторяющихся оптимизаций.
Хоть #LISP садись пиши. Хотя вариант интересный. В плане абстракций Лисп хорош.
Код будет забавным: проверка форт-кода на соответствие шаблона на Лиспе, который написан на форте.
Но это ещё одну фундаментальную вещь продумывать.
А это ж всё-таки глазковая оптимизация. Хотя инструментарий в виде таблицы предкомпиляции есть. Можно потом #натив в псевдокод (на этот раз не в форт-код, а в некий вымышленный асм) и снова в натив.
И тут уже настоящая оптимизация возможна по скорости, размеру, использованию стеков и регистров.

Дополнительно:
Чтобы разгрузить #ассемблер в оптимизаторе, вызываемые ассемблирующие слова можно немного "съоптимизировать". Если установлено, что ассемблирующие слово жрёт 2 параметра и они всегда одинаковы, то оно вызывается 1 раз, а полученный код от него в последующих вызовах компилируется через S,
Пока это делается вручную, думаю над автоматическим использованием.
Таким образом в оптимизаторе будет меньше вызовов и скорость оптимизатора должна увеличиться.