rusi/README.md

762 lines
41 KiB
Markdown
Raw Permalink Normal View History

```markdown
# Руси: двуязычный компилятор C с русским синтаксисом
**Руси** — это компилятор языка C, поддерживающий **полноценный двуязычный синтаксис**.
Вы можете писать программы на C, используя как **английские**, так и **русские** ключевые слова, типы данных, операторы и директивы препроцессора — в любом сочетании, в одном файле.
Название проекта — **Руси** — говорит само за себя: это язык C, заговоривший по-русски, но при этом сохранивший родной английский синтаксис для тех, кому он привычнее.
Проект вдохновлен двумя реализациями:
- [chibicc](https://github.com/rui314/chibicc) — небольшой, но мощный C11 компилятор, способный компилировать реальные проекты.(Собственно и сделан на его основе)
- [c89cc.sh](https://gist.github.com/alganet/2b89c4368f8d23d033961d8a3deb5c19) — минималистичный компилятор C89/ELF64 на чистом shell, демонстрирующий невероятную простоту реализации.
Проект **Руси** разработан для портирования компилятора [КВС (kvs)](https://github.com/artradeskz/kvs) — ассемблера с русским синтаксисом, написанного на Python. Вместо того чтобы использовать интерпретатор Python для сборки, **Руси** позволит скомпилировать этот ассемблер в нативный бинарный файл, значительно повысив производительность и удобство использования.
## Двуязычность: как это работает
**Руси** одновременно понимает два языка: английский C и русский C. Это означает, что:
- Вы можете писать код **полностью на английском** — как в любом стандартном C.
- Вы можете писать код **полностью на русском** — используя русские ключевые слова, типы и операторы.
- Вы можете **смешивать** английский и русский синтаксис в одном файле.
Это делает компилятор идеальным инструментом для обучения, миграции проектов и команд с разными языковыми предпочтениями.
### Примеры смешанного синтаксиса
```c
// Английский main с русским типом и оператором
int главн() {
цел x = 42;
if (x == 42) {
возврат 0;
}
return 1;
}
// Русский
цел главн() {
цел ы = 42;
если (ы == 42) {
возврат 0;
}
возврат 1;
}
// Полностью смешанный стиль
цел main() {
int счетчик = 0;
для (счетчик = 0; счетчик < 10; счетчик = счетчик + 1) {
if (счетчик % 2 == 0) {
printf("Четное: %d\n", счетчик);
}
}
возврат 0;
}
```
## Полный список русских слов для программирования
### Типы данных (13)
| Английский | Русский | Пример |
|------------|---------|--------|
| `int` | `цел` | `цел x = 42;` |
| `char` | `символ` | `символ c = 'A';` |
| `short` | `корот` | `корот s = 123;` |
| `long` | `длин` | `длин l = 456789;` |
| `void` | `пусто` | `пусто функция() {}` |
| `float` | `плав` | `плав f = 3.14;` |
| `double` | `двойн` | `двойн d = 2.71;` |
| `struct` | `структ` | `структ Точка {};` |
| `union` | `объед` | `объед Данные {};` |
| `enum` | `переч` | `переч Цвет {};` |
| `_Bool` | `бул` | `бул flag = истина;` |
| `unsigned` | `беззнак` | `беззнак цел u = 42;` |
| `signed` | `знак` | `знак цел s = -42;` |
### Ключевые слова (16)
| Английский | Русский | Пример |
|------------|---------|--------|
| `typedef` | `типдеф` | `типдеф цел МойЦел;` |
| `static` | `стат` | `стат цел счетчик = 0;` |
| `extern` | `внеш` | `внеш цел глобальная;` |
| `inline` | `инлайн` | `инлайн цел квадрат() {}` |
| `const` | `конст` | `конст цел x = 42;` |
| `volatile` | `летуч` | `летуч цел x;` |
| `auto` | `авто` | `авто цел x = 42;` |
| `register` | `регистр` | `регистр цел x;` |
| `restrict` | `огранич` | `цел * огранич ptr;` |
| `_Alignas` | `_Выравнивание` | `_Выравнивание(16) символ buf[32];` |
| `_Alignof` | `_Выравнивание_типа` | `_Выравнивание_типа(цел);` |
| `_Noreturn` | `_Безвозврат` | `_Безвозврат пусто функция() {}` |
| `_Generic` | `_Обобщ` | `_Обобщ(42, цел: 1, умолч: 0);` |
| `_Atomic` | `_Атом` | `_Атом цел x;` |
| `_Thread_local` | `_Поток_лок` | `_Поток_лок цел x;` |
| `__thread` | `__поток` | `__поток цел x;` |
### Операторы (18)
| Английский | Русский | Пример |
|------------|---------|--------|
| `return` | `возврат` | `возврат 0;` |
| `if` | `если` | `если (x == 10) {}` |
| `else` | `иначе` | `иначе {}` |
| `for` | `для` | `для (i = 0; i < 10; i++) {}` |
| `while` | `пока` | `пока (i < 10) {}` |
| `do` | `делай` | `делай {} пока (i < 10);` |
| `switch` | `выбор` | `выбор (x) {}` |
| `case` | `случай` | `случай 1:` |
| `default` | `умолч` | `умолч:` |
| `goto` | `перейти` | `перейти метка;` |
| `break` | `прерви` | `прерви;` |
| `continue` | `продолжи` | `продолжи;` |
| `sizeof` | `размер` | `размер(цел);` |
| `typeof` | `типоф` | `типоф(x) y;` |
| `asm` | `асм` | `асм("nop");` |
| `&&` | Оставлено как есть | `x && y` |
| `\|\|` | Оставлено как есть | `x \|\| y` |
| `!` | Оставлено как есть | `!x` |
### Директивы препроцессора (15)
| Английский | Русский | Пример |
|------------|---------|--------|
| `#include` | `#включить` | `#включить <stdio.h>` |
| `#include_next` | `#включить_след` | `#включить_след "file.h"` |
| `#define` | `#определить` | `#определить ПИ 3.14` |
| `#undef` | `#отменить` | `#отменить ПИ` |
| `#if` | `#если` | `#если ВЕРСИЯ == 2` |
| `#ifdef` | `#еслиопр` | `#еслиопр ТЕСТ` |
| `#ifndef` | `#еслинеопр` | `#еслинеопр ТЕСТ` |
| `#elif` | `#иначеесли` | `#иначеесли ВЕРСИЯ == 2` |
| `#else` | `#иначе` | `#иначе` |
| `#endif` | `#конецесли` | `#конецесли` |
| `#line` | `#строка` | `#строка 100 "file.c"` |
| `#error` | `#ошибка` | `#ошибка "Сообщение"` |
| `#pragma` | `#прагма` | `#прагма once` |
| `defined` | `определено` | `#если определено(ТЕСТ)` |
| `once` | `однократно` | `#прагма однократно` |
### Встроенные макросы (9)
| Английский | Русский | Пример |
|------------|---------|--------|
| `__FILE__` | `__ФАЙЛ__` | `символ *f = __ФАЙЛ__;` |
| `__LINE__` | `__ЛИНИЯ__` | `цел n = __ЛИНИЯ__;` |
| `__func__` | `__функ__` | `символ *f = __функ__;` |
| `__FUNCTION__` | `__ФУНКЦИЯ__` | `символ *f = __ФУНКЦИЯ__;` |
| `__COUNTER__` | `__СЧЕТЧИК__` | `цел n = __СЧЕТЧИК__;` |
| `__TIMESTAMP__` | `__ВРЕМЯ_ФАЙЛА__` | `символ *t = __ВРЕМЯ_ФАЙЛА__;` |
| `__DATE__` | `__ДАТА__` | `символ *d = __ДАТА__;` |
| `__TIME__` | `__ВРЕМЯ__` | `символ *t = __ВРЕМЯ__;` |
| `__BASE_FILE__` | `__БАЗОВЫЙ_ФАЙЛ__` | `символ *b = __БАЗОВЫЙ_ФАЙЛ__;` |
### Функции (1)
| Английский | Русский | Пример |
|------------|---------|--------|
| `main` | `главн` | `цел главн() {}` |
## Особенности
- **Двуязычный синтаксис**: все ключевые слова, типы, операторы и директивы препроцессора доступны как на английском, так и на русском языке.
- **Смешивание языков**: английский и русский синтаксис можно использовать в одном файле в любых сочетаниях.
- **Русские идентификаторы**: можно называть переменные, функции и структуры по-русски.
- **Русские имена файлов и расширения**: компилятор работает с файлами `программа.си` и заголовками `привет.з`.
- **Полная поддержка C11**: включая препроцессор, битовые поля, VLA, атомарные и thread-local переменные.
- **70+ переведенных конструкций**: все ключевые слова, операторы, макросы и директивы покрыты тестами.
## Пример программы (смешанный синтаксис)
```c
#включить <stdio.h>
#включить <stdbool.h>
структ Точка {
цел x;
цел y;
};
цел суммаоординат(структ Точка точка) {
возврат точка.x + точка.y;
}
цел главн() {
цел массив[10];
for (цел i = 0; i < 10; i = i + 1) {
массив[i] = i * 2;
}
int сумма = 0;
для (int i = 0; i < 10; i = i + 1) {
сумма = сумма + массив[i];
}
если (sum == 90) {
printf("Сумма: %d\n", сумма);
} else {
printf("Ошибка!\n");
возврат 1;
}
struct Точка точка = {10, 20};
цел результат = суммаоординат(точка);
если (результат == 30) {
printf("OK\n");
возврат 0;
}
return 1;
}
```
## Импорт файлов с русскими именами
```c
// привет.з - русский заголовочный файл
#еслинеопр ПРИВЕТ_З
#определить ПРИВЕТ_З
#включить <stdio.h>
#define ПЕЧАТЬ printf
#endif
```
```c
// программа.рс - основная программа
#включить "привет.з"
цел главн() {
ПЕЧАТЬ("Привет, мир!\n");
возврат 0;
}
```
## Компиляция русских файлов
```bash
./руси программа.рс -o программа
./программа
# Вывод: Привет, мир!
```
## Внутреннее устройство
Компилятор состоит из четырех этапов:
1. **Токенизация** — разбиение исходного кода на токены (с поддержкой UTF-8 и кириллицы).
2. **Препроцессинг** — обработка директив и макросов (с русскими синонимами).
3. **Парсинг** — построение AST с использованием рекурсивного спуска.
4. **Генерация кода** — создание ассемблерного текста для x86-64 (ELF64).
## Тестирование и самосборка
Проект имеет две независимые системы тестирования:
### 1. Стандартные тесты (английский синтаксис)
Запускаются командой `make test`. Проверяют базовую функциональность компилятора на оригинальном C.
### 2. Русские тесты
Запускаются командой `make test-ru`. Написаны на Python (`test_ru/run_tests.py`) и проверяют все русские синонимы. 70+ тестов покрывают все переведенные конструкции:
```bash
make test-ru
# Вывод: 🎉 Все тесты пройдены!
```
### 3. Самосборка (Stage 2)
Компилятор способен скомпилировать сам себя. Этот процесс называется **самосборкой** (self-hosting) и подтверждает, что компилятор достаточно зрелый для работы с собственным кодом.
```bash
make test-stage2
```
Эта команда:
1. Компилирует компилятор с помощью самого себя (stage2)
2. Проверяет, что stage2-версия проходит все тесты
3. Подтверждает, что компилятор способен воспроизвести себя
Самосборка — важный этап разработки компилятора, доказывающий его надежность и полноту.
## Планы по миграции исходного кода на русский синтаксис
Текущая версия компилятора уже **полностью понимает русский синтаксис** и успешно проходит все тесты (включая 70+ русских тестов). Следующий логический шаг — **переписать сам исходный код компилятора на русском синтаксисе**.
### Что это даст?
1. **Полная русификация**: исходный код компилятора будет написан на том же языке, который он компилирует.
2. **Демонстрация возможностей**: сам компилятор станет лучшим примером использования русского синтаксиса.
3. **Образовательная ценность**: русскоязычные студенты смогут изучать устройство компилятора без языкового барьера.
4. **Двуязычная кодовая база**: английская и русская версии будут существовать параллельно.
### Как это будет сделано
1. **Поэтапная миграция**: исходный код будет переписан на русский синтаксис постепенно, файл за файлом.
2. **Сохранение двуязычности**: компилятор продолжит понимать оба синтаксиса.
3. **Тестирование**: после каждого этапа будет запускаться полный набор тестов.
4. **Самосборка**: после завершения миграции компилятор сможет скомпилировать себя из русскоязычного исходного кода.
### Статус
-**Компилятор понимает русский синтаксис** — полностью готово.
-**Функция main переименована в главн** — сделано.
-**Миграция исходного кода на русский синтаксис** — в планах.
-**Самосборка из русскоязычного исходного кода** — следующий этап.
### Пример того, как будет выглядеть код компилятора на русском
```c
// Токенизатор на русском синтаксисе (планируется)
структ Токен {
переч ВидТокена вид;
Токен *следующий;
цел значение;
символ *позиция;
цел длина;
};
цел прочитать_идентификатор(символ *начало) {
символ *p = начало;
цел c = декодировать_utf8(&p, p);
если (!это_идентификатор1(c)) {
возврат 0;
}
пока (истина) {
символ *q;
c = декодировать_utf8(&q, p);
если (!это_идентификатор2(c)) {
возврат p - начало;
}
p = q;
}
}
```
## Портирование КВС (kvs) с Python на C
Проект **Руси** разработан с прицелом на портирование компилятора [КВС (kvs)](https://github.com/artradeskz/kvs) — ассемблера с русским синтаксисом для x86-64, написанного на Python.
### Зачем это нужно?
КВС (расшифровывается как "Код В Силу" или просто "КВС") — это образовательный ассемблер, который использует русскую лексику для мнемоник инструкций, имён регистров и директив. Однако он написан на Python и работает как интерпретатор, что ограничивает его производительность и распространение.
**Руси** позволит:
1. **Скомпилировать КВС в нативный бинарный файл** — вместо интерпретации Python-скриптов, ассемблер будет работать как обычный исполняемый файл.
2. **Значительно повысить производительность** — компилированный код работает на порядок быстрее интерпретируемого.
3. **Распространять как самостоятельный бинарник** — не требуется устанавливать Python и зависимости.
4. **Улучшить интеграцию** — бинарный файл легче встраивать в различные системы и инструменты.
### Как будет происходить портирование
1. **Анализ архитектуры КВС**: КВС состоит из шести проходов: лексер, парсер, 4 прохода разрешения меток и констант, финальная сборка ELF.
2. **Переписывание на C с русским синтаксисом**: каждый модуль будет переписан на C, используя русские ключевые слова и идентификаторы.
3. **Сохранение логики**: шестипроходная архитектура останется, но будет оптимизирована для нативного выполнения.
4. **Полная совместимость**: бинарный файл должен компилировать те же `.квс` файлы, что и оригинальный Python-скрипт.
### Пример: лексер КВС на русском C
```c
// планируемый код лексера КВС на русском C
структ Токен {
переч ВидТокена вид;
символ *текст;
цел длина;
Токен *следующий;
};
Токен *лексический_анализ(символ *исходник) {
Токен *голова = нуль;
Токен *текущий = нуль;
символ *позиция = исходник;
пока (*позиция != '\0') {
пропустить_пробелы(&позиция);
если (*позиция == '\0') {
прерви;
}
если (*позиция == ';') {
пропустить_комментарий(&позиция);
продолжи;
}
Токен *токен = выделить_токен(&позиция);
если (голова == нуль) {
голова = токен;
} иначе {
текущий->следующий = токен;
}
текущий = токен;
}
возврат голова;
}
```
### Преимущества портирования для КВС
| Аспект | Python-версия (оригинал) | C-версия (план) |
|--------|--------------------------|-----------------|
| **Скорость сборки** | ~0.5-1.0 сек для простых программ | ~0.01-0.05 сек |
| **Установка** | Требуется Python 3.7+ | Ничего не требуется |
| **Распространение** | Исходники или .deb | Один бинарник |
| **Зависимости** | Стандартная библиотека Python | Только libc |
| **Интеграция** | Только как скрипт | Может встраиваться в любую систему |
### План работ по портированию
1. **Этап 1**: Портирование лексера (`квсексер.py` → `лексер.рс`)
2. **Этап 2**: Портирование парсера (`квс_парсер.py` → `парсер.рс`)
3. **Этап 3**: Портирование четырех проходов (`квс_проход*.py` → `проход*.рс`)
4. **Этап 4**: Портирование финальной сборки ELF (`квс_финсбор.py` → `финсбор.рс`)
5. **Этап 5**: Интеграция в единый бинарник (`квс_сборка.рс`)
6. **Этап 6**: Тестирование на всех 26 тестах КВС
## Подсветка синтаксиса для VS Code / VS Codium
В планах разработка **расширения для подсветки синтаксиса** русского C для редакторов VS Code и VS Codium.
### Что будет поддерживаться
- **Русские ключевые слова**: подсветка всех переведенных конструкций (`цел`, `если`, `возврат` и др.)
- **Русские идентификаторы**: правильное распознавание переменных и функций с кириллицей
- **Русские директивы препроцессора**: подсветка `#включить`, `#определить` и др.
- **Русские имена файлов**: корректная работа с файлами `.рс` и `.з`
### Планируемые функции расширения
- **Автодополнение**: подсказки для русских ключевых слов
- **Фрагменты кода**: готовые шаблоны для `если`, `для`, `структ` и др.
- **Форматирование**: автоматическое форматирование кода с русским синтаксисом
- **Проверка синтаксиса**: интеграция с компилятором **Руси** для проверки ошибок
### Статус
-**Разработка расширения для подсветки синтаксиса** — в планах.
-**Интеграция с компилятором** — следующий этап.
## Планы по русификации стандартной библиотеки
В планах создание **русскоязычной стандартной библиотеки** — заголовочных файлов с русскими именами для всех основных функций и констант.
### Зачем это нужно?
Русификация стандартной библиотеки сделает русский синтаксис по-настоящему завершенным. Программист сможет не только писать ключевые слова на русском, но и использовать функции и константы с русскими именами:
```c
#включить <стандарт.з>
цел главн() {
// Вместо printf("Привет!\n");
печать("Привет!\n");
// Вместо strlen("текст");
цел длина = длина_строки("текст");
// Вместо malloc(100);
пусто *память = выделить(100);
// Вместо free(память);
освободить(память);
возврат 0;
}
```
### Какие функции будут переведены
| Английское имя | Русское имя | Заголовочный файл |
|----------------|-------------|-------------------|
| `printf` | `печать` | `стандарт.з` (stdio.h) |
| `scanf` | `ввод` | `стандарт.з` (stdio.h) |
| `puts` | `вывод_строки` | `стандарт.з` (stdio.h) |
| `gets` | `получить_строку` | `стандарт.з` (stdio.h) |
| `malloc` | `выделить` | `стандарт.з` (stdlib.h) |
| `free` | `освободить` | `стандарт.з` (stdlib.h) |
| `calloc` | `выделить_нули` | `стандарт.з` (stdlib.h) |
| `realloc` | `перевыделить` | `стандарт.з` (stdlib.h) |
| `strlen` | `длина_строки` | `строки.з` (string.h) |
| `strcpy` | опировать_строку` | `строки.з` (string.h) |
| `strcmp` | `сравнить_строки` | `строки.з` (string.h) |
| `strcat` | `склеить_строки` | `строки.з` (string.h) |
| `strchr` | айти_в_строке` | `строки.з` (string.h) |
| `strstr` | айти_подстроку` | `строки.з` (string.h) |
| `memcpy` | опировать_память` | `память.з` (string.h) |
| `memset` | аполнить_память` | `память.з` (string.h) |
| `memcmp` | `сравнить_память` | `память.з` (string.h) |
| `exit` | `завершить` | `стандарт.з` (stdlib.h) |
| `rand` | `случайное` | `стандарт.з` (stdlib.h) |
| `srand` | `инициализировать_случайное` | `стандарт.з` (stdlib.h) |
| `time` | `время` | `время.з` (time.h) |
| `sqrt` | `корень` | `математика.з` (math.h) |
| `sin` | `синус` | `математика.з` (math.h) |
| `cos` | `косинус` | `математика.з` (math.h) |
| `tan` | `тангенс` | `математика.з` (math.h) |
| `pow` | `степень` | `математика.з` (math.h) |
| `abs` | `модуль` | `стандарт.з` (stdlib.h) |
### Как это будет реализовано
1. **Создание заголовочных файлов с русскими именами**: например, `стандарт.з` (аналог stdio.h + stdlib.h), `строки.з` (string.h), `математика.з` (math.h).
2. **Использование макросов**: русские имена будут определены через `#define` или через `typedef`.
3. **Полная совместимость**: можно будет использовать как русские, так и английские имена в одной программе.
### Пример заголовочного файла `стандарт.з`
```c
// стандарт.з - русская стандартная библиотека
#еслинеопр СТАНДАРТ_З
#определить СТАНДАРТ_З
#включить <stdio.h>
#включить <stdlib.h>
#включить <string.h>
#включить <math.h>
// Ввод-вывод
#определить печать printf
#определить ввод scanf
#определить вывод_строки puts
#определить получить_строку gets
#определить вывод_ошибки fprintf
// Управление памятью
#определить выделить malloc
#определить освободить free
#определить выделить_нули calloc
#определить перевыделить realloc
// Завершение программы
#определить завершить exit
// Работа со строками
#определить длина_строки strlen
#определить копировать_строку strcpy
#определить сравнить_строки strcmp
#определить склеить_строки strcat
#определить найти_в_строке strchr
#определить найти_подстроку strstr
// Работа с памятью
#определить копировать_память memcpy
#определить заполнить_память memset
#определить сравнить_память memcmp
// Случайные числа
#определить случайное rand
#определить инициализировать_случайное srand
// Математика
#определить корень sqrt
#определить синус sin
#определить косинус cos
#определить тангенс tan
#определить степень pow
// Константы
#определить ПИ 3.14159265358979323846
#определить Е 2.71828182845904523536
#конецесли
```
### Пример программы с русской стандартной библиотекой
```c
#включить "стандарт.з"
цел главн() {
печать("Введите число: ");
цел x;
ввод("%d", &x);
цел квадрат = степень(x, 2);
печать("Квадрат числа %d равен %d\n", x, квадрат);
печать("Синус числа: %f\n", синус(x));
символ *сообщение = выделить(100);
если (сообщение != нуль) {
копировать_строку(сообщение, "Привет, мир!");
печать("%s\n", сообщение);
освободить(сообщение);
}
завершить(0);
}
```
### Преимущества для образования
Русскоязычная стандартная библиотека станет мощным инструментом для обучения программированию, так как:
1. **Снижает порог входа**: студентам не нужно запоминать английские названия функций.
2. **Ускоряет обучение**: можно сразу переходить к логике, а не тратить время на запоминание терминов.
3. **Сохраняет совместимость**: при необходимости можно использовать английские имена.
### Статус
-**Русификация стандартной библиотеки** — в планах.
-**Создание заголовочных файлов с русскими именами** — следующий этап.
-**Интеграция с компилятором** — после создания библиотеки.
## Настройка русской раскладки для Linux
В планах создание **настройки для русской раскладки клавиатуры в Linux**, чтобы программистам не приходилось переключаться между русской и английской раскладками при вводе знаков препинания.
### Проблема
При написании кода на русском языке программисты сталкиваются с необходимостью часто переключать раскладку:
- Русская раскладка: буквы на русском, но знаки препинания (`.` , `,` , `;` , `:` , `[` , `]` , `{` , `}` , `(` , `)` , `!` , `?` , `@` , `#` , `$` , `%` , `^` , `&` , `*` , `-` , `_` , `+` , `=` , `~` , `|` , `\` , `/` , `<` , `>` ) находятся в других местах или недоступны.
- Английская раскладка: знаки препинания на привычных местах, но буквы на английском.
Постоянное переключение раскладки замедляет написание кода и отвлекает от процесса.
### Решение
Создание **специальной настройки (раскладки или модификации)** для Linux, которая:
1. **Сохраняет расположение букв как в русской раскладке** (ЙЦУКЕН или ЙЦУКЕНГ).
2. **Размещает знаки препинания на тех же клавишах, что и в английской раскладке** (`.` на той же клавише, где в английском, `,` на той же и т.д.).
В результате программист может:
- Писать буквы на русском (без переключения).
- Вводить знаки препинания на тех же клавишах, к которым привык в английской раскладке.
### Как это будет реализовано
1. **Создание файла настройки XKB (xkb)** — стандартный способ настройки раскладок в Linux (Xorg и Wayland).
2. **Интеграция с системой** — установка через скрипт или пакет.
### Пример файла `ru_prog` (русская программистская раскладка)
```xkb
// ru_prog - русская раскладка со знаками препинания как в английской
xkb_symbols "prog" {
include "ru(ru)"
name[Group1] = "Russian (programming)";
// Переопределяем знаки препинания
key <TLDE> { [ apostrophe, asciitilde ] }; // ` ~
key <AE01> { [ 1, exclam ] }; // 1 !
key <AE02> { [ 2, at ] }; // 2 @
key <AE03> { [ 3, numbersign ] }; // 3 #
key <AE04> { [ 4, dollar ] }; // 4 $
key <AE05> { [ 5, percent ] }; // 5 %
key <AE06> { [ 6, asciicircum ] }; // 6 ^
key <AE07> { [ 7, ampersand ] }; // 7 &
key <AE08> { [ 8, asterisk ] }; // 8 *
key <AE09> { [ 9, parenleft ] }; // 9 (
key <AE10> { [ 0, parenright ] }; // 0 )
key <AE11> { [ minus, underscore ] }; // - _
key <AE12> { [ equal, plus ] }; // = +
key <AD01> { [ q, Q ] }; // q
key <AD02> { [ w, W ] }; // w
key <AD03> { [ e, E ] }; // e
key <AD04> { [ r, R ] }; // r
key <AD05> { [ t, T ] }; // t
key <AD06> { [ y, Y ] }; // y
key <AD07> { [ u, U ] }; // u
key <AD08> { [ i, I ] }; // i
key <AD09> { [ o, O ] }; // o
key <AD10> { [ p, P ] }; // p
key <AD11> { [ bracketleft, braceleft ] }; // [ {
key <AD12> { [ bracketright, braceright ] }; // ] }
key <AC01> { [ a, A ] }; // a
key <AC02> { [ s, S ] }; // s
key <AC03> { [ d, D ] }; // d
key <AC04> { [ f, F ] }; // f
key <AC05> { [ g, G ] }; // g
key <AC06> { [ h, H ] }; // h
key <AC07> { [ j, J ] }; // j
key <AC08> { [ k, K ] }; // k
key <AC09> { [ l, L ] }; // l
key <AC10> { [ semicolon, colon ] }; // ; :
key <AC11> { [ apostrophe, quotedbl ] }; // ' "
key <AB01> { [ z, Z ] }; // z
key <AB02> { [ x, X ] }; // x
key <AB03> { [ c, C ] }; // c
key <AB04> { [ v, V ] }; // v
key <AB05> { [ b, B ] }; // b
key <AB06> { [ n, N ] }; // n
key <AB07> { [ m, M ] }; // m
key <AB08> { [ comma, less ] }; // , <
key <AB09> { [ period, greater ] }; // . >
key <AB10> { [ slash, question ] }; // / ?
};
```
### Альтернативный подход: использование `setxkbmap`
Для быстрой настройки можно использовать команду:
```bash
setxkbmap -layout us,ru -variant ,prog -option grp:alt_shift_toggle
```
### Планируемые функции
1. **Установка через скрипт**: `./настроить_раскладку.sh` — автоматически добавляет раскладку в систему.
2. **Переключение по горячим клавишам**: например, `Alt+Shift` переключает между стандартной русской и программистской русской раскладкой.
3. **Интеграция с редакторами**: автоматическое переключение раскладки при открытии `.рс` файлов.
4. **Документация**: инструкции для различных дистрибутивов Linux (Ubuntu, Fedora, Arch, etc.)
### Статус
-**Создание файла XKB для русской программистской раскладки** — в планах.
-**Скрипт автоматической установки** — следующий этап.
-**Документация для различных дистрибутивов** — в планах.
## Сборка и тестирование
```bash
# Сборка компилятора
make
# Запуск стандартных тестов
make test
# Запуск русских тестов
make test-ru
# Запуск всех тестов (стандартные + русские)
make test-all
# Самосборка и тестирование stage2
make test-stage2
# Очистка собранных файлов
make clean
```
## Благодарности
Особая благодарность:
- **Rui Ueyama** за создание [chibicc](https://github.com/rui314/chibicc) — образцово-простого и образовательного компилятора.
- **Alexandre Gaigalas** за [c89cc.sh](https://gist.github.com/alganet/2b89c4368f8d23d033961d8a3deb5c19) — демонстрацию минимализма в реализации компилятора.
## Статус
-Все основные конструкции переведены и протестированы.
- ✅ Двуязычный синтаксис полностью работоспособен.
- ✅ Поддержка русского синтаксиса и смешанного стиля успешно проходит 70+ тестов.
- ✅ Русские имена файлов и расширений поддерживаются.
- ✅ Самосборка (self-hosting) успешно работает.
- ✅ Функция `main` переименована в `главн`.
- ⏳ Миграция исходного кода на русский синтаксис — в процессе.
- ⏳ Портирование КВС с Python на C — в планах.
- ⏳ Расширение для подсветки синтаксиса VS Code / VS Codium — в планах.
- ⏳ Русификация стандартной библиотеки — в планах.
- ⏳ Настройка русской раскладки для Linux — в планах.
```