Repository: goplus/gop
Pull request #1766 (2024-02-21 14:39:07)

ArrowOp: -> <>


Patch:
diff --git a/cl/compile.go b/cl/compile.go
index a602873a..84a51673 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -1289,6 +1289,9 @@ var binaryGopNames = map[string]string{
 	">=": "Gop_GE",
 	">":  "Gop_GT",
 
+	"->": "Gop_PointTo",
+	"<>": "Gop_PointBi",
+
 	"&&": "Gop_LAnd",
 	"||": "Gop_LOr",
 
diff --git a/go.mod b/go.mod
index 941f6424..740050f0 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.18
 require (
 	github.com/fsnotify/fsnotify v1.7.0
 	github.com/goplus/c2go v0.7.24-0.20240221044754-e542e30f9dbc
-	github.com/goplus/gox v1.14.13-0.20240221041432-a29adc8f26fd
+	github.com/goplus/gox v1.14.13-0.20240221143457-e20cebf7f229
 	github.com/goplus/mod v0.13.8-0.20240218230953-c1aeebf6e4f7
 	github.com/qiniu/x v1.13.9-0.20240218231431-55e88daed284
 	golang.org/x/tools v0.18.0
diff --git a/go.sum b/go.sum
index ef48ecf1..d8c86ee0 100644
--- a/go.sum
+++ b/go.sum
@@ -6,8 +6,8 @@ github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyT
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/goplus/c2go v0.7.24-0.20240221044754-e542e30f9dbc h1:HGH6KoedGQ+DikZ1n9cDkCpMjODHftxbPqEhb7zDz4I=
 github.com/goplus/c2go v0.7.24-0.20240221044754-e542e30f9dbc/go.mod h1:m+2bOIErSOA4sxyrg0deb7RS6cnC3czzo7AaL9IZ+YE=
-github.com/goplus/gox v1.14.13-0.20240221041432-a29adc8f26fd h1:DZsCu/zgtGKDwp6MBjRRrmSvZRktI/Fs6TYS8O8pKVs=
-github.com/goplus/gox v1.14.13-0.20240221041432-a29adc8f26fd/go.mod h1:6b6XYHmyiCevhwuEHcV/jzm7Z2FXLDBhuxgvkjceA+o=
+github.com/goplus/gox v1.14.13-0.20240221143457-e20cebf7f229 h1:zKgGmIvM7dvMEMF4Q5K51vo3aPqRf5GjPzlYMZhp7bk=
+github.com/goplus/gox v1.14.13-0.20240221143457-e20cebf7f229/go.mod h1:6b6XYHmyiCevhwuEHcV/jzm7Z2FXLDBhuxgvkjceA+o=
 github.com/goplus/mod v0.13.8-0.20240218230953-c1aeebf6e4f7 h1:3r+SsB6gkVApZgxG6WaFk41nIKHWaSDx7T/C4aTo2S8=
 github.com/goplus/mod v0.13.8-0.20240218230953-c1aeebf6e4f7/go.mod h1:edZE5Qs+9mRnIjvWhyMNUkm5ayJ+dMlJ3J3YeXODNwA=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
diff --git a/token/token.go b/token/token.go
index a0b31993..7b13d64b 100644
--- a/token/token.go
+++ b/token/token.go
@@ -21,6 +21,8 @@ package token
 import (
 	"go/token"
 	"strconv"
+
+	xtoken "github.com/goplus/gox/token"
 )
 
 // Token is the set of lexical tokens of the Go+ programming language.
@@ -140,12 +142,13 @@ const (
 	TILDE // additional tokens, handled in an ad-hoc manner
 	additional_end
 
-	CSTRING   = literal_beg    // C"Hello"
-	RAT       = literal_end    // 123.5r
-	DRARROW   = operator_beg   // => (double right arrow)
-	QUESTION  = operator_end   // ?
-	SRARROW   = additional_beg // -> (single right arrow)
-	BIDIARROW = additional_end // <> (bidirectional arrow)
+	CSTRING  = literal_beg  // C"Hello"
+	RAT      = literal_end  // 123.5r
+	DRARROW  = operator_beg // => (double right arrow)
+	QUESTION = operator_end // ?
+
+	SRARROW   = Token(xtoken.SRARROW)   // -> (single right arrow) = additional_beg
+	BIDIARROW = Token(xtoken.BIDIARROW) // <> (bidirectional arrow) = additional_end
 
 	// Deprecated: use DRARROW instead of RARROW
 	RARROW = DRARROW


Test patch:
diff --git a/cl/compile_gop_test.go b/cl/compile_gop_test.go
index 09563cce..56e1831d 100644
--- a/cl/compile_gop_test.go
+++ b/cl/compile_gop_test.go
@@ -20,6 +20,34 @@ import (
 	"testing"
 )
 
+func TestArrowOp(t *testing.T) {
+	gopClTest(t, `
+type foo struct {
+}
+
+func (a foo) -> (b foo) {
+	println "a -> b"
+}
+
+func (a foo) <> (b foo) {
+	println "a <> b"
+}
+`, `package main
+
+import "fmt"
+
+type foo struct {
+}
+
+func (a foo) Gop_PointTo(b foo) {
+	fmt.Println("a -> b")
+}
+func (a foo) Gop_PointBi(b foo) {
+	fmt.Println("a <> b")
+}
+`)
+}
+
 func TestMapLit(t *testing.T) {
 	gopClTest(t, `
 func foo(map[string]string) {}
diff --git a/testdata/overloadop1/overloadop.gop b/testdata/overloadop1/overloadop.gop
index ccc1dca5..95744412 100644
--- a/testdata/overloadop1/overloadop.gop
+++ b/testdata/overloadop1/overloadop.gop
@@ -11,6 +11,14 @@ func (a foo) - (b foo) (ret foo) {
 	return
 }
 
+func (a foo) -> (b foo) {
+	println "a -> b"
+}
+
+func (a foo) <> (b foo) {
+	println "a <> b"
+}
+
 func -(a foo) (ret foo) {
 	println "-a"
 	return
@@ -32,3 +40,5 @@ var e = -a
 var f = a != b
 println f
 a++
+a -> b
+a <> b
diff --git a/token/token_test.go b/token/token_test.go
new file mode 100644
index 00000000..ee555fc9
--- /dev/null
+++ b/token/token_test.go
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package token
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestArrowOp(t *testing.T) {
+	if v := BIDIARROW.IsOperator(); !v {
+		t.Fatal("BIDIARROW not op?")
+	}
+	if v := SRARROW.IsOperator(); !v {
+		t.Fatal("SRARROW not op?")
+	}
+	if BIDIARROW.Precedence() != NEQ.Precedence() {
+		t.Fatal("BIDIARROW.Precedence")
+	}
+	if v := BIDIARROW.String(); v != "<>" {
+		t.Fatal("BIDIARROW.String:", v)
+	}
+	if v := (additional_end + 100).String(); v != "token(189)" {
+		t.Fatal("token.String:", v)
+	}
+}
+
+func TestPrecedence(t *testing.T) {
+	cases := map[Token]int{
+		LOR:   1,
+		LAND:  2,
+		EQL:   3,
+		SUB:   4,
+		MUL:   5,
+		ARROW: LowestPrec,
+	}
+	for op, prec := range cases {
+		if v := op.Precedence(); v != prec {
+			t.Fatal("Precedence:", op, v)
+		}
+	}
+}
+
+func TestLookup(t *testing.T) {
+	if v := Lookup("type"); v != TYPE {
+		t.Fatal("TestLookup type:", v)
+	} else if !v.IsKeyword() {
+		t.Fatal("v.IsKeyword:", v)
+	}
+	if v := Lookup("new"); v != IDENT {
+		t.Fatal("TestLookup new:", v)
+	} else if !v.IsLiteral() {
+		t.Fatal("v.IsLiteral:", v)
+	}
+}
+
+func TestBasic(t *testing.T) {
+	if !IsExported("Name") {
+		t.Fatal("IsExported")
+	}
+	if !IsKeyword("func") {
+		t.Fatal("IsKeyword")
+	}
+	if !IsIdentifier("new") {
+		t.Fatal("IsIdentifier")
+	}
+}
+
+func TestLines(t *testing.T) {
+	fset := NewFileSet()
+	f := fset.AddFile("foo.go", 100, 100)
+	lines := []int{0, 10, 50}
+	f.SetLines(lines)
+	ret := Lines(f)
+	if !reflect.DeepEqual(ret, lines) {
+		t.Fatal("TestLines failed:", ret)
+	}
+}