{-# LANGUAGE OverloadedStrings #-}

module IR ( Exp (..), FExp (..)
          , Stmt (..)
          , Temp (..), FTemp (..)
          , Label, AsmData
          , AE (..)
          , WSt (..)
          , prettyIR
          ) where

import           CF.AL
import           Data.Int          (Int64)
import qualified Data.IntMap       as IM
import           Data.Word         (Word64)
import           Op
import           Prettyprinter     (Doc, Pretty (..), hardline, parens, (<+>))
import           Prettyprinter.Ext

-- see https://my.eng.utah.edu/~cs4400/sse-fp.pdf
type Label = Word; type AsmData = IM.IntMap [Word64]

data WSt = WSt { WSt -> Label
wlabel :: !Label, WSt -> Int
wtemps :: !Int }

prettyLabel :: Label -> Doc ann
prettyLabel :: forall ann. Label -> Doc ann
prettyLabel Label
l = Doc ann
"apple_" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Label -> Doc ann
forall ann. Label -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Label
l

data FTemp = FTemp !Int
           | F0 | F1 | F2 | F3 | F4 | F5
           | FRet | FRet1
           deriving (FTemp -> FTemp -> Bool
(FTemp -> FTemp -> Bool) -> (FTemp -> FTemp -> Bool) -> Eq FTemp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FTemp -> FTemp -> Bool
== :: FTemp -> FTemp -> Bool
$c/= :: FTemp -> FTemp -> Bool
/= :: FTemp -> FTemp -> Bool
Eq, Eq FTemp
Eq FTemp =>
(FTemp -> FTemp -> Ordering)
-> (FTemp -> FTemp -> Bool)
-> (FTemp -> FTemp -> Bool)
-> (FTemp -> FTemp -> Bool)
-> (FTemp -> FTemp -> Bool)
-> (FTemp -> FTemp -> FTemp)
-> (FTemp -> FTemp -> FTemp)
-> Ord FTemp
FTemp -> FTemp -> Bool
FTemp -> FTemp -> Ordering
FTemp -> FTemp -> FTemp
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: FTemp -> FTemp -> Ordering
compare :: FTemp -> FTemp -> Ordering
$c< :: FTemp -> FTemp -> Bool
< :: FTemp -> FTemp -> Bool
$c<= :: FTemp -> FTemp -> Bool
<= :: FTemp -> FTemp -> Bool
$c> :: FTemp -> FTemp -> Bool
> :: FTemp -> FTemp -> Bool
$c>= :: FTemp -> FTemp -> Bool
>= :: FTemp -> FTemp -> Bool
$cmax :: FTemp -> FTemp -> FTemp
max :: FTemp -> FTemp -> FTemp
$cmin :: FTemp -> FTemp -> FTemp
min :: FTemp -> FTemp -> FTemp
Ord)

data Temp = ITemp !Int
          | ATemp !Int
          | C0 | C1 | C2 | C3 | C4 | C5
          | CRet
          deriving Temp -> Temp -> Bool
(Temp -> Temp -> Bool) -> (Temp -> Temp -> Bool) -> Eq Temp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Temp -> Temp -> Bool
== :: Temp -> Temp -> Bool
$c/= :: Temp -> Temp -> Bool
/= :: Temp -> Temp -> Bool
Eq

instance Pretty Temp where
    pretty :: forall ann. Temp -> Doc ann
pretty (ITemp Int
i) = Doc ann
"r_" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
i
    pretty (ATemp Int
i) = Doc ann
"a_" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
i
    pretty Temp
C0        = Doc ann
"r_arg0"
    pretty Temp
C1        = Doc ann
"r_arg1"
    pretty Temp
C2        = Doc ann
"r_arg2"
    pretty Temp
C3        = Doc ann
"r_arg3"
    pretty Temp
C4        = Doc ann
"r_arg4"
    pretty Temp
C5        = Doc ann
"r_arg5"
    pretty Temp
CRet      = Doc ann
"r_ret"

instance Pretty FTemp where
    pretty :: forall ann. FTemp -> Doc ann
pretty (FTemp Int
i) = Doc ann
"f_" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
i
    pretty FTemp
F0        = Doc ann
"f_arg0"
    pretty FTemp
F1        = Doc ann
"f_arg1"
    pretty FTemp
F2        = Doc ann
"f_arg2"
    pretty FTemp
F3        = Doc ann
"f_arg3"
    pretty FTemp
F4        = Doc ann
"f_arg4"
    pretty FTemp
F5        = Doc ann
"f_arg5"
    pretty FTemp
FRet      = Doc ann
"f_ret"
    pretty FTemp
FRet1     = Doc ann
"f_ret1"

instance Show Temp where show :: Temp -> String
show=Doc Any -> String
forall a. Show a => a -> String
show(Doc Any -> String) -> (Temp -> Doc Any) -> Temp -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Temp -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty

data Stmt = L Label
          | MJ Exp Label
          | J Label
          | MT Temp Exp | MX FTemp FExp -- move targeting xmm0 &c.
          | Ma AL Temp Exp -- label, register, size
          | Free Temp | RA !AL -- "return array" no-op
          | Wr AE Exp | WrF AE FExp | WrB AE Exp
          | Cmov Exp Temp Exp | Fcmov Exp FTemp FExp
          | Cset Temp Exp
          | Sa Temp Exp -- register, size
          | Pop Exp -- pop salloc
          | Cpy AE AE Exp
          | Cpy1 AE AE Exp
          | C Label | R Label
          | IRnd Temp | FRnd FTemp

instance Pretty Stmt where
    pretty :: forall ann. Stmt -> Doc ann
pretty (L Label
l)         = Doc ann
forall ann. Doc ann
hardline Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Label -> Doc ann
forall ann. Label -> Doc ann
prettyLabel Label
l Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
":"
    pretty (MT Temp
t Exp
e)      = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"movtemp" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (MX FTemp
t FExp
e)      = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"movf" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FTemp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FTemp -> Doc ann
pretty FTemp
t Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FExp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty FExp
e)
    pretty (MJ Exp
e Label
l)      = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"mjump" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Label -> Doc ann
forall ann. Label -> Doc ann
prettyLabel Label
l)
    pretty (J Label
l)         = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"j" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Label -> Doc ann
forall ann. Label -> Doc ann
prettyLabel Label
l)
    pretty (Wr AE
p Exp
e)      = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"write" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (WrF AE
p FExp
e)     = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"write" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FExp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty FExp
e)
    pretty (WrB AE
p Exp
e)     = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"write-1" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (Ma AL
_ Temp
t Exp
e)    = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"malloc" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
":" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (Free Temp
t)      = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"free" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t)
    pretty (Cmov Exp
p Temp
t Exp
e)  = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"cmov" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
p Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (Fcmov Exp
p FTemp
t FExp
e) = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"fcmov" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
p Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FTemp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FTemp -> Doc ann
pretty FTemp
t Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FExp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty FExp
e)
    pretty RA{}          = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens Doc ann
"return-array"
    pretty (Sa Temp
t Exp
e)      = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"salloc" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
":" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (Pop Exp
e)       = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"spop" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (Cpy AE
p AE
p' Exp
e)  = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"cpy" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"," Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p' Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (Cpy1 AE
p AE
p' Exp
e) = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"cpy-byte" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"," Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p' Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (C Label
l)         = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"call" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Label -> Doc ann
forall ann. Label -> Doc ann
prettyLabel Label
l)
    pretty R{}           = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens Doc ann
"ret" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
forall ann. Doc ann
hardline
    pretty (IRnd Temp
t)      = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"<- rnd")
    pretty (FRnd FTemp
t)      = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (FTemp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FTemp -> Doc ann
pretty FTemp
t Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"<- xrnd")
    pretty (Cset Temp
t Exp
e)    = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"cset" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"<-" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)

instance Show Stmt where show :: Stmt -> String
show = Doc Any -> String
forall a. Show a => a -> String
show (Doc Any -> String) -> (Stmt -> Doc Any) -> Stmt -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stmt -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Stmt -> Doc ann
pretty

data AE = AP Temp (Maybe Exp) (Maybe AL) -- offset, label for tracking liveness

instance Pretty AE where
    pretty :: forall ann. AE -> Doc ann
pretty (AP Temp
t Maybe Exp
Nothing Maybe AL
_)  = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"ptr" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t)
    pretty (AP Temp
t (Just Exp
e) Maybe AL
_) = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"ptr" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"+" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)

data FExp = ConstF Double
          | FB FBin FExp FExp
          | FConv Exp
          | FReg FTemp
          | FU FUn FExp
          | FAt AE

instance Num Exp where
    + :: Exp -> Exp -> Exp
(+) = IBin -> Exp -> Exp -> Exp
IB IBin
IPlus; * :: Exp -> Exp -> Exp
(*) = IBin -> Exp -> Exp -> Exp
IB IBin
ITimes; (-) = IBin -> Exp -> Exp -> Exp
IB IBin
IMinus; fromInteger :: Integer -> Exp
fromInteger = Int64 -> Exp
ConstI (Int64 -> Exp) -> (Integer -> Int64) -> Integer -> Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Int64
forall a. Num a => Integer -> a
fromInteger

instance Num FExp where
    + :: FExp -> FExp -> FExp
(+) = FBin -> FExp -> FExp -> FExp
FB FBin
FPlus; * :: FExp -> FExp -> FExp
(*) = FBin -> FExp -> FExp -> FExp
FB FBin
FTimes; (-) = FBin -> FExp -> FExp -> FExp
FB FBin
FMinus; fromInteger :: Integer -> FExp
fromInteger = Double -> FExp
ConstF (Double -> FExp) -> (Integer -> Double) -> Integer -> FExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Double
forall a. Num a => Integer -> a
fromInteger

instance Fractional FExp where
    / :: FExp -> FExp -> FExp
(/) = FBin -> FExp -> FExp -> FExp
FB FBin
FDiv; fromRational :: Rational -> FExp
fromRational = Double -> FExp
ConstF (Double -> FExp) -> (Rational -> Double) -> Rational -> FExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Double
forall a. Fractional a => Rational -> a
fromRational

data Exp = ConstI Int64
         | Reg Temp
         | IB IBin Exp Exp
         | FRel FRel FExp FExp
         | IRel IRel Exp Exp | Is Temp
         | IU IUn Exp
         | BU BUn Exp
         | IRFloor FExp
         | EAt AE | BAt AE
         | LA !Int -- assembler data

instance Pretty FExp where
    pretty :: forall ann. FExp -> Doc ann
pretty (ConstF Double
x)   = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"double" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Double -> Doc ann
forall ann. Double -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Double
x)
    pretty (FConv Exp
e)    = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"itof" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (FReg FTemp
t)     = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"freg" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FTemp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FTemp -> Doc ann
pretty FTemp
t)
    pretty (FB FBin
op FExp
e FExp
e') = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (FBin -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FBin -> Doc ann
pretty FBin
op Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FExp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty FExp
e Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FExp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty FExp
e')
    pretty (FU FUn
op FExp
e)    = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (FUn -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FUn -> Doc ann
pretty FUn
op Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FExp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty FExp
e)
    pretty (FAt AE
p)      = Doc ann
"f@" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p

instance Show FExp where show :: FExp -> String
show=Doc Any -> String
forall a. Show a => a -> String
show(Doc Any -> String) -> (FExp -> Doc Any) -> FExp -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.FExp -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty

instance Pretty Exp where
    pretty :: forall ann. Exp -> Doc ann
pretty (ConstI Int64
i)     = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"int" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Int64 -> Doc ann
forall ann. Int64 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int64
i)
    pretty (Reg Temp
t)        = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"reg" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
t)
    pretty (IRel IRel
op Exp
e Exp
e') = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (IRel -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. IRel -> Doc ann
pretty IRel
op Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e')
    pretty (IB IBin
op Exp
e Exp
e')   = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (IBin -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. IBin -> Doc ann
pretty IBin
op Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e')
    pretty (IU IUn
op Exp
e)      = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (IUn -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. IUn -> Doc ann
pretty IUn
op Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e)
    pretty (BU BUn
op Exp
e)      = BUn -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. BUn -> Doc ann
pretty BUn
op Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e
    pretty (IRFloor FExp
e)    = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"floor" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FExp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty FExp
e)
    pretty (EAt AE
p)        = Doc ann
"@" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p
    pretty (BAt AE
p)        = Doc ann
"b@" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> AE -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. AE -> Doc ann
pretty AE
p
    pretty (FRel FRel
op FExp
e FExp
e') = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (FRel -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FRel -> Doc ann
pretty FRel
op Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FExp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty FExp
e Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> FExp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FExp -> Doc ann
pretty FExp
e')
    pretty (Is Temp
e)         = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann
"is?" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Temp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Temp -> Doc ann
pretty Temp
e)
    pretty (LA Int
n)         = Doc ann
"arr_" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
n

instance Show Exp where show :: Exp -> String
show = Doc Any -> String
forall a. Show a => a -> String
show(Doc Any -> String) -> (Exp -> Doc Any) -> Exp -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Exp -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty

prettyIR :: (AsmData, [Stmt]) -> Doc ann
prettyIR :: forall ann. (AsmData, [Stmt]) -> Doc ann
prettyIR (AsmData
ds,[Stmt]
ss) = AsmData -> Doc ann
forall {t :: * -> *} {ann}.
(Foldable t, Functor t) =>
IntMap (t Word64) -> Doc ann
pAD AsmData
ds Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<#> [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
prettyLines (Stmt -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Stmt -> Doc ann
pretty(Stmt -> Doc ann) -> [Stmt] -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>[Stmt]
ss)