Changeset 2952

Show
Ignore:
Timestamp:
05/11/05 00:31:18 (4 years ago)
Author:
bsmith
svk:copy_cache_prev:
4498
Message:

Refactoring: Pugs.Prims -> Pugs.Prims.Numeric and Pugs.Prims.Lifts

Location:
src/Pugs
Files:
1 added
2 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Prim.hs

    r2951 r2952  
    2727import Pugs.Prim.List 
    2828import Pugs.Prim.Numeric 
     29import Pugs.Prim.Lifts 
    2930 
    3031op0 :: Ident -> [Val] -> Eval Val 
     
    437438            retEmpty 
    438439 
    439 op1Cast :: (Value n) => (n -> Val) -> Val -> Eval Val 
    440 op1Cast f val = fmap f (fromVal =<< fromVal' val) 
    441  
    442 op2Cast :: (Value n, Value m) => (n -> m -> Val) -> Val -> Val -> Eval Val 
    443 op2Cast f x y = do 
    444     x' <- fromVal =<< fromVal' x 
    445     y' <- fromVal =<< fromVal' y 
    446     return (f x' y') 
    447  
    448440op1StrFirst :: (Char -> Char) -> Val -> Eval Val 
    449441op1StrFirst f = op1Cast $ VStr . 
     
    784776        return (val:rest) 
    785777 
    786 op2Array :: (forall a. ArrayClass a => a -> [Val] -> Eval ()) -> Val -> Val -> Eval Val 
    787 op2Array f x y = do 
    788     f    <- doArray x f 
    789     vals <- fromVal y 
    790     f vals 
    791     size <- doArray x array_fetchSize 
    792     idx  <- size 
    793     return $ castV idx 
    794  
    795 vCastStr :: Val -> Eval VStr 
    796 vCastStr = fromVal 
    797 vCastRat :: Val -> Eval VRat 
    798 vCastRat = fromVal 
    799  
    800 op2Str :: (Value v1, Value v2) => (v1 -> v2 -> VStr) -> Val -> Val -> Eval Val 
    801 op2Str f x y = do 
    802     x' <- fromVal x 
    803     y' <- fromVal y 
    804     return $ VStr $ f x' y' 
    805  
    806 op2Num    :: (Value v1, Value v2) => (v1 -> v2 -> VNum) -> Val -> Val -> Eval Val 
    807 op2Num  f = op2Cast $ (VNum .) . f 
    808  
    809 op2Bool   :: (Value v1, Value v2) => (v1 -> v2 -> VBool) -> Val -> Val -> Eval Val 
    810 op2Bool f = op2Cast $ (VBool .) . f 
    811  
    812 op2Int    :: (Value v1, Value v2) => (v1 -> v2 -> VInt) -> Val -> Val -> Eval Val 
    813 op2Int  f = op2Cast $ (VInt .) . f 
    814  
    815 op2Rat    :: (Value v1, Value v2) => (v1 -> v2 -> VRat) -> Val -> Val -> Eval Val 
    816 op2Rat  f = op2Cast $ (VRat .) . f 
    817  
    818 op2Exp :: Val -> Val -> Eval Val 
    819 op2Exp x y = do 
    820     num2 <- fromVal =<< fromVal' y 
    821     case reverse $ show (num2 :: VNum) of 
    822         ('0':'.':_) -> do 
    823             num1 <- fromVal =<< fromVal' x 
    824             if isDigit . head $ show (num1 :: VNum) 
    825                 then op2Rat ((^^) :: VRat -> VInt -> VRat) x y 
    826                 else op2Num ((**) :: VNum -> VNum -> VNum) x y 
    827         _ -> op2Num ((**) :: VNum -> VNum -> VNum) x y 
    828  
    829778op1Range :: Val -> Val 
    830779op1Range (VStr s)    = VList $ map VStr $ strRangeInf s 
     
    840789op2Range x (VRat n)  = VList $ map VRat [vCast x .. n] 
    841790op2Range x y         = VList $ map VInt [vCast x .. vCast y] 
    842  
    843 op2Divide :: Val -> Val -> Eval Val 
    844 op2Divide x y 
    845     | VInt x' <- x, VInt y' <- y 
    846     = if y' == 0 then err else return . VRat $ x' % y' 
    847     | VInt x' <- x, VRat y' <- y 
    848     = if y' == 0 then err else return . VRat $ (x' % 1) / y' 
    849     | VRat x' <- x, VInt y' <- y 
    850     = if y' == 0 then err else return . VRat $ x' / (y' % 1) 
    851     | VRat x' <- x, VRat y' <- y 
    852     = if y' == 0 then err else return . VRat $ x' / y' 
    853     | otherwise 
    854     = op2Num (/) x y 
    855     where 
    856     err = fail "Illegal division by zero" 
    857  
    858 op2Modulus :: Val -> Val -> Eval Val 
    859 op2Modulus x y 
    860     | VInt x' <- x, VInt y' <- y 
    861     = if y' == 0 then err else return . VInt $ x' `mod` y' 
    862     | VInt x' <- x, VRat y' <- y 
    863     = if y' == 0 then err else return . VInt $ x' `mod` (truncate y') 
    864     | VRat x' <- x, VInt y' <- y 
    865     = if y' == 0 then err else return . VInt $ (truncate x') `mod` y' 
    866     | VRat x' <- x, VRat y' <- y 
    867     = if y' == 0 then err else return . VInt $ (truncate x') `mod` (truncate y') 
    868     | VRef ref <- x 
    869     = do 
    870         x' <- readRef ref 
    871         op2Modulus x' y 
    872     | VRef ref <- y 
    873     = do 
    874         y' <- readRef ref 
    875         op2Modulus x y' 
    876     | otherwise      -- pray for the best 
    877     = op2Int mod x y -- typeErr 
    878     where 
    879     err = fail "Illegal modulus zero" 
    880791 
    881792op2ChainedList :: Val -> Val -> Val 
  • src/Pugs/Prim/Numeric.hs

    r2951 r2952  
    33module Pugs.Prim.Numeric ( 
    44    op2Numeric, op1Floating, op1Numeric, 
     5    op2Exp, op2Divide, op2Modulus, 
    56) where 
    67import Pugs.Internals 
    78import Pugs.AST 
     9import Pugs.Types 
     10 
     11import Pugs.Prim.Lifts 
    812 
    913--- XXX wrong: try num first, then int, then vcast to Rat (I think) 
     
    3943op1Numeric f (VRef x)   = op1Numeric f =<< readRef x 
    4044op1Numeric f x          = fmap (VNum . f) (fromVal x) 
     45 
     46op2Exp :: Val -> Val -> Eval Val 
     47op2Exp 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 
     57op2Divide :: Val -> Val -> Eval Val 
     58op2Divide 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 
     72op2Modulus :: Val -> Val -> Eval Val 
     73op2Modulus 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"