module CaseOpt where import PosCode import State import IntState import Info import Syntax import SyntaxUtil import Maybe import Id optFatBar :: PosExp -> PosExp -> State0 d (IntState, b) (PosExp, (IntState, b)) optFatBar e1 e2 = failExp e1 >>>= \ canfail -> if canfail then failExp e2 >>>= \ canfail -> unitS (PosExpFatBar canfail e1 e2) else unitS e1 failExp :: PosExp -> d -> (IntState, b) -> (Bool, (IntState, b)) failExp (PosExpCase pos exp alts) = anyMissing alts >>>= \ notfull -> mapS failAlt alts >>>= \ alts -> unitS (notfull || or alts) failExp (PosExpFatBar b exp1 exp2) = unitS b failExp (PosExpFail) = unitS True -- Might need to check if exp1 is True, in which case there can be no fail failExp (PosExpIf pos g exp1 exp2 exp3) = failExp exp3 -- the fail is always in the else branch failExp (PosExpLet rec pos bindings exp) = failExp exp -- used in lhs-patterns failExp e = unitS False failAlt :: PosAlt -> d -> (IntState, b) -> (Bool, (IntState, b)) failAlt (PosAltCon pos con args exp) = failExp exp failAlt (PosAltInt pos int b exp) = failExp exp anyMissing :: [PosAlt] -> t -> (IntState, b) -> (Bool, (IntState, b)) anyMissing (PosAltInt pos int b exp:alts) down up@(state,_) = (True,up) anyMissing (PosAltCon pos con args exp:alts) down up@(state,_) = let all = ( constrsI . fromJust . lookupIS state . belongstoI . fromJust . lookupIS state ) con has = con : map ( \ (PosAltCon pos con args exp) -> con ) alts missing = (not . null . filter (`notElem` has)) all in (missing,up) --- singleVars :: Exp Id -> t -> (IntState, b) -> (Maybe [Maybe (Pos, Id)], (IntState, b)) singleVars (ExpApplication _ (ExpCon _ con:es)) down up@(state,_) = ( if ( (1==) . length . constrsI . fromJust . lookupIS state . belongstoI . fromJust . lookupIS state) con -- only one constructor && all isVar es -- and all arguments are variables (or wildcards) then Just (map getPosI es) else Nothing , up ) singleVars _ down up = (Nothing,up) getPosI :: Exp id -> Maybe (Pos, id) getPosI (ExpVar pos i) = Just (pos, i) getPosI (PatWildcard pos) = Nothing