Repository: goplus/gop
Pull request #1160 (2022-04-24 01:55:07)

v1.1.0-beta3


Patch:
diff --git a/README.md b/README.md
index 0b705db1..eccf90e0 100644
--- a/README.md
+++ b/README.md
@@ -194,7 +194,7 @@ var y *big.Rat = 4/5r
 println x, y
 ```
 
-### Large number: uint128, int128
+### Large integer: uint128, int128
 
 ```go
 var x uint128 = 1 << 65
diff --git a/VERSION b/VERSION
deleted file mode 100644
index f081620b..00000000
--- a/VERSION
+++ /dev/null
@@ -1,1 +0,0 @@
-v1.1.0-beta3
diff --git a/builtin/ng/big.go b/builtin/ng/big.go
index 4bb173b1..73a70a26 100644
--- a/builtin/ng/big.go
+++ b/builtin/ng/big.go
@@ -80,15 +80,6 @@ func (a Bigint) IsNil() bool {
 	return a.Int == nil
 }
 
-// Gop_Assign: func (a bigint) = (b bigint)
-func (a Bigint) Gop_Assign(b Bigint) {
-	if Gop_istmp(b) {
-		*a.Int = *b.Int
-	} else {
-		a.Int.Set(b.Int)
-	}
-}
-
 // Gop_Add: func (a bigint) + (b bigint) bigint
 func (a Bigint) Gop_Add(b Bigint) Bigint {
 	return Bigint{tmpint(a, b).Add(a.Int, b.Int)}
@@ -179,9 +170,9 @@ func (a Bigint) Gop_Neg() Bigint {
 	return Bigint{tmpint1(a).Neg(a.Int)}
 }
 
-// Gop_Pos: func +(a bigint) bigint
-func (a Bigint) Gop_Pos() Bigint {
-	return a
+// Gop_Dup: func +(a bigint) bigint
+func (a Bigint) Gop_Dup() Bigint {
+	return Bigint{new(big.Int).Set(a.Int)}
 }
 
 // Gop_Not: func ^(a bigint) bigint
@@ -189,61 +180,93 @@ func (a Bigint) Gop_Not() Bigint {
 	return Bigint{tmpint1(a).Not(a.Int)}
 }
 
-// Gop_Add: func (a bigint) += (b bigint)
+// Gop_Inc: func ++(b bigint)
+func (a Bigint) Gop_Inc() {
+	a.Int.Add(a.Int, big1)
+}
+
+// Gop_Dec: func --(b bigint)
+func (a Bigint) Gop_Dec() {
+	a.Int.Sub(a.Int, big1)
+}
+
+// Gop_AddAssign: func (a bigint) += (b bigint)
 func (a Bigint) Gop_AddAssign(b Bigint) {
 	a.Int.Add(a.Int, b.Int)
 }
 
-// Gop_Sub: func (a bigint) -= (b bigint)
+// Gop_SubAssign: func (a bigint) -= (b bigint)
 func (a Bigint) Gop_SubAssign(b Bigint) {
 	a.Int.Sub(a.Int, b.Int)
 }
 
-// Gop_Mul: func (a bigint) *= (b bigint)
+// Gop_MulAssign: func (a bigint) *= (b bigint)
 func (a Bigint) Gop_MulAssign(b Bigint) {
 	a.Int.Mul(a.Int, b.Int)
 }
 
-// Gop_Quo: func (a bigint) /= (b bigint) {
+// Gop_QuoAssign: func (a bigint) /= (b bigint) {
 func (a Bigint) Gop_QuoAssign(b Bigint) {
 	a.Int.Quo(a.Int, b.Int)
 }
 
-// Gop_Rem: func (a bigint) %= (b bigint)
+// Gop_RemAssign: func (a bigint) %= (b bigint)
 func (a Bigint) Gop_RemAssign(b Bigint) {
 	a.Int.Rem(a.Int, b.Int)
 }
 
-// Gop_Or: func (a bigint) |= (b bigint)
+// Gop_OrAssign: func (a bigint) |= (b bigint)
 func (a Bigint) Gop_OrAssign(b Bigint) {
 	a.Int.Or(a.Int, b.Int)
 }
 
-// Gop_Xor: func (a bigint) ^= (b bigint)
+// Gop_XorAssign: func (a bigint) ^= (b bigint)
 func (a Bigint) Gop_XorAssign(b Bigint) {
 	a.Int.Xor(a.Int, b.Int)
 }
 
-// Gop_And: func (a bigint) &= (b bigint)
+// Gop_AndAssign: func (a bigint) &= (b bigint)
 func (a Bigint) Gop_AndAssign(b Bigint) {
 	a.Int.And(a.Int, b.Int)
 }
 
-// Gop_AndNot: func (a bigint) &^= (b bigint)
+// Gop_AndNotAssign: func (a bigint) &^= (b bigint)
 func (a Bigint) Gop_AndNotAssign(b Bigint) {
 	a.Int.AndNot(a.Int, b.Int)
 }
 
-// Gop_Lsh: func (a bigint) <<= (n untyped_uint)
+// Gop_LshAssign: func (a bigint) <<= (n untyped_uint)
 func (a Bigint) Gop_LshAssign(n Gop_ninteger) {
 	a.Int.Lsh(a.Int, uint(n))
 }
 
-// Gop_Rsh: func (a bigint) >>= (n untyped_uint)
+// Gop_RshAssign: func (a bigint) >>= (n untyped_uint)
 func (a Bigint) Gop_RshAssign(n Gop_ninteger) {
 	a.Int.Rsh(a.Int, uint(n))
 }
 
+// -----------------------------------------------------------------------------
+
+// Gop_Rcast: func int64(x bigint) int64
+func (a Bigint) Gop_Rcast__0() int64 {
+	return a.Int64()
+}
+
+// Gop_Rcast: func int64(x bigint) (int64, bool)
+func (a Bigint) Gop_Rcast__1() (int64, bool) {
+	return a.Int64(), a.IsInt64()
+}
+
+// Gop_Rcast: func uint64(x bigint) uint64
+func (a Bigint) Gop_Rcast__2() uint64 {
+	return a.Uint64()
+}
+
+// Gop_Rcast: func uint64(x bigint) (uint64, bool)
+func (a Bigint) Gop_Rcast__3() (uint64, bool) {
+	return a.Uint64(), a.IsUint64()
+}
+
 // Bigint_Cast: func bigint(x untyped_int) bigint
 func Bigint_Cast__0(x int) Bigint {
 	return Bigint{big.NewInt(int64(x))}
@@ -397,9 +420,9 @@ func (a Bigrat) Gop_Neg() Bigrat {
 	return Bigrat{tmprat1(a).Neg(a.Rat)}
 }
 
-// Gop_Pos: func +(a bigrat) bigrat
-func (a Bigrat) Gop_Pos() Bigrat {
-	return a
+// Gop_Dup: func +(a bigrat) bigrat
+func (a Bigrat) Gop_Dup() Bigrat {
+	return Bigrat{new(big.Rat).Set(a.Rat)}
 }
 
 // Gop_Inv: func /(a bigrat) bigrat
@@ -427,6 +450,8 @@ func (a Bigrat) Gop_QuoAssign(b Bigrat) {
 	a.Rat.Quo(a.Rat, b.Rat)
 }
 
+// -----------------------------------------------------------------------------
+
 // Bigrat_Cast: func bigrat(x untyped_int) bigrat
 func Bigrat_Cast__0(x int) Bigrat {
 	return Bigrat{big.NewRat(int64(x), 1)}
diff --git a/builtin/ng/int128.go b/builtin/ng/int128.go
index ff586c1a..34127492 100644
--- a/builtin/ng/int128.go
+++ b/builtin/ng/int128.go
@@ -12,6 +12,16 @@ const (
 	maxInt64 = 1<<63 - 1
 )
 
+var (
+	big1       = new(big.Int).SetUint64(1)
+	bigMaxU128 *big.Int
+)
+
+func init() {
+	bigMaxU128 = new(big.Int).Lsh(big1, 128)
+	bigMaxU128.Sub(bigMaxU128, big1) // 340282366920938463463374607431768211455
+}
+
 // -----------------------------------------------------------------------------
 
 type Int128 struct {
@@ -235,11 +245,6 @@ func (i Int128) ToBigInt(b *big.Int) {
 	}
 }
 
-var (
-	big1          = new(big.Int).SetUint64(1)
-	bigMaxU128, _ = new(big.Int).SetString("340282366920938463463374607431768211455", 10)
-)
-
 func (i Int128) Sign() int {
 	if i.lo == 0 && i.hi == 0 {
 		return 0
@@ -249,22 +254,73 @@ func (i Int128) Sign() int {
 	return -1
 }
 
-func (i Int128) Gop_Inc() (v Int128) {
-	v.lo = i.lo + 1
-	v.hi = i.hi
-	if i.lo > v.lo {
-		v.hi++
+func (i *Int128) Gop_Inc() {
+	i.lo++
+	if i.lo == 0 {
+		i.hi++
 	}
-	return v
 }
 
-func (i Int128) Gop_Dec() (v Int128) {
-	v.lo = i.lo - 1
-	v.hi = i.hi
-	if i.lo < v.lo {
-		v.hi--
+func (i *Int128) Gop_Dec() {
+	if i.lo == 0 {
+		i.hi--
 	}
-	return v
+	i.lo--
+}
+
+// Gop_AddAssign: func (a *int128) += (b int128)
+func (i *Int128) Gop_AddAssign(b Int128) {
+	*i = i.Gop_Add__1(b)
+}
+
+// Gop_SubAssign: func (a *int128) -= (b int128)
+func (i *Int128) Gop_SubAssign(b Int128) {
+	*i = i.Gop_Sub__1(b)
+}
+
+// Gop_MulAssign: func (a *int128) *= (b int128)
+func (i *Int128) Gop_MulAssign(b Int128) {
+	*i = i.Gop_Mul__1(b)
+}
+
+// Gop_QuoAssign: func (a *int128) /= (b int128) {
+func (i *Int128) Gop_QuoAssign(b Int128) {
+	*i = i.Gop_Quo__1(b)
+}
+
+// Gop_RemAssign: func (a *int128) %= (b int128)
+func (i *Int128) Gop_RemAssign(b Int128) {
+	*i = i.Gop_Rem__1(b)
+}
+
+// Gop_OrAssign: func (a *int128) |= (b int128)
+func (i *Int128) Gop_OrAssign(b Int128) {
+	*i = i.Gop_Or(b)
+}
+
+// Gop_XorAssign: func (a *int128) ^= (b int128)
+func (i *Int128) Gop_XorAssign(b Int128) {
+	*i = i.Gop_Xor(b)
+}
+
+// Gop_AndAssign: func (a *int128) &= (b int128)
+func (i *Int128) Gop_AndAssign(b Int128) {
+	*i = i.Gop_And(b)
+}
+
+// Gop_AndNotAssign: func (a *int128) &^= (b int128)
+func (i *Int128) Gop_AndNotAssign(b Int128) {
+	*i = i.Gop_AndNot(b)
+}
+
+// Gop_LshAssign: func (a *int128) <<= (n untyped_uint)
+func (i *Int128) Gop_LshAssign(n Gop_ninteger) {
+	*i = i.Gop_Lsh(n)
+}
+
+// Gop_RshAssign: func (a *int128) >>= (n untyped_uint)
+func (i *Int128) Gop_RshAssign(n Gop_ninteger) {
+	*i = i.Gop_Rsh(n)
 }
 
 func (i Int128) Gop_Add__1(n Int128) (v Int128) {
@@ -321,6 +377,10 @@ func (i Int128) Gop_Neg() (v Int128) {
 	return v
 }
 
+func (i Int128) Gop_Dup() (v Int128) {
+	return i
+}
+
 // Abs returns the absolute value of i as a signed integer.
 func (i Int128) Abs__0() Int128 {
 	if i.hi&signBit != 0 {
@@ -522,6 +582,55 @@ func (i Int128) Gop_LE__0(n int64) bool {
 	return false
 }
 
+func (i Int128) Gop_And(n Int128) Int128 {
+	i.hi &= n.hi
+	i.lo &= n.lo
+	return i
+}
+
+func (i Int128) Gop_AndNot(n Int128) Int128 {
+	i.hi &^= n.hi
+	i.lo &^= n.lo
+	return i
+}
+
+func (i Int128) Gop_Not() Int128 {
+	return Int128{hi: ^i.hi, lo: ^i.lo}
+}
+
+func (i Int128) Gop_Or(n Int128) Int128 {
+	i.hi |= n.hi
+	i.lo |= n.lo
+	return i
+}
+
+func (i Int128) Gop_Xor(v Int128) Int128 {
+	i.hi ^= v.hi
+	i.lo ^= v.lo
+	return i
+}
+
+func (i Int128) Gop_Lsh(n Gop_ninteger) Int128 {
+	if n < 64 {
+		i.hi = (i.hi << n) | (i.lo >> (64 - n))
+		i.lo <<= n
+	} else {
+		i.hi = i.lo << (n - 64)
+		i.lo = 0
+	}
+	return i
+}
+
+func (i Int128) Gop_Rsh(n Gop_ninteger) Int128 {
+	if n < 64 {
+		i.lo = (i.lo >> n) | (i.hi << (64 - n))
+	} else {
+		i.lo = i.hi >> (n - 64)
+	}
+	i.hi = uint64(int64(i.hi) >> n)
+	return i
+}
+
 // Mul returns the product of two I128s.
 //
 // Overflow should wrap around, as per the Go spec.
@@ -653,15 +762,15 @@ func (i Int128) Gop_Quo__0(by int64) (q Int128) {
 	return q
 }
 
-// Rem returns the remainder of x%y for y != 0. If y == 0, a division-by-zero
-// run-time panic occurs. Rem implements truncated modulus (like Go); see
+// Gop_Rem returns the remainder of x%y for y != 0. If y == 0, a division-by-zero
+// run-time panic occurs. Gop_Rem implements truncated modulus (like Go); see
 // QuoRem for more details.
-func (i Int128) Rem__1(by Int128) (r Int128) {
+func (i Int128) Gop_Rem__1(by Int128) (r Int128) {
 	_, r = i.QuoRem__1(by)
 	return r
 }
 
-func (i Int128) Rem__0(by int64) (r Int128) {
+func (i Int128) Gop_Rem__0(by int64) (r Int128) {
 	ineg := i.hi&signBit != 0
 	if ineg {
 		i = i.Gop_Neg()
diff --git a/builtin/ng/uint128.go b/builtin/ng/uint128.go
index f6d6a7d8..b1852c36 100644
--- a/builtin/ng/uint128.go
+++ b/builtin/ng/uint128.go
@@ -179,6 +179,16 @@ func (u Uint128) Gop_Rcast__2() (out uint64, inRange bool) {
 	return u.lo, u.hi == 0
 }
 
+// Gop_Rcast: func int64(v uint128) int64
+func (u Uint128) Gop_Rcast__3() int64 {
+	return int64(u.lo)
+}
+
+// Gop_Rcast: func int64(v uint128) (int64, bool)
+func (u Uint128) Gop_Rcast__4() (out int64, inRange bool) {
+	return int64(u.lo), u.hi == 0 && u.lo <= maxInt64
+}
+
 // -----------------------------------------------------------------------------
 
 func (u Uint128) IsZero() bool {
@@ -366,18 +376,77 @@ func (u Uint128) Cmp__0(n uint64) int {
 	return 0
 }
 
-func (u Uint128) Gop_Inc() (v Uint128) {
-	var carry uint64
-	v.lo, carry = bits.Add64(u.lo, 1, 0)
-	v.hi = u.hi + carry
-	return v
+func (u Uint128) Gop_Dup() (v Uint128) {
+	return u
 }
 
-func (u Uint128) Gop_Dec() (v Uint128) {
-	var borrowed uint64
-	v.lo, borrowed = bits.Sub64(u.lo, 1, 0)
-	v.hi = u.hi - borrowed
-	return v
+func (u *Uint128) Gop_Inc() {
+	u.lo++
+	if u.lo == 0 {
+		u.hi++
+	}
+}
+
+func (u *Uint128) Gop_Dec() {
+	if u.lo == 0 {
+		u.hi--
+	}
+	u.lo--
+}
+
+// Gop_AddAssign: func (a *uint128) += (b uint128)
+func (u *Uint128) Gop_AddAssign(b Uint128) {
+	*u = u.Gop_Add__1(b)
+}
+
+// Gop_SubAssign: func (a *uint128) -= (b uint128)
+func (u *Uint128) Gop_SubAssign(b Uint128) {
+	*u = u.Gop_Sub__1(b)
+}
+
+// Gop_MulAssign: func (a *uint128) *= (b uint128)
+func (u *Uint128) Gop_MulAssign(b Uint128) {
+	*u = u.Gop_Mul__1(b)
+}
+
+// Gop_QuoAssign: func (a *uint128) /= (b uint128) {
+func (u *Uint128) Gop_QuoAssign(b Uint128) {
+	*u = u.Gop_Quo__1(b)
+}
+
+// Gop_RemAssign: func (a *uint128) %= (b uint128)
+func (u *Uint128) Gop_RemAssign(b Uint128) {
+	*u = u.Gop_Rem__1(b)
+}
+
+// Gop_OrAssign: func (a *uint128) |= (b uint128)
+func (u *Uint128) Gop_OrAssign(b Uint128) {
+	*u = u.Gop_Or__1(b)
+}
+
+// Gop_XorAssign: func (a *uint128) ^= (b uint128)
+func (u *Uint128) Gop_XorAssign(b Uint128) {
+	*u = u.Gop_Xor__1(b)
+}
+
+// Gop_AndAssign: func (a *uint128) &= (b uint128)
+func (u *Uint128) Gop_AndAssign(b Uint128) {
+	*u = u.Gop_And__1(b)
+}
+
+// Gop_AndNotAssign: func (a *uint128) &^= (b uint128)
+func (u *Uint128) Gop_AndNotAssign(b Uint128) {
+	*u = u.Gop_AndNot(b)
+}
+
+// Gop_LshAssign: func (a *uint128) <<= (n untyped_uint)
+func (u *Uint128) Gop_LshAssign(n Gop_ninteger) {
+	*u = u.Gop_Lsh(n)
+}
+
+// Gop_RshAssign: func (a *uint128) >>= (n untyped_uint)
+func (u *Uint128) Gop_RshAssign(n Gop_ninteger) {
+	*u = u.Gop_Rsh(n)
 }
 
 func (u Uint128) Gop_Add__1(n Uint128) (v Uint128) {
@@ -449,8 +518,8 @@ func (u Uint128) Gop_LE__0(n uint64) bool {
 }
 
 func (u Uint128) Gop_And__1(n Uint128) Uint128 {
-	u.hi = u.hi & n.hi
-	u.lo = u.lo & n.lo
+	u.hi &= n.hi
+	u.lo &= n.lo
 	return u
 }
 
@@ -459,71 +528,57 @@ func (u Uint128) Gop_And__0(n uint64) Uint128 {
 }
 
 func (u Uint128) Gop_AndNot(n Uint128) Uint128 {
-	u.hi = u.hi &^ n.hi
-	u.lo = u.lo &^ n.lo
+	u.hi &^= n.hi
+	u.lo &^= n.lo
 	return u
 }
 
-func (u Uint128) Gop_Not() (out Uint128) {
-	out.hi = ^u.hi
-	out.lo = ^u.lo
-	return out
+func (u Uint128) Gop_Not() Uint128 {
+	return Uint128{hi: ^u.hi, lo: ^u.lo}
 }
 
-func (u Uint128) Gop_Or__1(n Uint128) (out Uint128) {
-	out.hi = u.hi | n.hi
-	out.lo = u.lo | n.lo
-	return out
+func (u Uint128) Gop_Or__1(n Uint128) Uint128 {
+	u.hi |= n.hi
+	u.lo |= n.lo
+	return u
 }
 
 func (u Uint128) Gop_Or__0(n uint64) Uint128 {
-	u.lo = u.lo | n
+	u.lo |= n
 	return u
 }
 
 func (u Uint128) Gop_Xor__1(v Uint128) Uint128 {
-	u.hi = u.hi ^ v.hi
-	u.lo = u.lo ^ v.lo
+	u.hi ^= v.hi
+	u.lo ^= v.lo
 	return u
 }
 
 func (u Uint128) Gop_Xor__0(v uint64) Uint128 {
-	u.hi = u.hi ^ 0
-	u.lo = u.lo ^ v
+	u.lo ^= v
 	return u
 }
 
-func (u Uint128) Gop_Lsh(n Gop_ninteger) (v Uint128) {
-	if n == 0 {
-		return u
-	} else if n > 64 {
-		v.hi = u.lo << (n - 64)
-		v.lo = 0
-	} else if n < 64 {
-		v.hi = (u.hi << n) | (u.lo >> (64 - n))
-		v.lo = u.lo << n
-	} else if n == 64 {
-		v.hi = u.lo
-		v.lo = 0
+func (u Uint128) Gop_Lsh(n Gop_ninteger) Uint128 {
+	if n < 64 {
+		u.hi = (u.hi << n) | (u.lo >> (64 - n))
+		u.lo <<= n
+	} else {
+		u.hi = u.lo << (n - 64)
+		u.lo = 0
 	}
-	return v
+	return u
 }
 
-func (u Uint128) Gop_Rsh(n Gop_ninteger) (v Uint128) {
-	if n == 0 {
-		return u
-	} else if n > 64 {
-		v.lo = u.hi >> (n - 64)
-		v.hi = 0
-	} else if n < 64 {
-		v.lo = (u.lo >> n) | (u.hi << (64 - n))
-		v.hi = u.hi >> n
-	} else if n == 64 {
-		v.lo = u.hi
-		v.hi = 0
+func (u Uint128) Gop_Rsh(n Gop_ninteger) Uint128 {
+	if n < 64 {
+		u.lo = (u.lo >> n) | (u.hi << (64 - n))
+		u.hi >>= n
+	} else {
+		u.lo = u.hi >> (n - 64)
+		u.hi = 0
 	}
-
-	return v
+	return u
 }
 
 func (u Uint128) Gop_Mul__1(n Uint128) Uint128 {
@@ -623,7 +678,7 @@ func (u Uint128) QuoRem__1(by Uint128) (q, r Uint128) {
 	byTrailing0 := uint(by.TrailingZeros())
 	if (byLeading0 + byTrailing0) == 127 {
 		q = u.Gop_Rsh(byTrailing0)
-		by = by.Gop_Dec()
+		by.Gop_Dec()
 		r = by.Gop_And__1(u)
 		return
 	}
@@ -821,14 +876,14 @@ func quorem128by128(m, v Uint128, vHiLeading0, vLoLeading0 uint) (q, r Uint128)
 		q1 = q1.Gop_Rsh(63 - vHiLeading0)
 
 		if q1.hi|q1.lo != 0 {
-			q1 = q1.Gop_Dec()
+			q1.Gop_Dec()
 		}
 		q = q1
 		q1 = q1.Gop_Mul__1(v)
 		r = m.Gop_Sub__1(q1)
 
 		if r.Cmp__1(v) >= 0 {
-			q = q.Gop_Inc()
+			q.Gop_Inc()
 			r = r.Gop_Sub__1(v)
 		}
 
diff --git a/cl/compile.go b/cl/compile.go
index 4c0e2217..b74fa9d5 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -779,7 +779,6 @@ var binaryGopNames = map[string]string{
 	"<<=": "Gop_LshAssign",
 	">>=": "Gop_RshAssign",
 	"&^=": "Gop_AndNotAssign",
-	"=":   "Gop_Assign",
 
 	"==": "Gop_EQ",
 	"!=": "Gop_NE",
@@ -798,7 +797,7 @@ var unaryGopNames = map[string]string{
 	"++": "Gop_Inc",
 	"--": "Gop_Dec",
 	"-":  "Gop_Neg",
-	"+":  "Gop_Pos",
+	"+":  "Gop_Dup",
 	"^":  "Gop_Not",
 	"!":  "Gop_LNot",
 	"<-": "Gop_Recv",
diff --git a/cl/expr.go b/cl/expr.go
index 1945aa2a..4535527c 100644
--- a/cl/expr.go
+++ b/cl/expr.go
@@ -59,6 +59,7 @@ const (
 	clIdentLHS
 	clIdentSelectorExpr
 	clIdentGoto
+	clCallWithTwoValue
 )
 
 func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) *gox.PkgRef {
@@ -179,7 +180,11 @@ func compileExpr(ctx *blockCtx, expr ast.Expr, twoValue ...bool) {
 	case *ast.BasicLit:
 		compileBasicLit(ctx, v)
 	case *ast.CallExpr:
-		compileCallExpr(ctx, v, 0)
+		flags := 0
+		if twoValue != nil && twoValue[0] {
+			flags = clCallWithTwoValue
+		}
+		compileCallExpr(ctx, v, flags)
 	case *ast.SelectorExpr:
 		compileSelectorExpr(ctx, v, clIdentAutoCall)
 	case *ast.BinaryExpr:
@@ -409,18 +414,25 @@ func (p *fnType) initWith(fnt types.Type, idx, nin int) {
 	}
 }
 
-func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, flags int) {
+func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) {
 	switch fn := v.Fun.(type) {
 	case *ast.Ident:
-		compileIdent(ctx, fn, clIdentAllowBuiltin|flags)
+		compileIdent(ctx, fn, clIdentAllowBuiltin|inFlags)
 	case *ast.SelectorExpr:
 		compileSelectorExpr(ctx, fn, 0)
 	default:
 		compileExpr(ctx, fn)
 	}
 	var fn fnType
-	fnt := ctx.cb.Get(-1).Type
-	ellipsis := v.Ellipsis != gotoken.NoPos
+	var fnt = ctx.cb.Get(-1).Type
+	var flags gox.InstrFlags
+	var ellipsis = v.Ellipsis != gotoken.NoPos
+	if ellipsis {
+		flags = gox.InstrFlagEllipsis
+	}
+	if (inFlags & clCallWithTwoValue) != 0 {
+		flags |= gox.InstrFlagTwoValue
+	}
 	for i, arg := range v.Args {
 		switch expr := arg.(type) {
 		case *ast.LambdaExpr:
@@ -438,7 +450,7 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, flags int) {
 			compileExpr(ctx, arg)
 		}
 	}
-	ctx.cb.CallWith(len(v.Args), ellipsis, v)
+	ctx.cb.CallWith(len(v.Args), flags, v)
 }
 
 type clLambaFlag string
diff --git a/go.mod b/go.mod
index 6c6e02df..e5866bfc 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/goplus/gop
 go 1.16
 
 require (
-	github.com/goplus/gox v1.10.7
+	github.com/goplus/gox v1.10.8
 	github.com/qiniu/x v1.11.5
 	golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3
 	golang.org/x/tools v0.1.10
diff --git a/go.sum b/go.sum
index e785d092..4514d140 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
-github.com/goplus/gox v1.10.7 h1:OeoppVRhcNuuze2Dxy3fwY26iKB8O39Y/Ba5TuKuH9Y=
-github.com/goplus/gox v1.10.7/go.mod h1:gu7fuQF8RmWPZUjd+tEJGuV3m/vOEv0bHrct0x/KatM=
+github.com/goplus/gox v1.10.8 h1:Dra25Sxz1BOIzREFqMwfc+yGDA1GoEBzUHMqKaC7EKg=
+github.com/goplus/gox v1.10.8/go.mod h1:gu7fuQF8RmWPZUjd+tEJGuV3m/vOEv0bHrct0x/KatM=
 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.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=


Test patch:
diff --git a/cl/run_test.go b/cl/run_test.go
index daa71d4f..4687d724 100644
--- a/cl/run_test.go
+++ b/cl/run_test.go
@@ -118,22 +118,46 @@ func testRunType(t *testing.T, typ, gopcodeT, expected string) {
 // -----------------------------------------------------------------------------
 
 const (
-	testType_println_code, testType_println_ret = `
+	testType_inc_code, testType_inc_ret = `
 {
 	var x $(type) = 1
+	var y = +x
+	x++
+	x+=10
+	println x, y
+}
+`, `12 1
+`
+	testType_dec_code, testType_dec_ret = `
+{
+	var x $(type) = 0
+	x--
 	println x
 }
-`, `1
+`, `-1
 `
 	testType_init_code, testType_init_ret = `
 {
 	var x $(type) = 1 << 65
-	var y = x + 1
+	var y = x >> 63
+	var z = x >> 65
 	println x
-	println y
+	println y, z
 }
 `, `36893488147419103232
-36893488147419103233
+4 1
+`
+	testType_twoval_code, testType_twoval_ret = `
+{
+	var x $(type) = 1 << 65
+	var y = (x >> 2) - 1
+	v1, ok1 := int64(x)
+	v2, ok2 := int64(y)
+	println v1, ok1
+	println v2, ok2
+}
+`, `0 false
+9223372036854775807 true
 `
 	testType_cast_code, testType_cast_ret = `
 {
@@ -161,22 +185,22 @@ import "fmt"
 )
 
 const (
-	testType_noscanf_code, testType_noscanf_ret = testType_println_code + testType_init_code + testType_cast_code + testType_printf_code,
-		testType_println_ret + testType_init_ret + testType_cast_ret + testType_printf_ret
-	testType_all_code, testType_all_ret = testTypescanf_code + testType_noscanf_code,
-		testType_scanf_ret + testType_noscanf_ret
+	testType_com_code, testType_com_ret = testType_inc_code + testType_init_code + testType_cast_code + testType_printf_code + testType_twoval_code,
+		testType_inc_ret + testType_init_ret + testType_cast_ret + testType_printf_ret + testType_twoval_ret
+	testType_fixint_code, testType_fixint_ret = testTypescanf_code + testType_com_code,
+		testType_scanf_ret + testType_com_ret
 )
 
 func TestUint128_run(t *testing.T) {
-	testRunType(t, "uint128", testType_all_code, testType_all_ret)
+	testRunType(t, "uint128", testType_fixint_code, testType_fixint_ret)
 }
 
 func TestInt128_run(t *testing.T) {
-	testRunType(t, "int128", testType_all_code, testType_all_ret)
+	testRunType(t, "int128", testType_fixint_code+testType_dec_code, testType_fixint_ret+testType_dec_ret)
 }
 
 func TestBigint_run(t *testing.T) {
-	testRunType(t, "bigint", testType_noscanf_code, testType_noscanf_ret)
+	testRunType(t, "bigint", testType_com_code+testType_dec_code, testType_com_ret+testType_dec_ret)
 }
 
 // -----------------------------------------------------------------------------