Implement interfaces on the string type
Этот коммит содержится в:
родитель
fc2eee4ee8
коммит
217c48f933
2 изменённых файлов: 24 добавлений и 2 удалений
|
@ -24,6 +24,7 @@ func main() {
|
||||||
println("thing:", thing.String())
|
println("thing:", thing.String())
|
||||||
printItf(5)
|
printItf(5)
|
||||||
printItf(byte('x'))
|
printItf(byte('x'))
|
||||||
|
printItf("foo")
|
||||||
}
|
}
|
||||||
|
|
||||||
func strlen(s string) int {
|
func strlen(s string) int {
|
||||||
|
@ -36,6 +37,8 @@ func printItf(val interface{}) {
|
||||||
println("is int:", val)
|
println("is int:", val)
|
||||||
case byte:
|
case byte:
|
||||||
println("is byte:", val)
|
println("is byte:", val)
|
||||||
|
case string:
|
||||||
|
println("is string:", val)
|
||||||
default:
|
default:
|
||||||
println("is ?")
|
println("is ?")
|
||||||
}
|
}
|
||||||
|
|
23
tgo.go
23
tgo.go
|
@ -654,8 +654,14 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||||
var itfValue llvm.Value
|
var itfValue llvm.Value
|
||||||
switch typ := expr.X.Type().(type) {
|
switch typ := expr.X.Type().(type) {
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
|
itfValueType := llvm.PointerType(llvm.Int8Type(), 0)
|
||||||
if typ.Info() & types.IsInteger != 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 {
|
} else {
|
||||||
return llvm.Value{}, errors.New("todo: make interface: unknown basic type")
|
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)
|
assertedTypeNum := c.getInterfaceType(expr.AssertedType)
|
||||||
actualTypeNum := c.builder.CreateExtractValue(itf, 0, "interface.type")
|
actualTypeNum := c.builder.CreateExtractValue(itf, 0, "interface.type")
|
||||||
valuePtr := c.builder.CreateExtractValue(itf, 1, "interface.value")
|
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, "")
|
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 := llvm.ConstStruct([]llvm.Value{llvm.Undef(assertedType), llvm.Undef(llvm.Int1Type())}, false) // create empty tuple
|
||||||
tuple = c.builder.CreateInsertValue(tuple, value, 0, "") // insert value
|
tuple = c.builder.CreateInsertValue(tuple, value, 0, "") // insert value
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче