ESPNFollow live: Valkyries battle Dream in Game 1 of WNBA FinalsESPN DeportesRays y Guardians mantienen alineaciones del viernes para el sábadoRTP DesportoIúri Leitão é outra vez campeão do mundoThe Jerusalem PostRomanian F-16 fighter jets shoot down two drones over Romanian territorial watersZDF heuteEntdecken Sie das ZDF-NachrichtenstudioNHK 社会秋田 奈良 クマに襲われけが人相次ぐ 警察などが注意呼びかけMyJoyOnlineA proper reset would’ve been to clear the EC and set new standards – Suhuyini on EC appointmentsInteriaPłoną warte miliony rezydencje, pożary w Kalifornii. Wezwanie do ewakuacjiGuardian SportDaniel Dubois v Fabio Wardley II: WBO heavyweight title fight – liveFrance 24Looters seize on massive French protests to raid and vandalise shopsSRF NewsDie Kunst, loszulassen – Julia Steiner: «Scheitern war keine Option»NOS SportVan Veen met recordgemiddelde op Europese tour langs Bialecki, Van Gerwen meteen klaar
The Daily Newsstand · Free, Always
Saturday, October 17, 2026

Русский язык в программировании. РУСИ++

Translate

Статья посвящена системному программированию на русском языке с C-подобным синтаксисом. Компилятор для языков программирования РУСИ, РУСИ++ и объектный-РУСИ создан путём модификации и пересборки компилятора GCC 14й версии с превращением его в полноценный русско-английский билингвальный компилятор. Отдельно дана инструкция модификации русской раскладки клавиатуры для добавления в неё фигурных, угловых и квадратных скобок - дабы не переключаться и не терять поток.

Оглавление

Предыстория

В предыдущей статье был описан концепт билингвального самособирающегося компилятора языка Си, в котором кириллица уравнялась с оригинальным синтаксисом и можно писать на русском и английском Си одновременно. Код, напомню, выглядит так:

// Английский main с русским типом и оператором
int main() {
    int x = 42;
    if (x == 42) {
        возврат 0;
    }
    return 1;
}

// Полностью русский синтаксис
цел главн() {
    цел ъ = 42;
    если (ъ == 42) {
        возврат  0;
    }
    возврат 1;
}

// Смешанный стиль
цел main() {
    printf("Легкоступов! Ты чего написал?");
    возврат 0;
}

Создан он был на базе chibicc для написания на нём кириллического ассемблера КВС https://xn–d1alm1bt.xn–p1ai/administrator/kvs. По сути, это был путь к своеобразной концептуальной полноте: кириллический ассемблер на кириллическом же Си. И для той задачи это было идеальным решением. Минималистичный русский компилятор под Linux. Ничего лишнего. Байты в бинарь складывать может. Задачу свою решает.

Но далее пошли предсказуемые комментарии со сравнениями с бухгалтерским программированием, предложением добавить падежи и пожеланиями не использовать это в продакшене. Обоснование последнего не осталось без внимания.

И действительно: во «взрослых» компиляторах есть ряд преимуществ как маркеров качества - множественное покрытие тестами и 40 лет ассемблерных оптимизаций. И как человек, пишущий свой ассемблер, я на это обратил внимание. Это тысячи человеко-лет работы, сотни оптимизационных проходов, отладка на миллионах строк кода.

Гипотетически: каким бы был полноценный продакшеновый русский Си?

Из спортивного интереса я решил попробовать. Смогу ли оседлать GCC и сделать его билингвом? Ранее мне поддались pascalABC.NET, Blaise и PHP. Вшивал я в них великий и могучий с целью поизучать на практике компиляторостроение. Отличный метод обучаться, кстати.

Получилось. Компилятор, в котором русские и английские ключевые слова - синонимы. Можно использовать любой язык или их гибрид. Реализовано так же, как в исходной статье. Даже тесты взял из русифицированного chibicc.

GCC сложнее, чем chibicc. Множество стандартов Си, поддерживаемых им, не могли не наложить свой отпечаток на его внутреннюю архитектуру.

Что получилось: RUSI на GCC 14.2.0. Русский Си, который компилируется в тот же самый машинный код, что и английский Си. С теми же оптимизациями. С той же производительностью.

Побочными продуктами получились РУСИ++ и объектный-РУСИ.

Зачем это всё

Эрик Рэймонд, «Собор и Базар» (1997), предисловие:

«Every good work of software starts by scratching a developer’s personal itch.»

Точный перевод: «Каждая хорошая программа начинается с того, что разработчик почесал свою личную нужду».

И где-то в России программист решил создать то, что считает нужным. И создаёт.

Линус Торвальдс, предисловие к книге Пекки Химанена «Хакерская этика и дух информационной эры» (2001):

«Linux был в значительной степени хобби (но серьёзным, лучшим из всех).»

Это не «продукт». Не «стартап». Не «проект для галочки». Хобби, но серьёзное. Работа, которая является игрой. Не потому, что «надо», а потому что интересно. Внутренний ребёнок радуется в процессе творчества.

Химанен в книге формулирует суть этики так:

«Хакер - это тот, кто решает проблему, а не тот, кто пользуется готовым решением. Если машина не делает то, что нужно, - хакер открывает её. Если система неудобна - хакер меняет её. Не потому, что заплатили, а потому что интересно. Не потому, что велели, а потому что сам захотел.»

И ведь можно открыть и переделать всё. Компилятор, раскладку, стандарт, технологию, чьё-то мнение.

RUSI - ровно это. Личное творчество. Захотел - переделал. Сделал. Сам захотел - и получилось.

Частично взгляды описаны в предыдущей статье Программисты на Руси программируют на Си. RUSI: Концепт билингвального компилятора.

В конце статьи есть список промптов для анализа текста статьи через призму различных подходов и взглядов.

Где взять и что внутри

Репозиторий: https://github.com/artradeskz/rgcc

Что внутри: GCC 14.2.0 с патчами для русского синтаксиса. Полный diff огромен - здесь не привожу. Но он есть в конце статьи под спойлером.

Краткая выжимка: что именно изменено и зачем.

1. UTF-8 в лексере (libcpp/lex.cc)

Традиционно работая с исходниками, GCC читает не по буквам, а по байтам. Так сложилось исторически. В интернете можно встретить утверждение, что GCC умеет работать с идентификаторами на UTF-8. Про то, что он может так же работать со служебными словами, там не будет сказано. Одна английская буква - один байт. Кириллица же в UTF-8 - это 2 байта на букву. И прежние алгоритмы чтения уже не сработают. Для русификации добавлена обработка UTF-8-последовательностей в forms_identifier_p, чтобы лексер парсил посимвольно, а не побайтово.

if (*buffer->cur == 0xD0 || *buffer->cur == 0xD1)
  {
    unsigned char first = *buffer->cur;
    unsigned char second = *(buffer->cur + 1);

    if (first == 0xD0 && second >= 0x90 && second <= 0xBF)
      {
        buffer->cur += 2;
        return true;
      }
    if (first == 0xD1 && second >= 0x80 && second <= 0x8F)
      {
        buffer->cur += 2;
        return true;
      }
  }

2. Синонимы ключевых слов (gcc/c-family/c-common.cc)

Добавлено ~250 русских синонимов в таблицу c_common_reswords[]:

{ "int",     RID_INT,     0 },
{ "цел",     RID_INT_RU,  0 },
{ "if",      RID_IF,      0 },
{ "если",    RID_IF,      0 },
{ "return",  RID_RETURN,  0 },
{ "возврат", RID_RETURN,  0 },
{ "char",    RID_CHAR,    0 },
{ "символ",  RID_CHAR,    0 },

3. Русские встроенные макросы (libcpp/init.cc)

B("__ФАЙЛ__",        BT_FILE,         false),
B("__ЛИНИЯ__",       BT_SPECLINE,     true),
B("__ДАТА__",        BT_DATE,         false),
B("__СЧЁТЧИК__",     BT_COUNTER,      true),
B("__ВРЕМЯ_ФАЙЛА__", BT_TIMESTAMP,    false),

4. Русские директивы препроцессора (libcpp/directives.cc и libcpp/expr.cc)

Директивы препроцессора - это команды, которые начинаются с #. Они не являются частью языка C в том смысле, что парсер их не видит. Их обрабатывает libcpp до того, как парсер получит лексемы. Именно поэтому удалось добавить русские директивы без изменения парсера: достаточно было добавить синонимы в таблицу директив.

В libcpp/directives.cc есть таблица dtable[] - список всех директив. Туда добавлены русские аналоги:

{ do_define,   UC"определить",  sizeof "определить" - 1,   KANDR, IN_I },
{ do_include,  UC"включить",    sizeof "включить" - 1,     KANDR, INCL | EXPAND },
{ do_if,       UC"если",        sizeof "если" - 1,         KANDR, COND | IF_COND | EXPAND },
{ do_endif,    UC"конецесли",   sizeof "конецесли" - 1,    KANDR, COND },

Теперь #включить <stdio.h> работает так же, как #include <stdio.h>. #определить - как #define. #если - как #if. И так далее.

Теперь можно писать:

#если определено(ОТЛАДКА)
    printf("Отладка включена\n");
#конецесли

Это полный русский аналог английского:

#if defined(DEBUG)
    printf("Отладка включена\n");
#endif

Немного хулиганства

Чтоб не перепутать стандартный и патченный компиляторы, было бы неплохо иметь возможность различать русифицированный GCC и обычный. Для этого можно доработать вывод команды с информацией о версии компилятора.

Где пропатчить команду gcc --version:

Файл: gcc/gcc.cc, 8900-я строка.

Там зашиты строка копирайта и текст про гарантию. Их можно заменить на свой текст.

  if (print_version)
    {
      printf (_("%s %s%s\n"), progname, pkgversion_string,
	      version_string);
      printf ("Copyright %s 2026 Coded by @artrades.\n",
	      _("(C)"));
      fputs (_("Использовать можно и нужно. Но никто ни за что ответственность не несет(очевидно). This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
	     stdout);
      if (! verbose_flag)
	return 0;

После сборки:

$ gcc --version
gcc (GCC) 14.2.0
Copyright (C) 2026 Coded by @artrades.
Использовать можно и нужно. Но никто ни за что ответственность не несет(очевидно).
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

В репозитории в данный участок кода - оригинальный. Текст можно менять на свое усмотрение.

Теория: почему русский синтаксис работает

Компилятор - это цепочка преобразований

Компилятор - это сложный многоэтапный механизм превращения слов в исполняемый файл. Это конвейер преобразователей, где каждый этап - это обособленная знаково-логическая система, словно свой отдельный язык программирования.

Упрощённая схема для любого компилятора высокого уровня:

Исходник → лексемы → AST → ассемблер → лексемы → AST → исполняемый файл

Между каждым этапом работает преобразователь со своей логикой.

Что такое «знаково-логическая система»

На каждом этапе есть:

  • Алфавит - набор допустимых символов

  • Правила - как из символов строить конструкции

  • Семантика - что эти конструкции означают

Примеры:

Этап

Алфавит

Что описывает

Исходник

ASCII + UTF-8

текст программы

Лексемы

TK_INT, TK_IF, TK_RETURN

ключевые слова, операторы, идентификаторы

AST

VarDecl, IfStmt, ReturnStmt

структура программы

Ассемблер

mov, add, call

инструкции процессора

Лексемы

MOV, ADD, CALL, REG_EAX, IMM, MEM

мнемоники, регистры, непосредственные значения, адреса памяти

AST

Instruction(mov, src=REG, dst=REG), Label, Directive(.text)

инструкции, метки, директивы

Бинарь

байты

готовая программа

Что изменено

Только первые два преобразования:

  1. Исходник → лексемы (лексер libcpp)

  2. Лексемы → AST (парсер c-parser.cc)

На этапе первого AST компилятору уже безразлично, как выглядели слова на человеческом языке.

Вот два исходника:

int x = 42;
цел x = 42;

После преобразований оба превращаются в один и тот же узел AST:

VarDecl(name="x", type=Int, init=42)

Дальше компилятор работает только с абстрактным синтаксическим деревом: оптимизирует его, преобразует в ассемблер, в объектный код. Информация о том, что ты написал int или цел, была актуальна лишь на этапе парсера.

Почему производительность идентична

Именно потому, что после AST всё одинаково:

int x = 42;    ─┐
                ├─ AST - ассемблер - объектный код - линкер - бинарь
цел x = 42;    ─┘

Русский и английский исходники дают идентичный AST, значит, идентичный ассемблер, идентичный объектный код, идентичный бинарь.

Это подтверждено экспериментально: секция .text (исполняемый код) русского и английского исходников побайтово идентична.

Ключевой вывод

RUSI - это не «новый язык». Это билингвальный фасад к существующему языку C.

GCC научили понимать русские слова на входе, на этапе лексера и парсера. Всё остальное - стандартный GCC 14.2.

Русский синтаксис не добавляет ни одной инструкции в машинный код. Потому что после парсера разницы между русским и английским C не существует, есть только AST.

Сборка: от исходников до установки

Проверено на Ubuntu 26 с установленным в систему GCC 12 или с GCC 15.

Качаем:

git clone --depth 1 https://github.com/artradeskz/rgcc.git

Зависимости:

sudo apt install flex bison libgmp-dev libmpfr-dev libmpc-dev

Или, если не хочется ставить dev-пакеты, используется встроенный скрипт:

cd rgcc
./contrib/download_prerequisites

Он скачает GMP, MPFR, MPC, ISL в дерево исходников:

2026-10-03 18:13:45 URL:https://gcc.gnu.org/pub/gcc/infrastructure/gettext-0.22.tar.gz [26105696/26105696] -> "gettext-0.22.tar.gz" [1]
2026-10-03 18:13:47 URL:http://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.2.1.tar.bz2 [2493916/2493916] -> "gmp-6.2.1.tar.bz2" [1]
2026-10-03 18:13:49 URL:http://gcc.gnu.org/pub/gcc/infrastructure/mpfr-4.1.0.tar.bz2 [1747243/1747243] -> "mpfr-4.1.0.tar.bz2" [1]
2026-10-03 18:13:50 URL:http://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.2.1.tar.gz [838731/838731] -> "mpc-1.2.1.tar.gz" [1]
2026-10-03 18:13:52 URL:http://gcc.gnu.org/pub/gcc/infrastructure/isl-0.24.tar.bz2 [2261594/2261594] -> "isl-0.24.tar.bz2" [1]
gettext-0.22.tar.gz: OK
gmp-6.2.1.tar.bz2: OK
mpfr-4.1.0.tar.bz2: OK
mpc-1.2.1.tar.gz: OK
isl-0.24.tar.bz2: OK
All prerequisites downloaded successfully.

Конфигурация:

mkdir build && cd build

../configure \
    --enable-languages=c,c++ \
    --disable-multilib \
    --disable-nls \
    --disable-libgomp \  
    --disable-libquadmath \
    --disable-libssp \
    --disable-libvtv \
    --disable-libcc1 \
    --disable-libmpx \
    --disable-libcilkrts \
    --disable-libsanitizer \
    --disable-isl \
    --disable-bootstrap \
    --disable-graphite \
    --prefix=/usr/local/gcc-rus

Пояснения:

  • --enable-languages=c,c++ - собираем только C и C++

  • --disable-isl - отключает ISL и Graphite

  • --disable-bootstrap - отключен автоматический самосбор(об этом ниже)

  • --prefix=/usr/local/gcc-rus - изолированная установка

Сборка (2 потока, можно и быстрее):

make -j2 2>&1 | tee build.log

На Aspire 5742G - около часа. На современной машине - 15–20 минут.

Установка:

sudo make install

Проверка:

/usr/local/gcc-rus/bin/gcc --version

Добавление в PATH:

echo 'export PATH=/usr/local/gcc-rus/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

Тесты из chibicc-rusi

Методика

Взяты тесты из chibicc-RUSI без изменений. Прогнаны на RUSI-GCC.

cd тесты

python3 run_tests.py \
    --compiler ~/Документы/RUSI++/rgcc/build-full/gcc/xgcc \
    --build-dir ~/Документы/RUSI++/rgcc/build-full/gcc \
    --dir test_ru \
    --verbose

Результат: 63 из 65 (96.9%).

Полный вывод тестов

📌 Результат прогона тестов
============================================================
               ЗАПУСК РУССКИХ ТЕСТОВ ДЛЯ RUSI               
============================================================

Найдено тестов: 65
Компилятор: /home/me/Документы/RUSI++/rgcc/build-full/gcc/xgcc
Папка сборки (-B): /home/me/Документы/RUSI++/rgcc/build-full/gcc
Папка тестов: test_ru

[1/65] #else                     ✓ ОК (код 0)
[2/65] alignas                   ✓ ОК (код 0)
[3/65] alignof                   ✓ ОК (код 0)
[4/65] asm                       ✓ ОК (код 0)
[5/65] asm2                      ✓ ОК (код 0)
[6/65] atomic                    ✓ ОК (код 0)
[7/65] auto                      ✓ ОК (код 0)
[8/65] bool                      ✓ ОК (код 0)
[9/65] break                     ✓ ОК (код 0)
[10/65] case                     ✓ ОК (код 0)
[11/65] char                     ✓ ОК (код 65)
[12/65] const                    ✓ ОК (код 0)
[13/65] continue                 ✓ ОК (код 0)
[14/65] counter_ru               ✓ ОК (код 0)
[15/65] cyrillic_ident           ✓ ОК (код 0)
[16/65] cyrillic_ptr             ✓ ОК (код 0)
[17/65] date_ru                  ✓ ОК (код 0)
[18/65] default                  ✓ ОК (код 0)
[19/65] define                   ✓ ОК (код 0)
[20/65] defined                  ✓ ОК (код 0)
[21/65] do                       ✓ ОК (код 0)
[22/65] double                   ✓ ОК (код 2)
[23/65] elif                     ✓ ОК (код 0)
[24/65] else                     ✓ ОК (код 0)
[25/65] endif                    ✓ ОК (код 0)
[26/65] enum                     ✓ ОК (код 0)
[27/65] extern                   ✓ ОК (код 0)
[28/65] file_ru                  ✓ ОК (код 0)
[29/65] float                    ✓ ОК (код 3)
[30/65] for                      ✓ ОК (код 0)
[31/65] func_ru                  ✓ ОК (код 0)
[32/65] function_ru              ✓ ОК (код 0)
[33/65] generic                  ✓ ОК (код 0)
[34/65] goto                     ✓ ОК (код 0)
[35/65] if                       ✓ ОК (код 0)
[36/65] ifdef                    ✓ ОК (код 0)
[37/65] ifndef                   ✓ ОК (код 0)
[38/65] include                  ✓ ОК (код 0)
[39/65] inline                   ОШИБКА КОМПИЛЯЦИИ
    /usr/bin/x86_64-linux-gnu-ld.bfd: /tmp/ccvZ6sZh.o: в функции «main»:
    /home/me/Документы/RUSI++/rgcc/тесты/test_ru/inline.c:7:(.text+0xe): undefined reference to `квадрат'
    collect2: error: ld returned 1 exit status
[40/65] int                       ✓ ОК (код 0)
[41/65] line                      ✓ ОК (код 0)
[42/65] line_ru                   ✓ ОК (код 0)
[43/65] long                      ✓ ОК (код 0)
[44/65] main                      ✓ ОК (код 0)
[45/65] noreturn                  ✗ ОШИБКА ожидался 0, получен -11
[46/65] once                      ✓ ОК (код 0)
[47/65] register                  ✓ ОК (код 0)
[48/65] restrict                  ✓ ОК (код 0)
[49/65] return                    ✓ ОК (код 0)
[50/65] short                     ✓ ОК (код 123)
[51/65] signed                    ✓ ОК (код 0)
[52/65] sizeof                    ✓ ОК (код 0)
[53/65] static                    ✓ ОК (код 0)
[54/65] struct                    ✓ ОК (код 0)
[55/65] switch                    ✓ ОК (код 0)
[56/65] test_import               ✓ ОК (код 0)
[57/65] thread_local              ✓ ОК (код 0)
[58/65] time_ru                   ✓ ОК (код 0)
[59/65] typedef                   ✓ ОК (код 0)
[60/65] typeof                    ✓ ОК (код 0)
[61/65] undef                     ✓ ОК (код 0)
[62/65] union                     ✓ ОК (код 0)
[63/65] unsigned                  ✓ ОК (код 0)
[64/65] volatile                  ✓ ОК (код 0)
[65/65] while                     ✓ ОК (код 0)

============================================================
                  РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ                   
============================================================

Итого:
  Пройдено: 63
  Провалено: 2
  Ошибок компиляции: 1
  Всего: 65
  Успешность: 96.9%

Два «провала» и почему это не баг GCC

inline.c:

// inline.c - Проверка ключевого слова inline
инлайн цел квадрат(цел х) {
    возврат х * х;
}

цел главн(){
    цел рез = квадрат(5);
    если (рез == 25) {
        возврат 0;
    }
    возврат 1;
}

Ошибка линковки: undefined reference to 'квадрат'.

Причина: в C99 inline без static/extern - это внутренняя функция, которая может не создаваться как внешняя. chibicc игнорирует inline и создаёт функцию. GCC следует стандарту и не создаёт. GCC прав.

noreturn.c:

// noreturn.c - Проверка _Безвозврат
_Безвозврат пусто завершение() {
    // Функция помечена как _Безвозврат, но на самом деле возвращается
    возврат;
}

цел главн(){
    завершение();
    возврат 0;
}

Падение с SIGSEGV (-11).

Причина: _Noreturn - это обещание компилятору, что функция не вернётся. Если она возвращается, это неопределённое поведение (согласно C11 §6.7.4). chibicc игнорирует _Noreturn. GCC применяет его для оптимизации (выбрасывает недостижимый код). Программа падает. GCC прав.

Вывод

Два «провала» - это не баги GCC, а разница семантики между chibicc и GCC. chibicc не проверяет типы и игнорирует атрибуты. GCC следует стандарту C. RUSI-GCC работает корректнее, чем chibicc-RUSI.

Самосбор

Лучшим способом проверить, что оригинальный Си и Си++ не отвалились, будет сбор GCC самим же собой. После установки в систему это делается аналогичной командой с аналогичной же конфигурацией(см.выше). Затем можно прогнать тесты. Для уверенности можно собрать еще раз.

В отличие от компилятора chibbic, GCC я не стал переписывать на русифицированном Си. Это огромный объем кодовой базы. Однако испытать РУСИ путем вкрапления в исходный код компилятора сам факт выполняемой задачи обязывает. Нужный компилятор в системе есть - можно приступать. Для испытания я выбрал файл gcc/c-family/c-common.cc (таблица ключевых слов).

Две директивы в начале.

#определить GCC_C_COMMON_C  

#включить "config.h"
#include "system.h"

И функцию c_addr_space_name().

/* Return identifier for address space AS.  */

конст char *
c_addr_space_name (addr_space_t as)
{
  цел rid = RID_FIRST_ADDR_SPACE + as;
  gcc_assert (ridpointers [rid]);
  возврат IDENTIFIER_POINTER (ridpointers [rid]);
}

С такими изменениями собирать это стандартным компилятором уже не получится!

После сборки можно снова прогнать тесты. И для верности собрать и протестировать еще раз.

При желании можно русифицировать весь код компилятора таким образом, но с практической точки зрения лучше всего начинать переводить стандартные библиотеки: ввод-вывод, работа со строками, математический модуль.

В статье приведена команда для сборки с отключенным бутстрапом. Каждый этап запускается вручную приведенный выше командой. Это сделано чтоб не сломать сборку внутренними тестами, не рассчитанными на задвоенные ключевые слова(-fself-test не даст запустить Stage 2 и Stage 3).

Сравнительные сборки

«Привет, мир»

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

#включить <stdio.h>

цел главн(пусто) {
    printf("Привет, мир!\n");
    возврат 0;
}

Обратите внимание: здесь смешанный синтаксис. Директива #включить - русская. Тип цел - русский. Ключевое слово возврат - русское. А printf и stdio.h - латиница, потому что это имена из стандартной библиотеки, их мы не переводим.

Сохраним файл в двух вариантах: привет.си для chibicc (он понимает расширение .си) и привет.c для GCC (он понимает .c). Содержимое одинаковое.

Собираем через chibicc-RUSI:

./rusi.elf -o привет_chibicc привет.си

Собираем через GCC-RUSI (с оптимизацией -O2):

/usr/local/gcc-rus-full/bin/gcc -O2 привет.c -o привет_gcc

Сравнение размеров:

$ stat -c '%n %s байт' привет_chibicc привет_gcc
привет_chibicc 17640 байт
привет_gcc 15688 байт
$ size привет_chibicc привет_gcc
   text    data     bss     dec     hex filename
   1623     933       3    2559     9ff привет_chibicc
    949     544       8    1501     5dd привет_gcc

Сведём в таблицу:

Метрика

chibicc

GCC -O2

Разница

Размер файла

17 640 байт

15 688 байт

−11%

.text (код)

1 623 байт

949 байт

−42%

.data

933 байта

544 байта

−42%

.bss

3 байта

8 байт

+5 байт

Итог (dec)

2 559

1 501

−41%

Файл от GCC на 11% меньше. Но самое интересное - секция .text: код от GCC почти в 2 раза компактнее. .bss чуть больше у GCC, но это 8 байт против 3 - несущественно.

Проверим, что оба работают:

$ ./привет_chibicc
Привет, мир!
$ ./привет_gcc
Привет, мир!

Ответ одинаковый. Теперь посмотрим, почему код от GCC компактнее.

Дизассемблер chibicc-RUSI

0000000000401106 <главн>:
  401106:	55                   	push   %rbp
  401107:	48 89 e5             	mov    %rsp,%rbp
  40110a:	48 83 ec 10          	sub    $0x10,%rsp
  40110e:	48 89 65 f8          	mov    %rsp,-0x8(%rbp)
  401112:	48 8d 05 f7 2e 00 00 	lea    0x2ef7(%rip),%rax
  401119:	50                   	push   %rax
  40111a:	48 8b 05 b7 2e 00 00 	mov    0x2eb7(%rip),%rax
  401121:	5f                   	pop    %rdi
  401122:	49 89 c2             	mov    %rax,%r10
  401125:	48 c7 c0 00 00 00 00 	mov    $0x0,%rax
  40112c:	41 ff d2             	call   *%r10
  40112f:	48 83 c4 00          	add    $0x0,%rsp
  401133:	48 c7 c0 00 00 00 00 	mov    $0x0,%rax
  40113a:	eb 07                	jmp    401143 <главн+0x3d>
  40113c:	48 c7 c0 00 00 00 00 	mov    $0x0,%rax
  401143:	48 89 ec             	mov    %rbp,%rsp
  401146:	5d                   	pop    %rbp
  401147:	c3                   	ret

Дизассемблер GCC-RUSI

0000000000401040 <main>:
  401040:	48 83 ec 08          	sub    $0x8,%rsp
  401044:	bf 04 20 40 00       	mov    $0x402004,%edi
  401049:	e8 e2 ff ff ff       	call   401030 <puts@plt>
  40104e:	31 c0                	xor    %eax,%eax
  401050:	48 83 c4 08          	add    $0x8,%rsp
  401054:	c3                   	ret

Что видно

Разница драматическая. Пройдёмся по пунктам.

1. Передача аргумента.

chibicc:

lea    0x2ef7(%rip),%rax
push   %rax
...
pop    %rdi

Адрес строки сначала кладётся в rax, потом пушится в стек, потом вытаскивается в rdi. Три инструкции вместо одной.

GCC:

mov    $0x402004,%edi

Адрес строки сразу попадает в edi (младшие 32 бита rdi). Одна инструкция.

2. Вызов функции.

chibicc:

mov    0x2eb7(%rip),%rax
mov    %rax,%r10
mov    $0x0,%rax
call   *%r10

Адрес printf загружается из GOT в регистр, потом перекладывается в r10, потом вызов через указатель. Ещё и rax обнуляется (для variadic-функций).

GCC:

call   401030 <puts@plt>

Прямой вызов puts через PLT. Одна инструкция.

3. printf против puts.

GCC заменил printf("Привет, мир!\n") на puts("Привет, мир!"). Это классическая оптимизация: если строка заканчивается на \n и нет форматирования, puts работает быстрее. chibicc не делает этого - вызывает printf напрямую.

4. Возврат значения.

chibicc:

mov    $0x0,%rax
jmp    401143
...
mov    $0x0,%rax

Два mov $0x0,%rax и лишний jmp.

GCC:

xor    %eax,%eax

Одна инструкция. xor регистра с самим собой - идиоматический способ обнуления, работает быстрее, чем mov.

5. Frame pointer.

chibicc:

push   %rbp
mov    %rsp,%rbp
...
pop    %rbp

Сохраняет frame pointer, потому что chibicc не оптимизирует. GCC в -O2 выбрасывает его: sub $0x8,%rsp вместо push %rbp; mov %rsp,%rbp. Меньше инструкций, меньше стекового фрейма.

6. Лишние инструкции.

chibicc:

sub    $0x10,%rsp
mov    %rsp,-0x8(%rbp)
...
add    $0x0,%rsp

Выделяет 16 байт стека, сохраняет указатель стека в память (зачем?), потом прибавляет 0 к rsp. Безсмысленные операции.

GCC:

sub    $0x8,%rsp
...
add    $0x8,%rsp

Выделяет ровно столько, сколько нужно для выравнивания стека. Никаких лишних операций.

Итог

Что

chibicc

GCC

Передача аргумента

через стек (push/pop)

прямо в регистр (mov … %edi)

Вызов функции

через указатель (call *%r10)

напрямую (call puts@plt)

printf vs puts

printf

puts (оптимизация)

return 0

mov $0x0,%rax + jmp

xor %eax,%eax

Frame pointer

есть (push %rbp)

нет

Лишние инструкции

add $0x0,%rsp, mov %rsp,-0x8(%rbp)

нет

Размер кода

~66 байт

~21 байт

Именно поэтому секция .text от GCC в 1.7 раза меньше. chibicc генерирует наивный код: каждая операция через стек, вызов через указатель, лишние jmp и mov. GCC оптимизирует: аргументы в регистрах, прямой вызов, puts вместо printf.

И самое главное: это тот же самый исходник. Один и тот же русский C. Разница только в компиляторе. В конце статьи под спойлером полные дизассемблерные тексты.

Простые числа до 100 000

Исходник (prost.c):

#включить <stdio.h>

цел простые(цел н) {
    цел счёт = 0;
    для (цел и = 2; и <= н; и++) {
        цел флаг = 1;
        для (цел й = 2; й * й <= и; й++) {
            если (и % й == 0) { флаг = 0; прерви; }
        }
        если (флаг) счёт++;
    }
    возврат счёт;
}

цел главн(пусто) {
    printf("Простых до 100000: %d\n", простые(100000));
    возврат 0;
}

Тот же алгоритм на английском C для проверки, что ответ идентичен:

#include <stdio.h>

int simple(int n) {
    int count = 0;
    for (int i = 2; i <= n; i++) {
        int flag = 1;
        for (int j = 2; j * j <= i; j++) {
            if (i % j == 0) { flag = 0; break; }
        }
        if (flag) count++;
    }
    return count;
}

int main(void) {
    printf("Простых до 100000: %d\n", simple(100000));
    return 0;
}

Собираем тремя способами:

./rusi.elf -o prost_chibicc prost.c
/usr/local/gcc-rus-full/bin/gcc -O0 prost.c -o prost_gcc_O0
/usr/local/gcc-rus-full/bin/gcc -O2 prost.c -o prost_gcc_O2

Запускаем и проверяем, что ответ одинаковый:

$ ./prost_chibicc
Простых до 100000: 9592
$ ./prost_gcc_O0
Простых до 100000: 9592
$ ./prost_gcc_O2
Простых до 100000: 9592

Все три дают одинаковый ответ.

Сравнение размеров:

$ stat -c '%n %s байт' prost_chibicc prost_gcc_O0 prost_gcc_O2
prost_chibicc 17872 байт
prost_gcc_O0 15728 байт
prost_gcc_O2 15728 байт
$ size prost_chibicc prost_gcc_O0 prost_gcc_O2
   text    data     bss     dec     hex filename
   2139     997       3    3139     c43 prost_chibicc
   1125     544       8    1677     68d prost_gcc_O0
   1106     544       8    1658     67a prost_gcc_O2

Замер скорости:

$ time ./prost_chibicc
=== chibicc ===
Простых до 100000: 9592

real    0m0,039s
user    0m0,038s
sys     0m0,002s

$ time ./prost_gcc_O0
=== gcc -O0 ===
Простых до 100000: 9592

real    0m0,016s
user    0m0,012s
sys     0m0,002s

$ time ./prost_gcc_O2
=== gcc -O2 ===
Простых до 100000: 9592

real    0m0,015s
user    0m0,011s
sys     0m0,004s

Итоговая таблица:

Метрика

chibicc

gcc -O0

gcc -O2

Разница (chibicc → gcc -O2)

Размер файла

17 872 байт

15 728 байт

15 728 байт

−12%

.text (код)

2 139 байт

1 125 байт

1 106 байт

−48% (почти в 2 раза!)

.data

997 байт

544 байта

544 байта

−45%

Итог (dec)

3 139

1 677

1 658

−47%

Время (real)

0,039 с

0,016 с

0,015 с

−62% (в 2,6 раза!)

Время (user)

0,038 с

0,012 с

0,011 с

−71% (в 3,5 раза!)

Ответ

9592

9592

9592

одинаковый

Почему так

GCC:

  • Держит переменные в регистрах, а не в стеке

  • Оптимизирует условие й * й <= и

  • Разматывает циклы

  • Инлайнит мелкие функции

  • Заменяет printf на puts, где возможно

chibicc:

  • Каждая операция через стек

  • Нет оптимизаций

  • Наивный код

Ассемблерные оптимизации работают.

РУСИ++: побочный продукт

Если перебирать компилятор, который парсит не только Си, а еще и Си++, то есть смысл сделать билингвальный построитель AST полностью. Были добавлены синонимы для всех слов.

Что это

RUSI++ - это C++ с русским синтаксисом. Работают:

  • Классы (класс)

  • Конструкторы

  • private / public (без перевода, оставлено как есть)

  • Шаблоны (шаблон<имя_типа T>)

  • Наследование

  • Виртуальные функции

Пример

#включить <iostream>
#включить <string>

класс Приветствие {
закрыт:
    std::string имя;

открыт:
    Приветствие(конст std::string& н) : имя(н) {}

    пусто поздороваться() конст {
        std::cout << "Привет, " << имя << "!" << std::endl;
    }
};

цел главн() {
    Приветствие п("мир");
    п.поздороваться();
    возврат 0;
}

Сравнение с английским C++

#include <iostream>
#include <string>

class Greeting {
private:
    std::string name;

public:
    Greeting(const std::string& n) : name(n) {}

    void greet() const {
        std::cout << "Привет, " << name << "!" << std::endl;
    }
};

int main() {
    Greeting g("мир");
    g.greet();
    return 0;
}

Собран тот же код на английском C++ через тот же RUSI++:

/usr/local/gcc-rus-full/bin/g++ -O2 привет_класс.cpp -o привет_класс
/usr/local/gcc-rus-full/bin/g++ -O2 privet_class_en.cpp -o privet_class_en

Проверка запуска:

$ ./привет_класс
Привет, мир!
$ ./privet_class_en
Привет, мир!

Сравнение размеров:

$ stat -c '%n %s байт' привет_класс privet_class_en
привет_класс 16672 байт
privet_class_en 16664 байт
$ size привет_класс privet_class_en
   text    data     bss     dec     hex filename
   2690     656     280    3626     e2a привет_класс
   2690     656     280    3626     e2a privet_class_en

Сравнение кода:

$ objcopy -O binary --only-section=.text привет_класс /tmp/ru.bin
$ objcopy -O binary --only-section=.text privet_class_en /tmp/en.bin
$ cmp /tmp/ru.bin /tmp/en.bin && echo "✅ КОД ИДЕНТИЧЕН" || echo "❌ РАЗЛИЧАЕТСЯ"
✅ КОД ИДЕНТИЧЕН

Таблица:

Метрика

привет_класс (рус)

privet_class_en (англ)

Разница

Размер файла

16 672 байт

16 664 байта

8 байт (0,05%)

.text (код)

2 690 байт

2 690 байт

0

.data

656 байт

656 байт

0

.bss

280 байт

280 байт

0

Машинный код

идентичен

идентичен

0

Разница в 8 байт - это имена функций и классов в таблице символов (главн() vs main(), Приветствие vs Greeting). Сам код один и тот же.

Вывод

RUSI++ - это не переопределение слов через дефайны. Это полноценный C++ с русским синтаксисом. Классы, шаблоны, ООП - всё работает и компилируется в тот же машинный код, что и английский C++. Это побочный продукт работы над РУСИ: раз GCC поддерживает C++, а фронтенд русифицирован, C++ тоже стал русским.

Итог: форк chibicc породил три более совершенных языка

Что было: RUSI на chibicc - учебный компилятор для русского C.

Что стало:

Компилятор

База

Что умеет

РУСИ (GCC)

GCC 14.2

Русский C, оптимизации, все архитектуры

РУСИ++

GCC 14.2

Русский C++, классы, шаблоны, ООП

Объектный-РУСИ

GCC 14.2

Русский Objective-C (не тестировался)

Ключевое: все три - не «перевод ключевых слов», а полноценные фронтенды GCC с русским синтаксисом. После парсера AST идентичен английскому, дальше работает стандартный бэкенд GCC.

Перспективы применения

Куда можно применить технологию, с помощью которой создано почти всё? Преимуществом тут будет факт того, что Си все знают. Никого переучивать не нужно. Билингвальность же даёт обратную совместимость: всё, что написано ранее, можно без проблем применять. Да и переписывание такого компилятора на кириллическом Си - способ быстро прокачать инженерную школу.

Операционные системы

  • Linux - можно писать модули ядра

  • Windows - MinGW / Cygwin

  • macOS - через кросс-компиляцию

  • FreeBSD - нативная поддержка

  • Экзотические системы - всё, что поддерживает GCC

Встроенные системы

  • Прошивки для микроконтроллеров

  • Контроллеры (ARM Cortex-M, RISC-V)

  • Arduino (AVR)

  • Bare-metal

Процессоры

  • x86, x86-64

  • ARM, ARM64

  • RISC-V

  • MIPS

  • PowerPC

  • AVR

  • Всё, что поддерживает GCC

Отрасли

  • Приборостроение - уникальные приборы, измерительная техника

  • Робототехника - управление роботами

  • Системы связи - телекоммуникационное оборудование

  • Транспорт - встроенные системы автомобилей, поездов, самолётов

Образование

КуМир - школьный язык для обучения. RUSI может заменить его профессиональным инструментом с тем же русским синтаксисом, но с реальными возможностями GCC.

Экспорт в страны с кириллическим алфавитом

Болгария, Монголия, Сербия, Северная Македония, Казахстан, Кыргызстан - страны, где кириллица является официальной или широко используемой письменностью.

Создание отечественного стандарта ЯП Си

РУСИ может стать основой для отечественного стандарта языка системного программирования. Не «новый язык с нуля», а билингвальный стандарт:

  • Полная совместимость с международным стандартом C (ISO/IEC 9899)

  • Кириллический синтаксис как равноправный с латинским

  • Промышленная база GCC 14.2, а не учебный компилятор

Такой стандарт может быть принят для использования в … - везде, где требуется русскоязычная документация и код.

Появление нового стандарта раскладки.

Новая ru-раскладка с фигурными, квадратными и угловыми скобками однозначно продвинет применение русского языка в различных технологиях.

СПбГУ. RuC. Интерпретатор Терехова

До появления проекта RUSI в СПбГУ зародился свой Си с русскими словами - RuC. Виртуальная машина. Не сборщик в бинарь.

RuC - компилятор русского C в байт-код виртуальной машины. Автор - Андрей Терехов (СПбГУ). Проект остановился в 2023 году.

Почему остановился? Академический проект. Всё держалось на профессоре.

Названия похожи. Наверняка найдутся желающие столкнуть проекты по части именования. Оба могут сосуществовать со своими именами как Java и JavaScript.

Но есть идея даже концептуально развить RuC Терехова. И тут скорее win/win получится.

RuC написан на C++. RUSI++ - это C++ с русским синтаксисом. Значит:

  1. Берём исходники RuC

  2. Заменяем ключевые слова на русские (class → класс, int → цел, return → возврат)

  3. Собираем через РУСИ++

  4. Получаем тот же самый RuC, но с исходниками на русском

И возможно, в процессе появятся идеи развития проекта.

Заключение

Что сделано:

  • GCC 14.2.0 русифицирован

  • Тесты chibicc-RUSI проходят на 96.9% (два «провала» - баги chibicc, не RUSI)

  • RUSI-GCC быстрее и компактнее chibicc-RUSI в 2–3.5 раза

  • RUSI++ работает: классы, шаблоны, ООП

Что дальше:

  • Кросс-компиляция под ARM, RISC-V

  • Bare-metal поддержка (newlib, linker scripts)

  • Русификация стандартной библиотеки

  • Написание документации

Если кто размышлял о создании кириллического системного ЯП, то вот он - готовый, рабочий, всамделишный. Бонусом - инструкция по настройке раскладки, чтоб не переключать язык для скобок.

Ссылки

Бонус: фигурные скобки в русской раскладке

Проблема

Стандартная русская раскладка в Ubuntu 26 не имеет {, }, [, ], <, >. Клавиши, где они лежат в английской (Shift + [, Shift + ], Shift + ,, Shift + .), в русской заняты буквами х, ъ, б, ю.

Без фигурных скобок в C не написать ни функцию, ни блок, ни структуру. Без квадратных - не объявить массив или не обратиться к элементу. Без угловых - не подключить заголовок или не использовать шаблон. Переключать раскладку каждый раз - убивать поток.

Решение: задействуем правый Alt (AltGr). Он даёт третий уровень клавиатуры, специально созданный для ввода дополнительных символов. Он не конфликтует с Ctrl+X, Ctrl+C и другими системными сокращениями.

Что получится:

AltGr + х → {
AltGr + ъ → }
AltGr + щ → [
AltGr + з → ]
AltGr + б → <
AltGr + ю → >
Левый Alt, оба Ctrl, Shift → работают как обычно

Почему именно щ и з для квадратных скобок: это самый простой способ. Можно, конечно, заморочиться и на правый Ctrl сделать комбинацию с кнопками «х» и «ъ» - путь сложный. Зато теперь конструкция вида если (щ[ы] < щ[ю]) { } не представляет никаких сложностей.

Патчим раскладку

Шаг 1. Резервная копия

sudo cp /usr/share/X11/xkb/symbols/ru /usr/share/X11/xkb/symbols/ru.orig

Шаг 2. Открыть файл раскладки

sudo nano /usr/share/X11/xkb/symbols/ru

Шаг 3. Найти блок winkeys

В самом начале файла:

// Windows layout
default partial alphanumeric_keys
xkb_symbols "winkeys" {

    include "ru(common)"
    name[Group1]= "Russian";

    key <AE03>	{[          3,  numerosign  ]};
    key <AE04>	{[          4,   semicolon  ]};
    ...
    key <AB10>	{[     period,       comma  ]};
    key <BKSL>	{[  backslash,       slash  ]};
};

Шаг 4. Заменить блок winkeys целиком

// Windows layout
default partial alphanumeric_keys
xkb_symbols "winkeys" {

    include "ru(common)"
    name[Group1]= "Russian";

    key <AE03>  {[          3,  numerosign  ]};
    key <AE04>  {[          4,   semicolon  ]};
    key <AE05>  {[          5,     percent  ]};
    key <AE06>  {[          6,       colon  ]};
    key <AE07>  {[          7,    question  ]};
    key <AE08>  {[          8,    asterisk,      U20BD  ]}; // ruble

    key <AB10>  {[     period,       comma  ]};
    key <BKSL>  {[  backslash,       slash  ]};


    // --- добавлено для C-подобных языков ---
    key <AD11> {
        type[Group1] = "FOUR_LEVEL",
        symbols[Group1] = [ Cyrillic_ha, Cyrillic_HA, braceleft, braceleft ]
    };
    key <AD12> {
        type[Group1] = "FOUR_LEVEL",
        symbols[Group1] = [ Cyrillic_hardsign, Cyrillic_HARDSIGN, braceright, braceright ]
    };

    // --- квадратные скобки на AltGr: щ → [, з → ] ---
    key <AD09> {
        type = "FOUR_LEVEL",
        symbols[Group1] = [ Cyrillic_shcha, Cyrillic_SHCHA, bracketleft, bracketleft ]
    };
    key <AD10> {
        type = "FOUR_LEVEL",
        symbols[Group1] = [ Cyrillic_ze, Cyrillic_ZE, bracketright, bracketright ]
    };

    // --- угловые скобки на AltGr: б → <, ю → > ---
    key <AB08> {
        type = "FOUR_LEVEL",
        symbols[Group1] = [ Cyrillic_be, Cyrillic_BE, less, less ]
    };
    key <AB09> {
        type = "FOUR_LEVEL",
        symbols[Group1] = [ Cyrillic_yu, Cyrillic_YU, greater, greater ]
    };



    include "level3(ralt_switch)"

};

Пояснения:

  • <AD11> - физическая клавиша [, в русской раскладке х

  • <AD12> - физическая клавиша ], в русской раскладке ъ

  • <AD09> - физическая клавиша O, в русской раскладке щ

  • <AD10> - физическая клавиша P, в русской раскладке з

  • <AB08> - физическая клавиша ,, в русской раскладке б

  • <AB09> - физическая клавиша ., в русской раскладке ю

  • FOUR_LEVEL - четыре уровня: без модификатора, Shift, AltGr, Shift+AltGr

  • braceleft/braceright - { и }

  • bracketleft/bracketright - [ и ]

  • less/greater - < и >

  • level3(ralt_switch) - включает правый Alt как AltGr

Шаг 5. Перезагрузить систему

sudo reboot

Шаг 6. Проверить

Открыть любой текстовый редактор:

х → х,  Shift + х → Х,  AltGr + х → {
ъ → ъ,  Shift + ъ → Ъ,  AltGr + ъ → }
щ → щ,  Shift + щ → Щ,  AltGr + щ → [
з → з,  Shift + з → З,  AltGr + з → ]
б → б,  Shift + б → Б,  AltGr + б → <
ю → ю,  Shift + ю → Ю,  AltGr + ю → >

Если AltGr + х даёт { - всё готово.

Кастомная XKB-раскладка работает на уровне системы, без конфликтов. Левый Alt, оба Ctrl, Shift - как обычно.

Спойлеры

Ниже приведены спойлеры для тех, кто хочет вникнуть в детали.

📌 Git diff
[diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index aae998d0f73..6c12d22fc17 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -383,245 +383,465 @@ static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
    reserved word too, but only if it follows an '@' sign.
 */
 const struct c_common_resword c_common_reswords[] =
-{
+{ 
   { "_Alignas",		RID_ALIGNAS,   D_CONLY },
+  { "_Выравнивание",	RID_ALIGNAS,   D_CONLY },
   { "_Alignof",		RID_ALIGNOF,   D_CONLY },
+  { "_Выравнивание_типа",	RID_ALIGNOF,   D_CONLY },
   { "_Atomic",		RID_ATOMIC,    D_CONLY },
+  { "_Атом",		RID_ATOMIC,    D_CONLY },
   { "_BitInt",		RID_BITINT,    D_CONLY },
+  { "_бит_цел",		RID_BITINT,    D_CONLY },
   { "_Bool",		RID_BOOL,      D_CONLY },
+  { "_лог",		RID_BOOL,      D_CONLY },
   { "_Complex",		RID_COMPLEX,	0 },
+  { "_комплекс",	RID_COMPLEX,	0 },
   { "_Imaginary",	RID_IMAGINARY, D_CONLY },
+  { "_мнимое",		RID_IMAGINARY, D_CONLY },
   { "_Float16",         RID_FLOAT16,    0 },
+  { "_вещ16",         RID_FLOAT16,    0 },
   { "_Float32",         RID_FLOAT32,    0 },
+  { "_вещ32",         RID_FLOAT32,    0 },
   { "_Float64",         RID_FLOAT64,    0 },
+  { "_вещ64",         RID_FLOAT64,    0 },
   { "_Float128",        RID_FLOAT128,   0 },
+  { "_вещ128",        RID_FLOAT128,   0 },
   { "_Float32x",        RID_FLOAT32X,   0 },
+  { "_вещ32x",        RID_FLOAT32X,   0 },
   { "_Float64x",        RID_FLOAT64X,   0 },
+  { "_вещ64x",        RID_FLOAT64X,   0 },
   { "_Float128x",       RID_FLOAT128X,  0 },
+  { "_вещ128x",       RID_FLOAT128X,  0 },
   { "_Decimal32",       RID_DFLOAT32,  D_CONLY },
+  { "_десят32",       RID_DFLOAT32,  D_CONLY },
   { "_Decimal64",       RID_DFLOAT64,  D_CONLY },
+  { "_десят64",       RID_DFLOAT64,  D_CONLY },
   { "_Decimal128",      RID_DFLOAT128, D_CONLY },
+  { "_десят128",      RID_DFLOAT128, D_CONLY },
   { "_Fract",           RID_FRACT,     D_CONLY | D_EXT },
+  { "_дробь",           RID_FRACT,     D_CONLY | D_EXT },
   { "_Accum",           RID_ACCUM,     D_CONLY | D_EXT },
+  { "_аккум",           RID_ACCUM,     D_CONLY | D_EXT },
   { "_Sat",             RID_SAT,       D_CONLY | D_EXT },
+  { "_насыщ",           RID_SAT,       D_CONLY | D_EXT },
   { "_Static_assert",   RID_STATIC_ASSERT, D_CONLY },
+  { "_стат_проверка",   RID_STATIC_ASSERT, D_CONLY },
   { "_Noreturn",        RID_NORETURN,  D_CONLY },
+  { "_Безвозврат",        RID_NORETURN,  D_CONLY },
   { "_Generic",         RID_GENERIC,   D_CONLY },
+  { "_Обобщ",           RID_GENERIC,   D_CONLY },
   { "_Thread_local",    RID_THREAD,    D_CONLY },
+  { "_Поток_лок",     RID_THREAD,    D_CONLY },
   { "__FUNCTION__",	RID_FUNCTION_NAME, 0 },
+  { "__ФУНКЦИЯ__",	RID_FUNCTION_NAME, 0 },
   { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
+  { "__КРАСИВАЯ_ФУНКЦИЯ__", RID_PRETTY_FUNCTION_NAME, 0 },
   { "__alignof",	RID_ALIGNOF,	0 },
+  { "__выравн_от",	RID_ALIGNOF,	0 },
   { "__alignof__",	RID_ALIGNOF,	0 },
+  { "__выравн_от__",	RID_ALIGNOF,	0 },
   { "__asm",		RID_ASM,	0 },
+  { "__ассемблер",	RID_ASM,	0 },
   { "__asm__",		RID_ASM,	0 },
+  { "__ассемблер__",	RID_ASM,	0 },
   { "__attribute",	RID_ATTRIBUTE,	0 },
+  { "__атрибут",	RID_ATTRIBUTE,	0 },
   { "__attribute__",	RID_ATTRIBUTE,	0 },
+  { "__атрибут__",	RID_ATTRIBUTE,	0 },
   { "__auto_type",	RID_AUTO_TYPE,	D_CONLY },
+  { "__авто_тип",	RID_AUTO_TYPE,	D_CONLY },
   { "__builtin_addressof", RID_ADDRESSOF, D_CXXONLY },
+  { "__встр_адрес_от", RID_ADDRESSOF, D_CXXONLY },
   { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 },
+  { "__встр_барьер_ассоц", RID_BUILTIN_ASSOC_BARRIER, 0 },
   { "__builtin_bit_cast", RID_BUILTIN_BIT_CAST, D_CXXONLY },
+  { "__встр_бит_преобр", RID_BUILTIN_BIT_CAST, D_CXXONLY },
   { "__builtin_call_with_static_chain",
     RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY },
+  { "__встр_вызов_со_стат_цепью",
+    RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY },
   { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
+  { "__встр_выбор_выраж", RID_CHOOSE_EXPR, D_CONLY },
   { "__builtin_complex", RID_BUILTIN_COMPLEX, D_CONLY },
+  { "__встр_комплекс", RID_BUILTIN_COMPLEX, D_CONLY },
   { "__builtin_convertvector", RID_BUILTIN_CONVERTVECTOR, 0 },
+  { "__встр_преобр_вектор", RID_BUILTIN_CONVERTVECTOR, 0 },
   { "__builtin_has_attribute", RID_BUILTIN_HAS_ATTRIBUTE, 0 },
+  { "__встр_имеет_атрибут", RID_BUILTIN_HAS_ATTRIBUTE, 0 },
   { "__builtin_launder", RID_BUILTIN_LAUNDER, D_CXXONLY },
+  { "__встр_очистка", RID_BUILTIN_LAUNDER, D_CXXONLY },
   { "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 },
+  { "__встр_перемешать", RID_BUILTIN_SHUFFLE, 0 },
   { "__builtin_shufflevector", RID_BUILTIN_SHUFFLEVECTOR, 0 },
+  { "__встр_перемешать_вектор", RID_BUILTIN_SHUFFLEVECTOR, 0 },
   { "__builtin_stdc_bit_ceil", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_бит_потолок", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_bit_floor", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_бит_пол", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_bit_width", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_бит_ширина", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_count_ones", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_считать_единицы", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_count_zeros", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_считать_нули", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_first_leading_one", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_первый_ведущий_один", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_first_leading_zero", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_первый_ведущий_нуль", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_first_trailing_one", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_первый_хвостовой_один", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_first_trailing_zero", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_первый_хвостовой_нуль", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_has_single_bit", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_имеет_один_бит", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_leading_ones", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_ведущие_единицы", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_leading_zeros", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_ведущие_нули", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_trailing_ones", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_хвостовые_единицы", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_stdc_trailing_zeros", RID_BUILTIN_STDC, D_CONLY },
+  { "__встр_stdc_хвостовые_нули", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_tgmath", RID_BUILTIN_TGMATH, D_CONLY },
+  { "__встр_tgmath", RID_BUILTIN_TGMATH, D_CONLY },
   { "__builtin_offsetof", RID_OFFSETOF, 0 },
+  { "__встр_смещение", RID_OFFSETOF, 0 },
   { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
+  { "__встр_типы_совместимы", RID_TYPES_COMPATIBLE_P, D_CONLY },
   { "__builtin_va_arg",	RID_VA_ARG,	0 },
+  { "__встр_va_arg",	RID_VA_ARG,	0 },
   { "__complex",	RID_COMPLEX,	0 },
+  { "__комплекс",	RID_COMPLEX,	0 },
   { "__complex__",	RID_COMPLEX,	0 },
+  { "__комплекс__",	RID_COMPLEX,	0 },
   { "__const",		RID_CONST,	0 },
+  { "конст",		RID_CONST,	0 },
   { "__const__",	RID_CONST,	0 },
+  { "__неизм__",	RID_CONST,	0 },
   { "__constinit",	RID_CONSTINIT,	D_CXXONLY },
+  { "__конст_иниц",	RID_CONSTINIT,	D_CXXONLY },
   { "__decltype",       RID_DECLTYPE,   D_CXXONLY },
+  { "__тип_выраж",      RID_DECLTYPE,   D_CXXONLY },
   { "__extension__",	RID_EXTENSION,	0 },
+  { "__расширение__",	RID_EXTENSION,	0 },
   { "__func__",		RID_C99_FUNCTION_NAME, 0 },
+  { "__функ__",		RID_C99_FUNCTION_NAME, 0 },
   { "__imag",		RID_IMAGPART,	0 },
+  { "__мнимая",		RID_IMAGPART,	0 },
   { "__imag__",		RID_IMAGPART,	0 },
+  { "__мнимая__",	RID_IMAGPART,	0 },
   { "__inline",		RID_INLINE,	0 },
+  { "__встр",		RID_INLINE,	0 },
   { "__inline__",	RID_INLINE,	0 },
+  { "__встр__",		RID_INLINE,	0 },
   { "__label__",	RID_LABEL,	0 },
+  { "__метка__",	RID_LABEL,	0 },
   { "__null",		RID_NULL,	0 },
+  { "__нуль",		RID_NULL,	0 },
   { "__real",		RID_REALPART,	0 },
+  { "__действ",		RID_REALPART,	0 },
   { "__real__",		RID_REALPART,	0 },
+  { "__действ__",	RID_REALPART,	0 },
   { "__restrict",	RID_RESTRICT,	0 },
+  { "__огран",	        RID_RESTRICT,	0 },
   { "__restrict__",	RID_RESTRICT,	0 },
+  { "__огран__",	RID_RESTRICT,	0 },
   { "__signed",		RID_SIGNED,	0 },
+  { "__знак",		RID_SIGNED,	0 },
   { "__signed__",	RID_SIGNED,	0 },
+  { "__знак__",		RID_SIGNED,	0 },
   { "__thread",		RID_THREAD,	0 },
+  { "__поток",		RID_THREAD,	0 },
   { "__transaction_atomic", RID_TRANSACTION_ATOMIC, 0 },
+  { "__транзакция_атомарн", RID_TRANSACTION_ATOMIC, 0 },
   { "__transaction_relaxed", RID_TRANSACTION_RELAXED, 0 },
+  { "__транзакция_расслабл", RID_TRANSACTION_RELAXED, 0 },
   { "__transaction_cancel", RID_TRANSACTION_CANCEL, 0 },
+  { "__транзакция_отмена", RID_TRANSACTION_CANCEL, 0 },
   { "__typeof",		RID_TYPEOF,	0 },
+  { "__тип_от",		RID_TYPEOF,	0 },
   { "__typeof__",	RID_TYPEOF,	0 },
+  { "__тип_от__",	RID_TYPEOF,	0 },
   { "__typeof_unqual",	RID_TYPEOF_UNQUAL, D_CONLY },
+  { "__тип_от_без_квал",	RID_TYPEOF_UNQUAL, D_CONLY },
   { "__typeof_unqual__", RID_TYPEOF_UNQUAL, D_CONLY },
+  { "__тип_от_без_квал__", RID_TYPEOF_UNQUAL, D_CONLY },
   { "__volatile",	RID_VOLATILE,	0 },
+  { "__неуст",	        RID_VOLATILE,	0 },
   { "__volatile__",	RID_VOLATILE,	0 },
+  { "__неуст__",	RID_VOLATILE,	0 },
   { "__GIMPLE",		RID_GIMPLE,	D_CONLY },
-  { "__PHI",		RID_PHI,	D_CONLY },
+  { "__PHI",		RID_PHI,	D_CONLY },    // 
   { "__RTL",		RID_RTL,	D_CONLY },
   { "alignas",		RID_ALIGNAS,	D_C23 | D_CXX11 | D_CXXWARN },
+  { "выравн_как",	RID_ALIGNAS,	D_C23 | D_CXX11 | D_CXXWARN },
   { "alignof",		RID_ALIGNOF,	D_C23 | D_CXX11 | D_CXXWARN },
+  { "выравн_от",	RID_ALIGNOF,	D_C23 | D_CXX11 | D_CXXWARN },
   { "asm",		RID_ASM,	D_ASM },
+  { "асм",		RID_ASM,	D_ASM },
   { "auto",		RID_AUTO,	0 },
+  { "авто",		RID_AUTO,	0 },
   { "bool",		RID_BOOL,	D_C23 | D_CXXWARN },
+  //{ "бул",		RID_BOOL,	D_C23 | D_CXXWARN },
+  { "бул", RID_BOOL, 0 },
   { "break",		RID_BREAK,	0 },
+  { "прерви",		RID_BREAK,	0 },
   { "case",		RID_CASE,	0 },
+  { "случай",		RID_CASE,	0 },
   { "catch",		RID_CATCH,	D_CXX_OBJC | D_CXXWARN },
+  { "поймать",		RID_CATCH,	D_CXX_OBJC | D_CXXWARN },
   { "char",		RID_CHAR,	0 },
+  { "символ",		RID_CHAR,	0 },
   { "char8_t",		RID_CHAR8,	D_CXX_CHAR8_T_FLAGS | D_CXXWARN },
+  { "симв8_t",		RID_CHAR8,	D_CXX_CHAR8_T_FLAGS | D_CXXWARN },
   { "char16_t",		RID_CHAR16,	D_CXXONLY | D_CXX11 | D_CXXWARN },
+  { "симв16_t",		RID_CHAR16,	D_CXXONLY | D_CXX11 | D_CXXWARN },
   { "char32_t",		RID_CHAR32,	D_CXXONLY | D_CXX11 | D_CXXWARN },
+  { "симв32_t",		RID_CHAR32,	D_CXXONLY | D_CXX11 | D_CXXWARN },
   { "class",		RID_CLASS,	D_CXX_OBJC | D_CXXWARN },
+  { "класс",		RID_CLASS,	D_CXX_OBJC | D_CXXWARN },
+  { "__конст",		RID_CONST,	0 }, 
   { "consteval",	RID_CONSTEVAL,	D_CXXONLY | D_CXX20 | D_CXXWARN },
+  { "конст_вычисл",	RID_CONSTEVAL,	D_CXXONLY | D_CXX20 | D_CXXWARN },
   { "constexpr",	RID_CONSTEXPR,	D_C23 | D_CXX11 | D_CXXWARN },
+  { "конст_выраж",	RID_CONSTEXPR,	D_C23 | D_CXX11 | D_CXXWARN },
   { "constinit",	RID_CONSTINIT,	D_CXXONLY | D_CXX20 | D_CXXWARN },
+  { "конст_иниц",	RID_CONSTINIT,	D_CXXONLY | D_CXX20 | D_CXXWARN },
   { "const_cast",	RID_CONSTCAST,	D_CXXONLY | D_CXXWARN },
+  { "конст_преобр",	RID_CONSTCAST,	D_CXXONLY | D_CXXWARN },
   { "continue",		RID_CONTINUE,	0 },
+  { "продолжи",		RID_CONTINUE,	0 },
   { "decltype",         RID_DECLTYPE,   D_CXXONLY | D_CXX11 | D_CXXWARN },
+  { "тип_выраж",        RID_DECLTYPE,   D_CXXONLY | D_CXX11 | D_CXXWARN },
   { "default",		RID_DEFAULT,	0 },
+  { "умолч",		RID_DEFAULT,	0 },
   { "delete",		RID_DELETE,	D_CXXONLY | D_CXXWARN },
+  { "удалить",		RID_DELETE,	D_CXXONLY | D_CXXWARN },
   { "do",		RID_DO,		0 },
+  { "делай",		RID_DO,		0 },
   { "double",		RID_DOUBLE,	0 },
+  { "двойн",		RID_DOUBLE,	0 },
   { "dynamic_cast",	RID_DYNCAST,	D_CXXONLY | D_CXXWARN },
+  { "динам_преобр",	RID_DYNCAST,	D_CXXONLY | D_CXXWARN },
   { "else",		RID_ELSE,	0 },
+  { "иначе",		RID_ELSE,	0 },
   { "enum",		RID_ENUM,	0 },
+  { "переч",		RID_ENUM,	0 },
   { "explicit",		RID_EXPLICIT,	D_CXXONLY | D_CXXWARN },
+  { "явный",		RID_EXPLICIT,	D_CXXONLY | D_CXXWARN },
   { "export",		RID_EXPORT,	D_CXXONLY | D_CXXWARN },
+  { "экспорт",		RID_EXPORT,	D_CXXONLY | D_CXXWARN },
   { "extern",		RID_EXTERN,	0 },
+  { "внеш",		RID_EXTERN,	0 },
   { "false",		RID_FALSE,	D_C23 | D_CXXWARN },
+  { "ложь",		RID_FALSE,	0 },
   { "float",		RID_FLOAT,	0 },
+  { "плав",		RID_FLOAT,	0 },
   { "for",		RID_FOR,	0 },
+  { "для",		RID_FOR,	0 },
   { "friend",		RID_FRIEND,	D_CXXONLY | D_CXXWARN },
+  { "друг",		RID_FRIEND,	D_CXXONLY | D_CXXWARN },
   { "goto",		RID_GOTO,	0 },
+  { "перейти",		RID_GOTO,	0 },
   { "if",		RID_IF,		0 },
+  { "если",		RID_IF,		0 },
   { "inline",		RID_INLINE,	D_EXT89 },
+  { "инлайн",		RID_INLINE,	D_EXT89 },
   { "int",		RID_INT,	0 },
+  { "цел",		RID_INT_RU,	0 },                                             
   { "long",		RID_LONG,	0 },
+  { "длин",		RID_LONG,	0 },
   { "mutable",		RID_MUTABLE,	D_CXXONLY | D_CXXWARN },
+  { "измен",		RID_MUTABLE,	D_CXXONLY | D_CXXWARN },
   { "namespace",	RID_NAMESPACE,	D_CXXONLY | D_CXXWARN },
+  { "пространство",	RID_NAMESPACE,	D_CXXONLY | D_CXXWARN },
   { "new",		RID_NEW,	D_CXXONLY | D_CXXWARN },
+  { "новый",		RID_NEW,	D_CXXONLY | D_CXXWARN },
   { "noexcept",		RID_NOEXCEPT,	D_CXXONLY | D_CXX11 | D_CXXWARN },
+  { "без_искл",		RID_NOEXCEPT,	D_CXXONLY | D_CXX11 | D_CXXWARN },
   { "nullptr",		RID_NULLPTR,	D_C23 | D_CXX11 | D_CXXWARN },
+  { "пуст_указ",	RID_NULLPTR,	D_C23 | D_CXX11 | D_CXXWARN },
   { "operator",		RID_OPERATOR,	D_CXXONLY | D_CXXWARN },
+  { "оператор",		RID_OPERATOR,	D_CXXONLY | D_CXXWARN },
   { "private",		RID_PRIVATE,	D_CXX_OBJC | D_CXXWARN },
+  { "закрыт",		RID_PRIVATE,	D_CXX_OBJC | D_CXXWARN },
   { "protected",	RID_PROTECTED,	D_CXX_OBJC | D_CXXWARN },
+  { "защищ",	        RID_PROTECTED,	D_CXX_OBJC | D_CXXWARN },
   { "public",		RID_PUBLIC,	D_CXX_OBJC | D_CXXWARN },
+  { "открыт",		RID_PUBLIC,	D_CXX_OBJC | D_CXXWARN },
   { "register",		RID_REGISTER,	0 },
+  { "регистр",		RID_REGISTER,	0 },
   { "reinterpret_cast",	RID_REINTCAST,	D_CXXONLY | D_CXXWARN },
+  { "переинт_преобр",	RID_REINTCAST,	D_CXXONLY | D_CXXWARN },
   { "restrict",		RID_RESTRICT,	D_CONLY | D_C99 },
+  { "огранич",		RID_RESTRICT,	D_CONLY | D_C99 },
   { "return",		RID_RETURN,	0 },
+  { "возврат",		RID_RETURN,	0 },
   { "short",		RID_SHORT,	0 },
+  { "корот",		RID_SHORT,	0 },
   { "signed",		RID_SIGNED,	0 },
+  { "знак",		RID_SIGNED,	0 },
   { "sizeof",		RID_SIZEOF,	0 },
+  { "размер",		RID_SIZEOF,	0 },
   { "static",		RID_STATIC,	0 },
+  { "стат",		RID_STATIC,	0 },
   { "static_assert",    RID_STATIC_ASSERT, D_C23 | D_CXX11 | D_CXXWARN },
+  { "стат_проверка",    RID_STATIC_ASSERT, D_C23 | D_CXX11 | D_CXXWARN },
   { "static_cast",	RID_STATCAST,	D_CXXONLY | D_CXXWARN },
+  { "стат_преобр",	RID_STATCAST,	D_CXXONLY | D_CXXWARN },
   { "struct",		RID_STRUCT,	0 },
+  { "структ",		RID_STRUCT,	0 },
   { "switch",		RID_SWITCH,	0 },
+  { "выбор",		RID_SWITCH,	0 },
   { "template",		RID_TEMPLATE,	D_CXXONLY | D_CXXWARN },
+  { "шаблон",		RID_TEMPLATE,	D_CXXONLY | D_CXXWARN },
   { "this",		RID_THIS,	D_CXXONLY | D_CXXWARN },
+  { "этот",		RID_THIS,	D_CXXONLY | D_CXXWARN },
   { "thread_local",	RID_THREAD,	D_C23 | D_CXX11 | D_CXXWARN },
+  { "_Поток_лок",	RID_THREAD,	D_C23 | D_CXX11 | D_CXXWARN },
   { "throw",		RID_THROW,	D_CXX_OBJC | D_CXXWARN },
+  { "бросить",		RID_THROW,	D_CXX_OBJC | D_CXXWARN },
   { "true",		RID_TRUE,	D_C23 | D_CXXWARN },
+  { "истина",		RID_TRUE,	0 },
   { "try",		RID_TRY,	D_CXX_OBJC | D_CXXWARN },
+  { "попытка",		RID_TRY,	D_CXX_OBJC | D_CXXWARN },
   { "typedef",		RID_TYPEDEF,	0 },
+  { "типдеф",		RID_TYPEDEF,	0 },
   { "typename",		RID_TYPENAME,	D_CXXONLY | D_CXXWARN },
+  { "имя_типа",		RID_TYPENAME,	D_CXXONLY | D_CXXWARN },
   { "typeid",		RID_TYPEID,	D_CXXONLY | D_CXXWARN },
+  { "ид_типа",		RID_TYPEID,	D_CXXONLY | D_CXXWARN },
   { "typeof",		RID_TYPEOF,	D_EXT11 },
+  { "типоф",		RID_TYPEOF,	D_EXT11 },
   { "typeof_unqual",	RID_TYPEOF_UNQUAL,	D_CONLY | D_C23 },
+  { "тип_от_без_квал",	RID_TYPEOF_UNQUAL,	D_CONLY | D_C23 },
   { "union",		RID_UNION,	0 },
+  { "объед",		RID_UNION,	0 },
   { "unsigned",		RID_UNSIGNED,	0 },
+  { "беззнак",		RID_UNSIGNED,	0 },
   { "using",		RID_USING,	D_CXXONLY | D_CXXWARN },
+  { "используя",	RID_USING,	D_CXXONLY | D_CXXWARN },
   { "virtual",		RID_VIRTUAL,	D_CXXONLY | D_CXXWARN },
+  { "вирт",		RID_VIRTUAL,	D_CXXONLY | D_CXXWARN },
   { "void",		RID_VOID,	0 },
+  { "пусто",		RID_VOID,	0 },
   { "volatile",		RID_VOLATILE,	0 },
+  { "летуч",		RID_VOLATILE,	0 },
   { "wchar_t",		RID_WCHAR,	D_CXXONLY },
+  { "ш_симв",		RID_WCHAR,	D_CXXONLY },
   { "while",		RID_WHILE,	0 },
+  { "пока",		RID_WHILE,	0 },
 
   /* C++ transactional memory.  */
   { "synchronized",	RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
+  { "синхрон",	        RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
   { "atomic_noexcept",	RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM },
+  { "атомарн_без_искл",	RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM },
   { "atomic_cancel",	RID_ATOMIC_CANCEL, D_CXXONLY | D_TRANSMEM },
+  { "атомарн_отмена",	RID_ATOMIC_CANCEL, D_CXXONLY | D_TRANSMEM },
   { "atomic_commit",	RID_TRANSACTION_ATOMIC, D_CXXONLY | D_TRANSMEM },
+  { "атомарн_фиксация",	RID_TRANSACTION_ATOMIC, D_CXXONLY | D_TRANSMEM },
 
   /* Concepts-related keywords */
   { "concept",		RID_CONCEPT,	D_CXX_CONCEPTS_FLAGS | D_CXXWARN },
+  { "концепт",		RID_CONCEPT,	D_CXX_CONCEPTS_FLAGS | D_CXXWARN },
   { "requires", 	RID_REQUIRES,	D_CXX_CONCEPTS_FLAGS | D_CXXWARN },
+  { "требует", 	        RID_REQUIRES,	D_CXX_CONCEPTS_FLAGS | D_CXXWARN },
 
   /* Modules-related keywords, these are internal unspellable tokens,
      created by the preprocessor.  */
   { "module ",		RID__MODULE,	D_CXX_MODULES_FLAGS | D_CXXWARN },
+  { "модуль ",		RID__MODULE,	D_CXX_MODULES_FLAGS | D_CXXWARN },
   { "import ",		RID__IMPORT,	D_CXX_MODULES_FLAGS | D_CXXWARN },
+  { "импорт ",		RID__IMPORT,	D_CXX_MODULES_FLAGS | D_CXXWARN },
   { "export ",		RID__EXPORT,	D_CXX_MODULES_FLAGS | D_CXXWARN },
+  { "экспорт ",		RID__EXPORT,	D_CXX_MODULES_FLAGS | D_CXXWARN },
 
   /* Coroutines-related keywords */
   { "co_await",		RID_CO_AWAIT,	D_CXX_COROUTINES_FLAGS | D_CXXWARN },
+  { "со_ждать",		RID_CO_AWAIT,	D_CXX_COROUTINES_FLAGS | D_CXXWARN },
   { "co_yield",		RID_CO_YIELD,	D_CXX_COROUTINES_FLAGS | D_CXXWARN },
+  { "со_уступить",	RID_CO_YIELD,	D_CXX_COROUTINES_FLAGS | D_CXXWARN },
   { "co_return", 	RID_CO_RETURN,	D_CXX_COROUTINES_FLAGS | D_CXXWARN },
+  { "со_возврат", 	RID_CO_RETURN,	D_CXX_COROUTINES_FLAGS | D_CXXWARN },
 
   /* These Objective-C keywords are recognized only immediately after
      an '@'.  */
   { "compatibility_alias", RID_AT_ALIAS,	D_OBJC },
+  { "совместим_псевдоним", RID_AT_ALIAS,	D_OBJC },
   { "defs",		RID_AT_DEFS,		D_OBJC },
+  { "описания",		RID_AT_DEFS,		D_OBJC },
   { "encode",		RID_AT_ENCODE,		D_OBJC },
+  { "кодировать",	RID_AT_ENCODE,		D_OBJC },
   { "end",		RID_AT_END,		D_OBJC },
+  { "конец",		RID_AT_END,		D_OBJC },
   { "implementation",	RID_AT_IMPLEMENTATION,	D_OBJC },
+  { "реализация",	RID_AT_IMPLEMENTATION,	D_OBJC },
   { "interface",	RID_AT_INTERFACE,	D_OBJC },
+  { "интерфейс",	RID_AT_INTERFACE,	D_OBJC },
   { "protocol",		RID_AT_PROTOCOL,	D_OBJC },
+  { "протокол",		RID_AT_PROTOCOL,	D_OBJC },
   { "selector",		RID_AT_SELECTOR,	D_OBJC },
+  { "селектор",		RID_AT_SELECTOR,	D_OBJC },
   { "finally",		RID_AT_FINALLY,		D_OBJC },
+  { "наконец",		RID_AT_FINALLY,		D_OBJC },
   { "optional",		RID_AT_OPTIONAL,	D_OBJC },
+  { "необязат",		RID_AT_OPTIONAL,	D_OBJC },
   { "required",		RID_AT_REQUIRED,	D_OBJC },
+  { "обязат",		RID_AT_REQUIRED,	D_OBJC },
   { "property",		RID_AT_PROPERTY,	D_OBJC },
+  { "свойство",		RID_AT_PROPERTY,	D_OBJC },
   { "package",		RID_AT_PACKAGE,		D_OBJC },
+  { "пакет",		RID_AT_PACKAGE,		D_OBJC },
   { "synthesize",	RID_AT_SYNTHESIZE,	D_OBJC },
+  { "синтез",	        RID_AT_SYNTHESIZE,	D_OBJC },
   { "dynamic",		RID_AT_DYNAMIC,		D_OBJC },
+  { "динам",		RID_AT_DYNAMIC,		D_OBJC },
   /* These are recognized only in protocol-qualifier context
      (see above) */
   { "bycopy",		RID_BYCOPY,		D_OBJC },
+  { "копировать",	RID_BYCOPY,		D_OBJC },
   { "byref",		RID_BYREF,		D_OBJC },
+  { "по_ссылке",	RID_BYREF,		D_OBJC },
   { "in",		RID_IN,			D_OBJC },
+  { "вход",		RID_IN,			D_OBJC },
   { "inout",		RID_INOUT,		D_OBJC },
+  { "вход_выход",	RID_INOUT,		D_OBJC },
   { "oneway",		RID_ONEWAY,		D_OBJC },
+  { "однонапр",		RID_ONEWAY,		D_OBJC },
   { "out",		RID_OUT,		D_OBJC },
+  { "выход",		RID_OUT,		D_OBJC },
   /* These are recognized inside a property attribute list */
   { "assign",		RID_ASSIGN,		D_OBJC },
+  { "присвоить",	RID_ASSIGN,		D_OBJC },
   { "atomic",		RID_PROPATOMIC,		D_OBJC },
+  { "атомарн",		RID_PROPATOMIC,		D_OBJC },
   { "copy",		RID_COPY,		D_OBJC },
+  { "копия",		RID_COPY,		D_OBJC },
   { "getter",		RID_GETTER,		D_OBJC },
+  { "получатель",	RID_GETTER,		D_OBJC },
   { "nonatomic",	RID_NONATOMIC,		D_OBJC },
+  { "не_атомарн",	RID_NONATOMIC,		D_OBJC },
   { "readonly",		RID_READONLY,		D_OBJC },
+  { "только_чтение",	RID_READONLY,		D_OBJC },
   { "readwrite",	RID_READWRITE,		D_OBJC },
+  { "чтение_запись",	RID_READWRITE,		D_OBJC },
   { "retain",		RID_RETAIN,		D_OBJC },
+  { "удержать",		RID_RETAIN,		D_OBJC },
   { "setter",		RID_SETTER,		D_OBJC },
+  { "установщик",	RID_SETTER,		D_OBJC },
   /* These are Objective C implementation of nullability, accepted only in
      specific contexts.  */
   { "null_unspecified", RID_NULL_UNSPECIFIED,	D_OBJC },
+  { "нуль_не_указан",   RID_NULL_UNSPECIFIED,	D_OBJC },
   { "nullable",		RID_NULLABLE,		D_OBJC },
+  { "может_быть_нуль",	RID_NULLABLE,		D_OBJC },
   { "nonnull",		RID_NONNULL,		D_OBJC },
+  { "не_нуль",		RID_NONNULL,		D_OBJC },
   { "null_resettable",	RID_NULL_RESETTABLE,	D_OBJC },
+  { "нуль_сбрасываемый",RID_NULL_RESETTABLE,	D_OBJC },
 };
 
 const unsigned int num_c_common_reswords = ARRAY_SIZE (c_common_reswords);
@@ -4792,6 +5012,7 @@ c_common_nodes_and_builtins (void)
   c_define_builtins (va_list_ref_type_node, va_list_arg_type_node);
 
   main_identifier_node = get_identifier ("main");
+  main_ru_identifier_node = get_identifier ("главн");
 
   /* Create the built-in __null node.  It is important that this is
      not shared.  */
@@ -8802,6 +9023,7 @@ keyword_begins_type_specifier (enum rid keyword)
     {
     case RID_AUTO_TYPE:
     case RID_INT:
+    case RID_INT_RU:  // ДОБАВИТЬ ЗДЕСЬ!
     case RID_CHAR:
     case RID_FLOAT:
     case RID_DOUBLE:
@@ -8847,6 +9069,7 @@ keyword_is_type_qualifier (enum rid keyword)
   switch (keyword)
     {
     case RID_CONST:
+    //case RID_CONST_RU:  // ДОБАВИТЬ ЗДЕСЬ!
     case RID_VOLATILE:
     case RID_RESTRICT:
     case RID_ATOMIC:
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 2d5f5399885..d94ebf3fe89 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -260,7 +260,11 @@ enum rid
   RID_FIRST_PQ = RID_IN,
   RID_LAST_PQ = RID_ONEWAY,
   RID_FIRST_PATTR = RID_GETTER,
-  RID_LAST_PATTR = RID_NULL_RESETTABLE
+  RID_LAST_PATTR = RID_NULL_RESETTABLE,
+
+  RID_INT_RU,
+  RID_CONST_RU,
+  RID_MAIN_RU
 };
 
 #define OBJC_IS_AT_KEYWORD(rid) \
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 0e52f217618..cbb738b142b 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -10502,6 +10502,14 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
 			  &attributes, &expr, NULL, DEPRECATED_NORMAL);
   invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
 
+  /* === ДОБАВЛЕНО: замена "главн" на "main" === */
+  if (decl1 != NULL_TREE && TREE_CODE (decl1) == FUNCTION_DECL)
+    {
+      if (DECL_NAME (decl1) == main_ru_identifier_node)
+        DECL_NAME (decl1) = main_identifier_node;
+    }
+  /* === КОНЕЦ ДОБАВЛЕННОГО БЛОКА === */
+
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
   if (decl1 == NULL_TREE
@@ -12466,6 +12474,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
 		}
 	      return specs;
 	    case RID_INT:
+		case RID_INT_RU:  // ДОБАВИТЬ ЗДЕСЬ!
 	      if (specs->saturating_p)
 		error_at (loc,
 			  ("both %<_Sat%> and %<int%> in "
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 5fcfff7134a..1e1a68eb1b8 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -588,6 +588,7 @@ c_keyword_starts_typename (enum rid keyword)
     case RID_SIGNED:
     case RID_COMPLEX:
     case RID_INT:
+case RID_INT_RU:  // ДОБАВИТЬ ЗДЕСЬ!
     case RID_CHAR:
     case RID_FLOAT:
     case RID_DOUBLE:
@@ -792,6 +793,7 @@ c_token_starts_declspecs (c_token *token)
 	case RID_SIGNED:
 	case RID_COMPLEX:
 	case RID_INT:
+case RID_INT_RU:  // ДОБАВИТЬ ЗДЕСЬ!
 	case RID_CHAR:
 	case RID_FLOAT:
 	case RID_DOUBLE:
@@ -3446,6 +3448,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
 	case RID_SIGNED:
 	case RID_COMPLEX:
 	case RID_INT:
+case RID_INT_RU:  // ДОБАВИТЬ ЗДЕСЬ!
 	case RID_CHAR:
 	case RID_FLOAT:
 	case RID_DOUBLE:
@@ -5173,6 +5176,7 @@ c_parser_gnu_attribute_any_word (c_parser *parser)
 	case RID_COMPLEX:
 	case RID_THREAD:
 	case RID_INT:
+case RID_INT_RU:  // ДОБАВИТЬ ЗДЕСЬ!
 	case RID_CHAR:
 	case RID_FLOAT:
 	case RID_DOUBLE:
@@ -13901,6 +13905,7 @@ c_parser_objc_selector (c_parser *parser)
     case RID_BYREF:
     case RID_ONEWAY:
     case RID_INT:
+case RID_INT_RU:  // ДОБАВИТЬ ЗДЕСЬ!
     case RID_CHAR:
     case RID_FLOAT:
     case RID_DOUBLE:
diff --git a/gcc/cp/lex.cc b/gcc/cp/lex.cc
index 1110db7f8d0..d29f5c20100 100644
--- a/gcc/cp/lex.cc
+++ b/gcc/cp/lex.cc
@@ -262,17 +262,33 @@ init_reswords (void)
   /* The Objective-C keywords are all context-dependent.  */
   mask |= D_OBJC;
 
-  ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
-  for (i = 0; i < num_c_common_reswords; i++)
-    {
-      if (c_common_reswords[i].disable & D_CONLY)
-	continue;
-      id = get_identifier (c_common_reswords[i].word);
-      C_SET_RID_CODE (id, c_common_reswords[i].rid);
-      ridpointers [(int) c_common_reswords[i].rid] = id;
-      if (! (c_common_reswords[i].disable & mask))
-	set_identifier_kind (id, cik_keyword);
-    }
+// В gcc/cp/lex.cc (или gcc/c-family/c-common.cc для C)
+// Добавить специальную обработку после основного цикла
+
+ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
+for (i = 0; i < num_c_common_reswords; i++)
+{
+    if (c_common_reswords[i].disable & D_CONLY)
+        continue;
+    id = get_identifier (c_common_reswords[i].word);
+    C_SET_RID_CODE (id, c_common_reswords[i].rid);
+    ridpointers [(int) c_common_reswords[i].rid] = id;
+    if (! (c_common_reswords[i].disable & mask))
+        set_identifier_kind (id, cik_keyword);
+}
+
+// ✅ ДОБАВИТЬ: сделать RID_INT_RU и RID_INT эквивалентными
+// Делаем так, чтобы оба ключевых слова указывали на ОДИН идентификатор
+if (ridpointers[RID_INT] && ridpointers[RID_INT_RU])
+{
+    // Вариант 1: переиспользовать идентификатор RID_INT для RID_INT_RU
+    ridpointers[RID_INT_RU] = ridpointers[RID_INT];
+    
+    // ИЛИ вариант 2: сделать оба указателя на идентификатор "цел"
+    // ridpointers[RID_INT] = ridpointers[RID_INT_RU];
+}
+
+
 
   for (i = 0; i < NUM_INT_N_ENTS; i++)
     {
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 9fa74342919..a5be6ec6955 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -754,6 +754,7 @@ enum tree_index {
   TI_VOID_LIST_NODE,
 
   TI_MAIN_IDENTIFIER,
+  TI_MAIN_RU_IDENTIFIER,
 
   TI_SAT_SFRACT_TYPE,
   TI_SAT_FRACT_TYPE,
diff --git a/gcc/tree.h b/gcc/tree.h
index ee2aae332a4..b3336250935 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4606,9 +4606,11 @@ tree_strip_any_location_wrapper (tree exp)
 #define void_list_node                  global_trees[TI_VOID_LIST_NODE]
 
 #define main_identifier_node		global_trees[TI_MAIN_IDENTIFIER]
+#define main_ru_identifier_node global_trees[TI_MAIN_RU_IDENTIFIER]
 #define MAIN_NAME_P(NODE) \
   (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node)
-
+#define MAIN_RU_NAME_P(NODE) \
+  (IDENTIFIER_NODE_CHECK (NODE) == main_ru_identifier_node)  // ← ДОБАВИТЬ
 /* Optimization options (OPTIMIZATION_NODE) to use for default and current
    functions.  */
 #define optimization_default_node	global_trees[TI_OPTIMIZATION_DEFAULT]
diff --git a/libcpp/directives.cc b/libcpp/directives.cc
index 479f8c716e8..aed62174ab0 100644
--- a/libcpp/directives.cc
+++ b/libcpp/directives.cc
@@ -190,6 +190,23 @@ enum
 static const directive dtable[] =
 {
 DIRECTIVE_TABLE
+
+  /* Русские синонимы для директив */
+  { do_define,   UC"определить",   sizeof "определить" - 1, KANDR, IN_I },
+  { do_include,  UC"включить",     sizeof "включить" - 1,   KANDR, INCL | EXPAND },
+  { do_if,       UC"если",         sizeof "если" - 1,       KANDR, COND | IF_COND | EXPAND },
+  { do_ifdef,    UC"еслиопр",      sizeof "еслиопр" - 1, KANDR, COND | IF_COND },
+  { do_ifndef,   UC"еслинеопр", sizeof "еслинеопр" - 1, KANDR, COND | IF_COND },
+  { do_elif,     UC"иначеесли",    sizeof "иначеесли" - 1, STDC89, COND | EXPAND },
+  { do_else,     UC"иначе",        sizeof "иначе" - 1,      KANDR, COND },
+  { do_endif,    UC"конецесли",    sizeof "конецесли" - 1, KANDR, COND },
+  { do_undef,    UC"отменить",     sizeof "отменить" - 1,   KANDR, IN_I },
+  { do_error,    UC"ошибка",       sizeof "ошибка" - 1,     STDC89, 0 },
+  { do_warning,  UC"предупреждение", sizeof "предупреждение" - 1, STDC23, 0 },
+  { do_pragma,   UC"прагма",       sizeof "прагма" - 1,     STDC89, IN_I },
+  { do_line,     UC"строка",       sizeof "строка" - 1,     KANDR, EXPAND },
+  { do_include_next, UC"включить_след", sizeof "включить_след" - 1, EXTENSION, INCL | EXPAND },
+  { do_import,   UC"импорт",       sizeof "импорт" - 1,     EXTENSION, INCL | EXPAND },
 };
 #undef D
 
@@ -197,7 +214,25 @@ DIRECTIVE_TABLE
    when suggesting corrections for misspelled directives.  */
 #define D(name, t, origin, flags) #name,
 static const char * const directive_names[] = {
-DIRECTIVE_TABLE
+  DIRECTIVE_TABLE
+
+  /* Русские синонимы для подсказок */
+  "определить",
+  "включить",
+  "если",
+  "если_определен",
+  "если_не_определен",
+  "иначе_если",
+  "иначе",
+  "конец_если",
+  "отменить",
+  "ошибка",
+  "предупреждение",
+  "прагма",
+  "строка",
+  "включить_след",
+  "импорт",
+
   NULL
 };
 #undef D
@@ -459,6 +494,7 @@ _cpp_handle_directive (cpp_reader *pfile, bool indented)
 
   if (dname->type == CPP_NAME)
     {
+      /* Сначала проверяем стандартные директивы по is_directive.  */
       if (dname->val.node.node->is_directive)
 	{
 	  dir = &dtable[dname->val.node.node->directive_index];
@@ -469,6 +505,31 @@ _cpp_handle_directive (cpp_reader *pfile, bool indented)
 	      && CPP_OPTION (pfile, std))
 	    dir = 0;
 	}
+else
+  {
+    /* Если не нашли по is_directive, ищем русский синоним в dtable.  */
+    const uchar *name = NODE_NAME (dname->val.node.node);
+    size_t len = NODE_LEN (dname->val.node.node);
+    
+    /* ОТЛАДКА: выводим имя и длину искомой директивы */
+    fprintf (stderr, "DEBUG: Looking for directive '%.*s' (len=%zu)\n",
+             (int)len, name, len);
+    
+    for (unsigned int i = 0; i < ARRAY_SIZE (dtable); i++)
+      {
+        /* ОТЛАДКА: выводим каждую запись в dtable */
+        fprintf (stderr, "DEBUG: dtable[%u] = '%.*s' (len=%hu)\n",
+                 i, (int)dtable[i].length, dtable[i].name, dtable[i].length);
+        
+        if (dtable[i].length == len
+            && memcmp (dtable[i].name, name, len) == 0)
+          {
+            fprintf (stderr, "DEBUG: FOUND! i=%u\n", i);
+            dir = &dtable[i];
+            break;
+          }
+      }
+  }
     }
   /* We do not recognize the # followed by a number extension in
      assembler code.  */
@@ -2171,8 +2232,9 @@ do_elif (cpp_reader *pfile)
 	}
       else
 	{
-	  if (pfile->directive == &dtable[T_ELIF])
-	    pfile->state.skipping = !_cpp_parse_expr (pfile, false);
+	  if (pfile->directive == &dtable[T_ELIF]
+      || pfile->directive->handler == do_elif)
+      pfile->state.skipping = !_cpp_parse_expr (pfile, false);
 	  else
 	    {
 	      cpp_hashnode *node = lex_macro_node (pfile, false);
@@ -2813,6 +2875,16 @@ _cpp_init_directives (cpp_reader *pfile)
       node->is_directive = 1;
       node->directive_index = i;
     }
+
+  /* Добавляем русские синонимы в хеш-таблицу.
+     Они не должны иметь is_directive, потому что мы будем
+     искать их напрямую в dtable[] по имени.  */
+  const char *russian_aliases[] = {
+    "определить", "включить", "если", "если_определен",
+    "если_не_определен", "иначе_если", "иначе",
+    "конец_если", "отменить", "ошибка", "предупреждение",
+    "прагма", "строка", "включить_след", "импорт"
+  };
 }
 
 /* Extract header file from a bracket include. Parsing starts after '<'.
diff --git a/libcpp/expr.cc b/libcpp/expr.cc
index 815eb137a99..4008d222560 100644
--- a/libcpp/expr.cc
+++ b/libcpp/expr.cc
@@ -1174,6 +1174,16 @@ parse_defined (cpp_reader *pfile)
   return result;
 }
 
+/* Handle meeting "определено" in a preprocessor expression (Russian synonym).  */
+static cpp_num
+parse_defined_ru (cpp_reader *pfile)
+{
+  /* Просто вызываем parse_defined, так как логика обработки идентична.
+     Разница только в имени оператора, которое используется только в
+     сообщениях об ошибках, поэтому переиспользуем существующую функцию.  */
+  return parse_defined (pfile);
+}
+
 /* Convert a token into a CPP_NUMBER (an interpreted preprocessing
    number or character constant, or the result of the "defined" or "#"
    operators).  */
@@ -1241,6 +1251,9 @@ eval_token (cpp_reader *pfile, const cpp_token *token,
     case CPP_NAME:
       if (token->val.node.node == pfile->spec_nodes.n_defined)
 	return parse_defined (pfile);
+      /* Русский синоним "определено" */
+      else if (token->val.node.node == pfile->spec_nodes.n_defined_ru)
+	return parse_defined (pfile);
       else if (CPP_OPTION (pfile, true_false)
 	       && (token->val.node.node == pfile->spec_nodes.n_true
 		   || token->val.node.node == pfile->spec_nodes.n_false))
diff --git a/libcpp/init.cc b/libcpp/init.cc
index 54fc9236d38..ea647e5b544 100644
--- a/libcpp/init.cc
+++ b/libcpp/init.cc
@@ -309,6 +309,9 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
 
   _cpp_init_hashtable (pfile, table, extra_table);
 
+  pfile->spec_nodes.n_defined_ru = cpp_lookup (pfile, UC"определено", 
+                                                sizeof "определено" - 1);
+
   return pfile;
 }
 
@@ -418,14 +421,22 @@ struct builtin_macro
 static const struct builtin_macro builtin_array[] =
 {
   B("__TIMESTAMP__",	 BT_TIMESTAMP,     false),
+  B("__ВРЕМЯ_ФАЙЛА__",	 BT_TIMESTAMP,     false),
   B("__TIME__",		 BT_TIME,          false),
+  B("__ВРЕМЯ__",		 BT_TIME,          false),
   B("__DATE__",		 BT_DATE,          false),
+  B("__ДАТА__",		 BT_DATE,          false),
   B("__FILE__",		 BT_FILE,          false),
+  B("__ФАЙЛ__",		 BT_FILE,          false),
   B("__FILE_NAME__",	 BT_FILE_NAME,     false),
   B("__BASE_FILE__",	 BT_BASE_FILE,     false),
+  B("__БАЗОВЫЙ_ФАЙЛ__",	 BT_BASE_FILE,     false),
   B("__LINE__",		 BT_SPECLINE,      true),
+  B("__ЛИНИЯ__",		 BT_SPECLINE,      true),
   B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL, true),
   B("__COUNTER__",	 BT_COUNTER,       true),
+  B("__СЧЁТЧИК__",	 BT_COUNTER,       true),
+  B("__СЧЕТЧИК__",	 BT_COUNTER,       true),
   /* Make sure to update the list of built-in
      function-like macros in traditional.cc:
      fun_like_macro() when adding more following */
diff --git a/libcpp/internal.h b/libcpp/internal.h
index a20215c5709..538013d980f 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -297,6 +297,7 @@ struct lexer_state
 struct spec_nodes
 {
   cpp_hashnode *n_defined;		/* defined operator */
+  cpp_hashnode *n_defined_ru;	/* русский синоним "определено" */
   cpp_hashnode *n_true;			/* C++ keyword true */
   cpp_hashnode *n_false;		/* C++ keyword false */
   cpp_hashnode *n__VA_ARGS__;		/* C99 vararg macros */
diff --git a/libcpp/lex.cc b/libcpp/lex.cc
index c9e44e6cccc..e6743393116 100644
--- a/libcpp/lex.cc
+++ b/libcpp/lex.cc
@@ -2085,6 +2085,40 @@ forms_identifier_p (cpp_reader *pfile, int first,
       return true;
     }
 
+  /* ================================================================
+     ДОБАВЛЕНО: Проверка на русские буквы в UTF-8
+     ================================================================ */
+  if (*buffer->cur == 0xD0 || *buffer->cur == 0xD1)
+    {
+      unsigned char first = *buffer->cur;
+      unsigned char second = *(buffer->cur + 1);
+
+      /* Диапазоны русских букв в UTF-8:
+         А-Я: D0 90 - D0 AF
+         а-я: D1 80 - D1 8F
+         Ё:   D0 81
+         ё:   D1 91
+      */
+      if (first == 0xD0 && second >= 0x90 && second <= 0xBF)
+	{
+	  buffer->cur += 2;
+	  return true;
+	}
+      if (first == 0xD1 && second >= 0x80 && second <= 0x8F)
+	{
+	  buffer->cur += 2;
+	  return true;
+	}
+      if (first == 0xD0 && (second == 0x81 || second == 0x91))
+	{
+	  buffer->cur += 2;
+	  return true;
+	}
+    }
+  /* ================================================================
+     КОНЕЦ ДОБАВЛЕННОГО БЛОКА
+     ================================================================ */
+
   /* Is this a syntactically valid UCN or a valid UTF-8 char?  */
   if (CPP_OPTION (pfile, extended_identifiers))
     {
📌 Дизассемблированные привет мир
me@me-Aspire-5742G:~/Документы/rusi/rusi$ objdump -d привет_chibicc 

привет_chibicc:     формат файла elf64-x86-64


Дизассемблирование раздела .init:

0000000000401000 <_init>:
  401000:	f3 0f 1e fa          	endbr64
  401004:	48 83 ec 08          	sub    $0x8,%rsp
  401008:	48 8b 05 d1 2f 00 00 	mov    0x2fd1(%rip),%rax        # 403fe0 <__gmon_start__>
  40100f:	48 85 c0             	test   %rax,%rax
  401012:	74 02                	je     401016 <_init+0x16>
  401014:	ff d0                	call   *%rax
  401016:	48 83 c4 08          	add    $0x8,%rsp
  40101a:	c3                   	ret

Дизассемблирование раздела .text:

0000000000401020 <_start>:
  401020:	f3 0f 1e fa          	endbr64
  401024:	31 ed                	xor    %ebp,%ebp
  401026:	49 89 d1             	mov    %rdx,%r9
  401029:	5e                   	pop    %rsi
  40102a:	48 89 e2             	mov    %rsp,%rdx
  40102d:	48 83 e4 f0          	and    $0xfffffffffffffff0,%rsp
  401031:	50                   	push   %rax
  401032:	54                   	push   %rsp
  401033:	45 31 c0             	xor    %r8d,%r8d
  401036:	31 c9                	xor    %ecx,%ecx
  401038:	48 c7 c7 06 11 40 00 	mov    $0x401106,%rdi
  40103f:	ff 15 8b 2f 00 00    	call   *0x2f8b(%rip)        # 403fd0 <__libc_start_main@GLIBC_2.34>
  401045:	f4                   	hlt
  401046:	66 2e 0f 1f 84 00 00 	cs nopw 0x0(%rax,%rax,1)
  40104d:	00 00 00 

0000000000401050 <_dl_relocate_static_pie>:
  401050:	f3 0f 1e fa          	endbr64
  401054:	c3                   	ret
  401055:	66 2e 0f 1f 84 00 00 	cs nopw 0x0(%rax,%rax,1)
  40105c:	00 00 00 
  40105f: 90                   	nop

0000000000401060 <deregister_tm_clones>:
  401060:	b8 d8 41 40 00       	mov    $0x4041d8,%eax
  401065:	48 3d d8 41 40 00    	cmp    $0x4041d8,%rax
  40106b:	74 13                	je     401080 <deregister_tm_clones+0x20>
  40106d:	b8 00 00 00 00       	mov    $0x0,%eax
  401072:	48 85 c0             	test   %rax,%rax
  401075:	74 09                	je     401080 <deregister_tm_clones+0x20>
  401077:	bf d8 41 40 00       	mov    $0x4041d8,%edi
  40107c:	ff e0                	jmp    *%rax
  40107e:	66 90                	xchg   %ax,%ax
  401080:	c3                   	ret
  401081:	0f 1f 40 00          	nopl   0x0(%rax)
  401085:	66 66 2e 0f 1f 84 00 	data16 cs nopw 0x0(%rax,%rax,1)
  40108c:	00 00 00 00 

0000000000401090 <register_tm_clones>:
  401090:	be d8 41 40 00       	mov    $0x4041d8,%esi
  401095:	48 81 ee d8 41 40 00 	sub    $0x4041d8,%rsi
  40109c:	48 89 f0             	mov    %rsi,%rax
  40109f:	48 c1 ee 3f          	shr    $0x3f,%rsi
  4010a3:	48 c1 f8 03          	sar    $0x3,%rax
  4010a7:	48 01 c6             	add    %rax,%rsi
  4010aa: 48 d1 fe             	sar    $1,%rsi
  4010ad:	74 11                	je     4010c0 <register_tm_clones+0x30>
  4010af:	b8 00 00 00 00       	mov    $0x0,%eax
  4010b4:	48 85 c0             	test   %rax,%rax
  4010b7:	74 07                	je     4010c0 <register_tm_clones+0x30>
  4010b9:	bf d8 41 40 00       	mov    $0x4041d8,%edi
  4010be:	ff e0                	jmp    *%rax
  4010c0:	c3                   	ret
  4010c1:	0f 1f 40 00          	nopl   0x0(%rax)
  4010c5:	66 66 2e 0f 1f 84 00 	data16 cs nopw 0x0(%rax,%rax,1)
  4010cc:	00 00 00 00 

00000000004010d0 <__do_global_dtors_aux>:
  4010d0:	f3 0f 1e fa          	endbr64
  4010d4:	80 3d fa 30 00 00 00 	cmpb   $0x0,0x30fa(%rip)        # 4041d5 <completed.0>
  4010db:	75 13                	jne    4010f0 <__do_global_dtors_aux+0x20>
  4010dd:	55                   	push   %rbp
  4010de:	48 89 e5             	mov    %rsp,%rbp
  4010e1:	e8 7a ff ff ff       	call   401060 <deregister_tm_clones>
  4010e6:	c6 05 e8 30 00 00 01 	movb   $0x1,0x30e8(%rip)        # 4041d5 <completed.0>
  4010ed:	5d                   	pop    %rbp
  4010ee:	c3                   	ret
  4010ef:	90                   	nop
  4010f0:	c3                   	ret
  4010f1:	0f 1f 40 00          	nopl   0x0(%rax)
  4010f5:	66 66 2e 0f 1f 84 00 	data16 cs nopw 0x0(%rax,%rax,1)
  4010fc:	00 00 00 00 

0000000000401100 <frame_dummy>:
  401100:	f3 0f 1e fa          	endbr64
  401104:	eb 8a                	jmp    401090 <register_tm_clones>

0000000000401106 <главн>:
  401106:	55                   	push   %rbp
  401107:	48 89 e5             	mov    %rsp,%rbp
  40110a:	48 83 ec 10          	sub    $0x10,%rsp
  40110e:	48 89 65 f8          	mov    %rsp,-0x8(%rbp)
  401112:	48 8d 05 f7 2e 00 00 	lea    0x2ef7(%rip),%rax        # 404010 <__dso_handle+0x8>
  401119:	50                   	push   %rax
  40111a:	48 8b 05 b7 2e 00 00 	mov    0x2eb7(%rip),%rax        # 403fd8 <printf@GLIBC_2.2.5>
  401121:	5f                   	pop    %rdi
  401122:	49 89 c2             	mov    %rax,%r10
  401125:	48 c7 c0 00 00 00 00 	mov    $0x0,%rax
  40112c:	41 ff d2             	call   *%r10
  40112f:	48 83 c4 00          	add    $0x0,%rsp
  401133:	48 c7 c0 00 00 00 00 	mov    $0x0,%rax
  40113a:	eb 07                	jmp    401143 <главн+0x3d>
  40113c:	48 c7 c0 00 00 00 00 	mov    $0x0,%rax
  401143:	48 89 ec             	mov    %rbp,%rsp
  401146:	5d                   	pop    %rbp
  401147:	c3                   	ret

0000000000401148 <__va_read_from_fp>:
  401148:	55                   	push   %rbp
  401149:	48 89 e5             	mov    %rsp,%rbp
  40114c:	48 83 ec 30          	sub    $0x30,%rsp
  401150:	48 89 65 e8          	mov    %rsp,-0x18(%rbp)
  401154:	48 89 7d e0          	mov    %rdi,-0x20(%rbp)
  401158:	89 75 dc             	mov    %esi,-0x24(%rbp)
  40115b:	89 55 d8             	mov    %edx,-0x28(%rbp)
  40115e:	48 8d 45 e0          	lea    -0x20(%rbp),%rax
  401162:	48 8b 00             	mov    (%rax),%rax
  401165:	48 83 c0 04          	add    $0x4,%rax
  401169:	48 63 00             	movslq (%rax),%rax
  40116c:	50                   	push   %rax
  40116d:	48 c7 c0 70 00 00 00 	mov    $0x70,%rax
  401174:	5f                   	pop    %rdi
  401175:	39 f8                	cmp    %edi,%eax
  401177:	0f 96 c0             	setbe  %al
  40117a:	48 0f b6 c0          	movzbq %al,%rax
  40117e:	83 f8 00             	cmp    $0x0,%eax
  401181:	74 3a                	je     4011bd <__va_read_from_fp+0x75>
  401183:	48 8d 45 d8          	lea    -0x28(%rbp),%rax
  401187:	48 63 00             	movslq (%rax),%rax
  40118a:	50                   	push   %rax
  40118b:	48 8d 45 dc          	lea    -0x24(%rbp),%rax
  40118f:	48 63 00             	movslq (%rax),%rax
  401192:	50                   	push   %rax
  401193:	48 8d 45 e0          	lea    -0x20(%rbp),%rax
  401197:	48 8b 00             	mov    (%rax),%rax
  40119a:	50                   	push   %rax
  40119b:	48 8d 05 ac 01 00 00 	lea    0x1ac(%rip),%rax        # 40134e <__va_read_from_stack>
  4011a2:	5f                   	pop    %rdi
  4011a3:	5e                   	pop    %rsi
  4011a4:	5a                   	pop    %rdx
  4011a5:	49 89 c2             	mov    %rax,%r10
  4011a8:	48 c7 c0 00 00 00 00 	mov    $0x0,%rax
  4011af:	41 ff d2             	call   *%r10
  4011b2:	48 83 c4 00          	add    $0x0,%rsp
  4011b6:	e9 8b 00 00 00       	jmp    401246 <__va_read_from_fp+0xfe>
  4011bb:	eb 00                	jmp    4011bd <__va_read_from_fp+0x75>
  4011bd:	48 c7 c1 08 00 00 00 	mov    $0x8,%rcx
  4011c4:	48 8d 7d f0          	lea    -0x10(%rbp),%rdi
  4011c8:	b0 00                	mov    $0x0,%al
  4011ca:	f3 aa                	rep stos %al,(%rdi)
  4011cc:	48 8d 45 f0          	lea    -0x10(%rbp),%rax
  4011d0:	50                   	push   %rax
  4011d1:	48 c7 c0 01 00 00 00 	mov    $0x1,%rax
  4011d8:	50                   	push   %rax
  4011d9: 48 8d 45 e0          	lea    -0x20(%rbp),%rax
  4011dd:	48 8b 00             	mov    (%rax),%rax
  4011e0: 48 83 c0 04          	add    $0x4,%rax
  4011e4: 48 63 00             	movslq (%rax),%rax
  4011e7: 89 c0                	mov    %eax,%eax
  4011e9: 5f                   	pop    %rdi
  4011ea: 48 0f af c7          	imul   %rdi,%rax
  4011ee: 50                   	push   %rax
  4011ef: 48 8d 45 e0          	lea    -0x20(%rbp),%rax
  4011f3: 48 8b 00             	mov    (%rax),%rax
  4011f6: 48 83 c0 10          	add    $0x10,%rax
  4011fa: 48 8b 00             	mov    (%rax),%rax
  4011fd: 5f                   	pop    %rdi
  4011fe: 48 01 f8             	add    %rdi,%rax
  401201:	5f                   	pop    %rdi
  401202:	48 89 07             	mov    %rax,(%rdi)
  401205: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  401209:	50                   	push   %rax
  40120a: 48 8d 45 e0          	lea    -0x20(%rbp),%rax
  40120e:	48 8b 00             	mov    (%rax),%rax
  401211:	5f                   	pop    %rdi
  401212:	48 89 07             	mov    %rax,(%rdi)
  401215: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  401219:	48 8b 00             	mov    (%rax),%rax
  40121c:	48 83 c0 04          	add    $0x4,%rax
  401220:	50                   	push   %rax
  401221: 48 c7 c0 08 00 00 00 	mov    $0x8,%rax
  401228:	50                   	push   %rax
  401229: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  40122d: 48 8b 00             	mov    (%rax),%rax
  401230: 48 83 c0 04          	add    $0x4,%rax
  401234: 48 63 00             	movslq (%rax),%rax
  401237:	5f                   	pop    %rdi
  401238:	01 f8                	add    %edi,%eax
  40123a:	5f                   	pop    %rdi
  40123b:	89 07                	mov    %eax,(%rdi)
  40123d: 48 8d 45 f0          	lea    -0x10(%rbp),%rax
  401241: 48 8b 00             	mov    (%rax),%rax
  401244:	eb 00                	jmp    401246 <__va_read_from_fp+0xfe>
  401246:	48 89 ec             	mov    %rbp,%rsp
  401249:	5d                   	pop    %rbp
  40124a:	c3                   	ret

000000000040124b <__va_read_from_gp>:
  40124b:	55                   	push   %rbp
  40124c:	48 89 e5             	mov    %rsp,%rbp
  40124f:	48 83 ec 30          	sub    $0x30,%rsp
  401253:	48 89 65 e8          	mov    %rsp,-0x18(%rbp)
  401257:	48 89 7d e0          	mov    %rdi,-0x20(%rbp)
  40125b:	89 75 dc             	mov    %esi,-0x24(%rbp)
  40125e:	89 55 d8             	mov    %edx,-0x28(%rbp)
  401261:	48 8d 45 e0          	lea    -0x20(%rbp),%rax
  401265:	48 8b 00             	mov    (%rax),%rax
  401268:	48 83 c0 00          	add    $0x0,%rax
  40126c:	48 63 00             	movslq (%rax),%rax
  40126f:	50                   	push   %rax
  401270: 48 c7 c0 30 00 00 00 	mov    $0x30,%rax
  401277: 5f                   	pop    %rdi
  401278:	39 f8                	cmp    %edi,%eax
  40127a:	0f 96 c0             	setbe  %al
  40127d: 48 0f b6 c0          	movzbq %al,%rax
  401281:	83 f8 00             	cmp    $0x0,%eax
  401284: 74 3a                	je     4012c0 <__va_read_from_gp+0x75>
  401286: 48 8d 45 d8          	lea    -0x28(%rbp),%rax
  40128a: 48 63 00             	movslq (%rax),%rax
  40128d:	50                   	push   %rax
  40128e: 48 8d 45 dc          	lea    -0x24(%rbp),%rax
  401292: 48 63 00             	movslq (%rax),%rax
  401295:	50                   	push   %rax
  401296: 48 8d 45 e0          	lea    -0x20(%rbp),%rax
  40129a: 48 8b 00             	mov    (%rax),%rax
  40129d:	50                   	push   %rax
  40129e: 48 8d 05 a9 00 00 00 	lea    0xa9(%rip),%rax        # 40134e <__va_read_from_stack>
  4012a5: 5f                   	pop    %rdi
  4012a6: 5e                   	pop    %rsi
  4012a7: 5a                   	pop    %rdx
  4012a8: 49 89 c2             	mov    %rax,%r10
  4012ab: 48 c7 c0 00 00 00 00 	mov    $0x0,%rax
  4012b2: 41 ff d2             	call   *%r10
  4012b5: 48 83 c4 00          	add    $0x0,%rsp
  4012b9: e9 8b 00 00 00       	jmp    401349 <__va_read_from_gp+0xfe>
  4012be: eb 00                	jmp    4012c0 <__va_read_from_gp+0x75>
  4012c0: 48 c7 c1 08 00 00 00 	mov    $0x8,%rcx
  4012c7: 48 8d 7d f0          	lea    -0x10(%rbp),%rdi
  4012cb: b0 00                	mov    $0x0,%al
  4012cd: f3 aa                	rep stos %al,(%rdi)
  4012cf: 48 8d 45 f0          	lea    -0x10(%rbp),%rax
  4012d3: 50                   	push   %rax
  4012d4: 48 c7 c0 01 00 00 00 	mov    $0x1,%rax
  4012db: 50                   	push   %rax
  4012dc: 48 8d 45 e0          	lea    -0x20(%rbp),%rax
  4012e0: 48 8b 00             	mov    (%rax),%rax
  4012e3: 48 83 c0 00          	add    $0x0,%rax
  4012e7: 48 63 00             	movslq (%rax),%rax
  4012ea: 89 c0                	mov    %eax,%eax
  4012ec: 5f                   	pop    %rdi
  4012ed: 48 0f af c7          	imul   %rdi,%rax
  4012f1: 50                   	push   %rax
  4012f2: 48 8d 45 e0          	lea    -0x20(%rbp),%rax
  4012f6: 48 8b 00             	mov    (%rax),%rax
  4012f9: 48 83 c0 10          	add    $0x10,%rax
  4012fd: 48 8b 00             	mov    (%rax),%rax
  401300: 5f                   	pop    %rdi
  401301: 48 01 f8             	add    %rdi,%rax
  401304: 5f                   	pop    %rdi
  401305: 48 89 07             	mov    %rax,(%rdi)
  401308: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  40130c: 50                   	push   %rax
  40130d: 48 8d 45 e0          	lea    -0x20(%rbp),%rax
  401311: 48 8b 00             	mov    (%rax),%rax
  401314: 5f                   	pop    %rdi
  401315: 48 89 07             	mov    %rax,(%rdi)
  401318: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  40131c: 48 8b 00             	mov    (%rax),%rax
  40131f: 48 83 c0 00          	add    $0x0,%rax
  401323: 50                   	push   %rax
  401324: 48 c7 c0 08 00 00 00 	mov    $0x8,%rax
  40132b: 50                   	push   %rax
  40132c: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  401330: 48 8b 00             	mov    (%rax),%rax
  401333: 48 83 c0 00          	add    $0x0,%rax
  401337: 48 63 00             	movslq (%rax),%rax
  40133a: 5f                   	pop    %rdi
  40133b: 01 f8                	add    %edi,%eax
  40133d: 5f                   	pop    %rdi
  40133e: 89 07                	mov    %eax,(%rdi)
  401340: 48 8d 45 f0          	lea    -0x10(%rbp),%rax
  401344: 48 8b 00             	mov    (%rax),%rax
  401347: eb 00                	jmp    401349 <__va_read_from_gp+0xfe>
  401349: 48 89 ec             	mov    %rbp,%rsp
  40134c: 5d                   	pop    %rbp
  40134d:	c3                   	ret

000000000040134e <__va_read_from_stack>:
  40134e: 55                   	push   %rbp
  40134f: 48 89 e5             	mov    %rsp,%rbp
  401352: 48 83 ec 20          	sub    $0x20,%rsp
  401356: 48 89 65 f0          	mov    %rsp,-0x10(%rbp)
  40135a: 48 89 7d e8          	mov    %rdi,-0x18(%rbp)
  40135e: 89 75 e4             	mov    %esi,-0x1c(%rbp)
  401361: 89 55 e0             	mov    %edx,-0x20(%rbp)
  401364: 48 c7 c1 08 00 00 00 	mov    $0x8,%rcx
  40136b: 48 8d 7d f8          	lea    -0x8(%rbp),%rdi
  40136f: b0 00                	mov    $0x0,%al
  401371: f3 aa                	rep stos %al,(%rdi)
  401373: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  401377: 50                   	push   %rax
  401378: 48 8d 45 e8          	lea    -0x18(%rbp),%rax
  40137c: 48 8b 00             	mov    (%rax),%rax
  40137f: 48 83 c0 08          	add    $0x8,%rax
  401383: 48 8b 00             	mov    (%rax),%rax
  401386: 5f                   	pop    %rdi
  401387: 48 89 07             	mov    %rax,(%rdi)
  40138a: 48 8d 45 e0          	lea    -0x20(%rbp),%rax
  40138e: 48 63 00             	movslq (%rax),%rax
  401391: 50                   	push   %rax
  401392: 48 c7 c0 08 00 00 00 	mov    $0x8,%rax
  401399: 5f                   	pop    %rdi
  40139a: 39 f8                	cmp    %edi,%eax
  40139c: 0f 9c c0             	setl   %al
  40139f: 48 0f b6 c0          	movzbq %al,%rax
  4013a3: 83 f8 00             	cmp    $0x0,%eax
  4013a6: 74 54                	je     4013fc <__va_read_from_stack+0xae>
  4013a8: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  4013ac: 50                   	push   %rax
  4013ad: 48 c7 c0 10 00 00 00 	mov    $0x10,%rax
  4013b4: 48 63 c0             	movslq %eax,%rax
  4013b7: 50                   	push   %rax
  4013b8: 48 c7 c0 10 00 00 00 	mov    $0x10,%rax
  4013bf: 48 63 c0             	movslq %eax,%rax
  4013c2: 50                   	push   %rax
  4013c3: 48 c7 c0 01 00 00 00 	mov    $0x1,%rax
  4013ca: 50                   	push   %rax
  4013cb: 48 c7 c0 0f 00 00 00 	mov    $0xf,%rax
  4013d2: 48 63 c0             	movslq %eax,%rax
  4013d5: 5f                   	pop    %rdi
  4013d6: 48 0f af c7          	imul   %rdi,%rax
  4013da: 50                   	push   %rax
  4013db: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  4013df: 48 8b 00             	mov    (%rax),%rax
  4013e2: 5f                   	pop    %rdi
  4013e3: 48 01 f8             	add    %rdi,%rax
  4013e6: 5f                   	pop    %rdi
  4013e7: 48 c7 c2 00 00 00 00 	mov    $0x0,%rdx
  4013ee: 48 f7 f7             	div    %rdi
  4013f1: 5f                   	pop    %rdi
  4013f2: 48 0f af c7          	imul   %rdi,%rax
  4013f6: 5f                   	pop    %rdi
  4013f7: 48 89 07             	mov    %rax,(%rdi)
  4013fa: eb 00                	jmp    4013fc <__va_read_from_stack+0xae>
  4013fc: 48 8d 45 e8          	lea    -0x18(%rbp),%rax
  401400: 48 8b 00             	mov    (%rax),%rax
  401403: 48 83 c0 08          	add    $0x8,%rax
  401407: 50                   	push   %rax
  401408: 48 c7 c0 08 00 00 00 	mov    $0x8,%rax
  40140f: 48 63 c0             	movslq %eax,%rax
  401412: 50                   	push   %rax
  401413: 48 c7 c0 08 00 00 00 	mov    $0x8,%rax
  40141a: 48 63 c0             	movslq %eax,%rax
  40141d: 50                   	push   %rax
  40141e: 48 c7 c0 07 00 00 00 	mov    $0x7,%rax
  401425: 48 63 c0             	movslq %eax,%rax
  401428: 50                   	push   %rax
  401429: 48 8d 45 e4          	lea    -0x1c(%rbp),%rax
  40142d: 48 63 00             	movslq (%rax),%rax
  401430: 48 63 c0             	movslq %eax,%rax
  401433: 50                   	push   %rax
  401434: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  401438: 48 8b 00             	mov    (%rax),%rax
  40143b: 5f                   	pop    %rdi
  40143c: 48 01 f8             	add    %rdi,%rax
  40143f: 5f                   	pop    %rdi
  401440: 48 01 f8             	add    %rdi,%rax
  401443: 5f                   	pop    %rdi
  401444: 48 c7 c2 00 00 00 00 	mov    $0x0,%rdx
  40144b: 48 f7 f7              div    %rdi
  40144e: 5f                   	pop    %rdi
  40144f: 48 0f af c7          	imul   %rdi,%rax
  401453: 5f                   	pop    %rdi
  401454: 48 89 07             	mov    %rax,(%rdi)
  401457: 48 8d 45 f8          	lea    -0x8(%rbp),%rax
  40145b: 48 8b 00             	mov    (%rax),%rax
  40145e: eb 00                	jmp    401460 <__va_read_from_stack+0x112>
  401460: 48 89 ec             	mov    %rbp,%rsp
  401463: 5d                   	pop    %rbp
  401464: c3                   	ret

Дизассемблирование раздела .fini:

0000000000401468 <_fini>:
  401468: f3 0f 1e fa          	endbr64
  40146c: 48 83 ec 08          	sub    $0x8,%rsp
  401470: 48 83 c4 08          	add    $0x8,%rsp
  401474: c3                   	ret
me@me-Aspire-5742G:~/Документы/rusi/rusi$ 
me@me-Aspire-5742G:~/Документы/rusi/rusi$ objdump -d привет_gcc

привет_gcc:     формат файла elf64-x86-64


Дизассемблирование раздела .init:

0000000000401000 <_init>:
  401000: f3 0f 1e fa          	endbr64
  401004: 48 83 ec 08          	sub    $0x8,%rsp
  401008: 48 8b 05 d1 2f 00 00 	mov    0x2fd1(%rip),%rax        # 403fe0 <__gmon_start__>
  40100f: 48 85 c0             	test   %rax,%rax
  401012: 74 02                	je     401016 <_init+0x16>
  401014: ff d0                	call   *%rax
  401016: 48 83 c4 08          	add    $0x8,%rsp
  40101a: c3                   	ret

Дизассемблирование раздела .plt:

0000000000401020 <puts@plt-0x10>:
  401020: ff 35 ca 2f 00 00    	push   0x2fca(%rip)        # 403ff0 <_GLOBAL_OFFSET_TABLE_+0x8>
  401026: ff 25 cc 2f 00 00    	jmp    *0x2fcc(%rip)        # 403ff8 <_GLOBAL_OFFSET_TABLE_+0x10>
  40102c: 0f 1f 40 00          	nopl   0x0(%rax)

0000000000401030 <puts@plt>:
  401030: ff 25 ca 2f 00 00    	jmp    *0x2fca(%rip)        # 404000 <puts@GLIBC_2.2.5>
  401036: 68 00 00 00 00       	push   $0x0
  40103b: e9 e0 ff ff ff       	jmp    401020 <_init+0x20>

Дизассемблирование раздела .text:

0000000000401040 <main>:
  401040: 48 83 ec 08          	sub    $0x8,%rsp
  401044: bf 04 20 40 00       	mov    $0x402004,%edi
  401049: e8 e2 ff ff ff       	call   401030 <puts@plt>
  40104e: 31 c0                	xor    %eax,%eax
  401050: 48 83 c4 08          	add    $0x8,%rsp
  401054: c3                   	ret
  401055: 66 2e 0f 1f 84 00 00 	cs nopw 0x0(%rax,%rax,1)
  40105c: 00 00 00 
  40105f: 90                   	nop

0000000000401060 <_start>:
  401060: f3 0f 1e fa          	endbr64
  401064: 31 ed                	xor    %ebp,%ebp
  401066: 49 89 d1             	mov    %rdx,%r9
  401069: 5e                   	pop    %rsi
  40106a: 48 89 e2             	mov    %rsp,%rdx
  40106d: 48 83 e4 f0          	and    $0xfffffffffffffff0,%rsp
  401071: 50                   	push   %rax
  401072: 54                   	push   %rsp
  401073: 45 31 c0             	xor    %r8d,%r8d
  401076: 31 c9                	xor    %ecx,%ecx
  401078: 48 c7 c7 40 10 40 00 	mov    $0x401040,%rdi
  40107f: ff 15 53 2f 00 00    	call   *0x2f53(%rip)        # 403fd8 <__libc_start_main@GLIBC_2.34>
  401085: f4                   	hlt
  401086: 66 2e 0f 1f 84 00 00 	cs nopw 0x0(%rax,%rax,1)
  40108d: 00 00 00 

0000000000401090 <_dl_relocate_static_pie>:
  401090: f3 0f 1e fa          	endbr64
  401094: c3                   	ret
  401095: 66 2e 0f 1f 84 00 00 	cs nopw 0x0(%rax,%rax,1)
  40109c: 00 00 00 
  40109f: 90                   	nop

00000000004010a0 <deregister_tm_clones>:
  4010a0: b8 18 40 40 00       	mov    $0x404018,%eax
  4010a5: 48 3d 18 40 40 00    	cmp    $0x404018,%rax
  4010ab: 74 13                	je     4010c0 <deregister_tm_clones+0x20>
  4010ad: b8 00 00 00 00       	mov    $0x0,%eax
  4010b2: 48 85 c0             	test   %rax,%rax
  4010b5: 74 09                	je     4010c0 <deregister_tm_clones+0x20>
  4010b7: bf 18 40 40 00       	mov    $0x404018,%edi
  4010bc: ff e0                	jmp    *%rax
  4010be: 66 90                	xchg   %ax,%ax
  4010c0: c3                   	ret
  4010c1: 0f 1f 40 00          	nopl   0x0(%rax)
  4010c5: 66 66 2e 0f 1f 84 00 	data16 cs nopw 0x0(%rax,%rax,1)
  4010cc: 00 00 00 00 

00000000004010d0 <register_tm_clones>:
  4010d0: be 18 40 40 00       	mov    $0x404018,%esi
  4010d5: 48 81 ee 18 40 40 00 	sub    $0x404018,%rsi
  4010dc: 48 89 f0             	mov    %rsi,%rax
  4010df: 48 c1 ee 3f          	shr    $0x3f,%rsi
  4010e3: 48 c1 f8 03          	sar    $0x3,%rax
  4010e7: 48 01 c6             	add    %rax,%rsi
  4010ea: 48 d1 fe             	sar    $1,%rsi
  4010ed: 74 11                	je     401100 <register_tm_clones+0x30>
  4010ef: b8 00 00 00 00       	mov    $0x0,%eax
  4010f4: 48 85 c0             	test   %rax,%rax
  4010f7: 74 07                	je     401100 <register_tm_clones+0x30>
  4010f9: bf 18 40 40 00       	mov    $0x404018,%edi
  4010fe: ff e0                	jmp    *%rax
  401100: c3                   	ret
  401101: 0f 1f 40 00          	nopl   0x0(%rax)
  401105: 66 66 2e 0f 1f 84 00 	data16 cs nopw 0x0(%rax,%rax,1)
  40110c: 00 00 00 00 

0000000000401110 <__do_global_dtors_aux>:
  401110: f3 0f 1e fa          	endbr64
  401114: 80 3d fd 2e 00 00 00 	cmpb   $0x0,0x2efd(%rip)        # 404018 <__TMC_END__>
  40111b: 75 13                	jne    401130 <__do_global_dtors_aux+0x20>
  40111d: 55                   	push   %rbp
  40111e: 48 89 e5             	mov    %rsp,%rbp
  401121: e8 7a ff ff ff       	call   4010a0 <deregister_tm_clones>
  401126: c6 05 eb 2e 00 00 01 	movb   $0x1,0x2eeb(%rip)        # 404018 <__TMC_END__>
  40112d: 5d                   	pop    %rbp
  40112e: c3                   	ret
  40112f: 90                   	nop
  401130: c3                   	ret
  401131: 0f 1f 40 00          	nopl   0x0(%rax)
  401135: 66 66 2e 0f 1f 84 00 	data16 cs nopw 0x0(%rax,%rax,1)
  40113c: 00 00 00 00 

0000000000401140 <frame_dummy>:
  401140: f3 0f 1e fa          	endbr64
  401144: eb 8a                	jmp    4010d0 <register_tm_clones>

Дизассемблирование раздела .fini:

0000000000401148 <_fini>:
  401148: f3 0f 1e fa          	endbr64
  40114c: 48 83 ec 08          	sub    $0x8,%rsp
  401150: 48 83 c4 08          	add    $0x8,%rsp
  401154: c3                   	ret
me@me-Aspire-5742G:~/Документы/rusi/rusi$
📌 Еще один тестовый пример на плюсах
класс Фигура {
открыт:
    вирт пусто описать() {
        std::cout << "Фигура" << std::endl;
    }
    вирт ~Фигура() {}
};

класс Круг : открыт Фигура {
открыт:
    двойн радиус;
    Круг(двойн р) : радиус(р) {}
    пусто описать() override {
        std::cout << "Круг радиусом " << радиус << std::endl;
    }
};

шаблон<имя_типа T>
T удвоить(T значение) {
    возврат значение * 2;
}

цел главн() {
    Круг к(5.0);
    к.описать();

    std::cout << "Удвоенное 21 = " << удвоить(21) << std::endl;
    std::cout << "Удвоенное 1.5 = " << удвоить(1.5) << std::endl;

    возврат 0;
}
me@me-Aspire-5742G:/usr/local/gcc-rus/bin/g++ -std=c++20 /tmp/руси_плюс_плюс.cpp -o /tmp/руси_плюс_плюс 2>&1 | head -30
me@me-Aspire-5742G:~/RUSI-build/rgcc/тесты$ /tmp/руси_плюс_плюс
Круг радиусом 5
Удвоенное 21 = 42
Удвоенное 1.5 = 3

Промпты для анализа статьи

Тем, кто хочет извлечь дополнительную информацию для размышлений или почерпнуть филосовских и технических взглядов на проект. Загружаем текст статьи в контекст и просим:

Оценку с позиции кибернетики.
Анализ с позиции ТРИЗ.
Провести анализ текста с позиций эвристики.
Анализ написанного с позиции теории систем.
Оценить написанное с позиции философии open source.
Оценка с позиций аналитической философии техники.

Послесловие

Этот проект начинался как спортивный интерес. «Смогу ли я одолеть GCC?» Смог, получилось, заработало. И результат радует.

Из нишевого форка chibicc выросли три оригинальных синтаксиса: Руси (Си), Руси++ (C++), Объектный-Руси (Objective-C). Все три - промышленного уровня, на базе GCC 14.2.

Это не «русский язык программирования с нуля». Это теперь двойной Си. Это билингвальный интерфейс к существующему языку. Не «вместо», а «вместе».

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.