Skip to content

Commit

Permalink
this.Sprite.Main(...) or this.Game.MainEntry(...)
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Mar 8, 2024
1 parent 5566564 commit 766e6b2
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 16 deletions.
28 changes: 25 additions & 3 deletions cl/classfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,16 +298,38 @@ func gmxMainNarg(sig *types.Signature) int {
}

func hasMethod(o types.Object, name string) bool {
return findMethod(o, name) != nil
}

func findMethod(o types.Object, name string) *types.Func {
if obj, ok := o.(*types.TypeName); ok {
if t, ok := obj.Type().(*types.Named); ok {
for i, n := 0, t.NumMethods(); i < n; i++ {
if t.Method(i).Name() == name {
return true
f := t.Method(i)
if f.Name() == name {
return f
}
}
}
}
return false
return nil
}

func makeMainSig(recv *types.Var, f *types.Func) *types.Signature {
const (
paramNameTempl = "_gop_arg0"
)
sig := f.Type().(*types.Signature)
in := sig.Params()
nin := in.Len()
pkg := recv.Pkg()
params := make([]*types.Var, nin)
paramName := []byte(paramNameTempl)
for i := 0; i < nin; i++ {
paramName[len(paramNameTempl)-1] = byte('0' + i)
params[i] = types.NewParam(token.NoPos, pkg, string(paramName), in.At(i).Type())
}
return types.NewSignatureType(recv, nil, nil, types.NewTuple(params...), nil, false)
}

// -----------------------------------------------------------------------------
45 changes: 36 additions & 9 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,12 @@ type blockCtx struct {
tlookup *typeParamLookup
c2goBase string // default is `github.com/goplus/`
relBaseDir string
classRecv *ast.FieldList // available when gmxSettings != nil
fileScope *types.Scope // only valid when isGopFile
rec *goxRecorder

classRecv *ast.FieldList // available when isClass
baseClass types.Object // available when isClass

fileScope *types.Scope // available when isGopFile
rec *goxRecorder

fileLine bool
isClass bool
Expand Down Expand Up @@ -742,12 +745,14 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
}
if f.IsProj {
o := proj.game
ctx.baseClass = o
baseTypeName, baseType = o.Name(), o.Type()
if proj.gameIsPtr {
baseType = types.NewPointer(baseType)
}
} else {
o := proj.sprite[c.ext]
ctx.baseClass = o
baseTypeName, baseType, spxClass = o.Name(), o.Type(), true
}
}
Expand Down Expand Up @@ -1215,8 +1220,17 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
log.Printf("==> Load method %v.%s\n", recv.Type(), name)
}
}
pkg := ctx.pkg
if d.Operator {
var pkg = ctx.pkg
var sigBase *types.Signature
if d.Shadow {
if recv != nil {
if base := ctx.baseClass; base != nil {
if f := findMethod(base, name); f != nil {
sigBase = makeMainSig(recv, f)
}
}
}
} else if d.Operator {
if recv != nil { // binary op
if v, ok := binaryGopNames[name]; ok {
name = v
Expand All @@ -1232,7 +1246,10 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
}
}
}
sig := toFuncType(ctx, d.Type, recv, d)
sig := sigBase
if sig == nil {
sig = toFuncType(ctx, d.Type, recv, d)
}
fn, err := pkg.NewFuncWith(d.Name.Pos(), name, sig, func() token.Pos {
return d.Recv.List[0].Type.Pos()
})
Expand All @@ -1253,11 +1270,11 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
file := pkg.CurFile()
ctx.inits = append(ctx.inits, func() { // interface issue: #795
old := pkg.RestoreCurFile(file)
loadFuncBody(ctx, fn, body, d)
loadFuncBody(ctx, fn, body, sigBase, d)
pkg.RestoreCurFile(old)
})
} else {
loadFuncBody(ctx, fn, body, d)
loadFuncBody(ctx, fn, body, nil, d)
}
}
}
Expand Down Expand Up @@ -1316,8 +1333,18 @@ var unaryGopNames = map[string]string{
"<-": "Gop_Recv",
}

func loadFuncBody(ctx *blockCtx, fn *gox.Func, body *ast.BlockStmt, src ast.Node) {
func loadFuncBody(ctx *blockCtx, fn *gox.Func, body *ast.BlockStmt, sigBase *types.Signature, src ast.Node) {
cb := fn.BodyStart(ctx.pkg, body)
if sigBase != nil {
// this.Sprite.Main(...) or this.Game.MainEntry(...)
cb.VarVal("this").MemberVal(ctx.baseClass.Name()).MemberVal(fn.Name())
params := sigBase.Params()
n := params.Len()
for i := 0; i < n; i++ {
cb.Val(params.At(i))
}
cb.Call(n).EndStmt()
}
compileStmts(ctx, body.List)
if rec := ctx.recorder(); rec != nil {
switch fn := src.(type) {
Expand Down
3 changes: 2 additions & 1 deletion cl/compile_spx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ func (this *Game) MainEntry() {
func main() {
spx3.Gopt_Game_Main(new(Game), new(Kai))
}
func (this *Kai) Main() {
func (this *Kai) Main(_gop_arg0 string) {
this.Sprite.Main(_gop_arg0)
fmt.Println(jwt.Token("Hi"))
}
`, "main_spx.gox", "Kai_spx.gox")
Expand Down
2 changes: 1 addition & 1 deletion cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ func compileFuncLit(ctx *blockCtx, v *ast.FuncLit) {
}
fn := cb.NewClosureWith(sig)
if body := v.Body; body != nil {
loadFuncBody(ctx, fn, body, v)
loadFuncBody(ctx, fn, body, nil, v)
cb.SetComments(comments, once)
}
}
Expand Down
4 changes: 2 additions & 2 deletions cl/internal/spx3/spx3.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (p *Sprite) Name() string {
return "sprite"
}

func (p *Sprite) initSprite(name string) {}
func (p *Sprite) Main(name string) {}

func Gopt_Game_Main(game interface{ initGame() }, workers ...interface{ initSprite(name string) }) {
func Gopt_Game_Main(game interface{ initGame() }, workers ...interface{ Main(name string) }) {
}

0 comments on commit 766e6b2

Please sign in to comment.