и что к этому вопросу имеете добавить? :)
Давайте я начну издалека. Интересно ознакомиться с историей проекта. Оказывается, этот MicroC родом из университетского курса. Курс вполне стандартный, но простенький компилятор там предлагалось строить на Ocaml. По мотивам автор блога решил сделать версию для Haskell. Как видно из github-статистики, работал он над своей версией в течение 2 лет.
На что сразу хочу обратить внимание. Здесь имеет место типичная история для современных bondage-and-discipline ("строгих"/"чистых"/etc) языков в духе Haskell или, например, Rust. Задача четко и формально определена, более того, уже есть ее решение. То есть весь вопрос в переписывании, с целью достижения каких-то новых качеств.
Вообще говоря, MicroC очень примитивен, в нем нет даже массивов (но автор добавил от себя структуры), а сам компилятор — это только передний план, без особых изысков, за исключением семантического анализа.
Автор активно пользуется готовыми библиотеками из Haskell для реализации парсера и порождения LLVM-представления, но при этом объем полученного кода на Haskell вполне сравним с chibicc (который реализует многое из C99 и генерирует x64-код) на чистом Си.
Теперь кратко по отдельным разделам.
1. Очень хорошо, что автор привел сравнение lex/yacc-подобного инструмента и работы библиотеки комбинаторов парсеров. На мой взгляд, в данном случае убедительную победу завоевал заурядный генератор парсеров. К счастью, комбинаторы парсеров могут быть гораздо более выразительными, но, увы, не в данной Haskell-реализации.
2. Специально для семантического анализа автор вводит еще один вариант промежуточного представления, что не назовешь легковесным решением. Далее наблюдается достаточно низкоуровневая работа по простейшему анализу семантики.
3. Здесь, в основном, идет работа с готовой библиотекой поддержки LLVM. В какой-то момент автор срывается в описание свойств SSA и phi-функций, но не стоит его принимать всерьез -- на деле код будет сгенерирован самым обычным образом, в надежде на LLVM'овский mem2reg.
В целом, на мой взгляд, посредственная читаемость кода данного игрушечного компилятора проистекает, в первую очередь, из-за монадического подхода. Классический вариант на SML от того же Аппеля имеет гораздо более ясный код. Конечно же, я не говорю сейчас о том, что части компилятора сегодня можно писать на более высоком уровне, с помощью специальных нотаций/eDSL.