Fix solving selector expression on binary object

This commit is contained in:
Marc Vertes
2018-11-20 12:21:01 +01:00
parent b3954838e9
commit 84d8456b92
5 changed files with 117 additions and 12 deletions

20
_test/cli0.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
resp, err := http.Get("http://localhost:8080/")
if err != nil {
log.Println(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err)
}
fmt.Println(string(body))
}

21
_test/ioutil0.go Normal file
View File

@@ -0,0 +1,21 @@
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
)
func main() {
r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.")
b, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", b)
}
// Output:
// Go is a general-purpose language designed with systems programming in mind.

View File

@@ -830,9 +830,24 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
n.gen = getIndexBinMethod
n.typ = &Type{cat: ValueT, rtype: method.Type}
n.fsize = method.Type.NumOut()
} else if n.typ.rtype.Kind() == reflect.Ptr {
if field, ok := n.typ.rtype.Elem().FieldByName(n.child[1].ident); ok {
n.typ = &Type{cat: ValueT, rtype: field.Type}
n.val = field.Index
n.gen = getPtrIndexBin
} else {
log.Println(n.index, "could not solve field or method", n.child[0].ident+"."+n.child[1].ident)
}
} else if n.typ.rtype.Kind() == reflect.Struct {
if field, ok := n.typ.rtype.FieldByName(n.child[1].ident); ok {
n.typ = &Type{cat: ValueT, rtype: field.Type}
n.val = field.Index
n.gen = getIndexSeq
} else {
log.Println(n.index, "could not solve field or method", n.child[0].ident+"."+n.child[1].ident)
}
} else {
// Method can be only resolved from value at execution
log.Println(n.index, "could not solve method")
log.Println(n.index, "could not solve field or method", n.child[0].ident+"."+n.child[1].ident)
n.gen = nop
}
} else if n.typ.cat == PtrT && n.typ.val.cat == ValueT {

View File

@@ -534,6 +534,33 @@ func main() {
// ping
}
func Example_cli0() {
src := `
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
resp, err := http.Get("http://localhost:8080/")
if err != nil {
log.Println(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err)
}
fmt.Println(string(body))
}`
i := NewInterpreter(Opt{Entry: "main"}, "cli0.go")
i.Eval(src)
}
func Example_closure0() {
src := `
package main
@@ -1471,6 +1498,34 @@ func main() {
// open __NotExisting__: no such file or directory
}
func Example_ioutil0() {
src := `
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
)
func main() {
r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.")
b, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", b)
}
`
i := NewInterpreter(Opt{Entry: "main"}, "ioutil0.go")
i.Eval(src)
// Output:
// Go is a general-purpose language designed with systems programming in mind.
}
func Example_l2() {
src := `
package main

View File

@@ -331,7 +331,6 @@ func addr(n *Node) {
next := getExec(n.tnext)
n.exec = func(f *Frame) Builtin {
log.Println(n.index, "addr", i)
f.data[i] = value(f).Addr()
return next
}
@@ -343,7 +342,6 @@ func deref(n *Node) {
next := getExec(n.tnext)
n.exec = func(f *Frame) Builtin {
log.Println(n.index, "deref", i)
f.data[i] = value(f).Elem()
return next
}
@@ -613,7 +611,6 @@ func callBin(n *Node) {
values = append(values, func(f *Frame) reflect.Value { return f.data[ind] })
}
} else {
//log.Println(n.index, "callbin#0", c.kind, c.typ.cat)
var argType reflect.Type
if variadic >= 0 && i >= variadic {
argType = funcType.In(variadic).Elem()
@@ -625,7 +622,6 @@ func callBin(n *Node) {
c.kind = Rvalue
} else if c.kind == BasicLit {
// Convert literal value (untyped) to function argument type (if not an interface{})
//log.Println(n.index, "callbin#1", c.val, argType, argType.Kind(), reflect.ValueOf(c.val).IsValid())
if argType != nil && argType.Kind() != reflect.Interface {
c.val = reflect.ValueOf(c.val).Convert(argType)
}
@@ -755,15 +751,13 @@ func getPtrIndex(n *Node) {
}
func getPtrIndexBin(n *Node) {
//i := n.findex
//fi := n.val.([]int)
//value := n.child[0].value
i := n.findex
fi := n.val.([]int)
value := genValue(n.child[0])
next := getExec(n.tnext)
n.exec = func(f *Frame) Builtin {
log.Println(n.index, "in getPtrIndexBin")
//a := reflect.ValueOf(value(f)).Elem()
//f.data[i] = a.FieldByIndex(fi).Interface()
f.data[i] = value(f).Elem().FieldByIndex(fi)
return next
}
}