package shell import ( "io" "log" ) type SubshellParameters struct{} func (p *SubshellParameters) SubParsers() []Parser { return []Parser{ &BaseParser{ parameters: &StatementParameters{}, }, } } func (p *SubshellParameters) Enter(i *CharIterator) error { return i.Next() } func (p *SubshellParameters) Supports(charsBefore []rune, r rune) bool { if r == '(' { return len(charsBefore) == 0 || countBackslashSuffixes(charsBefore)%2 == 0 } return false } func (p *SubshellParameters) ShouldLeave(charsBefore []rune, r rune) bool { if r == ')' { return len(charsBefore) == 0 || countBackslashSuffixes(charsBefore)%2 == 0 } return false } func (p *SubshellParameters) MakeToken() Token { return &Subshell{} } type Subshell struct { BaseToken } func (s *Subshell) Evaluate(state State, stdin io.Reader, stdout io.Writer, stderr io.Writer) uint8 { var ret uint8 for _, token := range s.Tokens() { if eval, ok := token.(Evalable); ok { ret = state.Eval(eval, stdin, stdout, stderr) } else { logstr := "shell: Unexpected token: " + token.String() log.Println(logstr) stderr.Write([]byte(logstr)) return 2 } } return ret } type Backtick struct { Subshell } type BacktickParameters struct { SubshellParameters } func (p *BacktickParameters) Supports(charsBefore []rune, r rune) bool { if r == '`' { return len(charsBefore) == 0 || countBackslashSuffixes(charsBefore)%2 == 0 } return false } func (p *BacktickParameters) ShouldLeave(charsBefore []rune, r rune) bool { if r == '`' { return len(charsBefore) == 0 || countBackslashSuffixes(charsBefore)%2 == 0 } return false }