ФлеймФорумПроЭкты

Ü (Programmiersprache) (95 стр)

Страницы: 194 95 96 97100 Следующая »
#1410
12:54, 27 фев 2023

/A\
> К модулям неплохо бы добавить атрибуты с лицензией кода.
Сбор лицензий - это вопрос системы сборки, а не языка. А своей системы сборки для Ü нету.

#1411
13:21, 27 фев 2023

Panzerschrek[CN]
> Сбор лицензий - это вопрос системы сборки
Не всегда, бывают случаи когда нужно скопипастить одну функцию, не делать же ее отдельной либой.

> А своей системы сборки для Ü нету.
И не будет?

#1412
13:33, 27 фев 2023

/A\
> не делать же ее отдельной либой
Делать.

+ Показать

/A\
> И не будет?
Не знаю. Пока что не вижу особой необходимости.

#1413
17:35, 4 мар 2023

Чё-то мой PR уже месяц протухает: https://reviews.llvm.org/D142386
Но тут недавно один товарищ объявился, и дескать заявляет, что ExecutionEngine ненужон.

Я кстати к этому тоже склоняюсь. У меня уже и так есть некая своя реализация интерпретатора, которая используется для constexpr функций. Возможно, проще будет её допилить и использовать в тестах, чем ждать, когда же мои изменения в llvm попадут.

#1414
12:41, 6 мар 2023

Panzerschrek[CN]
> В Компиляторе1 это ещё предстоит сделать.
Таки сделал. Это было весьма небыстро:

30 files changed, 2866 insertions(+), 2285 deletions(-)

Вообще, механизм проверки ссылок - это наверное самая сложная часть компилятора. Я его писал и переписывал несколько раз. И по ходу развития концепции и подходы несколько раз менялись.
Кроме собственно говоря статического учёта соблюдения правила количества ссылок этот механизм ещё и управляет временем жизни временных переменных, чего даже в Rust (насколько я понял) нету.

#1415
16:51, 6 мар 2023

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

var Variable local_val;
var Variable val= select( condition ? local_val : CreateComplexVal().val );

select - аналог оператора ?: из крестов. Компилятор ругался, что дескать на результат вызова CreateComplexVal() есть ещё ссылка. Хотя странно, вроде то ссылка не берётся и результат выражения это не ссылка, а значение.

  Забил я на время на эту ошибку и продолжил рефакторинг, закостылив код выше. Сегодня же к нему вернулся. Оказалось, всё гораздо хитрее. Поскольку обе ветви оператора select ссылочные, результат этого оператора является ссылочным, а уж потом он используется для инициализации локальной переменной значения. Но откуда же ошибка? А она оттуда, что после вычисления ветвей оператора select разрушаются временные переменные каждой ветви. Сначала я подумал, что это ошибка и отключил этот код. Но тут начали падать тесты. Я понял, что это неспроста.
  Подумав, я понял, зачем так было сделано. Дело в том, что оператор select содержит ветвление. А это значит, что в процессе выполнения программы будут созданы разные переменные в разных ветвях. И разрушать их придётся в этих же ветвях, ибо иначе не будет понятно, что создано и что нет и что соответственно нужно разрушать.
  Таким образом выходит, что через оператор select ссылки на временные переменные вообще не просачиваются. Это ограничение языка. Другое дело - значения. Они просто перемещаются в переменную-результат оператора select.

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

#1416
17:00, 6 мар 2023

Интересно сколько человек реально держат в голове баунд чекер из руста

#1417
17:18, 6 мар 2023

1 frag / 2 deaths
> баунд чекер из руста
Я конечно точно не знаю, но судя по наблюдаемому поведению он в некоторых аспектах проще моего. Во-первых, он не занимается ещё и отслеживанием времени жизни временных переменных. Во-вторых он работает отдельным проходом - если код содержит какие-то ошибки, то до borrow checker-а дело даже не доходит. А когда исправил эти ошибки, появляются ошибки от borrow checker-а.

#1418
17:22, 6 мар 2023

Panzerschrek[CN]
Отдельные проходы это вообщет хорошо. Странно что мы ими брезгуешь

#1419
17:31, 6 мар 2023

1 frag / 2 deaths
> Отдельные проходы это вообщет хорошо. Странно что мы ими брезгуешь
Да не понятно.
Исторически компилятор Ü так развивался, что есть три относительно обособленные части - лексический анализатор (вычленяет из текста лексемы), синтаксический анализатор (строит дерево элементов программы) и построитель кода (делает всё остальное). По размеру и сложности последний доминирует - лексический/синтаксический разбор по сравнению с ним достаточно просты, да и по времени почти ничего не занимают.
Построитель кода вычисляет типы, раскрывает шаблоны, строит llvm функции, переменные и т. д. В это включаются также проверка ссылок, вызов деструкторов и т. д. Не понятно, как его ещё можно как-то разбить на проходы - ибо даже чисто для вычисления типов надо вычислять константные выражения, для может понадобиться построение кода constexpr функций. Аналогично не понятно, как можно добавить каких-то проходов сверху (для обнаружения неиспользуемых переменных, например) - ведь по сути вся информация, необходимая для таких анализов строится на лету вместе с построением кода и во многом даже не сохраняется.

Чисто теоретически, наверное, можно было бы как-то сделать больше стадий, выделить непосредственно генерацию llvm кода в отдельный проход, например. Но это по сути требует создания своего промежуточного представления (а то и не одного) и переписывания тем самым почти всего построителя кода. И по сути это повлечёт за собою отчасти дублирование функционала (для тех же constexpr вычислений, например). Ну и переписывание всего - то, чего делать очень не хочется без весомых на то оснований. Переписывание 23 тысяч строк очень плотного кода только построителя кода это задача на месяцы разработки.

#1420
13:18, 8 мар 2023

Раздумываю над тем, как-бы лучше реализовать символы (функции и не только), видимость которых бы была private - чтобы они не были доступны из других единиц трансляции и вообще бы не появлялись в таблицах символов объектных файлов.

Можно сделать что-то вроде static для функций из крестов. Вариант рабочий, но местами многословный, ибо надо static прописывать каждой функции. Есть вариант с анонимным пространством имён, как опять же в крестах. Плюс в том, что в таком случае можно сразу группы функций сделать static, а заодно даже и классы. Есть вариант, как в Rust - когда всё считается private, если не сказано pub. Но мне такое не нравится, ибо опять же многословно это.

Можно кстати ещё подумать над тем, чтобы совместить этот механизм с другим - но похожим, чтобы из импортированных файлов (отчасти это как include в крестах, только умнее), что-то не импортировать (какие-нибудь кишки реализации шаблонных классов, например).

#1421
14:22, 8 мар 2023

Panzerschrek[CN]
Для общего развития, в хаскеле — в декларации модуля пишется отдельный список экспортов, примерно такого вида:

module Foobar
  ( Foo -- экспорт типа
  , Bar (Bar1, Bar2, barField) -- экспорт типа, двух его конструкторов и одного селектора поля
  , Duck (..) -- экспорт типа и всех его подчинённых объявлений
  , Quackable (..) -- экспорт тайпкласса и всех его методов
  , genericQuack -- экспорт функций и констант
  , module Ptich -- ре-экспорт импорта
  )
where

Если список отсутствует — то модуль экспортирует все топ-левел объявления, которые объявляет сам.

А в С++-модулях, вроде как, можно делать обоими способами — можно приписать export прямо к объявлению, а можно сделать отдельную export декларацию и поперечислять идентификаторы.

В тех же С++-модулях, кстати, вводится два "уровня доступности" — "непосредственно видимые" и "в принципе достижимые" — так как с помощью некоторых конструкций, типа decltype, код может обратиться и заиспользовать объявления, даже если они не экспортируются напрямую по имени — и, чтобы такое использование не вызывало проблем на дальнейших стадиях, у модуля делается отдельно таблица "достижимых" символов (видимые для линкера) и "опубликованных" (доступные непосредственно по имени из кода).

#1422
19:36, 8 мар 2023

Имбирная Ведьмочка
> пишется отдельный список экспортов
Многословно.

> Если список отсутствует — то модуль экспортирует все топ-левел объявления
А если я хочу к примеру только одну скрытую функцию иметь, придётся страдать и перечислять весь список кроме неё.

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

> непосредственно видимые" и "в принципе достижимые
Можно же банально по именам что-то при импорте игнорировать. Тогда такое разделение не нужно. Зачем оно крестам - ХЗ, но видимо зачем-то всё-же нужно.

#1423
20:24, 8 мар 2023

Panzerschrek[CN]
> Многословно
Можно сделать опцию наоборот.

Когда происходит импорт — ты тоже можешь открыть скобки и дать явный список импорта, и тогда из модуля будет импортировано только явно перечисленное; но можно сделать и наоборот — писануть hiding и список после него, и тогда будет импортировано всё, кроме перечисленного.

Теоретически, можно сделать так же и со списком экспорта — либо не пишешь ничего, и экспортируются все топ-левелы, либо пишешь явный список экспорта, либо пишешь hiding и перечисляешь только то, что нужно скрыть.
_

О, можно ещё взять механику из пацкаля — сначала идёт раздел interface, и все объявления в нём экспортируются, а затем — implementation, и там всё локально в модуле.

#1424
21:11, 8 мар 2023

https://releases.llvm.org/15.0.0/docs/Coroutines.html
О, оказывается в llvm есть какая-то поддержка корутин. Надо будет посмотреть, что и как. Возможно, это облегчит реализацию корутин в языке высокого уровня.

Страницы: 194 95 96 97100 Следующая »
ФлеймФорумПроЭкты

Тема в архиве.