import PrimOp ( PrimOp(..) )
import SimplMonad
import TysWiredIn ( trueDataCon, falseDataCon )
+import TyCon ( tyConDataCons, isEnumerationTyCon )
+import DataCon ( dataConTag, fIRST_TAG )
+import Type ( splitTyConApp_maybe )
import Char ( ord, chr )
import Outputable
\end{code}
\begin{code}
+tryPrimOp TagToEnumOp [Type ty, Con (Literal (MachInt i _)) _]
+ | isEnumerationTyCon tycon = Just (Con (DataCon dc) [])
+ | otherwise = panic "tryPrimOp: tagToEnum# on non-enumeration type"
+ where tag = fromInteger i
+ constrs = tyConDataCons tycon
+ (dc:_) = [ dc | dc <- constrs, tag == dataConTag dc ]
+ (Just (tycon,_)) = splitTyConApp_maybe ty
+
+tryPrimOp DataToTagOp [Type ty, Con (DataCon dc) _]
+ = Just (Con (Literal (mkMachInt (toInteger (dataConTag dc - fIRST_TAG)))) [])
+tryPrimOp DataToTagOp [Type ty, Var x]
+ | unfolding_is_constr
+ = Just (Con (Literal (mkMachInt (toInteger (dataConTag dc - fIRST_TAG)))) [])
+ where
+ unfolding = getIdUnfolding var
+ CoreUnfolding form guidance unf_template = unfolding
+ unfolding_is_constr = case unf_template of
+ Con con@(DataCon _) _ -> conOkForAlt con
+ other -> False
+ Con (DataCon dc) con_args = unf_template
+\end{code}
+
+\begin{code}
tryPrimOp op args
= case args of
[Con (Literal (MachChar char_lit)) _] -> oneCharLit op char_lit