uhc-util-0.1.6.6: src/UHC/Util/CHR/GTerm/AST.hs
-------------------------------------------------------------------------------------------
--- Generic terms describing constraints, providing interpretation to AST of your choice
-------------------------------------------------------------------------------------------
module UHC.Util.CHR.GTerm.AST
( GTm(..)
, GTermAs(..)
, gtermasFail
)
where
import Data.Char
import Data.Typeable
import GHC.Generics
import Control.Monad.Except
import UHC.Util.Pretty as PP
import UHC.Util.Utils
-------------------------------------------------------------------------------------------
--- Term language/AST
-------------------------------------------------------------------------------------------
-- | Terms
data GTm
= GTm_Var String -- ^ variable (to be substituted)
| GTm_Int Integer -- ^ int value (for arithmetic)
| GTm_Str String -- ^ string value
| GTm_Con String [GTm] -- ^ general term structure
| GTm_Nil -- ^ special case: list nil
| GTm_Cns GTm GTm -- ^ special case: list cons
deriving (Show, Eq, Ord, Typeable, Generic)
instance PP GTm where
pp (GTm_Var v ) = pp v -- "v" >|< v
pp (GTm_Con c [] ) = pp c
pp (GTm_Con c@(h:_) [a1,a2])
| not (isAlpha h) = ppParens $ a1 >#< c >#< a2
pp (GTm_Con c as ) = ppParens $ c >#< ppSpaces as
pp (GTm_Nil ) = pp "[]"
pp (GTm_Cns h t ) = "[" >|< h >#< ":" >#< t >|< "]"
pp (GTm_Int i ) = pp i
pp (GTm_Str s ) = pp $ show s
-------------------------------------------------------------------------------------------
--- Term interpretation in context of CHR
-------------------------------------------------------------------------------------------
-- | Interpretation monad, which is partial
type GTermAsM = Either PP_Doc
-- | Term interpretation in context of CHR
class GTermAs cnstr guard bprio prio tm
| cnstr -> guard bprio prio tm
, guard -> cnstr bprio prio tm
, bprio -> cnstr guard prio tm
, prio -> cnstr guard bprio tm
, tm -> cnstr guard bprio prio
where
--
asTm :: GTm -> GTermAsM tm
-- | as list, if matches/possible. Only to be invoked for GTm_Cns
asTmList :: GTm -> GTermAsM ([tm], Maybe tm)
asTmList (GTm_Cns h GTm_Nil ) = asTm h >>= \h -> return ([h], Nothing)
asTmList (GTm_Cns h t@(GTm_Cns _ _)) = asTm h >>= \h -> asTmList t >>= \(t,mt) -> return ((h:t),mt)
asTmList (GTm_Cns h t ) = asTm h >>= \h -> asTm t >>= \t -> return ([h], Just t)
asTmList _ = panic "GTermAs.asTmList: should not happen, not intended to be called with non GTm_Cns"
--
asHeadConstraint :: GTm -> GTermAsM cnstr
--
asBodyConstraint :: GTm -> GTermAsM cnstr
--
asGuard :: GTm -> GTermAsM guard
--
asHeadBacktrackPrio :: GTm -> GTermAsM bprio
--
asAltBacktrackPrio :: GTm -> GTermAsM bprio
--
asRulePrio :: GTm -> GTermAsM prio
-- | Fail the interpretation
gtermasFail :: GTm -> String -> GTermAsM a
gtermasFail t m = throwError $ "GTerm interpretation failure" >-< indent 2 ("why :" >#< m >-< "term:" >#< t)