Исходя из вашего комментария, звучит так, будто вы пытались написать компилятор, не зная, как он работает, и в итоге все смешали в одну большую чашу.
Вы говорите об использовании DirectX для написания компилятора - но если вы компилируете его в какой-то байт-код, то компилятору не должно быть важно, будете ли вы использовать DirectX, GDI, OpenGL, или что-то совершенно другое. Интерпретатор должен быть осторожен, но если вы абстрагировали графические операции за некоторым набором кодов операций, то не имеет значения, что использует интерпретатор - вы можете написать интерпретатор для каждой отдельной платформы и запустить тот же код.
Компиляция обычно проще, если вы используете многоступенчатый процесс . Возможно, вы захотите начать с нуля:
- Составьте грамматику и запишите семантику для каждой синтаксической конструкции; не только то, что делает каждая конструкция, но и то, что для этого требуется (ввод правил и т. д.). Возможно, вам будет полезно взглянуть на существующие грамматики, но это зависит от сложности вашего языка.
- Написать парсер - вы можете сделать это вручную или использовать генератор парсеров , в зависимости от сложности вашей грамматики.
- Напишите код для проверки ваших семантических правил.
- Создайте набор инструкций и определите виртуальную машину и используйте свою семантику для преобразования ваших конструкций в инструкции (или используйте что-то, что уже существует). Вы можете обрабатывать «внешние» вещи (например, графику), распределяя инструкции для каждой вещи, или вы можете определить конкретные адреса, которые служат целью для каждого типа операции (поэтому, если вы попытаетесь вызвать функцию, скажем, по адресу 0xF000 Затем интерпретатор должен выполнить код, чтобы установить определенный пиксель в некоторый цвет). Последний подход дает вам больше гибкости (и означает, что вы можете использовать коды операций для чего-то другого), но за счет более сложной реализации инструкции CALL - вам решать, что подходит для ваших нужд.
Когда у вас есть набор инструкций, вы можете легко написать для него интерпретатор, используя все, что вы хотите для обработки графических объектов (DirectX, OpenGL, GDI, SDL ...) - это в значительной степени всего лишь один большой оператор switch, с кодами операций, реализованными как дела. Вот где вы размещаете код, специфичный для того, что вы используете для рисования.
Если ваша проблема в том, что вы хотите объединить эти два в одну программу, чтобы она считывала исходные файлы и выполняла их сразу, тогда вы можете это сделать, но это все равно должно помочь вам сохранить их в своем коде отдельно. , Простейший способ сделать это, вероятно, сначала скомпилировать его в байт-код, а затем просто сохранить в памяти и позволить интерпретатору прочитать его там.
Примечание: вы должны знать, что написание компилятора не является тривиальной задачей. Это не совсем сложно , но есть много вещей, о которых вам придется узнать. Вы можете прочитать книгу на эту тему - так называемая Книга Дракона считается одной из лучших, если не лучшей, но существуют и другие хорошие книги. Когда я узнал об этом материале год назад, мы использовали Концепции языков программирования Роберта Себесты и Процессоры языков программирования на Java Дэвида Уотта и Дерика Брауна. Возможно, вы захотите проверить свою местную библиотеку, чтобы узнать, есть ли у них какие-либо из них.
Если вы хотите больше вдохновения, это может помочь вам взглянуть на отчет , который мы написали в рамках создания нашего собственного языка программирования в университете в прошлом году. Не обращайте внимания на грамматику языка - он не только немного глючит, но и не является хорошим примером того, как вы должны это делать, - но остальная часть отчета может дать вам некоторые идеи о том, как подойти к проблеме.