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

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • 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"