Тривиль — первая программа скомпилирована и исполнена

Программа:

модуль x
@внешняя фн tri_welcome()
вход {
tri_welcome()
}

Скомпилирована в С:

#include «trirun.h»
#include «x.h»
int main() {
tri_welcome();
return 0;
}

и выполнена:

trivil-welcome

Функция tri_welcome написана на С и печатает: Trivil!

Трудозатраты на компилятор до этого момента — примерно 25-30 часов, не пытался точно засекать. Я вполне доволен скоростью разработки.

Компилятор делаю в самом удобном для меня стиле — сначала делаю «скелет», потом наращиваю «жир».

Скелет готов, в него входит:

  • Сканер — практически полный, нет экспоненты у вещественных.
  • Парсер — часть грамматики: модуль, функция, оператор только один, выражение — только вызов. Строит AST
  • Семантика — один обход AST — построение таблицы имен и поиск, типы не проверяются
  • Генерация — только того, что есть в AST
  • Обработка ошибок вполне рабочая

Далее наращивание возможностей:

  • более-менее полный набор операторов и выражений. Проверка: факториал
  • импорт. Проверка: библиотека консольной печати
  • массивы и классы

 

4 комментария


  1. Мои поздравления и соболезнования))

    Русский язык горячо поддерживаю, собака впереди внешнего объявления (сугубо имхо) — лишняя. Лучше сделать в форме стандартного импорта Но с каким-нибудь спецификатором в объявлении импорта.

    Окончание модуля часть опциональная, но по опыту Компонентного Паскаля — лучше добавить. За окончанием модуля можно вставлять документацию, команды запуска, да хоть котиков. Имхо, очень удобно.

    Ответить

    1. «собака впереди внешнего объявления (сугубо имхо) — лишняя.»

      Вполне возможно, что в модификаторы (@имя) придется добавить доп. параметры, например: @внешняя{имя=»printf», ABI=»C»}. А это не сделаешь импортом. Да и использование собаки уже устоялось — Java annotations, Typescript decorators, Swift attributes…

      «Окончание модуля часть опциональная, но по опыту Компонентного Паскаля — лучше добавить» — может быть, но я уже пришел к мысли, что модули надо делать много-файловыми (как в Го), иначе неудобно. А тогда смысл добавления «котиков» изрядно теряется.

      Ответить

      1. А зачем, по вашему опыту, делать модули многофайловыми?
        Недостаточно делать их иерархическими, как в Rust?
        Может быть «если что-то требует нескольких файлов, это стоит рассмотреть как больше чем один модуль?»

        Ответить

        1. Сейчас парсер в Тривиле 1200 строк и будет раза в полтора больше. Делить парсер на несколько модулей нет смысла, это лишний импорт/экспорт. Я предпочитаю разбить его на несколько файлов, сейчас их 7: из них 5 основных (описания, типы, операторы, выражения, функции), один отладочный и один для тестирования.

          В принципе, можно весь парсер запихать в один файл. Например, основная часть Go парсера — около 3000 строк в одном файле, впрочем кроме этого файла, есть еще два файла поменьше. Но мне так неудобно.

          Ответить

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *