mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-05 03:17:50 +08:00
Implement IndexerCaller.
Now we have M-expression!
This commit is contained in:
parent
a2635d78b7
commit
5609dd1a84
12
eval/call.go
12
eval/call.go
|
@ -27,19 +27,23 @@ type Caller interface {
|
|||
}
|
||||
|
||||
func mustCaller(v Value) Caller {
|
||||
caller, ok := getCaller(v)
|
||||
caller, ok := getCaller(v, true)
|
||||
if !ok {
|
||||
throw(fmt.Errorf("a %s is not callable", v.Kind()))
|
||||
}
|
||||
return caller
|
||||
}
|
||||
|
||||
func getCaller(v Value) (Caller, bool) {
|
||||
// getCaller adapts a Value to a Caller if there is an adapter. It adapts an
|
||||
// Indexer if adaptIndexer is true.
|
||||
func getCaller(v Value, adaptIndexer bool) (Caller, bool) {
|
||||
if caller, ok := v.(Caller); ok {
|
||||
return caller, true
|
||||
}
|
||||
if indexer, ok := getIndexer(v); ok {
|
||||
return IndexerCaller{indexer}, true
|
||||
if adaptIndexer {
|
||||
if indexer, ok := getIndexer(v, nil); ok {
|
||||
return IndexerCaller{indexer}, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
|
|
@ -411,7 +411,7 @@ func (cp *compiler) singleVariable(n *parse.Indexing, msg string) VariableOp {
|
|||
value := variable.Get()
|
||||
n := len(indexOps)
|
||||
for _, op := range indexOps[:n-1] {
|
||||
indexer := mustIndexer(value)
|
||||
indexer := mustIndexer(value, ec)
|
||||
|
||||
indicies := op(ec)
|
||||
values := indexer.Index(indicies)
|
||||
|
@ -700,7 +700,7 @@ func (cp *compiler) indexing(n *parse.Indexing) ValuesOp {
|
|||
indicies := indexOp(ec)
|
||||
newvs := make([]Value, 0, len(vs)*len(indicies))
|
||||
for _, v := range vs {
|
||||
newvs = append(newvs, mustIndexer(v).Index(indicies)...)
|
||||
newvs = append(newvs, mustIndexer(v, ec).Index(indicies)...)
|
||||
}
|
||||
vs = newvs
|
||||
}
|
||||
|
|
|
@ -24,21 +24,28 @@ type IndexSetter interface {
|
|||
IndexSet(idx Value, v Value)
|
||||
}
|
||||
|
||||
func mustIndexer(v Value) Indexer {
|
||||
indexer, ok := getIndexer(v)
|
||||
func mustIndexer(v Value, ec *EvalCtx) Indexer {
|
||||
indexer, ok := getIndexer(v, ec)
|
||||
if !ok {
|
||||
throw(fmt.Errorf("a %s is not indexable", v.Kind()))
|
||||
}
|
||||
return indexer
|
||||
}
|
||||
|
||||
func getIndexer(v Value) (Indexer, bool) {
|
||||
// getIndexer adapts a Value to an Indexer if there is an adapter. It adapts a
|
||||
// Caller if ec is not nil.
|
||||
func getIndexer(v Value, ec *EvalCtx) (Indexer, bool) {
|
||||
if indexer, ok := v.(Indexer); ok {
|
||||
return indexer, true
|
||||
}
|
||||
if indexOneer, ok := v.(IndexOneer); ok {
|
||||
return IndexOneerIndexer{indexOneer}, true
|
||||
}
|
||||
if ec != nil {
|
||||
if caller, ok := v.(Caller); ok {
|
||||
return CallerIndexer{caller, ec}, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
|
@ -104,16 +111,14 @@ func intIndex(idx Value) int {
|
|||
return i
|
||||
}
|
||||
|
||||
/*
|
||||
// CallerIndexer adapts a Caller to an Indexer.
|
||||
type CallerIndexer struct {
|
||||
Caller
|
||||
ec *EvalCtx
|
||||
}
|
||||
|
||||
func (ci CallerIndexer) Index(idx Value) Value {
|
||||
func (ci CallerIndexer) Index(idx []Value) []Value {
|
||||
return captureOutput(ci.ec, func(ec *EvalCtx) {
|
||||
ci.Caller.Call(ec, []Value{idx})
|
||||
ci.Caller.Call(ec, idx)
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user