Интерпретатор Python в 1024 байта показывает не размер Python, а минимальный набор решений, после которого текст уже кажется знакомым языком. Остин Хенли вручную написал на C крошечное подмножество с отступами, условиями, циклами и функциями. Эксперимент отлично объясняет устройство интерпретатора именно потому, что почти всё привычное пришлось выбросить.
6 сентября 2026 года Хенли опубликовал исходник и рассказ о код-гольфе. Первая цель в 512 байт оказалась слишком жёсткой: простой калькулятор уже занимал лимит, но ещё не выглядел как Python. Тогда автор поднял границу до 1024 байт, сначала собрал читаемую версию объёмом более 4800 байт, а потом сокращал имена, проверки и промежуточные действия. Итог умеет запустить ограниченный FizzBuzz, однако не претендует на совместимость с обычными Python-программами.
Минимальный лексический слой двигает позицию по исходнику и сохраняет значимые отступы.
Небольшие функции разбирают числа, операции, сравнения и блоки.
Парсер вычисляет выражения по ходу чтения, без отдельного байткода.

Интерпретатор Python в 1024 байта: три слоя без лишнего
Программа читает исходный текст посимвольно. Большинство пробелов удаляется заранее, но отступы строк и пробелы внутри строковых литералов сохраняются. Отдельного полноценного токенизатора нет: текущий символ и позиция выполняют роль очень простого лексического состояния. Массив целых чисел используется как таблица символов. Это возможно из-за строгого правила: имя переменной или функции состоит из одной строчной буквы.
Выражения разбираются рекурсивным спуском. Один уровень отвечает за числа и переменные, следующий за умножение и остаток, затем идут сложение и сравнение. Приоритет операций получается из порядка вызовов. Но вместо построения абстрактного синтаксического дерева значение вычисляется сразу. Такой ход экономит структуру данных и код обхода, зато усложняет повторное выполнение.
символы исходника
↓
разбор выражения по приоритету
↓
немедленное изменение таблицы переменных
↓
переход к следующей строке
Циклы раскрывают цену прямого выполнения. После тела while или for интерпретатор возвращает позицию назад и заново разбирает условие и блок. Функции используют похожий трюк: таблица запоминает позицию определения, вызов временно прыгает к телу, а затем возвращает позицию вызывающего кода. Вложенные блоки опираются на стек вызовов самого C.
Конфигуратор бюджета: что оставить в мини-языке
Выберите ограничение эксперимента
Это учебная модель компромиссов. Полосы не равны реальной стоимости функций в байтах: точные размеры зависят от кода, компилятора и правил соревнования.
- Можно оставить арифметическое ядро
- Python-похожесть быстро теряется
- Условия и блоки конкурируют за место
- От идеи 512 байт автор отказался
- Целые числа и присваивание
- Арифметика с приоритетом
if,else,while,for- Функции без аргументов
- Однобуквенные имена
- Нет обработки ошибок
- Токены с координатами
- Понятное дерево разбора
- Диагностика неверного ввода
- Тесты каждого слоя
- Нормальные имена и структуры
- Документированная грамматика
Что именно поместилось, а что исчезло
По списку автора версия на 1024 байта поддерживает целочисленные литералы и переменные, присваивание, операции +, -, * и %, одно сравнение в выражении, целочисленную истинность, условия, циклы, функции без аргументов, рекурсивные вызовы, блоки по отступам, простой print и комментарии. Некоторые детали намеренно не совпадают с Python. Например, области видимости отсутствуют, унарные знаки ограничены, а печать принимает лишь один строковый литерал или целочисленное выражение.
Самая большая уступка касается ошибок. Интерпретатор предполагает, что ключевые слова написаны правильно, границы токенов уже корректны, а программа соответствует ожидаемой форме. Неверный ввод не получает полезного сообщения со строкой, колонкой и объяснением. Для код-гольфа это допустимое правило игры. Для учебного проекта такая экономия мешает: хороший парсер должен сообщать, что ожидал и что встретил.

Почему это не «весь Python»
Официальный справочник Python отдельно описывает лексический анализ, модель данных, выполнение, импорт, выражения, простые и составные инструкции, функции, классы, корутины и полную грамматику. Язык задаётся не только набором узнаваемых ключевых слов. Нужны правила объектов и типов, связывания имён, исключений, областей видимости, итерации, контекстных менеджеров и множества других конструкций.
CPython, основная реализация языка, идёт более длинным путём. В объяснении Хенли он токенизирует текст, строит AST, выполняет анализ и оптимизации, создаёт байткод и затем исполняет его. Репозиторий CPython также содержит стандартную библиотеку, тесты, инструменты сборки, платформенный код и документацию. Сравнивать их объём с одним гольф-файлом бессмысленно: они решают разные задачи и дают разные гарантии.
| Слой | В эксперименте | В полноценной реализации |
|---|---|---|
| Имена | Одна строчная буква и прямой индекс массива | Идентификаторы, области видимости и правила связывания |
| Синтаксис | Небольшой ручной парсер | Полная грамматика и точные позиции токенов |
| Выполнение | Вычисление во время разбора | Промежуточное представление и среда выполнения |
| Ошибки | Вход заранее считается корректным | Исключения и диагностические сообщения |
Как повторить идею без код-гольфа
Начните с четырёх правил: целое число, сложение, переменная и команда печати. Запишите грамматику обычным текстом, а затем сделайте функцию чтения текущего символа. После первого работающего выражения добавьте приоритет умножения. Для каждой новой конструкции заранее придумайте корректный пример и ошибку: незакрытую скобку, неизвестное имя или неожиданный символ.
Следующий шаг состоит не в сокращении имён, а в разделении ответственности. Лексер возвращает токены, парсер строит небольшие узлы, интерпретатор обходит их и хранит окружение. Так можно распечатать дерево для строки x = 1 + 2 * 3 и увидеть, почему умножение выполняется раньше. Когда эта версия покрыта тестами, полезно отдельно попробовать прямое выполнение и сравнить сложность циклов.
Это настоящий Python?
Это намеренно ограниченный Python-подобный язык. Он узнаваем по синтаксису, но не реализует полную семантику и совместимость.
Зачем заново разбирать цикл?
Отдельного AST или байткода нет. Возврат позиции к условию позволяет повторить блок с минимальным количеством состояния.
Почему нельзя использовать такой код в приложении?
Он оптимизирован под размер и корректный демонстрационный ввод. В нём нет нужной диагностики, совместимости и защитных проверок.
Подробности эксперимента опубликованы в блоге Остина Хенли. Для точной семантики сверяйтесь со справочником языка, а устройство основной реализации исследуйте в репозитории CPython.
Продолжить разбор языка
Синтаксис и функции можно закрепить на курсе Python. Затем сравните путь от старого языка в статье от Basic к Python, проверьте базовые понятия по вопросам Python junior и потренируйте декомпозицию на алгоритмических задачах. Попробуйте описать свой мини-язык пятью правилами до написания первой функции.