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

Ü (Programmiersprache) (55 стр)

Страницы: 154 55 56 5759 Следующая »
#810
(Правка: 0:16) 0:15, 23 окт. 2020

Panzerschrek[CN]
Эх, круть какая! Эта тема одна из самых интересных на форуме, определенно.

> Но если всё посчитать, то, исключая LLVM код, Компилятор1 примерно на 85-90%
> написан на Ü.
А планируешь в дальнейшем допереписывать на Ü? Я с LLVM не контактировал особо, поэтому тонкостей не знаю.

А я тем временем написал парсер полной грамматики Луа, только вот насколько правильно - вопрос. Хотя все официальные тесты парятся без ошибок.
#811
(Правка: 10:02) 10:00, 24 окт. 2020

Последнее время меня удручала ситуация со скоростью сборки Компилятора1. Собирался он не быстро - минуты по 2.5 - 3, в release режиме. Если собирать в debug режиме да и ещё debug Компилятором0, то можно и минут по 40 было ждать. Проблема состоит в том, что компилятор выдаёт ну уж очень жирные объектные файлы с тысячами и даже десятками тысяч символов. Я грешил на то, что это от того, что уж слишком много шаблонных методов. сгенерированных методов и прочих typeinfo выгружаются в объектный файл. Их сильно больше, в сравнении с C++, т. к. в Ü нету ленивого построения методов.
Сегодня я решил поэкспериментировать, попытаться решить эту проблему. Без особой надежды поменял пару строчек, чтобы LinkageType у сгенерированных методов был private, а не external.  И о чудо - сборка Компилятора1 начала проходить в 2 раза быстрее. Потом я пошёл дальше, и сделал private linkage у шаблонных функций и всех методов шаблонных классов, что ещё убыстрило сборку более чем в 2 раза.

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

#812
15:56, 29 окт. 2020

Нашёл тут сегодня в документации к LLVM такой совет.

When building a distribution of a compiler it is generally advised to perform a bootstrap build of the compiler. That means building a “stage 1” compiler with your host toolchain, then building the “stage 2” compiler using the “stage 1” compiler. This is done so that the compiler you distribute benefits from all the bug fixes, performance optimizations and general improvements provided by the new compiler.

В общем то да, правильно я сделал, написав Компилятор1, даже разроботчики LLVM рекомендуют так делать.

#813
18:31, 8 ноя. 2020

Подумываю добавить сырые указатели как фичу языка.
Зачем же оно нужно?

Сами по себе указатели нужны в низкоуровневом коде, без них не обойтись. Сейчас такие указатели реализованы через незамысловатый шаблонный класс, вроде этого:

template</ type T />
class raw_ptr_mut
{
public:
  fn get_ref( this ) unsafe : T &mut
  {
    unsafe{  return cast_mut( cast_ref_unsafe</ T />( int_to_ref(val_) ) );  }
  }
private:
  size_type val_;
}

Этот класс свою задачу выполняет. Так зачем же тогда вводить указатели как фичу языка?
Во-первых, это класс, а значит, он передаётся в функции и возвращается из функций всегда по ссылке. Это не совсем оптимально, хотелось бы более быстрого решения - без излишней индирекции.
Во-вторых, из за вышеописанной индирекции этот класс нельзя использовать в сигнатурах методов, взаимодействующих со внешним (Си) кодом.
В третьих, в llvm коде обращение с таким эрзац-указателем происходит через inttoptr/ptrtoint операции. Это потенциально может помешать оптимизатору в его работе, например, ломая анализ указателей на пересечение их областей действия.
В четвёртых, в дальнейшем я планирую включить анализ пересечений на основе типов (type based alias analysis, TBAA), преобразования целых чисел в указатель и наоборот могут его сломать, ну или, как минимум, замедлить.
В пятых, честные указатели в сигнатурах методов позволят использовать межьязыковую межмодульную оптимизацию, к примеру, встроив вызов C++ функций, принимающих сырые указатели, из Ü.

Теперь назревает вопрос, каким образом эти самые указатели реализовать?
Первая группа вопросов - а как собственно в языке будут работать указатели? Я предполагаю, что для них можно не реализовывать контроля ссылок и сделать все операции разыменования небезопасными. Думаю, что нужно будет реализовать отдельные операторы преобразования ссылки в указатель и наоборот (разименовывание). Также наверняка понадобится сложение указателей и целых чисел, вычитание целых чисел из указателей. Опционально можно добавить ++ и --. Точно не знаю, нужна ли разность указателей. На счёт оператора [] склоняюсь к тому, что он скорее вреден, чем полезен. Сомневаюсь в необходимости делать разделение на изменяемые/неизменяемые указатели, ведь раз с ними и так небезопасно работать, то неизменяемость сильно полезной не будет.
Вторая группа вопросов - каков синтаксис будет у указателей? Какой должен быть синтаксис у имени типа указателя? Каковыми должны быть операторы преобразования между ссылками и указателями - префиксными, постфиксными, функциональными?

#814
18:49, 8 ноя. 2020

Передавай классы по копии, что сложного-то.

#815
19:11, 8 ноя. 2020

1 frag / 2 deaths
> Передавай классы по копии, что сложного-то.
Это решает только проблему под номером 1. Да и то, это для этого придётся городить костыли в компиляторе.

#816
23:03, 8 ноя. 2020
В общем, начав с красивой рустообразной идеи и продвинувшись вдоль неё достаточно далеко, становится понятным, что идея несовершенна, и костыли таки неизбежны?

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

> встроив вызов C++ функций, принимающих сырые указатели, из Ü.
А этого, от греха подальше, лучше не делать. Вызовы внешних функций пусть будут некими гражданами второго класса, завёрнутыми в хитрые классы с кучей методов. Так будет проще контролировать расхождения в конвенциях.

#817
19:55, 9 ноя. 2020

Sbtrn. Devil
> всеми правдами и неправдами ограничивать время жизни указателя неким
> ансейф-блоком
В класс тогда его не поместить. Но это нужно.
Но вот разыменовывание указателя таки да, планирую разрешить только в unsafe блоке.

> Сделать так, чтобы нельзя было просто брать и возвращать-передавать указатели в
> обычном коде,
Типа, разрешать вызов и возврат указателей только в unsafe коде? В принципе да, здравая идея.

> и чтоб требовалось завёртывать это в безопасные врапперы.
Ну как бы сейчас так по факту и есть. Существует, например, шаблонный класс optional_ref, который внутри содержит тот же указатель. Просто этот указатель реализован немного через задницу.

> . Вызовы внешних функций пусть будут некими гражданами второго класса,
> завёрнутыми в хитрые классы с кучей методов.
Заворачивать то, конечно, надо. Но llvm тип указателя Ü, совпадающий с таковым в C++, должен быть.

#818
(Правка: 20:54) 20:54, 9 ноя. 2020

Panzerschrek[CN]
У тебя в языке нет ньютайпов?
В хаскеле есть такое понятие, ньютайп:

newtype ThreadId = ThreadId { getThreadId :: Int64 }
В базовых чертах, он похож на enum class из крестов:
enum class ThreadId: int64_t;
С точки зрения внешнего кода, в большинстве случаев, ньютайп - это структура с одним полем.
Если в области видимости есть конструктор ThreadId - то можно взять число и поместить его в эту "структуру":
foobar :: ThreadId
foobar = ThreadId 1234
ThreadId foobar = ThreadId(1234);
Если видна функция getThreadId - то можно, наоборот, вытащить из "структуры" её единственный элемент:
printThread :: ThreadId -> IO ()
printThread tid = do
    let n = getThreadId tid
    putStrLn ("thread id: " ++ show n)
void printThread(ThreadId tid) {
    int64_t n = int64_t(tid);
    std::cout << "thread id: " << n;
}
Int64 и ThreadId - это два различных типа, точно так же, как число Int64 и массив [Int64] - если нужен перевод, он делается через явный вызов функции.

Однако, в плане фактического расположения в памяти, ThreadId - это всё тот же Int64 - после проверки типов, все ThreadId и getThreadId отбрасываются как но-опы, и в IR код уже работает с базовым типом - точно так же, как в крестах операции над enum class преобразуются в операции над базовым интом.

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

Ну и, собственно - почему бы не реализовать указатели как ньютайп над целым числом?
#819
21:24, 9 ноя. 2020

Delfigamer
> У тебя в языке нет ньютайпов?
Нету.
Пока не вижу особого смысла. Чисто технически, если надо, можно и через класс такое реализовать. Будет небольшая потеря производительности из-за того, что это будет класс, но тут уж извините - куда деваться.
В перспективе, конечно, можно было бы такое добавить, но сильно позже, где-то в то же время, когда будут лямбды и параметры с умолчательным значением.

> почему бы не реализовать указатели как ньютайп над целым числом?
> отбрасываются как но-опы, и в IR код уже работает с базовым типом
Ну так вся суть - получить llvm-ный казатель в IR коде, а не i64 + пачку inttoptr/ptrtoint.

#820
1:40, 10 ноя. 2020

Panzerschrek[CN]
> В класс тогда его не поместить. Но это нужно.
> Но вот разыменовывание указателя таки да, планирую разрешить только в unsafe
> блоке.
Вообще да, я примерно такой вариант и имел в виду. То есть за пределами блока указатель имеет право на существование только в приватно-обёрнутом виде, а от этой обёртки (в смысле от автора, сочиняющего этот обёрточный класс) можно уже пытаться требовать чего-нибудь интересного, в том числе статически.

#821
1:36, 12 ноя. 2020

Panzerschrek[CN]
> Никаких говносборщиков мусора.

усё понятно

#822
18:41, 15 ноя. 2020

Есть у меня плагин Ü для QtCreator, который умеет в подсветку кода и почти ничего кроме этого. Думаю, как его дальше развивать и стоит ли. API для плагинов там весьма нестабильное и приходится под каждую новую версию его немного менять.
Подумываю, а нужен ли QtCreator? Может есть какая-нибудь другая IDE, где API стабилен длительное время? Было бы неплохо написать плагин под такую IDE. Кто-нибудь что-нибудь знает на этот счёт?

#823
12:09, 16 ноя. 2020

Panzerschrek[CN]
Пиши плагин под Visual Studio Code, он сейчас очень активно развивается.

#824
14:42, 16 ноя. 2020

Great V.
> Visual Studio Code
Плагины к Хромиуму у меня желания писать нету.

Страницы: 154 55 56 5759 Следующая »
ФлеймФорумПроЭкты