diff options
Diffstat (limited to 'src/Script/Expr.hs')
| -rw-r--r-- | src/Script/Expr.hs | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/Script/Expr.hs b/src/Script/Expr.hs index 7a446c5..1a0f458 100644 --- a/src/Script/Expr.hs +++ b/src/Script/Expr.hs @@ -20,6 +20,7 @@ module Script.Expr ( Traced(..), EvalTrace, CallStack(..), VarNameSelectors, gatherVars, AppAnnotation(..), + callStackVarName, callStackFqVarName, module Script.Var, @@ -28,6 +29,7 @@ module Script.Expr ( ) where import Control.Monad +import Control.Monad.Except import Control.Monad.Reader import Data.Char @@ -132,14 +134,17 @@ withTypedVar :: (MonadEval m, ExprType e) => TypedVarName e -> e -> m a -> m a withTypedVar (TypedVarName name) = withVar name -newtype SimpleEval a = SimpleEval (Reader ( GlobalDefs, VariableDictionary ) a) - deriving (Functor, Applicative, Monad) +newtype SimpleEval a = SimpleEval (ReaderT ( GlobalDefs, VariableDictionary ) (Except String) a) + deriving (Functor, Applicative, Monad, MonadError String) runSimpleEval :: SimpleEval a -> GlobalDefs -> VariableDictionary -> a -runSimpleEval (SimpleEval x) = curry $ runReader x +runSimpleEval (SimpleEval x) gdefs dict = either error id $ runExcept $ runReaderT x ( gdefs, dict ) + +trySimpleEval :: SimpleEval a -> GlobalDefs -> VariableDictionary -> Maybe a +trySimpleEval (SimpleEval x) gdefs dict = either (const Nothing) Just $ runExcept $ runReaderT x ( gdefs, dict ) instance MonadFail SimpleEval where - fail = error . ("eval failed: " <>) + fail = throwError . ("eval failed: " <>) instance MonadEval SimpleEval where askGlobalDefs = SimpleEval (asks fst) @@ -175,7 +180,7 @@ eval = \case gdefs <- askGlobalDefs dict <- askDictionary return $ FunctionType $ \stack _ -> - runSimpleEval (eval expr) gdefs (( callStackVarName, someConstValue stack ) : dict) + runSimpleEval (eval expr) gdefs (( callStackVarName, someConstValue stack ) : filter ((callStackVarName /=) . fst) dict) FunctionEval sline efun -> do vars <- gatherVars efun CallStack cs <- maybe (return $ CallStack []) (fromSomeVarValue (CallStack []) callStackFqVarName) =<< tryLookupVar callStackFqVarName @@ -415,8 +420,10 @@ gatherVars = fmap (uniqOn fst . sortOn fst) . helper e@(App (AnnRecord sel) _ x) | Just (var, sels) <- gatherSelectors x -> do - val <- SomeVarValue . VarValue [] mempty . const . const <$> eval e - return [ (( var, sels ++ [ sel ] ), val ) ] + gdefs <- askGlobalDefs + dict <- askDictionary + let mbVal = SomeVarValue . VarValue [] mempty . const . const <$> trySimpleEval (eval e) gdefs dict + return $ catMaybes [ (( var, sels ++ [ sel ] ), ) <$> mbVal ] | otherwise -> do helper x App _ f x -> (++) <$> helper f <*> helper x |