Skip to content

Commit

Permalink
Merge pull request #1736 from xushiwei/t
Browse files Browse the repository at this point in the history
Gop_Exec support
  • Loading branch information
xushiwei authored Feb 13, 2024
2 parents 634aa46 + 99cbe24 commit 03d1acb
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 14 deletions.
24 changes: 24 additions & 0 deletions cl/compile_spx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,30 @@ func (this *index) onInit() {
`)
}

func TestSpxGopExec(t *testing.T) {
gopSpxTest(t, `
vim "a.txt"
`, ``, `package main
import "github.com/goplus/gop/cl/internal/spx"
type bar struct {
spx.Sprite
*index
}
type index struct {
*spx.MyGame
}
func (this *index) MainEntry() {
this.Gop_Exec("vim", "a.txt")
}
func main() {
spx.Gopt_MyGame_Main(new(index))
}
`)
}

func TestSpxMethod(t *testing.T) {
gopSpxTestEx(t, `
func onInit() {
Expand Down
47 changes: 33 additions & 14 deletions cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,49 +64,53 @@ const (
clIdentGoto
clCallWithTwoValue
clCommandWithoutArgs
clCommandIdent
)

const (
objNormal = iota
objPkgRef
objCPkgRef
objGopExec
)

const errorPkgPath = "github.com/qiniu/x/errors"

func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (pkg gox.PkgRef, kind int) {
fvalue := (flags&clIdentSelectorExpr) != 0 || (flags&clIdentLHS) == 0
cb := ctx.cb
name := ident.Name
if name == "_" {
if fvalue {
panic(ctx.newCodeError(ident.Pos(), "cannot use _ as value"))
}
ctx.cb.VarRef(nil)
cb.VarRef(nil)
return
}

var recv *types.Var
var oldo types.Object
scope := ctx.pkg.Types.Scope()
at, o := ctx.cb.Scope().LookupParent(name, token.NoPos)
at, o := cb.Scope().LookupParent(name, token.NoPos)
if o != nil {
if at != scope && at != types.Universe { // local object
goto find
}
}

if ctx.isClass { // in a Go+ class file
if fn := ctx.cb.Func(); fn != nil {
if fn := cb.Func(); fn != nil {
sig := fn.Ancestor().Type().(*types.Signature)
if recv := sig.Recv(); recv != nil {
ctx.cb.Val(recv)
if recv = sig.Recv(); recv != nil {
cb.Val(recv)
chkFlag := flags // &^ clCommandWithoutArgs (TODO: why?)
if chkFlag&clIdentSelectorExpr != 0 {
chkFlag = clIdentCanAutoCall
}
if compileMember(ctx, ident, name, chkFlag) == nil { // class member object
return
}
ctx.cb.InternalStack().PopN(1)
cb.InternalStack().PopN(1)
}
}
}
Expand Down Expand Up @@ -150,6 +154,12 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (pkg gox.PkgRef, k
}
oldo, o = o, obj
} else if o == nil {
if (clCommandIdent&flags) != 0 && recv != nil { // for support Gop_Exec, see TestSpxGopExec
if _, e := cb.Val(recv).Member("Gop_Exec", gox.MemberFlagVal, ident); e == nil {
kind = objGopExec
return
}
}
if (clIdentGoto & flags) != 0 {
l := ident.Obj.Data.(*ast.Ident)
panic(ctx.newCodeErrorf(l.Pos(), "label %v is not defined", l.Name))
Expand All @@ -159,13 +169,13 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (pkg gox.PkgRef, k

find:
if fvalue {
ctx.cb.Val(o, ident)
cb.Val(o, ident)
} else {
ctx.cb.VarRef(o, ident)
cb.VarRef(o, ident)
}
if rec := ctx.recorder(); rec != nil {
e := ctx.cb.Get(-1)
if oldo != nil && gox.IsTypeEx(e.Type) {
e := cb.Get(-1)
if oldo != nil && gox.IsTypeEx(e.Type) { // for builtin object
rec.recordIdent(ctx, ident, oldo)
return
}
Expand Down Expand Up @@ -564,8 +574,17 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) {
var ifn *ast.Ident
switch fn := v.Fun.(type) {
case *ast.Ident:
compileIdent(ctx, fn, clIdentAllowBuiltin|inFlags)
ifn = fn
if v.IsCommand() { // for support Gop_Exec, see TestSpxGopExec
inFlags |= clCommandIdent
}
if _, kind := compileIdent(ctx, fn, clIdentAllowBuiltin|inFlags); kind == objGopExec {
args := make([]ast.Expr, 1, len(v.Args)+1)
args[0] = &ast.BasicLit{ValuePos: fn.NamePos, Kind: token.STRING, Value: strconv.Quote(fn.Name)}
args = append(args, v.Args...)
v = &ast.CallExpr{Fun: fn, Args: args, Ellipsis: v.Ellipsis, NoParenEnd: v.NoParenEnd}
} else {
ifn = fn
}
case *ast.SelectorExpr:
compileSelectorExpr(ctx, fn, 0)
case *ast.ErrWrapExpr:
Expand Down Expand Up @@ -615,7 +634,7 @@ func mayBuiltin(ctx *blockCtx, ifn *ast.Ident, v *ast.CallExpr, flags gox.InstrF
switch name := ifn.Name; name {
case "new", "delete":
cb := ctx.cb
cb.InternalStack().Pop()
cb.InternalStack().PopN(1)
o := ctx.pkg.Builtin().Ref(name)
cb.Val(o, ifn)
for _, arg := range v.Args {
Expand Down Expand Up @@ -665,7 +684,7 @@ func compileCallArgs(fn *fnType, ctx *blockCtx, v *ast.CallExpr, ellipsis bool,
}
typetype := fn.typetype && t != nil
if typetype {
stk.Pop()
stk.PopN(1)
}
compileSliceLit(ctx, expr, t)
if typetype {
Expand Down
3 changes: 3 additions & 0 deletions cl/internal/spx/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ type MyGame struct {
func Gopt_MyGame_Main(game interface{}) {
}

func (p *MyGame) Gop_Exec(name string, args ...any) {
}

func (p *MyGame) InitGameApp(args ...string) {
}

Expand Down

0 comments on commit 03d1acb

Please sign in to comment.