Commit d862c7ce authored by Tomislav Pree's avatar Tomislav Pree
Browse files

added cfg to debug combinator

parent e6676632
......@@ -65,3 +65,6 @@ instance (Monoid w, ArrowControlFlow stmt c) => ArrowControlFlow stmt (WriterT w
instance ArrowCFG graph c => ArrowCFG graph (ConstT r c)
instance ArrowCFG graph c => ArrowCFG graph (ReaderT r c)
instance ArrowCFG graph c => ArrowCFG graph (StateT r c)
instance (ArrowCFG graph c, Monoid r) => ArrowCFG graph (WriterT r c)
instance (ArrowCFG graph c, Applicative r) => ArrowCFG graph (StaticT r c)
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE Arrows #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Control.Arrow.Fix.FiniteEnvStore where
import Control.Arrow
import Control.Arrow.Fix
import Control.Arrow.Trans
import Control.Arrow.Transformer.Const
import Control.Arrow.Transformer.Reader
import Control.Arrow.Transformer.State
import Control.Arrow.Transformer.Static
import Control.Arrow.Transformer.Writer
......@@ -32,13 +32,15 @@ import Data.Profunctor.Unsafe((.#))
import Data.Coerce
import Data.Order hiding (lub)
import Control.Arrow.State
newtype FixT c x y = FixT (c x y)
deriving (Profunctor,Category,Arrow,ArrowChoice,
ArrowContext ctx, ArrowJoinContext a, ArrowControlFlow a,
ArrowCache a b, ArrowParallelCache a b, ArrowIterateCache a b, ArrowGetCache cache,
ArrowStack a,ArrowStackElements a,ArrowStackDepth,
ArrowComponent a, ArrowInComponent a,
ArrowMetrics a, ArrowStrict, ArrowPrimitive)
ArrowMetrics a, ArrowStrict, ArrowPrimitive, ArrowCFG a)
runFixT :: FixT c x y -> c x y
runFixT (FixT f) = f
......@@ -70,3 +72,10 @@ instance (Complete y, Profunctor c, Arrow c) => ArrowComplete y (FixT c) where
instance (Profunctor c, Arrow c) => ArrowJoin (FixT c) where
joinSecond lub f (FixT g) = FixT (dimap (\x -> (x, x)) (\(x,y) -> (lub (f x) y)) (second g))
instance ArrowState s c => ArrowState s (FixT c) where
get = lift get
put = lift put
{-# INLINE get #-}
{-# INLINE put #-}
......@@ -49,7 +49,7 @@ import GHC.Exts
newtype CacheT cache a b c x y = CacheT { unCacheT :: StateT (cache a b) c x y}
deriving (Profunctor,Category,Arrow,ArrowChoice,ArrowStrict,ArrowTrans,
ArrowState (cache a b),ArrowControlFlow stmt, ArrowPrimitive)
ArrowState (cache a b),ArrowControlFlow stmt, ArrowPrimitive, ArrowCFG graph)
instance (IsEmpty (cache a b), ArrowRun c) => ArrowRun (CacheT cache a b c) where
type Run (CacheT cache a b c) x y = Run c x (cache a b,y)
......
......@@ -29,6 +29,9 @@ import Control.Arrow.Trans
-- import Control.Arrow.Transformer.Writer
import Control.Arrow.Transformer.State
import Control.Arrow.Transformer.Abstract.FiniteEnvStore
import Data.Abstract.MonotoneStore(Store)
import Data.Bits
import Data.Profunctor
import Data.Identifiable
......@@ -41,7 +44,7 @@ newtype ComponentT component a c x y = ComponentT (StateT (component a) c x y)
deriving (Profunctor,Category,Arrow,ArrowChoice,ArrowStrict,
ArrowStackDepth,ArrowStackElements a,
ArrowCache a b, ArrowParallelCache a b,ArrowIterateCache a b,ArrowGetCache cache,
ArrowContext ctx, ArrowJoinContext u, ArrowControlFlow stmt, ArrowPrimitive)
ArrowContext ctx, ArrowJoinContext u, ArrowControlFlow stmt, ArrowPrimitive, ArrowCFG graph)
runComponentT :: (IsEmpty (comp a), Profunctor c) => ComponentT comp a c x y -> c x y
runComponentT (ComponentT f) = dimap (\x -> (empty,x)) snd (runStateT f)
......@@ -63,11 +66,11 @@ instance (Identifiable a, Profunctor c,ArrowApply c) => ArrowApply (ComponentT c
app = ComponentT (lmap (first coerce) app)
{-# INLINE app #-}
instance ArrowState s c => ArrowState s (ComponentT comp a c) where
get = lift' get
put = lift' put
{-# INLINE get #-}
{-# INLINE put #-}
--instance (Arrow c, Profunctor c) => ArrowState (Store addr val) (EnvStoreT var addr val c) where
-- get = EnvStoreT get
-- put = EnvStoreT put
-- {-# INLINE get #-}
-- {-# INLINE put #-}
newtype Component a = Component Integer
......@@ -110,6 +113,8 @@ instance (Arrow c, Profunctor c) => ArrowInComponent a (ComponentT Component a c
{-# INLINE inComponent #-}
{-# SCC inComponent #-}
-- Standard Component ----------------------------------------------------------------------------------
-- newtype Component a = Component (HashSet a) deriving (Eq,IsEmpty,Monoid,Semigroup)
......
......@@ -30,7 +30,7 @@ import Data.Empty
newtype ContextT ctx c x y = ContextT (ReaderT ctx c x y)
deriving (Category,Profunctor,Arrow,ArrowChoice,ArrowStrict,
ArrowLift,ArrowControlFlow stmt, ArrowPrimitive)
ArrowLift,ArrowControlFlow stmt, ArrowPrimitive, ArrowCFG graph)
runContextT :: (IsEmpty ctx, Profunctor c) => ContextT ctx c x y -> c x y
runContextT (ContextT f) = lmap (empty,) (runReaderT f)
......
......@@ -23,6 +23,8 @@ import Control.Arrow.Fix.Metrics
import Control.Arrow.Fix.Stack (ArrowStackDepth,ArrowStackElements)
import Control.Category
import Control.Arrow.State
import Data.Label
import Data.Coerce
import Data.Empty
......@@ -30,12 +32,12 @@ import Data.Profunctor.Unsafe
import Data.Graph.Inductive (Gr)
import qualified Data.Graph.Inductive as G
newtype CFG stmt = CFG (Gr stmt ())
newtype CFG stmt = CFG (Gr stmt ()) deriving (Show)
instance IsEmpty (CFG stmt) where
empty = CFG G.empty
newtype ControlFlowT stmt c x y = ControlFlowT (StateT (CFG stmt) (ReaderT (Maybe stmt) c) x y)
newtype ControlFlowT stmt c x y = ControlFlowT (StateT (CFG stmt) (ReaderT (Maybe stmt) c) x y)
deriving (
Profunctor, Category, Arrow, ArrowChoice, ArrowContext ctx,
ArrowCache a b, ArrowParallelCache a b, ArrowIterateCache a b,
......@@ -44,7 +46,7 @@ newtype ControlFlowT stmt c x y = ControlFlowT (StateT (CFG stmt) (ReaderT (Mayb
ArrowPrimitive
)
instance (HasLabel stmt, Arrow c, Profunctor c) => ArrowControlFlow stmt (ControlFlowT stmt c) where
instance (HasLabel stmt, Arrow c, Profunctor c) => ArrowControlFlow stmt (ControlFlowT stmt c) where
nextStatement f = lift $ proc (predecessor, (cfg, (nextStmt, x))) ->
unlift f -< (nextStmt, (addEdge predecessor nextStmt cfg, x))
where
......@@ -82,3 +84,7 @@ instance ArrowLift (ControlFlowT stmt c) where
instance (Profunctor c,ArrowApply c) => ArrowApply (ControlFlowT stmt c) where
app = ControlFlowT (app .# first coerce)
{-# INLINE app #-}
instance (Arrow c, Profunctor c) => ArrowCFG (CFG stmt) (ControlFlowT stmt c) where
getCFG = ControlFlowT $ proc () -> get -< ()
{-# INLINE getCFG #-}
......@@ -40,11 +40,14 @@ import Data.Coerce
import Text.Printf
import Control.Arrow.Transformer.Abstract.FiniteEnvStore
import Data.Abstract.MonotoneStore(Store)
newtype MetricsT metric a c x y = MetricsT (StateT (metric a) c x y)
deriving (Profunctor,Category,Arrow,ArrowChoice,ArrowLowerBounded z,
ArrowComponent a,ArrowInComponent a,ArrowControlFlow stmt,
ArrowStackDepth,ArrowStackElements a,ArrowContext ctx,ArrowTopLevel,
ArrowGetCache cache, ArrowPrimitive)
ArrowGetCache cache, ArrowPrimitive, ArrowCFG graph)
instance (IsEmpty (metrics a), ArrowRun c) => ArrowRun (MetricsT metrics a c) where
type Run (MetricsT metrics a c) x y = Run c x (metrics a,y)
......@@ -61,11 +64,17 @@ instance (Profunctor c,ArrowApply c) => ArrowApply (MetricsT metrics a c) where
app = MetricsT (app .# first coerce)
{-# INLINE app #-}
instance ArrowState s c => ArrowState s (MetricsT metrics a c) where
get = lift' get
put = lift' put
{-# INLINE get #-}
{-# INLINE put #-}
--instance ArrowState s c => ArrowState s (MetricsT metrics a c) where
-- get = lift' get
-- put = lift' put
-- {-# INLINE get #-}
-- {-# INLINE put #-}
--instance (Arrow c, Profunctor c) => ArrowState (Store addr val) (EnvStoreT var addr val c) where
-- get = EnvStoreT get
-- put = EnvStoreT put
-- {-# INLINE get #-}
-- {-# INLINE put #-}
-- Basic Metric ----------------------------------------------------------------
newtype Metrics a = Metrics (HashMap a Metric)
......
......@@ -43,7 +43,7 @@ newtype StackT stack a c x y = StackT (ReaderT (stack a) c x y)
ArrowStrict,ArrowTrans, ArrowLowerBounded z,
ArrowParallelCache a b, ArrowIterateCache a b, ArrowGetCache cache,
ArrowState s,ArrowContext ctx, ArrowJoinContext u,
ArrowControlFlow stmt, ArrowPrimitive)
ArrowControlFlow stmt, ArrowPrimitive, ArrowCFG graph)
runStackT :: (IsEmpty (stack a), Profunctor c) => StackT stack a c x y -> c x y
runStackT (StackT f) = lmap (\x -> (empty,x)) (runReaderT f)
......
......@@ -76,7 +76,9 @@ import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as M
import Data.Monoidal
import Data.Abstract.MonotoneStore(Store)
import Data.Graph.Inductive.Graph(mkGraph, LNode, LEdge, labNodes, labEdges, Graph)
type ClientId = Int
......@@ -103,7 +105,7 @@ newtype DebugT c x y = DebugT (StateT DebugState c x y)
ArrowCache a b, ArrowParallelCache a b, ArrowIterateCache a b, ArrowGetCache cache,
ArrowStack a,ArrowStackElements a,ArrowStackDepth,
ArrowComponent a, ArrowInComponent a,
ArrowMetrics a, ArrowStrict, ArrowPrimitive)
ArrowMetrics a, ArrowStrict, ArrowPrimitive, ArrowCFG a)
......@@ -146,6 +148,8 @@ instance (Arrow c, Profunctor c, ArrowIO c) => ArrowDebug (DebugT c) where
state <- State.get -< ()
--stack <- Stack.elems -< ()
returnA-< ()
{-# INLINE addBreakpoints #-}
{-# INLINE isBreakpoint #-}
{-# INLINE sendMessage #-}
......
{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
module Parser(loadSchemeFile,loadSchemeFile') where
module Parser(loadSchemeFile,loadSchemeFile',loadSourceCode, loadSchemeFileWithCode) where
import Prelude hiding (fail)
......@@ -25,13 +25,14 @@ import Text.Printf
loadSchemeFile :: String -> IO LExpr
loadSchemeFile file = do
contents <- readFile =<< getDataFileName (printf "scheme_files/%s" file)
print contents
case readExprList contents of
Left err -> throwLispError err
Right val -> do
expanded <- macroExpand (List val)
-- print expanded
print expanded
let expr = parseTopLevelSExpr expanded
-- print (generate expr)
print (generate expr)
return expr
loadSchemeFile' :: String -> IO Expr
......@@ -39,6 +40,23 @@ loadSchemeFile' file = do
lexpr <- loadSchemeFile file
return $ generate lexpr
loadSourceCode :: String -> IO FilePath
loadSourceCode file = readFile =<< getDataFileName (printf "scheme_files/%s" file)
loadSchemeFileWithCode :: String -> IO LExpr
loadSchemeFileWithCode code = do
print code
case readExprList code of
Left err -> throwLispError err
Right val -> do
expanded <- macroExpand (List val)
print expanded
let expr = parseTopLevelSExpr expanded
print "GLEICH KOMMT GENERATE EXPR"
print (generate expr)
return expr
macroExpand :: LispVal -> IO LispVal
macroExpand program = do
env <- r7rsEnv
......
......@@ -146,7 +146,7 @@ instance FromJSON Expr
instance Eq Expr where
e1 == e2 = label e1 == label e2
type LExpr = State Label Expr
type LExpr = State Label Expr
-- Smart constructors that build labeled Scheme expressions.
-- | Expressions for inner representation and evaluation
......
......@@ -34,7 +34,7 @@ import qualified Control.Arrow.Fix as Fix
import Control.Arrow.Fix.Chaotic(IterationStrategy,chaotic,innermost',outermost')
import qualified Control.Arrow.Fix.Context as Ctx
--import Control.Arrow.Fix.Stack as Stack
import Control.Arrow.Fix.Stack (ArrowStack,ArrowStackDepth,ArrowStackElements,widenInput,maxDepth,reuseByMetric)
import Control.Arrow.Fix.Stack (ArrowStack,ArrowStackDepth,ArrowStackElements,widenInput,maxDepth,reuseByMetric, StackPointer)
import qualified Control.Arrow.Fix.Stack as Stack
import Control.Arrow.IO
import qualified Control.Arrow.Trans as Trans
......@@ -62,6 +62,7 @@ import TypedAnalysis
import Syntax (LExpr,Expr(App),Literal)
import GenericInterpreter as Generic
--import Control.Arrow.Transformer.Debug(DebugT)
......@@ -94,10 +95,21 @@ import Parser
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString as B
import Control.Arrow.Transformer.Debug(DebugState(..), DebugT, ArrowDebug, sendMessage)
import Control.Arrow.Transformer.Debug(DebugState(..), DebugT, ArrowDebug, sendMessage, isBreakpoint, receiveMessage)
import Control.Arrow.Transformer.State
import Control.Arrow.Fix.ControlFlow
import Text.Printf
import Data.HashMap.Strict (HashMap)
import Data.Graph.Inductive(Gr)
import Data.Graph.Inductive.Graph(mkGraph, LNode, LEdge, labNodes, labEdges, Graph)
import Control.Arrow.State as State
import Control.Arrow.Fix.FiniteEnvStore
type InterpT c x y =
(ValueT Val
......@@ -114,40 +126,7 @@ type InterpT c x y =
(ControlFlowT Expr
c)))))))))))) x y
{--
evalChaotic :: (?sensitivity :: Int) => IterationStrategy _ In Out -> [(Text,Addr)] -> [LExpr] -> (CFG Expr, (Metric.Monotone In, Out'))
evalChaotic iterationStrat env0 e =
let ?cacheWidening = (storeErrWidening, W.finite) in
let ?fixpointAlgorithm = transform $
Fix.fixpointAlgorithm $
-- Fix.trace printIn printOut .
Ctx.recordCallsite ?sensitivity (\(_,(_,exprs)) -> case exprs of App _ _ l:_ -> Just l; _ -> Nothing) .
Fix.recordEvaluated .
-- CFlow.recordControlFlowGraph' (\(_,(_,exprs)) -> case exprs of e':_ -> Just e'; _ -> Nothing) .
-- Fix.filter' isFunctionBody (Fix.trace printIn printOut . chaotic iterationStrat)
Fix.filter' isFunctionBody (chaotic iterationStrat) in
second snd $ Trans.run (extend' (Generic.runFixed :: InterpT (->) [Expr] Val)) (empty,(empty,(env0,e0)))
where
e0 = generate (sequence e)
{-# INLINE evalChaotic #-}
-}
{--
evalInner :: Eval
evalInner = evalChaotic innermost'
evalOuter :: Eval
evalOuter = evalChaotic outermost'
evalInner' :: Eval'
evalInner' exprs = let (metrics,(cfg,res)) = evalInner [] exprs in (metrics,(cfg,snd res))
evalOuter':: Eval'
evalOuter' exprs = let (metrics,(cfg,res)) = evalOuter [] exprs in (metrics,(cfg,snd res))
eval' :: (?sensitivity :: Int) => [(Text,Addr)] -> [LExpr] -> (Errors,Terminating Val)
eval' env exprs = snd $ snd $ snd $ evalInner env exprs
-}
--------------------------------------------------
......@@ -158,36 +137,41 @@ type ClientId = Int
type Client = (ClientId, WS.Connection)
type State = [Client]
type Socket = () -- Placeholder
type Breakpoints = [Expr] -- Placeholder
type StackElems = [In] -- Placeholder
data Message
= ReachedBreakpoint {breakpoint :: Expr, env :: Env}
| Continue
| GetStackRequest
| GetStackResponse StackElems
--------------------- Websocket Messages ----------------------------
data TestMessage
= InitializeDebuggerRequest {path :: String}
| InitializeDebuggerResponse {code :: [Expr]}
| ContinueRequest {bps :: [Int], start :: Bool}
| ContinueResponse {debugInfo :: Text}
data WebsocketMessage
= LoadSourceCodeRequest {path :: String}
| LoadSourceCodeResponse {code :: FilePath}
| StartDebuggerRequest {code :: String}
| StartDebuggerResponse {}
| ContinueRequest {} --bps :: [Int], start :: Bool
| BreakpointResponse {stackElems :: String, exprs :: String, cfg :: String}
| RefreshRequest
| RefreshResponse {success :: Bool}
deriving (Show, Eq, Generic)
deriving (Show, Generic)
instance ToJSON TestMessage
instance FromJSON TestMessage
instance ToJSON WebsocketMessage
instance FromJSON WebsocketMessage
instance ToJSON Addr
instance ToJSONKey Addr
instance FromJSON Addr
instance FromJSONKey Addr
instance ToJSON Val
instance FromJSON Val
instance FromJSONKey Expr
instance ToJSONKey Expr
instance ToJSON List
instance FromJSON List
instance ToJSON Number
instance FromJSON Number
......@@ -234,9 +218,6 @@ connectClient conn stateRef = Concurrent.modifyMVar stateRef $ \state -> do
return ((clientId, conn) : state, clientId)
extractClient :: ClientId -> State -> State
extractClient clientId = List.filter ((==) clientId . fst)
withoutClient :: ClientId -> State -> State
withoutClient clientId = List.filter ((/=) clientId . fst)
......@@ -248,25 +229,38 @@ listen :: DebugState -> P.IO ()
listen debugState = do
print (clientId debugState)
msg <- WS.receiveData (conn debugState)
let dec = Maybe.fromJust (decode'' msg) :: TestMessage
let dec = Maybe.fromJust (decode'' msg) :: WebsocketMessage
print "JETZT KOMMT PRINT DEC "
print (dec)
case dec of
InitializeDebuggerRequest { path = p } -> do
LoadSourceCodeRequest { path = p } -> do
contents <- Parser.loadSourceCode p
print "JETZT CONTENTS"
print contents
print "CONTENTS VORBEI"
expressions <- Parser.loadSchemeFile (path dec)
ulEx <- Parser.loadSchemeFile' (path dec)
print ulEx
--let object = InitializeDebuggerResponse ([generate expressions])
let object = InitializeDebuggerResponse ([ulEx])
--let object = LoadSourceCodeResponse ([generate expressions])
let object = LoadSourceCodeResponse (contents)
print object
let encodedObject = encode object
let textObject = Data.Text.Encoding.decodeUtf8 (toStrict1 encodedObject)
let changedDebugState = changeExpressions debugState [expressions]
sendResponse changedDebugState textObject
--let changedDebugState = changeExpressions debugState [expressions]
sendResponse debugState textObject
ContinueRequest {bps = b, start = s} -> do --hier b und s benutzen
sendResponse debugState "bla"
StartDebuggerRequest {code = code } -> do
let ?sensitivity = 0
let ?debugState = debugState
expressions <- Parser.loadSchemeFileWithCode code
evalDebug ([expressions])
ContinueRequest {} -> do --hier b und s benutzen
--sendResponse debugState "bla"
--eval debug aufrufen
let ?sensitivity = 0
let ?debugState = debugState
......@@ -275,6 +269,7 @@ listen debugState = do
expressions <- Parser.loadSchemeFile ("test_factorial.scm")
evalDebug ([expressions])
print "continueRequest"
RefreshRequest -> do
let object = RefreshResponse True
......@@ -297,9 +292,6 @@ listen debugState = do
sendResponse :: DebugState -> Text.Text -> P.IO ()
sendResponse debugState msg = do
print msg
putStrLn "hier in sendResponse"
WS.sendTextData (conn debugState) msg
......@@ -311,6 +303,7 @@ evalDebug expr =
Fix.fixpointAlgorithm $
debug .
Ctx.recordCallsite ?sensitivity (\(_,(_,exprs)) -> case exprs of App _ _ l:_ -> Just l; _ -> Nothing) .
recordControlFlowGraph' (\(_,(_,exprs)) -> case exprs of e':_ -> Just e'; _ -> Nothing) .
Fix.filter' isFunctionBody (chaotic innermost') in
do _ <- Trans.run (Generic.runFixed :: InterpT IO [Expr] Val) (?debugState, (empty, (empty, e0)))
return ()
......@@ -321,46 +314,45 @@ evalDebug expr =
-- | Debugging combinator
debug :: (?debugState :: DebugState,
ArrowChoice c, ArrowIO c, ArrowDebug c, ArrowStack In c, ArrowStackDepth c, ArrowStackElements In c, ArrowControlFlow stmt c)
ArrowChoice c, ArrowIO c, ArrowDebug c, ArrowStack In c, ArrowStackDepth c, ArrowStackElements In c, ArrowCFG graph c, Show graph) --
=> Fix.FixpointCombinator c ((Store,Errors),(Env,[Expr]))
((Store,Errors), Terminating Val)
debug f = proc input@((store,errors),(env,exprs)) -> do
sendMessage -< (Text.pack "DEBUG COMBINATOR")
stackDepth <- Stack.depth -< ()
stackElems <- Stack.elems -< ()
--liftIO print -< "stackDepth"
--liftIO print -< stackDepth
liftIO print -< "stackElems"
liftIO print -< stackElems
liftIO print -< "exprs"
liftIO print -< exprs
case exprs of
e:es | isBreakpoint' e -> do
liftIO print -< e
liftIO print -< es
loop -< ((store,errors),(env,es))
_ -> f -< (input)
--case exprs of
-- expr:_ | isBreakpoint expr -> do
-- -- Breakpoint reached
-- stack <- Stack.elems -< ()
--
-- sendMessage -< ContinueResponse stack input --cfg
-- loop -< input
-- f -< input
-- _ ->
-- f -< input
--where
-- loop = proc input@((store,errors),(env,expr)) -> do
-- msg <- receiveMessage -< ()
-- dec <- Maybe.fromJust (decode'' msg) :: TestMessage
-- liftIO print -< (dec)
-- case dec of
-- ContinueRequest ->
-- returnA -< ()
-- _ -> do
-- loop -< input
f -< (input)
where
loop = proc input@((store,errors),(env,exprs)) -> do
cfg <- getCFG -< ()
liftIO print -< (labNodes cfg)
stackElems <- Stack.elems -< ()
liftIO print -< stackElems
let breakpointResponse = createBreakpointResponse (stackElems) (show input) (show cfg)
sendMessage -< (breakpointResponse)
msg <- receiveMessage -< () --Hilfsfunktion
let dec = Maybe.fromJust (decode'' msg) :: WebsocketMessage
case dec of
ContinueRequest {} -> do
f -< input
_ -> do
loop -< input
{-# INLINE debug #-}
-- newtype CFG stmt = CFG (Gr stmt ()) was für typen? brauche ich das? wenn ja wohin ? | c -> stmt
--------------------- Helper Functions ----------------------------
......@@ -374,6 +366,97 @@ toStrict1 = B.concat . BL.toChunks
isBreakpoint' :: Expr -> Bool