Merge branch '201703_split_replace' of https://github.com/JonesAndrew/wren into JonesAndrew-201703_split_replace

This commit is contained in:
Bob Nystrom
2017-03-15 07:04:56 -07:00
10 changed files with 158 additions and 0 deletions

View File

@ -129,6 +129,24 @@ negative to count backwards from the end of the string.
It is a runtime error if `search` is not a string or `start` is not an integer
index within the string's byte length.
### **split**(seperator)
Returns a list of one or more strings seperated by `seperator`.
:::wren
var string = "abc abc abc"
System.print(string.split(" ")) //> [abc, abc, abc]
It is a runtime error if `seperator` is not a string or is an empty string.
### **replace**(old, swap)
Returns a new string with all occurences of `old` replaced with `swap`.
:::wren
var string = "abc abc abc"
System.print(string.replace(" ", "")) //> abcabcabc
### **iterate**(iterator), **iteratorValue**(iterator)
Implements the [iterator protocol](../../control-flow.html#the-iterator-protocol)

View File

@ -132,6 +132,57 @@ class String is Sequence {
bytes { StringByteSequence.new(this) }
codePoints { StringCodePointSequence.new(this) }
split(delim) {
if (!(delim is String) || delim.isEmpty) {
Fiber.abort("Argument must be a non-empty string.")
}
var result = []
var last = 0
var index = 0
var delimSize = delim.byteCount_
var size = byteCount_
while (last < size && (index = indexOf(delim, last)) != -1) {
result.add(this[last...index])
last = index + delimSize
}
if (last < size) {
result.add(this[last..-1])
} else {
result.add("")
}
return result
}
replace(from, to) {
if (!(from is String) || from.isEmpty) {
Fiber.abort("From must be a non-empty string.")
} else if (!(to is String)) {
Fiber.abort("To must be a string.")
}
var result = ""
var last = 0
var index = 0
var fromSize = from.byteCount_
var size = byteCount_
while (last < size && (index = indexOf(from, last)) != -1) {
result = result + this[last...index] + to
last = index + fromSize
}
if (last < size) result = result + this[last..-1]
return result
}
*(count) {
if (!(count is Num) || !count.isInteger || count < 0) {
Fiber.abort("Count must be a non-negative integer.")

View File

@ -134,6 +134,57 @@ static const char* coreModuleSource =
" bytes { StringByteSequence.new(this) }\n"
" codePoints { StringCodePointSequence.new(this) }\n"
"\n"
" split(delim) {\n"
" if (!(delim is String) || delim.isEmpty) {\n"
" Fiber.abort(\"Argument must be a non-empty string.\")\n"
" }\n"
"\n"
" var result = []\n"
"\n"
" var last = 0\n"
" var index = 0\n"
"\n"
" var delimSize = delim.byteCount_\n"
" var size = byteCount_\n"
"\n"
" while (last < size && (index = indexOf(delim, last)) != -1) {\n"
" result.add(this[last...index])\n"
" last = index + delimSize\n"
" }\n"
"\n"
" if (last < size) {\n"
" result.add(this[last..-1])\n"
" } else {\n"
" result.add(\"\")\n"
" }\n"
" return result\n"
" }\n"
"\n"
" replace(from, to) {\n"
" if (!(from is String) || from.isEmpty) {\n"
" Fiber.abort(\"From must be a non-empty string.\")\n"
" } else if (!(to is String)) {\n"
" Fiber.abort(\"To must be a string.\")\n"
" }\n"
"\n"
" var result = \"\"\n"
"\n"
" var last = 0\n"
" var index = 0\n"
"\n"
" var fromSize = from.byteCount_\n"
" var size = byteCount_\n"
"\n"
" while (last < size && (index = indexOf(from, last)) != -1) {\n"
" result = result + this[last...index] + to\n"
" last = index + fromSize\n"
" }\n"
"\n"
" if (last < size) result = result + this[last..-1]\n"
"\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"

View File

@ -0,0 +1,17 @@
System.print("something".replace("some", "no")) // expect: nothing
System.print("something".replace("thing", "one")) // expect: someone
System.print("something".replace("ometh", "umm")) // expect: summing
System.print("something".replace("math", "ton")) // expect: something
// Multiple.
System.print("somethingsomething".replace("some", "no")) // expect: nothingnothing
System.print("abc abc abc".replace(" ", "")) // expect: abcabcabc
System.print("abcabcabc".replace("abc", "")) // expect:
// Non-ASCII.
System.print("søméthîng".replace("sømé", "nø")) // expect: nøthîng
System.print("søméthîng".replace("meth", "ton")) // expect: søméthîng
// 8-bit clean.
System.print("a\0b\0c".replace("\0", "")) // expect: abc
System.print("a\0b\0c".replace("b", "") == "a\0\0c") // expect: true

View File

@ -0,0 +1 @@
"foo".replace("", "f") // expect runtime error: From must be a non-empty string.

View File

@ -0,0 +1 @@
"foo".replace("o", 1) // expect runtime error: To must be a string.

View File

@ -0,0 +1 @@
"foo".replace(1, "o") // expect runtime error: From must be a non-empty string.

View File

@ -0,0 +1,16 @@
System.print("something".split("meth")) // expect: [so, ing]
System.print("something".split("some")) // expect: [, thing]
System.print("something".split("ing")) // expect: [someth, ]
System.print("something".split("math")) // expect: [something]
// Multiple.
System.print("somethingsomething".split("meth")) // expect: [so, ingso, ing]
System.print("abc abc abc".split(" ")) // expect: [abc, abc, abc]
System.print("abcabcabc".split("abc")) // expect: [, , , ]
// Non-ASCII.
System.print("søméthîng".split("méth")) // expect: [sø, îng]
System.print("søméthîng".split("meth")) // expect: [søméthîng]
// 8-bit clean.
System.print("a\0b\0c".split("\0")) // expect: [a, b, c]

View File

@ -0,0 +1 @@
"foo".split(1) // expect runtime error: Argument must be a non-empty string.

View File

@ -0,0 +1 @@
"foo".split("") // expect runtime error: Argument must be a non-empty string.