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

Статья посвящена системному программированию на русском языке с 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) | инструкции, метки, директивы |
Бинарь | байты | готовая программа |
Что изменено
Только первые два преобразования:
Исходник → лексемы (лексер
libcpp)Лексемы → 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++ с русским синтаксисом. Значит:
Берём исходники RuC
Заменяем ключевые слова на русские (
class→класс,int→цел,return→возврат)Собираем через РУСИ++
Получаем тот же самый 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)
Русификация стандартной библиотеки
Написание документации
Если кто размышлял о создании кириллического системного ЯП, то вот он - готовый, рабочий, всамделишный. Бонусом - инструкция по настройке раскладки, чтоб не переключать язык для скобок.
Ссылки
Программисты на Руси программируют на Си. RUSI: Концепт билингвального компилятора
Сфера - полностью кириллический язык программирования: от «Привет, мир» до HTTP-сервера и bare-metal
Бонус: фигурные скобки в русской раскладке
Проблема
Стандартная русская раскладка в 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+AltGrbraceleft/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.
Это не «русский язык программирования с нуля». Это теперь двойной Си. Это билингвальный интерфейс к существующему языку. Не «вместо», а «вместе».
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.