comment msg k = k
{ unGen = \ctx -> {-trace "unGen.comment" $-}
[||
- let _ = $$(liftTypedString $ "comment: "<>msg) in
+ let _ = $$(TH.liftTypedString $ "comment: "<>msg) in
$$(unGen k ctx)
||]
}
lift2Value f k = k
{ unGen = \ctx -> {-trace "unGen.lift2Value" $-}
[||
- let _ = $$(liftTypedString ("lift2Value checkedHorizon="<>show (checkedHorizon ctx))) in
+ let _ = $$(TH.liftTypedString ("lift2Value checkedHorizon="<>show (checkedHorizon ctx))) in
$$(unGen k ctx
{ valueStack =
let ValueStackCons y (ValueStackCons x vs) = valueStack ctx in
go x ((p,b):bs') = [||
if $$(genCode (p Prod..@ x))
then
- let _ = $$(liftTypedString ("choicesBranch checkedHorizon="<>show (checkedHorizon ctx))) in
+ let _ = $$(TH.liftTypedString ("choicesBranch checkedHorizon="<>show (checkedHorizon ctx))) in
$$({-trace "unGen.choicesBranch.b" $-} unGen b ctx)
else
let _ = "choicesBranch.else" in
$$(raiseException ctx (ExceptionLabel exn))
(ExceptionLabel $$(TH.liftTyped exn))
{-failInp-}$$(input ctx)
- {-farInp-}$$(input ctx)
- $$(farthestExpecting ctx)
+ {-farFail-}(Just $$(input ctx))
+ {-farExp-}[]
$$(inputBuffer ctx)
$$(inputEnded ctx)
||]
}
- fail fs = Gen
+ fail failMode = Gen
{ genAnalysisByLet = HM.empty
, genAnalysis = \_final -> GenAnalysis
{ minReads = 0
, freeRegs = Set.empty
}
, unGen = \ctx@GenCtx{} -> {-trace ("unGen.fail: "<>show exn) $-}
- if null fs
- then [|| -- Raise without updating the farthest error.
- $$(raiseException ctx ExceptionFailure)
- ExceptionFailure
- {-failInp-}$$(input ctx)
- $$(farthestInput ctx)
- $$(farthestExpecting ctx)
- $$(inputBuffer ctx)
- $$(inputEnded ctx)
- ||]
- else raiseFailure ctx [||fs||]
+ case failMode of
+ FailModePreserve -> [|| -- Raise without updating the farthest error.
+ $$(raiseException ctx ExceptionFailure)
+ ExceptionFailure
+ {-failInp-}$$(input ctx)
+ $$(farthestFailure ctx)
+ $$(farthestExpecting ctx)
+ $$(inputBuffer ctx)
+ $$(inputEnded ctx)
+ ||]
+ FailModeNewFailure someFail -> raiseFailure ctx {-someFail-}someFail
}
commit exn k = k
{ unGen = \ctx -> {-trace ("unGen.commit: "<>show exn) $-}
[||
- let _ = "commit" in
+ let _ = $$(TH.liftTypedString ("commit "<>show exn)) in
$$(unGen k ctx{onExceptionStackByLabel =
Map.update (\case
_r0:|(r1:rs) -> Just (r1:|rs)
{ unGen = \ctx ->
{-trace "unGen.saveInput" $-}
[||
- let _ = $$(liftTypedString $ "saveInput checkedHorizon="<>show (checkedHorizon ctx)) in
+ let _ = $$(TH.liftTypedString $ "saveInput checkedHorizon="<>show (checkedHorizon ctx)) in
$$(unGen k ctx
{ valueStack = inputSave (input ctx) (checkedHorizon ctx) `ValueStackCons` valueStack ctx
})
-- This case should never happen if 'saveInput' is used.
i -> (genCode i, 0) in
[||
- let _ = $$(liftTypedString $ "loadInput checkedHorizon="<>show checkedHorizon) in
+ let _ = $$(TH.liftTypedString $ "loadInput checkedHorizon="<>show checkedHorizon) in
$$(unGen (checkHorizon k) ctx
{ valueStack = vs
, input
if isRec
then GenAnalysis
{ minReads = 0
- , mayRaise = Map.empty
+ -- Assume 'checkToken' is used, otherwise it would loop
+ , mayRaise = Map.singleton ExceptionFailure ()
, alwaysRaise = Set.empty
, freeRegs = Set.empty
}
else seqGenAnalysis $ (final HM.! subName) :| [ genAnalysis k final ]
, unGen = {-trace ("unGen.call: "<>show subName) $-} \ctx ->
- -- let ks = (Map.keys (onExceptionStackByLabel ctx)) in
+ let ks = Map.keys (onExceptionStackByLabel ctx) in
let subAnalysis = analysisByLet ctx HM.! subName in
[||
- -- let _ = $$(liftTypedString $ "call exceptByLet("<>show subName<>")="<>show (Map.keys (Map.findWithDefault Map.empty subName (exceptByLet ctx))) <> " onExceptionStackByLabel(ctx)="<> show ks) in
+ let _ = $$(TH.liftTypedString $ "call mayRaise("<>show subName<>")="<>show (Map.keys (mayRaise subAnalysis)) <> " onExceptionStackByLabel="<> show ks) in
$$(TH.unsafeCodeCoerce $
giveFreeRegs (freeRegs subAnalysis) $
return (TH.VarE subName))
+ -- TODO: more readable in a let binding
{-ok-}$$(onReturnCode k ctx)
$$(input ctx)
$$(inputBuffer ctx)
onExceptionStackByLabel ctx
-- Pass only the labels raised by the 'defLet'.
`Map.intersection`
- (mayRaise subAnalysis)
+ (mayRaise subAnalysis)
)
||]
}
go [] = k
go (r:rs) = [| $(go rs) $(return (TH.VarE r)) |]
--- | Like 'TH.liftString' but on 'TH.Code'.
--- Useful to get a 'TH.StringL' instead of a 'TH.ListE'.
-liftTypedString :: String -> TH.Code TH.Q a
-liftTypedString = TH.unsafeCodeCoerce . TH.liftString
-
-- | Like 'TH.liftTyped' but adjusted to work on 'onExceptionStackByLabel'
-- which already contains 'CodeQ' terms.
-- Moreover, only the 'OnException' at the top of the stack
Gen inp (InputPosition inp : vs) a ->
GenCtx inp vs a -> TH.CodeQ (OnException inp a)
onExceptionCode resetInput resetCheckedHorizon k ctx = [||
- let _ = $$(liftTypedString $ "onException") in
- \ !_exn !failInp !farInp !farExp buf end ->
+ let _ = $$(TH.liftTypedString $ "onException") in
+ \ !_exn !failInp !farFail !farExp buf end ->
$$(unGen k ctx
-- Push 'input' and 'checkedHorizon'
-- as they were when entering the 'catch' or 'iter',
if checkedHorizon ctx0 >= 1
then
[||
- let _ = $$(liftTypedString $ "checkHorizon.oldCheck: checkedHorizon="<>show (checkedHorizon ctx0)) in
+ let _ = $$(TH.liftTypedString $ "checkHorizon.oldCheck: checkedHorizon="<>show (checkedHorizon ctx0)) in
$$(unGen ok ctx0{checkedHorizon = checkedHorizon ctx0 - 1})
||]
else
, inputBuffer = [||buf||]
} in
[||
- let _ = $$(liftTypedString $ "checkHorizon.newCheck: checkedHorizon="<>show (checkedHorizon ctx)<>" minHoriz="<>show minHoriz) in
+ let _ = $$(TH.liftTypedString $ "checkHorizon.newCheck: checkedHorizon="<>show (checkedHorizon ctx)<>" minHoriz="<>show minHoriz) in
if $$(moreInput ctx) buf
$$(if minHoriz > 1
then [||$$shiftRight $$(TH.liftTyped (minHoriz - 1)) $$(input ctx)||]