diff --git a/compiler.go b/compiler.go index 0e47e766..540e800c 100644 --- a/compiler.go +++ b/compiler.go @@ -2066,7 +2066,18 @@ func (c *Compiler) parseConvert(typeFrom, typeTo types.Type, value llvm.Value) ( sizeFrom := c.targetData.TypeAllocSize(llvmTypeFrom) if typeTo.Kind() == types.String { - return llvm.Value{}, errors.New("todo: convert to string: " + typeFrom.String()) + switch typeFrom := typeFrom.Underlying().(type) { + case *types.Slice: + switch typeFrom.Elem().(*types.Basic).Kind() { + case types.Byte: + fn := c.mod.NamedFunction("runtime.stringFromBytes") + return c.builder.CreateCall(fn, []llvm.Value{value}, ""), nil + default: + return llvm.Value{}, errors.New("todo: convert to string: " + typeFrom.String()) + } + default: + return llvm.Value{}, errors.New("todo: convert to string: " + typeFrom.String()) + } } typeFrom := typeFrom.Underlying().(*types.Basic) diff --git a/src/runtime/string.go b/src/runtime/string.go index e1196509..52a1c89b 100644 --- a/src/runtime/string.go +++ b/src/runtime/string.go @@ -9,7 +9,7 @@ import ( // The underlying struct for the Go string type. type _string struct { length lenType - ptr *uint8 + ptr *byte } // Return true iff the strings match. @@ -36,6 +36,15 @@ func stringConcat(x, y _string) _string { 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)} + return _string{lenType(length), (*byte)(buf)} } } + +// Create a string from a []byte slice. +func stringFromBytes(x []byte) _string { + buf := alloc(uintptr(len(x))) + for i, c := range x { + *(*byte)(unsafe.Pointer(uintptr(buf) + uintptr(i))) = c + } + return _string{lenType(len(x)), (*byte)(buf)} +}