module Lang.LamIf.StateSpace where

import FP
import Lang.LamIf.Syntax
import Lang.LamIf.CPS

data Addr   = Addr
  { addrLocation :: Name
  , addrLexicalTime :: 
  , addrDynamicTime :: 
  } deriving (Eq, Ord)

type Env   = Map Name (Addr  )
type Store val   = Map (Addr  ) val

data 𝒮Cxt   = 𝒮Cxt
  { 𝓈Cxtlτ :: 
  , 𝓈Cxtdτ :: 
  , 𝓈Cxtρ :: Env  
  } deriving (Eq, Ord)
makeLenses ''𝒮Cxt
instance (Bot , Bot ) => Bot (𝒮Cxt  ) where bot = 𝒮Cxt bot bot bot

data 𝒮 val   = 𝒮
  { 𝓈Cxt :: 𝒮Cxt  
  , 𝓈σ :: Store val  
  } deriving (Eq, Ord)
makeLenses ''𝒮
instance (Bot , Bot ) => Bot (𝒮 val  ) where bot = 𝒮 bot bot

𝓈lτL :: Lens (𝒮 val  ) 
𝓈lτL = 𝓈CxtlτL <.> 𝓈CxtL

𝓈dτL :: Lens (𝒮 val  ) 
𝓈dτL = 𝓈CxtdτL <.> 𝓈CxtL

𝓈ρL :: Lens (𝒮 val  ) (Env  )
𝓈ρL = 𝓈CxtρL <.> 𝓈CxtL

data Clo   = Clo 
  { cloLoc :: LocNum
  , cloArgs :: [Name]
  , cloCall :: Call
  , cloEnv :: Env  
  , cloTime :: 
  } deriving (Eq, Ord)

data PicoVal   =
    LitPicoVal Lit
  | AddrPicoVal (Addr  )
  deriving (Eq, Ord)

class Val   val | val -> , val ->  where
  lit :: Lit -> val 
  clo :: Clo   -> val 
  binop :: BinOp -> val -> val -> val
  tup :: (PicoVal  , PicoVal  ) -> val
  elimBool :: val -> Set Bool
  elimClo :: val -> Set (Clo  )
  elimTup :: val -> Set (PicoVal  , PicoVal  )