Commit 37afd3e3 authored by Daniel Martí's avatar Daniel Martí

text/template/parse: simplify Tree.pipeline

The pipeline parsing code was unnecessarily complex. It used a for loop
with a trailing break, a complex switch, and up to seven levels of
indentation.

Instead, drop the loop in favor of a single named goto with a comment,
and flatten out the complex switch to be easier to follow. Two lines of
code are now duplicated, but they're simple and only three lines apart.

While at it, move the pipe initialization further up to remove the need
for three variables.

Change-Id: I07b29de195f4000336219aadeadeacaaa4285c58
Reviewed-on: https://go-review.googlesource.com/c/145285Reviewed-by: default avatarRob Pike <r@golang.org>
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 3f3142ad
...@@ -380,52 +380,44 @@ func (t *Tree) action() (n Node) { ...@@ -380,52 +380,44 @@ func (t *Tree) action() (n Node) {
// Pipeline: // Pipeline:
// declarations? command ('|' command)* // declarations? command ('|' command)*
func (t *Tree) pipeline(context string) (pipe *PipeNode) { func (t *Tree) pipeline(context string) (pipe *PipeNode) {
decl := false
var vars []*VariableNode
token := t.peekNonSpace() token := t.peekNonSpace()
pos := token.pos pipe = t.newPipeline(token.pos, token.line, nil)
// Are there declarations or assignments? // Are there declarations or assignments?
// TODO(mvdan): simplify the loop break/continue logic decls:
for { if v := t.peekNonSpace(); v.typ == itemVariable {
if v := t.peekNonSpace(); v.typ == itemVariable { t.next()
t.next() // Since space is a token, we need 3-token look-ahead here in the worst case:
// Since space is a token, we need 3-token look-ahead here in the worst case: // in "$x foo" we need to read "foo" (as opposed to ":=") to know that $x is an
// in "$x foo" we need to read "foo" (as opposed to ":=") to know that $x is an // argument variable rather than a declaration. So remember the token
// argument variable rather than a declaration. So remember the token // adjacent to the variable so we can push it back if necessary.
// adjacent to the variable so we can push it back if necessary. tokenAfterVariable := t.peek()
tokenAfterVariable := t.peek() next := t.peekNonSpace()
next := t.peekNonSpace() switch {
switch { case next.typ == itemAssign, next.typ == itemDeclare:
case next.typ == itemAssign, next.typ == itemDeclare, pipe.IsAssign = next.typ == itemAssign
next.typ == itemChar && next.val == ",": t.nextNonSpace()
t.nextNonSpace() pipe.Decl = append(pipe.Decl, t.newVariable(v.pos, v.val))
variable := t.newVariable(v.pos, v.val) t.vars = append(t.vars, v.val)
vars = append(vars, variable) case next.typ == itemChar && next.val == ",":
t.vars = append(t.vars, v.val) t.nextNonSpace()
if next.typ == itemDeclare { pipe.Decl = append(pipe.Decl, t.newVariable(v.pos, v.val))
decl = true t.vars = append(t.vars, v.val)
} if context == "range" && len(pipe.Decl) < 2 {
if next.typ == itemChar && next.val == "," { switch t.peekNonSpace().typ {
if context == "range" && len(vars) < 2 { case itemVariable, itemRightDelim, itemRightParen:
switch t.peekNonSpace().typ { // second initialized variable in a range pipeline
case itemVariable, itemRightDelim, itemRightParen: goto decls
continue default:
default: t.errorf("range can only initialize variables")
t.errorf("range can only initialize variables")
}
}
t.errorf("too many declarations in %s", context)
} }
case tokenAfterVariable.typ == itemSpace:
t.backup3(v, tokenAfterVariable)
default:
t.backup2(v)
} }
t.errorf("too many declarations in %s", context)
case tokenAfterVariable.typ == itemSpace:
t.backup3(v, tokenAfterVariable)
default:
t.backup2(v)
} }
break
} }
pipe = t.newPipeline(pos, token.line, vars)
pipe.IsAssign = !decl
for { for {
switch token := t.nextNonSpace(); token.typ { switch token := t.nextNonSpace(); token.typ {
case itemRightDelim, itemRightParen: case itemRightDelim, itemRightParen:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment