-- 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
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 -> []
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
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