mirror of
https://github.com/github/semantic.git
synced 2024-12-30 02:14:20 +03:00
Handle LoopControl local to Evaluatable.
This commit is contained in:
parent
8b679d0f80
commit
848543010d
@ -27,8 +27,7 @@ deriving instance (Show (Cell location value), Show location, Show term, Show va
|
|||||||
|
|
||||||
-- | Effects necessary for evaluating (whether concrete or abstract).
|
-- | Effects necessary for evaluating (whether concrete or abstract).
|
||||||
type EvaluatingEffects location term value
|
type EvaluatingEffects location term value
|
||||||
= '[ LoopControl value
|
= '[ Fail -- Failure with an error message
|
||||||
, Fail -- Failure with an error message
|
|
||||||
, Fresh -- For allocating new addresses and/or type variables.
|
, Fresh -- For allocating new addresses and/or type variables.
|
||||||
, Reader (Environment location value) -- Default environment used as a fallback in lookupEnv
|
, Reader (Environment location value) -- Default environment used as a fallback in lookupEnv
|
||||||
, State (Environment location value)
|
, State (Environment location value)
|
||||||
@ -39,7 +38,7 @@ type EvaluatingEffects location term value
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
evaluating :: Show value => Evaluator location term value (EvaluatingEffects location term value) result -> (Either String result, EvaluatingState location term value)
|
evaluating :: Evaluator location term value (EvaluatingEffects location term value) result -> (Either String result, EvaluatingState location term value)
|
||||||
evaluating
|
evaluating
|
||||||
= (\ (((((result, env), heap), modules), exports), jumps) -> (result, EvaluatingState env heap modules exports jumps))
|
= (\ (((((result, env), heap), modules), exports), jumps) -> (result, EvaluatingState env heap modules exports jumps))
|
||||||
. Eff.run
|
. Eff.run
|
||||||
@ -52,10 +51,4 @@ evaluating
|
|||||||
. handleReader lowerBound -- Reader (Environment location value)
|
. handleReader lowerBound -- Reader (Environment location value)
|
||||||
. raiseHandler
|
. raiseHandler
|
||||||
( flip runFresh' 0
|
( flip runFresh' 0
|
||||||
. runFail
|
. runFail)
|
||||||
-- NB: We should never have a 'Return', 'Break', or 'Continue' at this point in execution; the scope being returned from/broken from/continued should have intercepted the effect. This handler will therefore only be invoked if we issue a 'Return', 'Break', or 'Continue' outside of such a scope, and unfortunately if this happens it will handle it by resuming the scope being returned from. While it would be _slightly_ more correct to instead exit with the value being returned, we aren’t able to do that here since 'Interpreter'’s type is parametric in the value being returned—we don’t know that we’re returning a @value@ (because we very well may not be). On the balance, I felt the strange behaviour in error cases is worth the improved behaviour in the common case—we get to lose a layer of 'Either' in the result for each.
|
|
||||||
-- In general, it’s expected that none of the following effects will remain by the time 'interpret' is called—they should have been handled by local 'interpose's—but if they do, we’ll at least trace.
|
|
||||||
. Eff.interpret (\ control -> case control of
|
|
||||||
Break value -> traceM ("Evaluating.interpret: resuming uncaught break with " <> show value) $> value
|
|
||||||
Continue value -> traceM ("Evaluating.interpret: resuming uncaught continue with " <> show value) $> value))
|
|
||||||
-- TODO: Replace 'traceM's with e.g. 'Telemetry'.
|
|
||||||
|
@ -324,7 +324,7 @@ evaluatePackageWith :: ( Evaluatable (Base term)
|
|||||||
, State (Environment location value)
|
, State (Environment location value)
|
||||||
] effects
|
] effects
|
||||||
, Recursive term
|
, Recursive term
|
||||||
, termEffects ~ (Return value ': EvalClosure term value ': moduleEffects)
|
, termEffects ~ (LoopControl value ': Return value ': EvalClosure term value ': moduleEffects)
|
||||||
, moduleEffects ~ (Reader ModuleInfo ': EvalModule term value ': packageBodyEffects)
|
, moduleEffects ~ (Reader ModuleInfo ': EvalModule term value ': packageBodyEffects)
|
||||||
, packageBodyEffects ~ (Reader LoadStack ': Reader (ModuleTable [Module term]) ': packageEffects)
|
, packageBodyEffects ~ (Reader LoadStack ': Reader (ModuleTable [Module term]) ': packageEffects)
|
||||||
, packageEffects ~ (Reader PackageInfo ': effects)
|
, packageEffects ~ (Reader PackageInfo ': effects)
|
||||||
@ -344,7 +344,7 @@ evaluatePackageBodyWith :: forall location term value effects termEffects module
|
|||||||
, State (Environment location value)
|
, State (Environment location value)
|
||||||
] effects
|
] effects
|
||||||
, Recursive term
|
, Recursive term
|
||||||
, termEffects ~ (Return value ': EvalClosure term value ': moduleEffects)
|
, termEffects ~ (LoopControl value ': Return value ': EvalClosure term value ': moduleEffects)
|
||||||
, moduleEffects ~ (Reader ModuleInfo ': EvalModule term value ': packageBodyEffects)
|
, moduleEffects ~ (Reader ModuleInfo ': EvalModule term value ': packageBodyEffects)
|
||||||
, packageBodyEffects ~ (Reader LoadStack ': Reader (ModuleTable [Module term]) ': effects)
|
, packageBodyEffects ~ (Reader LoadStack ': Reader (ModuleTable [Module term]) ': effects)
|
||||||
)
|
)
|
||||||
@ -370,9 +370,10 @@ evaluatePackageBodyWith perModule perTerm body
|
|||||||
evalTerm
|
evalTerm
|
||||||
= handleEvalClosures
|
= handleEvalClosures
|
||||||
. runReturn
|
. runReturn
|
||||||
|
. runLoopControl
|
||||||
. foldSubterms (perTerm eval)
|
. foldSubterms (perTerm eval)
|
||||||
|
|
||||||
evaluateEntryPoint m sym = handleReader (ModuleInfo m) . handleEvalClosures . runReturn $ do
|
evaluateEntryPoint m sym = handleReader (ModuleInfo m) . handleEvalClosures . runReturn . runLoopControl $ do
|
||||||
v <- maybe unit (pure . snd) <$> require m
|
v <- maybe unit (pure . snd) <$> require m
|
||||||
maybe v ((`call` []) <=< variable) sym
|
maybe v ((`call` []) <=< variable) sym
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ import qualified Language.Python.Assignment as Python
|
|||||||
import qualified Language.Ruby.Assignment as Ruby
|
import qualified Language.Ruby.Assignment as Ruby
|
||||||
|
|
||||||
justEvaluating
|
justEvaluating
|
||||||
= evaluating @(Value Precise)
|
= evaluating
|
||||||
. failingOnLoadErrors
|
. failingOnLoadErrors
|
||||||
. erroring @(ValueError Precise (Value Precise))
|
. erroring @(ValueError Precise (Value Precise))
|
||||||
. erroring @(Unspecialized (Value Precise))
|
. erroring @(Unspecialized (Value Precise))
|
||||||
@ -41,7 +41,7 @@ justEvaluating
|
|||||||
. erroring @(AddressError Precise (Value Precise))
|
. erroring @(AddressError Precise (Value Precise))
|
||||||
|
|
||||||
evaluatingWithHoles
|
evaluatingWithHoles
|
||||||
= evaluating @(Value Precise)
|
= evaluating
|
||||||
. failingOnLoadErrors
|
. failingOnLoadErrors
|
||||||
. resumingBadSyntax @(Value Precise)
|
. resumingBadSyntax @(Value Precise)
|
||||||
. resumingBadValues @(Value Precise)
|
. resumingBadValues @(Value Precise)
|
||||||
@ -51,7 +51,7 @@ evaluatingWithHoles
|
|||||||
|
|
||||||
-- The order is significant here: caching has to run before typeChecking, or else we’ll nondeterministically produce TypeErrors as part of the result set. While this is probably actually correct, it will require us to have an Ord instance for TypeError, which we don’t have yet.
|
-- The order is significant here: caching has to run before typeChecking, or else we’ll nondeterministically produce TypeErrors as part of the result set. While this is probably actually correct, it will require us to have an Ord instance for TypeError, which we don’t have yet.
|
||||||
checking
|
checking
|
||||||
= evaluating @(Type Monovariant)
|
= evaluating
|
||||||
. providingLiveSet
|
. providingLiveSet
|
||||||
. failingOnLoadErrors
|
. failingOnLoadErrors
|
||||||
. erroring @(Unspecialized (Type Monovariant))
|
. erroring @(Unspecialized (Type Monovariant))
|
||||||
|
Loading…
Reference in New Issue
Block a user