// simpleCommand func (p *Parser) simpleCommand() Node { tok := p.next() assignments := map[string]Arg{} args := []Arg{} startLine := tok.LineNo assignmentAllowed := true p.lexer.CheckAlias = true p.lexer.IgnoreNewlines = false p.lexer.CheckKeyword = false OuterLoop: for { switch tok.Tok { case TWord: if assignmentAllowed && variables.IsAssignment(tok.Val) { parts := strings.SplitN(tok.Val, "=", 2) assignments[parts[0]] = Arg{Raw: parts[1], Subs: tok.Subs, Quoted: tok.Quoted} p.lexer.CheckAlias = false } else { assignmentAllowed = false args = append(args, Arg{Raw: tok.Val, Subs: tok.Subs, Quoted: tok.Quoted}) } case TLeftParen: if len(args) == 1 && len(assignments) == 0 { p.expect(TRightParen) name := args[0] if !variables.IsGoodName(name.Raw) { panic("Bad function name: " + name.Raw) } p.lexer.CheckAlias = true p.lexer.IgnoreNewlines = true p.lexer.CheckKeyword = true n := NodeFunction{} n.Body = p.command() n.Name = name.Raw return n } fallthrough default: p.backup() break OuterLoop } tok = p.next() } n := NodeCommand{} n.Assign = assignments n.Args = args n.LineNo = startLine return n }
// parseFor return a NodeFor which contains the body of the for loop, the // variable to assign into and a list of things to assign. // // XXX: This does not follow the shell spec, which allows omitting the in // and then defaults to using all the set positional variables. E.g $1, $2 func parseFor(p *Parser) Node { tok := p.next() if tok.Tok != TWord || tok.Quoted || !variables.IsGoodName(tok.Val) { p.log.Error(fmt.Sprintf("Bad for loop variable name", kisslog.Attrs{ "name": tok.Val, "line": tok.LineNo, })) } n := NodeFor{Args: []Arg{}} n.LoopVar = tok.Val p.lexer.CheckAlias = true p.lexer.IgnoreNewlines = false p.lexer.CheckKeyword = true p.expect(TIn) for { tok = p.next() if tok.Tok != TWord { p.backup() p.expect(TNewLine, TSemicolon) break } n.Args = append(n.Args, Arg{Raw: tok.Val, Subs: tok.Subs, Quoted: tok.Quoted}) } p.lexer.CheckAlias = true p.lexer.IgnoreNewlines = true p.lexer.CheckKeyword = true p.expect(TDo) n.Body = p.list(IgnoreNewlines) p.expect(TDone) return n }