Add closures and fix lets in monomorphizer

This commit is contained in:
Martin Fredin 2023-05-06 22:49:08 +02:00
parent 677a200a15
commit 72e599d5de
26 changed files with 1440 additions and 692 deletions

View file

@ -9,17 +9,18 @@ module Codegen.LlvmIr (
Visibility (..),
CallingConvention (..),
ToIr (..),
typeOf
) where
import Data.List (intercalate)
import TypeChecker.TypeCheckerIr (Ident (..))
import Data.List (intercalate)
import TypeChecker.TypeCheckerIr (Ident (..))
data CallingConvention = TailCC | FastCC | CCC | ColdCC deriving (Show, Eq, Ord)
instance ToIr CallingConvention where
toIr :: CallingConvention -> String
toIr TailCC = "tailcc"
toIr FastCC = "fastcc"
toIr CCC = "ccc"
toIr CCC = "ccc"
toIr ColdCC = "coldcc"
-- | A datatype which represents some basic LLVM types
@ -38,6 +39,9 @@ data LLVMType
class ToIr a where
toIr :: a -> String
instance ToIr a => ToIr [a] where
toIr = concatMap toIr
instance ToIr LLVMType where
toIr :: LLVMType -> String
toIr = \case
@ -66,8 +70,8 @@ data LLVMComp
instance ToIr LLVMComp where
toIr :: LLVMComp -> String
toIr = \case
LLEq -> "eq"
LLNe -> "ne"
LLEq -> "eq"
LLNe -> "ne"
LLUgt -> "ugt"
LLUge -> "uge"
LLUlt -> "ult"
@ -80,7 +84,7 @@ instance ToIr LLVMComp where
data Visibility = Local | Global deriving (Show, Eq, Ord)
instance ToIr Visibility where
toIr :: Visibility -> String
toIr Local = "%"
toIr Local = "%"
toIr Global = "@"
{- | Represents a LLVM "value", as in an integer, a register variable,
@ -92,16 +96,18 @@ data LLVMValue
| VIdent Ident LLVMType
| VConstant String
| VFunction Ident Visibility LLVMType
| VNull
deriving (Show, Eq, Ord)
instance ToIr LLVMValue where
toIr :: LLVMValue -> String
toIr v = case v of
VInteger i -> show i
VChar i -> show i
VIdent (Ident n) _ -> "%" <> n
VInteger i -> show i
VChar i -> show i
VIdent (Ident n) _ -> "%" <> n
VFunction (Ident n) vis _ -> toIr vis <> n
VConstant s -> "c" <> show s
VConstant s -> "c" <> show s
VNull -> "null"
type Params = [(Ident, LLVMType)]
type Args = [(LLVMType, LLVMValue)]
@ -139,6 +145,21 @@ data LLVMIr
-- instructions should be used in its place
deriving (Show, Eq, Ord)
-- TODO add missing clauses
typeOf :: LLVMIr -> LLVMType
typeOf = \case
Add t _ _ -> t
Sub t _ _ -> t
Mul t _ _ -> t
Div t _ _ -> t
Load t _ _ -> t
Store t _ _ _ -> t
Type x _ -> CustomType x
SetVariable _ ir -> typeOf ir
-- | Converts a list of LLVMIr instructions to a string
llvmIrToString :: [LLVMIr] -> String
llvmIrToString = go 0
@ -147,9 +168,9 @@ llvmIrToString = go 0
go _ [] = mempty
go i (x : xs) = do
let (i', n) = case x of
Define{} -> (i + 1, 0)
Define{} -> (i + 1, 0)
DefineEnd -> (i - 1, 0)
_ -> (i, i)
_ -> (i, i)
insToString n x <> go i' xs
-- \| Converts a LLVM inststruction to a String, allowing for printing etc.
@ -224,10 +245,10 @@ llvmIrToString = go 0
, ")\n"
]
(Alloca t) -> unwords ["alloca", toIr t, "\n"]
(Malloc t) ->
(Malloc t) ->
concat
[ "call ptr @malloc(i64 ", show t, ")\n"]
(GcMalloc t) ->
(GcMalloc t) ->
concat
[ "call ptr @cheap_alloc(i64 ", show t, ")\n"]
(Store t1 val t2 (Ident id2)) ->