как они работают с замыканиями, просто копируют все переменные в объект замыкания что-ли?
Так или иначе, утаскивают замыкаемые переменные в кучу. Детали зависят от того, делается ли замыкание по ссылке или по значению.
Если замыкание нисходящее, можно просто сослаться на кадр стека, как в ISO Pascal и Аде
Но тогда надо следить, чтобы эти замыкания не утекали наверх
У параметров могут быть типы, не имеющие аналогов в переменных и полях записей, так что параметр некуда деть, кроме как вызвать или передать в вызов
Ну вот есть у меня что-то вроде Vec<(&str, Value)> и в данный момент интерпретатор столкнулся с замыканием, какие дальнейшие действия приблизительные? Как интерпретатору узнать какие переменные будут захвачены? Разве что смотреть идентификаторы в теле в момент объявления, но выглядит как-то муторно. Или просто скопировать все локальные переменные в этот момент. Язык - небольшое подмножество лиспа
Дальнейшие действия — добавить соответствующее поле в структуру замыкания и подставить это поле на место переменной. К концу компиляции тела функции у вас будет собрана вся структура замыкаемых переменных. Тащить весь стековый кадр в кучу — это анахронизм из очень древних Лиспов. Не стоит так делать сейчас.
>> К концу компиляции тела функции Я про интерпрететор изначально спрашивал Лисп интерпретатор это просто символьные выражения по сути. Лямбды прикручены уже сбоку, я пока что думал хранить их в окружении как sexp аргументы . тело. Но как вижу сейчас этого не достаточно, потому что нужно ещё окружение запомнить
@vtereshkov Может нужно рекурсивно просмотреть тело функции и при встрече идентификатора проверять, что его нет в аргументах? Так?
Чаще всего интерпретаторы хранят локальные переменные (точнее, объекты, на которые локальные переменные указывают) на куче, и при этом собирают их GC — чтобы их "замкнуть" достаточно просто сделать ссылки на те же объекты изнутри самого замыкания (которое тоже структура на куче, из которой идут ссылки на функцию и замкнутые переменные).
А как это будет в раст выглядеть? Vec или HashMap же тоже данные в куче хранят. И опять же вопрос как определить какие переменные нужно замкнуть, разве что пройтись по телу исключая аргументы, но можно же внутри замыкания тоже присваивать переменные
> А как это будет в раст выглядеть? Rc<Value> или как-то так. > как определить какие переменные нужно замкнуть К которым идёт обращение в теле функции — те и замыкаем.
Vec<Rc<Value>> выходит? > К которым идёт обращение в теле функции. Перед тем как добавить "объект функции" с с-выражением, которое является телом пройтись просто по нему и посмотреть какие встречаются идентификаторы?
А Вы свой Lisp не парсите, что ли? Пытаетесь интерпретировать строчка за строчкой? Думаю, с Lisp так не выйдет. В любом случае строить AST и tree-walking interpreter — это минимум. А при наличии AST — какие проблемы по нему пройти лишний раз? Есть подозрение, что таблицу символов можно построить одновременно с самим AST.
Парсим конечно. Просто я почему-то думал, что ещё раз пройтись действительно лишнее действие:) > AST tree-walking interpreter минимум. А почему минимум, разве иртерпретаторы комона или схемы, да впринципе лиспов не ограничиваются tree-walking interpreter, там же синтаксис очень простой, я даже слышал мнение, что парсинг можно вообще не отделять никак. > Таблица символов одновременно с AST. Опять же, разве ее используют в подобных интерпретаторах? Мне казалось это гораздо ближе к компиляции
> А почему минимум, разве иртерпретаторы комона или схемы, да впринципе лиспов не ограничиваются tree-walking interpreter Потому что медленее — только построчная интерпретация. Не ограничиваются, конечно — любой пристойный интерпретатор сначала компилирует в байт-код. Промышленные "интерпретаторы" Common Lisp/Scheme и других — компилируют в машинный код. > Мне казалось это гораздо ближе к компиляции Так называемый "environment", который у Вас (был) Vec<&str, Value> — это то же самое, что таблица символов. Плюс-минус нюансы.
Подождите, но разве компиляция в машинный код это не компилятор?
Если компиляция в байт-код считается интерпретацией — то почему нет? 😂
Ну, не знаю, меня тоже компиляция в байткод как-то смущала в процессе интерпретации
это всё условности, главное - результат
В daScript tree walk interpreter, но быстрый
Обсуждают сегодня