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

View file

@ -104,6 +104,7 @@ data LLVMIr
| Declare LLVMType Ident Params | Declare LLVMType Ident Params
| SetVariable Ident LLVMIr | SetVariable Ident LLVMIr
| Variable Ident | Variable Ident
| GetElementPtrInbounds LLVMType LLVMType LLVMValue LLVMType LLVMValue LLVMType LLVMValue
| Add LLVMType LLVMValue LLVMValue | Add LLVMType LLVMValue LLVMValue
| Sub LLVMType LLVMValue LLVMValue | Sub LLVMType LLVMValue LLVMValue
| Div LLVMType LLVMValue LLVMValue | Div LLVMType LLVMValue LLVMValue
@ -144,6 +145,12 @@ llvmIrToString = go 0
insToString :: Int -> LLVMIr -> String insToString :: Int -> LLVMIr -> String
insToString i l = insToString i l =
replicate i '\t' <> case l of 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) -> (Type (Ident n) types) ->
concat concat
[ "%", n, " = type { " [ "%", n, " = type { "