Отображение нетипизированных данных Lisp в типизированный двоичный формат для использования в скомпилированных функциях - PullRequest
4 голосов
/ 30 июня 2011

Справочная информация : Я пишу игрушечный интерпретатор Lisp (Scheme) в Haskell.Я нахожусь в точке, где я хотел бы иметь возможность компилировать код с использованием LLVM.Я потратил пару дней, придумывая различные способы подачи нетипизированных значений Lisp в скомпилированные функции, которые ожидают знать формат поступающих на них данных.Мне приходит в голову, что я не первый, кому нужно решить эту проблему.

Вопрос : Каковы некоторые исторически успешные способы преобразования нетипизированных данных в эффективный двоичный формат.

Приложение : На самом деле я знаю, какой из дюжины различных типов данных, я просто не знаю, какой из них может быть отправлен в функцию во время компиляции.Для самой функции нужен способ определить, что она получила.

Ответы [ 2 ]

3 голосов
/ 30 июня 2011

Вы имеете в виду: «Я просто не знаю, какой [тип] может быть отправлен функции в время выполнения »?Дело не в том, что данные не напечатаны;конечно, 1 и '() имеют разные типы.Скорее, данные не являются статически типизированными, то есть во время компиляции неизвестно, каким будет тип данной переменной.Это называется динамическая типизация .

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

  • 0 = целое число
  • 1 = cons пара
  • 2 = вектор
  • и т. Д.

Как только вы это сделаете, зарезервируйте первые четыре бита каждого слова для тега.Затем каждый раз, когда два объекта передаются в +, сначала вы выполняете простую битовую маску, чтобы убедиться, что первые четыре бита обоих объектов равны 0b0000, то есть оба они являются целыми числами.Если это не так, вы переходите к сообщению об ошибке;в противном случае вы продолжите добавление и убедитесь, что результат также помечен соответствующим образом.

Этот метод по существу делает каждое значение времени выполнения объединенным вручную теговым объединением , что должно быть вам знакомоесли вы использовали C. На самом деле, это также похоже на тип данных Haskell, за исключением того, что в Haskell тегирование намного более абстрактно.

Я предполагаю, что вы знакомы с указателями, если вы 'пытаемся написать компилятор Scheme.Чтобы избежать ограничения используемой памяти, может быть более разумно использовать нижние (наименее значимые) четыре бита, а не верхние.Еще лучше, поскольку у выровненных указателей dword уже есть три бессмысленных бита внизу, вы можете просто выбрать эти биты для своего тега, если вы разыменовываете фактический адрес, а не тегированный.

это поможет?

2 голосов
/ 30 июня 2011

Ваше решение по умолчанию должно быть простым теговым объединением.Если вы хотите сузить набор текста до более конкретных типов, вы можете сделать это, но это больше не будет «игрушкой».На что нужно смотреть, называется абстрактная интерпретация .

Существует несколько успешных реализаций такой оптимизации, при этом V8 является, вероятно, наиболее распространенным.В мире Схем наиболее агрессивно оптимизирующей реализацией является Сталин .

...