improve handling of closures (in progress)
This commit is contained in:
25
_test/a16.go
Normal file
25
_test/a16.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a := [6]int{1, 2, 3, 4, 5, 6}
|
||||
println(a[1]) // 2
|
||||
for k := 0; k < 2; k++ {
|
||||
for i, v := range a {
|
||||
println(v)
|
||||
if i == 3 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 2
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
11
_test/a17.go
Normal file
11
_test/a17.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := make([]int, 2, 7)
|
||||
fmt.Println(a, len(a), cap(a))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [0 0] 2 7
|
||||
@@ -2,12 +2,13 @@ package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
var (
|
||||
samples = []int{}
|
||||
b = 1
|
||||
)
|
||||
//var (
|
||||
// samples = []int{}
|
||||
// b = 1
|
||||
//)
|
||||
|
||||
func main() {
|
||||
var samples = []int{}
|
||||
samples = append(samples, 1)
|
||||
fmt.Println(samples)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ package main
|
||||
type adder func(int, int) int
|
||||
|
||||
func genAdd(k int) adder {
|
||||
println("k:", k)
|
||||
return func(i, j int) int {
|
||||
return i + j
|
||||
println("#1 k:", k)
|
||||
return i + j + k
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +16,4 @@ func main() {
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 7
|
||||
// 12
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
dict := map[string]string{}
|
||||
dict["truc"] = "machin"
|
||||
//dict := map[string]string{}
|
||||
dict := map[string]string{"bidule": "machin", "truc": "bidule"}
|
||||
//println(dict)
|
||||
//dict["truc"] = "machin"
|
||||
//println(dict)
|
||||
println(dict["truc"])
|
||||
}
|
||||
|
||||
|
||||
12
_test/map6.go
Normal file
12
_test/map6.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
dict := map[string]string{"bidule": "machin", "truc": "chouette"}
|
||||
for k, v := range dict {
|
||||
println(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Output:
|
||||
// bidule machin
|
||||
// truc chouette
|
||||
28
_test/struct8.go
Normal file
28
_test/struct8.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
type T3 struct {
|
||||
k int
|
||||
}
|
||||
|
||||
type T2 struct {
|
||||
h int
|
||||
T3
|
||||
}
|
||||
|
||||
type T struct {
|
||||
f int
|
||||
g int
|
||||
T2
|
||||
}
|
||||
|
||||
func f(i int) int { return i * i }
|
||||
|
||||
func main() {
|
||||
a := T{5, 7, T2{8, T3{9}}}
|
||||
//println(a.f, a.g, a.T2.h, a.T2.T3.k)
|
||||
//fmt.Println(a.T2)
|
||||
println(a.h)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 5 7 8 9
|
||||
@@ -221,6 +221,7 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
|
||||
scope.sym[name] = &Symbol{index: scope.size, kind: Var}
|
||||
}
|
||||
if n.child[1].action == GetFunc {
|
||||
log.Println(n.index, "assign getFunc")
|
||||
scope.sym[name].index = -1
|
||||
scope.sym[name].node = n.child[1]
|
||||
}
|
||||
@@ -488,19 +489,11 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
|
||||
n.typ = &Type{cat: ValueT}
|
||||
} else {
|
||||
n.val = sym.node
|
||||
if def := n.val.(*Node); def != nil {
|
||||
// Reserve as many frame entries as nb of ret values for called function
|
||||
// node frame index should point to the first entry
|
||||
j := len(def.child[2].child) - 1
|
||||
l := len(def.child[2].child[j].child) // Number of return values for def
|
||||
if l == 1 {
|
||||
// If def returns exactly one value, propagate its type in call node.
|
||||
// Multiple return values will be handled differently through AssignX.
|
||||
n.typ = scope.getType(def.child[2].child[j].child[0].child[0].ident)
|
||||
}
|
||||
n.fsize = l
|
||||
} else {
|
||||
log.Println(n.index, "call to unknown def", n.child[0].ident, sym.typ)
|
||||
n.fsize = len(sym.typ.ret)
|
||||
if n.fsize == 1 {
|
||||
// If called func returns exactly one value, propagate its type in call node.
|
||||
// Multiple return values will be handled differently through AssignX.
|
||||
n.typ = sym.typ.ret[0]
|
||||
}
|
||||
}
|
||||
} else if n.child[0].kind == SelectorSrc {
|
||||
@@ -569,6 +562,7 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
|
||||
} else {
|
||||
for _, f := range n.child[:l] {
|
||||
scope.sym[f.ident].typ = n.typ
|
||||
f.typ = n.typ
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,7 +654,7 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
|
||||
interp.scope[pkgName].sym[funcName].typ = n.typ
|
||||
interp.scope[pkgName].sym[funcName].kind = Func
|
||||
interp.scope[pkgName].sym[funcName].node = n
|
||||
n.types = frameTypes(n.child[3], n.flen)
|
||||
n.types = frameTypes(n, n.flen)
|
||||
|
||||
case FuncLit:
|
||||
n.typ = n.child[2].typ
|
||||
@@ -668,8 +662,7 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
|
||||
n.flen = scope.size + 1
|
||||
scope = scope.pop()
|
||||
funcDef = true
|
||||
n.types = frameTypes(n.child[3], n.flen)
|
||||
n.start = n.child[3].start
|
||||
n.types = frameTypes(n, n.flen)
|
||||
|
||||
case FuncType:
|
||||
n.typ = nodeType(interp, scope, n)
|
||||
@@ -965,12 +958,6 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
|
||||
}
|
||||
})
|
||||
|
||||
//root.Walk(func(n *Node) bool {
|
||||
// n.value = genValue(n)
|
||||
// //n.pvalue = genPvalue(n)
|
||||
// return true
|
||||
//}, nil)
|
||||
|
||||
return initNodes
|
||||
}
|
||||
|
||||
@@ -1098,7 +1085,10 @@ func valueGenerator(n *Node, i int) func(*Frame) reflect.Value {
|
||||
case 0:
|
||||
return func(f *Frame) reflect.Value { return f.data[i] }
|
||||
case 1:
|
||||
return func(f *Frame) reflect.Value { return f.anc.data[i] }
|
||||
return func(f *Frame) reflect.Value {
|
||||
//log.Println(n.index, i, f.anc.data[i])
|
||||
return f.anc.data[i]
|
||||
}
|
||||
case 2:
|
||||
return func(f *Frame) reflect.Value { return f.anc.anc.data[i] }
|
||||
default:
|
||||
@@ -1178,14 +1168,18 @@ func frameTypes(node *Node, size int) []reflect.Type {
|
||||
ft := make([]reflect.Type, size)
|
||||
|
||||
node.Walk(func(n *Node) bool {
|
||||
if n.kind == FuncDecl || n.kind == ImportDecl || n.kind == TypeDecl {
|
||||
return false
|
||||
if n.kind == FuncDecl || n.kind == ImportDecl || n.kind == TypeDecl || n.kind == FuncLit {
|
||||
return n == node // Do not dive in substree, except if this the entry point
|
||||
}
|
||||
if n.typ == nil || n.level > 0 || n.kind == BasicLit || n.kind == SelectorSrc {
|
||||
return true
|
||||
}
|
||||
if ft[n.findex] == nil {
|
||||
ft[n.findex] = n.typ.TypeOf()
|
||||
if n.typ.cat == FuncT {
|
||||
ft[n.findex] = reflect.TypeOf(n)
|
||||
} else {
|
||||
ft[n.findex] = n.typ.TypeOf()
|
||||
}
|
||||
} else {
|
||||
// TODO: Check that type is identical
|
||||
}
|
||||
|
||||
@@ -2,6 +2,32 @@ package interp
|
||||
|
||||
// Do not edit! File generated by ../_test/gen_example.sh
|
||||
|
||||
func Example_a1() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a := [6]int{1, 2, 3, 4, 5, 6}
|
||||
println(a[1]) // 2
|
||||
for i, v := range a {
|
||||
println(v)
|
||||
if i == 3 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 2
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
}
|
||||
|
||||
func Example_a10() {
|
||||
src := `
|
||||
package main
|
||||
@@ -125,17 +151,19 @@ func main() {
|
||||
|
||||
}
|
||||
|
||||
func Example_a1() {
|
||||
func Example_a16() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a := [6]int{1, 2, 3, 4, 5, 6}
|
||||
println(a[1]) // 2
|
||||
for i, v := range a {
|
||||
println(v)
|
||||
if i == 3 {
|
||||
break
|
||||
for k := 0; k < 2; k++ {
|
||||
for i, v := range a {
|
||||
println(v)
|
||||
if i == 3 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,6 +177,28 @@ func main() {
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
}
|
||||
|
||||
func Example_a17() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := make([]int, 2, 7)
|
||||
fmt.Println(a, len(a), cap(a))
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// [0 0] 2 7
|
||||
}
|
||||
|
||||
func Example_a2() {
|
||||
@@ -292,12 +342,13 @@ package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
var (
|
||||
samples = []int{}
|
||||
b = 1
|
||||
)
|
||||
//var (
|
||||
// samples = []int{}
|
||||
// b = 1
|
||||
//)
|
||||
|
||||
func main() {
|
||||
var samples = []int{}
|
||||
samples = append(samples, 1)
|
||||
fmt.Println(samples)
|
||||
}
|
||||
@@ -357,20 +408,6 @@ func main() {
|
||||
// 1 2
|
||||
}
|
||||
|
||||
func Example_bool0() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println(true)
|
||||
}`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
}
|
||||
|
||||
func Example_bool() {
|
||||
src := `
|
||||
package main
|
||||
@@ -388,6 +425,20 @@ func main() {
|
||||
// false true
|
||||
}
|
||||
|
||||
func Example_bool0() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println(true)
|
||||
}`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
}
|
||||
|
||||
func Example_chan0() {
|
||||
src := `
|
||||
package main
|
||||
@@ -630,6 +681,30 @@ func main() { println(a, b, c) }
|
||||
// 1 2 3
|
||||
}
|
||||
|
||||
func Example_cont() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func main() {
|
||||
for i := 0; i < 10; i++ {
|
||||
if i < 5 {
|
||||
continue
|
||||
}
|
||||
println(i)
|
||||
}
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 5
|
||||
// 6
|
||||
// 7
|
||||
// 8
|
||||
// 9
|
||||
}
|
||||
|
||||
func Example_cont0() {
|
||||
src := `
|
||||
package main
|
||||
@@ -692,30 +767,6 @@ func main() {
|
||||
// 10
|
||||
}
|
||||
|
||||
func Example_cont() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func main() {
|
||||
for i := 0; i < 10; i++ {
|
||||
if i < 5 {
|
||||
continue
|
||||
}
|
||||
println(i)
|
||||
}
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 5
|
||||
// 6
|
||||
// 7
|
||||
// 8
|
||||
// 9
|
||||
}
|
||||
|
||||
func Example_export0() {
|
||||
src := `
|
||||
package main
|
||||
@@ -742,6 +793,27 @@ func (s *Sample) Test() {
|
||||
|
||||
}
|
||||
|
||||
func Example_fib() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
// Compute fibonacci numbers, no memoization
|
||||
func fib(n int) int {
|
||||
if n < 2 {
|
||||
return n
|
||||
}
|
||||
return fib(n-2) + fib(n-1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
println(fib(35))
|
||||
//println(fib(10))
|
||||
}`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
}
|
||||
|
||||
func Example_fib0() {
|
||||
src := `
|
||||
package main
|
||||
@@ -765,27 +837,6 @@ func main() {
|
||||
// 3
|
||||
}
|
||||
|
||||
func Example_fib() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
// Compute fibonacci numbers, no memoization
|
||||
func fib(n int) int {
|
||||
if n < 2 {
|
||||
return n
|
||||
}
|
||||
return fib(n-2) + fib(n-1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
println(fib(35))
|
||||
//println(fib(10))
|
||||
}`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
}
|
||||
|
||||
func Example_for0() {
|
||||
src := `
|
||||
package main
|
||||
@@ -862,6 +913,23 @@ func main() {
|
||||
// 4
|
||||
}
|
||||
|
||||
func Example_fun() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func f(i int) int { return i + 15 }
|
||||
|
||||
func main() {
|
||||
println(f(4))
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 19
|
||||
}
|
||||
|
||||
func Example_fun2() {
|
||||
src := `
|
||||
package main
|
||||
@@ -920,23 +988,6 @@ func main() {
|
||||
// ok
|
||||
}
|
||||
|
||||
func Example_fun() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func f(i int) int { return i + 15 }
|
||||
|
||||
func main() {
|
||||
println(f(4))
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 19
|
||||
}
|
||||
|
||||
func Example_goroutine() {
|
||||
src := `
|
||||
package main
|
||||
@@ -1181,38 +1232,6 @@ func main() {
|
||||
|
||||
}
|
||||
|
||||
func Example_iota0() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const (
|
||||
Foo = iota
|
||||
Bar
|
||||
Baz
|
||||
)
|
||||
|
||||
const (
|
||||
Asm = iota
|
||||
C
|
||||
Java
|
||||
Go
|
||||
)
|
||||
|
||||
fmt.Println(Foo, Bar, Baz)
|
||||
fmt.Println(Asm, C, Java, Go)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 0 1 2
|
||||
// 0 1 2 3
|
||||
}
|
||||
|
||||
func Example_iota() {
|
||||
src := `
|
||||
package main
|
||||
@@ -1245,6 +1264,38 @@ func main() {
|
||||
// 0 1 2 3
|
||||
}
|
||||
|
||||
func Example_iota0() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const (
|
||||
Foo = iota
|
||||
Bar
|
||||
Baz
|
||||
)
|
||||
|
||||
const (
|
||||
Asm = iota
|
||||
C
|
||||
Java
|
||||
Go
|
||||
)
|
||||
|
||||
fmt.Println(Foo, Bar, Baz)
|
||||
fmt.Println(Asm, C, Java, Go)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 0 1 2
|
||||
// 0 1 2 3
|
||||
}
|
||||
|
||||
func Example_ioutil() {
|
||||
src := `
|
||||
package main
|
||||
@@ -1288,7 +1339,7 @@ func Example_l3() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func myprint(i int) { println(i) }
|
||||
//func myprint(i int) { println(i) }
|
||||
|
||||
func main() {
|
||||
for a := 0; a < 20000000; a++ {
|
||||
@@ -1317,6 +1368,44 @@ func f(i int) int { return i + 1 }
|
||||
// 6
|
||||
}
|
||||
|
||||
func Example_l5() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
//func myprint(i int) { println(i) }
|
||||
|
||||
func main() {
|
||||
for a := 0; a < 20000000; {
|
||||
if a&0x8ffff == 0x80000 {
|
||||
println(a)
|
||||
}
|
||||
a = a + 1
|
||||
}
|
||||
}`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
}
|
||||
|
||||
func Example_map() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type Dict map[string]string
|
||||
|
||||
func main() {
|
||||
dict := make(Dict)
|
||||
dict["truc"] = "machin"
|
||||
println(dict["truc"])
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// machin
|
||||
}
|
||||
|
||||
func Example_map2() {
|
||||
src := `
|
||||
package main
|
||||
@@ -1339,8 +1428,11 @@ func Example_map3() {
|
||||
package main
|
||||
|
||||
func main() {
|
||||
dict := map[string]string{}
|
||||
dict["truc"] = "machin"
|
||||
//dict := map[string]string{}
|
||||
dict := map[string]string{"bidule": "machin", "truc": "bidule"}
|
||||
//println(dict)
|
||||
//dict["truc"] = "machin"
|
||||
//println(dict)
|
||||
println(dict["truc"])
|
||||
}
|
||||
`
|
||||
@@ -1389,23 +1481,23 @@ func main() {
|
||||
// false
|
||||
}
|
||||
|
||||
func Example_map() {
|
||||
func Example_map6() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type Dict map[string]string
|
||||
|
||||
func main() {
|
||||
dict := make(Dict)
|
||||
dict["truc"] = "machin"
|
||||
println(dict["truc"])
|
||||
dict := map[string]string{"bidule": "machin", "truc": "chouette"}
|
||||
for k, v := range dict {
|
||||
println(k, v)
|
||||
}
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// machin
|
||||
// bidule machin
|
||||
// truc chouette
|
||||
}
|
||||
|
||||
func Example_math0() {
|
||||
@@ -1428,6 +1520,28 @@ func main() {
|
||||
// -1
|
||||
}
|
||||
|
||||
func Example_method() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type Coord struct {
|
||||
x, y int
|
||||
}
|
||||
|
||||
func (c Coord) dist() int { return c.x*c.x + c.y*c.y }
|
||||
|
||||
func main() {
|
||||
o := Coord{3, 4}
|
||||
println(o.dist())
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 25
|
||||
}
|
||||
|
||||
func Example_method0() {
|
||||
src := `
|
||||
package main
|
||||
@@ -1468,6 +1582,31 @@ func main() {
|
||||
// Baz Called
|
||||
}
|
||||
|
||||
func Example_method1() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type Sample struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (s *Sample) foo(i int) {
|
||||
println("in foo", s.Name, i)
|
||||
}
|
||||
|
||||
func main() {
|
||||
sample := Sample{"hello"}
|
||||
s := &sample
|
||||
s.foo(3)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// in foo hello 3
|
||||
}
|
||||
|
||||
func Example_method10() {
|
||||
src := `
|
||||
package main
|
||||
@@ -1512,31 +1651,6 @@ type Coord struct {
|
||||
// 25
|
||||
}
|
||||
|
||||
func Example_method1() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type Sample struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (s *Sample) foo(i int) {
|
||||
println("in foo", s.Name, i)
|
||||
}
|
||||
|
||||
func main() {
|
||||
sample := Sample{"hello"}
|
||||
s := &sample
|
||||
s.foo(3)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// in foo hello 3
|
||||
}
|
||||
|
||||
func Example_method2() {
|
||||
src := `
|
||||
package main
|
||||
@@ -1773,28 +1887,6 @@ func (c Coord) dist() int { return c.x*c.x + c.y*c.y }
|
||||
// 25
|
||||
}
|
||||
|
||||
func Example_method() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type Coord struct {
|
||||
x, y int
|
||||
}
|
||||
|
||||
func (c Coord) dist() int { return c.x*c.x + c.y*c.y }
|
||||
|
||||
func main() {
|
||||
o := Coord{3, 4}
|
||||
println(o.dist())
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 25
|
||||
}
|
||||
|
||||
func Example_neg0() {
|
||||
src := `
|
||||
package main
|
||||
@@ -2018,6 +2110,26 @@ func main() {
|
||||
// 5
|
||||
}
|
||||
|
||||
func Example_ptr5() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type Foo struct {
|
||||
val int
|
||||
}
|
||||
|
||||
func main() {
|
||||
var a = &Foo{3}
|
||||
println(a.val)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
|
||||
func Example_ptr5a() {
|
||||
src := `
|
||||
package main
|
||||
@@ -2039,26 +2151,6 @@ func main() {
|
||||
// 3
|
||||
}
|
||||
|
||||
func Example_ptr5() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type Foo struct {
|
||||
val int
|
||||
}
|
||||
|
||||
func main() {
|
||||
var a = &Foo{3}
|
||||
println(a.val)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
|
||||
func Example_ptr6() {
|
||||
src := `
|
||||
package main
|
||||
@@ -2146,6 +2238,25 @@ func main() {
|
||||
// 2 3
|
||||
}
|
||||
|
||||
func Example_run1() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func f() (int, int) { return 2, 3 }
|
||||
|
||||
func g(i, j int) int { return i + j }
|
||||
|
||||
func main() {
|
||||
println(g(f()))
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 5
|
||||
}
|
||||
|
||||
func Example_run10() {
|
||||
src := `
|
||||
package main
|
||||
@@ -2218,25 +2329,6 @@ func f(a int) (int, int) {
|
||||
// 4 5
|
||||
}
|
||||
|
||||
func Example_run1() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func f() (int, int) { return 2, 3 }
|
||||
|
||||
func g(i, j int) int { return i + j }
|
||||
|
||||
func main() {
|
||||
println(g(f()))
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 5
|
||||
}
|
||||
|
||||
func Example_run4() {
|
||||
src := `
|
||||
package main
|
||||
@@ -2530,6 +2622,30 @@ func main() {
|
||||
// [6 7]
|
||||
}
|
||||
|
||||
func Example_server() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var v string = "v1.0"
|
||||
|
||||
func main() {
|
||||
a := "hello "
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "Welcome to my website! ", a, v)
|
||||
})
|
||||
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
}
|
||||
|
||||
func Example_server0() {
|
||||
src := `
|
||||
package main
|
||||
@@ -2555,6 +2671,33 @@ func main() {
|
||||
|
||||
}
|
||||
|
||||
func Example_server1() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Middleware struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (m *Middleware) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "Welcome to my website", m.Name)
|
||||
}
|
||||
|
||||
func main() {
|
||||
m := &Middleware{"Test"}
|
||||
http.HandleFunc("/", m.Handler)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
}
|
||||
|
||||
func Example_server1a() {
|
||||
src := `
|
||||
package main
|
||||
@@ -2588,33 +2731,6 @@ func main() {
|
||||
|
||||
}
|
||||
|
||||
func Example_server1() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Middleware struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (m *Middleware) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "Welcome to my website", m.Name)
|
||||
}
|
||||
|
||||
func main() {
|
||||
m := &Middleware{"Test"}
|
||||
http.HandleFunc("/", m.Handler)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
}
|
||||
|
||||
func Example_server2() {
|
||||
src := `
|
||||
package main
|
||||
@@ -2737,30 +2853,6 @@ func main() {
|
||||
|
||||
}
|
||||
|
||||
func Example_server() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var v string = "v1.0"
|
||||
|
||||
func main() {
|
||||
a := "hello "
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "Welcome to my website! ", a, v)
|
||||
})
|
||||
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
}
|
||||
|
||||
func Example_sieve() {
|
||||
src := `
|
||||
// A concurrent prime sieve
|
||||
@@ -2913,27 +3005,25 @@ func main() {
|
||||
// hello world
|
||||
}
|
||||
|
||||
func Example_struct0a() {
|
||||
func Example_struct() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type T struct {
|
||||
f int
|
||||
g int
|
||||
}
|
||||
|
||||
func main() {
|
||||
a := T{}
|
||||
println(a.f)
|
||||
a.f = 8
|
||||
println(a.f)
|
||||
a := T{7, 8}
|
||||
println(a.f, a.g)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// 8
|
||||
// 7 8
|
||||
}
|
||||
|
||||
func Example_struct0() {
|
||||
@@ -2957,6 +3047,29 @@ func main() {
|
||||
// 0 0
|
||||
}
|
||||
|
||||
func Example_struct0a() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type T struct {
|
||||
f int
|
||||
}
|
||||
|
||||
func main() {
|
||||
a := T{}
|
||||
println(a.f)
|
||||
a.f = 8
|
||||
println(a.f)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// 8
|
||||
}
|
||||
|
||||
func Example_struct1() {
|
||||
src := `
|
||||
package main
|
||||
@@ -3127,25 +3240,39 @@ func main() {
|
||||
|
||||
}
|
||||
|
||||
func Example_struct() {
|
||||
func Example_struct8() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
type T3 struct {
|
||||
k int
|
||||
}
|
||||
|
||||
type T2 struct {
|
||||
h int
|
||||
T3
|
||||
}
|
||||
|
||||
type T struct {
|
||||
f int
|
||||
g int
|
||||
T2
|
||||
}
|
||||
|
||||
func f(i int) int { return i * i }
|
||||
|
||||
func main() {
|
||||
a := T{7, 8}
|
||||
println(a.f, a.g)
|
||||
a := T{5, 7, T2{8, T3{9}}}
|
||||
//println(a.f, a.g, a.T2.h, a.T2.T3.k)
|
||||
//fmt.Println(a.T2)
|
||||
println(a.h)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 7 8
|
||||
// 5 7 8 9
|
||||
}
|
||||
|
||||
func Example_switch() {
|
||||
@@ -3438,6 +3565,22 @@ type T int
|
||||
// int
|
||||
}
|
||||
|
||||
func Example_var() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
func main() {
|
||||
var a, b, c int
|
||||
println(a, b, c)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 0 0 0
|
||||
}
|
||||
|
||||
func Example_var2() {
|
||||
src := `
|
||||
package main
|
||||
@@ -3486,20 +3629,25 @@ func main() {
|
||||
// 2 3
|
||||
}
|
||||
|
||||
func Example_var() {
|
||||
func Example_variadic() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func f(a ...int) {
|
||||
fmt.Println(a)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var a, b, c int
|
||||
println(a, b, c)
|
||||
f(1, 2, 3, 4)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// 0 0 0
|
||||
// [1 2 3 4]
|
||||
}
|
||||
|
||||
func Example_variadic0() {
|
||||
@@ -3522,24 +3670,3 @@ func main() {
|
||||
// Output:
|
||||
// hello []
|
||||
}
|
||||
|
||||
func Example_variadic() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func f(a ...int) {
|
||||
fmt.Println(a)
|
||||
}
|
||||
|
||||
func main() {
|
||||
f(1, 2, 3, 4)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"})
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4]
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ func (interp *Interpreter) run(n *Node, cf *Frame) {
|
||||
runCfg(n.start, f)
|
||||
}
|
||||
|
||||
/*
|
||||
func Run(def *Node, cf *Frame, recv *Node, rseq []int, args []*Node, rets []int, fork bool, goroutine bool) {
|
||||
//log.Println("run", def.index, def.child[1].ident, "allocate", def.flen)
|
||||
// Allocate a new Frame to store local variables
|
||||
@@ -132,6 +133,7 @@ func Run(def *Node, cf *Frame, recv *Node, rseq []int, args []*Node, rets []int,
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Functions set to run during execution of CFG
|
||||
|
||||
@@ -456,17 +458,9 @@ func (n *Node) wrapNode(in []reflect.Value) []reflect.Value {
|
||||
func call(n *Node) {
|
||||
//var recv *Node
|
||||
//var rseq []int
|
||||
//var forkFrame bool
|
||||
//forkFrame := n.action == CallF // add a frame indirection for closure
|
||||
goroutine := n.anc.kind == GoStmt
|
||||
|
||||
//if n.action == CallF {
|
||||
// forkFrame = true
|
||||
//}
|
||||
|
||||
//if n.anc.kind == GoStmt {
|
||||
// goroutine = true
|
||||
//}
|
||||
|
||||
//if n.child[0].kind == SelectorExpr && n.child[0].typ.cat != SrcPkgT && n.child[0].typ.cat != BinPkgT {
|
||||
// recv = n.child[0].recv
|
||||
// rseq = n.child[0].child[1].val.([]int)
|
||||
@@ -487,8 +481,15 @@ func call(n *Node) {
|
||||
ret[i] = n.findex + i
|
||||
}
|
||||
|
||||
//log.Println(n.index, "call", forkFrame)
|
||||
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
def := value(f).Interface().(*Node)
|
||||
//anc := f.anc
|
||||
//if forkFrame {
|
||||
// anc = f
|
||||
//}
|
||||
//nf := Frame{anc: anc, data: make([]reflect.Value, def.flen)}
|
||||
nf := Frame{anc: f, data: make([]reflect.Value, def.flen)}
|
||||
|
||||
// Init local frame values
|
||||
@@ -507,7 +508,6 @@ func call(n *Node) {
|
||||
if goroutine {
|
||||
go runCfg(def.child[3].start, &nf)
|
||||
} else {
|
||||
|
||||
runCfg(def.child[3].start, &nf)
|
||||
// Propagate return values to caller frame
|
||||
for i, r := range ret {
|
||||
|
||||
@@ -300,21 +300,6 @@ func (t *Type) zero() reflect.Value {
|
||||
case AliasT:
|
||||
return t.val.zero()
|
||||
|
||||
//case ArrayT:
|
||||
// //a := make([]interface{}, t.size)
|
||||
// //z := t.val.zero()
|
||||
// //for i := 0; i < t.size; i++ {
|
||||
// // a[i] = z
|
||||
// //}
|
||||
// //return a
|
||||
// if t.size > 0 {
|
||||
// log.Println("#1 zero array", t.size)
|
||||
// return reflect.New(t.TypeOf()).Elem()
|
||||
// //return reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(t.val.zero())), t.size, t.size)
|
||||
// } else {
|
||||
// return reflect.Zero(reflect.SliceOf(reflect.TypeOf(t.val.zero())))
|
||||
// }
|
||||
|
||||
case ArrayT, StructT:
|
||||
return reflect.New(t.TypeOf()).Elem()
|
||||
|
||||
@@ -457,7 +442,6 @@ func (t *Type) TypeOf() reflect.Type {
|
||||
return t.rtype
|
||||
|
||||
default:
|
||||
//return reflect.TypeOf(t.zero())
|
||||
return t.zero().Type()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user