qute

A software analysis framework built around the QBE intermediate language

git clone https://git.8pit.net/qute.git

 1-- SPDX-FileCopyrightText: 2025 Sören Tempel <soeren+git@soeren-tempel.net>
 2--
 3-- SPDX-License-Identifier: GPL-3.0-only
 4
 5module Main (main) where
 6
 7import Data.Word (Word64, Word8)
 8import Language.QBE.CmdLine qualified as CMD
 9import Language.QBE.Simulator (execFunc)
10import Language.QBE.Simulator.Default.Expression qualified as DE
11import Language.QBE.Simulator.Default.State (Env, mkEnv, run)
12import Language.QBE.Simulator.Expression qualified as E
13import Language.QBE.Types qualified as QBE
14import Options.Applicative qualified as OPT
15import System.Exit (ExitCode (ExitFailure, ExitSuccess), exitWith)
16
17fromWord :: DE.RegVal -> Maybe Word64
18fromWord v
19  | E.getType v == QBE.Base QBE.Word = Just $ E.toWord64 v
20  | otherwise = Nothing
21
22execFile :: CMD.BasicArgs -> IO Int
23execFile opts = do
24  (prog, func) <- CMD.parseEntryFile $ CMD.optQBEFile opts
25
26  env <- mkEnv prog (CMD.optMemStart opts) (CMD.optMemSize opts)
27  res <- run (env :: Env DE.RegVal Word8) (execFunc func [])
28  case res >>= fromWord of
29    Just x -> pure $ fromIntegral x
30    Nothing ->
31      -- The main function emitted by the Hare compiler does not
32      -- return an int. Therefore, we do not emit an error here.
33      pure 0
34
35main :: IO ()
36main = do
37  retVal <- OPT.execParser cmd >>= execFile
38  exitWith $
39    if retVal == 0
40      then ExitSuccess
41      else ExitFailure retVal
42  where
43    cmd :: OPT.ParserInfo CMD.BasicArgs
44    cmd =
45      OPT.info
46        (CMD.basicArgs OPT.<**> OPT.helper)
47        ( OPT.fullDesc
48            <> OPT.progDesc "Concrete execution of programs in the QBE intermediate language"
49        )