Eval: wrap returned interpreter node into a callable function
This commit is contained in:
33
example/test_plugin/plugin/plugin.go
Normal file
33
example/test_plugin/plugin/plugin.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var version = "v1"
|
||||
|
||||
type Sample struct{ Name string }
|
||||
|
||||
func (s *Sample) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "Welcome to my website", s.Name, version)
|
||||
}
|
||||
|
||||
func Handler2(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "Welcome to my website", version)
|
||||
}
|
||||
|
||||
func NewSample(name string) func(http.ResponseWriter, *http.Request) {
|
||||
fmt.Println("in NewSample", name, version)
|
||||
s := &Sample{"test"}
|
||||
return s.Handler
|
||||
//return Handler2
|
||||
//return func(w http.ResponseWriter, r *http.Request) { return Handler2(w, r) }
|
||||
//return func(w http.ResponseWriter, r *http.Request) { return s.Handler(w, r) }
|
||||
}
|
||||
|
||||
//func main() {
|
||||
// s := &Sample{"Test"}
|
||||
// http.HandleFunc("/", s.Handler)
|
||||
// http.ListenAndServe(":8080", nil)
|
||||
//}
|
||||
40
example/test_plugin/server.go
Normal file
40
example/test_plugin/server.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/containous/dyngo/interp"
|
||||
"github.com/containous/dyngo/stdlib"
|
||||
)
|
||||
|
||||
// Plugin struct stores metadata for external modules
|
||||
type Plugin struct {
|
||||
Pkgname, Typename string
|
||||
Id int
|
||||
handler func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// Handler redirect http.Handler processing in the interpreter
|
||||
func (p *Plugin) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
p.handler(w, r)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Init go interpreter
|
||||
log.SetFlags(log.Lshortfile)
|
||||
//i := interp.NewInterpreter(interp.Opt{AstDot: true}, "")
|
||||
i := interp.NewInterpreter(interp.Opt{}, "")
|
||||
i.Import(stdlib.Value, stdlib.Type)
|
||||
|
||||
// Load plugin
|
||||
_, err := i.Eval(`import "github.com/containous/dyngo/example/test_plugin/plugin"`)
|
||||
log.Println("err:", err)
|
||||
|
||||
handler, err := i.Eval(`plugin.NewSample("test")`)
|
||||
log.Println("handler:", handler, "err:", err)
|
||||
p := &Plugin{"sample", "Middleware", 0, nil}
|
||||
p.handler = handler.Interface().(func(http.ResponseWriter, *http.Request))
|
||||
http.HandleFunc("/", p.Handler)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
BIN
example/test_plugin/test_plugin
Executable file
BIN
example/test_plugin/test_plugin
Executable file
Binary file not shown.
@@ -93,8 +93,6 @@ func NewInterpreter(opt Opt, name string) *Interpreter {
|
||||
Opt: opt,
|
||||
universe: initUniverse(),
|
||||
scope: map[string]*Scope{},
|
||||
//binValue: LibValueMap(stdlib.Value),
|
||||
//binType: LibTypeMap(stdlib.Type),
|
||||
binValue: LibValueMap{},
|
||||
binType: LibTypeMap{},
|
||||
Frame: &Frame{data: []reflect.Value{}},
|
||||
@@ -194,6 +192,13 @@ func (i *Interpreter) Eval(src string) (reflect.Value, error) {
|
||||
v := genValue(root)
|
||||
res = v(i.Frame)
|
||||
}
|
||||
|
||||
// If result is an interpreter node, wrap it in a runtime callable function
|
||||
if res.IsValid() {
|
||||
if n, ok := res.Interface().(*Node); ok {
|
||||
res = genNodeWrapper(n)(i.Frame)
|
||||
}
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ func (t *Type) TypeOf() reflect.Type {
|
||||
}
|
||||
return reflect.SliceOf(t.val.TypeOf())
|
||||
|
||||
case BuiltinT:
|
||||
case BinPkgT, BuiltinT, InterfaceT, SrcPkgT:
|
||||
return nil
|
||||
|
||||
case ChanT:
|
||||
@@ -456,9 +456,6 @@ func (t *Type) TypeOf() reflect.Type {
|
||||
}
|
||||
return reflect.FuncOf(in, out, false)
|
||||
|
||||
case InterfaceT:
|
||||
return nil
|
||||
|
||||
case MapT:
|
||||
return reflect.MapOf(t.key.TypeOf(), t.val.TypeOf())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user