Show
Ignore:
Timestamp:
02/06/07 21:28:57 (22 months ago)
Author:
audreyt
Message:

* Numeric primitives for complex numbers.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Prim/Numeric.hs

    r12522 r15201  
    33module Pugs.Prim.Numeric ( 
    44    op2Numeric, op1Floating, op1Round, op1Numeric, 
    5     op2Exp, op2Divide, op2Modulus, 
     5    op2Exp, op2Divide, op2Modulus, op2OrdNumeric 
    66) where 
    77import Pugs.Internals 
     
    1111import Pugs.Prim.Lifts 
    1212 
    13 --- XXX wrong: try num first, then int, then vcast to Rat (I think) 
     13op2OrdNumeric :: Value b => (forall a. (Ord a) => a -> a -> b) -> Val -> Val -> Eval Val 
     14op2OrdNumeric f x y 
     15    | VInt x' <- x, VInt y' <- y  = return $ castV $ f x' y' 
     16    | VRat x' <- x, VRat y' <- y  = return $ castV $ f x' y' 
     17    | VRat x' <- x, VInt y' <- y  = return $ castV $ f x' (y' % 1) 
     18    | VInt x' <- x, VRat y' <- y  = return $ castV $ f (x' % 1) y' 
     19    | VUndef <- x = op2OrdNumeric f (VInt 0) y 
     20    | VUndef <- y = op2OrdNumeric f x (VInt 0) 
     21    | VType{} <- x = op2OrdNumeric f (VInt 0) y 
     22    | VType{} <- y = op2OrdNumeric f x (VInt 0) 
     23    | VRef r <- x = do 
     24        x' <- readRef r 
     25        op2OrdNumeric f x' y 
     26    | VRef r <- y = do 
     27        y' <- readRef r 
     28        op2OrdNumeric f x y' 
     29    | VComplex x' <- x = do 
     30        y'  <- fromVal y 
     31        return . castV $ f x' y' 
     32    | VComplex y' <- y = do 
     33        x'  <- fromVal x 
     34        return . castV $ f x' y' 
     35    | otherwise = do 
     36        x' <- fromVal x :: Eval VNum 
     37        y' <- fromVal y 
     38        return . castV $ f x' y' 
     39 
    1440op2Numeric :: (forall a. (Num a) => a -> a -> a) -> Val -> Val -> Eval Val 
    1541op2Numeric f x y 
     
    2854        y' <- readRef r 
    2955        op2Numeric f x y' 
     56    | VComplex x' <- x = do 
     57        y'  <- fromVal y 
     58        return . VComplex $ f x' y' 
     59    | VComplex y' <- y = do 
     60        x'  <- fromVal x 
     61        return . VComplex $ f x' y' 
    3062    | otherwise = do 
    3163        x' <- fromVal x 
     
    3365        return . VNum $ f x' y' 
    3466 
    35 op1Floating :: (Double -> Double) -> Val -> Eval Val 
    36 op1Floating f v = do 
    37     foo <- fromVal v 
    38     return $ VNum $ f foo 
     67op1Floating :: (forall a. (Floating a) => a -> a) -> Val -> Eval Val 
     68op1Floating f VUndef        = return . VNum $ f 0 
     69op1Floating f VType{}       = return . VNum $ f 0 
     70op1Floating f (VComplex x)  = return . VComplex $ f x 
     71op1Floating f (VRef x)      = op1Floating f =<< readRef x 
     72op1Floating f x             = fmap (VNum . f) (fromVal x) 
    3973 
    4074op1Round :: (Double -> Integer) -> Val -> Eval Val 
     
    5286op1Numeric f l@(VList _)= fmap (VInt . f) (fromVal l) 
    5387op1Numeric f (VRat x)   = return . VRat $ f x 
     88op1Numeric f (VComplex x) = return . VComplex $ f x 
    5489op1Numeric f (VRef x)   = op1Numeric f =<< readRef x 
    5590op1Numeric f x          = fmap (VNum . f) (fromVal x) 
     
    68103            if isDigit . head $ show (num1 :: VNum) 
    69104                then op2Rat ((^^) :: VRat -> VInt -> VRat) x y 
    70                 else op2Num ((**) :: VNum -> VNum -> VNum) x y 
    71         _ -> op2Num ((**) :: VNum -> VNum -> VNum) x y 
     105                else op2Num (**) x y 
     106        _ -> op2Num (**) x y 
    72107 
    73108op2Divide :: Val -> Val -> Eval Val 
     
    81116    | VRat x' <- x, VRat y' <- y 
    82117    = if y' == 0 then err else return . VRat $ x' / y' 
     118    | VComplex x' <- x = do 
     119        y' <- fromVal y 
     120        if y' == 0 then err else return . VComplex $ x' / y' 
     121    | VComplex y' <- y = do 
     122        x' <- fromVal x 
     123        if y' == 0 then err else return . VComplex $ x' / y' 
    83124    | otherwise 
    84125    = op2Num (/) x y 
     
    96137    | VRat x' <- x, VRat y' <- y 
    97138    = if y' == 0 then err else return . VRat $ x' `fmod` y' 
     139--  | VComplex x' <- x = do 
     140--      y' <- fromVal y 
     141--      if y' == 0 then err else return . VComplex $ x' `fmod` y' 
     142--  | VComplex y' <- y = do 
     143--      x' <- fromVal x 
     144--      if y' == 0 then err else return . VComplex $ x' `fmod` y' 
    98145    | otherwise      -- pray for the best 
    99146    = op2Num fmod x y