Type assertion: add support for 2nd return value
This commit is contained in:
22
_test/context2.go
Normal file
22
_test/context2.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import "context"
|
||||
|
||||
func get(ctx context.Context, k string) string {
|
||||
var r string
|
||||
var ok bool
|
||||
if v := ctx.Value(k); v != nil {
|
||||
r, ok = v.(string)
|
||||
println(ok)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx := context.WithValue(context.Background(), "hello", "world")
|
||||
println(get(ctx, "hello"))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// world
|
||||
12
_test/type7.go
Normal file
12
_test/type7.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
var i interface{} = "hello"
|
||||
s, ok := i.(string)
|
||||
fmt.Println(s, ok)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
@@ -318,7 +318,9 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
|
||||
n.gen = nop
|
||||
|
||||
case TypeAssertExpr:
|
||||
types = append(types, n.child[l].child[1].typ, scope.getType("error"))
|
||||
types = append(types, n.child[l].child[1].typ, scope.getType("bool"))
|
||||
n.child[l].gen = typeAssert2
|
||||
n.gen = nop
|
||||
|
||||
default:
|
||||
log.Fatalln(n.index, "Assign expression unsupported:", n.child[l].kind)
|
||||
@@ -862,12 +864,13 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
|
||||
scope = scope.pop()
|
||||
|
||||
case TypeAssertExpr:
|
||||
// TODO: handle 2 return values variant
|
||||
if n.child[1].typ == nil {
|
||||
n.child[1].typ = scope.getType(n.child[1].ident)
|
||||
}
|
||||
n.typ = n.child[1].typ
|
||||
n.findex = scope.inc(interp)
|
||||
if n.anc.action != AssignX {
|
||||
n.typ = n.child[1].typ
|
||||
n.findex = scope.inc(interp)
|
||||
}
|
||||
|
||||
case SliceExpr, UnaryExpr:
|
||||
wireChild(n)
|
||||
|
||||
@@ -1291,6 +1291,35 @@ func main() {
|
||||
// world
|
||||
}
|
||||
|
||||
func Example_context2() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import "context"
|
||||
|
||||
func get(ctx context.Context, k string) string {
|
||||
var r string
|
||||
var ok bool
|
||||
if v := ctx.Value(k); v != nil {
|
||||
r, ok = v.(string)
|
||||
println(ok)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx := context.WithValue(context.Background(), "hello", "world")
|
||||
println(get(ctx, "hello"))
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"}, "context2.go")
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// world
|
||||
}
|
||||
|
||||
func Example_export0() {
|
||||
src := `
|
||||
package main
|
||||
@@ -4360,6 +4389,25 @@ type T int
|
||||
// int
|
||||
}
|
||||
|
||||
func Example_type7() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
var i interface{} = "hello"
|
||||
s, ok := i.(string)
|
||||
fmt.Println(s, ok)
|
||||
}
|
||||
`
|
||||
i := NewInterpreter(Opt{Entry: "main"}, "type7.go")
|
||||
i.Eval(src)
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func Example_var() {
|
||||
src := `
|
||||
package main
|
||||
|
||||
@@ -90,6 +90,27 @@ func typeAssert(n *Node) {
|
||||
}
|
||||
}
|
||||
|
||||
func typeAssert2(n *Node) {
|
||||
value := genValue(n.child[0]) // input value
|
||||
value0 := genValue(n.anc.child[0]) // returned result
|
||||
value1 := genValue(n.anc.child[1]) // returned status
|
||||
next := getExec(n.tnext)
|
||||
|
||||
if n.child[0].typ.cat == ValueT {
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value0(f).Set(value(f).Elem())
|
||||
value1(f).SetBool(true)
|
||||
return next
|
||||
}
|
||||
} else {
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value0(f).Set(value(f))
|
||||
value1(f).SetBool(true)
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func convert(n *Node) {
|
||||
i := n.findex
|
||||
var value func(*Frame) reflect.Value
|
||||
|
||||
Reference in New Issue
Block a user