{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Strict #-}

module GHC.CmmToAsm.Wasm.Utils
  ( naturalNarrowing,
    widthMax,
    detEltsUFM,
    detEltsUniqMap,
    builderCommas,
  )
where

import Data.ByteString.Builder
import Data.List (intersperse, sortOn)
import GHC.Cmm
import GHC.Prelude
import GHC.Types.Unique.FM
import GHC.Types.Unique.Map

naturalNarrowing :: Width -> Integer -> Integer
naturalNarrowing :: Width -> Integer -> Integer
naturalNarrowing Width
w Integer
i
  | Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = Width -> Integer -> Integer
narrowS Width
w Integer
i
  | Bool
otherwise = Width -> Integer -> Integer
narrowU Width
w Integer
i

widthMax :: Width -> Integer
widthMax :: Width -> Integer
widthMax Width
w = (Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Width -> Int
widthInBits Width
w) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

detEltsUFM :: Ord k => UniqFM k0 (k, a) -> [(k, a)]
detEltsUFM :: forall k k0 a. Ord k => UniqFM k0 (k, a) -> [(k, a)]
detEltsUFM = ((k, a) -> k) -> [(k, a)] -> [(k, a)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (k, a) -> k
forall a b. (a, b) -> a
fst ([(k, a)] -> [(k, a)])
-> (UniqFM k0 (k, a) -> [(k, a)]) -> UniqFM k0 (k, a) -> [(k, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UniqFM k0 (k, a) -> [(k, a)]
forall key elt. UniqFM key elt -> [elt]
nonDetEltsUFM

detEltsUniqMap :: Ord k => UniqMap k a -> [(k, a)]
detEltsUniqMap :: forall k a. Ord k => UniqMap k a -> [(k, a)]
detEltsUniqMap = ((k, a) -> k) -> [(k, a)] -> [(k, a)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (k, a) -> k
forall a b. (a, b) -> a
fst ([(k, a)] -> [(k, a)])
-> (UniqMap k a -> [(k, a)]) -> UniqMap k a -> [(k, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UniqMap k a -> [(k, a)]
forall k a. UniqMap k a -> [(k, a)]
nonDetEltsUniqMap

builderCommas :: (a -> Builder) -> [a] -> Builder
builderCommas :: forall a. (a -> Builder) -> [a] -> Builder
builderCommas a -> Builder
f [a]
xs = [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat (Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse Builder
", " ((a -> Builder) -> [a] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map a -> Builder
f [a]
xs))