mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-05 03:17:50 +08:00
Implement for
.
This commit is contained in:
parent
26006a03f4
commit
ec9a628ba0
|
@ -77,14 +77,14 @@ func assignmentBegins(ns []*parse.Assignment) []int {
|
||||||
return begins
|
return begins
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *compiler) indexingVars(ns []*parse.Indexing, msg string) []VariableOp {
|
func (cp *compiler) singleVariables(ns []*parse.Indexing, msg string) []VariableOp {
|
||||||
ops := make([]VariableOp, len(ns))
|
ops := make([]VariableOp, len(ns))
|
||||||
for i, n := range ns {
|
for i, n := range ns {
|
||||||
ops[i] = cp.indexingVar(n, msg)
|
ops[i] = cp.singleVariable(n, msg)
|
||||||
}
|
}
|
||||||
return ops
|
return ops
|
||||||
}
|
}
|
||||||
func indexingVarBegins(ns []*parse.Indexing) []int {
|
func singleVariableBegins(ns []*parse.Indexing) []int {
|
||||||
begins := make([]int, len(ns))
|
begins := make([]int, len(ns))
|
||||||
for i, n := range ns {
|
for i, n := range ns {
|
||||||
begins[i] = n.Begin()
|
begins[i] = n.Begin()
|
||||||
|
|
|
@ -277,8 +277,17 @@ func (cp *compiler) control(n *parse.Control) Op {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case parse.ForControl:
|
case parse.ForControl:
|
||||||
cp.errorf(n.Begin(), "not yet implemented")
|
iteratorOp := cp.singleVariable(n.Iterator, "must be a single variable")
|
||||||
panic("unreachable")
|
valuesOp := cp.array(n.Array)
|
||||||
|
bodyOp := cp.chunk(n.Body)
|
||||||
|
return func(ec *EvalCtx) {
|
||||||
|
iterator := iteratorOp(ec)
|
||||||
|
values := valuesOp(ec)
|
||||||
|
for _, v := range values {
|
||||||
|
doSet(ec, []Variable{iterator}, []Value{v})
|
||||||
|
bodyOp(ec)
|
||||||
|
}
|
||||||
|
}
|
||||||
case parse.BeginControl:
|
case parse.BeginControl:
|
||||||
return cp.chunk(n.Body)
|
return cp.chunk(n.Body)
|
||||||
default:
|
default:
|
||||||
|
@ -298,21 +307,7 @@ func (cp *compiler) literal(n *parse.Primary, msg string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *compiler) assignment(n *parse.Assignment) Op {
|
func (cp *compiler) assignment(n *parse.Assignment) Op {
|
||||||
var variableOps []VariableOp
|
variableOps := cp.multiVariable(n.Dst)
|
||||||
if n.Dst.Head.Type == parse.Braced {
|
|
||||||
compounds := n.Dst.Head.Braced
|
|
||||||
indexings := make([]*parse.Indexing, len(compounds))
|
|
||||||
for i, cn := range compounds {
|
|
||||||
if len(cn.Indexings) != 1 {
|
|
||||||
cp.errorf(cn.Begin(), "must be a variable spec")
|
|
||||||
}
|
|
||||||
indexings[i] = cn.Indexings[0]
|
|
||||||
}
|
|
||||||
variableOps = cp.indexingVars(indexings, "must be a variable spc")
|
|
||||||
} else {
|
|
||||||
variableOps = []VariableOp{cp.indexingVar(n.Dst, "must be a variable spec or a braced list of those")}
|
|
||||||
}
|
|
||||||
|
|
||||||
valuesOp := cp.compound(n.Src)
|
valuesOp := cp.compound(n.Src)
|
||||||
|
|
||||||
return func(ec *EvalCtx) {
|
return func(ec *EvalCtx) {
|
||||||
|
@ -324,8 +319,27 @@ func (cp *compiler) assignment(n *parse.Assignment) Op {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *compiler) indexingVar(n *parse.Indexing, msg string) VariableOp {
|
func (cp *compiler) multiVariable(n *parse.Indexing) []VariableOp {
|
||||||
// XXX will we be using indexingVar for purposes other than setting?
|
var variableOps []VariableOp
|
||||||
|
if n.Head.Type == parse.Braced {
|
||||||
|
// XXX ignore n.Indicies.
|
||||||
|
compounds := n.Head.Braced
|
||||||
|
indexings := make([]*parse.Indexing, len(compounds))
|
||||||
|
for i, cn := range compounds {
|
||||||
|
if len(cn.Indexings) != 1 {
|
||||||
|
cp.errorf(cn.Begin(), "must be a variable spec")
|
||||||
|
}
|
||||||
|
indexings[i] = cn.Indexings[0]
|
||||||
|
}
|
||||||
|
variableOps = cp.singleVariables(indexings, "must be a variable spc")
|
||||||
|
} else {
|
||||||
|
variableOps = []VariableOp{cp.singleVariable(n, "must be a variable spec or a braced list of those")}
|
||||||
|
}
|
||||||
|
return variableOps
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp *compiler) singleVariable(n *parse.Indexing, msg string) VariableOp {
|
||||||
|
// XXX will we be using this for purposes other than setting?
|
||||||
varname := cp.literal(n.Head, msg)
|
varname := cp.literal(n.Head, msg)
|
||||||
p := n.Begin()
|
p := n.Begin()
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ func (n *Control) setCondition(ch *Chunk) {
|
||||||
addChild(n, ch)
|
addChild(n, ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Control) setIterator(ch *Primary) {
|
func (n *Control) setIterator(ch *Indexing) {
|
||||||
n.Iterator = ch
|
n.Iterator = ch
|
||||||
addChild(n, ch)
|
addChild(n, ch)
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,7 +287,7 @@ type Control struct {
|
||||||
node
|
node
|
||||||
Kind ControlKind
|
Kind ControlKind
|
||||||
Condition *Chunk // Valid for WhileControl.
|
Condition *Chunk // Valid for WhileControl.
|
||||||
Iterator *Primary // Valid for ForControl.
|
Iterator *Indexing // Valid for ForControl.
|
||||||
Array *Array // Valid for ForControl.
|
Array *Array // Valid for ForControl.
|
||||||
Body *Chunk // Valid for all except IfControl.
|
Body *Chunk // Valid for all except IfControl.
|
||||||
Conditions []*Chunk // Valid for IfControl.
|
Conditions []*Chunk // Valid for IfControl.
|
||||||
|
@ -374,7 +374,7 @@ func (ctrl *Control) parse(ps *parser, leader string) {
|
||||||
case "for":
|
case "for":
|
||||||
ctrl.Kind = ForControl
|
ctrl.Kind = ForControl
|
||||||
parseSpaces(ctrl, ps)
|
parseSpaces(ctrl, ps)
|
||||||
ctrl.setIterator(parsePrimary(ps))
|
ctrl.setIterator(parseIndexing(ps))
|
||||||
parseSpaces(ctrl, ps)
|
parseSpaces(ctrl, ps)
|
||||||
if ps.findPossibleLeader() == "in" {
|
if ps.findPossibleLeader() == "in" {
|
||||||
ps.advance(len("in"))
|
ps.advance(len("in"))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user