Сложный перевод структуры с ленивой оценкой - PullRequest
3 голосов
/ 10 августа 2010

Краткая справка: я пишу универсальный компилятор низкого уровня.На стороне высокого уровня он понимает классы, методы, поля, вызовы виртуальных методов и т. Д., А на стороне низкого уровня - функции, структуры, массивы и т. Д. Интерфейсы транслируют скомпилированные формы языков, таких как Java (основное внимание) и C # в мой IR.Промежуточный шаг понижает классы, методы, поля и виртуальные вызовы и т. Д. В вызовы функций и структуры.Серверная часть выплевывает C, LLVM IR (основной фокус) или, возможно, другие.

В настоящее время типы (такие как целые числа, числа с плавающей запятой, структуры, классы и т. Д.) Являются (в основном) неизменяемыми.Классы позволяют вам добавлять поля и методы, потому что они не меняют тип (то есть указатель класса).Существует только один из любого данного типа для каждой единицы перевода («Модуль») - структуры, указатели, массивы и другие «производные» типы.Другими словами, типы имеют структурную эквивалентность, такую ​​как LLVM, - вместо эквивалентности имени, как C ++.

Проблема, с которой я сталкиваюсь, заключается в преобразовании экземпляров ClassType, которые интерфейс Java выделяет в экземпляры StructType (суказатель vtable и все поля класса), которые понимает серверная часть LLVM таким образом, что система поддерживает согласованное состояние в течение всего процесса.Одна из трудностей заключается в поддержании эквивалентности структуры - два разных класса могут быть понижены до одной и той же структуры, и это должно быть либо обнаружено в начале процесса понижения, либо исправлено после процесса понижения.

Это долгоПридуманное объяснение приводит меня к моему вопросу: могут ли ленивые языки оценки, такие как Haskell, предложить удобное решение?Если да, то как это можно перевести обратно на Java, возможно, используя шаблон «Обещание»?

1 Ответ

1 голос
/ 10 августа 2010

Я не уверен, что вы ищете общий ответ или что-то более конкретное, но это звучит примерно так:

lower :: Eq b => a -> b
lower = undefined

generate :: Eq b => [a] -> [b]
generate xs = go $ map lower xs
    where go [] = []
          go (y:ys) = y : go (filter (not . (==y)) ys)

, который создает уникальные элементы постепенно. Инкрементальный аспект обусловлен только ленивыми минусами, если только вы не можете сделать свой экземпляр Eq ленивым (например, сравнивая только какой-то структурный хэш-код, который может позволить вам пропустить более дорогостоящий шаг генерации кода).

...