1-- SPDX-FileCopyrightText: 2024 University of Bremen2-- SPDX-FileCopyrightText: 2025 Sören Tempel <soeren+git@soeren-tempel.net>3--4-- SPDX-License-Identifier: MIT AND GPL-3.0-only56module Language.QBE.CmdLine7 ( BasicArgs (..),8 basicArgs,9 loadProg,10 )11where1213import Data.Archive (qbeArchive)14import Language.QBE (Program, parseAndFind)15import Language.QBE.Linker (link)16import Language.QBE.Simulator.Memory qualified as MEM17import Language.QBE.Types qualified as QBE18import Options.Applicative qualified as OPT1920-- | t'BasicArgs' can be combined/extended with additional parsers using21-- the '<*>' applicative operator provided by "Options.Applicative".22data BasicArgs = BasicArgs23 { -- | Start address of the general-purpose memory.24 optMemStart :: MEM.Address,25 -- | Size of the memory in bytes.26 optMemSize :: MEM.Size,27 -- | Do not zero-initialize the memory.28 optMemUndef :: Bool,29 -- | Path to an .ar archive to preload.30 optQBEArchive :: Maybe FilePath,31 -- | Path to the QBE input file.32 optQBEFile :: FilePath33 }3435-- | "Options.Applicative" parser for t'BasicArgs'.36basicArgs :: OPT.Parser BasicArgs37basicArgs =38 BasicArgs39 <$> OPT.option40 OPT.auto41 ( OPT.long "memory-start"42 <> OPT.short 'm'43 <> OPT.value 0x1000044 )45 <*> OPT.option46 OPT.auto47 ( OPT.long "memory-size"48 <> OPT.short 's'49 <> OPT.value (1024 * 1024) -- 1 MB RAM50 <> OPT.help "Size of the memory region"51 )52 <*> OPT.switch53 ( OPT.long "memory-uninitialized"54 <> OPT.help "Do not zero-initialize the memory"55 )56 <*> OPT.optional57 ( OPT.strOption58 ( OPT.long "preload"59 <> OPT.short 'p'60 <> OPT.metavar "FILE"61 <> OPT.help "Preload the given .ar archive consisting of QBE files"62 )63 )64 <*> OPT.argument OPT.str (OPT.metavar "FILE")6566------------------------------------------------------------------------6768-- | Name of the entry function.69entryFunc :: QBE.GlobalIdent70entryFunc = QBE.GlobalIdent "main"7172-- | Parse a file and find the 'entryFunc'.73parseEntryFile :: FilePath -> IO (Program, QBE.FuncDef)74parseEntryFile filePath =75 readFile filePath >>= parseAndFind entryFunc7677-- | Load the program specified in 'BasicArgs'. Returns the78-- loaded 'Program' and the entry function.79loadProg :: BasicArgs -> IO (Program, QBE.FuncDef)80loadProg opts = do81 (prog, func) <- parseEntryFile $ optQBEFile opts82 linked <-83 case optQBEArchive opts of84 Nothing -> pure prog85 Just ar -> (\xs -> link $ prog : xs) <$> qbeArchive ar86 pure (linked, func)