Обновлённый язык программирования на русском языке, с компилятором даже на телефонах

В первой статье мы рассказывали про сферу, компилируемый язык, где всё построено на русском языке: ключевые слова, типы, стандартная библиотека. Компилятор написан на Rust и выдаёт машинный код через LLVM 18. С тех пор прошло несколько версий, и накопилось достаточно, чтобы рассказать отдельно. Сразу предупредим, что статья длинная: здесь и смена синтаксиса, и сборки под все платформы, и Android-приложение с компилятором внутри, и сайт, который написан на сфере.
Репозиторий: github.com/nikitosklim/Sfera, лицензия MIT. Сайт с уроками и загрузками: языксфера.рф.

Что не давало покоя: русские слова и не русская пунктуация
Любой, кто пробовал писать на сфере, упирался в одно и то же. Слова русские, а скобки {}, стрелка ->, &&, <>, [] и $ приходилось набирать на английской раскладке. Язык, который заставлял писать код на двух раскладках сразу. Так быть не должно, поэтому пришлось менять привычные {} скобки на иной подход.
функция главная() -> целое {
Список<целое> числа = Список<целое>();
числа.добавить(10);
если (числа.получить(0) > 5 && !(числа.размер() == 0)) {
вывести("ok");
}
вернуть 0;
}Стало:
функция главная(): целое
Список из целых числа = Список из целых();
числа.добавить(10);
если (числа.получить(0) больше 5 и не (числа.размер() == 0))
вывести("ok");
конец
вернуть 0;
конецЧто именно поменялось:
Блок закрывается словом
конец. Открывающего слова нет: блок начинается сразу после заголовка. Цепочкаесли … иначе если … иначезакрывается однимконец.Тип возврата пишется после двоеточия, стрелка не нужна.
Обобщённые типы пишутся словами:
Список из целых,Словарь из текста и целого,результат из целого,канал из текста.Операторы словами:
и,или,не,меньше,больше,не меньше,не больше.Подстановка в строках:
"Сумма: %сумма%, вдвое: %(сумма * 2)%"вместо$имя.Побитовые операции стали функциями:
включить_биты(1, сдвинуть_влево(1, 4))даёт 17.
Если вы считаете что данное обновление может приносить дискомфорт или это не удобно, или же у вас есть предложения как можно сделать лучше, то пожалуйста оставьте свой коментарий под этой статьей. Будем вместе думать и вносить изменения, чтобы добится лучшего варианта!
Старая запись продолжает работать, даже в одном проекте. А для переезда есть конвертер:
запустить --в-русский файл.код # результат в стандартный вывод
запустить --в-русский файл.код --на-месте # перезаписать файлОн не заменяет текст регулярками. Конвертер разбирает программу настоящим парсером, запоминает, какие токены перевести, а после преобразования проверяет, что дерево программы не изменилось. Если проверка не прошла, файл остаётся как был. Так мы и перевели весь репозиторий: примеры, тесты, стандартную библиотеку, сайт и панель разработчика.
Цена у этого решения тоже есть:
Слова
конец,из,и,или,не,меньше,большетеперь зарезервированы. У меня в собственной панели нашлась переменная с именемви несколько с именеми, пришлось переименовывать.%имя%внутри любой строки теперь подстановка. Если нужен буквальный процент, пишется%%.Операторы
ииилине вычисляют правую часть лениво. Если вы привыкли писатьх != 0 && 10 / х > 1, здесь так делать нельзя, нужны вложенныеесли. Я наступил на это сам: программа падала там, где в другом языке всё было бы в порядке. Это в списке того, что надо исправить.Фраза «иначе если» превращается в цепочку только тогда, когда оба слова стоят на одной строке. Иначе парсер не отличит её от вложенного условия.
Если обобщённый тип вложен в другой и стоит не последним аргументом, пока остаются угловые скобки.
Один язык — пять платформ
Раньше «Сфера» жила у нас на MacBook или Windows. Теперь у каждой системы есть своя сборка:
Windows. Установщик и панель разработчика. Пришлось переписать сокеты на Winsock, переключать консоль в UTF-8 и подменять недостающие POSIX-вызовы (
snprintf,clock_gettime, потоки). На Windows было потрачено больше времени, чем на что-либо другое: подряд идёт десяток коммитов с названием «Fix» про линковку, LLVM-символы и условную компиляцию.macOS. Отдельные сборки для Intel (собираемые у себя на MacBook) и Apple Silicon (собирается в GitHub Actions).
Linux. Панель и компилятор в архиве.
Android. Об этом отдельный рассказ ниже.

Линукс, Apple Silicon и Android собирает GitHub Actions: запуск вручную или при выпуске тега версии. Сборки для Intel Mac и Windows пока делаются скриптами. Дальше все файлы выкладываются на сайт, и рядом с каждым показана контрольная сумма SHA-256.
Компилятор внутри Android-приложения
Это самое неожиданное, что получилось. Идея в том, чтобы писать и запускать код сферы на телефоне, без root, без Termux и без компьютера.

Устроено так. В APK лежит сам компилятор, собранный под ARM64, линковщик ld.lld и небольшая замена clang, которая нужна для линковки. Всё это приложение вызывает как обычные программы: компилирует код в объектный файл, линкует и запускает получившийся бинарник в собственной песочнице.
Пришлось решить несколько неприятных задач:
Откуда запускать бинарники. Android запрещает исполнять файлы из домашней папки приложения, начиная с API 29. Поэтому инструменты лежат в APK под видом библиотек
lib*.so: система сама распаковывает их в каталог, откуда запуск разрешён. А для собранных на телефоне программ приходится собирать приложение сtargetSdk 28. Из-за этого в Google Play такое приложение не попадёт, поэтому распространяется оно через сайт.Целевая тройка. LLVM, который я собрал под Android, не знал нужную тройку, пришлось указывать её явно.
Путь к библиотекам. Приложение определяет каталог с библиотеками при первой подготовке и сохраняет его в файл. Сначала я вычислял его на лету, и фоновый запуск терял цепочку родительских процессов: пользователь видел сообщение «В этом APK нет компилятора», хотя компилятор там был.

Сама среда разработки тоже написана на сфере: редактор с подсветкой синтаксиса, файлы, справка, уроки и примеры внутри приложения, консоль с выводом. Графика идёт через SDL по FFI. Приложение подписывается постоянным ключом, значок и версия берутся из Cargo.toml.
Проверка на живом телефоне выглядит так: открываю многопоточность.код, нажимаю «Запустить», в консоли появляется «сборка, готово, запуск, 4, код выхода: 0». Программа компилируется и исполняется на устройстве.
функция главная(): целое
канал из целого канал_результата = создать_канал();
параллельно
целое вычислено = 2 + 2;
канал_результата.отправить(вычислено);
конец
целое значение = канал_результата.получить();
вывести(целое_в_текст(значение));
вернуть 0;
конецСайт, написанный на сфере

Сайт обязательно должен был быть написан на нашем языке программирования. Это хороший способ найти его слабые места: если чего-то не хватает для настоящего сервера, это сразу видно.
Что внутри:
HTTP-сервер из стандартной библиотеки: пул из 16 потоков, каждый принимает подключения с общего слушающего сокета. Загрузка большого файла занимает только один поток.
Раздача файлов с докачкой (
Range),ETagи ответами 304.Собственный разбор Markdown (модуль
разметка.код), оглавление и подсветка кода.Поиск по всем материалам: индекс отдаётся одним текстом, поиск делает страница.
Загрузка установщиков на сервер через
PUTпо токену прямо потоком в файл, для этого есть скриптupload-release.sh.Счётчик посещений, карта сайта,
robots.txt.
Маршрутизация выглядит так:
функция маршрутизировать(целое32 клиент, Запрос з): целое
текст сегмент = первый_сегмент(з.путь);
текст остаток = остаток_пути(з.путь);
...
текст раздел = раздел_по_сегменту(сегмент);
если (длина(раздел) больше 0)
текст русский_раздел = раздел_в_адрес(раздел);
если (длина(остаток) == 0)
если (сегмент != русский_раздел)
вернуть на_русский_адрес(клиент, з, "/" + русский_раздел);
конец
вернуть показать_каталог(клиент, раздел);
конец
...Домен у сайта тоже русский: языксфера.рф. Адреса страниц между прочем тоже на русском языке: /уроки/быстрый-старт, /документация/многопоточность, /загрузки, а служебные пути называются /статика и /загрузить. Старые латинские адреса, которые мы писали вначале разработки сайта, отвечают кодом 301 и перенаправляют на русские, так что ссылки не сломались.
Работает всё на обычном VPS: nginx с сертификатом Let's Encrypt проксирует запросы на сервер на «Сфере», который запущен как systemd-служба. Релиз сайта собирает GitHub Actions, на сервере его разворачивает один скрипт.
На сайте сейчас 32 раздела документации, семь уроков (от первой программы до своего веб-сервера), 11 примеров и поиск. Можете перейти и глянуть, я думаю это удобный способ просмотра того как устроен язык, всё разделено по разделам и также имеется поиск по словам, так что можно найти любую учебную информацию для справки, по тому как устроен язык. Обязательно перейдите на сайт и сами зацените, если есть пожелания, то пожалуйста напишите их в комментарии.
Что нашлось по нашему пути
Писать большой проект на своём языке полезно в основном из-за ошибок, которые он вытаскивает наружу. Из недавних:
Проверка обязательного возврата из функций и методов работала неправильно. Бесконечный цикл
пока (да)теперь считается возвратом, а ошибочные срабатывания исправлены.Структуры с текстовыми полями копируют строку, поэтому нельзя хранить в них указатель на буфер, который может содержать нулевые байты: он обрезается. Для дескрипторов я использовал целые числа.
Через переменную, объявленную внутри цикла, на каждой итерации утекал стек. Это одна из самых неприятных ошибок за всё время: после полумиллиона итераций программа падала без единого предупреждения. Теперь все переменные размещаются в начале функции.
Подробный список найденных и исправленных use-after-free и double-free есть в дневнике разработки в репозитории.
Чего ещё нет
Честно о слабых местах:
Язык молодой (версия 0.3.3), совместимость между версиями пока не гарантируется.
В отладчике нельзя посмотреть значение переменной по имени, а точки останова и шаги работают в обычных lldb и gdb.
Установщик для Windows не подписан, система покажет предупреждение.
Операторы
ииилине ленивые, об этом выше.Сообщества почти нет: нужна заинтересованность людей в нашем проекте.
Что дальше
Пакетный индекс для менеджера пакетов
сфера_пакеты.Значения переменных в отладчике.
Ленивые
ииили.Подписанные установщики и автоматическая сборка для Windows.
Больше уроков и примеров, раздел с проектами сообщества на сайте.

Скачайте сборку для своей системы на языксфера.рф/загрузки. Для каждой системы там есть короткая инструкция.
Пройдите быстрый старт, это около десяти минут.
Или соберите из исходников:
cargo build --release(нужен LLVM 18).
Если попробуете и что-то сломается, напишите в issues. Такая обратная связь для нашего проекте ценнее всего! А если проект кажется полезным, его можно поддержать или же рассказать о нём знакомым.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.