| | 45 | |
| | 46 | op2Exp :: Val -> Val -> Eval Val |
| | 47 | op2Exp x y = do |
| | 48 | num2 <- fromVal =<< fromVal' y |
| | 49 | case reverse $ show (num2 :: VNum) of |
| | 50 | ('0':'.':_) -> do |
| | 51 | num1 <- fromVal =<< fromVal' x |
| | 52 | if isDigit . head $ show (num1 :: VNum) |
| | 53 | then op2Rat ((^^) :: VRat -> VInt -> VRat) x y |
| | 54 | else op2Num ((**) :: VNum -> VNum -> VNum) x y |
| | 55 | _ -> op2Num ((**) :: VNum -> VNum -> VNum) x y |
| | 56 | |
| | 57 | op2Divide :: Val -> Val -> Eval Val |
| | 58 | op2Divide x y |
| | 59 | | VInt x' <- x, VInt y' <- y |
| | 60 | = if y' == 0 then err else return . VRat $ x' % y' |
| | 61 | | VInt x' <- x, VRat y' <- y |
| | 62 | = if y' == 0 then err else return . VRat $ (x' % 1) / y' |
| | 63 | | VRat x' <- x, VInt y' <- y |
| | 64 | = if y' == 0 then err else return . VRat $ x' / (y' % 1) |
| | 65 | | VRat x' <- x, VRat y' <- y |
| | 66 | = if y' == 0 then err else return . VRat $ x' / y' |
| | 67 | | otherwise |
| | 68 | = op2Num (/) x y |
| | 69 | where |
| | 70 | err = fail "Illegal division by zero" |
| | 71 | |
| | 72 | op2Modulus :: Val -> Val -> Eval Val |
| | 73 | op2Modulus x y |
| | 74 | | VInt x' <- x, VInt y' <- y |
| | 75 | = if y' == 0 then err else return . VInt $ x' `mod` y' |
| | 76 | | VInt x' <- x, VRat y' <- y |
| | 77 | = if y' == 0 then err else return . VInt $ x' `mod` (truncate y') |
| | 78 | | VRat x' <- x, VInt y' <- y |
| | 79 | = if y' == 0 then err else return . VInt $ (truncate x') `mod` y' |
| | 80 | | VRat x' <- x, VRat y' <- y |
| | 81 | = if y' == 0 then err else return . VInt $ (truncate x') `mod` (truncate y') |
| | 82 | | VRef ref <- x |
| | 83 | = do |
| | 84 | x' <- readRef ref |
| | 85 | op2Modulus x' y |
| | 86 | | VRef ref <- y |
| | 87 | = do |
| | 88 | y' <- readRef ref |
| | 89 | op2Modulus x y' |
| | 90 | | otherwise -- pray for the best |
| | 91 | = op2Int mod x y -- typeErr |
| | 92 | where |
| | 93 | err = fail "Illegal modulus zero" |