О том как я писал компилятор Си
Всем привет, и, сегодня вы узнаете как я писал компилятор Си.
Вот части статьи:
1 - Что за компилятор
2 - Как я его создал
Ну, как понимаете он чуть-чуть плохой но ладно.
Что за компилятор?
Я его назвал pycc. Как вы поняли, он написан на python. Ведь pycc переводится как Python C Compiler.
Он поддерживает такие правила:
Два типа данных (int и char)
Цикл while и цикл do-while.
Условие if-else.
Минимальный препроцессор (только директива #include)
Функции через void.
Их мало, но и чтобы эти правила работали я пропотел.
Где то щас 700 - 724 строчек кода (вроде бы).
Вот пример кода (C в хабре нету):
#include <stdio.h>
void fac(n) {
int f = 1;
while (n > 0) {
f = f * n;
n = n - 1;
}
}
void main() {
fac(5);
printf("'factorial of 5: '+str(f)");
}
Из этого примера кода вот что мы видим:
Все переменные - глобальные что и хорошо, что и плохо.
Функция printf принимает питонью строку.
Вывод:
factorial of 5: 120
Как и ожидалось.
Да. Пока что нечего больше.
Вот так мы и прошлись по его правилам.
О том как я писал этот компилятор
Это мне далось очень не легко.
И я это знал за ранее.
Начал я с лексера. Написать Скопировать лексер с одного сайта очень легко.
Да и парсер дался достаточно легко.
Ну. По началу было всё хорошо. Я легко справлялся. И багов пока не было.
Но всё началось с void. Я реально понял что оказывается я делал всё с багами.
Когда я делал такой код:
void main() {
int n = 5;
while (n > 0) {
n = n - 1;
}
}
То, парсеру это не нравилось. Но в скором я начал писать данный код:
d = Parser()
d.parse(...)
block.append(...)
Это всё ОЧЕНЬ ПЛОХО. Но я делал этот проект не из-за красивого кода, а чтобы всё работало. Чего я добился.
В скором ошибка типизации... int x = "h";
это было нормально... Ну ладно эта типизация (я быстро решил) но потом и ошибка с char.
Которая была из-за пробелов. Да. Но... К концу я всё таки справился и исправил все баги кроме того самого (с пробелами, но я был доволен).
Сейчас я работаю над другими изменениями.
Да, данный заголовок был очень маленьким но я не умею объяснять истории.
CHANGELOG (только у меня, больше не у кого)
Пре-альфа 1.0
Очень мало было.
Циклы, условия и переменные.
При этом было очень примитивно и не работающее.
Альфа 1.0
Добавился сам полный функционал. Больше багов было устранено.
Но, они были. За то вы могли написать такой код:
void main() {
int n = 5;
while (n > 0) {
n = n - 1;
}
}
И он мог работать. Что самое главное.
Бета 1.0
Ну прям все баги исправлены.
И добавлена возможность выводить другие данные.
Релиз 1.0
Официальный выпуск. Тогда я опубликовал это на гитхаб.
Релиз 1.1
Добавлен препроцессор.
К примеру:
#include <stdio.h>
Теперь можно было импортировать заголовочные обычные файлы.
Релиз 1.1.2 (Последний)
Я исправил баг с больше и меньше.
Раньше было не так:
if stack[-2] > stack[-1]:
...
else:
...
А так:
if stack[-2] >= stack[-1]:
...
else:
...
И я это исправил (да, самое легкое исправление)
Итог
Статья получилась плохой и большой, но, вот ссылка на проект:
SystemSoftware2/pycc: Компилятор C на Python
В скором я добавлю больше всего. И возможно компилироваться будет в x86 ASM.
UPD: компилируется в байткод