Как стать автором
Обновить
37.75

Компиляторы *

Из исходного кода в машинный

Сначала показывать
Порог рейтинга
Уровень сложности

Это слишком опасно для C++

Время на прочтение 6 мин
Количество просмотров 32K

Некоторые паттерны стало возможно использовать на практике только благодаря безопасности Rust по памяти, а на C++ они слишком опасны. В статье приведён один такой пример.

Работая над внутренней библиотекой, написанной на Rust, я создал тип ошибок для парсера, у которых должна быть возможность сделать Clone без дублирования внутренних данных. В Rust для этого требуется указатель с подсчётом ссылок (reference-counted pointer) наподобие Rc.

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

Читать далее
Всего голосов 67: ↑55 и ↓12 +43
Комментарии 108

Новости

Митап по С++ в Питере и онлайн: цена абстракции, статический анализ и дискуссия о код-ревью

Уровень сложности Простой
Время на прочтение 2 мин
Количество просмотров 1.2K

20 марта собираемся на бесплатном митапе в Санкт-Петербурге и онлайн. Константин Владимиров расскажет о цене абстракции, а разработчик из команды телекома YADRO Владимир Леонтьев на примере инструмента генерации RPC-серверов покажет, как написать кодогенератор. В конце встречи создатель Sprinx Андрей Аксенов, разработчик VK AdTech Станислав Юрченко, техлид Kaspersky Александр Еналдиев и разработчик YADRO Илья Казаков вместе с гостями и зрителями митапа обсудят тонкости код-ревью.

В этом материале делимся программой митапа. Регистрация уже открыта — переходите по ссылке и заполняйте форму, чтобы присоединиться к мероприятию.

Читать далее
Всего голосов 9: ↑8 и ↓1 +7
Комментарии 0

Создание собственного компилятора

Уровень сложности Средний
Время на прочтение 17 мин
Количество просмотров 13K

В сети не так много короткой информации по написанию компиляторов, оформленных в виде краткой статьи, поэтому я решил попробовать восполнить этот пробел.

В рамках данной статьи будет написан простой компилятор на C++, транслирующий код в ассемблер для MS-DOS, а также опробован на реальных боевых задачах.

Читать далее
Всего голосов 23: ↑22 и ↓1 +21
Комментарии 39

Как устроен языковой сервер

Время на прочтение 7 мин
Количество просмотров 3.7K
В этом посте я хочу прокомментировать один любопытный комментарий из базы кода rust-analyzer. Вот этот комментарий.

Здесь описан интересный рекурсивный алгоритм, неоднократно встречающийся в разных аспектах программирования языковых серверов. Я видел реализации такого алгоритма на Kotlin и C#, а затем сам реализовал его на Rust.

Вот, казалось бы, рандомная подборка возможностей IDE:

  • Переход к определению
  • Завершение кода
  • Прогон теста на курсоре
  • Извлечение переменной

Что общего между ними? Все эти возможности относятся к актуальному положению курсора! В данном случае вводом служит не только состояние кода в конкретный момент времени, но и конкретное расположение исходников проекта, например src/main.rs:90:2.
Читать дальше →
Всего голосов 17: ↑17 и ↓0 +17
Комментарии 2

Истории

Компилятор за выходные: избавляемся от переменных

Уровень сложности Средний
Время на прочтение 15 мин
Количество просмотров 11K

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

Продолжаем разговор о минималистичном компиляторе, который вполне реально написать за выходные. Задачей стоит транслировать код из придуманного мной языка в x86 ассемблер. Мой компилятор состоит из 611 строк кода, при этом не имеет ни единой зависимости:

ssloy@khronos:~/tinycompiler$ cat *.py|wc -l

611

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

Итак, тема сегодняшнего разговора: генерация кода на питоне без использования переменных.

Читать далее
Всего голосов 43: ↑42 и ↓1 +41
Комментарии 35

Rust 1.76.0: обновление совместимости ABI, получение имени типа из ссылки

Уровень сложности Простой
Время на прочтение 2 мин
Количество просмотров 1.3K

Команда Rust рада сообщить о новой версии языка — 1.76.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.


Если у вас есть предыдущая версия Rust, установленная через rustup, то для обновления до версии 1.76.0 вам достаточно выполнить команду:


rustup update stable

Если у вас ещё не установлен rustup, вы можете установить его с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску на GitHub.


Если вы хотите помочь нам протестировать будущие выпуски, вы можете использовать канал beta (rustup default beta) или nightly (rustup default nightly). Пожалуйста, сообщайте обо всех встреченных вами ошибках.

Читать дальше →
Всего голосов 12: ↑12 и ↓0 +12
Комментарии 2

Книга «Основы компиляции: инкрементный подход»

Время на прочтение 14 мин
Количество просмотров 4.6K
image Привет, Хаброжители!

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

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

Джереми Сик объясняет важнейшие концепции, алгоритмы и структуры данных, лежащие в основе современных компиляторов, и закладывает основу для изучения более сложных тем. Это краткое, но доступное руководство уже давно используют студенты и профессионалы.
Читать дальше →
Всего голосов 19: ↑19 и ↓0 +19
Комментарии 6

Каково это, создавать язык программирования сегодня?

Уровень сложности Средний
Время на прочтение 8 мин
Количество просмотров 16K

«Эта книга – классика. Относитесь к ней бережно».

Такую фразу произнёс архитектор из нашей команды, передавая мне The Dragon Book. Разработкой компиляторов я увлёкся где-то 15 лет назад ещё на заре своей карьеры. Как-то раз, читая эту книгу поздно вечером, я заснул, небрежно уронив её на пол. Надеюсь, владелец не заметил небольшую вмятину на обложке после того, как я ему её вернул.

Вышла эта книжка в 1986 году. В те времена создание компиляторов было крайне сложной задачей, требовавшей обладания различными навыками в области компьютерных наук в целом и программирования в частности. Теперь, почти четыре десятилетия спустя, этой задачей занимаюсь я. Насколько сложна она сегодня? Приглашаю вместе разобрать процесс создания языка и посмотреть, насколько современные инструменты его упростили.
Читать дальше →
Всего голосов 62: ↑59 и ↓3 +56
Комментарии 5

О мат-нотациях и Машинах Тьюринга

Уровень сложности Сложный
Время на прочтение 10 мин
Количество просмотров 2.3K

Всем Хабр! Совсем недавно открыл для себя некоторые прелести Латеха и начал активно в нем работать. По ходу дела возникали разные интересные мысли, которыми здесь и поделюсь. В статье пойдет речь о моих небольших дополнениях к мат-нотациям, которых мне не хватало, а также о том, как построить Машину Тьюринга с помощью оных.

Сразу оговорюсь. Да, я, конечно, знаю о том, что есть Вольфрам. Да, он содержит большую часть того, о чем пойдет речь, и еще тонну всякого-разного, чего мне не постичь за всю мою жизнь. Поэтому из первого своего прототипа этой статьи я возьму лишь самое интересное и попытаюсь рассказать так, чтобы не звучало как изобретение велосипеда. Прошу не судить строго, ибо я профан. Я лишь делюсь тем, как было бы удобно мне, возможно, кому-то тоже окажется полезным. В том числе я пишу статью, не столько, чтобы что-то рассказать, сколько чтобы быть разумно критикуемым в комментах (вместо пустых дизов).

Построить МТ
Всего голосов 6: ↑6 и ↓0 +6
Комментарии 16

Зачем делать новый язык программирования?

Уровень сложности Простой
Время на прочтение 8 мин
Количество просмотров 8.6K

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

Причин у этого явления много и, скорее всего, сделать с ним ничего нельзя, такова уж человеческая природа.

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

Попробуем разобрать мотивы, подвигающие людей на такую работу.

Читать далее
Всего голосов 21: ↑14 и ↓7 +7
Комментарии 50

Компилятор за выходные: таблицы символов

Уровень сложности Средний
Время на прочтение 9 мин
Количество просмотров 7.2K

Как водится воскресным вечером, снова я с моим компилятором. На этот раз я расскажу, как работают области видимости переменных и как перегружать функции. Это позволит нам скомпилировать демку про́клятого огня, а также я накидал фантазию на тему игрушки арканоид (скриншот на КПДВ, видео в конце статьи). Я на удивление сам долго залипал на эту анимацию :)

На всякий случай я даю код и на wend, и на C, поскольку понимаю, что код на моём языке вряд ли интересен кому-то помимо того, кто реально возьмётся за компилятор. А вот мелкий код с интересными эффектами всегда найдёт свою публику. Кстати, если у вас есть идеи на тему чего-то интересного, что можно запрограммировать в полста строчек кода, делитесь в комментариях, я внимательно слушаю!

Читать далее
Всего голосов 26: ↑26 и ↓0 +26
Комментарии 2

Делаем двоичные файлы Rust меньше по умолчанию

Уровень сложности Средний
Время на прочтение 6 мин
Количество просмотров 4.6K

Вы когда-нибудь пробовали компилировать program helloworld на Rust в режиме --release? Если да, то видели, какой размер двоичного файла получается? Достаточно сказать, что он не очень маленький. Или, по крайней мере, не был таким до недавнего времени. В этом посте я расскажу, как узнал об этой проблеме и попытался устранить её в Cargo.

Читать далее
Всего голосов 38: ↑38 и ↓0 +38
Комментарии 13

Сравнение производительности dict() и {} в Python

Уровень сложности Средний
Время на прочтение 11 мин
Количество просмотров 14K

Какое-то время назад, во время разбора кода, мы обсудили выбор dict() вместо {} в новом коде на Python. Коллега утверждал, что dict() более читаем и чётче выражает цель, поэтому следует предпочесть его. Меня это не убедило, но в тот момент контраргуентов не нашлось, поэтому я воздержался.

Это заставило меня задуматься: в чём разница между типом dict и литеральным выражением {}?

Давайте изучим этот вопрос.

Читать далее
Всего голосов 26: ↑23 и ↓3 +20
Комментарии 19

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн

Umka обрастает мясом: улучшения в языке, менеджер пакетов, применение в играх

Уровень сложности Средний
Время на прочтение 3 мин
Количество просмотров 2.1K

Только что вышла новая версия 1.3 моего встраиваемого скриптового языка Umka со статической типизацией. С момента выпуска версии 1.0 язык пополнился замыканиями, инструкцией выбора switch по фактическому типу интерфейса, тернарным условным оператором, более удобным API для взаимодействия с кодом на C, другими мелкими радостями.

Маленькое, но упрямое сообщество пользователей Umka всерьёз озаботилось библиотеками, появился менеджер пакетов UmBox, загружающий и устанавливающий библиотеки и отслеживающий их зависимости.

Umka живёт в ядре фреймворка Tophat для создания 2D игр. На основе этого фреймворка развивается платформер-головоломка SaveScum. Коллекция пробных уровней для игры была выпущена в декабре в виде адвент-календаря, принеся с собой дух простого геймерского счастья в наш проект.

Читать далее
Всего голосов 9: ↑9 и ↓0 +9
Комментарии 3

Компилятор за выходные: лексер и парсер

Уровень сложности Средний
Время на прочтение 12 мин
Количество просмотров 13K

Продолжаем разговор. На прошлой неделе я пообещал за выходные написать компилятор из простенького мной придуманного языка в ассемблер. В назначенное время уложился, и компилятор даже вроде работает, см. заглавную картинку. Теперь дело за малым, потихоньку причесать и стройно изложить. В прошлый раз я рассказал про синтаксические деревья и показал простейший транслятор в питон (по факту, обычный pretty print дерева). Но если в предыдущей статье я синтаксическое дерево строил вручную, то сегодня всё же будем автоматизировать процесс.

Сегодня я публикую две статьи разом, поскольку по дороге меня довольно круто занесло, и получился небольшой спин-офф. Очень рекомендую к прочтению :)

Ну а тема этой статьи - автоматическое построение синтаксического дерева aka лексер и парсер.

Читать далее
Всего голосов 39: ↑39 и ↓0 +39
Комментарии 44

Про́клятый огонь, или магия препроцессора C

Время на прочтение 18 мин
Количество просмотров 25K

Задавались ли вы когда-нибудь вопросом, можно ли полноценно программировать при помощи директивы #define в языке C? Полнота по Тьюрингу шаблонов C++ известна весьма широко, например, люди пишут трассировщики лучей, делающие все вычисления во время компиляции (вместо времени исполнения). А как обстоят дела с препроцессором C? Вопрос оказался сильно нетривиальнее, и эта история является, на мой вкус, отличным анекдотом для курса лекций по теории компиляторов, что я готовлю в данный момент. В частности, для лучшего понимания происходящего здесь, рекомендую ознакомиться со второй статьёй, которую я опубликовал параллельно этой: лексер и парсер.

Чтобы не было обманутых впечатлений, предупрежу сразу, что рейтрейсера не будет, но про́клятый код будет очень даже! Итак, поехали. Для начала, почему я вообще задался этим вопросом? Если обычный код компьютерной графики вам скучен, следующий раздел можно пропустить, перематывайте до последней картинки.

Читать далее
Всего голосов 169: ↑169 и ↓0 +169
Комментарии 54

К вопросу о gcc в разрезе RISCV

Уровень сложности Простой
Время на прочтение 3 мин
Количество просмотров 3.1K

Разбирался тут на досуге с (относительно) новыми МК фирмы WCH с ядром RISCV (CH32V307FBP6) с целью осветить данный прибор, скачал рекомендованную среду разработки (mounriver) и на первом же примере наткнулся на совершенно неожиданную вещь. Пример совершенно классический (нет, не мигание светодиодом и даже не приветствие миру) и посвящен использованию функции printf, вот он:

USART_Printf_Init(115200);
printf("SystemClk:%d\r\n"),SystemCoreClоck);
printf("This is printf example\r\n");

Пнп: Вы (программисты сайта) думайте, что хотите, но я считаю, что редактор у Вас ("вот это слово еще ...") омерзительный.

И что же могло удивить ?
Всего голосов 10: ↑6 и ↓4 +2
Комментарии 11

Кратко про то, как устроен компилятор Go

Время на прочтение 8 мин
Количество просмотров 7.4K

Привет, Хабр!

В back in 2007 трое гуру из Google — Роб Пайк, Кен Томпсон и Роберт Гриземер — решили, что мир нуждается в чем-то свежем и быстром. Они метили на упрощение процесса разработки, но при этом хотели сохранить весь перфоманс на уровне C. И вот, в 2009 году появился Golang.

Первые версии были далеки от совершенства, но с каждым релизом Go становился только круче. Garbage collector, goroutines, channels — эти фичи сделали Go особенным. С каждым апдейтом Go становился только быстрее и надежнее. И не забудем про экосистему — с каждым годом она росла как на дрожжах, предлагая всё новые инструменты и библиотеки.

С версии 1.5 компилятор Go сам начал компилироваться в Go. С тех пор производительность только растет. JIT, улучшения в escape analysis, введение модулей в версии 1.11 — каждая фича делала Go всё более мощным.

В последниях версиях появились дженерики, которые все так долго ждали. Это был следующий шаг в удобстве написания кода в go.

Читать далее
Всего голосов 24: ↑16 и ↓8 +8
Комментарии 8

Компилятор за выходные: синтаксические деревья

Уровень сложности Средний
Время на прочтение 11 мин
Количество просмотров 23K

Вам когда-нибудь приходилось задаваться вопросом, как работает компилятор, но так руки и не дошли разобраться? Тогда этот текст для вас. Мне тоже не доводилось заглядывать под капот, но тут так случилось, что мне нужно прочитать курс лекций о компиляторах местным третьекурсникам. Кто встречался с некомпетентными преподавателями? Здравствуйте, это я :)

Итак, чтобы самому разобраться в теме, я собираюсь написать транслятор с эзотерического языка программирования wend (сокращение от week-end), который я только что сам придумал, в обычный ассемблер. Задача уложиться в несколько сотен строк питоновского кода. Основной репозиторий живёт на гитхабе (не забудьте заглянуть в мой профиль и посмотреть другие tiny* репозитории).

Читать далее
Всего голосов 75: ↑75 и ↓0 +75
Комментарии 28

Собираем автономную игру на C# в 2 килобайтах

Уровень сложности Средний
Время на прочтение 11 мин
Количество просмотров 19K

Моё детство пришлось на эпоху 1,44-мегабайтных дискет и 56-килобитных модемов, поэтому я всегда любил маленькие программы. Раньше можно было записать на дискету кучу мелких игр и таскать её с собой. Если программа не помещалась на дискету, я задумывался, почему — в ней много графики? Есть музыка? Возможно, она выполняет много сложных операций? Или она просто раздута?

В наши дни дисковое пространство стало настолько дешёвым, что люди отказались от оптимизации по размеру.

Размер важен только при передаче: если вы передаёте программу по проводам, мегабайты равны секундам. По быстрому соединению на 100 Мбит в лучшем случае можно передать 12 МБ в секунду. Если на другом конце провода находится человек, ожидающий завершения скачивания, то разница между пятью и одной секундой может существенно повлиять на его ощущения.

Человек может зависеть от времени передачи как напрямую (пользователь, скачивающий программу по сети), так и косвенно (serverless-сервис, отвечающий на веб-запрос).

Люди обычно воспринимают всё, что длится меньше 0,1 секунды, как мгновенное, 3 секунды — это примерно тот предел, после которого прерывается состояние потока пользователя; а уж 10 секунд удержать внимание пользователя очень сложно.

Хотя уменьшение сегодня уже необязательно, оно всё равно лучше.

Эта статья задумывалась как эксперимент, позволяющий выяснить, каким может быть минимальный размер полезного автономного исполняемого файла C#. Могут ли приложения на C# достичь размеров, при которых пользователи будут ощущать их скачивание как мгновенное? Позволит ли это использовать C# там, где он не используется сейчас?
Читать дальше →
Всего голосов 128: ↑127 и ↓1 +126
Комментарии 34

Вклад авторов