+ let arg_tyss = map DataCon.dataConRepArgTys dcs
+ let enum_ty = EnumType name (map (nameToString . DataCon.dataConName) dcs)
+ case (concat arg_tyss) of
+ -- No arguments, this is just an enumeration type
+ [] -> return (Right enum_ty)
+ -- At least one argument, this becomes an aggregate type
+ _ -> do
+ -- Resolve any type arguments to this type
+ let real_arg_tyss = map (map (CoreSubst.substTy subst)) arg_tyss
+ -- Remove any state type fields
+ let real_arg_tyss_nostate = map (filter (\x -> not (isStateType x))) real_arg_tyss
+ elem_htyss_either <- mapM (mapM mkHTypeEither) real_arg_tyss_nostate
+ let (errors, elem_htyss) = unzip (map Either.partitionEithers elem_htyss_either)
+ case (all null errors) of
+ True -> case (dcs, concat elem_htyss) of
+ -- A single constructor with a single (non-state) field?
+ ([dc], [elem_hty]) -> return $ Right elem_hty
+ -- If we get here, then all of the argument types were state
+ -- types (we check for enumeration types at the top). Not
+ -- sure how to handle this, so error out for now.
+ (_, []) -> error $ "ADT with only State elements (or something like that?) Dunno how to handle this yet. Tycon: " ++ pprString tycon ++ " Arguments: " ++ pprString args
+ -- A full ADT (with multiple fields and one or multiple
+ -- constructors).
+ (_, elem_htys) -> do
+ let (_, fieldss) = List.mapAccumL (List.mapAccumL label_field) labels elem_htyss
+ -- Only put in an enumeration as part of the aggregation
+ -- when there are multiple datacons
+ let enum_ty_part = case dcs of
+ [dc] -> Nothing
+ _ -> Just ("constructor", enum_ty)
+ -- Create the AggrType HType
+ return $ Right $ AggrType name enum_ty_part fieldss
+ -- There were errors in element types
+ False -> return $ Left $
+ "\nVHDLTools.mkTyConHType: Can not construct type for: " ++ pprString tycon ++ "\n because no type can be construced for some of the arguments.\n"
+ ++ (concat $ concat errors)