Придумайте на двоих уникальное название дирекории и создавайте там проект с уникальным называнием. Запишитесь в Excel-табличку (TODO link), чтобы я не забыл кто есть кто.
Выдается на двоих и сдается частями в виде PR в этот репо. Разумеется, там должно быть адекватное покрытие тестами, более-менее документация, использование линтера и нормальный функциональный код (на OCaml/Haskell).
Если вы не хотите ничего знать, то можно помечать PRы заклинанием "[D] ...", и CI не будет запускать линтер, а я буду проверить только тесты, без кода. На экзамене сможете рассчитывать максимум на D.
На всякий случай, скажу, что фичи не нужно реализовывать все сразу. Итеративная модель разработки подойдет лучше водопадной.
Задание можно разбивать на следующие части.
- Парсер+тайпчекер. (10 баллов)
- Автоматическое тестирование парсера стоит осуществлять в том числе QuickCheck-подобным способом.
- Трансляция в ANF представление (15 баллов)
- Если кто-то захочет сделать CPS представление --- не возражаю.
- В процессе построения оно должно быть адекватным. Стоит его распечатывать обратно в исходный синтаксис, и проверять, что типы (не) разъехались.
- Порождение кода для LLVM разумной версии (в том году это была 16я). (15 баллов)
- Код затем должен компилироваться в ELF и запускаться (QEMU). Интерпретировать LLVM биткод нельзя.
- Печатать в тестах биткод, чтобы его можно было проверить глазами на (не)адекватность.
- Порождение ассемблерного листинга для RISC-V 64. (25 баллов)
- Код должен затем компилироваться в ELF стандартным RISC-V тулчейном.
- Скомпилированные программы должны запускаться (что-то кроме QEMU --- запрещено).
- Аналогично печатать ассемблер в тестах
- Интегрировать в язык реализацию сборки мусора. (10 баллов)
- В идеале, одну и туже и для LLVM, и для RISC-V.
Итого: 10+15+15+25+10 + 20(за экзамен) даст вам примерно 100 баллов, которые пересчитаются в оценку стандартным для универа способом. N.B. За экзамен нужно получить хотябы 10 из 20, иначе на пересдачу.
- Целые числа, булевы значения и сравнения чисел и прочая арифметика
- Идентификаторы должны быть как в OCaml, запрещено резервировать какие-то имена, чтобы их порождать по ходу дела.
- Парсер должен работать шустро, а не парсить объявления факториала 10 секунд
- К идентификатором разрешено приписывать типы явно:
fun (x: int) -> ...
- Рекурсивные функции на верхнем уровне (в компиляторе называется structure_item).
- Разрешено переопределять операторы как функции:
let (+) = ...
- First-class Функции, в том числе с частичным примерением и взаимной рекурсией.
- Вызовы функций должны быть efficient: если 3-арная функция вызывается от трёх аргументов, то нельзя делать 3 частичных применения под одному аргументу.
- Вложенные let-определения
- Не должно быть никакого ограничения сверху на количество аргументов у функций.
- В том году бойцы нагенерили большой switch на 100 арностей функций, а в случае >100 --- рантайм падал. так делать не надо
- Разрешено переопределять операторы как функции:
- Сопоставление с образцом для кортежей и списков
- Полноценные алгебраические типы не обязательно
- Рантайм: печать чисел, примитивы частичного применения и сборки мусора.
- Должны обрабатываться ошибки в процессе компиляции: компилятор не должен крешиться.
- Что-нибудь ещё, что я забыл :)