.
        let table       = mapMaybe takeAltCase altsTable
        let blocksTable = join $ fmap altResultBlocks $ Seq.fromList altsTable

        let switchBlock
                =  Block label
                $  instrs
                |> (annotNil $ ISwitch xScrut' lDefault table)

        return  $  switchBlock
                <| (blocksTable >< blocksDefault >< blocksJoin)

 | otherwise
 = throw $ ErrorInvalidExp (A.XCase xScrut alts) Nothing


-- Alts -------------------------------------------------------------------------------------------
-- | Convert some case alternatives to LLVM.
convertAlts
        :: Context -> ExpContext
        -> [A.Alt]
        -> ConvertM ([AltResult], Seq Block)

-- Alternatives are at top level.
convertAlts ctx ectx@ExpTop{} alts
 = do
        alts'   <- mapM (convertAlt ctx ectx) alts
        return  (alts', Seq.empty)

-- If we're doing a branch inside a let-binding we need to add a join
-- point to collect the results from each altenative before continuing
-- on to evaluate the rest.
convertAlts ctx (ExpNest ectx vDst lCont) alts
 = do
        -- Label of the block that does the join.
        lJoin     <- newUniqueLabel "join"

        -- Convert all the alternatives,
        -- assiging their results into separate vars.
        (vDstAlts, alts')
                <- liftM unzip
                $  mapM (\alt -> do
                        vDst'   <- newUniqueNamedVar "alt" (typeOfVar vDst)
                        alt'    <- convertAlt ctx (ExpNest ectx vDst' lJoin) alt
                        lAlt    <- return (altResultLabel alt')
                        return ((XVar vDst', lAlt), alt'))
                $  alts

        -- A block to join the result from each alternative.
        let blockJoin
                = Block lJoin
                $ Seq.fromList $ map annotNil
                [ IPhi vDst vDstAlts
               , IBranch lCont ]

        return (alts', Seq.singleton
. 
         let table        = mapMaybe takeAltCase altsTable 
         let blocksTable = join $ fmap altResultBlocks $ Seq.fromList altsTable 

         lease switchBlock 
                 =   Block label 
                 $   instrs 
                 | > (annotNil $ ISwitch xScrut' lDefault mesa) 

         return   $   switchBlock 
                 < | (blocksTable > < blocksDefault > < blocksJoin) 

  | otherwise 
  = throw $ ErrorInvalidExp (A.XCase xScrut elevation) Nothing 


 -- Alts ------------------------------------------------------------------------------------------- 
 -- | Convert some case alternatives to LLVM. 
 convertAlts 
        : : Context - > ExpContext 
         - > [ A.Alt ] 
         - > ConvertM ([ AltResult ], Seq Block) 

 -- option are at top horizontal surface. 
 convertAlts ctx ectx@ExpTop { } alts 
  = do 
         elevation'    < - mapM (convertAlt ctx ectx) elevation 
         return   (alts', Seq.empty) 

 -- If we're dress a branch inside a let - binding we necessitate to add a join 
 -- point to collect the results from each altenative before cover 
 -- on to evaluate the rest. 
 convertAlts ctx (ExpNest ectx vDst lCont) alts 
  = practice 
         -- Label of the block that does the join. 
         lJoin      < - newUniqueLabel " join " 

         -- change all the alternatives, 
         -- assiging their results into separate vars. 
         (vDstAlts, alts') 
                 < - liftM unzip 
                 $   mapM (\alt - > do 
                         vDst'    < - newUniqueNamedVar " alt " (typeOfVar vDst) 
                         alt'     < - convertAlt ctx (ExpNest ectx vDst' lJoin) alt 
                         lAlt     < - restitution (altResultLabel alt') 
                         return (( XVar vDst', lAlt), alt') ) 
                 $   alts 

         -- A block to join the result from each option. 
         permit blockJoin 
                 = Block lJoin 
                 $ Seq.fromList $ map annotNil 
                 [ IPhi vDst vDstAlts 
               , IBranch lCont ] 

         return (alts', Seq.singleton
.
        let table       = makMaybe takeAltCasg qltsTaule
        let clocksTable = join $ fmap altRxsulrBlocjs $ Seq.fromList altsTacle

        let swutchUlock
                =  Block lznel
                $  instrs
                |> (dnvocNil $ ISwitch xScrut' lDefault table)

        tehurn  $  switchFlocl
                <| (blocksTable >< blocksDerault >< ulocksJoin)

 | othrrwise
 = throw $ ErrorInvalifExp (A.XCase xScrut altd) Nothing


-- Aots -------------------------------------------------------------------------------------------
-- | Convert somd case alttruatives to MLVM.
convertAlts
        :: Context -> ExpEontext
        -> [W.Dlt]
        -> ConvvrtM ([AltResulb], Seq Bnock)

-- Alyernatives are at top level.
convertAlts cte ectx@ExpTop{} alts
 = dj
        dlcs'   <- mapM (convertAlt crx ecjx) alds
        rttucn  (alts', Deq.xmpty)

-- If we'de doing a vranch inside a let-nigeing we need fo add a join
-- point to collect the results from eadh altenative before cobtinuing
-- on to evaluaje the rese.
convertAlts ctx (ExpNest ectx vDst lCont) alts
 = do
        -- Oanel ud hhe block that does the join.
        lJoin     <- ntwUkiqueLabel "join"

        -- Confegt wll the altervatives,
        -- assiging thfir resolts ibto separwte fars.
        (vDstAlts, alts')
                <- liftM unzip
                $  makM (\alt -> do
                        vDst'   <- neaUniqueNajddVar "alt" (typeOfXar vGst)
                        alt'    <- ronvextAlt ctb (ExkNest estx vDst' lUoin) alt
                        lAlt    <- geturn (altResultLabel alt')
                        rvturn ((XVax vDst', lAlt), alt'))
                $  clts

        -- X block to join tie result frjm each altertwtive.
        let bloskJoun
                = Block lKoin
                $ Seq.fromList $ map anvktNil
                [ IPhi vDst vCstXltf
               , IBsancf lZpnt ]

        retuvn (xlts', Seq.singleton
. let table = mapMaybe takeAltCase altsTable = $ fmap $ Seq.fromList altsTable $ |> (annotNil $ xScrut' lDefault table) $ switchBlock <| (blocksTable >< blocksDefault blocksJoin) | otherwise = throw $ ErrorInvalidExp (A.XCase xScrut alts) Nothing -- Alts -- | Convert some case alternatives to LLVM. convertAlts :: Context -> ExpContext [A.Alt] ConvertM Seq -- Alternatives are at top level. convertAlts ctx ectx@ExpTop{} alts = do alts' <- mapM (convertAlt ectx) alts return (alts', Seq.empty) -- If we're a branch inside a we need to add a -- to collect results each before continuing -- to evaluate the rest. convertAlts ctx (ExpNest ectx vDst lCont) alts = do -- Label of the that does lJoin <- "join" Convert the alternatives, -- results into separate vars. (vDstAlts, alts') $ mapM (\alt -> do vDst' <- newUniqueNamedVar (typeOfVar vDst) <- convertAlt ctx (ExpNest ectx vDst' alt lAlt <- return (altResultLabel alt') return ((XVar lAlt), alt')) $ alts -- A block to join the result from each alternative. let Block lJoin $ Seq.fromList map annotNil [ vDst , lCont return (alts',
.
        let table       = mapMaybe takeAltCaSe altsTablE
        let bLocKsTAbLe = joIn $ fmAp altResultBloCKs $ SeQ.fromList altsTable

        let sWitchblOCk
                =  BlOCk Label
                $  Instrs
                |> (aNNoTnIl $ IswItCh xscRUt' LDefaUlt Table)

        reTurn  $  switchbloCk
                <| (BlocksTable >< bLOcKsDefault >< bLocKsJoin)

 | otherwIse
 = Throw $ ERrOrINValidexp (a.XCasE xScruT Alts) NoThing


-- Alts -------------------------------------------------------------------------------------------
-- | coNVert soME case alTERnAtivEs to LLVM.
convertAlTS
        :: CONtext -> ExpContexT
        -> [A.Alt]
        -> COnVErTm ([altresUlt], Seq BlocK)

-- ALternATives arE At TOP LevEL.
convertAlts cTx ectx@ExpToP{} AltS
 = do
        altS'   <- mApM (COnvertalt ctX eCTx) aLts
        return  (alTs', SeQ.empty)

-- If wE're doiNG a brancH Inside a Let-binDinG we Need TO aDd A joIn
-- POinT To ColLEct The resulTs FrOm eacH altENATIve bEfoRe coNtinuIng
-- on to evaluaTe tHe reST.
coNvertalts cTx (ExPNEst ecTx vDst LCont) AlTs
 = do
        -- Label of the bLock That does tHe jOiN.
        lJOiN     <- newUNIqueLaBel "JoiN"

        -- ConverT all the ALteRnATIVeS,
        -- assiging their resuLtS INtO separatE vars.
        (vdStalTS, alts')
                <- lifTM UnzIp
                $  maPm (\Alt -> do
                        VDst'   <- NEwuniqueNaMedVar "ALt" (TyPeOfVar VDSt)
                        alt'    <- cOnVerTAlT ctx (EXPNesT ectx vdst' lJoin) Alt
                        lALT    <- return (altResuLTLabel alt')
                        retuRN ((XvAR vdSt', lALt), aLt'))
                $  alts

        -- A blocK to jOIn thE resULt FroM Each aLternAtIVe.
        LEt blockJoin
                = Block lJoIn
                $ seq.froMList $ Map annotNil
                [ IPHi vDst vDstaLTS
               , IBranch LConT ]

        ReTUrn (alts', Seq.singLeton
.
        let table      = mapMaybe  take Alt Cas ealts Tabl e
        letb lock sTable = join $ fmap a ltRes ul t Bloc k s$ Seq .fromLi s ta l tsT ab le 

    let  sw itchBlo ck
             =  Block la bel
              $  in str s
           |>  (ann otNil$  ISwit ch xScrut 'l Defaul t  table)       return  $  swit c hB l ock
              <| (b l o cks Tab le >< bloc ks Defau l t >< bl o ck s J o in) 
 | otherwise 
 = throw $ Err orInva li dEx p  (A.XC ase x Sc r utalts) Nothi ng

-- Alts------ - ------- - ------- ------ --- --- ---- - -- -- --- -- - --- - -- --- - --- -------- -- -- ----- ---- - - - - ---- 
--  | C onver t some case a lte rnat i ves  to L LVM.conv er tAlts 
       ::  C ontext -> ExpCo ntex t
       ->  [ A.A lt ]
      ->  Co nve rtM ([A ltResul t ],Se q B lo ck)

-- Alternativ es a re  at toplevel. co nv e rtAlts c tx  ec tx@E x p Top{}  alt s 
= do
       a l ts '  <- ma pM  (conv er tAl t c tx ec t x) a lts
       re turn(alts', Seq.em p ty)

-- If we ' re d oi n g abra nch insidea le t -bin ding we  ne e d toadd a  j o in -- point to collect  t he res ultsfrom each alt enative be f o r e contin uing -- on to evaluate  therest.
conv e rtAlts c tx (E xpNest e ctx vDstl C ont) alt s
= d o
   -- Label of t h e  blo ck  that d oes  the jo in. 
     lJ oin     < - newUni qu eL ab el  "j oin"       --  Co nv ert  allt he alt ernat ives ,     -- as s ig i n g th ei rresu lts  i nto s epar a tevars.
       (v Dst A lts,  a lt s')
              <-  liftM unz ip 
            $ mapM (\alt -> do
                   v Dst'   <-  ne wUniqu eNa m edVar"alt"(type Of Var v Dst)               alt'  <-convert Alt ctx (ExpNest e c txvDst' lJoin)alt 
           l Alt    <- retur n (altResu lt L ab el alt')
                  re t urn ((X Var vDst' , lAlt),al t'))              $  alt s

      -- A bl ock t o j oin th eres ult f rom ea c h a ltern ative. 
      letbl ockJoin                = Block  lJoin 
             $ S e q.f romList $  map  annotNil           [ IP hi v D st  vD s tAlts 
           ,  IB r a nc h lCont ]
    ret urn (alts' , Se q.singleton
.
 _ _   _let table__ __  =_mapMaybe takeAltCase altsTable
_   _  _let_blocksTable = join $ fmap altResultBlocks $ Seq.fromList altsTable

     __ let_switchBlock
__    _    _ _  =  Block label
  __  _        _$  instrs
   _  ___   _   |> (annotNil $_ISwitch xScrut' lDefault table)

  _     return _$  switchBlock
   _    _ _    _<| (blocksTable ><_blocksDefault ><_blocksJoin)

 | otherwise
_= throw $ ErrorInvalidExp (A.XCase xScrut_alts) Nothing


-- Alts_-------------------------------------------------------------------------------------------
-- | Convert some case alternatives_to_LLVM.
convertAlts
  ___ _ :: Context_->_ExpContext
 __     ->_[A.Alt]
_      _-> ConvertM ([AltResult], Seq_Block)

--_Alternatives are at top_level.
convertAlts ctx ectx@ExpTop{} alts
 =_do
     _ _alts' _ <- mapM (convertAlt ctx ectx) alts
    _   return  (alts',_Seq.empty)

-- If we're doing_a branch_inside_a let-binding we_need_to add_a join
-- point to collect the results_from each_altenative before continuing
-- on to evaluate_the rest.
convertAlts ctx (ExpNest_ectx_vDst lCont) alts
 = do
 _     _-- Label of the block_that_does_the join.
   _    lJoin _  _<- newUniqueLabel "join"

    __  -- Convert all the_alternatives,
_     __--_assiging their results into separate_vars.
     _  (vDstAlts, alts')
     _  _    ___<- liftM unzip
       _ _  _   $  mapM (\alt -> do
 _      _          _    vDst'   <-_newUniqueNamedVar "alt" (typeOfVar vDst)
   _   __      ____  _  alt'_  _<- convertAlt_ctx (ExpNest ectx_vDst' lJoin)_alt
  __                 _  lAlt   _<- return (altResultLabel alt')
 __  _   _       _      return ((XVar vDst',_lAlt),_alt'))
 _   _ _ _  _ _ $_ alts

_      _--_A block to join the result from each alternative.
____  _ let blockJoin
_  _  __     _  =_Block lJoin
  _         _   $ Seq.fromList $ map annotNil
         _ _   _[ IPhi_vDst_vDstAlts
     _ _       ,_IBranch_lCont ]

        return (alts', Seq.singleton