mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 22:28:45 +01:00
Allow "*" on lists and strings to repeat them.
This is not implemented on Sequence because, at least for lists and strings, I think users expect an eager result. Multiplying a string should give you back a string, not a lazy sequence of repeated characters. This also mirrors "+" on strings and lists, which is eager. I like the idea of having a general guideline that operators are eager. Repetition is useful for arbitrary sequences, but for that maybe we should add a "repeat()" method.
This commit is contained in:
@ -131,6 +131,18 @@ class WhereSequence is Sequence {
|
||||
class String is Sequence {
|
||||
bytes { StringByteSequence.new(this) }
|
||||
codePoints { StringCodePointSequence.new(this) }
|
||||
|
||||
*(count) {
|
||||
if (!(count is Num) || !count.isInteger || count < 0) {
|
||||
Fiber.abort("Count must be a non-negative integer.")
|
||||
}
|
||||
|
||||
var result = ""
|
||||
for (i in 0...count) {
|
||||
result = result + this
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class StringByteSequence is Sequence {
|
||||
@ -174,6 +186,18 @@ class List is Sequence {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
*(count) {
|
||||
if (!(count is Num) || !count.isInteger || count < 0) {
|
||||
Fiber.abort("Count must be a non-negative integer.")
|
||||
}
|
||||
|
||||
var result = []
|
||||
for (i in 0...count) {
|
||||
result.addAll(this)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class Map {
|
||||
|
||||
@ -133,6 +133,18 @@ static const char* coreModuleSource =
|
||||
"class String is Sequence {\n"
|
||||
" bytes { StringByteSequence.new(this) }\n"
|
||||
" codePoints { StringCodePointSequence.new(this) }\n"
|
||||
"\n"
|
||||
" *(count) {\n"
|
||||
" if (!(count is Num) || !count.isInteger || count < 0) {\n"
|
||||
" Fiber.abort(\"Count must be a non-negative integer.\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" var result = \"\"\n"
|
||||
" for (i in 0...count) {\n"
|
||||
" result = result + this\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"class StringByteSequence is Sequence {\n"
|
||||
@ -176,6 +188,18 @@ static const char* coreModuleSource =
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" *(count) {\n"
|
||||
" if (!(count is Num) || !count.isInteger || count < 0) {\n"
|
||||
" Fiber.abort(\"Count must be a non-negative integer.\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" var result = []\n"
|
||||
" for (i in 0...count) {\n"
|
||||
" result.addAll(this)\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"class Map {\n"
|
||||
|
||||
8
test/core/list/multiply.wren
Normal file
8
test/core/list/multiply.wren
Normal file
@ -0,0 +1,8 @@
|
||||
System.print([1, 2, 3] * 0) // expect: []
|
||||
System.print([1, 2, 3] * 1) // expect: [1, 2, 3]
|
||||
System.print([1, 2, 3] * 4) // expect: [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
|
||||
|
||||
// Doesn't modify original list.
|
||||
var a = [1, 2, 3]
|
||||
a * 5
|
||||
System.print(a) // expect: [1, 2, 3]
|
||||
1
test/core/list/multiply_negative.wren
Normal file
1
test/core/list/multiply_negative.wren
Normal file
@ -0,0 +1 @@
|
||||
[1, 2, 3] * -3 // expect runtime error: Count must be a non-negative integer.
|
||||
1
test/core/list/multiply_not_int.wren
Normal file
1
test/core/list/multiply_not_int.wren
Normal file
@ -0,0 +1 @@
|
||||
[1, 2, 3] * 1.2 // expect runtime error: Count must be a non-negative integer.
|
||||
1
test/core/list/multiply_not_num.wren
Normal file
1
test/core/list/multiply_not_num.wren
Normal file
@ -0,0 +1 @@
|
||||
[1, 2, 3] * "not num" // expect runtime error: Count must be a non-negative integer.
|
||||
@ -1,18 +1,11 @@
|
||||
var a = [1, 2, 3]
|
||||
var b = [4, 5, 6]
|
||||
var c = a + b
|
||||
var d = a + (4..6)
|
||||
var e = a + []
|
||||
var f = [] + a
|
||||
var g = [] + []
|
||||
|
||||
System.print(a) // expect: [1, 2, 3]
|
||||
System.print(b) // expect: [4, 5, 6]
|
||||
System.print(c) // expect: [1, 2, 3, 4, 5, 6]
|
||||
System.print(d) // expect: [1, 2, 3, 4, 5, 6]
|
||||
System.print(e) // expect: [1, 2, 3]
|
||||
System.print(f) // expect: [1, 2, 3]
|
||||
System.print(g) // expect: []
|
||||
System.print([1, 2, 3] + [4, 5, 6]) // expect: [1, 2, 3, 4, 5, 6]
|
||||
System.print([1, 2, 3] + (4..6)) // expect: [1, 2, 3, 4, 5, 6]
|
||||
System.print([1, 2, 3] + "abc") // expect: [1, 2, 3, a, b, c]
|
||||
System.print([] + []) // expect: []
|
||||
System.print([1, 2] + []) // expect: [1, 2]
|
||||
System.print([] + [3, 4]) // expect: [3, 4]
|
||||
|
||||
// Doesn't modify original list.
|
||||
var a = [1, 2, 3]
|
||||
a * 5
|
||||
System.print(a) // expect: [1, 2, 3]
|
||||
|
||||
1
test/core/list/plus_not_iterable.wren
Normal file
1
test/core/list/plus_not_iterable.wren
Normal file
@ -0,0 +1 @@
|
||||
[1, 2, 3] + 4 // expect runtime error: Num does not implement 'iterate(_)'.
|
||||
3
test/core/string/multiply.wren
Normal file
3
test/core/string/multiply.wren
Normal file
@ -0,0 +1,3 @@
|
||||
System.print("|" + "abc" * 0 + "|") // expect: ||
|
||||
System.print("abc" * 1) // expect: abc
|
||||
System.print("abc" * 4) // expect: abcabcabcabc
|
||||
1
test/core/string/multiply_negative.wren
Normal file
1
test/core/string/multiply_negative.wren
Normal file
@ -0,0 +1 @@
|
||||
"abc" * -3 // expect runtime error: Count must be a non-negative integer.
|
||||
1
test/core/string/multiply_not_int.wren
Normal file
1
test/core/string/multiply_not_int.wren
Normal file
@ -0,0 +1 @@
|
||||
"abc" * 1.2 // expect runtime error: Count must be a non-negative integer.
|
||||
1
test/core/string/multiply_not_num.wren
Normal file
1
test/core/string/multiply_not_num.wren
Normal file
@ -0,0 +1 @@
|
||||
"abc" * "not num" // expect runtime error: Count must be a non-negative integer.
|
||||
Reference in New Issue
Block a user