Compare commits

4 Commits
qq ... master

Author SHA1 Message Date
64be009635 fix: escape characters as octal sequences
All checks were successful
build / build (push) Successful in 44s
2026-05-18 10:01:05 -06:00
ab7cc053a4 refactor: records
All checks were successful
build / build (push) Successful in 27s
2026-04-30 22:20:22 -06:00
e61853e7a6 feat: Data instances
All checks were successful
build / build (push) Successful in 6s
2026-04-30 17:37:05 -06:00
25b62cb69d refactor: CInt Integer
All checks were successful
build / build (push) Successful in 16s
2026-04-30 12:24:13 -06:00
8 changed files with 86 additions and 106 deletions

3
.gitignore vendored
View File

@@ -6,4 +6,5 @@ dist-newstyle
*.hi *.hi
.ghc.environment.* .ghc.environment.*
*.tix *.tix
.direnv .direnv
result

View File

@@ -1,7 +1,5 @@
# qbe-hs # qbe-hs
**fork of [qbe-hs](https://git.sr.ht/~fgaz/qbe-hs)**
[![Hackage](https://img.shields.io/hackage/v/qbe.svg)](https://hackage.haskell.org/package/qbe) [![Hackage](https://img.shields.io/hackage/v/qbe.svg)](https://hackage.haskell.org/package/qbe)
[![builds.sr.ht status](https://builds.sr.ht/~fgaz/qbe-hs/commits/master.svg)](https://builds.sr.ht/~fgaz/qbe-hs/commits/master?) [![builds.sr.ht status](https://builds.sr.ht/~fgaz/qbe-hs/commits/master.svg)](https://builds.sr.ht/~fgaz/qbe-hs/commits/master?)

View File

@@ -24,7 +24,7 @@
shell.tools = { shell.tools = {
cabal = {}; cabal = {};
# hlint = {}; # hlint = {};
# haskell-language-server = {}; haskell-language-server = {};
}; };
# Non-Haskell shell tools go here # Non-Haskell shell tools go here
shell.buildInputs = with final; [ shell.buildInputs = with final; [

View File

@@ -1,3 +1,3 @@
export export
data $d = align 8 data $d = align 8
{z 16, b $g + 32 "foo\nbar\NULbaz" -1} {z 16, b $g + 32 "foo\012bar\000baz" -1}

View File

@@ -39,15 +39,11 @@ common common
-Wredundant-constraints -Wredundant-constraints
-Wincomplete-uni-patterns -Wincomplete-uni-patterns
-Wincomplete-record-updates -Wincomplete-record-updates
-fdefer-type-errors
-fno-show-valid-hole-fits
-fdefer-out-of-scope-variables
-Wno-typed-holes
default-language: Haskell2010 default-language: Haskell2010
library library
import: common import: common
exposed-modules: Language.QBE Language.QBE.QQ exposed-modules: Language.QBE
-- other-modules: -- other-modules:
other-extensions: DataKinds other-extensions: DataKinds
KindSignatures KindSignatures
@@ -71,8 +67,6 @@ library
|| ^>= 1.5.0 || ^>= 1.5.0
, deepseq ^>= 1.4.4 || ^>= 1.5 , deepseq ^>= 1.4.4 || ^>= 1.5
, prettyprinter ^>= 1.7.1 , prettyprinter ^>= 1.7.1
, megaparsec ^>= 9.7.0
, template-haskell
hs-source-dirs: src hs-source-dirs: src
test-suite golden test-suite golden

View File

@@ -4,6 +4,9 @@
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DuplicateRecordFields, NoFieldSelectors #-}
{-| {-|
Module : Language.QBE Module : Language.QBE
Description : Types and Pretty instances for the QBE IL Description : Types and Pretty instances for the QBE IL
@@ -82,16 +85,21 @@ import Data.Text (Text)
import Data.Text.Short (ShortText) import Data.Text.Short (ShortText)
import qualified Data.Text.Short as TS import qualified Data.Text.Short as TS
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.ByteString.Internal (w2c)
import Data.Word (Word64) import Data.Word (Word64)
import Data.List.NonEmpty (NonEmpty, toList) import Data.List.NonEmpty (NonEmpty, toList)
import Data.Maybe (maybeToList) import Data.Maybe (maybeToList)
import Prettyprinter import Prettyprinter
( Pretty(pretty), Doc, (<+>), vsep, hsep, hang, punctuate, group, flatAlt ( Pretty(pretty), Doc, (<+>), vsep, hsep, hang, punctuate, group, flatAlt
, space, encloseSep, tupled, comma, equals, braces, lbrace, rbrace ) , space, encloseSep, tupled, comma, equals, braces, lbrace, rbrace, enclose )
-- Instances -- Instances
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)
import Numeric (showOct)
import Data.Char (isPrint, isAscii)
-- * Identifiers -- * Identifiers
---------------- ----------------
@@ -100,12 +108,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 +132,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 +152,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 +165,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
@@ -170,15 +178,14 @@ instance Pretty ExtTy where
-- | Constant/immediate -- | Constant/immediate
data Const data Const
-- MAYBE just use a signed type -- MAYBE just use a signed type
= CInt Bool Word64 -- ^ 64 bit integer. The 'Bool' is whether to negate. = CInt Integer -- ^ Integer
| 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 negative int) | negative = pretty '-' <> pretty int pretty (CInt int) = pretty int
| otherwise = pretty int
pretty (CSingle float) = "s_" <> pretty float pretty (CSingle float) = "s_" <> pretty float
pretty (CDouble double) = "d_" <> pretty double pretty (CDouble double) = "d_" <> pretty double
pretty (CGlobal ident) = pretty ident pretty (CGlobal ident) = pretty ident
@@ -189,7 +196,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"
@@ -211,7 +218,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) =
@@ -229,7 +236,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
@@ -240,7 +247,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
@@ -254,18 +261,28 @@ 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) =
hsep $ pretty ident : maybeToList ((pretty '+' <+>) . pretty <$> alignment) hsep $ pretty ident : maybeToList ((pretty '+' <+>) . pretty <$> alignment)
pretty (String bs) = pretty $ show bs -- HACK: hoping that the escape sequences are the same... -- ~~HACK: hoping that the escape sequences are the same...~~
-- ↑ wrong bitch (it's undocumented; i don't blame you babe.)
pretty (String bs) =
enclose "\"" "\"" . pretty . showHexSequences . BS.unpack $ bs
where
showHexSequences =
foldr (\a acc -> char a <> acc) ""
char c
| isAscii (w2c c) && isPrint (w2c c) = [w2c c]
| otherwise = "\\" <> pad 3 (showOct c "")
pad n s = replicate (max 0 (n - length s)) '0' <> s
pretty (Const c) = pretty c pretty (Const c) = pretty c
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,8 +293,16 @@ 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
deriving (Show, Eq) { linkage :: [Linkage]
, returnType :: Maybe AbiTy
, name :: Ident 'Global
, env :: Maybe (Ident 'Temporary)
, params :: [Param]
, variadic :: Variadic
, code :: NonEmpty Block
}
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
@@ -292,7 +317,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
@@ -300,14 +325,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@
@@ -323,7 +348,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,8 +356,13 @@ instance Pretty Val where
pretty (ValGlobal ident) = pretty ident pretty (ValGlobal ident) = pretty ident
-- | 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
deriving (Show, Eq) { label :: Ident 'Label
, phis :: [Phi]
, insts :: [Inst]
, jump :: Jump
}
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
@@ -347,7 +377,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
@@ -363,7 +393,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) =
@@ -371,7 +401,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
@@ -430,7 +460,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) =
@@ -479,7 +509,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
@@ -490,7 +520,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
@@ -517,7 +547,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"
@@ -549,7 +579,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"
@@ -567,7 +597,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
@@ -577,7 +607,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

View File

@@ -1,43 +0,0 @@
{-# LANGUAGE RankNTypes, TypeAbstractions, OverloadedStrings, ScopedTypeVariables #-}
module Language.QBE.QQ
( qbe
)
where
import qualified Language.Haskell.TH as TH
import Language.Haskell.TH.Quote
import Data.Void
import Text.Megaparsec
import Text.Megaparsec.Char
import qualified Text.Megaparsec.Char.Lexer as L
import Language.QBE
import Data.Proxy
type P = Parsec Void String
space = L.space space1 empty empty
lexeme = L.lexeme space1
symbol = L.symbol space1
ident :: Sigil -> P (Ident t)
ident (Proxy @t) = do
case t of
AggregateTy -> char ':'
Ident <$> ""
assignment :: P Assignment
assignment = do
ident
assignmentInst :: P Inst
assignmentInst = _
qbeQuoteExp :: String -> TH.ExpQ
qbeQuoteExp = _
qbe :: QuasiQuoter
qbe = QuasiQuoter
{ quoteExp = qbeQuoteExp
, quotePat = _
}

View File

@@ -6,8 +6,9 @@ module Main (main) where
import Language.QBE import Language.QBE
import Test.Tasty (TestTree, defaultMain, testGroup) import Test.Tasty (TestTree, testGroup)
import Test.Tasty.Silver (goldenVsAction) import Test.Tasty.Silver (goldenVsAction)
import Test.Tasty.Silver.Interactive (defaultMain)
import System.FilePath ((</>), (<.>)) import System.FilePath ((</>), (<.>))
import Prettyprinter (Pretty(pretty), layoutPretty, defaultLayoutOptions) import Prettyprinter (Pretty(pretty), layoutPretty, defaultLayoutOptions)
import Prettyprinter.Render.Text (renderStrict) import Prettyprinter.Render.Text (renderStrict)
@@ -31,8 +32,8 @@ goldenTests = testGroup "golden tests"
] ]
, t "type" ([Word, Long, Single, Double], [BaseTy Word, Byte, HalfWord]) , t "type" ([Word, Long, Single, Double], [BaseTy Word, Byte, HalfWord])
, t "const" , t "const"
[ CInt True 1 [ CInt (-1)
, CInt False 2 , CInt 2
, CSingle 0.1 , CSingle 0.1
, CDouble (-0.2) , CDouble (-0.2)
, CGlobal "global" , CGlobal "global"
@@ -45,17 +46,17 @@ goldenTests = testGroup "golden tests"
, t "opaque" $ Opaque "t" 8 16 , t "opaque" $ Opaque "t" 8 16
, t "data" $ DataDef [Export] "d" (Just 8) , t "data" $ DataDef [Export] "d" (Just 8)
[ FieldZero 16 [ FieldZero 16
, FieldExtTy Byte $ Symbol "g" (Just 32) :| [String "foo\nbar\0baz", Const $ CInt True 1] , FieldExtTy Byte $ Symbol "g" (Just 32) :| [String "foo\nbar\0baz", Const $ CInt (-1)]
] ]
, t "function" $ FuncDef [Export] (Just $ AbiAggregateTy "t") "f" , t "function" $ FuncDef [Export] (Just $ AbiAggregateTy "t") "f"
(Just "env") [Param (AbiBaseTy Word) "a", Param (AbiBaseTy Double) "b"] Variadic $ (Just "env") [Param (AbiBaseTy Word) "a", Param (AbiBaseTy Double) "b"] Variadic $
Block "l" [] [] (Ret Nothing) :| [] Block "l" [] [] (Ret Nothing) :| []
, t "val" [valInt 0, ValTemporary "temporary", ValGlobal "global"] , t "val" [valInt 0, ValTemporary "temporary", ValConst (CGlobal "global")]
, t "jmp" $ Jmp "target" , t "jmp" $ Jmp "target"
, t "jnz" $ Jnz (valInt 0) "target1" "target2" , t "jnz" $ Jnz (valInt 0) "target1" "target2"
, t "ret" $ Ret $ Just $ ValTemporary "x" , t "ret" $ Ret $ Just $ ValTemporary "x"
, t "phi" $ Phi (Assignment "a" Word) [PhiArg "b" $ valInt 1, PhiArg "c" $ valInt 2] , t "phi" $ Phi (Assignment "a" Word) [PhiArg "b" $ valInt 1, PhiArg "c" $ valInt 2]
, t "call" $ Call (Just ("r", AbiBaseTy Word)) (ValGlobal "f") (Just $ valInt 1) , t "call" $ Call (Just ("r", AbiBaseTy Word)) (ValConst (CGlobal "f")) (Just $ valInt 1)
[Arg (AbiBaseTy Word) $ valInt 2, Arg (AbiAggregateTy "t") $ ValTemporary "a"] [Arg (AbiBaseTy Word) $ valInt 2, Arg (AbiAggregateTy "t") $ ValTemporary "a"]
[Arg (AbiBaseTy Word) $ valInt 3, Arg (AbiAggregateTy "t1") $ ValTemporary "b"] [Arg (AbiBaseTy Word) $ valInt 3, Arg (AbiAggregateTy "t1") $ ValTemporary "b"]
, t "inst" $ Block "l" [] , t "inst" $ Block "l" []
@@ -92,8 +93,7 @@ goldenTests = testGroup "golden tests"
(renderStrict . layoutPretty defaultLayoutOptions) (renderStrict . layoutPretty defaultLayoutOptions)
valInt :: Int -> Val valInt :: Int -> Val
valInt i | i >= 0 = ValConst $ CInt False $ fromIntegral i valInt i = ValConst $ CInt $ fromIntegral i
| otherwise = ValConst $ CInt True $ fromIntegral $ negate i
one, two :: Val one, two :: Val
one = valInt 1 one = valInt 1
@@ -107,16 +107,16 @@ helloWorld = Program [] [helloString] [helloMain]
where where
helloString = DataDef [] "str" Nothing helloString = DataDef [] "str" Nothing
[ FieldExtTy Byte $ String "hello world" :| [] [ FieldExtTy Byte $ String "hello world" :| []
, FieldExtTy Byte $ Const (CInt False 0) :| [] , FieldExtTy Byte $ Const (CInt 0) :| []
] ]
helloMain = FuncDef [Export] (Just $ AbiBaseTy Word) "main" helloMain = FuncDef [Export] (Just $ AbiBaseTy Word) "main"
Nothing [] NoVariadic $ Nothing [] NoVariadic $
Block "start" Block "start"
[] []
[ Call (Just ("r", AbiBaseTy Word)) (ValGlobal "puts") [ Call (Just ("r", AbiBaseTy Word)) (ValConst (CGlobal "puts"))
Nothing Nothing
[Arg (AbiBaseTy Long) $ ValGlobal "str"] [Arg (AbiBaseTy Long) $ ValConst (CGlobal "str")]
[] []
] ]
(Ret $ Just $ ValConst $ CInt False 0) (Ret $ Just $ ValConst $ CInt 0)
:| [] :| []