Browse Source

compiler,runtime: implement []rune to string conversion

This is used by a few packages in the standard library, at least
compress/gzip and regexp/syntax.
pull/493/head
Ayke van Laethem 5 years ago
committed by Ron Evans
parent
commit
fd3309afa8
  1. 2
      compiler/compiler.go
  2. 24
      src/runtime/string.go
  3. 5
      testdata/string.go
  4. 1
      testdata/string.txt

2
compiler/compiler.go

@ -2415,6 +2415,8 @@ func (c *Compiler) parseConvert(typeFrom, typeTo types.Type, value llvm.Value, p
switch typeFrom.Elem().(*types.Basic).Kind() { switch typeFrom.Elem().(*types.Basic).Kind() {
case types.Byte: case types.Byte:
return c.createRuntimeCall("stringFromBytes", []llvm.Value{value}, ""), nil return c.createRuntimeCall("stringFromBytes", []llvm.Value{value}, ""), nil
case types.Rune:
return c.createRuntimeCall("stringFromRunes", []llvm.Value{value}, ""), nil
default: default:
return llvm.Value{}, c.makeError(pos, "todo: convert to string: "+typeFrom.String()) return llvm.Value{}, c.makeError(pos, "todo: convert to string: "+typeFrom.String())
} }

24
src/runtime/string.go

@ -89,6 +89,30 @@ func stringToBytes(x _string) (slice struct {
return return
} }
// Convert a []rune slice to a string.
func stringFromRunes(runeSlice []rune) (s _string) {
// Count the number of characters that will be in the string.
for _, r := range runeSlice {
_, numBytes := encodeUTF8(r)
s.length += numBytes
}
// Allocate memory for the string.
s.ptr = (*byte)(alloc(s.length))
// Encode runes to UTF-8 and store the resulting bytes in the string.
index := uintptr(0)
for _, r := range runeSlice {
array, numBytes := encodeUTF8(r)
for _, c := range array[:numBytes] {
*(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(s.ptr)) + index)) = c
index++
}
}
return
}
// Convert a string to []rune slice. // Convert a string to []rune slice.
func stringToRunes(s string) []rune { func stringToRunes(s string) []rune {
var n = 0 var n = 0

5
testdata/string.go

@ -13,7 +13,12 @@ func testStringToRunes() {
} }
} }
func testRunesToString(r []rune) {
println("string from runes:", string(r))
}
func main() { func main() {
testRangeString() testRangeString()
testStringToRunes() testStringToRunes()
testRunesToString([]rune{97, 98, 99, 252, 162, 8364, 66376, 176, 120})
} }

1
testdata/string.txt

@ -16,3 +16,4 @@
6 66376 6 66376
7 176 7 176
8 120 8 120
string from runes: abcü¢€𐍈°x

Loading…
Cancel
Save