Repository: goplus/gop
Pull request #1326 (2022-07-05 11:27:10)

iox.Lines


Patch:
diff --git a/builtin/iox/enum.go b/builtin/iox/enum.go
index d7be472e..86ca1e33 100644
--- a/builtin/iox/enum.go
+++ b/builtin/iox/enum.go
@@ -21,12 +21,12 @@ import (
 // ----------------------------------------------------------------------------
 
 type LineIter struct {
-	*bufio.Scanner
+	s *bufio.Scanner
 }
 
 func (it LineIter) Next() (line string, ok bool) {
-	if ok = it.Scan(); ok {
-		line = it.Text()
+	if ok = it.s.Scan(); ok {
+		line = it.s.Text()
 	}
 	return
 }
@@ -37,3 +37,17 @@ func EnumLines(r io.Reader) LineIter {
 }
 
 // ----------------------------------------------------------------------------
+
+type LineReader struct {
+	r io.Reader
+}
+
+func (p LineReader) Gop_Enum() LineIter {
+	return EnumLines(p.r)
+}
+
+func Lines(r io.Reader) LineReader {
+	return LineReader{r}
+}
+
+// ----------------------------------------------------------------------------
diff --git a/cl/builtin.go b/cl/builtin.go
index 6c6e5e5c..0d10f357 100644
--- a/cl/builtin.go
+++ b/cl/builtin.go
@@ -32,29 +32,31 @@ func initMathBig(pkg *gox.Package, conf *gox.Config, big *gox.PkgRef) {
 	conf.UntypedBigFloat = big.Ref("UntypedBigfloat").Type().(*types.Named)
 }
 
-func initBuiltin(pkg *gox.Package, builtin *types.Package, os, fmt, ng, buil *gox.PkgRef) {
+func initBuiltinFns(builtin *types.Package, scope *types.Scope, pkg *gox.PkgRef, fns []string) {
+	for _, fn := range fns {
+		fnTitle := string(fn[0]-'a'+'A') + fn[1:]
+		scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, fn, pkg.Ref(fnTitle)))
+	}
+}
+
+func initBuiltin(pkg *gox.Package, builtin *types.Package, os, fmt, ng, iox, buil *gox.PkgRef) {
 	scope := builtin.Scope()
 	typs := []string{"bigint", "bigrat", "bigfloat"}
 	for _, typ := range typs {
 		name := string(typ[0]-('a'-'A')) + typ[1:]
 		scope.Insert(types.NewTypeName(token.NoPos, builtin, typ, ng.Ref(name).Type()))
 	}
-	fmtFns := []string{
+	initBuiltinFns(builtin, scope, fmt, []string{
 		"print", "println", "printf", "errorf",
 		"fprint", "fprintln", "fprintf",
 		"sprint", "sprintln", "sprintf",
-	}
-	for _, fn := range fmtFns {
-		fnTitle := string(fn[0]-'a'+'A') + fn[1:]
-		scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, fn, fmt.Ref(fnTitle)))
-	}
-	osFns := []string{
+	})
+	initBuiltinFns(builtin, scope, os, []string{
 		"open", "create",
-	}
-	for _, fn := range osFns {
-		fnTitle := string(fn[0]-'a'+'A') + fn[1:]
-		scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, fn, os.Ref(fnTitle)))
-	}
+	})
+	initBuiltinFns(builtin, scope, iox, []string{
+		"lines",
+	})
 	scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "newRange", buil.Ref("NewRange__0")))
 	scope.Insert(types.NewTypeName(token.NoPos, builtin, "uint128", ng.Ref("Uint128").Type()))
 	scope.Insert(types.NewTypeName(token.NoPos, builtin, "int128", ng.Ref("Int128").Type()))
@@ -67,10 +69,11 @@ func newBuiltinDefault(pkg *gox.Package, conf *gox.Config) *types.Package {
 	os := pkg.Import("os")
 	buil := pkg.Import("github.com/goplus/gop/builtin")
 	ng := pkg.Import("github.com/goplus/gop/builtin/ng")
+	iox := pkg.Import("github.com/goplus/gop/builtin/iox")
 	pkg.Import("strconv")
 	pkg.Import("strings")
 	initMathBig(pkg, conf, ng)
-	initBuiltin(pkg, builtin, os, fmt, ng, buil)
+	initBuiltin(pkg, builtin, os, fmt, ng, iox, buil)
 	gox.InitBuiltin(pkg, builtin, conf)
 	return builtin
 }


Test patch:
diff --git a/cl/compile_test.go b/cl/compile_test.go
index 30828d27..064fedf6 100644
--- a/cl/compile_test.go
+++ b/cl/compile_test.go
@@ -137,6 +137,39 @@ ls
 `)
 }
 
+func TestFileOpen(t *testing.T) {
+	gopClTest(t, `
+for line <- open("foo.txt")! {
+	println line
+}
+`, `package main
+
+import (
+	fmt "fmt"
+	os "os"
+	iox "github.com/goplus/gop/builtin/iox"
+)
+
+func main() {
+	for _gop_it := iox.EnumLines(func() (_gop_ret *os.File) {
+		var _gop_err error
+		_gop_ret, _gop_err = os.Open("foo.txt")
+		if _gop_err != nil {
+			panic(_gop_err)
+		}
+		return
+	}()); ; {
+		var _gop_ok bool
+		line, _gop_ok := _gop_it.Next()
+		if !_gop_ok {
+			break
+		}
+		fmt.Println(line)
+	}
+}
+`)
+}
+
 func TestFileEnumLines(t *testing.T) {
 	gopClTest(t, `
 import "os"
@@ -165,6 +198,38 @@ func main() {
 `)
 }
 
+func TestIoxLines(t *testing.T) {
+	gopClTest(t, `
+import "io"
+
+var r io.Reader
+
+for line <- lines(r) {
+	println line
+}
+`, `package main
+
+import (
+	fmt "fmt"
+	iox "github.com/goplus/gop/builtin/iox"
+	io "io"
+)
+
+var r io.Reader
+
+func main() {
+	for _gop_it := iox.Lines(r).Gop_Enum(); ; {
+		var _gop_ok bool
+		line, _gop_ok := _gop_it.Next()
+		if !_gop_ok {
+			break
+		}
+		fmt.Println(line)
+	}
+}
+`)
+}
+
 func TestMixedGo(t *testing.T) {
 	gopMixedClTest(t, "main", `package main