{-# LANGUAGE GADTs #-}
module Copilot.Compile.C99.Type
( transType
, transLocalVarDeclType
, transTypeName
)
where
import qualified Language.C99.Simple as C
import Copilot.Core ( Struct (..), Type (..), typeLength,
typeName )
import Copilot.Compile.C99.Error ( errorEmptyStruct, errorZeroLengthArray )
transType :: Type a -> C.Type
transType :: forall a. Type a -> Type
transType Type a
ty = case Type a
ty of
Type a
Bool -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.TypedefName Ident
"bool"
Type a
Int8 -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.TypedefName Ident
"int8_t"
Type a
Int16 -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.TypedefName Ident
"int16_t"
Type a
Int32 -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.TypedefName Ident
"int32_t"
Type a
Int64 -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.TypedefName Ident
"int64_t"
Type a
Word8 -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.TypedefName Ident
"uint8_t"
Type a
Word16 -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.TypedefName Ident
"uint16_t"
Type a
Word32 -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.TypedefName Ident
"uint32_t"
Type a
Word64 -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.TypedefName Ident
"uint64_t"
Type a
Float -> TypeSpec -> Type
C.TypeSpec TypeSpec
C.Float
Type a
Double -> TypeSpec -> Type
C.TypeSpec TypeSpec
C.Double
Array Type t
ty' | Type (Array n t) -> Int
forall (n :: Nat) t. KnownNat n => Type (Array n t) -> Int
typeLength Type a
Type (Array n t)
ty Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 -> Type
forall a. a
errorZeroLengthArray
| Bool
otherwise -> Type -> Maybe Expr -> Type
C.Array (Type t -> Type
forall a. Type a -> Type
transType Type t
ty') Maybe Expr
len
where
len :: Maybe Expr
len = Expr -> Maybe Expr
forall a. a -> Maybe a
Just (Expr -> Maybe Expr) -> Expr -> Maybe Expr
forall a b. (a -> b) -> a -> b
$ Integer -> Expr
C.LitInt (Integer -> Expr) -> Integer -> Expr
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ Type (Array n t) -> Int
forall (n :: Nat) t. KnownNat n => Type (Array n t) -> Int
typeLength Type a
Type (Array n t)
ty
Struct a
s | [Value a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (a -> [Value a]
forall a. Struct a => a -> [Value a]
toValues a
s) -> Type
forall a. a
errorEmptyStruct
| Bool
otherwise -> TypeSpec -> Type
C.TypeSpec (TypeSpec -> Type) -> TypeSpec -> Type
forall a b. (a -> b) -> a -> b
$ Ident -> TypeSpec
C.Struct (a -> Ident
forall a. Struct a => a -> Ident
typeName a
s)
transLocalVarDeclType :: Type a -> C.Type
transLocalVarDeclType :: forall a. Type a -> Type
transLocalVarDeclType (Array Type t
ty') = Type -> Type
C.Ptr (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ Type t -> Type
forall a. Type a -> Type
transType Type t
ty'
transLocalVarDeclType Type a
ty = Type a -> Type
forall a. Type a -> Type
transType Type a
ty
transTypeName :: Type a -> C.TypeName
transTypeName :: forall a. Type a -> TypeName
transTypeName Type a
ty = Type -> TypeName
C.TypeName (Type -> TypeName) -> Type -> TypeName
forall a b. (a -> b) -> a -> b
$ Type a -> Type
forall a. Type a -> Type
transType Type a
ty