Сфера 0.3.0: язык, который наконец можно набирать на русской раскладке
В прошлой статье я рассказывал, как устроена «Сфера» — компилируемый язык программирования, в котором на русском всё: ключевые слова, типы, стандартная библиотека. Компилятор написан на Rust и генерирует машинный код через LLVM 18.
Оставалась одна неловкость, и она бросалась в глаза любому, кто пробовал писать на «Сфере» по-настоящему. Слова русские, а пунктуация — нет. Фигурные скобки, ->, <>, &&, [], $: чтобы их набрать, приходится переключать раскладку туда-сюда каждые несколько слов. Язык без единой латинской буквы в ключевых словах заставлял вас жить на двух раскладках сразу.
В версии 0.3.0 я это исправил. Весь синтаксис теперь можно набрать, ни разу не переключаясь на английскую раскладку.
Как это выглядит
Было:
функция главная() -> целое {
Список<целое> числа = Список<целое>();
числа.добавить(10);
если (числа.получить(0).значение > 5 && !(числа.размер() == 0)) {
вывести("ok");
}
вернуть 0;
}
Стало:
функция главная(): целое
Список из целых числа = Список из целых();
числа.добавить(10);
если (числа.получить(0).значение больше 5 и не (числа.размер() == 0))
вывести("ok");
конец
вернуть 0;
конец
Это не пересказ «на глаз»: вторая запись — буквальный вывод конвертера, который входит в компилятор (о нём ниже).
Что изменилось
Блоки закрываются словом конец. Открывающего слова нет: блок начинается сразу после заголовка. Цепочка если … иначе если … иначе закрывается одним конец, а не лесом скобок. «Иначе если» — это цепочка только тогда, когда оба слова стоят на одной строке.
функция оценка(целое баллы): текст
если (баллы не меньше 90)
вернуть "отлично";
иначе если (баллы не меньше 60)
вернуть "хорошо";
иначе
вернуть "подтянуть";
конец
конец
Тип возврата — после двоеточия: функция сложить(целое а, целое б): целое. Стрелка -> не нужна.
Обобщённые типы пишутся словами. Список из целых, Словарь из текста и целого, результат из целого, канал из текста. Вместо угловых скобок — предлог «из» и союз «и».
Операторы — словами. и, или, не, меньше, больше, не больше, не меньше. Равенство == и арифметика остались как есть: они и так набираются на любой раскладке.
Строки с подстановкой. Вместо $имя теперь %имя%, а для выражений — %(выражение)%. Сам знак процента пишется как %%:
вывести("Сумма: %сумма%, частное: %(р.значение)%");
вывести("Вдвое: %(сумма * 2)%, оценка: %(оценка(75))%");
Индексы и массивы. числа(0) вместо числа[0], тип массива — целое(5), литерал — массив(1, 2, 3).
Побитовые операции — функциями. Вместо &, |, ^, ~, <<, >> теперь есть наложить_маску, включить_биты, переключить_биты, инвертировать_биты, сдвинуть_влево, сдвинуть_вправо:
целое флаги = включить_биты(1, сдвинуть_влево(1, 4)); // 17
Старый код не сломался
Старый синтаксис по-прежнему работает: можно писать и так и так, даже в одном проекте. Но есть и конвертер, который переводит существующий код в новую запись:
запустить --в-русский файл.код # результат в стандартный вывод
запустить --в-русский файл.код --на-месте # перезаписать файл
Конвертер не делает замен по регулярным выражениям. Он разбирает программу настоящим парсером, запоминает, какие токены нужно заменить, и после преобразования проверяет, что дерево программы не изменилось. Если проверка не прошла, файл не трогается. Так я перевёл весь репозиторий — 48 файлов .код: примеры, тесты, стандартную библиотеку, сайт и панель разработчика.
Цена вопроса
Честно о том, чего это стоило.
- Слова
конец,из,и,или,не,меньше,большетеперь зарезервированы. Если у вас была переменная с именемконецилииз, её придётся переименовать. У меня такая нашлась в собственной панели разработчика. - Правила
%…%действуют во всех строках, в том числе в старом коде. Одиночный%остаётся обычным символом, но%имя%внутри строки теперь подстановка. Если вам нужен буквальный текст вроде100%имя%, пишите%%. - Если обобщённый тип вложен в другой и стоит не последним аргументом, остаются старые угловые скобки. Это единственное место, где без
<>пока не обойтись. - Разбор стал сложнее. Фраза «иначе если» может означать цепочку, а может — вложенное условие после
иначе, поэтому появилось правило про одну строку.
Заодно обновилось
- Языковой сервер и расширение для VS Code знают новые слова: подсветка, автодополнение, сниппеты, отступы по
конец. - Сообщения об ошибках стали человеческими. Вместо
ожидался Конец, но встретился ТочкаЗапятойтеперь: «ожидалось «конец», но встретилось «;»». - Исправлен баг установщика панели на Windows: путь, выбранный в диалоге папки, приходил с символами перевода строки.
Что дальше
Из планов: сайт и документация уже переведены на новый синтаксис, дальше хочется заняться пакетным индексом и теми частями, которые я честно перечислял как незавершённые в прошлой статье.
Код открыт, лицензия MIT: github.com/nikitosklim/Sfera. Справочник по синтаксису — ДОКУМЕНТАЦИЯ_ЯЗЫКА.md в репозитории, там есть раздел «Два способа записи» с таблицей соответствий. Если попробуете конвертер на своём коде и он сломается — пишите в issues, это самый ценный отзыв.