===============================
Commands
===============================

whoami

---

(program
  (command (command_name (word))))

===============================
Commands with arguments
===============================

cat file1.txt
git diff --word-diff=color -- file1.txt file2.txt
echo $sing\
levar

---

(program
  (command (command_name (word)) (word))
  (command (command_name (word)) (word) (word) (word) (word) (word))
  (command (command_name (word)) (simple_expansion (variable_name)) (word)))

===============================
Quoted command names
===============================

"$a/$b" c

---

(program
  (command
    (command_name (string (simple_expansion (variable_name)) (simple_expansion (variable_name))))
    (word)))

===============================
Commands with numeric arguments
===============================

exit 1

---

(program
  (command (command_name (word)) (number)))

===================================
Commands with environment variables
===================================

VAR1=1 ./script/test
VAR1=a VAR2="ok" git diff --word-diff=color

---

(program
  (command
    (variable_assignment (variable_name) (number))
    (command_name (word)))
  (command
    (variable_assignment (variable_name) (word))
    (variable_assignment (variable_name) (string))
    (command_name (word))
    (word)
    (word)))

===================================
Empty environment variables
===================================

VAR1=
VAR2= echo

---

(program
  (variable_assignment (variable_name))
  (command (variable_assignment (variable_name)) (command_name (word))))

===============================
File redirects
===============================

whoami > /dev/null
cat a b > /dev/null
2>&1 whoami
echo "foobar" >&2
[ ! command -v go &>/dev/null ] && return

if [ ]; then
	>aa >bb
fi

---

(program
  (redirected_statement
    (command (command_name (word)))
    (file_redirect (word)))
  (redirected_statement
    (command (command_name (word)) (word) (word))
    (file_redirect (word)))
  (command
    (file_redirect (file_descriptor) (number))
    (command_name (word)))
  (redirected_statement
    (command (command_name (word)) (string))
    (file_redirect (number)))
  (list
    (test_command
      (redirected_statement
        (negated_command
          (command (command_name (word)) (word) (word)))
        (file_redirect (word))))
    (command (command_name (word))))
  (if_statement
    (test_command)
    (redirected_statement
      (file_redirect (word))
      (file_redirect (word)))))

===============================
File redirects (noclobber override)
===============================

whoami >| /dev/null
cat a b >| /dev/null

---

(program
  (redirected_statement
    (command (command_name (word)))
    (file_redirect (word)))
  (redirected_statement
    (command (command_name (word)) (word) (word))
    (file_redirect (word))))

===============================
Heredoc redirects
===============================

node <<JS
console.log("hi")
JS

bash -c <<JS
echo hi
JS

---

(program
  (redirected_statement
    (command
      (command_name
        (word)))
    (heredoc_redirect
      (heredoc_start)
      (simple_heredoc_body)
      (heredoc_end)))
  (redirected_statement
    (command
      (command_name
        (word))
      (word))
    (heredoc_redirect
      (heredoc_start)
      (simple_heredoc_body)
      (heredoc_end))))

===============================
Heredocs with variables
===============================

node <<JS
a $B ${C}
JS

exit

---

(program
  (redirected_statement
    (command
      (command_name
        (word)))
    (heredoc_redirect
      (heredoc_start)
      (heredoc_body
        (simple_expansion
          (variable_name))
        (expansion
          (variable_name)))
      (heredoc_end)))
  (command
    (command_name
      (word))))

=================================
Heredocs with file redirects
=================================

cat <<EOF > $tmpfile
a $B ${C}
EOF

wc -l $tmpfile

---

(program
  (redirected_statement
    (command
      (command_name
        (word)))
    (heredoc_redirect
      (heredoc_start)
      (file_redirect
        (simple_expansion
          (variable_name)))
      (heredoc_body
        (simple_expansion
          (variable_name))
        (expansion
          (variable_name)))
      (heredoc_end)))
  (command
    (command_name
      (word))
    (word)
    (simple_expansion
      (variable_name))))

=================================
Heredocs with pipes
=================================

one <<EOF | grep two
three
EOF

---

(program
  (redirected_statement
    (command
      (command_name
        (word)))
    (heredoc_redirect
      (heredoc_start)
      (pipeline
        (command
          (command_name
            (word))
          (word)))
      (simple_heredoc_body)
      (heredoc_end))))

======================================
Heredocs with escaped expansions
======================================

cat  << EOF
DEV_NAME=\$(lsblk)
EOF

---

(program (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end))))

======================================
Quoted Heredocs
======================================

cat << 'EOF'
a=$b
EOF

cat << "EOF"
a=$b
EOF

cat <<"END OF FILE"
hello,
world
END OF FILE

cat << \EOF
EOF

---

(program
  (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end)))
  (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end)))
  (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end)))
  (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end))))

==========================================
Heredocs with indented closing delimiters
==========================================

usage() {
	cat <<-EOF
		Usage: ${0##*/} FOO BAR
	EOF
}

---

(program
  (function_definition
    (word)
    (compound_statement
      (redirected_statement
        (command (command_name (word)))
        (heredoc_redirect (heredoc_start) (heredoc_body (expansion (special_variable_name) (regex))) (heredoc_end))))))

==========================================
Heredocs with empty bodies
==========================================

node <<JS
JS

node << 'SJ'
SJ

usage() {
	cat <<-EOF
	EOF
}

node << 'EOF' > temp
EOF

---

(program
  (redirected_statement
    body: (command
      name: (command_name
        (word)))
    redirect: (heredoc_redirect
      (heredoc_start)
      (simple_heredoc_body)
      (heredoc_end)))
  (redirected_statement
    body: (command
      name: (command_name
        (word)))
    redirect: (heredoc_redirect
      (heredoc_start)
      (simple_heredoc_body)
      (heredoc_end)))
  (function_definition
    name: (word)
    body: (compound_statement
      (redirected_statement
        body: (command
          name: (command_name
            (word)))
        redirect: (heredoc_redirect
          (heredoc_start)
          (simple_heredoc_body)
          (heredoc_end)))))
  (redirected_statement
    body: (command
      name: (command_name
        (word)))
    redirect: (heredoc_redirect
      (heredoc_start)
      (file_redirect
        destination: (word))
      (simple_heredoc_body)
      (heredoc_end))))

==========================================
Heredocs with weird characters
==========================================

node <<_DELIMITER_WITH_UNDERSCORES_
Hello.
_DELIMITER_WITH_UNDERSCORES_

node <<'```'
Hello.
```

node <<!HEREDOC!
Hello.
!HEREDOC!

node <<\'
Hello.
'

node <<\\
Hello.
\

---

(program
  (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end)))
  (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end)))
  (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end)))
  (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end)))
  (redirected_statement (command (command_name (word))) (heredoc_redirect (heredoc_start) (simple_heredoc_body) (heredoc_end))))

==========================================
Herestrings
==========================================

node <<< foo

while read -u 3 entry; do
  echo $entry
done 3<<<"$ENTRIES"

---

(program
  (redirected_statement (command (command_name (word))) (herestring_redirect (word)))
  (redirected_statement
    (while_statement
      (command (command_name (word)) (word) (number) (word))
      (do_group (command (command_name (word)) (simple_expansion (variable_name)))))
    (herestring_redirect (file_descriptor) (string (simple_expansion (variable_name))))))

==========================================
Subscripts
==========================================

echo ${a[1 + 2]}

echo ${b[1234 % 2]}

${words[++counter]}

${array[(($number+1))]}

${array[((number+1))]}

---

(program
  (command
    (command_name (word))
    (expansion
      (subscript (variable_name) (binary_expression (number) (number)))))
  (command
    (command_name (word))
    (expansion
      (subscript (variable_name) (binary_expression (number) (number)))))
  (command
    (command_name
      (expansion
        (subscript (variable_name) (unary_expression (word))))))
  (command
    (command_name
      (expansion
        (subscript
          (variable_name)
          (arithmetic_expansion (binary_expression (simple_expansion (variable_name)) (number)))))))
  (command
    (command_name
      (expansion
        (subscript
          (variable_name)
          (arithmetic_expansion (binary_expression (variable_name) (number))))))))

==========================================
Bare $
==========================================

echo $

---

(program
  (command
    (command_name
      (word))))
