{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TemplateHaskell #-}

-- | Implements an effect for interactions with the architectural state, upon
-- which instructions are executed (register file, memory, program counter, etc.).
module LibRISCV.Effects.Operations.Language where

import Control.Monad.Freer.TH (makeEffect)

-- | Abstraction for expressing a 8-, 16-, or 32-bit size.
data Size = Byte | Half | Word
    deriving (Size -> Size -> Bool
(Size -> Size -> Bool) -> (Size -> Size -> Bool) -> Eq Size
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Size -> Size -> Bool
== :: Size -> Size -> Bool
$c/= :: Size -> Size -> Bool
/= :: Size -> Size -> Bool
Eq, Int -> Size -> ShowS
[Size] -> ShowS
Size -> String
(Int -> Size -> ShowS)
-> (Size -> String) -> ([Size] -> ShowS) -> Show Size
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Size -> ShowS
showsPrec :: Int -> Size -> ShowS
$cshow :: Size -> String
show :: Size -> String
$cshowList :: [Size] -> ShowS
showList :: [Size] -> ShowS
Show)

-- | Returns the size in bits (either 8, 16, or 32).
bitSize :: Size -> Int
bitSize :: Size -> Int
bitSize Size
Byte = Int
8
bitSize Size
Half = Int
16
bitSize Size
Word = Int
32

data Operations v r where
    ReadRegister :: v -> Operations v v
    WriteRegister :: v -> v -> Operations v ()
    Load :: Size -> v -> Operations v v
    Store :: Size -> v -> v -> Operations v ()
    WritePC :: v -> Operations v ()
    ReadPC :: Operations v v
    Exception :: v -> String -> Operations v ()
    Ecall :: v -> Operations v ()
    Ebreak :: v -> Operations v ()

makeEffect ''Operations