Skip to content

Commit

Permalink
Merge pull request #894 from xushiwei/q
Browse files Browse the repository at this point in the history
support function instruction
  • Loading branch information
xushiwei committed Nov 15, 2021
2 parents 276f00f + 910c95a commit f7ac2c9
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 110 deletions.
92 changes: 2 additions & 90 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package ast

import (
"go/ast"
"strings"

"github.com/goplus/gop/token"
)
Expand Down Expand Up @@ -56,99 +55,12 @@ type Decl interface {
// Comments

// A Comment node represents a single //-style 、#-style or /*-style comment.
type Comment struct {
Slash token.Pos // position of "/" or # starting the comment
Text string // comment text (excluding '\n' for //-style comments)
}

// Pos returns position of first character belonging to the node.
func (c *Comment) Pos() token.Pos { return c.Slash }

// End returns position of first character immediately after the node.
func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
type Comment = ast.Comment

// A CommentGroup represents a sequence of comments
// with no other tokens and no empty lines between.
//
type CommentGroup struct {
List []*Comment // len(List) > 0
}

// Pos returns position of first character belonging to the node.
func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() }

// End returns position of first character immediately after the node.
func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }

func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }

func stripTrailingWhitespace(s string) string {
i := len(s)
for i > 0 && isWhitespace(s[i-1]) {
i--
}
return s[0:i]
}

// Text returns the text of the comment.
// Comment markers (//, /*, and */), the first space of a line comment, and
// leading and trailing empty lines are removed. Multiple empty lines are
// reduced to one, and trailing space on lines is trimmed. Unless the result
// is empty, it is newline-terminated.
//
func (g *CommentGroup) Text() string {
if g == nil {
return ""
}
comments := make([]string, len(g.List))
for i, c := range g.List {
comments[i] = c.Text
}

lines := make([]string, 0, 10) // most comments are less than 10 lines
for _, c := range comments {
// Remove comment markers.
// The parser has given us exactly the comment text.
switch c[1] {
case '/':
//-style comment (no newline at the end)
c = c[2:]
// strip first space - required for Example tests
if len(c) > 0 && c[0] == ' ' {
c = c[1:]
}
case '*':
/*-style comment */
c = c[2 : len(c)-2]
}

// Split on newlines.
cl := strings.Split(c, "\n")

// Walk lines, stripping trailing white space and adding to list.
for _, l := range cl {
lines = append(lines, stripTrailingWhitespace(l))
}
}

// Remove leading blank lines; convert runs of
// interior blank lines to a single blank line.
n := 0
for _, line := range lines {
if line != "" || n > 0 && lines[n-1] != "" {
lines[n] = line
n++
}
}
lines = lines[0:n]

// Add final "" entry to get trailing newline from Join.
if n > 0 && lines[n-1] != "" {
lines = append(lines, "")
}

return strings.Join(lines, "\n")
}
type CommentGroup = ast.CommentGroup

// ----------------------------------------------------------------------------
// Expressions and types
Expand Down
3 changes: 3 additions & 0 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,9 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl) {
ctx.handleErr(err)
return
}
if d.Doc != nil {
fn.SetComments(d.Doc)
}
if body := d.Body; body != nil {
if recv != nil {
ctx.inits = append(ctx.inits, func() { // interface issue: #795
Expand Down
16 changes: 15 additions & 1 deletion cl/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func gopClTest(t *testing.T, gopcode, expected string, cachefile ...string) {
defer cl.SetDisableRecover(false)

fs := parsertest.NewSingleFileFS("/foo", "bar.gop", gopcode)
pkgs, err := parser.ParseFSDir(gblFset, fs, "/foo", nil, 0)
pkgs, err := parser.ParseFSDir(gblFset, fs, "/foo", nil, parser.ParseComments)
if err != nil {
scanner.PrintError(os.Stderr, err)
t.Fatal("ParseFSDir:", err)
Expand Down Expand Up @@ -3211,3 +3211,17 @@ func main() {
}
`)
}

func TestGoInstr(t *testing.T) {
gopClTest(t, `package main
//go:noinline
//go:uintptrescapes
func test(s string, p, q uintptr, rest ...uintptr) int {
}`, `package main
//go:noinline
//go:uintptrescapes
func test(s string, p uintptr, q uintptr, rest ...uintptr) int {
}
`)
}
2 changes: 1 addition & 1 deletion cmd/gengo/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (p *Runner) GenGoPkg(pkgDir string, base *cl.Config) (err error) {
if conf.Fset == nil {
conf.Fset = token.NewFileSet()
}
pkgs, err := parser.ParseDir(conf.Fset, pkgDir, nil, 0)
pkgs, err := parser.ParseDir(conf.Fset, pkgDir, nil, parser.ParseComments)
if err != nil {
return p.addError(pkgDir, "parse", err)
}
Expand Down
9 changes: 3 additions & 6 deletions cmd/goptestgo/goptestgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,11 @@ var (
"issue15071.dir": {}, // dir
"issue29612.dir": {},
"issue31959.dir": {},
"issue24491a.go": {}, // instruction
"issue24491b.go": {},
"issue29504.go": {},
"issue17381.go": {},
"issue29504.go": {}, // line
"issue18149.go": {},
"issue22662.go": {},
"issue27201.go": {},
"issue40954.go": {},
"issue40954.go": {}, // type instruction
"nilptr_aix.go": {},
"inline_literal.go": {},
"returntype.go": {}, // not a problem
Expand Down Expand Up @@ -99,7 +96,7 @@ func gopTestRunGo(dir string) {
return nil
}
log.Println("==> gop run -gop -v", file)
RunGopCmd("", "run", "-nr", "-gop", file)
RunGopCmd("", "run", "-nr", "-rtoe", "-gop", file)
return nil
})
}
Expand Down
22 changes: 20 additions & 2 deletions cmd/internal/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,15 @@ var (
flagQuiet = flag.Bool("quiet", false, "don't generate any compiling stage log")
flagDebug = flag.Bool("debug", false, "set log level to debug")
flagNorun = flag.Bool("nr", false, "don't run if no change")
flagRTOE = flag.Bool("rtoe", false, "remove tempfile on error")
flagGop = flag.Bool("gop", false, "parse a .go file as a .gop file")
flagProf = flag.Bool("prof", false, "do profile and generate profile report")
)

const (
parserMode = parser.ParseComments
)

func init() {
Cmd.Run = runCmd
}
Expand Down Expand Up @@ -132,12 +137,13 @@ func runCmd(cmd *base.Command, args []string) {
var isDirty bool
var srcDir, file, gofile string
var pkgs map[string]*ast.Package
onExit = nil
if isDir {
srcDir = src
gofile = src + "/gop_autogen.go"
isDirty = true // TODO: check if code changed
if isDirty {
pkgs, err = parser.ParseDir(fset, src, nil, 0)
pkgs, err = parser.ParseDir(fset, src, nil, parserMode)
} else if *flagNorun {
return
}
Expand All @@ -149,6 +155,11 @@ func runCmd(cmd *base.Command, args []string) {
dir := os.Getenv("HOME") + "/.gop/run"
os.MkdirAll(dir, 0755)
gofile = dir + "/g" + base64.RawURLEncoding.EncodeToString(hash[:]) + file
if *flagRTOE { // remove tempfile on error
onExit = func() {
os.Remove(gofile)
}
}
} else if hasMultiFiles(srcDir, ".gop") {
gofile = filepath.Join(srcDir, "gop_autogen_"+file+".go")
} else {
Expand All @@ -160,7 +171,7 @@ func runCmd(cmd *base.Command, args []string) {
fmt.Println("==> GenGo to", gofile)
}
if *flagGop {
pkgs, err = parser.Parse(fset, src, nil, 0)
pkgs, err = parser.Parse(fset, src, nil, parserMode)
} else {
pkgs, err = parser.Parse(fset, src, nil, 0) // TODO: only to check dependencies
}
Expand Down Expand Up @@ -213,6 +224,10 @@ func fileIsDirty(fi os.FileInfo, gofile string) bool {
return fi.ModTime().After(fiDest.ModTime())
}

var (
onExit func()
)

func goRun(file string, args []string) {
goArgs := make([]string, len(args)+2)
goArgs[0] = "run"
Expand All @@ -225,6 +240,9 @@ func goRun(file string, args []string) {
cmd.Env = os.Environ()
err := cmd.Run()
if err != nil {
if onExit != nil {
onExit()
}
switch e := err.(type) {
case *exec.ExitError:
os.Exit(e.ExitCode())
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/goplus/gop
go 1.16

require (
github.com/goplus/gox v1.7.13
github.com/goplus/gox v1.7.14
github.com/qiniu/x v1.11.5
golang.org/x/mod v0.5.1
golang.org/x/tools v0.1.7
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/goplus/gox v1.7.13 h1:w8l/77j3Dj/jOQOSu3DixXuYuBqZx3m7k0BMEWjNsdA=
github.com/goplus/gox v1.7.13/go.mod h1:orZ6Mr9qqB4BVaVCMp/cypMtkn0Fp5XUE7e5uqjZATA=
github.com/goplus/gox v1.7.14 h1:Y1SRmPm+Xlv8DZkf7Q0d9umvVtGcC6m0K6w8GvSC+Kg=
github.com/goplus/gox v1.7.14/go.mod h1:orZ6Mr9qqB4BVaVCMp/cypMtkn0Fp5XUE7e5uqjZATA=
github.com/qiniu/x v1.11.5 h1:TYr5cl4g2yoHAZeDK4MTjKF6CMoG+IHlCDvvM5qym6U=
github.com/qiniu/x v1.11.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
Expand Down
6 changes: 6 additions & 0 deletions parser/_testdata/funcdoc/funcdoc.gop
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package foo

//go:noinline
//go:uintptrescapes
func test(s string, p, q uintptr, rest ...uintptr) int {
}
53 changes: 53 additions & 0 deletions parser/_testdata/funcdoc/parser.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package foo

file funcdoc.gop
ast.FuncDecl:
Doc:
ast.CommentGroup:
List:
ast.Comment:
Text: //go:noinline
ast.Comment:
Text: //go:uintptrescapes
Name:
ast.Ident:
Name: test
Type:
ast.FuncType:
Params:
ast.FieldList:
List:
ast.Field:
Names:
ast.Ident:
Name: s
Type:
ast.Ident:
Name: string
ast.Field:
Names:
ast.Ident:
Name: p
ast.Ident:
Name: q
Type:
ast.Ident:
Name: uintptr
ast.Field:
Names:
ast.Ident:
Name: rest
Type:
ast.Ellipsis:
Elt:
ast.Ident:
Name: uintptr
Results:
ast.FieldList:
List:
ast.Field:
Type:
ast.Ident:
Name: int
Body:
ast.BlockStmt:

0 comments on commit f7ac2c9

Please sign in to comment.