-- Semantic -- Decaf IR generator and semantic checker
-- Copyright (C) 2018 Jun Zhang <zhangjunphy[at]gmail[dot]com>
--
-- This file is a part of decafc.
--
-- decafc is free software: you can redistribute it and/or modify it under the
-- terms of the MIT (X11) License as described in the LICENSE file.
--
-- decafc is distributed in the hope that it will be useful, but WITHOUT ANY
-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE.  See the X11 license for more details.
module CodeGen (buildLLVMIR) where

import CodeGen.LLVMGen
import CFG (SingleFileCFG)
import CodeGen.LLVMIR (Module)
import Types (CompileError)
import Control.Monad.Except (runExceptT)
import Control.Monad.State (runState)

buildLLVMIR :: SingleFileCFG -> Either [CompileError] Module
buildLLVMIR :: SingleFileCFG -> Either [CompileError] Module
buildLLVMIR SingleFileCFG
cfg =
  let genLLVM :: LLVMGen Module
genLLVM = SingleFileCFG -> LLVMGen Module
genLLVMIR SingleFileCFG
cfg
      (Either CompileError Module
res, LLVMGenState
_) = (State LLVMGenState (Either CompileError Module)
-> LLVMGenState -> (Either CompileError Module, LLVMGenState)
forall s a. State s a -> s -> (a, s)
runState (State LLVMGenState (Either CompileError Module)
 -> LLVMGenState -> (Either CompileError Module, LLVMGenState))
-> State LLVMGenState (Either CompileError Module)
-> LLVMGenState
-> (Either CompileError Module, LLVMGenState)
forall a b. (a -> b) -> a -> b
$ ExceptT CompileError (StateT LLVMGenState Identity) Module
-> State LLVMGenState (Either CompileError Module)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT CompileError (StateT LLVMGenState Identity) Module
 -> State LLVMGenState (Either CompileError Module))
-> ExceptT CompileError (StateT LLVMGenState Identity) Module
-> State LLVMGenState (Either CompileError Module)
forall a b. (a -> b) -> a -> b
$ LLVMGen Module
-> ExceptT CompileError (StateT LLVMGenState Identity) Module
forall a.
LLVMGen a -> ExceptT CompileError (StateT LLVMGenState Identity) a
runLLVMGen LLVMGen Module
genLLVM) LLVMGenState
LLVMGenState
  in
    case Either CompileError Module
res of
      Left CompileError
err -> [CompileError] -> Either [CompileError] Module
forall a b. a -> Either a b
Left [CompileError
err]
      Right Module
mod -> Module -> Either [CompileError] Module
forall a b. b -> Either a b
Right Module
mod