hic-0.0.0.1: test/Language/Cimple/Analysis/Refined/Inference/LifterSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Language.Cimple.Analysis.Refined.Inference.LifterSpec (spec) where
import Control.Monad.State.Strict (runState)
import qualified Data.Map.Strict as Map
import Data.Word (Word32)
import qualified Language.Cimple as C
import Language.Cimple.Analysis.Refined.Inference.Lifter
import Language.Cimple.Analysis.Refined.Inference.Types
import Language.Cimple.Analysis.Refined.LatticeOp
import Language.Cimple.Analysis.Refined.Registry
import Language.Cimple.Analysis.Refined.Types
import qualified Language.Cimple.Analysis.TypeSystem as TS
import Test.Hspec
spec :: Spec
spec = describe "Language.Cimple.Analysis.Refined.Inference.Lifter" $ do
let emptyTS = Map.empty :: TS.TypeSystem
let st0 = emptyTranslatorState emptyTS
describe "liftImplicitPolymorphism" $ do
it "identifies implicit parameters in structs" $ do
-- struct Box { void *data; };
-- void* data translates to a node containing a TIdParam PLocal ...
-- Lifter should find this and promote it.
let tidT = TIdParam PLocal 10 (Just "T")
let varNode = AnyRigidNodeF (RObject (VVar tidT Nothing) (Quals False))
let member = Member (dummyL "data") 100
let boxDef = StructDef (dummyL "Box") [] [member]
let reg = Registry (Map.singleton "Box" boxDef)
let st = st0 { tsNodes = Map.insert 100 varNode (tsNodes st0) }
let (reg', st') = runState (liftImplicitPolymorphism reg) st
let mDef = Map.lookup "Box" (regDefinitions reg')
case mDef of
Just (StructDef _ params _) -> params `shouldContain` [(tidT, Invariant)]
_ -> expectationFailure "Expected Box to be a StructDef"
-- Should also register an existential form
Map.member "Box" (tsExistentials st') `shouldBe` True
it "handles nested implicit polymorphism" $ do
-- struct Inner { void *p; };
-- struct Outer { struct Inner inner; };
let tidT = TIdParam PLocal 10 (Just "T")
let varNode = AnyRigidNodeF (RObject (VVar tidT Nothing) (Quals False))
let innerId = 100 :: Word32
let memberP = Member (dummyL "p") innerId
let innerDef = StructDef (dummyL "Inner") [] [memberP]
let innerNominal = AnyRigidNodeF (RObject (VNominal (dummyL (TIdName "Inner")) [innerId]) (Quals False))
let memberI = Member (dummyL "inner") (102 :: Word32)
let outerDef = StructDef (dummyL "Outer") [] [memberI]
let reg = Registry (Map.fromList [("Inner", innerDef), ("Outer", outerDef)])
let st = st0 { tsNodes = Map.fromList
[ (innerId, varNode)
, (102, innerNominal)
] }
let (reg', _) = runState (liftImplicitPolymorphism reg) st
case Map.lookup "Outer" (regDefinitions reg') of
Just (StructDef _ params _) -> params `shouldContain` [(tidT, Invariant)]
_ -> expectationFailure "Expected Outer to be a StructDef with lifted parameter T"
dummyL :: t -> C.Lexeme t
dummyL = C.L (C.AlexPn 0 0 0) C.IdSueType