Changeset 2952
- Timestamp:
- 05/11/05 00:31:18 (4 years ago)
- svk:copy_cache_prev:
- 4498
- Location:
- src/Pugs
- Files:
-
- 1 added
- 2 modified
-
Prim.hs (modified) (4 diffs)
-
Prim/Lifts.hs (added)
-
Prim/Numeric.hs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Pugs/Prim.hs
r2951 r2952 27 27 import Pugs.Prim.List 28 28 import Pugs.Prim.Numeric 29 import Pugs.Prim.Lifts 29 30 30 31 op0 :: Ident -> [Val] -> Eval Val … … 437 438 retEmpty 438 439 439 op1Cast :: (Value n) => (n -> Val) -> Val -> Eval Val440 op1Cast f val = fmap f (fromVal =<< fromVal' val)441 442 op2Cast :: (Value n, Value m) => (n -> m -> Val) -> Val -> Val -> Eval Val443 op2Cast f x y = do444 x' <- fromVal =<< fromVal' x445 y' <- fromVal =<< fromVal' y446 return (f x' y')447 448 440 op1StrFirst :: (Char -> Char) -> Val -> Eval Val 449 441 op1StrFirst f = op1Cast $ VStr . … … 784 776 return (val:rest) 785 777 786 op2Array :: (forall a. ArrayClass a => a -> [Val] -> Eval ()) -> Val -> Val -> Eval Val787 op2Array f x y = do788 f <- doArray x f789 vals <- fromVal y790 f vals791 size <- doArray x array_fetchSize792 idx <- size793 return $ castV idx794 795 vCastStr :: Val -> Eval VStr796 vCastStr = fromVal797 vCastRat :: Val -> Eval VRat798 vCastRat = fromVal799 800 op2Str :: (Value v1, Value v2) => (v1 -> v2 -> VStr) -> Val -> Val -> Eval Val801 op2Str f x y = do802 x' <- fromVal x803 y' <- fromVal y804 return $ VStr $ f x' y'805 806 op2Num :: (Value v1, Value v2) => (v1 -> v2 -> VNum) -> Val -> Val -> Eval Val807 op2Num f = op2Cast $ (VNum .) . f808 809 op2Bool :: (Value v1, Value v2) => (v1 -> v2 -> VBool) -> Val -> Val -> Eval Val810 op2Bool f = op2Cast $ (VBool .) . f811 812 op2Int :: (Value v1, Value v2) => (v1 -> v2 -> VInt) -> Val -> Val -> Eval Val813 op2Int f = op2Cast $ (VInt .) . f814 815 op2Rat :: (Value v1, Value v2) => (v1 -> v2 -> VRat) -> Val -> Val -> Eval Val816 op2Rat f = op2Cast $ (VRat .) . f817 818 op2Exp :: Val -> Val -> Eval Val819 op2Exp x y = do820 num2 <- fromVal =<< fromVal' y821 case reverse $ show (num2 :: VNum) of822 ('0':'.':_) -> do823 num1 <- fromVal =<< fromVal' x824 if isDigit . head $ show (num1 :: VNum)825 then op2Rat ((^^) :: VRat -> VInt -> VRat) x y826 else op2Num ((**) :: VNum -> VNum -> VNum) x y827 _ -> op2Num ((**) :: VNum -> VNum -> VNum) x y828 829 778 op1Range :: Val -> Val 830 779 op1Range (VStr s) = VList $ map VStr $ strRangeInf s … … 840 789 op2Range x (VRat n) = VList $ map VRat [vCast x .. n] 841 790 op2Range x y = VList $ map VInt [vCast x .. vCast y] 842 843 op2Divide :: Val -> Val -> Eval Val844 op2Divide x y845 | VInt x' <- x, VInt y' <- y846 = if y' == 0 then err else return . VRat $ x' % y'847 | VInt x' <- x, VRat y' <- y848 = if y' == 0 then err else return . VRat $ (x' % 1) / y'849 | VRat x' <- x, VInt y' <- y850 = if y' == 0 then err else return . VRat $ x' / (y' % 1)851 | VRat x' <- x, VRat y' <- y852 = if y' == 0 then err else return . VRat $ x' / y'853 | otherwise854 = op2Num (/) x y855 where856 err = fail "Illegal division by zero"857 858 op2Modulus :: Val -> Val -> Eval Val859 op2Modulus x y860 | VInt x' <- x, VInt y' <- y861 = if y' == 0 then err else return . VInt $ x' `mod` y'862 | VInt x' <- x, VRat y' <- y863 = if y' == 0 then err else return . VInt $ x' `mod` (truncate y')864 | VRat x' <- x, VInt y' <- y865 = if y' == 0 then err else return . VInt $ (truncate x') `mod` y'866 | VRat x' <- x, VRat y' <- y867 = if y' == 0 then err else return . VInt $ (truncate x') `mod` (truncate y')868 | VRef ref <- x869 = do870 x' <- readRef ref871 op2Modulus x' y872 | VRef ref <- y873 = do874 y' <- readRef ref875 op2Modulus x y'876 | otherwise -- pray for the best877 = op2Int mod x y -- typeErr878 where879 err = fail "Illegal modulus zero"880 791 881 792 op2ChainedList :: Val -> Val -> Val -
src/Pugs/Prim/Numeric.hs
r2951 r2952 3 3 module Pugs.Prim.Numeric ( 4 4 op2Numeric, op1Floating, op1Numeric, 5 op2Exp, op2Divide, op2Modulus, 5 6 ) where 6 7 import Pugs.Internals 7 8 import Pugs.AST 9 import Pugs.Types 10 11 import Pugs.Prim.Lifts 8 12 9 13 --- XXX wrong: try num first, then int, then vcast to Rat (I think) … … 39 43 op1Numeric f (VRef x) = op1Numeric f =<< readRef x 40 44 op1Numeric f x = fmap (VNum . f) (fromVal x) 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"
