From 3e60c0a9fcccfbdab0fdf5e7886079e5e0cb3584 Mon Sep 17 00:00:00 2001 From: Nikolai Kudasov Date: Mon, 9 Dec 2024 11:04:44 +0300 Subject: [PATCH] Avoid dividing by zero --- .../src/Language/EO/Phi/Dataize.hs | 46 +++++++++++++++++++ .../src/Language/EO/Phi/Dataize/Atoms.hs | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Dataize.hs b/eo-phi-normalizer/src/Language/EO/Phi/Dataize.hs index f5794045f..c42dfc8b7 100644 --- a/eo-phi-normalizer/src/Language/EO/Phi/Dataize.hs +++ b/eo-phi-normalizer/src/Language/EO/Phi/Dataize.hs @@ -250,6 +250,49 @@ evaluateBinaryDataizationFunChain resultToBytes bytesToParam wrapBytes arg1 arg2 fail (name <> ": Couldn't find bytes in RHS: " <> printTree (hideRho r)) return (result, ()) +evaluatePartialBinaryDataizationFunChain :: + -- | How to convert the result back to bytes + (res -> Bytes) -> + -- | How to interpret the bytes in terms of the given data type + (Bytes -> a) -> + -- | How to wrap the bytes in an object + (Bytes -> Object) -> + -- | Extract the 1st argument to be dataized + (Object -> Object) -> + -- | Extract the 2nd argument to be dataized + (Object -> Object) -> + -- | A binary function on the argument + (a -> a -> Maybe res) -> + -- | Name of the atom. + String -> + Object -> + EvaluationState -> + DataizeChain (Object, EvaluationState) +evaluatePartialBinaryDataizationFunChain resultToBytes bytesToParam wrapBytes arg1 arg2 func name obj _state = do + let lhsArg = arg1 obj + let rhsArg = arg2 obj + lhs <- incLogLevel $ do + logStep "Evaluating LHS" (AsObject lhsArg) + dataizeRecursivelyChain True lhsArg + rhs <- incLogLevel $ do + logStep "Evaluating RHS" (AsObject rhsArg) + dataizeRecursivelyChain True rhsArg + result <- case (lhs, rhs) of + (AsBytes l, AsBytes r) -> do + case resultToBytes <$> bytesToParam l `func` bytesToParam r of + Nothing -> fail (name <> ": throws an error") + Just bytes -> do + let resultObj = wrapBytes bytes + logStep "Evaluated function" (AsObject resultObj) + return resultObj + (AsObject _l, AsObject _r) -> + fail (name <> ": Couldn't find bytes in both LHS and RHS") + (AsObject l, _) -> do + fail (name <> ": Couldn't find bytes in LHS: " <> printTree (hideRho l)) + (_, AsObject r) -> do + fail (name <> ": Couldn't find bytes in RHS: " <> printTree (hideRho r)) + return (result, ()) + -- | Unary functions operate on the given object without any additional parameters evaluateUnaryDataizationFunChain :: -- | How to convert the result back to bytes @@ -273,6 +316,9 @@ evaluateUnaryDataizationFunChain resultToBytes bytesToParam wrapBytes extractArg evaluateIntIntIntFunChain :: (Int -> Int -> Int) -> String -> Object -> EvaluationState -> DataizeChain (Object, EvaluationState) evaluateIntIntIntFunChain = evaluateBinaryDataizationFunChain intToBytes bytesToInt wrapBytesInConstInt extractRho (extractLabel "x") +evaluateIntIntMaybeIntFunChain :: (Int -> Int -> Maybe Int) -> String -> Object -> EvaluationState -> DataizeChain (Object, EvaluationState) +evaluateIntIntMaybeIntFunChain = evaluatePartialBinaryDataizationFunChain intToBytes bytesToInt wrapBytesInConstInt extractRho (extractLabel "x") + evaluateIntIntBoolFunChain :: (Int -> Int -> Bool) -> String -> Object -> EvaluationState -> DataizeChain (Object, EvaluationState) evaluateIntIntBoolFunChain = evaluateBinaryDataizationFunChain boolToBytes bytesToInt wrapBytesAsBool extractRho (extractLabel "x") diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Dataize/Atoms.hs b/eo-phi-normalizer/src/Language/EO/Phi/Dataize/Atoms.hs index f9714736f..0337204d8 100644 --- a/eo-phi-normalizer/src/Language/EO/Phi/Dataize/Atoms.hs +++ b/eo-phi-normalizer/src/Language/EO/Phi/Dataize/Atoms.hs @@ -101,7 +101,7 @@ knownAtomsList = ("Lorg_eolang_i16_as_i32", evaluateUnaryDataizationFunChain intToBytes bytesToInt wrapBytesInConstInt extractRho id) , ("Lorg_eolang_i32_as_i64", evaluateUnaryDataizationFunChain intToBytes bytesToInt wrapBytesInConstInt extractRho id) , ("Lorg_eolang_i64_as_number", evaluateUnaryDataizationFunChain floatToBytes bytesToInt wrapBytesInConstInt extractRho fromIntegral) - , ("Lorg_eolang_i64_div", evaluateIntIntIntFunChain div) + , ("Lorg_eolang_i64_div", evaluateIntIntMaybeIntFunChain (\x y -> if y == 0 then Nothing else Just (x `quot` y))) , ("Lorg_eolang_i64_gt", evaluateIntIntBoolFunChain (>)) , ("Lorg_eolang_i64_plus", evaluateIntIntIntFunChain (+)) , ("Lorg_eolang_i64_times", evaluateIntIntIntFunChain (*))