mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-12 17:27:50 +08:00
Use outer product semantics for indexing.
This commit is contained in:
parent
b9a2693e57
commit
4b3d18442a
|
@ -617,22 +617,32 @@ func (cp *compiler) indexing(n *parse.Indexing) ValuesOp {
|
|||
|
||||
headOp := cp.primary(n.Head)
|
||||
indexOps := cp.arrays(n.Indicies)
|
||||
p := n.Begin()
|
||||
// p := n.Begin()
|
||||
indexPoses := make([]int, len(n.Indicies))
|
||||
for i, index := range n.Indicies {
|
||||
indexPoses[i] = index.Begin()
|
||||
}
|
||||
|
||||
return func(ec *EvalCtx) []Value {
|
||||
v := ec.must(headOp(ec), "the indexing value", p).mustOne()
|
||||
for i, indexOp := range indexOps {
|
||||
index := ec.must(indexOp(ec), "the index", p).mustOne()
|
||||
v = evalIndex(ec, v, index, p, indexPoses[i])
|
||||
vs := headOp(ec)
|
||||
for _, indexOp := range indexOps {
|
||||
index := indexOp(ec)
|
||||
vs = outerProduct(vs, index, func(l, r Value) Value {
|
||||
return mustIndexer(l).Index(r)
|
||||
})
|
||||
}
|
||||
return []Value{v}
|
||||
return vs
|
||||
}
|
||||
}
|
||||
|
||||
func mustIndexer(v Value) Indexer {
|
||||
indexer, ok := v.(Indexer)
|
||||
if !ok {
|
||||
throw(fmt.Errorf("%s value cannot be indexed", v.Kind()))
|
||||
}
|
||||
return indexer
|
||||
}
|
||||
|
||||
func literalValues(v ...Value) ValuesOp {
|
||||
return func(e *EvalCtx) []Value {
|
||||
return v
|
||||
|
|
|
@ -191,8 +191,7 @@ type IndexerCaller struct {
|
|||
func (ic IndexerCaller) Call(ec *EvalCtx, argVals []Value) {
|
||||
var v Value = ic.Indexer
|
||||
for _, idx := range argVals {
|
||||
// XXX the positions are obviously wrong.
|
||||
v = evalIndex(ec, v, idx, 0, 0)
|
||||
v = mustIndexer(v).Index(idx)
|
||||
}
|
||||
ec.ports[1].Chan <- v
|
||||
}
|
||||
|
|
|
@ -442,20 +442,6 @@ func stringToSegments(s string) []glob.Segment {
|
|||
return segs
|
||||
}
|
||||
|
||||
func evalIndex(ec *EvalCtx, l, r Value, lp, rp int) Value {
|
||||
left, ok := l.(Indexer)
|
||||
if !ok {
|
||||
ec.errorf(lp, "%s value cannot be indexing", l.Kind())
|
||||
}
|
||||
|
||||
right, ok := r.(String)
|
||||
if !ok {
|
||||
ec.errorf(rp, "%s invalid cannot be used as index", r.Kind())
|
||||
}
|
||||
|
||||
return left.Index(right)
|
||||
}
|
||||
|
||||
// FromJSONInterface converts a interface{} that results from json.Unmarshal to
|
||||
// a Value.
|
||||
func FromJSONInterface(v interface{}) Value {
|
||||
|
|
|
@ -376,7 +376,10 @@ func (ctrl *Control) parse(ps *parser, leader string) {
|
|||
parseSpaces(ctrl, ps)
|
||||
ctrl.setIterator(parsePrimary(ps))
|
||||
parseSpaces(ctrl, ps)
|
||||
if consumeLeader() != "in" {
|
||||
if ps.findPossibleLeader() == "in" {
|
||||
ps.advance(len("in"))
|
||||
addSep(ctrl, ps)
|
||||
} else {
|
||||
ps.error(errShouldBeIn)
|
||||
}
|
||||
ctrl.setArray(parseArray(ps))
|
||||
|
|
Loading…
Reference in New Issue
Block a user