"-" x -1 should evaluate to an empty string and 0 xx -1 should evaluate to an empty list. I have hacked pugs/src/Pugs/Prim.hs to correctly handle negatives, but I don't know Haskell very well and am not familiar with the layout of Pugs, so I may have written bad code in a bad place. I have also added tests to pugs/t/operators/repeat.t to test for correct handling of negative and zero values.
Hopefully the patch will make it through to the list.
diff -ruN pugs.orig/src/Pugs/Prim.hs pugs/src/Pugs/Prim.hs --- pugs.orig/src/Pugs/Prim.hs 2007-05-25 16:34:55.000000000 -0400 +++ pugs/src/Pugs/Prim.hs 2007-05-25 15:59:47.000000000 -0400 @@ -923,6 +923,11 @@ | last str == '\n' = VStr (init str) | otherwise = VStr str +perlReplicate :: VInt -> a -> [a] +perlReplicate i a = if i < 0 + then genericReplicate 0 a + else genericReplicate i a + -- |Implementation of 2-arity primitive operators and functions op2 :: String -> Val -> Val -> Eval Val op2 "rename" = guardedIO2 rename @@ -931,8 +936,8 @@ op2 "*" = op2Numeric (*) op2 "/" = op2Divide op2 "%" = op2Modulus -op2 "x" = op2Cast (\x y -> VStr . concat $ (y :: VInt) `genericReplicate` x) -op2 "xx" = op2Cast (\x y -> VList . concat $ (y :: VInt) `genericReplicate` x) +op2 "x" = op2Cast (\x y -> VStr . concat $ (y :: VInt) `perlReplicate` x) +op2 "xx" = op2Cast (\x y -> VList . concat $ (y :: VInt) `perlReplicate` x) op2 "+&" = op2Int (.&.) op2 "+<" = op2Int shiftL op2 "+>" = op2Int shiftR diff -ruN pugs.orig/t/operators/repeat.t pugs/t/operators/repeat.t --- pugs.orig/t/operators/repeat.t 2007-05-25 16:34:55.000000000 -0400 +++ pugs/t/operators/repeat.t 2007-05-25 16:13:29.000000000 -0400 @@ -8,7 +8,7 @@ =cut -plan 19; +plan 23; #L<S03/Changes to Perl 5 operators/"x (which concatenates repetitions of a string to produce a single string"> @@ -16,6 +16,8 @@ is('ab' x 4, 'abababab', 'string repeat operator works on multiple character'); is(1 x 5, '11111', 'number repeat operator works on number and creates string'); is('' x 6, '', 'repeating an empty string creates an empty string'); +is('a' x 0, '', 'repeating zero times produces an empty string'); +is('a' x -1, '', 'repeating negative times produces an empty string'); #L<S03/Changes to Perl 5 operators/"and xx (which creates a list of repetitions of a list or item)"> my @foo = 'x' xx 10; @@ -23,12 +25,20 @@ is(@foo[9], 'x', 'list repeat operator created correct array'); is([EMAIL PROTECTED], 10, 'list repeat operator created array of the right size'); + lives_ok { my @foo2 = undef xx 2; }, 'can repeat undefs'; my @foo3 = (1, 2) xx 2; is(@foo3[0], 1, 'can repeat lists'); is(@foo3[1], 2, 'can repeat lists'); is(@foo3[2], 1, 'can repeat lists'); is(@foo3[3], 2, 'can repeat lists'); + +my @foo4 = 'x' xx 0; +is([EMAIL PROTECTED], 0, 'repeating zero times produces an empty list'); + +my @foo5 = 'x' xx -1; +is([EMAIL PROTECTED], 0, 'repeating negative times produces an empty list'); + my @foo_2d = [1, 2] xx 2; # should create 2d is(@foo_2d[1], [1, 2], 'can create 2d arrays', :todo<bug>); # creates a flat 1d array # Wrong/unsure: \(1, 2) does not create a ref to the array/list (1,2), but