No more warnings, but everything to do with datatypes is outcommented.
This commit is contained in:
parent
6cbc83c5d9
commit
75fa232e21
4 changed files with 172 additions and 193 deletions
|
|
@ -4,40 +4,25 @@
|
||||||
module Codegen.Codegen (generateCode) where
|
module Codegen.Codegen (generateCode) where
|
||||||
|
|
||||||
import Auxiliary (snoc)
|
import Auxiliary (snoc)
|
||||||
import Codegen.LlvmIr (
|
|
||||||
CallingConvention (..),
|
|
||||||
LLVMComp (..),
|
|
||||||
LLVMIr (..),
|
|
||||||
LLVMType (..),
|
|
||||||
LLVMValue (..),
|
|
||||||
Visibility (..),
|
|
||||||
llvmIrToString,
|
|
||||||
)
|
|
||||||
import Codegen.LlvmIr as LIR
|
import Codegen.LlvmIr as LIR
|
||||||
import Control.Applicative ((<|>))
|
import Control.Applicative ((<|>))
|
||||||
import Control.Monad.State (
|
import Control.Monad.State (StateT, execStateT, foldM_,
|
||||||
StateT,
|
gets, modify)
|
||||||
execStateT,
|
import qualified Data.Bifunctor as BI
|
||||||
foldM_,
|
import Data.Coerce (coerce)
|
||||||
gets,
|
|
||||||
modify,
|
|
||||||
)
|
|
||||||
import Data.Bifunctor qualified as BI
|
|
||||||
import Data.List.Extra (trim)
|
|
||||||
import Data.Map (Map)
|
import Data.Map (Map)
|
||||||
import Data.Map qualified as Map
|
import qualified Data.Map as Map
|
||||||
import Data.Maybe (fromJust, fromMaybe)
|
import Data.Maybe (fromJust, fromMaybe)
|
||||||
import Data.Tuple.Extra (dupe, first, second)
|
import Data.Tuple.Extra (dupe, first, second)
|
||||||
import Grammar.Abs qualified as GA
|
import qualified Grammar.Abs as GA
|
||||||
import Grammar.ErrM (Err)
|
import Grammar.ErrM (Err)
|
||||||
import Monomorphizer.MonomorphizerIr as MIR
|
import Monomorphizer.MonomorphizerIr as MIR
|
||||||
import System.Process.Extra (readCreateProcess, shell)
|
|
||||||
|
|
||||||
-- | The record used as the code generator state
|
-- | The record used as the code generator state
|
||||||
data CodeGenerator = CodeGenerator
|
data CodeGenerator = CodeGenerator
|
||||||
{ instructions :: [LLVMIr]
|
{ instructions :: [LLVMIr]
|
||||||
, functions :: Map Id FunctionInfo
|
, functions :: Map MIR.Id FunctionInfo
|
||||||
, constructors :: Map Id ConstructorInfo
|
, constructors :: Map Ident ConstructorInfo
|
||||||
, variableCount :: Integer
|
, variableCount :: Integer
|
||||||
, labelCount :: Integer
|
, labelCount :: Integer
|
||||||
}
|
}
|
||||||
|
|
@ -82,18 +67,17 @@ getNewLabel = do
|
||||||
{- | 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.
|
||||||
-}
|
-}
|
||||||
getFunctions :: [Bind] -> Map Id FunctionInfo
|
getFunctions :: [MIR.Def] -> Map Id FunctionInfo
|
||||||
getFunctions bs = Map.fromList $ go bs
|
getFunctions bs = Map.fromList $ go bs
|
||||||
where
|
where
|
||||||
go [] = []
|
go [] = []
|
||||||
go (Bind id args _ : xs) =
|
go (MIR.DBind (MIR.Bind id args _) : xs) =
|
||||||
(id, FunctionInfo{numArgs = length args, arguments = args})
|
(id, FunctionInfo{numArgs = length args, arguments = args})
|
||||||
: go xs
|
: go xs
|
||||||
go (DataType n cons : xs) =
|
go (MIR.DData (MIR.Data n cons) : xs) = undefined
|
||||||
do
|
{-do map
|
||||||
map
|
|
||||||
( \(Constructor id xs) ->
|
( \(Constructor id xs) ->
|
||||||
( (id, MIR.Type n)
|
( (id, MIR.TLit n)
|
||||||
, FunctionInfo
|
, FunctionInfo
|
||||||
{ numArgs = length xs
|
{ numArgs = length xs
|
||||||
, arguments = createArgs xs
|
, arguments = createArgs xs
|
||||||
|
|
@ -101,24 +85,24 @@ getFunctions bs = Map.fromList $ go bs
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
cons
|
cons
|
||||||
<> go xs
|
<> go xs-}
|
||||||
|
|
||||||
createArgs :: [Type] -> [Id]
|
createArgs :: [MIR.Type] -> [Id]
|
||||||
createArgs xs = fst $ foldl (\(acc, l) t -> (acc ++ [(GA.Ident ("arg_" <> show l), t)], l + 1)) ([], 0) xs
|
createArgs xs = fst $ foldl (\(acc, l) t -> (acc ++ [(GA.Ident ("arg_" <> show l), t)], l + 1)) ([], 0) xs
|
||||||
|
|
||||||
{- | 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 ConstructorInfo
|
getConstructors :: [MIR.Def] -> Map Ident ConstructorInfo
|
||||||
getConstructors bs = Map.fromList $ go bs
|
getConstructors bs = Map.fromList $ go bs
|
||||||
where
|
where
|
||||||
go [] = []
|
go [] = []
|
||||||
go (DataType (GA.Ident n) cons : xs) =
|
go (MIR.DData (MIR.Data n cons) : xs) = undefined
|
||||||
do
|
{-do
|
||||||
fst
|
fst
|
||||||
( foldl
|
( foldl
|
||||||
( \(acc, i) (Constructor (GA.Ident id) xs) ->
|
( \(acc, i) (GA.Constructor (GA.Ident id) xs) ->
|
||||||
( ( (GA.Ident (n <> "_" <> id), MIR.Type (GA.Ident n))
|
( ( (GA.Ident (n <> "_" <> id), MIR.TLit (GA.Ident n))
|
||||||
, ConstructorInfo
|
, ConstructorInfo
|
||||||
{ numArgsCI = length xs
|
{ numArgsCI = length xs
|
||||||
, argumentsCI = createArgs xs
|
, argumentsCI = createArgs xs
|
||||||
|
|
@ -132,10 +116,10 @@ getConstructors bs = Map.fromList $ go bs
|
||||||
([], 0)
|
([], 0)
|
||||||
cons
|
cons
|
||||||
)
|
)
|
||||||
<> go xs
|
<> go xs-}
|
||||||
go (_ : xs) = go xs
|
go (_ : xs) = go xs
|
||||||
|
|
||||||
initCodeGenerator :: [Bind] -> CodeGenerator
|
initCodeGenerator :: [MIR.Def] -> CodeGenerator
|
||||||
initCodeGenerator scs =
|
initCodeGenerator scs =
|
||||||
CodeGenerator
|
CodeGenerator
|
||||||
{ instructions = defaultStart
|
{ instructions = defaultStart
|
||||||
|
|
@ -145,6 +129,7 @@ initCodeGenerator scs =
|
||||||
, labelCount = 0
|
, labelCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{-
|
||||||
run :: Err String -> IO ()
|
run :: Err String -> IO ()
|
||||||
run s = do
|
run s = do
|
||||||
let s' = case s of
|
let s' = case s of
|
||||||
|
|
@ -171,7 +156,7 @@ test v =
|
||||||
-- (EApp (MIR.Type (GA.Ident "Craig")) (EId (GA.Ident "Craig_Bob", MIR.Type (GA.Ident "Craig")), MIR.Type (GA.Ident "Craig")) (ELit (LInt v), MIR.Type (GA.Ident "_Int")), MIR.Type (GA.Ident "Craig"))-- (EInt 92)
|
-- (EApp (MIR.Type (GA.Ident "Craig")) (EId (GA.Ident "Craig_Bob", MIR.Type (GA.Ident "Craig")), MIR.Type (GA.Ident "Craig")) (ELit (LInt v), MIR.Type (GA.Ident "_Int")), MIR.Type (GA.Ident "Craig"))-- (EInt 92)
|
||||||
$
|
$
|
||||||
eCaseInt
|
eCaseInt
|
||||||
(EApp (MIR.Type (GA.Ident "Craig")) (EId (GA.Ident "Craig_Bob", MIR.Type (GA.Ident "Craig")), MIR.Type (GA.Ident "Craig")) (ELit (LInt v), MIR.Type (GA.Ident "_Int")), MIR.Type (GA.Ident "Craig"))
|
(EApp (MIR.TLit (GA.Ident "Craig")) (EId (GA.Ident "Craig_Bob", MIR.TLit (GA.Ident "Craig")), MIR.TLit (GA.Ident "Craig")) (ELit (LInt v), MIR.Type (GA.Ident "_Int")), MIR.Type (GA.Ident "Craig"))
|
||||||
[ injectionCons "Craig_Bob" "Craig" [CIdent (GA.Ident "x")] (EId (GA.Ident "x", MIR.Type (GA.Ident "_Int")), MIR.Type (GA.Ident "_Int"))
|
[ injectionCons "Craig_Bob" "Craig" [CIdent (GA.Ident "x")] (EId (GA.Ident "x", MIR.Type (GA.Ident "_Int")), MIR.Type (GA.Ident "_Int"))
|
||||||
, injectionCons "Craig_Betty" "Craig" [CLit (LInt 5)] (int 2)
|
, injectionCons "Craig_Betty" "Craig" [CLit (LInt 5)] (int 2)
|
||||||
, Injection (CIdent (GA.Ident "z")) (int 3)
|
, Injection (CIdent (GA.Ident "z")) (int 3)
|
||||||
|
|
@ -183,23 +168,24 @@ test v =
|
||||||
injectionCons x y xs = Injection (CCons (GA.Ident x, MIR.Type (GA.Ident y)) xs)
|
injectionCons x y xs = Injection (CCons (GA.Ident x, MIR.Type (GA.Ident y)) xs)
|
||||||
injectionInt x = Injection (CLit (LInt x))
|
injectionInt x = Injection (CLit (LInt x))
|
||||||
injectionCatchAll = Injection CatchAll
|
injectionCatchAll = Injection CatchAll
|
||||||
eCaseInt x xs = (ECase (MIR.Type "_Int") x xs, MIR.Type "_Int")
|
eCaseInt x xs = (ECase (MIR.TLit (MIR.Ident "_Int")) x xs, MIR.TLit (MIR.Ident "_Int"))
|
||||||
int x = (ELit (LInt x), MIR.Type "_Int")
|
int x = (ELit (LInt x), MIR.TLit (MIR.Ident "_Int"))
|
||||||
|
-}
|
||||||
{- | Compiles an AST and produces a LLVM Ir string.
|
{- | Compiles an AST and produces a LLVM Ir string.
|
||||||
An easy way to actually "compile" this output is to
|
An easy way to actually "compile" this output is to
|
||||||
Simply pipe it to LLI
|
Simply pipe it to LLI
|
||||||
-}
|
-}
|
||||||
generateCode :: Program -> Err String
|
generateCode :: MIR.Program -> Err String
|
||||||
generateCode (Program scs) = do
|
generateCode (MIR.Program scs) = do
|
||||||
let codegen = initCodeGenerator scs
|
let codegen = initCodeGenerator scs
|
||||||
llvmIrToString . instructions <$> execStateT (compileScs scs) codegen
|
llvmIrToString . instructions <$> execStateT (compileScs scs) codegen
|
||||||
|
|
||||||
compileScs :: [Bind] -> CompilerState ()
|
compileScs :: [MIR.Def] -> CompilerState ()
|
||||||
compileScs [] = do
|
compileScs [] = do
|
||||||
|
undefined
|
||||||
-- as a last step create all the constructors
|
-- as a last step create all the constructors
|
||||||
-- //TODO maybe merge this with the data type match?
|
-- //TODO maybe merge this with the data type match?
|
||||||
c <- gets (Map.toList . constructors)
|
{-c <- gets (Map.toList . constructors)
|
||||||
mapM_
|
mapM_
|
||||||
( \((id, t), ci) -> do
|
( \((id, t), ci) -> do
|
||||||
let t' = type2LlvmType t
|
let t' = type2LlvmType t
|
||||||
|
|
@ -261,28 +247,29 @@ compileScs [] = do
|
||||||
|
|
||||||
modify $ \s -> s{variableCount = 0}
|
modify $ \s -> s{variableCount = 0}
|
||||||
)
|
)
|
||||||
c
|
c-}
|
||||||
compileScs (Bind (name, _t) args exp : xs) = do
|
compileScs (MIR.DBind (MIR.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
|
||||||
let args' = map (second type2LlvmType) args
|
let args' = map (second type2LlvmType) args
|
||||||
emit $ Define FastCC I64 {-(type2LlvmType t_return)-} name args'
|
emit $ Define FastCC I64 {-(type2LlvmType t_return)-} name args'
|
||||||
functionBody <- exprToValue (fst exp)
|
functionBody <- exprToValue exp
|
||||||
if name == "main"
|
if name == "main"
|
||||||
then mapM_ emit $ mainContent functionBody
|
then mapM_ emit $ mainContent functionBody
|
||||||
else emit $ Ret I64 functionBody
|
else emit $ Ret I64 functionBody
|
||||||
emit DefineEnd
|
emit DefineEnd
|
||||||
modify $ \s -> s{variableCount = 0}
|
modify $ \s -> s{variableCount = 0}
|
||||||
compileScs xs
|
compileScs xs
|
||||||
compileScs (DataType id@(GA.Ident outer_id) ts : xs) = do
|
compileScs (MIR.DData (MIR.Data outer_id ts) : xs) = do
|
||||||
let biggestVariant = maximum ((\(Constructor _ t) -> sum $ typeByteSize . type2LlvmType <$> t) <$> ts)
|
undefined
|
||||||
emit $ LIR.Type id [I8, Array biggestVariant I8]
|
-- let biggestVariant = maximum ((\(Constructor _ t) -> sum $ typeByteSize . type2LlvmType <$> t) <$> ts)
|
||||||
mapM_
|
-- emit $ LIR.Type outer_id [I8, Array biggestVariant I8]
|
||||||
( \(Constructor (GA.Ident inner_id) fi) -> do
|
-- mapM_
|
||||||
emit $ LIR.Type (GA.Ident $ outer_id <> "_" <> inner_id) (I8 : map type2LlvmType fi)
|
-- ( \(GA.Constructor (GA.UIdent inner_id) fi) -> do
|
||||||
)
|
-- emit $ LIR.Type (GA.Ident $ outer_id <> "_" <> inner_id) (I8 : map type2LlvmType fi)
|
||||||
ts
|
-- )
|
||||||
compileScs xs
|
-- ts
|
||||||
|
-- compileScs xs
|
||||||
|
|
||||||
-- where
|
-- where
|
||||||
-- _t_return = snd $ partitionType (length args) t
|
-- _t_return = snd $ partitionType (length args) t
|
||||||
|
|
@ -318,27 +305,27 @@ defaultStart =
|
||||||
, UnsafeRaw "declare i32 @printf(ptr noalias nocapture, ...)\n"
|
, UnsafeRaw "declare i32 @printf(ptr noalias nocapture, ...)\n"
|
||||||
]
|
]
|
||||||
|
|
||||||
compileExp :: Exp -> CompilerState ()
|
compileExp :: ExpT -> CompilerState ()
|
||||||
compileExp (ELit lit) = emitLit lit
|
compileExp (MIR.ELit lit,t) = emitLit lit
|
||||||
compileExp (EAdd t e1 e2) = emitAdd t (fst e1) (fst e2)
|
compileExp (MIR.EAdd e1 e2,t) = emitAdd t e1 e2
|
||||||
-- compileExp (ESub t e1 e2) = emitSub t e1 e2
|
-- compileExp (ESub t e1 e2) = emitSub t e1 e2
|
||||||
compileExp (EId (name, _)) = emitIdent name
|
compileExp (MIR.EId name,t) = emitIdent name
|
||||||
compileExp (EApp t e1 e2) = emitApp t (fst e1) (fst e2)
|
compileExp (MIR.EApp e1 e2,t) = emitApp t e1 e2
|
||||||
-- compileExp (EAbs t ti e) = emitAbs t ti e
|
-- compileExp (EAbs t ti e) = emitAbs t ti e
|
||||||
compileExp (ELet _ binds e) = undefined emitLet binds (fst e)
|
compileExp (MIR.ELet binds e,t) = undefined -- emitLet binds (fst e)
|
||||||
compileExp (ECase t e cs) = emitECased t e (map (t,) cs)
|
compileExp (MIR.ECase e cs,t) = emitECased t e (map (t,) cs)
|
||||||
|
|
||||||
-- go (EMul e1 e2) = emitMul e1 e2
|
-- go (EMul e1 e2) = emitMul e1 e2
|
||||||
-- go (EDiv e1 e2) = emitDiv e1 e2
|
-- go (EDiv e1 e2) = emitDiv e1 e2
|
||||||
-- go (EMod e1 e2) = emitMod e1 e2
|
-- go (EMod e1 e2) = emitMod e1 e2
|
||||||
|
|
||||||
--- aux functions ---
|
--- aux functions ---
|
||||||
emitECased :: Type -> ExpT -> [(Type, Injection)] -> CompilerState ()
|
emitECased :: MIR.Type -> ExpT -> [(MIR.Type, Injection)] -> CompilerState ()
|
||||||
emitECased t e cases = do
|
emitECased t e cases = do
|
||||||
let cs = snd <$> cases
|
let cs = snd <$> cases
|
||||||
let ty = type2LlvmType t
|
let ty = type2LlvmType t
|
||||||
let rt = type2LlvmType (snd e)
|
let rt = type2LlvmType (snd e)
|
||||||
vs <- exprToValue (fst e)
|
vs <- exprToValue e
|
||||||
lbl <- getNewLabel
|
lbl <- getNewLabel
|
||||||
let label = GA.Ident $ "escape_" <> show lbl
|
let label = GA.Ident $ "escape_" <> show lbl
|
||||||
stackPtr <- getNewVar
|
stackPtr <- getNewVar
|
||||||
|
|
@ -349,9 +336,9 @@ emitECased t e cases = do
|
||||||
emit $ SetVariable res (Load ty Ptr stackPtr)
|
emit $ SetVariable res (Load ty Ptr stackPtr)
|
||||||
where
|
where
|
||||||
emitCases :: LLVMType -> LLVMType -> GA.Ident -> GA.Ident -> LLVMValue -> Injection -> CompilerState ()
|
emitCases :: LLVMType -> LLVMType -> GA.Ident -> GA.Ident -> LLVMValue -> Injection -> CompilerState ()
|
||||||
emitCases rt ty label stackPtr vs (Injection (MIR.CCons consId cs) exp) = do
|
emitCases rt ty label stackPtr vs (Injection (MIR.InitConstructor consId cs, _t) exp) = do
|
||||||
cons <- gets constructors
|
cons <- gets constructors
|
||||||
let r = fromJust $ Map.lookup consId cons
|
let r = fromJust $ Map.lookup (coerce consId) cons
|
||||||
|
|
||||||
lbl_failPos <- (\x -> GA.Ident $ "failed_" <> show x) <$> getNewLabel
|
lbl_failPos <- (\x -> GA.Ident $ "failed_" <> show x) <$> getNewLabel
|
||||||
lbl_succPos <- (\x -> GA.Ident $ "success_" <> show x) <$> getNewLabel
|
lbl_succPos <- (\x -> GA.Ident $ "success_" <> show x) <$> getNewLabel
|
||||||
|
|
@ -370,62 +357,62 @@ emitECased t e cases = do
|
||||||
emit $ SetVariable castPtr (Alloca rt)
|
emit $ SetVariable castPtr (Alloca rt)
|
||||||
emit $ Store rt vs Ptr castPtr
|
emit $ Store rt vs Ptr castPtr
|
||||||
emit $ SetVariable castedPtr (Bitcast Ptr (VIdent castPtr Ptr) Ptr)
|
emit $ SetVariable castedPtr (Bitcast Ptr (VIdent castPtr Ptr) Ptr)
|
||||||
emit $ SetVariable casted (Load (CustomType (fst consId)) Ptr castedPtr)
|
emit $ SetVariable casted (Load (CustomType (coerce consId)) Ptr castedPtr)
|
||||||
|
|
||||||
val <- exprToValue (fst exp)
|
val <- exprToValue exp
|
||||||
enumerateOneM_
|
-- enumerateOneM_
|
||||||
( \i c -> do
|
-- (\i c -> do
|
||||||
case c of
|
-- case c of
|
||||||
CIdent x -> do
|
-- CIdent x -> do
|
||||||
emit . Comment $ "ident " <> show x
|
-- emit . Comment $ "ident " <> show x
|
||||||
emit $ SetVariable x (ExtractValue (CustomType (fst consId)) (VIdent casted Ptr) i)
|
-- emit $ SetVariable x (ExtractValue (CustomType (fst consId)) (VIdent casted Ptr) i)
|
||||||
emit $ Store ty val Ptr stackPtr
|
-- emit $ Store ty val Ptr stackPtr
|
||||||
CCons x cs -> error "nested constructor"
|
-- CCons x cs -> error "nested constructor"
|
||||||
CLit l -> do
|
-- CLit l -> do
|
||||||
testVar <- getNewVar
|
-- testVar <- getNewVar
|
||||||
emit $ SetVariable testVar (ExtractValue (CustomType (fst consId)) (VIdent casted Ptr) i)
|
-- emit $ SetVariable testVar (ExtractValue (CustomType (fst consId)) (VIdent casted Ptr) i)
|
||||||
case l of
|
-- case l of
|
||||||
LInt l -> emit $ Icmp LLEq I64 (VIdent testVar Ptr) (VInteger l)
|
-- LInt l -> emit $ Icmp LLEq I64 (VIdent testVar Ptr) (VInteger l)
|
||||||
LChar c -> emit $ Icmp LLEq I8 (VIdent testVar Ptr) (VChar c)
|
-- LChar c -> emit $ Icmp LLEq I8 (VIdent testVar Ptr) (VChar c)
|
||||||
CatchAll -> emit . Comment $ "Catch all"
|
-- CCatch -> emit . Comment $ "Catch all"
|
||||||
emit . Comment $ "return this " <> toIr val
|
-- emit . Comment $ "return this " <> toIr val
|
||||||
emit . Comment . show $ c
|
-- emit . Comment . show $ c
|
||||||
emit . Comment . show $ i
|
-- emit . Comment . show $ i
|
||||||
)
|
-- )
|
||||||
cs
|
-- cs
|
||||||
-- emit $ Store ty val Ptr stackPtr
|
-- emit $ Store ty val Ptr stackPtr
|
||||||
emit $ Br label
|
emit $ Br label
|
||||||
emit $ Label lbl_failPos
|
emit $ Label lbl_failPos
|
||||||
emitCases rt ty label stackPtr vs (Injection (MIR.CLit i) exp) = do
|
emitCases rt ty label stackPtr vs (Injection (MIR.InitLit i, _) exp) = do
|
||||||
let i' = case i of
|
let i' = case i of
|
||||||
LInt i -> VInteger i
|
GA.LInt i -> VInteger i
|
||||||
LChar i -> VChar i
|
GA.LChar i -> VChar i
|
||||||
ns <- getNewVar
|
ns <- getNewVar
|
||||||
lbl_failPos <- (\x -> GA.Ident $ "failed_" <> show x) <$> getNewLabel
|
lbl_failPos <- (\x -> GA.Ident $ "failed_" <> show x) <$> getNewLabel
|
||||||
lbl_succPos <- (\x -> GA.Ident $ "success_" <> show x) <$> getNewLabel
|
lbl_succPos <- (\x -> GA.Ident $ "success_" <> show x) <$> getNewLabel
|
||||||
emit $ SetVariable ns (Icmp LLEq ty vs i')
|
emit $ SetVariable ns (Icmp LLEq ty vs i')
|
||||||
emit $ BrCond (VIdent ns ty) lbl_succPos lbl_failPos
|
emit $ BrCond (VIdent ns ty) lbl_succPos lbl_failPos
|
||||||
emit $ Label lbl_succPos
|
emit $ Label lbl_succPos
|
||||||
val <- exprToValue (fst exp)
|
val <- exprToValue exp
|
||||||
emit $ Store ty val Ptr stackPtr
|
emit $ Store ty val Ptr stackPtr
|
||||||
emit $ Br label
|
emit $ Br label
|
||||||
emit $ Label lbl_failPos
|
emit $ Label lbl_failPos
|
||||||
emitCases rt ty label stackPtr vs (Injection (MIR.CIdent id) exp) = do
|
-- emitCases rt ty label stackPtr vs (Injection (MIR.CIdent id) exp) = do
|
||||||
-- //TODO this is pretty disgusting and would heavily benefit from a rewrite
|
-- -- //TODO this is pretty disgusting and would heavily benefit from a rewrite
|
||||||
valPtr <- getNewVar
|
-- valPtr <- getNewVar
|
||||||
emit $ SetVariable valPtr (Alloca rt)
|
-- emit $ SetVariable valPtr (Alloca rt)
|
||||||
emit $ Store rt vs Ptr valPtr
|
-- emit $ Store rt vs Ptr valPtr
|
||||||
emit $ SetVariable id (Load rt Ptr valPtr)
|
-- emit $ SetVariable id (Load rt Ptr valPtr)
|
||||||
increaseVarCount
|
-- increaseVarCount
|
||||||
val <- exprToValue (fst exp)
|
-- val <- exprToValue (fst exp)
|
||||||
emit $ Store ty val Ptr stackPtr
|
-- emit $ Store ty val Ptr stackPtr
|
||||||
emit $ Br label
|
-- emit $ Br label
|
||||||
emitCases _ ty label stackPtr _ (Injection MIR.CatchAll exp) = do
|
emitCases _ ty label stackPtr _ (Injection (MIR.InitCatch, _) exp) = do
|
||||||
val <- exprToValue (fst exp)
|
val <- exprToValue exp
|
||||||
emit $ Store ty val Ptr stackPtr
|
emit $ Store ty val Ptr stackPtr
|
||||||
emit $ Br label
|
emit $ Br label
|
||||||
|
|
||||||
emitLet :: Bind -> Exp -> CompilerState ()
|
--emitLet :: Bind -> Exp -> CompilerState ()
|
||||||
emitLet xs e = do
|
emitLet xs e = do
|
||||||
emit $
|
emit $
|
||||||
Comment $
|
Comment $
|
||||||
|
|
@ -437,26 +424,26 @@ emitLet xs e = do
|
||||||
, ") is not implemented!"
|
, ") is not implemented!"
|
||||||
]
|
]
|
||||||
|
|
||||||
emitApp :: Type -> Exp -> Exp -> CompilerState ()
|
emitApp :: MIR.Type -> ExpT -> ExpT -> CompilerState ()
|
||||||
emitApp t e1 e2 = appEmitter t e1 e2 []
|
emitApp t e1 e2 = appEmitter e1 e2 []
|
||||||
where
|
where
|
||||||
appEmitter :: Type -> Exp -> Exp -> [Exp] -> CompilerState ()
|
appEmitter :: ExpT -> ExpT -> [ExpT] -> CompilerState ()
|
||||||
appEmitter t e1 e2 stack = do
|
appEmitter e1 e2 stack = do
|
||||||
let newStack = e2 : stack
|
let newStack = e2 : stack
|
||||||
case e1 of
|
case e1 of
|
||||||
EApp _ (e1', _) (e2', _) -> appEmitter t e1' e2' newStack
|
(MIR.EApp e1' e2', t) -> appEmitter e1' e2' newStack
|
||||||
EId id@(GA.Ident name, _) -> do
|
(MIR.EId name, t) -> do
|
||||||
args <- traverse exprToValue newStack
|
args <- traverse exprToValue newStack
|
||||||
vs <- getNewVar
|
vs <- getNewVar
|
||||||
funcs <- gets functions
|
funcs <- gets functions
|
||||||
consts <- gets constructors
|
consts <- gets constructors
|
||||||
let visibility =
|
let visibility =
|
||||||
fromMaybe Local $
|
fromMaybe Local $
|
||||||
Global <$ Map.lookup id consts
|
Global <$ Map.lookup name consts
|
||||||
<|> Global <$ Map.lookup id funcs
|
<|> Global <$ Map.lookup (name,t) funcs
|
||||||
-- this piece of code could probably be improved, i.e remove the double `const Global`
|
-- this piece of code could probably be improved, i.e remove the double `const Global`
|
||||||
args' = map (first valueGetType . dupe) args
|
args' = map (first valueGetType . dupe) args
|
||||||
call = Call FastCC (type2LlvmType t) visibility (GA.Ident name) args'
|
call = Call FastCC (type2LlvmType t) visibility name args'
|
||||||
emit $ SetVariable vs call
|
emit $ SetVariable vs call
|
||||||
x -> error $ "The unspeakable happened: " <> show x
|
x -> error $ "The unspeakable happened: " <> show x
|
||||||
|
|
||||||
|
|
@ -467,38 +454,38 @@ emitIdent id = do
|
||||||
emit $ Variable id
|
emit $ Variable id
|
||||||
emit $ UnsafeRaw "\n"
|
emit $ UnsafeRaw "\n"
|
||||||
|
|
||||||
emitLit :: Lit -> CompilerState ()
|
emitLit :: MIR.Lit -> CompilerState ()
|
||||||
emitLit i = do
|
emitLit i = do
|
||||||
-- !!this should never happen!!
|
-- !!this should never happen!!
|
||||||
let (i', t) = case i of
|
let (i', t) = case i of
|
||||||
(LInt i'') -> (VInteger i'', I64)
|
(MIR.LInt i'') -> (VInteger i'', I64)
|
||||||
(LChar i'') -> (VChar i'', I8)
|
(MIR.LChar i'') -> (VChar i'', I8)
|
||||||
varCount <- getNewVar
|
varCount <- getNewVar
|
||||||
emit $ Comment "This should not have happened!"
|
emit $ Comment "This should not have happened!"
|
||||||
emit $ SetVariable (GA.Ident (show varCount)) (Add t i' (VInteger 0))
|
emit $ SetVariable (GA.Ident (show varCount)) (Add t i' (VInteger 0))
|
||||||
|
|
||||||
emitAdd :: Type -> Exp -> Exp -> CompilerState ()
|
emitAdd :: MIR.Type -> ExpT -> ExpT -> CompilerState ()
|
||||||
emitAdd t e1 e2 = do
|
emitAdd t e1 e2 = do
|
||||||
v1 <- exprToValue e1
|
v1 <- exprToValue e1
|
||||||
v2 <- exprToValue e2
|
v2 <- exprToValue e2
|
||||||
v <- getNewVar
|
v <- getNewVar
|
||||||
emit $ SetVariable (GA.Ident $ show v) (Add (type2LlvmType t) v1 v2)
|
emit $ SetVariable (GA.Ident $ show v) (Add (type2LlvmType t) v1 v2)
|
||||||
|
|
||||||
emitSub :: Type -> Exp -> Exp -> CompilerState ()
|
emitSub :: MIR.Type -> ExpT -> ExpT -> CompilerState ()
|
||||||
emitSub t e1 e2 = do
|
emitSub t e1 e2 = do
|
||||||
v1 <- exprToValue e1
|
v1 <- exprToValue e1
|
||||||
v2 <- exprToValue e2
|
v2 <- exprToValue e2
|
||||||
v <- getNewVar
|
v <- getNewVar
|
||||||
emit $ SetVariable v (Sub (type2LlvmType t) v1 v2)
|
emit $ SetVariable v (Sub (type2LlvmType t) v1 v2)
|
||||||
|
|
||||||
exprToValue :: Exp -> CompilerState LLVMValue
|
exprToValue :: ExpT -> CompilerState LLVMValue
|
||||||
exprToValue = \case
|
exprToValue = \case
|
||||||
ELit i -> pure $ case i of
|
(MIR.ELit i, t) -> pure $ case i of
|
||||||
(LInt i) -> VInteger i
|
(MIR.LInt i) -> VInteger i
|
||||||
(LChar i) -> VChar i
|
(MIR.LChar i) -> VChar i
|
||||||
EId id@(name, t) -> do
|
(MIR.EId name, t) -> do
|
||||||
funcs <- gets functions
|
funcs <- gets functions
|
||||||
case Map.lookup id funcs of
|
case Map.lookup (name, t) funcs of
|
||||||
Just fi -> do
|
Just fi -> do
|
||||||
if numArgs fi == 0
|
if numArgs fi == 0
|
||||||
then do
|
then do
|
||||||
|
|
@ -515,10 +502,10 @@ exprToValue = \case
|
||||||
v <- getVarCount
|
v <- getVarCount
|
||||||
pure $ VIdent (GA.Ident $ show v) (getType e)
|
pure $ VIdent (GA.Ident $ show v) (getType e)
|
||||||
|
|
||||||
type2LlvmType :: Type -> LLVMType
|
type2LlvmType :: MIR.Type -> LLVMType
|
||||||
type2LlvmType (MIR.Type (GA.Ident t)) = case t of
|
type2LlvmType = undefined {-(MIR.Type (GA.Ident t)) = case t of
|
||||||
"_Int" -> I64
|
"_Int" -> I64
|
||||||
t -> CustomType (GA.Ident t)
|
t -> CustomType (GA.Ident t)-}
|
||||||
|
|
||||||
-- TInt -> I64
|
-- TInt -> I64
|
||||||
-- TFun t xs -> do
|
-- TFun t xs -> do
|
||||||
|
|
@ -530,15 +517,8 @@ type2LlvmType (MIR.Type (GA.Ident t)) = case t of
|
||||||
-- function2LLVMType (TFun t xs) s = function2LLVMType xs (type2LlvmType t : s)
|
-- function2LLVMType (TFun t xs) s = function2LLVMType xs (type2LlvmType t : s)
|
||||||
-- function2LLVMType x s = (type2LlvmType x, s)
|
-- function2LLVMType x s = (type2LlvmType x, s)
|
||||||
|
|
||||||
getType :: Exp -> LLVMType
|
getType :: ExpT -> LLVMType
|
||||||
getType (ELit l) = I64
|
getType (_, t) = type2LlvmType t
|
||||||
getType (EAdd t _ _) = type2LlvmType t
|
|
||||||
-- getType (ESub t _ _) = type2LlvmType t
|
|
||||||
getType (EId (_, t)) = type2LlvmType t
|
|
||||||
getType (EApp t _ _) = type2LlvmType t
|
|
||||||
-- getType (EAbs t _ _) = type2LlvmType t
|
|
||||||
getType (ELet (_, t) _ e) = type2LlvmType t
|
|
||||||
getType (ECase t _ _) = type2LlvmType t
|
|
||||||
|
|
||||||
valueGetType :: LLVMValue -> LLVMType
|
valueGetType :: LLVMValue -> LLVMType
|
||||||
valueGetType (VInteger _) = I64
|
valueGetType (VInteger _) = I64
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,10 @@ import Control.Monad (when)
|
||||||
import Data.List.Extra (isSuffixOf)
|
import Data.List.Extra (isSuffixOf)
|
||||||
|
|
||||||
import Renamer.Renamer (rename)
|
import Renamer.Renamer (rename)
|
||||||
import System.Directory (
|
import System.Directory (createDirectory, doesPathExist,
|
||||||
createDirectory,
|
|
||||||
doesPathExist,
|
|
||||||
getDirectoryContents,
|
getDirectoryContents,
|
||||||
removeDirectoryRecursive,
|
removeDirectoryRecursive,
|
||||||
setCurrentDirectory,
|
setCurrentDirectory)
|
||||||
)
|
|
||||||
import System.Environment (getArgs)
|
import System.Environment (getArgs)
|
||||||
import System.Exit (exitFailure, exitSuccess)
|
import System.Exit (exitFailure, exitSuccess)
|
||||||
import System.IO (stderr)
|
import System.IO (stderr)
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ monoDef (T.DBind bind) = DBind $ monoBind bind
|
||||||
monoDef (T.DData d) = DData d
|
monoDef (T.DData d) = DData d
|
||||||
|
|
||||||
monoBind :: T.Bind -> Bind
|
monoBind :: T.Bind -> Bind
|
||||||
monoBind (T.Bind name args (e, t)) = Bind name args (monoExpr e, monoType t)
|
monoBind (T.Bind name args (e, t)) = Bind (monoId name) (map monoId args) (monoExpr e, monoType t)
|
||||||
|
|
||||||
monoExpr :: T.Exp -> M.Exp
|
monoExpr :: T.Exp -> M.Exp
|
||||||
monoExpr = \case
|
monoExpr = \case
|
||||||
|
|
@ -40,7 +40,7 @@ monoexpt :: T.ExpT -> M.ExpT
|
||||||
monoexpt (e, t) = (monoExpr e, monoType t)
|
monoexpt (e, t) = (monoExpr e, monoType t)
|
||||||
|
|
||||||
monoId :: T.Id -> Id
|
monoId :: T.Id -> Id
|
||||||
monoId = id
|
monoId (n,t) = (n, monoType t)
|
||||||
|
|
||||||
monoLit :: T.Lit -> Lit
|
monoLit :: T.Lit -> Lit
|
||||||
monoLit (T.LInt i) = LInt i
|
monoLit (T.LInt i) = LInt i
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@ module Monomorphizer.MonomorphizerIr (module Monomorphizer.MonomorphizerIr, modu
|
||||||
import Grammar.Abs (Data (..), Ident (..), Init (..))
|
import Grammar.Abs (Data (..), Ident (..), Init (..))
|
||||||
import qualified Grammar.Abs as GA (Data (..), Ident (..),
|
import qualified Grammar.Abs as GA (Data (..), Ident (..),
|
||||||
Init (..))
|
Init (..))
|
||||||
import qualified TypeChecker.TypeCheckerIr as RE (Id, Indexed)
|
import qualified TypeChecker.TypeCheckerIr as RE (Indexed)
|
||||||
import TypeChecker.TypeCheckerIr (Id, Indexed)
|
import TypeChecker.TypeCheckerIr (Indexed)
|
||||||
|
|
||||||
|
type Id = (Ident, Type)
|
||||||
|
|
||||||
newtype Program = Program [Def]
|
newtype Program = Program [Def]
|
||||||
deriving (Show, Ord, Eq)
|
deriving (Show, Ord, Eq)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue