"-" 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

Reply via email to