185 похожих чатов

Сейчас вернулся к проекту интерпретатора схемы с виртуальной машиной. Собираюсь

добавить замыкания. Хочу уточнить правильно ли я понимаю, что мне вообще нужно делать. Раньше мне сказали, что в качестве gc на первое время будет достаточно обычного реф каунтера. Как я представляю реализацию:
1) В структуре представляющей замыкание есть поле содержащее набор идентификаторов захватываемых переменных, которое заполняется при компиляции(Vec<&str>) и свой стек который заполняется при интерпретации(Vec<(&str, Rc<Value>)>).
2) Когда встречается лямбда выражение, помимо его компиляции мне также нужно составить список идентификаторов, которые в нем встречаются, но не объявлены в аргументах/теле функции.
3) Уже во время выполнения байткода при объявлении функции я для каждого идентификатора из первого поля ищу его в стеке и добавляю во второе поле пару вместе со значением.
4) При вызове какого-либо замыкания я пары из второго поля добавляю в текущий стек

Ещё у меня возникла пара вопросов:
1) Как поступают с глобальными переменными? Стоит ли сохранять их значение во время объявления функции?
2) Во втором шаге, нужно ли пытаться совместить компиляцию и этот анализ в один проход, или анализ будет нормально сделать уже отдельно?

23 ответов

61 просмотр

> содержащее набор идентификаторов захватываемых переменных Зачем захватывать идентификаторы переменных? Лучше сразу захватывать значения, которые лежат в этих переменных. > и свой стек который заполняется при интерпретации Зачем там свой стек? Это ж замыкания, а не продолжения? > При вызове какого-либо замыкания я пары из второго поля добавляю в текущий стек Зачем их на стек перекладывать? Проще взять прямо оттуда, где они хранятся. > Стоит ли сохранять их значение во время объявления функции? Да. Это называется "лексическая область видимости" (lexical scope). Вообще, имеет смысл посмотреть что такое lambda lifting и как это делается. Но по-простому можно прямо в байт-код добавить инструкции для создания замыканий и работы с ними.

Alexander Chichigin
> содержащее набор идентификаторов захватываемых п...

> Зачем захватывать идентификаторы переменных? Лучше сразу захватывать значения, которые лежат в этих переменных. А как узнать сами значения во время компиляции?

Alexander Chichigin
Так само замыкание создаётся во время выполнения.

Тогда анализ тела функции тоже во время интерпретации делать?

oleja ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
Тогда анализ тела функции тоже во время интерпрета...

Почему? Как тогда Вы сгенерируете код для создания замыкания, если Вы не проанализировали функцию, и не знаете, что нужно будет делать?

> В структуре представляющей замыкание есть поле содержащее набор идентификаторов Так, стоп. Это поминки. Замыкание может захватить локальный объект, уйти за пределы области определения и там быть вызванным. В этом случае всё развалится. Надо захватывать стек (контекст) на момент создания замыкания.

Andrei Kurosh
А если замкнутые переменные нужно менять?

Менять нужно значения, а не переменные — не надо это путать.

TOV_MULTIMASSO
> В структуре представляющей замыкание есть поле с...

> Надо захватывать стек (контекст) на момент создания замыкания. Ну, весь стек захватывать не нужно — это же не продолжение...

Alexander Chichigin
> Надо захватывать стек (контекст) на момент созда...

Если мы не весь стек захватываем, то у нас видимость перестаёт быть лексической

Andrei Kurosh
Значения переменной…

Я предлагаю не делать мутабельных переменных вообще, а докинуть их потом, как разберёмся с иммутабельными

Но весь стек то зачем, только те переменные, которые используются непосредственно в теле функции, нет? А то получится иррационально

oleja ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
Но весь стек то зачем, только те переменные, котор...

Это частный случай захвата всего. Обычно быстрее захватить стек, чем проходить по нему и выбирать конкретные вещи — даже когда набор известен статически.

oleja ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
Обычно советуют обратное

Можно и конкретику. Это потребует отдельного прохода с выводом явных списков захвата у лямбд.

TOV_MULTIMASSO
Я предлагаю не делать мутабельных переменных вообщ...

Это фундаментальное решение в дизайне, чтобы влепить их потом может понадобиться все переделать

TOV_MULTIMASSO
В окамле вон справились, в хаскелле тоже

Обратно-совместимо, без введения нового синтаксиса для этих переменных?

Andrei Kurosh
Обратно-совместимо, без введения нового синтаксиса...

Решаемо юзерспейсом. Добавить конструктор и операторы на чтение/запись. let a = ref 4; a := 5; print (a!);

TOV_MULTIMASSO
Решаемо юзерспейсом. Добавить конструктор и операт...

Давайте не будем подменять понятия - это не изменение переменой, а просто структура с изменяемым содержимым, плотно обмазанная сахаром

Andrei Kurosh
Это фундаментальное решение в дизайне, чтобы влепи...

М-да уж, в интерпретатор Nutt понадобилось очень много изменений внести, чтобы добавить квалификатор ссылки mut.

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Раз начали говорить про embassy, то присоединюсь со своими парой вопросов. 1) Есть ли сопоставимые аналоги для асинхронного кода в emdebbed? 2) Можно ли внутри задач embassy ...
NI_isx
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
1
Он в одиночку это дело запилил или была какая-то команда?
Aquinary
12
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Карта сайта