Size: a a a

Compiler Development

2020 May 19

А

Алексей in Compiler Development
А может быть и нет, зависит от реализации. Есть те же обратные поправки к примеру, чтобы два раза не проходить.
источник

SS

Sergey Sverdlov in Compiler Development
Алексей
У языка ассемблера - нет. У ассемблера - может быть есть.
Так разговор именно о разнице двух понятий: "ассемблер" и "язык ассемблера". В анонсе это в намеренно-вызывающей форме написано, а в самой лекции подробно и корректно разъясняется.
источник

А

Алексей in Compiler Development
а, хорошо
источник

А

Алексей in Compiler Development
кликбейт в анонсе
источник

SS

Sergey Sverdlov in Compiler Development
Алексей
кликбейт в анонсе
Да, вроде, это так называется :)
источник

p

polunin.ai in Compiler Development
Alexander Tchitchigin
Нет, мне непонятна позиция "не хочу читать книги на 800 страниц — расскажите мне персонально как-нибудь быстро и просто". Если бы можно было проще — не писали бы книги на 800 страниц.
Хехе. Учитывая что гайд по с# полный 1100 страниц, а укороченный 200 (туда попали все фичи, просто урезали объяснения), то можно. И мне кажется такой формат самый лучший. Когда даётся краткое объяснение и общая концепция, а если непонятно то даются линки на полные объяснения. Не знаю как вам, мне практически всегда достаточно пару предложений чтобы вникнуть в тему. Ещё пара чтобы понять зачем, и примерно полстраницы-страница как это на практике реализовывается. Лучше писать меньше предложений но загружать больше смысла в них.
источник
2020 May 20

M

MaxGraey in Compiler Development
MaxGraey
Ктонибудь знает эффективный алгоритм вычисления целочисленного логарифма с произвольным основанием? Требования достаточно необычные - нельзя использовать плавающую арифметику ну алготим должен быть как можно более бысртым и корректно отрабатывать всегда. Например первое что приходит в голову это:

ilogb(n: u64, base: i32) {
 t = u64(base)
 e = 1
 while (t <= n) {
   t *= base
   e += 1
 }
 return e
}

Но у него есть проблема с переполнением например ilogb(u64(-1), 2) провалиться в бесконечный цикл из-за переполнения после умножения. Если добавить проверку на переполнение то это + 1 деление, +1 проверка условия в цикле, все это выходит очень недешево для base = 2, 3 …
Да base находиться в промежутке [2, 36].

Все это нужно для подсчета колличества цифр необходимых для представления в виде строки.
Я встречал подход еще с бинарным поиском, но он требует возведения в степень и все это в цикле, в общем тоже весьма сомнительное удовольствие
В общем нашел сбалансированное решение без таблиц и пр. Есди base это POT (степень двойки) что самый частый случай то вычисляется вообще за O(1), в остальных случаях это что вроде O( log B ) где B - это колличество значащих бит. Выглядит это так:

if ((base & (base - 1)) == 0) {
   return (63 - <u32>clz(num)) / (31 - <u32>clz(base)) + 1;
 }
 var b64 = u64(base), b = b64, e: u32 = 1;
 while (num >= b) {
   num /= b;
   b *= b;
   e <<= 1;
 }
 if (num == 2) return e;
 while (num >= 1) {
   num /= b64;
   e++;
 }
 return e - 1;

И требует от 1 до ~17 делений для 64-бит (в наихудших и очень редких случаях
источник

BD

Berkus Decker in Compiler Development
Artyom Drozdov
ну тогда зачем им раст?)
Это у них надо спросить.
источник

Т8

Т-34 85 in Compiler Development
Кто-нибудь смотрел шаблоны D? Что там интересного приготовил Александреску, чего нет в C++?
источник

АГ

Алексей Герасимов... in Compiler Development
Т-34 85
Кто-нибудь смотрел шаблоны D? Что там интересного приготовил Александреску, чего нет в C++?
то же что и в c++, утиная типизация, но они более гибкие, можно в качестве параметров лямбды использовать (всякие filter/map пишутся как map!(x=>x+1)(myVec), первые скобки это типовые параметры), просто другие функции, можно делать баунды в императивном стиле (типа int foo(T)(T a, T b) if __compiles(a+b), функцию можно будет вызвать только если значения типа T можно складывать, ну и там еще есть всякие traits которые как предикаты на типах), миксины опять же, можно собрать строку дишного кода и втавить в любое место программы, а ля
auto a = 1;
mixin(«auto b = a*2»);
auto c = b - 1;

CTFE (compile-time function execution) довольно мощный, можно в функции на этапе компиляции с помощью statis if/static switch собрать ее тело в зависимости от свойств типовых параметров
источник

Т8

Т-34 85 in Compiler Development
Алексей Герасимов
то же что и в c++, утиная типизация, но они более гибкие, можно в качестве параметров лямбды использовать (всякие filter/map пишутся как map!(x=>x+1)(myVec), первые скобки это типовые параметры), просто другие функции, можно делать баунды в императивном стиле (типа int foo(T)(T a, T b) if __compiles(a+b), функцию можно будет вызвать только если значения типа T можно складывать, ну и там еще есть всякие traits которые как предикаты на типах), миксины опять же, можно собрать строку дишного кода и втавить в любое место программы, а ля
auto a = 1;
mixin(«auto b = a*2»);
auto c = b - 1;

CTFE (compile-time function execution) довольно мощный, можно в функции на этапе компиляции с помощью statis if/static switch собрать ее тело в зависимости от свойств типовых параметров
Здорово. А там constexpr if дружит со static_assert (static if со static assert соответственно, как я понимаю)?
В C++ static_assert проверяется в первую очередь, поэтому его невозможно поместить внутрь блока constexpr if, приходится придумывать какие-то костыли для обхода ограничений.
источник

АГ

Алексей Герасимов... in Compiler Development
Т-34 85
Здорово. А там constexpr if дружит со static_assert (static if со static assert соответственно, как я понимаю)?
В C++ static_assert проверяется в первую очередь, поэтому его невозможно поместить внутрь блока constexpr if, приходится придумывать какие-то костыли для обхода ограничений.
типа такого https://run.dlang.io/is/XjDzkM ?
источник

Т8

Т-34 85 in Compiler Development
Ага, оно! Спасибо, буду ковырять
источник

OK

Oleg Kovalov in Compiler Development
sup
источник

K

Kir in Compiler Development
TGG
Слышу часто такой ответ. Почему?
ADT почти идеальны для описания AST. Свёртка дерева (Data.Fix, recursion-schemes) подходит для операций над деревом. Композиция функций (и стрелок) подходит для соединения стадий компилятора. Да и просто язык удобный.
источник

PS

Peter Sovietov in Compiler Development
Kir
ADT почти идеальны для описания AST. Свёртка дерева (Data.Fix, recursion-schemes) подходит для операций над деревом. Композиция функций (и стрелок) подходит для соединения стадий компилятора. Да и просто язык удобный.
ADT "идеальны" лишь в том смысле, что похожи на БНФ-нотацию. Остальные тезисы, скорее, напоминают о желании поставить "телегу впереди лошади". Это в духе нашего прошлого спора на тему подходящего ЯП для разработки компиляторов. Кажется, никто всерьез не пробовал начать с выбора ключевых околокомпиляторных нотаций и алгоритмов.
источник

M

MaxGraey in Compiler Development
Вообще не важно на чем писать компилятор. Хоть на JavaScript:
https://github.com/moonad/Formality

Главное что бы это было продуктивно)
источник

Т8

Т-34 85 in Compiler Development
MaxGraey
Вообще не важно на чем писать компилятор. Хоть на JavaScript:
https://github.com/moonad/Formality

Главное что бы это было продуктивно)
А насколько важен self-hosting?
источник

M

MaxGraey in Compiler Development
Т-34 85
А насколько важен self-hosting?
Вообще не важен, особенно на начальном этапе
источник

AT

Alexander Tchitchigi... in Compiler Development
Peter Sovietov
ADT "идеальны" лишь в том смысле, что похожи на БНФ-нотацию. Остальные тезисы, скорее, напоминают о желании поставить "телегу впереди лошади". Это в духе нашего прошлого спора на тему подходящего ЯП для разработки компиляторов. Кажется, никто всерьез не пробовал начать с выбора ключевых околокомпиляторных нотаций и алгоритмов.
ADT идеальны в том смысле, что определяютя индуктивно, а деревья — такая штука, которая определяется индуктивно. Ну и обрабатываются и те, и другие, соответственно, рекурсивно.
источник