never executed always true always false
    1 module HelVM.HelMA.Automaton.Combiner.LSU where
    2 
    3 import           HelVM.HelMA.Automaton.Combiner.ALU
    4 import qualified HelVM.HelMA.Automaton.Combiner.RAM                     as RAM
    5 
    6 import           HelVM.HelMA.Automaton.IO.BusinessIO
    7 
    8 import           HelVM.HelMA.Automaton.Instruction.Extras.Common
    9 import           HelVM.HelMA.Automaton.Instruction.Groups.IOInstruction
   10 import           HelVM.HelMA.Automaton.Instruction.Groups.LSInstruction
   11 
   12 import           HelVM.HelIO.Control.Safe
   13 
   14 import           Control.Type.Operator
   15 
   16 runSLI :: (LSU m s r element) => LSInstruction -> LoadStoreMemory s r -> m $ LoadStoreMemory s r
   17 runSLI Load             = load
   18 runSLI Store            = store
   19 runSLI (LoadD     a)    = loadD a
   20 runSLI (StoreID v a)    = storeID v a
   21 runSLI (MoveD   s d)    = moveD s d
   22 runSLI (MIO OutputChar) = loadOutputChar
   23 runSLI (MIO OutputDec)  = loadOutputDec
   24 runSLI (MIO InputChar)  = storeInputChar
   25 runSLI (MIO InputDec)   = storeInputDec
   26 
   27 load :: LSU m s r element => LoadStoreMemory s r -> m $ LoadStoreMemory s r
   28 load (LSM s r) = appendError "LSM.load" $ build =<< pop1 s where
   29   build (address , s') = loadPure address $ LSM s' r
   30 
   31 loadD :: LSU m s r element => Index -> LoadStoreMemory s r -> m $ LoadStoreMemory s r
   32 loadD address = loadPure (fromIntegral address)
   33 
   34 loadPure :: LSU m s r element => element -> LoadStoreMemory s r -> m $ LoadStoreMemory s r
   35 loadPure address (LSM s r) = pure $ LSM (push1 (RAM.genericLoad r address) s) r
   36 
   37 store :: LSU m s r element => LoadStoreMemory s r -> m $ LoadStoreMemory s r
   38 store (LSM s r) = appendError "LSM.store" $ build =<< pop2 s where
   39   build (value , address , s') = storePure value address $ LSM s' r
   40 
   41 storeID :: LSU m s r element => Integer -> Index -> LoadStoreMemory s r -> m $ LoadStoreMemory s r
   42 storeID value address = storePure (fromIntegral value) (fromIntegral address)
   43 
   44 storePure :: LSU m s r element => element -> element -> LoadStoreMemory s r -> m $ LoadStoreMemory s r
   45 storePure value address (LSM s r) = pure $ LSM s $ RAM.store address value r
   46 
   47 moveD :: LSU m s r element => Index -> Index -> LoadStoreMemory s r -> m $ LoadStoreMemory s r
   48 moveD src dst lsm@(LSM _ r) = storePure (RAM.genericLoad r src) (fromIntegral dst) lsm
   49 
   50 -- | IO
   51 
   52 loadOutputChar :: LSU m s r element => LoadStoreMemory s r -> m $ LoadStoreMemory s r
   53 loadOutputChar (LSM s r) = appendError "LSM.loadOutputChar" $ build =<< pop1 s where
   54   build (address , s') = LSM s' r <$ wPutAsChar (RAM.genericLoad r address)
   55 
   56 loadOutputDec :: LSU m s r element => LoadStoreMemory s r -> m $ LoadStoreMemory s r
   57 loadOutputDec (LSM s r) = appendError "LSM.loadOutputDec" $ build =<< pop1 s where
   58   build (address , s') = LSM s' r <$ wPutAsDec (RAM.genericLoad r address)
   59 
   60 storeInputChar :: LSU m s r element => LoadStoreMemory s r -> m $ LoadStoreMemory s r
   61 storeInputChar (LSM s r) = appendError "LSM.storeInputChar" $ build =<< pop1 s where
   62   build (address , s') = LSM s' . flip (RAM.store address) r <$> wGetCharAs
   63 
   64 storeInputDec :: LSU m s r element => LoadStoreMemory s r -> m $ LoadStoreMemory s r
   65 storeInputDec (LSM s r) = appendError "LSM.storeInputDec" $ build =<< pop1 s where
   66   build (address , s') = LSM s' . flip (RAM.store address) r <$> wGetDecAs
   67 
   68 -- | Types
   69 type LSU m s r element = (ALU m s element , RAM.RAM r element)
   70 
   71 data LoadStoreMemory s r = LSM
   72   { stack :: s
   73   , ram   :: r
   74   }