From: Christiaan Baaij Date: Wed, 9 Sep 2009 10:11:43 +0000 (+0200) Subject: Add support for multiple alts in case statements X-Git-Url: https://git.stderr.nl/gitweb?a=commitdiff_plain;h=cf39807bf7b8424b6db0bc07a922a19972786735;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git Add support for multiple alts in case statements --- diff --git "a/c\316\273ash/CLasH/VHDL/Generate.hs" "b/c\316\273ash/CLasH/VHDL/Generate.hs" index da8be8a..8ed2575 100644 --- "a/c\316\273ash/CLasH/VHDL/Generate.hs" +++ "b/c\316\273ash/CLasH/VHDL/Generate.hs" @@ -232,15 +232,21 @@ mkConcSm (bndr, expr@(CoreSyn.Case (CoreSyn.Var scrut) b ty [alt])) -- binders in the alts and only variables in the case values and a variable -- for a scrutinee. We check the constructor of the second alt, since the -- first is the default case, if there is any. -mkConcSm (bndr, (CoreSyn.Case (CoreSyn.Var scrut) b ty [(_, _, CoreSyn.Var false), (con, _, CoreSyn.Var true)])) = do +-- mkConcSm (bndr, (CoreSyn.Case (CoreSyn.Var scrut) b ty [(_, _, CoreSyn.Var false), (con, _, CoreSyn.Var true)])) = do +-- scrut' <- MonadState.lift tsType $ varToVHDLExpr scrut +-- altcon <- MonadState.lift tsType $ altconToVHDLExpr con +-- let cond_expr = scrut' AST.:=: altcon +-- true_expr <- MonadState.lift tsType $ varToVHDLExpr true +-- false_expr <- MonadState.lift tsType $ varToVHDLExpr false +-- return ([mkCondAssign (Left bndr) cond_expr true_expr false_expr], []) + +mkConcSm (bndr, (CoreSyn.Case (CoreSyn.Var scrut) _ _ (alt:alts))) = do --error "\nVHDL.mkConcSm: Not in normal form: Case statement with more than two alternatives" scrut' <- MonadState.lift tsType $ varToVHDLExpr scrut - altcon <- MonadState.lift tsType $ altconToVHDLExpr con - let cond_expr = scrut' AST.:=: altcon - true_expr <- MonadState.lift tsType $ varToVHDLExpr true - false_expr <- MonadState.lift tsType $ varToVHDLExpr false - return ([mkCondAssign (Left bndr) cond_expr true_expr false_expr], []) + altcons <- MonadState.lift tsType $ mapM (altconToVHDLExpr . (\(con,_,_) -> con)) (alts ++ [alt]) + let cond_exprs = map (\x -> scrut' AST.:=: x) (init altcons) + exprs <- MonadState.lift tsType $ mapM (varToVHDLExpr . (\(_,_,CoreSyn.Var expr) -> expr)) (alts ++ [alt]) + return ([mkAltsAssign (Left bndr) cond_exprs exprs], []) -mkConcSm (_, (CoreSyn.Case (CoreSyn.Var _) _ _ alts)) = error "\nVHDL.mkConcSm: Not in normal form: Case statement with more than two alternatives" mkConcSm (_, CoreSyn.Case _ _ _ _) = error "\nVHDL.mkConcSm: Not in normal form: Case statement has does not have a simple variable as scrutinee" mkConcSm (bndr, expr) = error $ "\nVHDL.mkConcSM: Unsupported binding in let expression: " ++ pprString bndr ++ " = " ++ pprString expr diff --git "a/c\316\273ash/CLasH/VHDL/VHDLTools.hs" "b/c\316\273ash/CLasH/VHDL/VHDLTools.hs" index 5fc3473..785b528 100644 --- "a/c\316\273ash/CLasH/VHDL/VHDLTools.hs" +++ "b/c\316\273ash/CLasH/VHDL/VHDLTools.hs" @@ -73,7 +73,7 @@ mkAssign dst cond false_expr = whenelse = case cond of Just (cond_expr, true_expr) -> let - true_wform = AST.Wform [AST.WformElem true_expr Nothing] + true_wform = AST.Wform [AST.WformElem true_expr Nothing] in [AST.WhenElse true_wform cond_expr] Nothing -> [] @@ -85,6 +85,31 @@ mkAssign dst cond false_expr = in AST.CSSASm assign +mkAltsAssign :: + Either CoreBndr AST.VHDLName -- ^ The signal to assign to + -> [AST.Expr] -- ^ The conditions + -> [AST.Expr] -- ^ The expressions + -> AST.ConcSm -- ^ The Alt assigns +mkAltsAssign dst conds exprs + | (length conds) /= ((length exprs) - 1) = error $ "\nVHDLTools.mkAltsAssign: conditions expression mismatch" + | otherwise = + let + whenelses = zipWith mkWhenElse conds exprs + false_wform = AST.Wform [AST.WformElem (last exprs) Nothing] + dst_name = case dst of + Left bndr -> AST.NSimple (varToVHDLId bndr) + Right name -> name + assign = dst_name AST.:<==: (AST.ConWforms whenelses false_wform Nothing) + in + AST.CSSASm assign + where + mkWhenElse :: AST.Expr -> AST.Expr -> AST.WhenElse + mkWhenElse cond true_expr = + let + true_wform = AST.Wform [AST.WformElem true_expr Nothing] + in + AST.WhenElse true_wform cond + mkAssocElems :: [AST.Expr] -- ^ The argument that are applied to function -> AST.VHDLName -- ^ The binder in which to store the result @@ -163,7 +188,7 @@ altconToVHDLExpr :: CoreSyn.AltCon -> TypeSession AST.Expr altconToVHDLExpr (DataAlt dc) = dataconToVHDLExpr dc altconToVHDLExpr (LitAlt _) = error "\nVHDL.conToVHDLExpr: Literals not support in case alternatives yet" -altconToVHDLExpr DEFAULT = error "\nVHDL.conToVHDLExpr: DEFAULT alternative should not occur here!" +altconToVHDLExpr DEFAULT = return $ AST.PrimLit "undefined" -- error "\nVHDL.conToVHDLExpr: DEFAULT alternative should not occur here!" -- Turn a datacon (without arguments!) into a VHDL expression. dataconToVHDLExpr :: DataCon.DataCon -> TypeSession AST.Expr