module CSPM.Interpreter.GenericBufferPrefix
(
initPrefix
,viewPrefixState
,prefixStateNext
,prefixStateFinalize
)
where
import qualified CSPM.CoreLanguage as Core
import Language.CSPM.AST as AST hiding (Bindings)
import CSPM.Interpreter.Types as Types
import CSPM.Interpreter.Bindings as Bindings
import CSPM.Interpreter.PatternMatcher
import CSPM.Interpreter.Eval
import qualified CSPM.Interpreter.Prefix as BasePrefix
import CSPM.Interpreter.SSet as SSet
import Data.List as List
import Control.Monad
initPrefix :: PrefixState -> GenericBufferPrefix
initPrefix = lookAhead . BasePrefix.initPrefix
viewPrefixState :: GenericBufferPrefix -> Core.PrefixFieldView INT
viewPrefixState p = case p of
GBOut (h:_) _ -> Core.FieldOut h
GBOut [] _ -> error "GenericBuffer.hs : viewPrefixState : internal error : empty buffer"
GBInput _ -> Core.FieldIn
GBInputGuard g _ -> Core.FieldGuard g
GBInputGeneric _ _ -> Core.FieldIn
GBFinished _ -> error "GenericBuffer.hs : viewPrefixState : no fields left"
prefixStateNext :: GenericBufferPrefix -> Field -> Maybe GenericBufferPrefix
prefixStateNext gbPrefix field = case gbPrefix of
GBOut [h] p -> do
guard $ h == field
liftM lookAhead $ BasePrefix.prefixStateNext p (error "GenericBufferDummyFields")
GBOut (h:t) p -> do
guard $ h == field
return $ GBOut t p
GBInput p -> liftM lookAhead $ BasePrefix.prefixStateNext p field
GBInputGuard g p -> do
guard $ field `SSet.member` g
liftM lookAhead $ BasePrefix.prefixStateNext p field
GBInputGeneric b p -> return $ GBInputGeneric (field:b) p
GBFinished _ -> error "GenericBuffer.hs : prefixStateNext : no fields left"
prefixStateFinalize :: GenericBufferPrefix -> Maybe PrefixState
prefixStateFinalize gbPrefix = case gbPrefix of
GBInputGeneric buffer p -> case buffer of
[] -> error "GenericBuffer.hs : empty dot tuple"
[v] -> BasePrefix.prefixStateNext p v >>= BasePrefix.prefixStateFinalize
l -> BasePrefix.prefixStateNext p (VDotTuple $ reverse l)
>>= BasePrefix.prefixStateFinalize
GBFinished p -> BasePrefix.prefixStateFinalize p
_ -> error "GenericBuffer.hs : stateError"
lookAhead :: PrefixState -> GenericBufferPrefix
lookAhead p | List.null $ prefixFields p = GBFinished p
lookAhead p | isLastInputField p = GBInputGeneric [] p
lookAhead p = case BasePrefix.viewPrefixState p of
Core.FieldOut v -> case v of
(VDotTuple l) -> GBOut (splitTuple l) p
x -> GBOut [x] p
Core.FieldIn -> GBInput p
Core.FieldGuard g -> GBInputGuard g p
isLastInputField :: PrefixState -> Bool
isLastInputField (PrefixState {
prefixFields = [unLabel -> InComm (unLabel -> VarPat _ )]
}) = True
isLastInputField _ = False
splitTuple :: [Value] -> [Value]
splitTuple [] = []
splitTuple l@(h:t) = case h of
VConstructor c | not $ List.null $ constrFields c
-> VDotTuple (take len l) : splitTuple (drop len l)
where len = 1 + (length $ constrFields c)
_ -> h : splitTuple t