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
|
||||
}
|
||||
|
||||
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))
|
||||
for i, n := range ns {
|
||||
ops[i] = cp.indexingVar(n, msg)
|
||||
ops[i] = cp.singleVariable(n, msg)
|
||||
}
|
||||
return ops
|
||||
}
|
||||
func indexingVarBegins(ns []*parse.Indexing) []int {
|
||||
func singleVariableBegins(ns []*parse.Indexing) []int {
|
||||
begins := make([]int, len(ns))
|
||||
for i, n := range ns {
|
||||
begins[i] = n.Begin()
|
||||
|
|
|
@ -277,8 +277,17 @@ func (cp *compiler) control(n *parse.Control) Op {
|
|||
}
|
||||
}
|
||||
case parse.ForControl:
|
||||
cp.errorf(n.Begin(), "not yet implemented")
|
||||
panic("unreachable")
|
||||
iteratorOp := cp.singleVariable(n.Iterator, "must be a single variable")
|
||||
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:
|
||||
return cp.chunk(n.Body)
|
||||
default:
|
||||
|
@ -298,21 +307,7 @@ func (cp *compiler) literal(n *parse.Primary, msg string) string {
|
|||
}
|
||||
|
||||
func (cp *compiler) assignment(n *parse.Assignment) Op {
|
||||
var variableOps []VariableOp
|
||||
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")}
|
||||
}
|
||||
|
||||
variableOps := cp.multiVariable(n.Dst)
|
||||
valuesOp := cp.compound(n.Src)
|
||||
|
||||
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 {
|
||||
// XXX will we be using indexingVar for purposes other than setting?
|
||||
func (cp *compiler) multiVariable(n *parse.Indexing) []VariableOp {
|
||||
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)
|
||||
p := n.Begin()
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ func (n *Control) setCondition(ch *Chunk) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func (n *Control) setIterator(ch *Primary) {
|
||||
func (n *Control) setIterator(ch *Indexing) {
|
||||
n.Iterator = ch
|
||||
addChild(n, ch)
|
||||
}
|
||||
|
|
|
@ -286,13 +286,13 @@ func (an *Assignment) parse(ps *parser) {
|
|||
type Control struct {
|
||||
node
|
||||
Kind ControlKind
|
||||
Condition *Chunk // Valid for WhileControl.
|
||||
Iterator *Primary // Valid for ForControl.
|
||||
Array *Array // Valid for ForControl.
|
||||
Body *Chunk // Valid for all except IfControl.
|
||||
Conditions []*Chunk // Valid for IfControl.
|
||||
Bodies []*Chunk // Valid for IfControl.
|
||||
ElseBody *Chunk // Valid for IfControl, WhileControl and ForControl.
|
||||
Condition *Chunk // Valid for WhileControl.
|
||||
Iterator *Indexing // Valid for ForControl.
|
||||
Array *Array // Valid for ForControl.
|
||||
Body *Chunk // Valid for all except IfControl.
|
||||
Conditions []*Chunk // Valid for IfControl.
|
||||
Bodies []*Chunk // Valid for IfControl.
|
||||
ElseBody *Chunk // Valid for IfControl, WhileControl and ForControl.
|
||||
}
|
||||
|
||||
// ControlKind identifies which control structure a Control represents.
|
||||
|
@ -374,7 +374,7 @@ func (ctrl *Control) parse(ps *parser, leader string) {
|
|||
case "for":
|
||||
ctrl.Kind = ForControl
|
||||
parseSpaces(ctrl, ps)
|
||||
ctrl.setIterator(parsePrimary(ps))
|
||||
ctrl.setIterator(parseIndexing(ps))
|
||||
parseSpaces(ctrl, ps)
|
||||
if ps.findPossibleLeader() == "in" {
|
||||
ps.advance(len("in"))
|
||||
|
|
Loading…
Reference in New Issue
Block a user