Browse Source

Implement interfaces on the string type

pull/6/head
Ayke van Laethem 7 years ago
parent
commit
217c48f933
  1. 3
      src/examples/hello/hello.go
  2. 23
      tgo.go

3
src/examples/hello/hello.go

@ -24,6 +24,7 @@ func main() {
println("thing:", thing.String())
printItf(5)
printItf(byte('x'))
printItf("foo")
}
func strlen(s string) int {
@ -36,6 +37,8 @@ func printItf(val interface{}) {
println("is int:", val)
case byte:
println("is byte:", val)
case string:
println("is string:", val)
default:
println("is ?")
}

23
tgo.go

@ -654,8 +654,14 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
var itfValue llvm.Value
switch typ := expr.X.Type().(type) {
case *types.Basic:
itfValueType := llvm.PointerType(llvm.Int8Type(), 0)
if typ.Info() & types.IsInteger != 0 {
itfValue = c.builder.CreateIntToPtr(val, llvm.PointerType(llvm.Int8Type(), 0), "")
itfValue = c.builder.CreateIntToPtr(val, itfValueType, "")
} else if typ.Kind() == types.String {
// TODO: escape analysis
itfValue = c.builder.CreateMalloc(c.stringType, "")
c.builder.CreateStore(val, itfValue)
itfValue = c.builder.CreateBitCast(itfValue, itfValueType, "")
} else {
return llvm.Value{}, errors.New("todo: make interface: unknown basic type")
}
@ -689,7 +695,20 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
assertedTypeNum := c.getInterfaceType(expr.AssertedType)
actualTypeNum := c.builder.CreateExtractValue(itf, 0, "interface.type")
valuePtr := c.builder.CreateExtractValue(itf, 1, "interface.value")
value := c.builder.CreatePtrToInt(valuePtr, assertedType, "")
var value llvm.Value
switch typ := expr.AssertedType.(type) {
case *types.Basic:
if typ.Info() & types.IsInteger != 0 {
value = c.builder.CreatePtrToInt(valuePtr, assertedType, "")
} else if typ.Kind() == types.String {
valueStringPtr := c.builder.CreateBitCast(valuePtr, llvm.PointerType(c.stringType, 0), "")
value = c.builder.CreateLoad(valueStringPtr, "")
} else {
return llvm.Value{}, errors.New("todo: typeassert: unknown basic type")
}
default:
return llvm.Value{}, errors.New("todo: typeassert: unknown type")
}
commaOk := c.builder.CreateICmp(llvm.IntEQ, assertedTypeNum, actualTypeNum, "")
tuple := llvm.ConstStruct([]llvm.Value{llvm.Undef(assertedType), llvm.Undef(llvm.Int1Type())}, false) // create empty tuple
tuple = c.builder.CreateInsertValue(tuple, value, 0, "") // insert value

Loading…
Cancel
Save