Implement string concatenation

Этот коммит содержится в:
Ayke van Laethem 2018-08-29 22:10:46 +02:00
родитель c912091f8b
коммит 8b95b869ab
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED
2 изменённых файлов: 28 добавлений и 1 удалений

Просмотреть файл

@ -1835,7 +1835,13 @@ func (c *Compiler) parseBinOp(frame *Frame, binop *ssa.BinOp) (llvm.Value, error
} }
switch binop.Op { switch binop.Op {
case token.ADD: // + case token.ADD: // +
if typ, ok := binop.X.Type().(*types.Basic); ok && typ.Kind() == types.String {
// string concatenation
fn := c.mod.NamedFunction("runtime.stringConcat")
return c.builder.CreateCall(fn, []llvm.Value{x, y}, ""), nil
} else {
return c.builder.CreateAdd(x, y, ""), nil return c.builder.CreateAdd(x, y, ""), nil
}
case token.SUB: // - case token.SUB: // -
return c.builder.CreateSub(x, y, ""), nil return c.builder.CreateSub(x, y, ""), nil
case token.MUL: // * case token.MUL: // *

Просмотреть файл

@ -2,11 +2,17 @@ package runtime
// This file implements functions related to Go strings. // This file implements functions related to Go strings.
import (
"unsafe"
)
// The underlying struct for the Go string type.
type _string struct { type _string struct {
length lenType length lenType
ptr *uint8 ptr *uint8
} }
// Return true iff the strings match.
func stringEqual(x, y string) bool { func stringEqual(x, y string) bool {
if len(x) != len(y) { if len(x) != len(y) {
return false return false
@ -18,3 +24,18 @@ func stringEqual(x, y string) bool {
} }
return true return true
} }
// Add two strings together.
func stringConcat(x, y _string) _string {
if x.length == 0 {
return y
} else if y.length == 0 {
return x
} else {
length := uintptr(x.length + y.length)
buf := alloc(length)
memcpy(buf, unsafe.Pointer(x.ptr), uintptr(x.length))
memcpy(unsafe.Pointer(uintptr(buf)+uintptr(x.length)), unsafe.Pointer(y.ptr), uintptr(y.length))
return _string{lenType(length), (*uint8)(buf)}
}
}