[Из песочницы] Разработка модульной системы программирования
Создание собственного языка программирования — желание многих программистов. Сейчас данная задача несложно выполнима. Дело в том, что преподавание программирования в физико-математических СУЗах имеет высокий уровень. Не могу не отметить методику И.Р. Дединского и его графическую библиотеку TXLib (The Dump Artist Lobrary). Она имеет сугубый минимализм и подтолкновение человека на do-it-yourself.Но перейдем к системе. Она включает:1) Графический движок (сначала хотел использовать TXLib);2) Стек данных;3) Численную систему команд;4) Исполнитель программы;5) Парсер;6) Среда.
Система будет разработана на C++(Среда — на C#).
Перейдем к первому модулю.
Графический движок. Сами понимаете, что лучше всего использовать OpenGL, но моя суровость не знала покоя и я написал её, используя векторы и WinAPI.
Для начала надо разработать 2D-графический движок, потом можно добавить еще один слой на окне и фактически 3D готово. Конкретно движок включает в себя довольно много структур для упрощения жизни вам же самим. Советую сделать структуры:
а) Структура окна. Должна содержать дескриптор графического окна, холста, и id окна; б) Структура рисования. Она в основном состоит из ручки (HPEN), кисти (NBRUSH) и так называемой старой кисти и ручки (HGDIOBJ); в) Структура данных модуля (версия, ревизия и т.д.)
Советую к движку сделать функцию Update (обновляет окна).
Предложение по реализации:
Сделать вектор memory (неопределенного размера), константные коды примитивов графики (круга, эллипса, линии, прямоугольника и многоугольника). При вызове функции отрисовки или переключения на другое окно сохранять это в memory. А в функции update читать код операции, смотреть, сколько у нее параметров, получать их и потом отрисовывать с полученными аргументами.
На этом закончу говорить про движок графики.
Теперь поговорим про стек.
Итак, в моем компиляторе есть класс Stack, в приватных переменных — вектор команд, аргументов, вектор строк и счетчики сохранения. Так как я не доверяю штатным функциям, отдельно сделаны (в паблике, конечно) push, pop, dump, pushString, popSring.
Теперь расскажу, как они работают.
Push присваивает элементу вектора с id push_count значение введенное в аргумент функции. (И, конечно увеличивает push_count на 1).Pop присваивает последнему элементу значение 0, и уменьшает push_count на 1.Dump выводит состояние стека и все его переменные.pushString и popString работают анологично push и pop, но только с вектором строк.
Про стек еще добавлю, что все помещено в привет, чтобы нельзя было, скажем, так попортить стек, создать константную область, с возможностью изменения штатными функциями класса.
Теперь скажу про команды.
Это просто константы, которые сохраняются в стек и имеют численный вид.Далее все работает как с графическим update, делаем в стеке функцию get с аргументом id, которая возвращает объект data (память стека) с номером id.
Про исполнитель.Берем функцией get первый элемент из стека, получаем аргументы и переходим к следующему аргументу.
Парсер читает из файла команду, pushит в стек код операции, берет аргументы. Если команды нет, то отправляет в лог ошибку об отсутствии команды и завершает процесс компиляции. Добавлю лишь о создании отдельной переменной: пушим команду создания, сохраняем имя, проверяем следующий знак, ели это '=', то присвеваем следующее за знаком значение, если ',', то сохранить тип, сохранить имя и так пока знак не равен ';'.
Фактически все о парсере.
О среде скажу только, что там очень много всего и пишется это на другом языке. Не хочу сегодня средой плавить мозги, о ней будет рассказано во второй части статьи.