Changeset 17870

Show
Ignore:
Timestamp:
09/16/07 15:05:07 (14 months ago)
Author:
ryporter
Message:

Fix how the range operator handles rationals

Files:
2 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Prim.hs

    r17865 r17870  
    14561456    op1Range (VInt int) 
    14571457 
     1458{- In the four op2Range* functions below, rationals 
     1459have to be handled separately because Haskell ranges  
     1460are different from Perl 6 ranges.  For example,  
     1461in Haskell, [1.1 .. 2] will return [1.1,2.1].  So, we 
     1462run the elements through a filter to ensure that the  
     1463upper bound is satisfied  
     1464-} 
    14581465op2Range :: Val -> Val -> Eval Val 
    14591466op2Range (VStr s) y  = do 
     
    14681475op2Range (VRat n) y  = do 
    14691476    y'  <- fromVal y 
    1470     return . VList $ map VRat [n .. y'] 
     1477    return . VList $ map VRat (filter (<= y') [n .. y']) 
    14711478op2Range x (VRat n)  = do 
    14721479    x'  <- fromVal x 
    1473     return . VList $ map VRat [x' .. n] 
     1480    return . VList $ map VRat (filter (<= n) [x' .. n]) 
    14741481op2Range x y         = do 
    14751482    x'  <- fromVal x 
     
    14771484    return . VList $ map VInt [x' .. y'] 
    14781485 
     1486-- because the right-exclusivity of a range can leave it 
     1487-- with no remaining elements, we need to check before 
     1488-- removing an element when enforcing left-exclusivity 
     1489removeRangeFirst :: [Val] -> [Val] 
     1490removeRangeFirst vals = if null vals then vals else init vals 
     1491 
    14791492op2RangeExclRight :: Val -> Val -> Eval Val 
     1493op2RangeExclRight (VRat n) y  = do 
     1494    y' <- fromVal y 
     1495    return . VList $ map VRat (filter (< y') [n .. y']) 
     1496op2RangeExclRight x (VRat n)  = do 
     1497    x'  <- fromVal x 
     1498    return . VList $ map VRat (filter (< n) [x' .. n]) 
    14801499op2RangeExclRight x y = do 
    14811500    VList vals <- op2Range x y 
    1482     return . VList $ init vals 
     1501    return . VList $ removeRangeFirst vals 
    14831502 
    14841503op2RangeExclLeft :: Val -> Val -> Eval Val 
     1504op2RangeExclLeft (VRat n) y  = do 
     1505    y'  <- fromVal y 
     1506    return . VList $ map VRat (filter (\v -> n < v && v <= y') [n .. y']) 
     1507op2RangeExclLeft x (VRat n)  = do 
     1508    x'  <- fromVal x 
     1509    return . VList $ map VRat (filter (\v -> x' < v && v <= n) [x' .. n]) 
    14851510op2RangeExclLeft x y = do 
    14861511    VList vals <- op2Range x y 
     
    14881513 
    14891514op2RangeExclBoth :: Val -> Val -> Eval Val 
     1515op2RangeExclBoth (VRat n) y  = do 
     1516    y'  <- fromVal y 
     1517    return . VList $ map VRat (filter (\v -> n < v && v < y') [n .. y']) 
     1518op2RangeExclBoth x (VRat n)  = do 
     1519    x'  <- fromVal x 
     1520    return . VList $ map VRat (filter (\v -> x' < v && v < n) [x' .. n]) 
    14901521op2RangeExclBoth x y = do 
    14911522    VList vals <- op2Range x y 
    1492     return . VList $ init (tail vals) 
     1523    return . VList $ removeRangeFirst (tail vals) 
    14931524 
    14941525op2ChainedList :: Val -> Val -> Val 
  • t/operators/range.t

    r15818 r17870  
    33use Test; 
    44 
    5 plan 47; 
     5plan 50; 
    66 
    77# 3..2 must *not* produce "3 2".  Use reverse to get a reversed range. -lwall 
     
    3434is [1^..^2], [], "double-exclusive range (^..^) can produce null range"; 
    3535 
     36# tests of (x ^..^ x) here and below ensure that our implementation 
     37# of double-exclusive range does not blindly remove an element 
     38# from the head and tail of a list 
     39is [1^..^1], [], "double-exclusive range (x ^..^ x) where x is an int"; 
     40 
    3641is ["a"^.."z"], ["b".."z"], "bottom-exclusive string range (^..) works"; 
    3742is ["a"..^"z"], ["a".."y"], "top-exclusive string range (..^) works"; 
    3843is ["a"^..^"z"], ["b".."y"], "double-exclusive string range (^..^) works"; 
    3944is ['a'^..^'b'], [], "double-exclusive string range (^..^) can produce null range"; 
     45is ['a' ^..^ 'a'], [], "double-exclusive range (x ^..^ x) where x is a char"; 
    4046 
    4147is 1.5 ~~ 1^..^2, Bool::True, "lazy evaluation of the range operator", :todo<bug>; 
     
    7076is ~(1.1 ^..^ 4.9), "2.1 3.1 4.1", "both exclusive float range"; 
    7177is ~(1.9 ^..^ 4.9), "2.9 3.9"    , "both exclusive float range"; 
    72  
     78is [1.1 ^..^ 1.1], [], "double-exclusive range (x ^..^ x) where x is a float"; 
    7379 
    7480# Test that the operands are forced to scalar context