提交 d55e65ab 编写于 作者: 3 3dgen

支持匿名接口

上级 a5a6396e
......@@ -49,6 +49,10 @@ func main() {
//i2 := ni.(I2) //接口互转,由于v2未实现I2,这会触发异常
//i2.f2()
var anoi interface{ f() } = &v1 //具体类型到匿名接口
doConcreteType(anoi) //匿名接口向具名接口转换
anoi.f()
}
func doConcreteType(i I1) {
......
......@@ -3,6 +3,8 @@
package compiler_wat
import (
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir"
"wa-lang.org/wa/internal/loader"
"wa-lang.org/wa/internal/logger"
......@@ -16,6 +18,9 @@ type typeLib struct {
typeTable map[string]*wir.ValueType
pendingMethods []*ssa.Function
anonStructCount int
anonInterfaceCount int
}
func newTypeLib(m *wir.Module, prog *loader.Program) *typeLib {
......@@ -115,6 +120,7 @@ func (tLib *typeLib) compile(from types.Type) wir.ValueType {
pkg_name, _ := wir.GetPkgMangleName(t.Obj().Pkg().Path())
obj_name := wir.GenSymbolName(t.Obj().Name())
tStruct, found := tLib.module.GenValueType_Struct(pkg_name + "." + obj_name)
newType = tStruct
if !found {
for i := 0; i < ut.NumFields(); i++ {
sf := ut.Field(i)
......@@ -130,12 +136,7 @@ func (tLib *typeLib) compile(from types.Type) wir.ValueType {
tStruct.Finish()
}
newType = tStruct
case *types.Interface:
if ut.NumMethods() == 0 {
return tLib.compile(ut)
}
pkg_name := ""
if t.Obj().Pkg() != nil {
pkg_name, _ = wir.GetPkgMangleName(t.Obj().Pkg().Path())
......@@ -177,41 +178,48 @@ func (tLib *typeLib) compile(from types.Type) wir.ValueType {
newType = tLib.module.GenValueType_Closure(tLib.GenFnSig(t))
case *types.Interface:
if t.NumMethods() != 0 {
panic("NumMethods of interface{} != 0")
}
newType = tLib.module.GenValueType_Interface("interface")
newType = tLib.module.GenValueType_Interface("i`" + strconv.Itoa(tLib.anonInterfaceCount) + "`")
tLib.anonInterfaceCount++
case *types.Struct:
sname := "`"
var fields []*wir.StructField
for i := 0; i < t.NumFields(); i++ {
sf := t.Field(i)
dtyp := tLib.compile(sf.Type())
var fname string
if sf.Embedded() {
fname = "$" + dtyp.Name()
} else {
fname = sf.Name()
}
df := tLib.module.NewStructField(fname, dtyp)
fields = append(fields, df)
for i := 0; i < t.NumMethods(); i++ {
var method wir.Method
method.Sig = tLib.GenFnSig(t.Method(i).Type().(*types.Signature))
sname += fname + "@" + dtyp.Name()
if i != t.NumFields()-1 {
sname += "|"
}
method.Name = t.Method(i).Name()
var fnSig wir.FnSig
fnSig.Params = append(fnSig.Params, tLib.module.GenValueType_SPtr(tLib.module.VOID))
fnSig.Params = append(fnSig.Params, method.Sig.Params...)
fnSig.Results = method.Sig.Results
method.FullFnName = tLib.module.AddFnSig(&fnSig)
newType.AddMethod(method)
}
tStruct, found := tLib.module.GenValueType_Struct(sname)
case *types.Struct:
tStruct, found := tLib.module.GenValueType_Struct("s`" + strconv.Itoa(tLib.anonStructCount) + "`")
newType = tStruct
tLib.anonStructCount++
if !found {
for _, f := range fields {
tStruct.AppendField(f)
for i := 0; i < t.NumFields(); i++ {
sf := t.Field(i)
dtyp := tLib.compile(sf.Type())
var fname string
if sf.Embedded() {
fname = "$" + dtyp.Name()
} else {
fname = sf.Name()
}
df := tLib.module.NewStructField(fname, dtyp)
tStruct.AppendField(df)
}
tStruct.Finish()
} else {
panic("???")
}
newType = tStruct
default:
logger.Fatalf("Todo:%T", t)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册