This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE PatternSynonyms #-}
|
{-# LANGUAGE PatternSynonyms #-}
|
||||||
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
|
{-# LANGUAGE GADTs #-}
|
||||||
{-|
|
{-|
|
||||||
Module : Language.QBE
|
Module : Language.QBE
|
||||||
Description : Types and Pretty instances for the QBE IL
|
Description : Types and Pretty instances for the QBE IL
|
||||||
@@ -92,6 +94,7 @@ import Prettyprinter
|
|||||||
import Data.Hashable (Hashable)
|
import Data.Hashable (Hashable)
|
||||||
import Control.DeepSeq (NFData)
|
import Control.DeepSeq (NFData)
|
||||||
import Data.String (IsString)
|
import Data.String (IsString)
|
||||||
|
import Data.Data (Data)
|
||||||
|
|
||||||
-- * Identifiers
|
-- * Identifiers
|
||||||
----------------
|
----------------
|
||||||
@@ -100,12 +103,12 @@ import Data.String (IsString)
|
|||||||
type RawIdent = ShortText
|
type RawIdent = ShortText
|
||||||
|
|
||||||
-- | Sigils are used to differentiate the verious types of 'Ident'ifier.
|
-- | Sigils are used to differentiate the verious types of 'Ident'ifier.
|
||||||
data Sigil
|
data Sigil where
|
||||||
= AggregateTy -- ^ @:@
|
AggregateTy :: Sigil
|
||||||
| Global -- ^ @$@
|
Global :: Sigil
|
||||||
| Temporary -- ^ @%@
|
Temporary :: Sigil
|
||||||
| Label -- ^ @\@@
|
Label :: Sigil
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
-- | QBE identifiers. The sigil is represented at the type level, so that
|
-- | QBE identifiers. The sigil is represented at the type level, so that
|
||||||
-- mixing incompatible identifiers is impossible.
|
-- mixing incompatible identifiers is impossible.
|
||||||
@@ -124,7 +127,7 @@ data Sigil
|
|||||||
-- In the second argument of ‘($)’, namely ‘Jmp $ Ident @'Global "a"’
|
-- In the second argument of ‘($)’, namely ‘Jmp $ Ident @'Global "a"’
|
||||||
-- In the expression: pretty $ Jmp $ Ident @'Global "a"
|
-- In the expression: pretty $ Jmp $ Ident @'Global "a"
|
||||||
newtype Ident (t :: Sigil) = Ident RawIdent
|
newtype Ident (t :: Sigil) = Ident RawIdent
|
||||||
deriving (Show, Eq, Ord, IsString, NFData, Hashable)
|
deriving (Show, Eq, Ord, IsString, NFData, Hashable, Data)
|
||||||
|
|
||||||
instance Pretty (Ident 'AggregateTy) where
|
instance Pretty (Ident 'AggregateTy) where
|
||||||
pretty (Ident raw) = pretty ':' <> pretty (TS.toText raw)
|
pretty (Ident raw) = pretty ':' <> pretty (TS.toText raw)
|
||||||
@@ -144,7 +147,7 @@ data BaseTy
|
|||||||
| Long -- ^ @l@
|
| Long -- ^ @l@
|
||||||
| Single -- ^ @s@
|
| Single -- ^ @s@
|
||||||
| Double -- ^ @d@
|
| Double -- ^ @d@
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty BaseTy where
|
instance Pretty BaseTy where
|
||||||
pretty Word = pretty 'w'
|
pretty Word = pretty 'w'
|
||||||
@@ -157,7 +160,7 @@ data ExtTy
|
|||||||
= BaseTy BaseTy
|
= BaseTy BaseTy
|
||||||
| Byte -- ^ @b@
|
| Byte -- ^ @b@
|
||||||
| HalfWord -- ^ @h@
|
| HalfWord -- ^ @h@
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty ExtTy where
|
instance Pretty ExtTy where
|
||||||
pretty (BaseTy baseTy) = pretty baseTy
|
pretty (BaseTy baseTy) = pretty baseTy
|
||||||
@@ -174,7 +177,7 @@ data Const
|
|||||||
| CSingle Float -- ^ Single-precision float
|
| CSingle Float -- ^ Single-precision float
|
||||||
| CDouble Double -- ^ Double-precision float
|
| CDouble Double -- ^ Double-precision float
|
||||||
| CGlobal (Ident 'Global) -- ^ Global symbol
|
| CGlobal (Ident 'Global) -- ^ Global symbol
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Const where
|
instance Pretty Const where
|
||||||
pretty (CInt int) = pretty int
|
pretty (CInt int) = pretty int
|
||||||
@@ -188,7 +191,7 @@ instance Pretty Const where
|
|||||||
data Linkage
|
data Linkage
|
||||||
= Export -- ^ Marks the defined item as visible outside the current file's scope
|
= Export -- ^ Marks the defined item as visible outside the current file's scope
|
||||||
| Section ShortText (Maybe Text) -- ^ Section name, with optional linker flags
|
| Section ShortText (Maybe Text) -- ^ Section name, with optional linker flags
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Linkage where
|
instance Pretty Linkage where
|
||||||
pretty Export = "export"
|
pretty Export = "export"
|
||||||
@@ -210,7 +213,7 @@ type Amount = Word64
|
|||||||
data TypeDef
|
data TypeDef
|
||||||
= TypeDef (Ident 'AggregateTy) (Maybe Alignment) [(SubTy, Maybe Amount)]
|
= TypeDef (Ident 'AggregateTy) (Maybe Alignment) [(SubTy, Maybe Amount)]
|
||||||
| Opaque (Ident 'AggregateTy) Alignment Size
|
| Opaque (Ident 'AggregateTy) Alignment Size
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty TypeDef where
|
instance Pretty TypeDef where
|
||||||
pretty (TypeDef ident alignment def) =
|
pretty (TypeDef ident alignment def) =
|
||||||
@@ -228,7 +231,7 @@ instance Pretty TypeDef where
|
|||||||
data SubTy
|
data SubTy
|
||||||
= SubExtTy ExtTy
|
= SubExtTy ExtTy
|
||||||
| SubAggregateTy (Ident 'AggregateTy)
|
| SubAggregateTy (Ident 'AggregateTy)
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty SubTy where
|
instance Pretty SubTy where
|
||||||
pretty (SubExtTy extTy) = pretty extTy
|
pretty (SubExtTy extTy) = pretty extTy
|
||||||
@@ -239,7 +242,7 @@ instance Pretty SubTy where
|
|||||||
|
|
||||||
-- | Global object definition
|
-- | Global object definition
|
||||||
data DataDef = DataDef [Linkage] (Ident 'Global) (Maybe Alignment) [Field]
|
data DataDef = DataDef [Linkage] (Ident 'Global) (Maybe Alignment) [Field]
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty DataDef where
|
instance Pretty DataDef where
|
||||||
pretty (DataDef linkage ident alignment fields) = vsep
|
pretty (DataDef linkage ident alignment fields) = vsep
|
||||||
@@ -253,7 +256,7 @@ data DataItem
|
|||||||
= Symbol (Ident 'Global) (Maybe Alignment)
|
= Symbol (Ident 'Global) (Maybe Alignment)
|
||||||
| String ByteString
|
| String ByteString
|
||||||
| Const Const
|
| Const Const
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty DataItem where
|
instance Pretty DataItem where
|
||||||
pretty (Symbol ident alignment) =
|
pretty (Symbol ident alignment) =
|
||||||
@@ -264,7 +267,7 @@ instance Pretty DataItem where
|
|||||||
data Field
|
data Field
|
||||||
= FieldExtTy ExtTy (NonEmpty DataItem)
|
= FieldExtTy ExtTy (NonEmpty DataItem)
|
||||||
| FieldZero Size
|
| FieldZero Size
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Field where
|
instance Pretty Field where
|
||||||
pretty (FieldExtTy extTy items) = pretty extTy <+> hsep (toList $ pretty <$> items)
|
pretty (FieldExtTy extTy items) = pretty extTy <+> hsep (toList $ pretty <$> items)
|
||||||
@@ -276,7 +279,7 @@ instance Pretty Field where
|
|||||||
-- TODO use record syntax on long types like this one
|
-- TODO use record syntax on long types like this one
|
||||||
-- | Function definition. The 'Maybe (Ident \'Temporary)' is the environment
|
-- | Function definition. The 'Maybe (Ident \'Temporary)' is the environment
|
||||||
data FuncDef = FuncDef [Linkage] (Maybe AbiTy) (Ident 'Global) (Maybe (Ident 'Temporary)) [Param] Variadic (NonEmpty Block)
|
data FuncDef = FuncDef [Linkage] (Maybe AbiTy) (Ident 'Global) (Maybe (Ident 'Temporary)) [Param] Variadic (NonEmpty Block)
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty FuncDef where
|
instance Pretty FuncDef where
|
||||||
pretty (FuncDef linkage abiTy ident env params variadic blocks) = vsep
|
pretty (FuncDef linkage abiTy ident env params variadic blocks) = vsep
|
||||||
@@ -291,7 +294,7 @@ instance Pretty FuncDef where
|
|||||||
]
|
]
|
||||||
|
|
||||||
data AbiTy = AbiBaseTy BaseTy | AbiAggregateTy (Ident 'AggregateTy)
|
data AbiTy = AbiBaseTy BaseTy | AbiAggregateTy (Ident 'AggregateTy)
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty AbiTy where
|
instance Pretty AbiTy where
|
||||||
pretty (AbiBaseTy baseTy) = pretty baseTy
|
pretty (AbiBaseTy baseTy) = pretty baseTy
|
||||||
@@ -299,14 +302,14 @@ instance Pretty AbiTy where
|
|||||||
|
|
||||||
-- | Function parameter
|
-- | Function parameter
|
||||||
data Param = Param AbiTy (Ident 'Temporary)
|
data Param = Param AbiTy (Ident 'Temporary)
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Param where
|
instance Pretty Param where
|
||||||
pretty (Param abiTy ident) = pretty abiTy <+> pretty ident
|
pretty (Param abiTy ident) = pretty abiTy <+> pretty ident
|
||||||
|
|
||||||
-- | Indicates the presence or absence of a variadic marker
|
-- | Indicates the presence or absence of a variadic marker
|
||||||
data Variadic = Variadic | NoVariadic
|
data Variadic = Variadic | NoVariadic
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
-- | 'Variadic' → @Just "..."@
|
-- | 'Variadic' → @Just "..."@
|
||||||
-- 'NoVariadic' → @Nothing@
|
-- 'NoVariadic' → @Nothing@
|
||||||
@@ -322,7 +325,7 @@ data Val
|
|||||||
= ValConst Const
|
= ValConst Const
|
||||||
| ValTemporary (Ident 'Temporary)
|
| ValTemporary (Ident 'Temporary)
|
||||||
| ValGlobal (Ident 'Global)
|
| ValGlobal (Ident 'Global)
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Val where
|
instance Pretty Val where
|
||||||
pretty (ValConst c) = pretty c
|
pretty (ValConst c) = pretty c
|
||||||
@@ -331,7 +334,7 @@ instance Pretty Val where
|
|||||||
|
|
||||||
-- | Block of instructions beginning with a label and ending with a jump
|
-- | Block of instructions beginning with a label and ending with a jump
|
||||||
data Block = Block (Ident 'Label) [Phi] [Inst] Jump
|
data Block = Block (Ident 'Label) [Phi] [Inst] Jump
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Block where
|
instance Pretty Block where
|
||||||
pretty (Block ident phis insts jump) = hang 4 $ vsep $ concat
|
pretty (Block ident phis insts jump) = hang 4 $ vsep $ concat
|
||||||
@@ -346,7 +349,7 @@ data Jump
|
|||||||
= Jmp (Ident 'Label) -- ^ Unconditional jump
|
= Jmp (Ident 'Label) -- ^ Unconditional jump
|
||||||
| Jnz Val (Ident 'Label) (Ident 'Label) -- ^ Conditional jump
|
| Jnz Val (Ident 'Label) (Ident 'Label) -- ^ Conditional jump
|
||||||
| Ret (Maybe Val) -- ^ Function return
|
| Ret (Maybe Val) -- ^ Function return
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Jump where
|
instance Pretty Jump where
|
||||||
pretty (Jmp ident) = "jmp" <+> pretty ident
|
pretty (Jmp ident) = "jmp" <+> pretty ident
|
||||||
@@ -362,7 +365,7 @@ instance Pretty Jump where
|
|||||||
-- MAYBE change [PhiArg] to Map (Ident 'Label) Val
|
-- MAYBE change [PhiArg] to Map (Ident 'Label) Val
|
||||||
-- | Phi instruction
|
-- | Phi instruction
|
||||||
data Phi = Phi Assignment [PhiArg]
|
data Phi = Phi Assignment [PhiArg]
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Phi where
|
instance Pretty Phi where
|
||||||
pretty (Phi assignment args) =
|
pretty (Phi assignment args) =
|
||||||
@@ -370,7 +373,7 @@ instance Pretty Phi where
|
|||||||
|
|
||||||
-- | Phi instruction argument, associating a 'Val' to a 'Label'
|
-- | Phi instruction argument, associating a 'Val' to a 'Label'
|
||||||
data PhiArg = PhiArg (Ident 'Label) Val
|
data PhiArg = PhiArg (Ident 'Label) Val
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty PhiArg where
|
instance Pretty PhiArg where
|
||||||
pretty (PhiArg label val) = pretty label <+> pretty val
|
pretty (PhiArg label val) = pretty label <+> pretty val
|
||||||
@@ -429,7 +432,7 @@ data Inst
|
|||||||
| VaStart (Ident 'Temporary)
|
| VaStart (Ident 'Temporary)
|
||||||
-- | @vaarg@, fetches the next argument from a variable argument list
|
-- | @vaarg@, fetches the next argument from a variable argument list
|
||||||
| VaArg Assignment (Ident 'Temporary)
|
| VaArg Assignment (Ident 'Temporary)
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Inst where
|
instance Pretty Inst where
|
||||||
pretty (BinaryOp assignment op v1 v2) =
|
pretty (BinaryOp assignment op v1 v2) =
|
||||||
@@ -478,7 +481,7 @@ instance Pretty Inst where
|
|||||||
|
|
||||||
-- | Represents the @%x =t@ part of an instruction.
|
-- | Represents the @%x =t@ part of an instruction.
|
||||||
data Assignment = Assignment (Ident 'Temporary) BaseTy
|
data Assignment = Assignment (Ident 'Temporary) BaseTy
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
-- | Infix synonym of 'Assignment'
|
-- | Infix synonym of 'Assignment'
|
||||||
pattern (:=) :: Ident 'Temporary -> BaseTy -> Assignment
|
pattern (:=) :: Ident 'Temporary -> BaseTy -> Assignment
|
||||||
@@ -489,7 +492,7 @@ instance Pretty Assignment where
|
|||||||
|
|
||||||
-- | Integer representation
|
-- | Integer representation
|
||||||
data IntRepr = Signed | Unsigned
|
data IntRepr = Signed | Unsigned
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
-- | Binary arithmetic and bit operations
|
-- | Binary arithmetic and bit operations
|
||||||
data BinaryOp
|
data BinaryOp
|
||||||
@@ -516,7 +519,7 @@ data BinaryOp
|
|||||||
| Shr
|
| Shr
|
||||||
-- | @shl@
|
-- | @shl@
|
||||||
| Shl
|
| Shl
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty BinaryOp where
|
instance Pretty BinaryOp where
|
||||||
pretty Add = "add"
|
pretty Add = "add"
|
||||||
@@ -548,7 +551,7 @@ data Comparison
|
|||||||
-- Floating point only comparison
|
-- Floating point only comparison
|
||||||
| O -- ^ ordered (no operand is a NaN) (floating point only)
|
| O -- ^ ordered (no operand is a NaN) (floating point only)
|
||||||
| Uo -- ^ unordered (at least one operand is a NaN) (floating point only)
|
| Uo -- ^ unordered (at least one operand is a NaN) (floating point only)
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Comparison where
|
instance Pretty Comparison where
|
||||||
pretty Eq = "eq"
|
pretty Eq = "eq"
|
||||||
@@ -566,7 +569,7 @@ instance Pretty IntRepr where
|
|||||||
|
|
||||||
-- | Function argument
|
-- | Function argument
|
||||||
data Arg = Arg AbiTy Val
|
data Arg = Arg AbiTy Val
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Arg where
|
instance Pretty Arg where
|
||||||
pretty (Arg abiTy val) = pretty abiTy <+> pretty val
|
pretty (Arg abiTy val) = pretty abiTy <+> pretty val
|
||||||
@@ -576,7 +579,7 @@ instance Pretty Arg where
|
|||||||
|
|
||||||
-- | Datatypre representing a QBE IL source file
|
-- | Datatypre representing a QBE IL source file
|
||||||
data Program = Program [TypeDef] [DataDef] [FuncDef]
|
data Program = Program [TypeDef] [DataDef] [FuncDef]
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq, Data)
|
||||||
|
|
||||||
instance Pretty Program where
|
instance Pretty Program where
|
||||||
pretty (Program typeDefs dataDefs funcDefs) = vsep $ concat
|
pretty (Program typeDefs dataDefs funcDefs) = vsep $ concat
|
||||||
|
|||||||
Reference in New Issue
Block a user