Данный проект представляет собой мой язык программирования. У моего языка есть возможность транслировать код в два вида ассемблерных кода (x86-64 и мой собственный ассемблер).
Проект состоит из 4 частей:
- Frontend
- Middleend
- Backend
- Reverse frontend
Более подробно про каждый из них, поговорим чуть позже.
Note
Язык поддерживает только целочисленные типы данных, поэтому я решил не добавлять типы данных.
Для установки программы используются утилиты make и git.
git clone git@github.com:EntryFrager/language.git
cd language
makeРабота компилятора состоит из нескольких этапов:
- Frontend: Лексический анализ кода (разбиение на токены) и синтаксический анализ кода (создание абстрактного синтаксического дерева)
- Middleend: Оптимизации дерева
- Backend: Трансляция дерева в ассемблерный код
Рассмотрим более подробно backend. В моем проекте возможны трансляции в два вида ассемблерных кода:
- NASM (x86-64)
- Мой собственный ассемблер
Для моего ассемблера я взял старый проект CPU. Он состоит из двух частей:
- Ассемблер (на основе ассемблерного кода создает бинарный код для процессора)
- Процессор (представляет из себя виртуальную машину, которая выполняет бинарный код)
Главным отличием является то, что для перемещения данных в моем ассемблере используется стек. Поэтому все инструкции берут свои аргументы из стека. Также мой ассемблер составляет ассемблерный листинг, который сохраняется в папке files.
Для ввода и вывода чисел в моем ассемблере присутствуют инструкции in и out, которые соответственно считывают и выводят значения, используя стандартные потоки ввода и вывода (stdin, stdout). В NASM для данных функций я написал свою библиотеку stdio.asm.
Я написал два примера для тестирования языка:
- Программа, решающая квадратное уравнение
- Программа, считающая факториал от n
Приведу код второго примера. С первым примером вы можете ознакомиться самостоятельно.
def main()
{
input(a);
NO_FACT = 1;
if (a < 0 || a == 0)
{
print(NO_FACT);
}
else
{
result = fact(a);
print(result);
}
}
def fact(n)
{
if (n == 1)
{
return n;
}
b = n - 1;
n = n * fact(b);
return n;
}Note
Ниже приведен пример AST для второго примера.