Andy Melnikov (nponeccop) wrote,
Andy Melnikov
nponeccop

Categories:

Крокодил не ловится

Сегодня встал с утра и не мог никак собраться с силами. Пришлось чуток код попричёсывать - разнести бойлерплейт и смысловой код. После чего всё равно не собрался, и полез перечитывать статью по хуплу. Оказалось, действительно, они вызывают мой перезаписыватель до анализатора, а не после. В результате перезаписыватель удаляет у лямбд лишние аргументы, и анализатор уже не может из аргументов сделать локальные переменные, поскольку они уже удалены.

Ещё я выяснил, что халтурил в старом инлайнере, а в новом так не получится (в старом тоже это делать нельзя было, но он сейчас больше тестов проходит, чем новый).

Я передавал данные по графу управления только на один "хоп", и поэтому использовал только один адрес - он же адрес ближайшего хопа, он же адрес получателя. А сейчас надо, как это было сделано в примерах хупла, второй уровень адресов-меток организовать - так что будет Map Label (Map Label Fact) вместо просто Map Label Fact.

Ещё я изображал из себя нетипизированного и передавал разные сущности в одном и том же списке. Логически мне приходит

data WithTopAndBot a = Top | Bot | PElem a
data AFType = Call [WithTopAndBot ExpressionFix] | Value ExpressionFix

а я передавал просто [WithTopAndBot ExpressionFix]. А если мне приходило Value ExpressionFix - то я его представлял просто как одноэлементный список с PElem. Всё равно там по контексту можно было отличить, что приходит. Тьфу. Отрефакторил. Теперь хотя бы в диагностике красота.

По мере усложнения внутренней структуры фактов усложняются функции джойна решёток из фактов. Надо придумать, как композиционно эти решётки лепить. У них там ещё не обычные решётки, а инженерные. Джоин некоммутативен, принимает три аргумента и возвращает тапл. А сами решётки сделаны через явные словари. Т.е. вместо
class Lattice a where
   join :: a -> a -> a
   bot :: a
(заметьте, это ж monoid in disguise) у них совершеннейший пиздец в виде
data DataflowLattice a = DataflowLattice  
 { fact_name       :: String          -- Documentation
 , fact_bot        :: a               -- Lattice bottom element
 , fact_join       :: JoinFun a       -- Lattice join plus change flag
                                      -- (changes iff result > old fact)
 }
-- ^ A transfer function might want to use the logging flag
-- to control debugging, as in for example, it updates just one element
-- in a big finite map.  We don't want Hoopl to show the whole fact,
-- and only the transfer function knows exactly what changed.

type JoinFun a = Label -> OldFact a -> NewFact a -> (ChangeFlag, a)
  -- the label argument is for debugging purposes only
newtype OldFact a = OldFact a
newtype NewFact a = NewFact a

data ChangeFlag = NoChange | SomeChange
Завтра буду вводить двухуровневые решётки, будь они неладны, и выделять удаление лишних формальных параметров в отдельный проход.
Tags: hn0
Subscribe

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 2 comments