🌅
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
cabal.project.local
|
||||||
|
cabal.project.local~
|
||||||
|
dist
|
||||||
|
dist-newstyle
|
||||||
|
*.o
|
||||||
|
*.hi
|
||||||
|
.ghc.environment.*
|
||||||
5
CHANGELOG.md
Normal file
5
CHANGELOG.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Revision history for qbe-hs
|
||||||
|
|
||||||
|
## 0.1.0.0 -- YYYY-mm-dd
|
||||||
|
|
||||||
|
* First version. Released on an unsuspecting world.
|
||||||
30
LICENSE
Normal file
30
LICENSE
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
Copyright (c) 2022, Francesco Gazzetta
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials provided
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of Francesco Gazzetta nor the names of other
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
32
qbe.cabal
Normal file
32
qbe.cabal
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
cabal-version: 3.0
|
||||||
|
name: qbe
|
||||||
|
-- First component matches the QBE major version
|
||||||
|
version: 1.1.0.0
|
||||||
|
-- synopsis:
|
||||||
|
-- description:
|
||||||
|
license: BSD-3-Clause
|
||||||
|
license-file: LICENSE
|
||||||
|
author: Francesco Gazzetta
|
||||||
|
maintainer: fgaz@fgaz.me
|
||||||
|
copyright: 2022 Francesco Gazzetta
|
||||||
|
category: Language
|
||||||
|
build-type: Simple
|
||||||
|
extra-doc-files: CHANGELOG.md
|
||||||
|
-- extra-source-files:
|
||||||
|
|
||||||
|
library
|
||||||
|
exposed-modules: Language.QBE
|
||||||
|
-- other-modules:
|
||||||
|
other-extensions: DataKinds
|
||||||
|
KindSignatures
|
||||||
|
GeneralizedNewtypeDeriving
|
||||||
|
build-depends: base ^>=4.16.1.0
|
||||||
|
, text
|
||||||
|
, text-short
|
||||||
|
, bytestring
|
||||||
|
, hashable
|
||||||
|
, deepseq
|
||||||
|
, binary
|
||||||
|
hs-source-dirs: src
|
||||||
|
ghc-options: -Wall
|
||||||
|
default-language: Haskell2010
|
||||||
230
src/Language/QBE.hs
Normal file
230
src/Language/QBE.hs
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
|
{-# LANGUAGE KindSignatures #-}
|
||||||
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
|
module Language.QBE where
|
||||||
|
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Data.Text.Short (ShortText)
|
||||||
|
import Data.ByteString (ByteString)
|
||||||
|
import Data.Word (Word64)
|
||||||
|
import Data.List.NonEmpty (NonEmpty)
|
||||||
|
-- Instances
|
||||||
|
import Data.Hashable (Hashable)
|
||||||
|
import Control.DeepSeq (NFData)
|
||||||
|
import Data.Binary (Binary)
|
||||||
|
import Data.String (IsString)
|
||||||
|
|
||||||
|
-- * Identifiers
|
||||||
|
----------------
|
||||||
|
|
||||||
|
type RawIdent = ShortText
|
||||||
|
|
||||||
|
data Sigil
|
||||||
|
= AggregateTy -- ^ @:@
|
||||||
|
| Global -- ^ @$@
|
||||||
|
| Temporary -- ^ @%@
|
||||||
|
| Label -- ^ @\@@
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- | QBE identifiers. The sigil is represented at the type level, so that
|
||||||
|
-- mixing incompatible identifiers is impossible.
|
||||||
|
newtype Ident (t :: Sigil) = Ident RawIdent
|
||||||
|
deriving (Show, Eq, Ord, IsString, Binary, NFData, Hashable)
|
||||||
|
|
||||||
|
-- * Types
|
||||||
|
----------
|
||||||
|
|
||||||
|
data BaseTy = Word | Long | Single | Double
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data ExtTy = BaseTy BaseTy | Byte | HalfWord
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- * Constants
|
||||||
|
--------------
|
||||||
|
|
||||||
|
data Const
|
||||||
|
= CInt Bool Word64 -- ^ The 'Bool' is whether to negate
|
||||||
|
| CSingle Float
|
||||||
|
| CDouble Double
|
||||||
|
| CGlobal (Ident 'Global)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- * Linkage
|
||||||
|
------------
|
||||||
|
|
||||||
|
data Linkage
|
||||||
|
= Export
|
||||||
|
| Section ShortText (Maybe Text)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- * Definitions
|
||||||
|
----------------
|
||||||
|
|
||||||
|
type Alignment = Word64
|
||||||
|
type Size = Word64
|
||||||
|
type Amount = Word64
|
||||||
|
|
||||||
|
-- ** Aggregate types
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
data Typedef
|
||||||
|
= Typedef (Ident 'AggregateTy) (Maybe Alignment) [(SubTy, Maybe Amount)]
|
||||||
|
| Opaque (Ident 'AggregateTy) Alignment Size
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data SubTy
|
||||||
|
= SubExtTy
|
||||||
|
| SubAggregateTy (Ident 'AggregateTy)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- ** Data
|
||||||
|
----------
|
||||||
|
|
||||||
|
data DataDef = DataDef [Linkage] (Ident 'Global) (Maybe Alignment) [Field]
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data DataItem
|
||||||
|
= Symbol (Ident 'Global) Alignment
|
||||||
|
| String ByteString
|
||||||
|
| Const Const
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data Field
|
||||||
|
= FieldExtTy ExtTy (NonEmpty DataItem)
|
||||||
|
| FieldZero Size
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- ** Functions
|
||||||
|
---------------
|
||||||
|
|
||||||
|
-- | Function definition. The 'Maybe (Ident \'Temporary)' is the environment
|
||||||
|
data FuncDef = FuncDef [Linkage] (Maybe AbiTy) (Ident 'Global) (Maybe (Ident 'Temporary)) [Param] Variadic (NonEmpty Block)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data AbiTy = AbiBaseTy BaseTy | AbiAggregateTy (Ident 'AggregateTy)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data Param = Param AbiTy (Ident 'Temporary)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data Variadic = Variadic | NoVariadic
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- * Control
|
||||||
|
------------
|
||||||
|
|
||||||
|
data Val
|
||||||
|
= ValConst Const
|
||||||
|
| ValTemporary (Ident 'Temporary)
|
||||||
|
| ValGlobal (Ident 'Global)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data Block = Block (Ident 'Label) [Phi] [Inst] Jump
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data Jump
|
||||||
|
= Jmp (Ident 'Label)
|
||||||
|
| Jnz Val (Ident 'Label) (Ident 'Label)
|
||||||
|
| Ret (Maybe Val)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- * Instructions
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
data Phi = Phi (Ident 'Temporary) BaseTy [(Ident 'Label, Val)]
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data Inst
|
||||||
|
-- Arithmetic and Bits
|
||||||
|
= BinaryOp (Ident 'Temporary) BaseTy BinaryOp Val Val
|
||||||
|
| Neg (Ident 'Temporary) BaseTy Val
|
||||||
|
-- Memory
|
||||||
|
| Store ExtTy Val Val
|
||||||
|
| Load (Ident 'Temporary) BaseTy BaseTy Val -- ^ @\<ident\> =\<baseTy\> load\<baseTy\> \<val\>@
|
||||||
|
| LoadW (Ident 'Temporary) BaseTy IntRepr Val -- ^ @\<ident\> =\<baseTy\> load\<intRepr\>w \<val\>@
|
||||||
|
| LoadH (Ident 'Temporary) BaseTy IntRepr Val
|
||||||
|
| LoadB (Ident 'Temporary) BaseTy IntRepr Val
|
||||||
|
-- Comparisons
|
||||||
|
| Compare (Ident 'Temporary) BaseTy Comparison BaseTy Val Val
|
||||||
|
-- Conversions
|
||||||
|
-- | @extsw@/@extuw@. There is only one possible instruction type, so there's
|
||||||
|
-- no 'BaseTy' argument
|
||||||
|
| ExtW (Ident 'Temporary) IntRepr Val
|
||||||
|
-- | @extsh@/@extuh@
|
||||||
|
| ExtH (Ident 'Temporary) BaseTy IntRepr Val
|
||||||
|
-- | @extsb@/@extub@
|
||||||
|
| ExtB (Ident 'Temporary) BaseTy IntRepr Val
|
||||||
|
-- | @exts@. There is only one possible instruction type, so there's
|
||||||
|
-- no 'BaseTy' argument
|
||||||
|
| Exts (Ident 'Temporary) Val
|
||||||
|
-- | @truncd@. There is only one possible instruction type, so there's
|
||||||
|
-- no 'BaseTy' argument
|
||||||
|
| Truncd (Ident 'Temporary) Val
|
||||||
|
-- | @stosi@/@stoui@
|
||||||
|
| StoI (Ident 'Temporary) BaseTy IntRepr Val
|
||||||
|
-- | @dtosi@/@dtoui@
|
||||||
|
| DtoI (Ident 'Temporary) BaseTy IntRepr Val
|
||||||
|
-- | @swtof@/@uwtof@
|
||||||
|
| WtoF (Ident 'Temporary) BaseTy IntRepr Val
|
||||||
|
-- | @sltof@/@ultof@
|
||||||
|
| LtoF (Ident 'Temporary) BaseTy IntRepr Val
|
||||||
|
-- Cast and Copy
|
||||||
|
| Cast (Ident 'Temporary) BaseTy Val
|
||||||
|
| Copy (Ident 'Temporary) BaseTy Val
|
||||||
|
-- Calls
|
||||||
|
-- | the fields are: assignment, function name, environment, arguments, variadic arguments
|
||||||
|
| Call (Maybe (Ident 'Temporary, AbiTy)) Val (Maybe Val) [Arg] [Arg]
|
||||||
|
-- Variadic
|
||||||
|
| VaStart (Ident 'Temporary)
|
||||||
|
| VaArg (Ident 'Temporary) BaseTy (Ident 'Temporary)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data IntRepr = Signed | Unsigned
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data BinaryOp
|
||||||
|
-- | @add@
|
||||||
|
= Add
|
||||||
|
-- | @sub@
|
||||||
|
| Sub
|
||||||
|
-- | @div@/@udiv@. @Div Signed@ gets translated to @div@, so it will work
|
||||||
|
-- also on floats
|
||||||
|
| Div IntRepr
|
||||||
|
-- | @mul@
|
||||||
|
| Mul
|
||||||
|
-- | @rem@/@urem@
|
||||||
|
| Rem IntRepr
|
||||||
|
-- | @or@
|
||||||
|
| Or
|
||||||
|
-- | @xor@
|
||||||
|
| Xor
|
||||||
|
-- | @and@
|
||||||
|
| And
|
||||||
|
-- | @sar@
|
||||||
|
| Sar
|
||||||
|
-- | @shr@
|
||||||
|
| Shr
|
||||||
|
-- | @shl@
|
||||||
|
| Shl
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- | Comparison operators.
|
||||||
|
-- Where there's a @'Maybe' 'IntRepr'@, 'Nothing' means floating point
|
||||||
|
-- (@le@, @lt@, @ge@, @gt@), while @'Just' r@ means integer
|
||||||
|
-- (@sle@, @ule@, @slt@, @ult@...)
|
||||||
|
data Comparison
|
||||||
|
-- Universal comparison
|
||||||
|
= Eq -- ^ equality
|
||||||
|
| Ne -- ^ inequality
|
||||||
|
| Le (Maybe IntRepr) -- ^ lower or equal
|
||||||
|
| Lt (Maybe IntRepr) -- ^ lower
|
||||||
|
| Ge (Maybe IntRepr) -- ^ greater or equal
|
||||||
|
| Gt (Maybe IntRepr) -- ^ greater
|
||||||
|
-- Floating point only comparison
|
||||||
|
| O -- ^ ordered (no operand is a NaN) (floating point only)
|
||||||
|
| Uo -- ^ unordered (at least one operand is a NaN) (floating point only)
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data Arg = Arg AbiTy Val
|
||||||
|
deriving (Show, Eq)
|
||||||
Reference in New Issue
Block a user