elna/src/Main.hs

55 lines
2.2 KiB
Haskell
Raw Normal View History

module Main
( main
) where
2024-07-21 16:15:17 +02:00
2024-09-05 23:18:48 +02:00
import Language.Elna.CommandLine (CommandLine(..), commandLine, execParser)
import Language.Elna.Object.ElfCoder (elfObject)
2024-10-02 22:56:15 +02:00
import Language.Elna.Backend.Allocator (allocate)
import Language.Elna.Glue (glue)
import Language.Elna.Frontend.NameAnalysis (nameAnalysis)
import Language.Elna.Frontend.Parser (programP)
import Language.Elna.Frontend.TypeAnalysis (typeAnalysis)
import Language.Elna.RiscV.CodeGenerator (generateRiscV, riscVConfiguration)
import Language.Elna.RiscV.ElfWriter (riscv32Elf)
2024-09-05 23:18:48 +02:00
import Data.Maybe (fromMaybe)
import System.FilePath (replaceExtension, takeFileName)
2024-09-08 02:08:13 +02:00
import Text.Megaparsec (runParser, errorBundlePretty)
import qualified Data.Text.IO as Text
2024-10-31 22:19:48 +01:00
import System.Exit (ExitCode(..), exitWith)
import Control.Exception (IOException, catch)
-- * Error codes
--
-- 1 - Command line parsing failed and other errors.
-- 2 - The input could not be read.
-- 3 - Parse error.
-- 4 - Name analysis error.
-- 5 - Type error.
2024-11-24 13:05:11 +01:00
-- 6 - Register allocation error.
main :: IO ()
2024-10-31 22:19:48 +01:00
main = execParser commandLine >>= withCommandLine
2024-09-05 23:18:48 +02:00
where
withCommandLine CommandLine{..} =
2024-10-31 22:19:48 +01:00
let defaultOutputName = replaceExtension (takeFileName input) "o"
outputName = fromMaybe defaultOutputName output
in catch (Text.readFile input) (printAndExit 2 :: IOException -> IO a)
>>= withParsedInput outputName
2024-09-08 02:08:13 +02:00
. runParser programP input
2024-10-31 22:19:48 +01:00
withParsedInput output (Right program)
= either (printAndExit 4) (withSymbolTable output program)
$ nameAnalysis program
withParsedInput _ (Left errorBundle)
= putStrLn (errorBundlePretty errorBundle)
>> exitWith (ExitFailure 3)
withSymbolTable output program symbolTable
| Just typeError <- typeAnalysis symbolTable program =
printAndExit 5 typeError
| otherwise =
2024-11-24 13:05:11 +01:00
let makeObject = elfObject output . riscv32Elf . generateRiscV
in either (printAndExit 6) makeObject
$ allocate riscVConfiguration
$ glue symbolTable program
2024-10-31 22:19:48 +01:00
printAndExit :: Show b => forall a. Int -> b -> IO a
printAndExit failureCode e = print e >> exitWith (ExitFailure failureCode)