Repository: goplus/gop
Pull request #1022 (2021-12-03 12:27:48)

xformat: Source => GopstyleSource


Patch:
diff --git a/cl/stmt.go b/cl/stmt.go
index 6381083d..08732bec 100644
--- a/cl/stmt.go
+++ b/cl/stmt.go
@@ -260,14 +260,6 @@ func compileAssignStmt(ctx *blockCtx, expr *ast.AssignStmt) {
 //    body
 // end
 func compileRangeStmt(ctx *blockCtx, v *ast.RangeStmt) {
-	if re, ok := v.X.(*ast.RangeExpr); ok {
-		tok := token.DEFINE
-		if v.Tok == token.ASSIGN {
-			tok = v.Tok
-		}
-		compileForStmt(ctx, toForStmt(v.For, v.Key, v.Body, re, tok))
-		return
-	}
 	cb := ctx.cb
 	comments := cb.Comments()
 	if v.Tok == token.DEFINE {
@@ -312,10 +304,6 @@ func compileRangeStmt(ctx *blockCtx, v *ast.RangeStmt) {
 }
 
 func compileForPhraseStmt(ctx *blockCtx, v *ast.ForPhraseStmt) {
-	if re, ok := v.X.(*ast.RangeExpr); ok {
-		compileForStmt(ctx, toForStmt(v.For, v.Value, v.Body, re, token.DEFINE))
-		return
-	}
 	cb := ctx.cb
 	comments := cb.Comments()
 	names := make([]string, 1, 2)
@@ -345,82 +333,6 @@ func compileForPhraseStmt(ctx *blockCtx, v *ast.ForPhraseStmt) {
 	cb.End()
 }
 
-func toForStmt(forPos token.Pos, value ast.Expr, body *ast.BlockStmt, re *ast.RangeExpr, tok token.Token) *ast.ForStmt {
-	nilIdent := value == nil
-	if !nilIdent {
-		if v, ok := value.(*ast.Ident); ok && v.Name == "_" {
-			nilIdent = true
-		}
-	}
-	if nilIdent {
-		value = &ast.Ident{NamePos: forPos, Name: "_gop_k"}
-	}
-	if re.First == nil {
-		re.First = &ast.BasicLit{ValuePos: forPos, Kind: token.INT, Value: "0"}
-	}
-	initLhs := []ast.Expr{value}
-	initRhs := []ast.Expr{re.First}
-	replaceValue := false
-	var cond ast.Expr
-	var post ast.Expr
-	switch re.Last.(type) {
-	case *ast.Ident, *ast.BasicLit:
-		cond = re.Last
-	default:
-		replaceValue = true
-		cond = &ast.Ident{NamePos: forPos, Name: "_gop_end"}
-		initLhs = append(initLhs, cond)
-		initRhs = append(initRhs, re.Last)
-	}
-	if re.Expr3 == nil {
-		post = &ast.BasicLit{ValuePos: forPos, Kind: token.INT, Value: "1"}
-	} else {
-		switch re.Expr3.(type) {
-		case *ast.Ident, *ast.BasicLit:
-			post = re.Expr3
-		default:
-			replaceValue = true
-			post = &ast.Ident{NamePos: forPos, Name: "_gop_step"}
-			initLhs = append(initLhs, post)
-			initRhs = append(initRhs, re.Expr3)
-		}
-	}
-	if tok == token.ASSIGN && replaceValue {
-		oldValue := value
-		value = &ast.Ident{NamePos: forPos, Name: "_gop_k"}
-		initLhs[0] = value
-		body.List = append([]ast.Stmt{&ast.AssignStmt{
-			Lhs:    []ast.Expr{oldValue},
-			TokPos: forPos,
-			Tok:    token.ASSIGN,
-			Rhs:    []ast.Expr{value},
-		}}, body.List...)
-		tok = token.DEFINE
-	}
-	return &ast.ForStmt{
-		For: forPos,
-		Init: &ast.AssignStmt{
-			Lhs:    initLhs,
-			TokPos: re.To,
-			Tok:    tok,
-			Rhs:    initRhs,
-		},
-		Cond: &ast.BinaryExpr{
-			X:     value,
-			OpPos: re.To,
-			Op:    token.LSS,
-			Y:     cond,
-		},
-		Post: &ast.AssignStmt{
-			Lhs:    []ast.Expr{value},
-			TokPos: re.Colon2,
-			Tok:    token.ADD_ASSIGN,
-			Rhs:    []ast.Expr{post},
-		},
-		Body: body,
-	}
-}
-
 // for init; cond then
 //    body
 //    post
diff --git a/cmd/internal/gopfmt/fmt.go b/cmd/internal/gopfmt/fmt.go
index ae362467..0d4ded32 100644
--- a/cmd/internal/gopfmt/fmt.go
+++ b/cmd/internal/gopfmt/fmt.go
@@ -70,7 +70,7 @@ func gopfmt(path string, smart, mvgo bool) (err error) {
 	}
 	var target []byte
 	if smart {
-		target, err = xformat.Source(src)
+		target, err = xformat.GopstyleSource(src)
 	} else {
 		target, err = format.Source(src)
 	}
diff --git a/x/format/README.md b/x/format/README.md
deleted file mode 100644
index 8b76f1bb..00000000
--- a/x/format/README.md
+++ /dev/null
@@ -1,98 +0,0 @@
-Go+ Code Style
-======
-
-TODO
-
-
-## Specification
-
-### No package main
-
-```go
-package main
-
-func f() {
-}
-```
-
-will be converted into:
-
-```go
-func f() {
-}
-```
-
-
-### No func main
-
-```go
-package main
-
-func main() {
-    a := 0
-}
-```
-
-will be converted into:
-
-```go
-a := 0
-```
-
-
-### Replace fmt.Print to builtin (NotImpl)
-
-```go
-import "fmt"
-
-n, err := fmt.Println("Hello world")
-```
-
-will be converted into:
-
-```go
-n, err := println("Hello world")
-```
-
-Note:
-
-* Convert `fmt.Print` => `print`
-* Convert `fmt.Printf` => `printf`
-* Convert `fmt.Println` => `println`
-* ...
-
-
-### Command style first (NotImpl)
-
-```go
-import "fmt"
-
-fmt.Println()
-fmt.Println(fmt.Println("Hello world"))
-```
-
-will be converted into:
-
-```go
-println
-println println("Hello world")
-```
-
-Note:
-
-* Only the outermost function call statement is converted into command style. So `fmt.Println(fmt.Println("Hello world"))` is converted into `println println("Hello world")`, not `println println "Hello world"`.
-
-
-### Function call starting with lowercase (NotImpl)
-
-```go
-import "math"
-
-println math.Sin(math.Pi/3)
-```
-
-will be converted into:
-
-```go
-println math.sin(math.Pi/3)
-```
diff --git a/x/format/gopstyle.go b/x/format/gopstyle.go
index 35bfc402..3f6139ba 100644
--- a/x/format/gopstyle.go
+++ b/x/format/gopstyle.go
@@ -11,7 +11,7 @@ import (
 
 // -----------------------------------------------------------------------------
 
-func Source(src []byte) (ret []byte, err error) {
+func GopstyleSource(src []byte) (ret []byte, err error) {
 	fset := token.NewFileSet()
 	if f, err := parser.ParseFile(fset, "", src, parser.ParseComments); err == nil {
 		Gopstyle(f)


Test patch:
diff --git a/cl/compile_test.go b/cl/compile_test.go
index 4fe15af4..0c1d1322 100644
--- a/cl/compile_test.go
+++ b/cl/compile_test.go
@@ -19,7 +19,6 @@ package cl_test
 import (
 	"bytes"
 	"os"
-	"strings"
 	"sync"
 	"syscall"
 	"testing"
@@ -3254,26 +3253,24 @@ func newRepo() Repo {
 	}
 }
 
-func testRangeExpr(t *testing.T, codeTpl, expect string) {
-	for k, s := range []string{" <- ", " := range ", " = range "} {
-		if k == 2 {
-			codeTpl = "i:=0\n" + codeTpl
-			expect = strings.Replace(expect, "for i := ", "i := 0\n\tfor i = ", -1)
-		}
-		gopClTest(t, strings.Replace(codeTpl, "$", s, -1), expect)
-	}
-}
-
 func TestRangeExpr(t *testing.T) {
-	testRangeExpr(t, `
-for i $ :10 {
+	gopClTest(t, `
+for i := range :10 {
 	println(i)
 }`, `package main
 
-import fmt "fmt"
+import (
+	fmt "fmt"
+	builtin "github.com/goplus/gop/builtin"
+)
 
 func main() {
-	for i := 0; i < 10; i += 1 {
+	for _gop_it := builtin.NewRange__0(0, 10, 1).Gop_Enum(); ; {
+		var _gop_ok bool
+		i, _gop_ok := _gop_it.Next()
+		if !_gop_ok {
+			break
+		}
 		fmt.Println(i)
 	}
 }
@@ -3281,15 +3278,23 @@ func main() {
 }
 
 func TestRangeExpr2(t *testing.T) {
-	testRangeExpr(t, `
-for i $ 1:10:2 {
+	gopClTest(t, `
+for i := range 1:10:2 {
 	println(i)
 }`, `package main
 
-import fmt "fmt"
+import (
+	fmt "fmt"
+	builtin "github.com/goplus/gop/builtin"
+)
 
 func main() {
-	for i := 1; i < 10; i += 2 {
+	for _gop_it := builtin.NewRange__0(1, 10, 2).Gop_Enum(); ; {
+		var _gop_ok bool
+		i, _gop_ok := _gop_it.Next()
+		if !_gop_ok {
+			break
+		}
 		fmt.Println(i)
 	}
 }
@@ -3297,15 +3302,23 @@ func main() {
 }
 
 func TestRangeExpr3(t *testing.T) {
-	testRangeExpr(t, `
-for i $ 1:10 {
+	gopClTest(t, `
+for i := range 1:10 {
 	println(i)
 }`, `package main
 
-import fmt "fmt"
+import (
+	fmt "fmt"
+	builtin "github.com/goplus/gop/builtin"
+)
 
 func main() {
-	for i := 1; i < 10; i += 1 {
+	for _gop_it := builtin.NewRange__0(1, 10, 1).Gop_Enum(); ; {
+		var _gop_ok bool
+		i, _gop_ok := _gop_it.Next()
+		if !_gop_ok {
+			break
+		}
 		fmt.Println(i)
 	}
 }
@@ -3313,15 +3326,23 @@ func main() {
 }
 
 func TestRangeExpr4(t *testing.T) {
-	testRangeExpr(t, `
-for i $ :10:2 {
+	gopClTest(t, `
+for i := range :10:2 {
 	println(i)
 }`, `package main
 
-import fmt "fmt"
+import (
+	fmt "fmt"
+	builtin "github.com/goplus/gop/builtin"
+)
 
 func main() {
-	for i := 0; i < 10; i += 2 {
+	for _gop_it := builtin.NewRange__0(0, 10, 2).Gop_Enum(); ; {
+		var _gop_ok bool
+		i, _gop_ok := _gop_it.Next()
+		if !_gop_ok {
+			break
+		}
 		fmt.Println(i)
 	}
 }
@@ -3334,149 +3355,19 @@ for range :10 {
 	println("Hi")
 }`, `package main
 
-import fmt "fmt"
-
-func main() {
-	for _gop_k := 0; _gop_k < 10; _gop_k += 1 {
-		fmt.Println("Hi")
-	}
-}
-`)
-}
-
-func TestRangeExpr6(t *testing.T) {
-	gopClTest(t, `
-for _ <- :10 {
-	println("Hi")
-}`, `package main
-
-import fmt "fmt"
-
-func main() {
-	for _gop_k := 0; _gop_k < 10; _gop_k += 1 {
-		fmt.Println("Hi")
-	}
-}
-`)
-}
-
-func TestRangeExpr7(t *testing.T) {
-	gopClTest(t, `
-println [x for x <- 0:3:1]
-`, `package main
-
 import (
 	fmt "fmt"
 	builtin "github.com/goplus/gop/builtin"
 )
 
 func main() {
-	fmt.Println(func() (_gop_ret []int) {
-		for _gop_it := builtin.NewRange__0(0, 3, 1).Gop_Enum(); ; {
-			var _gop_ok bool
-			x, _gop_ok := _gop_it.Next()
-			if !_gop_ok {
-				break
-			}
-			_gop_ret = append(_gop_ret, x)
+	for _gop_it := builtin.NewRange__0(0, 10, 1).Gop_Enum(); ; {
+		var _gop_ok bool
+		_, _gop_ok = _gop_it.Next()
+		if !_gop_ok {
+			break
 		}
-		return
-	}())
-}
-`)
-}
-
-func testRangeExpr8(t *testing.T, codeTpl, expect string) {
-	for _, s := range []string{" <- ", " := range "} {
-		gopClTest(t, strings.Replace(codeTpl, "$", s, -1), expect)
-	}
-}
-
-func TestRangeExpr8(t *testing.T) {
-	testRangeExpr8(t, `
-	type T struct{}
-
-	func (t T)start()int{
-		return 0
-	}
-	func (t T)end()int{
-		return 3 
-	}
-	func (t T)step()int{
-		return 1 
-	}
-	
-	t:=T{}
-	
-	for i <- t.start():t.end():t.step(){
-		println i
-	}
-	`, `package main
-
-import fmt "fmt"
-
-type T struct {
-}
-
-func (t T) start() int {
-	return 0
-}
-func (t T) end() int {
-	return 3
-}
-func (t T) step() int {
-	return 1
-}
-func main() {
-	t := T{}
-	for i, _gop_end, _gop_step := t.start(), t.end(), t.step(); i < _gop_end; i += _gop_step {
-		fmt.Println(i)
-	}
-}
-`)
-}
-
-func TestRangeExpr9(t *testing.T) {
-	testRangeExpr8(t, `
-	type T struct{}
-
-	func (t T)start()int{
-		return 0
-	}
-	func (t T)end()int{
-		return 3 
-	}
-	func (t T)step()int{
-		return 1 
-	}
-	
-	t:=T{}
-	i:=0
-	for i =range t.start():t.end():t.step(){
-		println i
-	}
-	`, `package main
-
-import fmt "fmt"
-
-type T struct {
-}
-
-func (t T) start() int {
-	return 0
-}
-func (t T) end() int {
-	return 3
-}
-func (t T) step() int {
-	return 1
-}
-func main() {
-	t := T{}
-	i := 0
-	for _gop_k, _gop_end, _gop_step := t.start(), t.end(), t.step(); _gop_k < _gop_end; _gop_k += _gop_step {
-		i = _gop_k
-		fmt.Println(i)
+		fmt.Println("Hi")
 	}
 }
 `)
diff --git a/x/format/gopstyle_test.go b/x/format/gopstyle_test.go
index f9f9d7df..2b9c88e4 100644
--- a/x/format/gopstyle_test.go
+++ b/x/format/gopstyle_test.go
@@ -8,7 +8,7 @@ import (
 
 func testFormat(t *testing.T, name string, src, expect string) {
 	t.Run(name, func(t *testing.T) {
-		result, err := Source([]byte(src))
+		result, err := GopstyleSource([]byte(src))
 		if err != nil {
 			t.Fatal("format.Source failed:", err)
 		}