Data type constructors now properly tag the data.

This commit is contained in:
Samuel Hammersberg 2023-02-24 18:37:31 +01:00
parent 262543931c
commit 7cf6f30835
2 changed files with 40 additions and 13 deletions

View file

@ -5,6 +5,7 @@ module Compiler (compile) where
import Auxiliary (snoc)
import Control.Monad.State (StateT, execStateT, gets, modify)
import qualified Data.Bifunctor as BI
import Data.List.Extra (trim)
import Data.Map (Map)
import qualified Data.Map as Map
@ -16,7 +17,6 @@ import LlvmIr (CallingConvention (..), LLVMComp (..),
LLVMValue (..), Visibility (..),
llvmIrToString)
import System.Process.Extra (readCreateProcess, shell)
import TypeChecker (partitionType)
import TypeCheckerIr (Bind (..), Case (..), Exp (..), Id,
Ident (..), Program (..), Type (..))
@ -24,7 +24,7 @@ import TypeCheckerIr (Bind (..), Case (..), Exp (..), Id,
data CodeGenerator = CodeGenerator
{ instructions :: [LLVMIr]
, functions :: Map Id FunctionInfo
, constructors :: Map Id FunctionInfo
, constructors :: Map Id ConstructorInfo
, variableCount :: Integer
, labelCount :: Integer
}
@ -36,7 +36,12 @@ data FunctionInfo = FunctionInfo
{ numArgs :: Int
, arguments :: [Id]
}
deriving Show
data ConstructorInfo = ConstructorInfo
{ numArgsCI :: Int
, argumentsCI :: [Id]
, numCI :: Integer
}
-- | Adds a instruction to the CodeGenerator state
emit :: LLVMIr -> CompilerState ()
@ -80,14 +85,16 @@ createArgs xs = fst $ foldl (\(acc, l) t -> (acc ++ [(Ident ("arg_" <> show l) ,
-- | Produces a map of functions infos from a list of binds,
-- which contains useful data for code generation.
getConstructors :: [Bind] -> Map Id FunctionInfo
getConstructors :: [Bind] -> Map Id ConstructorInfo
getConstructors bs = Map.fromList $ go bs
where
go [] = []
go (DataStructure n cons : xs) = do
map (\(id, xs) -> ((id, TPol n), FunctionInfo {
numArgs=length xs, arguments=createArgs xs
})) cons
fst (foldl (\(acc,i) (id, xs) -> (((id, TPol n), ConstructorInfo {
numArgsCI=length xs,
argumentsCI=createArgs xs,
numCI=i
}) : acc, i+1)) ([],0) cons)
<> go xs
go (_: xs) = go xs
@ -130,12 +137,25 @@ compile (Program scs) = do
compileScs :: [Bind] -> CompilerState ()
compileScs [] = do
return ()
-- c <- gets (Map.toList . constructors)
-- mapM_ (\((id, t), fi) -> do
-- emit $ Define FastCC (type2LlvmType t) id []
-- emit DefineEnd
-- ) c
-- as a last step create all the constructors
c <- gets (Map.toList . constructors)
mapM_ (\((id, t), ci) -> do
let x = BI.second type2LlvmType <$> argumentsCI ci
emit $ Define FastCC (type2LlvmType t) id x
top <- Ident . show <$> getNewVar
ptr <- Ident . show <$> getNewVar
emit $ SetVariable top (Alloca (type2LlvmType t))
-- %0 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
emit $ SetVariable ptr $
GetElementPtrInbounds (type2LlvmType t) (Ref $ type2LlvmType t)
(VIdent top I8) I32 (VInteger 0) I32 (VInteger 0)
emit $ Store I8 (VInteger $ numCI ci ) (Ref I8) ptr
-- store i8 1, i8* %0
emit $ Ret I64 (VInteger 0)
emit DefineEnd
modify $ \s -> s { variableCount = 0 }
) c
compileScs (Bind (name, _t) args exp : xs) = do
emit $ UnsafeRaw "\n"
emit . Comment $ show name <> ": " <> show exp

View file

@ -104,6 +104,7 @@ data LLVMIr
| Declare LLVMType Ident Params
| SetVariable Ident LLVMIr
| Variable Ident
| GetElementPtrInbounds LLVMType LLVMType LLVMValue LLVMType LLVMValue LLVMType LLVMValue
| Add LLVMType LLVMValue LLVMValue
| Sub LLVMType LLVMValue LLVMValue
| Div LLVMType LLVMValue LLVMValue
@ -144,6 +145,12 @@ llvmIrToString = go 0
insToString :: Int -> LLVMIr -> String
insToString i l =
replicate i '\t' <> case l of
(GetElementPtrInbounds t1 t2 p t3 v1 t4 v2) -> do
-- getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
concat
[ "getelementptr inbounds ", show t1, ", " , show t2
, " ", show p, ", ", show t3, " ", show v1,
", ", show t4, " ", show v2, "\n" ]
(Type (Ident n) types) ->
concat
[ "%", n, " = type { "