Qt-Forth - учебный forth с графикой Qt для Windows и Linux |
Учиться никогда не поздно,
тем более классическим алгоритмам. |
Исходники
|
Сам проект представляет собой обыкновенную программу на C++ с Qt графикой. Взял я простой пример из Qt из tutorial и вставил в него файлы c алгоритмом (mim3hard.cpp и user.cpp) Qt-Forth. Количество графических классов в Qt-Forth ограничено (form1.cpp, form1.h), т.к. библиотека Qt просто огромная. К сожалению разработчики библиотек сейчас полностью перешли на C++ и не утруждают себя подготовкой C версии (исключение CodeBase) и WIN API. Из за этого нет возможности прямого подключения к объектам, для этого приходиться писать дополнительный слой (wrapping) обертки вызова объектов C++ (user.cpp). А написать полный wrapping к Qt не реально.
Проект состоит из следующих файлов qtforth_win_source.zip на MS С++ 6.0 и qtforth_linux_source.zip на gcc. Файлы почти одинаковы, кроме зависимых от ОС мест, по этому и кладу их в разные архивы, но основной алгоритм одинаков.:
- main.cpp - Инициализация Qt, проверка параметров командной строки, распределение памяти, старт вирт. машины
- mim3hard.cpp - hard слова (минимум для запуска)
- user.cpp - слова работы с графикой Qt
- form1.cpp - методы классов Qt
- form1.h - определение классов Qt
- z3types.h - определение внутренних типов
Описание алгоритма main.cpp
- Включение *.h файлов Qt
- Вставка файлов mim3hard.cpp и user.cpp обычным #include в тело main.cpp
- usage() - вывод информационного окна при непонятных параметрах командной строки
- main()
- запоминаем ссылки на количество и сами параметры коммандной строки
- Делаем главный объект app класса QApplication. Ссылку на него запоминаем, т.к. нам придеться на неё неоднократно ссылаться.
- Проверяем входные ключи при запуске (-v Версия) и (-q Версия Qt)
- Если есть ключ (-s source) значит
- InstallPCB (Program Control Blok) - распределение памяти под словари и стеки, инициализация указателей usr - указатель на вершину стека SR (возвратов) и usd указатель на вершину стека SD данных. Есть еще стек SC и его указатель usc (пользовательский стек), но он не применяеться. Переменные csd, csr, csc - фактически константы, указывающие на начальное положения стека.
- Распределение памяти под словарь имен. Имена слов храняться отдельно от основного словаря (в другом блоке памяти). Предпологалось, что словарь с шитыми кодами можно сохранить и имена самих слов нам не нужны (типа скомпилированный код)
- InitUserInterface - создание словарных статей для hard слов расширения, графика Qt, объекты и т.д.
- InitSystem - создание словарных статей для основных слов типа DUP, SWAP и т.д. Так же в этой процедуре определяеться набор шитых первичных слов (в скомпилированном виде) таких как : ; // и т.д.
- Если все нормально, то ищем адрес шитого слова "WRE" - фактически адрес основного интерпретатора, который и начнет чтение файлов. (ri = pp(*pp(Searchv(wre)));) ну а дальше запуск цикла интерпретатора виртуальной машины. Цикл бесконечный, пока не остановиться по mStop==1. Это и есть остановка виртуальной машины (mstop в конце программы или в словах, обработчиках событий)
- Если есть ключ (-c compile) значит
- InstallPCB (Program Control Blok) - распределение памяти под словари и стеки, инициализация указателей usr - указатель на вершину стека SR (возвратов) и usd указатель на вершину стека SD данных. Есть еще стек SC и его указатель usc (пользовательский стек), но он не применяеться.
- Распределение памяти под словарь имен. Имена слов храняться отдельно от основного словаря (в другом блоке памяти). Предпологалось, что словарь с шитыми кодами можно сохранить и имена самих слов нам не нужны (типа скомпилированный код)
- InitUserInterface - создание словарных статей для hard слов расширения, графика Qt, объекты и т.д.
- InitSystem - создание словарных статей для основных слов типа DUP, SWAP и т.д. Так же в этой процедуре определяеться набор шитых первичных слов (в скомпилированном виде) таких как : ; // и т.д.
- LoadZIC() - загрузка образа скомпилированного и сохраненного словаря (*.zic) в притык к уже определенным hard словам, и запуск на выполнение виртуальной машины с определенного адреса. Этот адрес задаеться во время выгрузки словаря на диск (что то похожее на целевую компиляцию)
конец main()