Вопрос
Я пытался понять, как работают блоки Ruby, и для этого пытался реализовать их на C.
Одним из простых способов реализации замыканий является передача void*
во включающий стек в замыкание/функцию, но блоки Ruby также, похоже, обрабатывают операторы возврата и прерывания из области, которая использует блок.
loop do
break i if (i >= 4000)
i *= 2
end
Я думаю, что одно из предложений по замыканиям для Java тоже работает аналогичным образом.
Итак, как бы вы реализовали Ruby-блоки/Java-замыкания в C?
Решение
Концепция замыканий требует концепции контекстов.Контекст C основан на стеке и регистрах ЦП, поэтому для создания блока/замыкания вам необходимо иметь возможность правильно (и повторно входить) манипулировать указателем стека и сохранять/восстанавливать регистры по мере необходимости.
То, как это делается интерпретаторами или виртуальными машинами, состоит в том, чтобы иметь context
структуру или что-то подобное, а не использовать стек и регистры напрямую.Эта структура отслеживает стек и, возможно, некоторые регистры, если вы разрабатываете виртуальную машину на основе регистров.По крайней мере, это самый простой способ сделать это (хотя и немного менее производительный, чем правильное отображение вещей).
Другие советы
На самом деле я ничего из этого не реализовал, так что относитесь к этому с мешком соли.
Закрытие состоит из двух частей:среда данных и среда кода.Как вы сказали, вы, вероятно, можете передать void* для обработки ссылок на данные.Вероятно, вы могли бы использовать setjmp и longjmp для реализации нелинейных переходов потока управления, которые требуются для разрыва Ruby.
Если вам нужны замыкания, вам, вероятно, следует программировать на языке, который их действительно поддерживает.:-)
ОБНОВЛЯТЬ:В Кланге происходят интересные вещи.Они создали прототип замыкания для C. http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html может оказаться интересным чтением.
В рамках курса «Rails with Passion» есть хороший набор слайдов по Ruby Blocks:
Здесь рассматривается представление блока, способы передачи аргументов и выполнения, а также такие вещи, как объекты Proc.Это очень ясно объяснено.
Тогда может быть интересно посмотреть, как ребята из JRuby справились с этим при синтаксическом анализе на Java.Взгляните на источник на кодхаус.