hasmtlib-1.2.0: src/Language/Hasmtlib/Internal/Render.hs
module Language.Hasmtlib.Internal.Render where
import Data.ByteString.Builder
import Data.Foldable (foldl')
import GHC.TypeNats
-- | Render values to their SMTLib2-Lisp form, represented as @Builder@.
class Render a where
render :: a -> Builder
instance Render Bool where
render b = if b then "true" else "false"
{-# INLINEABLE render #-}
instance Render Nat where
render = integerDec . fromIntegral
{-# INLINEABLE render #-}
instance Render Integer where
render x
| x < 0 = "(- " <> integerDec (abs x) <> ")"
| otherwise = integerDec x
{-# INLINEABLE render #-}
instance Render Double where
render x
| x < 0 = "(- " <> formatDouble standardDefaultPrecision (abs x) <> ")"
| otherwise = formatDouble standardDefaultPrecision x
{-# INLINEABLE render #-}
instance Render Builder where
render = id
{-# INLINEABLE render #-}
renderUnary :: Render a => Builder -> a -> Builder
renderUnary op x = "(" <> op <> " " <> render x <> ")"
{-# INLINEABLE renderUnary #-}
renderBinary :: (Render a, Render b) => Builder -> a -> b -> Builder
renderBinary op x y = "(" <> op <> " " <> render x <> " " <> render y <> ")"
{-# INLINEABLE renderBinary #-}
renderTernary :: (Render a, Render b, Render c) => Builder -> a -> b -> c -> Builder
renderTernary op x y z = "(" <> op <> " " <> render x <> " " <> render y <> " " <> render z <> ")"
{-# INLINEABLE renderTernary #-}
renderNary :: Render a => Builder -> [a] -> Builder
renderNary op xs = "(" <> op <> renderedXs <> ")"
where
renderedXs = foldl' (\s x -> s <> " " <> render x) mempty xs
{-# INLINEABLE renderNary #-}