Skip to content

Commit 766e6b2

Browse files
committed
this.Sprite.Main(...) or this.Game.MainEntry(...)
1 parent 5566564 commit 766e6b2

File tree

5 files changed

+66
-16
lines changed

5 files changed

+66
-16
lines changed

cl/classfile.go

+25-3
Original file line numberDiff line numberDiff line change
@@ -298,16 +298,38 @@ func gmxMainNarg(sig *types.Signature) int {
298298
}
299299

300300
func hasMethod(o types.Object, name string) bool {
301+
return findMethod(o, name) != nil
302+
}
303+
304+
func findMethod(o types.Object, name string) *types.Func {
301305
if obj, ok := o.(*types.TypeName); ok {
302306
if t, ok := obj.Type().(*types.Named); ok {
303307
for i, n := 0, t.NumMethods(); i < n; i++ {
304-
if t.Method(i).Name() == name {
305-
return true
308+
f := t.Method(i)
309+
if f.Name() == name {
310+
return f
306311
}
307312
}
308313
}
309314
}
310-
return false
315+
return nil
316+
}
317+
318+
func makeMainSig(recv *types.Var, f *types.Func) *types.Signature {
319+
const (
320+
paramNameTempl = "_gop_arg0"
321+
)
322+
sig := f.Type().(*types.Signature)
323+
in := sig.Params()
324+
nin := in.Len()
325+
pkg := recv.Pkg()
326+
params := make([]*types.Var, nin)
327+
paramName := []byte(paramNameTempl)
328+
for i := 0; i < nin; i++ {
329+
paramName[len(paramNameTempl)-1] = byte('0' + i)
330+
params[i] = types.NewParam(token.NoPos, pkg, string(paramName), in.At(i).Type())
331+
}
332+
return types.NewSignatureType(recv, nil, nil, types.NewTuple(params...), nil, false)
311333
}
312334

313335
// -----------------------------------------------------------------------------

cl/compile.go

+36-9
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,12 @@ type blockCtx struct {
369369
tlookup *typeParamLookup
370370
c2goBase string // default is `github.com/goplus/`
371371
relBaseDir string
372-
classRecv *ast.FieldList // available when gmxSettings != nil
373-
fileScope *types.Scope // only valid when isGopFile
374-
rec *goxRecorder
372+
373+
classRecv *ast.FieldList // available when isClass
374+
baseClass types.Object // available when isClass
375+
376+
fileScope *types.Scope // available when isGopFile
377+
rec *goxRecorder
375378

376379
fileLine bool
377380
isClass bool
@@ -742,12 +745,14 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
742745
}
743746
if f.IsProj {
744747
o := proj.game
748+
ctx.baseClass = o
745749
baseTypeName, baseType = o.Name(), o.Type()
746750
if proj.gameIsPtr {
747751
baseType = types.NewPointer(baseType)
748752
}
749753
} else {
750754
o := proj.sprite[c.ext]
755+
ctx.baseClass = o
751756
baseTypeName, baseType, spxClass = o.Name(), o.Type(), true
752757
}
753758
}
@@ -1215,8 +1220,17 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
12151220
log.Printf("==> Load method %v.%s\n", recv.Type(), name)
12161221
}
12171222
}
1218-
pkg := ctx.pkg
1219-
if d.Operator {
1223+
var pkg = ctx.pkg
1224+
var sigBase *types.Signature
1225+
if d.Shadow {
1226+
if recv != nil {
1227+
if base := ctx.baseClass; base != nil {
1228+
if f := findMethod(base, name); f != nil {
1229+
sigBase = makeMainSig(recv, f)
1230+
}
1231+
}
1232+
}
1233+
} else if d.Operator {
12201234
if recv != nil { // binary op
12211235
if v, ok := binaryGopNames[name]; ok {
12221236
name = v
@@ -1232,7 +1246,10 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
12321246
}
12331247
}
12341248
}
1235-
sig := toFuncType(ctx, d.Type, recv, d)
1249+
sig := sigBase
1250+
if sig == nil {
1251+
sig = toFuncType(ctx, d.Type, recv, d)
1252+
}
12361253
fn, err := pkg.NewFuncWith(d.Name.Pos(), name, sig, func() token.Pos {
12371254
return d.Recv.List[0].Type.Pos()
12381255
})
@@ -1253,11 +1270,11 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
12531270
file := pkg.CurFile()
12541271
ctx.inits = append(ctx.inits, func() { // interface issue: #795
12551272
old := pkg.RestoreCurFile(file)
1256-
loadFuncBody(ctx, fn, body, d)
1273+
loadFuncBody(ctx, fn, body, sigBase, d)
12571274
pkg.RestoreCurFile(old)
12581275
})
12591276
} else {
1260-
loadFuncBody(ctx, fn, body, d)
1277+
loadFuncBody(ctx, fn, body, nil, d)
12611278
}
12621279
}
12631280
}
@@ -1316,8 +1333,18 @@ var unaryGopNames = map[string]string{
13161333
"<-": "Gop_Recv",
13171334
}
13181335

1319-
func loadFuncBody(ctx *blockCtx, fn *gox.Func, body *ast.BlockStmt, src ast.Node) {
1336+
func loadFuncBody(ctx *blockCtx, fn *gox.Func, body *ast.BlockStmt, sigBase *types.Signature, src ast.Node) {
13201337
cb := fn.BodyStart(ctx.pkg, body)
1338+
if sigBase != nil {
1339+
// this.Sprite.Main(...) or this.Game.MainEntry(...)
1340+
cb.VarVal("this").MemberVal(ctx.baseClass.Name()).MemberVal(fn.Name())
1341+
params := sigBase.Params()
1342+
n := params.Len()
1343+
for i := 0; i < n; i++ {
1344+
cb.Val(params.At(i))
1345+
}
1346+
cb.Call(n).EndStmt()
1347+
}
13211348
compileStmts(ctx, body.List)
13221349
if rec := ctx.recorder(); rec != nil {
13231350
switch fn := src.(type) {

cl/compile_spx_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,8 @@ func (this *Game) MainEntry() {
486486
func main() {
487487
spx3.Gopt_Game_Main(new(Game), new(Kai))
488488
}
489-
func (this *Kai) Main() {
489+
func (this *Kai) Main(_gop_arg0 string) {
490+
this.Sprite.Main(_gop_arg0)
490491
fmt.Println(jwt.Token("Hi"))
491492
}
492493
`, "main_spx.gox", "Kai_spx.gox")

cl/expr.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ func compileFuncLit(ctx *blockCtx, v *ast.FuncLit) {
904904
}
905905
fn := cb.NewClosureWith(sig)
906906
if body := v.Body; body != nil {
907-
loadFuncBody(ctx, fn, body, v)
907+
loadFuncBody(ctx, fn, body, nil, v)
908908
cb.SetComments(comments, once)
909909
}
910910
}

cl/internal/spx3/spx3.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func (p *Sprite) Name() string {
3838
return "sprite"
3939
}
4040

41-
func (p *Sprite) initSprite(name string) {}
41+
func (p *Sprite) Main(name string) {}
4242

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

0 commit comments

Comments
 (0)