1-- SPDX-FileCopyrightText: 2025-2026 Sören Tempel <soeren+git@soeren-tempel.net>2--3-- SPDX-License-Identifier: GPL-3.0-only45module Util where67import Data.Bifunctor (second)8import Data.Word (Word64)9import Language.QBE (parseAndFind)10import Language.QBE.Backend.Tracer qualified as T11import Language.QBE.Simulator (execFunc)12import Language.QBE.Simulator.Concolic.Expression qualified as CE13import Language.QBE.Simulator.Concolic.State (mkEnv, run)14import Language.QBE.Simulator.Default.Expression qualified as DE15import Language.QBE.Simulator.Explorer (PathResult, defSolver, exploreFunc, newEngine)16import Language.QBE.Simulator.Expression qualified as E17import Language.QBE.Simulator.Symbolic.Expression qualified as SE18import Language.QBE.Types qualified as QBE19import SimpleBV qualified as SMT2021parseAndExec :: QBE.GlobalIdent -> [CE.Concolic DE.RegVal] -> String -> IO T.ExecTrace22parseAndExec funcName params input = do23 (prog, entry) <- parseAndFind funcName input2425 env <- mkEnv prog 0 128 Nothing26 fst <$> run env (execFunc entry params)2728unconstrained :: SMT.Solver -> Word64 -> String -> QBE.BaseType -> IO (CE.Concolic DE.RegVal)29unconstrained solver initCon name ty = do30 let symbolic = SE.symbolic name (QBE.Base ty)31 -- XXX: This is a hack, normally the Store does this for us.32 _ <- SMT.declareBV solver name $ SE.bitSize symbolic3334 let concrete = E.fromLit (QBE.Base ty) initCon35 pure $ CE.Concolic concrete (Just symbolic)3637explore' :: String -> String -> [(String, QBE.BaseType)] -> IO [PathResult]38explore' input funcName params = do39 (prog, entry) <- parseAndFind (QBE.GlobalIdent funcName) input4041 defEnv <- mkEnv prog 0 128 Nothing42 engine <- newEngine defEnv <$> defSolver43 exploreFunc engine entry $44 map (second QBE.Base) params