diff --git a/src/Concretize.hs b/src/Concretize.hs index 5e877dfb..1fa8b406 100644 --- a/src/Concretize.hs +++ b/src/Concretize.hs @@ -813,6 +813,10 @@ findFunctionForMemberIncludePrimitives typeEnv env functionName functionType (me setDeletersOnInfo :: Maybe Info -> Set.Set Deleter -> Maybe Info setDeletersOnInfo i deleters = fmap (\i' -> i' {infoDelete = deleters}) i +addDeletersToInfo :: Maybe Info -> Set.Set Deleter -> Maybe Info +addDeletersToInfo i deleters = + fmap (\i' -> i' {infoDelete = Set.union (infoDelete i') deleters}) i + -- | Helper function for setting the deleters for an XObj. del :: XObj -> Set.Set Deleter -> XObj del xobj deleters = xobj {xobjInfo = setDeletersOnInfo (xobjInfo xobj) deleters} @@ -989,8 +993,9 @@ manageMemory typeEnv globalEnv root = manage xobj pure $ do okBody <- visitedBody + let finalBody = searchForInnerBreak diff okBody okBindings <- fmap (concatMap (\(n, x) -> [n, x])) (sequence visitedBindings) - pure (XObj (Lst [letExpr, XObj (Arr okBindings) bindi bindt, okBody]) newInfo t) + pure (XObj (Lst [letExpr, XObj (Arr okBindings) bindi bindt, finalBody]) newInfo t) -- Set! [setbangExpr@(XObj SetBang _ _), variable, value] -> let varInfo = xobjInfo variable @@ -1108,7 +1113,8 @@ manageMemory typeEnv globalEnv root = XObj objExpr objInfo objTy = okExpr newExprInfo = setDeletersOnInfo objInfo (afterExprDeleters \\ preDeleters) newExpr = XObj objExpr newExprInfo objTy - pure (XObj (Lst [whileExpr, newExpr, okBody]) newInfo t) + finalBody = searchForInnerBreak diff okBody + pure (XObj (Lst [whileExpr, newExpr, finalBody]) newInfo t) [ifExpr@(XObj If _ _), expr, ifTrue, ifFalse] -> do visitedExpr <- visit expr @@ -1262,6 +1268,15 @@ manageMemory typeEnv globalEnv root = Right (XObj (Lst (okF : okArgs)) i t) [] -> pure (Right xobj) visitList _ = error "Must visit list." + searchForInnerBreak :: Set.Set Deleter -> XObj -> XObj + searchForInnerBreak diff (XObj (Lst [(XObj Break i' t')]) xi xt) = + let ni = addDeletersToInfo i' diff + in XObj (Lst [(XObj Break ni t')]) xi xt + searchForInnerBreak _ x@(XObj (Lst ((XObj While _ _) : _)) _ _) = x + searchForInnerBreak diff (XObj (Lst elems) i' t') = + let newElems = map (searchForInnerBreak diff) elems + in XObj (Lst newElems) i' t' + searchForInnerBreak _ e = e visitMatchCase :: (XObj, XObj) -> State MemState (Either TypeError ((Set.Set Deleter, (XObj, XObj)), [XObj])) visitMatchCase (lhs@XObj {}, rhs@XObj {}) = do diff --git a/src/Emit.hs b/src/Emit.hs index 24b48e6d..15390784 100644 --- a/src/Emit.hs +++ b/src/Emit.hs @@ -602,8 +602,12 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo XObj (Interface _ _) _ _ : _ -> pure "" -- Break - [XObj Break _ _] -> do + [XObj Break minfo _] -> do + case minfo of + Just i -> delete indent i + Nothing -> return () appendToSrc (addIndent indent ++ "break;\n") + appendToSrc (addIndent indent ++ "// Unreachable:\n") pure "" -- Function application (functions with overridden names) func@(XObj (Sym _ (LookupGlobalOverride overriddenName)) _ _) : args ->