Data type constructors now properly tag the data.
This commit is contained in:
parent
262543931c
commit
7cf6f30835
2 changed files with 40 additions and 13 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 { "
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue