mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-05 03:17:50 +08:00
pkg/eval: Use pseudo-structmap to implement closure introspection.
This commit is contained in:
parent
bd8130ee07
commit
5874863991
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/elves/elvish/pkg/eval/vals"
|
||||
"github.com/elves/elvish/pkg/eval/vars"
|
||||
"github.com/elves/elvish/pkg/parse"
|
||||
"github.com/elves/elvish/pkg/util"
|
||||
"github.com/xiaq/persistent/hash"
|
||||
)
|
||||
|
||||
|
@ -23,8 +22,8 @@ type Closure struct {
|
|||
Op effectOp
|
||||
Captured Ns
|
||||
SrcMeta parse.Source
|
||||
DefBegint int
|
||||
DefEnd int
|
||||
DefFrom int
|
||||
DefTo int
|
||||
}
|
||||
|
||||
var _ Callable = &Closure{}
|
||||
|
@ -49,29 +48,6 @@ func (c *Closure) Repr(int) string {
|
|||
return fmt.Sprintf("<closure %p>", c)
|
||||
}
|
||||
|
||||
// Index supports the introspection of the closure. Supported keys are
|
||||
// "arg-names", "rest-arg", "opt-names", "opt-defaults", "body", "def" and
|
||||
// "src".
|
||||
func (c *Closure) Index(k interface{}) (interface{}, bool) {
|
||||
switch k {
|
||||
case "arg-names":
|
||||
return listOfStrings(c.ArgNames), true
|
||||
case "rest-arg":
|
||||
return c.RestArg, true
|
||||
case "opt-names":
|
||||
return listOfStrings(c.OptNames), true
|
||||
case "opt-defaults":
|
||||
return vals.MakeList(c.OptDefaults...), true
|
||||
case "body":
|
||||
return c.SrcMeta.Code[c.Op.From:c.Op.To], true
|
||||
case "def":
|
||||
return c.SrcMeta.Code[c.DefBegint:c.DefEnd], true
|
||||
case "src":
|
||||
return c.SrcMeta, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func listOfStrings(ss []string) vals.List {
|
||||
list := vals.EmptyList
|
||||
for _, s := range ss {
|
||||
|
@ -80,12 +56,6 @@ func listOfStrings(ss []string) vals.List {
|
|||
return list
|
||||
}
|
||||
|
||||
// IterateKeys calls f with all the valid keys that can be used for Index.
|
||||
func (c *Closure) IterateKeys(f func(interface{}) bool) {
|
||||
util.Feed(f, "arg-names", "rest-arg",
|
||||
"opt-names", "opt-defaults", "body", "def", "src")
|
||||
}
|
||||
|
||||
// Call calls a closure.
|
||||
func (c *Closure) Call(fm *Frame, args []interface{}, opts map[string]interface{}) error {
|
||||
if c.RestArg != "" {
|
||||
|
@ -142,3 +112,26 @@ func (c *Closure) Call(fm *Frame, args []interface{}, opts map[string]interface{
|
|||
fm.srcMeta = c.SrcMeta
|
||||
return c.Op.exec(fm)
|
||||
}
|
||||
|
||||
func (c *Closure) Fields() vals.StructMap { return closureFields{c} }
|
||||
|
||||
type closureFields struct{ c *Closure }
|
||||
|
||||
func (closureFields) IsStructMap() {}
|
||||
|
||||
func (cf closureFields) ArgNames() vals.List { return listOfStrings(cf.c.ArgNames) }
|
||||
func (cf closureFields) RestArg() string { return cf.c.RestArg }
|
||||
func (cf closureFields) OptNames() vals.List { return listOfStrings(cf.c.OptNames) }
|
||||
func (cf closureFields) Src() parse.Source { return cf.c.SrcMeta }
|
||||
|
||||
func (cf closureFields) OptDefaults() vals.List {
|
||||
return vals.MakeList(cf.c.OptDefaults...)
|
||||
}
|
||||
|
||||
func (cf closureFields) Body() string {
|
||||
return cf.c.SrcMeta.Code[cf.c.Op.From:cf.c.Op.To]
|
||||
}
|
||||
|
||||
func (cf closureFields) Def() string {
|
||||
return cf.c.SrcMeta.Code[cf.c.DefFrom:cf.c.DefTo]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user