module Language.QBE.Backend.ExecTree
( BTree (..),
ExecTree,
mkTree,
addTrace,
)
where
import Language.QBE.Backend.Tracer (Branch, ExecTrace, fromBranch)
data BTree a = Node a (Maybe (BTree a)) (Maybe (BTree a)) | Leaf
deriving (Int -> BTree a -> ShowS
[BTree a] -> ShowS
BTree a -> String
(Int -> BTree a -> ShowS)
-> (BTree a -> String) -> ([BTree a] -> ShowS) -> Show (BTree a)
forall a. Show a => Int -> BTree a -> ShowS
forall a. Show a => [BTree a] -> ShowS
forall a. Show a => BTree a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> BTree a -> ShowS
showsPrec :: Int -> BTree a -> ShowS
$cshow :: forall a. Show a => BTree a -> String
show :: BTree a -> String
$cshowList :: forall a. Show a => [BTree a] -> ShowS
showList :: [BTree a] -> ShowS
Show, BTree a -> BTree a -> Bool
(BTree a -> BTree a -> Bool)
-> (BTree a -> BTree a -> Bool) -> Eq (BTree a)
forall a. Eq a => BTree a -> BTree a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => BTree a -> BTree a -> Bool
== :: BTree a -> BTree a -> Bool
$c/= :: forall a. Eq a => BTree a -> BTree a -> Bool
/= :: BTree a -> BTree a -> Bool
Eq)
type ExecTree = BTree Branch
canCont :: Maybe (BTree a) -> Bool
canCont :: forall a. Maybe (BTree a) -> Bool
canCont Maybe (BTree a)
Nothing = Bool
True
canCont (Just BTree a
Leaf) = Bool
True
canCont Maybe (BTree a)
_ = Bool
False
mkTree :: ExecTrace -> ExecTree
mkTree :: ExecTrace -> ExecTree
mkTree [] = ExecTree
forall a. BTree a
Leaf
mkTree [(Bool
wasTrue, Branch
br)]
| Bool
wasTrue = Branch -> Maybe ExecTree -> Maybe ExecTree -> ExecTree
forall a. a -> Maybe (BTree a) -> Maybe (BTree a) -> BTree a
Node Branch
br (ExecTree -> Maybe ExecTree
forall a. a -> Maybe a
Just ExecTree
forall a. BTree a
Leaf) Maybe ExecTree
forall a. Maybe a
Nothing
| Bool
otherwise = Branch -> Maybe ExecTree -> Maybe ExecTree -> ExecTree
forall a. a -> Maybe (BTree a) -> Maybe (BTree a) -> BTree a
Node Branch
br Maybe ExecTree
forall a. Maybe a
Nothing (ExecTree -> Maybe ExecTree
forall a. a -> Maybe a
Just ExecTree
forall a. BTree a
Leaf)
mkTree ((Bool
True, Branch
br) : ExecTrace
xs) = Branch -> Maybe ExecTree -> Maybe ExecTree -> ExecTree
forall a. a -> Maybe (BTree a) -> Maybe (BTree a) -> BTree a
Node Branch
br (ExecTree -> Maybe ExecTree
forall a. a -> Maybe a
Just (ExecTree -> Maybe ExecTree) -> ExecTree -> Maybe ExecTree
forall a b. (a -> b) -> a -> b
$ ExecTrace -> ExecTree
mkTree ExecTrace
xs) Maybe ExecTree
forall a. Maybe a
Nothing
mkTree ((Bool
False, Branch
br) : ExecTrace
xs) = Branch -> Maybe ExecTree -> Maybe ExecTree -> ExecTree
forall a. a -> Maybe (BTree a) -> Maybe (BTree a) -> BTree a
Node Branch
br Maybe ExecTree
forall a. Maybe a
Nothing (ExecTree -> Maybe ExecTree
forall a. a -> Maybe a
Just (ExecTree -> Maybe ExecTree) -> ExecTree -> Maybe ExecTree
forall a b. (a -> b) -> a -> b
$ ExecTrace -> ExecTree
mkTree ExecTrace
xs)
addTrace :: ExecTree -> ExecTrace -> ExecTree
addTrace :: ExecTree -> ExecTrace -> ExecTree
addTrace ExecTree
tree [] = ExecTree
tree
addTrace (Node Branch
br' (Just ExecTree
tb) Maybe ExecTree
fb) ((Bool
True, Branch
br) : ExecTrace
xs) =
Branch -> Maybe ExecTree -> Maybe ExecTree -> ExecTree
forall a. a -> Maybe (BTree a) -> Maybe (BTree a) -> BTree a
Node (Branch -> Branch -> Branch
fromBranch Branch
br' Branch
br) (ExecTree -> Maybe ExecTree
forall a. a -> Maybe a
Just (ExecTree -> Maybe ExecTree) -> ExecTree -> Maybe ExecTree
forall a b. (a -> b) -> a -> b
$ ExecTree -> ExecTrace -> ExecTree
addTrace ExecTree
tb ExecTrace
xs) Maybe ExecTree
fb
addTrace (Node Branch
br' Maybe ExecTree
tb (Just ExecTree
fb)) ((Bool
False, Branch
br) : ExecTrace
xs) =
Branch -> Maybe ExecTree -> Maybe ExecTree -> ExecTree
forall a. a -> Maybe (BTree a) -> Maybe (BTree a) -> BTree a
Node (Branch -> Branch -> Branch
fromBranch Branch
br' Branch
br) Maybe ExecTree
tb (ExecTree -> Maybe ExecTree
forall a. a -> Maybe a
Just (ExecTree -> Maybe ExecTree) -> ExecTree -> Maybe ExecTree
forall a b. (a -> b) -> a -> b
$ ExecTree -> ExecTrace -> ExecTree
addTrace ExecTree
fb ExecTrace
xs)
addTrace (Node Branch
br' Maybe ExecTree
tb Maybe ExecTree
fb) ((Bool
wasTrue, Branch
br) : ExecTrace
xs)
| Maybe ExecTree -> Bool
forall a. Maybe (BTree a) -> Bool
canCont Maybe ExecTree
tb Bool -> Bool -> Bool
&& Bool
wasTrue = Branch -> Maybe ExecTree -> Maybe ExecTree -> ExecTree
forall a. a -> Maybe (BTree a) -> Maybe (BTree a) -> BTree a
Node (Branch -> Branch -> Branch
fromBranch Branch
br' Branch
br) (ExecTree -> Maybe ExecTree
forall a. a -> Maybe a
Just (ExecTree -> Maybe ExecTree) -> ExecTree -> Maybe ExecTree
forall a b. (a -> b) -> a -> b
$ ExecTrace -> ExecTree
mkTree ExecTrace
xs) Maybe ExecTree
fb
| Maybe ExecTree -> Bool
forall a. Maybe (BTree a) -> Bool
canCont Maybe ExecTree
fb Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
wasTrue = Branch -> Maybe ExecTree -> Maybe ExecTree -> ExecTree
forall a. a -> Maybe (BTree a) -> Maybe (BTree a) -> BTree a
Node (Branch -> Branch -> Branch
fromBranch Branch
br' Branch
br) Maybe ExecTree
tb (ExecTree -> Maybe ExecTree
forall a. a -> Maybe a
Just (ExecTree -> Maybe ExecTree) -> ExecTree -> Maybe ExecTree
forall a b. (a -> b) -> a -> b
$ ExecTrace -> ExecTree
mkTree ExecTrace
xs)
| Bool
otherwise = String -> ExecTree
forall a. HasCallStack => String -> a
error String
"unreachable"
addTrace ExecTree
Leaf ExecTrace
trace = ExecTrace -> ExecTree
mkTree ExecTrace
trace