1-- SPDX-FileCopyrightText: 2025 Sören Tempel <soeren+git@soeren-tempel.net>2--3-- SPDX-License-Identifier: GPL-3.0-only45module Util where67import Data.Bifunctor (second)8import Data.List (find)9import Data.Word (Word64)10import Language.QBE (Program, globalFuncs, parse)11import Language.QBE.Backend.Store qualified as ST12import Language.QBE.Backend.Tracer qualified as ST13import Language.QBE.Backend.Tracer qualified as T14import Language.QBE.Simulator (execFunc)15import Language.QBE.Simulator.Concolic.Expression qualified as CE16import Language.QBE.Simulator.Concolic.State (mkEnv, run)17import Language.QBE.Simulator.Default.Expression qualified as DE18import Language.QBE.Simulator.Explorer (defSolver, explore, newEngine)19import Language.QBE.Simulator.Expression qualified as E20import Language.QBE.Simulator.Symbolic.Expression qualified as SE21import Language.QBE.Types qualified as QBE22import SimpleBV qualified as SMT2324parseProg :: String -> IO Program25parseProg input =26 case parse "" input of27 Left e -> fail $ "Unexpected parsing error: " ++ show e28 Right r -> pure r2930findFunc :: Program -> QBE.GlobalIdent -> QBE.FuncDef31findFunc prog funcName =32 case find (\f -> QBE.fName f == funcName) (globalFuncs prog) of33 Just x -> x34 Nothing -> error $ "Unknown function: " ++ show funcName3536-- TODO: Code duplication with quebex/test/Simulator.hs37parseAndExec :: QBE.GlobalIdent -> [CE.Concolic DE.RegVal] -> String -> IO ST.ExecTrace38parseAndExec funcName params input = do39 prog <- parseProg input40 let func = findFunc prog funcName41 env <- mkEnv prog 0 128 Nothing42 fst <$> run env (execFunc func params)4344unconstrained :: SMT.Solver -> Word64 -> String -> QBE.BaseType -> IO (CE.Concolic DE.RegVal)45unconstrained solver initCon name ty = do46 symbolic <- SMT.declareBV solver name $ QBE.baseTypeBitSize ty47 let concrete = E.fromLit (QBE.Base ty) initCon48 pure $ CE.Concolic concrete (Just $ SE.fromSExpr symbolic)4950explore' :: Program -> QBE.FuncDef -> [(String, QBE.BaseType)] -> IO [(ST.Assign, T.ExecTrace)]51explore' prog entry params = do52 engine <- newEngine <$> defSolver53 defEnv <- mkEnv prog 0 128 Nothing54 explore engine defEnv entry $55 map (second QBE.Base) params