Вы имеете в виду: «Я просто не знаю, какой [тип] может быть отправлен функции в время выполнения »?Дело не в том, что данные не напечатаны;конечно, 1
и '()
имеют разные типы.Скорее, данные не являются статически типизированными, то есть во время компиляции неизвестно, каким будет тип данной переменной.Это называется динамическая типизация .
Вы правы, что вы не первый, кому нужно решить эту проблему.Каноническим решением является тег каждого значения времени выполнения с его типом.Например, если у вас есть дюжина типов, нумеруйте их так:
- 0 = целое число
- 1 =
cons
пара - 2 = вектор
- и т. Д.
Как только вы это сделаете, зарезервируйте первые четыре бита каждого слова для тега.Затем каждый раз, когда два объекта передаются в +
, сначала вы выполняете простую битовую маску, чтобы убедиться, что первые четыре бита обоих объектов равны 0b0000, то есть оба они являются целыми числами.Если это не так, вы переходите к сообщению об ошибке;в противном случае вы продолжите добавление и убедитесь, что результат также помечен соответствующим образом.
Этот метод по существу делает каждое значение времени выполнения объединенным вручную теговым объединением , что должно быть вам знакомоесли вы использовали C. На самом деле, это также похоже на тип данных Haskell, за исключением того, что в Haskell тегирование намного более абстрактно.
Я предполагаю, что вы знакомы с указателями, если вы 'пытаемся написать компилятор Scheme.Чтобы избежать ограничения используемой памяти, может быть более разумно использовать нижние (наименее значимые) четыре бита, а не верхние.Еще лучше, поскольку у выровненных указателей dword уже есть три бессмысленных бита внизу, вы можете просто выбрать эти биты для своего тега, если вы разыменовываете фактический адрес, а не тегированный.
это поможет?