Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interp: recover in Eval and EvalPath #1560

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.*.swo
.*.swp
*.dot
*.out
.idea/
/yaegi
internal/cmd/extract/extract
Expand Down
9 changes: 9 additions & 0 deletions _test/assign19.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

func main() {
a, b, c := 1, 2
_, _, _ = a, b, c
}

// Error:
// _test/assign19.go:4:2: cannot assign 2 values to 3 variables
6 changes: 3 additions & 3 deletions _test/closure10.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ func main() {
}

// Output:
// 3 0 0
// 3 1 1
// 3 2 2
// 0 0 0
// 1 1 1
// 2 2 2
6 changes: 3 additions & 3 deletions _test/closure11.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ func main() {
}

// Output:
// 3 0
// 3 1
// 3 2
// 0 0
// 1 1
// 2 2
6 changes: 3 additions & 3 deletions _test/closure12.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ func main() {
}

// Output:
// 3 0 i=0
// 3 1 i=1
// 3 2 i=2
// 0 0 i=0
// 1 1 i=1
// 2 2 i=2
18 changes: 18 additions & 0 deletions _test/closure15.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

func main() {
foos := []func(){}

for i := range 3 {
a := i
foos = append(foos, func() { println(i, a) })
}
foos[0]()
foos[1]()
foos[2]()
}

// Output:
// 0 0
// 1 1
// 2 2
18 changes: 18 additions & 0 deletions _test/closure16.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

func main() {
foos := []func(){}

for i := range 3 {
a, b := i, i
foos = append(foos, func() { println(i, a, b) })
}
foos[0]()
foos[1]()
foos[2]()
}

// Output:
// 0 0 0
// 1 1 1
// 2 2 2
22 changes: 22 additions & 0 deletions _test/closure17.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package main

type T struct {
F func()
}

func main() {
foos := []T{}

for i := range 3 {
a := i
foos = append(foos, T{func() { println(i, a) }})
}
foos[0].F()
foos[1].F()
foos[2].F()
}

// Output:
// 0 0
// 1 1
// 2 2
25 changes: 25 additions & 0 deletions _test/closure18.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import "fmt"

type T struct {
F func()
}

func main() {
foos := []T{}

for i := range 3 {
a := i
n := fmt.Sprintf("i=%d", i)
foos = append(foos, T{func() { println(i, a, n) }})
}
foos[0].F()
foos[1].F()
foos[2].F()
}

// Output:
// 0 0 i=0
// 1 1 i=1
// 2 2 i=2
18 changes: 18 additions & 0 deletions _test/closure19.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

func main() {
foos := []func(){}

for i := 0; i < 3; i++ {
i := i
foos = append(foos, func() { println(i) })
}
foos[0]()
foos[1]()
foos[2]()
}

// Output:
// 0
// 1
// 2
18 changes: 18 additions & 0 deletions _test/closure20.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

func main() {
foos := []func(){}

for i := range 3 {
i := i
foos = append(foos, func() { println(i) })
}
foos[0]()
foos[1]()
foos[2]()
}

// Output:
// 0
// 1
// 2
6 changes: 3 additions & 3 deletions _test/closure9.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ func main() {
}

// Output:
// 3 0
// 3 1
// 3 2
// 0 0
// 1 1
// 2 2
13 changes: 13 additions & 0 deletions _test/for17.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package main

func main() {
mx := 3
for i := range mx {
println(i)
}
}

// Output:
// 0
// 1
// 2
12 changes: 12 additions & 0 deletions _test/for18.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

func main() {
for i := range 3 {
println(i)
}
}

// Output:
// 0
// 1
// 2
12 changes: 12 additions & 0 deletions _test/for19.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

func main() {
for range 3 {
println("i")
}
}

// Output:
// i
// i
// i
51 changes: 51 additions & 0 deletions _test/issue-1618.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"fmt"
"runtime"
"sync"
)

func humanizeBytes(bytes uint64) string {
const (
_ = iota
kB uint64 = 1 << (10 * iota)
mB
gB
tB
pB
)

switch {
case bytes < kB:
return fmt.Sprintf("%dB", bytes)
case bytes < mB:
return fmt.Sprintf("%.2fKB", float64(bytes)/float64(kB))
case bytes < gB:
return fmt.Sprintf("%.2fMB", float64(bytes)/float64(mB))
case bytes < tB:
return fmt.Sprintf("%.2fGB", float64(bytes)/float64(gB))
case bytes < pB:
return fmt.Sprintf("%.2fTB", float64(bytes)/float64(tB))
default:
return fmt.Sprintf("%dB", bytes)
}
}

func main() {
i := 0
wg := sync.WaitGroup{}

for {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("#%d: alloc = %s, routines = %d, gc = %d\n", i, humanizeBytes(m.Alloc), runtime.NumGoroutine(), m.NumGC)

wg.Add(1)
go func() {
wg.Done()
}()
wg.Wait()
i = i + 1
}
}
23 changes: 23 additions & 0 deletions _test/issue-1640.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"errors"
)

func ShortVariableDeclarations() (i int, err error) {
r, err := 1, errors.New("test")
i = r
return
}

func main() {
_, er := ShortVariableDeclarations()
if er != nil {
println("ShortVariableDeclarations ok")
} else {
println("ShortVariableDeclarations not ok")
}
}

// Output:
// ShortVariableDeclarations ok
12 changes: 12 additions & 0 deletions _test/issue-1653.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

func f(b uint) uint {
return uint(1) + (0x1 >> b)
}

func main() {
println(f(1))
}

// Output:
// 1
13 changes: 13 additions & 0 deletions _test/map31.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package main

func main() {
myMap := map[string]int{"a":2}

for s, _ := range myMap {
_ = s
}
println("ok")
}

// Output:
// ok
9 changes: 9 additions & 0 deletions _test/op10.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

func main() {
_ = 1 + 1
println("ok")
}

// Output:
// ok
10 changes: 10 additions & 0 deletions _test/op11.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

func main() {
a, b := 1, 2
_ = a + b
println("ok")
}

// Output:
// ok
17 changes: 16 additions & 1 deletion interp/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"go/parser"
"go/scanner"
"go/token"
"reflect"

Check failure on line 10 in interp/ast.go

View workflow job for this annotation

GitHub Actions / Linting

"reflect" imported and not used (typecheck)
"strconv"
"strings"
"sync/atomic"
Expand Down Expand Up @@ -431,11 +431,11 @@
func (interp *Interpreter) ast(f ast.Node) (string, *node, error) {
var err error
var root *node
var anc astNode

Check failure on line 434 in interp/ast.go

View workflow job for this annotation

GitHub Actions / Linting

anc declared and not used (typecheck)
var st nodestack
pkgName := "main"

addChild := func(root **node, anc astNode, pos token.Pos, kind nkind, act action) *node {

Check failure on line 438 in interp/ast.go

View workflow job for this annotation

GitHub Actions / Linting

addChild declared and not used (typecheck)
var i interface{}
nindex := atomic.AddInt64(&interp.nindex, 1)
n := &node{anc: anc.node, interp: interp, index: nindex, pos: pos, kind: kind, action: act, val: &i, gen: builtin[act]}
Expand Down Expand Up @@ -477,7 +477,7 @@
// A stack of ancestor nodes is used to keep track of current ancestor for each depth level
ast.Inspect(f, func(nod ast.Node) bool {
anc = st.top()
var pos token.Pos

Check failure on line 480 in interp/ast.go

View workflow job for this annotation

GitHub Actions / Linting

pos declared and not used (typecheck)
if nod != nil {
pos = nod.Pos()
}
Expand Down Expand Up @@ -597,7 +597,22 @@
st.push(addChild(&root, anc, pos, kind, act), nod)

case *ast.BlockStmt:
st.push(addChild(&root, anc, pos, blockStmt, aNop), nod)
b := addChild(&root, anc, pos, blockStmt, aNop)
st.push(b, nod)
var kind nkind
if anc.node != nil {
kind = anc.node.kind
}
switch kind {
case rangeStmt:
k := addChild(&root, astNode{b, nod}, pos, identExpr, aNop)
k.ident = "_"
v := addChild(&root, astNode{b, nod}, pos, identExpr, aNop)
v.ident = "_"
case forStmt7:
k := addChild(&root, astNode{b, nod}, pos, identExpr, aNop)
k.ident = "_"
}

case *ast.BranchStmt:
var kind nkind
Expand Down
Loading
Loading