Learn flattenExpr about single alt Case expressions.
[matthijs/master-project/cλash.git] / Flatten.hs
index 7dc261e8d23138f90865b0f083ec45f04c71f598..14fd781c5c6653ca989c393eb038f5af42cb38ab 100644 (file)
@@ -294,6 +294,52 @@ flattenExpr binds app@(App _ _) = do
         then error $ "Passing lambda expression or function as a function argument not supported: " ++ (showSDoc $ ppr arg)
         else flat 
 
+flattenExpr binds l@(Let (NonRec b bexpr) expr) = do
+  (b_args, b_res) <- flattenExpr binds bexpr
+  if not (null b_args)
+    then
+      error $ "Higher order functions not supported in let expression: " ++ (showSDoc $ ppr l)
+    else
+      let binds' = (b, Left b_res) : binds in
+      flattenExpr binds' expr
+
+flattenExpr binds l@(Let (Rec _) _) = error $ "Recursive let definitions not supported: " ++ (showSDoc $ ppr l)
+
+flattenExpr binds expr@(Case (Var v) b _ alts) =
+  case alts of
+    [alt] -> flattenSingleAltCaseExpr binds v b alt
+    otherwise -> error $ "Multiple alternative case expression not supported: " ++ (showSDoc $ ppr expr)
+  where
+    flattenSingleAltCaseExpr ::
+      BindMap
+                                -- A list of bindings in effect
+      -> Var.Var                -- The scrutinee
+      -> CoreBndr               -- The binder to bind the scrutinee to
+      -> CoreAlt                -- The single alternative
+      -> FlattenState ( [SignalDefMap], SignalUseMap)
+                                           -- See expandExpr
+    flattenSingleAltCaseExpr binds v b alt@(DataAlt datacon, bind_vars, expr) =
+      if not (DataCon.isTupleCon datacon) 
+        then
+          error $ "Dataconstructors other than tuple constructors not supported in case pattern of alternative: " ++ (showSDoc $ ppr alt)
+        else
+          let
+            -- Lookup the scrutinee (which must be a variable bound to a tuple) in
+            -- the existing bindings list and get the portname map for each of
+            -- it's elements.
+            Left (Tuple tuple_sigs) = Maybe.fromMaybe 
+              (error $ "Case expression uses unknown scrutinee " ++ Name.getOccString v)
+              (lookup v binds)
+            -- TODO include b in the binds list
+            -- Merge our existing binds with the new binds.
+            binds' = (zip bind_vars (map Left tuple_sigs)) ++ binds 
+          in
+            -- Expand the expression with the new binds list
+            flattenExpr binds' expr
+    flattenSingleAltCaseExpr _ _ _ alt = error $ "Case patterns other than data constructors not supported in case alternative: " ++ (showSDoc $ ppr alt)
+
+
+      
 flattenExpr _ _ = do
   return ([], Tuple [])