================================================================================
Literal words
================================================================================

echo a
echo a b

--------------------------------------------------------------------------------

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

================================================================================
Words with special characters
================================================================================

echo {o[k]}
echo }}}
echo ]]] ===

--------------------------------------------------------------------------------

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

================================================================================
Simple variable expansions
================================================================================

echo $abc

--------------------------------------------------------------------------------

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

================================================================================
Special variable expansions
================================================================================

echo $# $* $@ $!

--------------------------------------------------------------------------------

(program
  (command
    (command_name
      (word))
    (simple_expansion
      (special_variable_name))
    (simple_expansion
      (special_variable_name))
    (simple_expansion
      (special_variable_name))
    (simple_expansion
      (special_variable_name))))

================================================================================
Variable expansions
================================================================================

echo ${}
echo ${#}
echo ${var1#*#}
echo ${!abc}
echo ${abc}
echo ${abc:-def}
echo ${abc:+ghi}
echo ${abc:- }
echo ${abc:
}
echo ${abc,?}
echo ${abc^^b}
echo ${abc@U}

--------------------------------------------------------------------------------

(program
  (command (command_name (word)) (expansion))
  (command (command_name (word)) (expansion))
  (command (command_name (word)) (expansion (variable_name) (regex)))
  (command (command_name (word)) (expansion (variable_name)))
  (command (command_name (word)) (expansion (variable_name)))
  (command (command_name (word)) (expansion (variable_name) (word)))
  (command (command_name (word)) (expansion (variable_name) (word)))
  (command (command_name (word)) (expansion (variable_name) (word)))
  (command (command_name (word)) (expansion (variable_name)))
  (command (command_name (word)) (expansion (variable_name) (regex)))
  (command (command_name (word)) (expansion (variable_name) (regex)))
  (command (command_name (word)) (expansion (variable_name))))

================================================================================
Variable expansions with operators
================================================================================

A="${B[0]# }"
C="${D/#* -E /}"
F="${G%% *}"
H="${I#*;}"
J="${K##*;}"
L="${M%;*}"
N="${O%%;*}"
P="${Q%|*}"
R="${S%()}"
T="${U%(}"
V="${W%)}"
X="${Y%<}"
Z="${A#*<B>}"
C="${D%</E>*}"
F="${#!}"
G=${H,,[I]}
J=${K^^[L]}

--------------------------------------------------------------------------------

(program
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (subscript
          (variable_name)
          (number))
            (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (regex))))
  (variable_assignment
    (variable_name)
    (string
      (expansion)))
  (variable_assignment
    (variable_name)
    (expansion
      (variable_name)
      (regex)))
  (variable_assignment
    (variable_name)
    (expansion
      (variable_name)
      (regex))))

================================================================================
More Variable expansions with operators
================================================================================

${parameter-default}
${parameter:-default}
${parameter=default}
${parameter:=default}
${parameter+alt_value}
${parameter:+alt_value}
${parameter?err_msg}
${parameter:?err_msg}
${var%Pattern}
${var%%Pattern}
${var:pos}
${var:pos:len}
${MATRIX:$(($RANDOM%${#MATRIX})):1}

--------------------------------------------------------------------------------

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

================================================================================
Variable expansions in strings
================================================================================

A="${A:-$B/c}"
A="${b=$c/$d}"

--------------------------------------------------------------------------------

(program
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (concatenation
          (simple_expansion
            (variable_name))
          (word)))))
  (variable_assignment
    (variable_name)
    (string
      (expansion
        (variable_name)
        (concatenation
          (simple_expansion
            (variable_name))
          (word)
          (simple_expansion
            (variable_name)))))))

================================================================================
Variable expansions with regexes
================================================================================

A=${B//:;;/$'\n'}

# escaped space
C=${D/;\ *;|}

--------------------------------------------------------------------------------

(program
  (variable_assignment
    (variable_name)
    (expansion
      (variable_name)
      (regex)
      (ansi_c_string)))
  (comment)
  (variable_assignment
    (variable_name)
    (expansion
      (variable_name)
      (regex))))

================================================================================
Other variable expansion operators
================================================================================

cat ${BAR} ${ABC=def} ${GHI:?jkl}
[ "$a" != "${a#[Bc]}" ]

--------------------------------------------------------------------------------

(program
  (command
    (command_name
      (word))
    (expansion
      (variable_name))
    (expansion
      (variable_name)
      (word))
    (expansion
      (variable_name)
      (word)))
  (test_command
    (binary_expression
      (string
        (simple_expansion
          (variable_name)))
      (string
        (expansion
          (variable_name)
          (regex))))))

================================================================================
Variable Expansions: Length
================================================================================

${parameter:-1}

${parameter: -1}

${parameter:(-1)}

${matrix:$(($random%${#matrix})):1}

"${_component_to_single:${len}:2}"

--------------------------------------------------------------------------------

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

================================================================================
Variable Expansions with operators
================================================================================

${parameter-default}
${parameter- default}
${!varprefix*}
${!varprefix@}
${parameter@U}

--------------------------------------------------------------------------------

(program
  (command (command_name (expansion (variable_name) (word))))
  (command (command_name (expansion (variable_name) (word))))
  (command (command_name (expansion (variable_name))))
  (command (command_name (expansion (variable_name))))
  (command (command_name (expansion (variable_name)))))

================================================================================
Variable Expansions: Bizarre Cases
================================================================================

${!#}
${!# }
${!##}
${!## }
${!##/}

--------------------------------------------------------------------------------

(program
  (command (command_name (expansion)))
  (command (command_name (expansion)))
  (command (command_name (expansion)))
  (command (command_name (expansion)))
  (command (command_name (expansion (special_variable_name) (regex)))))

================================================================================
Variable Expansions: Weird Cases
================================================================================

${completions[*]}
${=1}
${2?}
${p_key#*=}
${abc:- }
${B[0]# }
${to_enables[0]##*/}
exec "${0#-}" --rcfile "${BASH_IT_BASHRC:-${HOME?}/.bashrc}"
recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS=\"$selvecs\"}"
local msg="${2:-command '$1' does not exist}"

--------------------------------------------------------------------------------

(program
  (command (command_name (expansion (subscript (variable_name) (word)))))
  (command (command_name (expansion (variable_name))))
  (command (command_name (expansion (variable_name))))
  (command (command_name (expansion (variable_name) (regex))))
  (command (command_name (expansion (variable_name) (word))))
  (command (command_name (expansion (subscript (variable_name) (number)) (regex))))
  (command (command_name (expansion (subscript (variable_name) (number)) (regex))))
  (command
    (command_name (word))
    (string (expansion (special_variable_name) (regex)))
    (word)
    (string (expansion (variable_name) (concatenation (expansion (variable_name)) (word)))))
  (command
    (command_name (word))
    (string
      (expansion (variable_name) (concatenation (variable_name) (word) (simple_expansion (variable_name)) (word)))))
  (declaration_command
    (variable_assignment
      (variable_name)
      (string (expansion (variable_name) (concatenation (word) (raw_string) (word) (word) (word)))))))

================================================================================
Variable Expansions: Regex
================================================================================

A=${B//:;;/$'\n'}
C="${D/#* -E /}"
BASH_IT_GIT_URL="${BASH_IT_GIT_URL/git@/https://}"
10#${command_start##*.}

--------------------------------------------------------------------------------

(program
  (variable_assignment (variable_name) (expansion (variable_name) (regex) (ansi_c_string)))
  (variable_assignment (variable_name) (string (expansion (variable_name) (regex))))
  (variable_assignment (variable_name) (string (expansion (variable_name) (regex) (word))))
  (command (command_name (number (expansion (variable_name) (regex))))))

================================================================================
Words ending with '$'
================================================================================

grep ^${var}$

--------------------------------------------------------------------------------

(program
  (command
    (command_name
      (word))
    (concatenation
      (word)
      (expansion
        (variable_name)))))

================================================================================
Command substitutions
================================================================================

echo `echo hi`
echo `echo hi; echo there`
echo $(echo $(echo hi))
echo $(< some-file)

# both of these are concatenations!
echo `echo otherword`word
echo word`echo otherword`

--------------------------------------------------------------------------------

(program
  (command
    (command_name
      (word))
    (command_substitution
      (command
        (command_name
          (word))
        (word))))
  (command
    (command_name
      (word))
    (command_substitution
      (command
        (command_name
          (word))
        (word))
      (command
        (command_name
          (word))
        (word))))
  (command
    (command_name
      (word))
    (command_substitution
      (command
        (command_name
          (word))
        (command_substitution
          (command
            (command_name
              (word))
            (word))))))
  (command
    (command_name
      (word))
    (command_substitution
      (file_redirect
        (word))))
  (comment)
  (command
    (command_name
      (word))
    (concatenation
      (command_substitution
        (command
          (command_name
            (word))
          (word)))
      (word)))
  (command
    (command_name
      (word))
    (concatenation
      (word)
      (command_substitution
        (command
          (command_name
            (word))
          (word))))))

================================================================================
Process substitutions
================================================================================

wc -c <(echo abc && echo def)
wc -c <(echo abc; echo def)
echo abc > >(wc -c)

--------------------------------------------------------------------------------

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

================================================================================
Single quoted strings
================================================================================

echo 'a b' 'c d'

--------------------------------------------------------------------------------

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

================================================================================
Double quoted strings
================================================================================

echo "a" "b"
echo "a ${b} c" "d $e"

--------------------------------------------------------------------------------

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

================================================================================
Strings containing command substitutions
================================================================================

find "`dirname $file`" -name "$base"'*'

--------------------------------------------------------------------------------

(program
  (command
    (command_name
      (word))
    (string
      (command_substitution
        (command
          (command_name
            (word))
          (simple_expansion
            (variable_name)))))
    (word)
    (concatenation
      (string
        (simple_expansion
          (variable_name)))
      (raw_string))))

================================================================================
Strings containing escape sequence
================================================================================

echo "\"The great escape\`\${var}"

--------------------------------------------------------------------------------

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

================================================================================
Strings containing special characters
================================================================================

echo "s/$/'/"
echo "#"
echo "s$"

--------------------------------------------------------------------------------

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

================================================================================
Strings with ANSI-C quoting
================================================================================

echo $'Here\'s Johnny!\r\n'

--------------------------------------------------------------------------------

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

================================================================================
Arrays and array expansions
================================================================================

a=()
b=(1 2 3)

echo ${a[@]}
echo ${#b[@]}

a[$i]=50
a+=(foo "bar" $(baz))

printf "  %-9s" "${seq0:-(default)}"

--------------------------------------------------------------------------------

(program
  (variable_assignment
    (variable_name)
    (array))
  (variable_assignment
    (variable_name)
    (array
      (number)
      (number)
      (number)))
  (command
    (command_name
      (word))
    (expansion
      (subscript
        (variable_name)
        (word))))
  (command
    (command_name
      (word))
    (expansion
      (subscript
        (variable_name)
        (word))))
  (variable_assignment
    (subscript
      (variable_name)
      (simple_expansion
        (variable_name)))
    (number))
  (variable_assignment
    (variable_name)
    (array
      (word)
      (string)
      (command_substitution
        (command
          (command_name
            (word))))))
  (command
    (command_name
      (word))
    (string)
    (string
      (expansion
        (variable_name)
        (array
          (word))))))

================================================================================
Escaped characters in strings
================================================================================

echo -ne "\033k$1\033\\" > /dev/stderr

--------------------------------------------------------------------------------

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

================================================================================
Words containing bare '#'
================================================================================

curl -# localhost #comment without space
nix build nixpkgs#hello -v # comment with space

--------------------------------------------------------------------------------

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

================================================================================
Words containing # that are not comments
================================================================================

echo 'word'#not-comment # a legit comment
echo $(uname -a)#not-comment # a legit comment
echo `uname -a`#not-comment # a legit comment
echo $hey#not-comment # a legit comment
var=#not-comment # a legit comment
echo "'$var'" # -> '#not-comment'

--------------------------------------------------------------------------------

(program
  (command
    (command_name
      (word))
    (concatenation
      (raw_string)
      (word)))
  (comment)
  (command
    (command_name
      (word))
    (concatenation
      (command_substitution
        (command
          (command_name
            (word))
          (word)))
      (word)))
  (comment)
  (command
    (command_name
      (word))
    (concatenation
      (command_substitution
        (command
          (command_name
            (word))
          (word)))
      (word)))
  (comment)
  (command
    (command_name
      (word))
    (concatenation
      (simple_expansion
        (variable_name))
      (word)))
  (comment)
  (variable_assignment
    (variable_name)
    (word))
  (comment)
  (command
    (command_name
      (word))
    (string
      (simple_expansion
        (variable_name))))
  (comment))

================================================================================
Variable assignments immediately followed by a terminator
================================================================================

loop=; variables=& here=;;

--------------------------------------------------------------------------------

(program
  (variable_assignment
    (variable_name))
  (variable_assignment
    (variable_name))
  (variable_assignment
    (variable_name)))

================================================================================
Multiple variable assignments
================================================================================

component_type="${1}" item_name="${2?}"

--------------------------------------------------------------------------------

(program
  (variable_assignments
    (variable_assignment
      (variable_name)
      (string
        (expansion
          (variable_name))))
    (variable_assignment
      (variable_name)
      (string
        (expansion
          (variable_name))))))

================================================================================
Arithmetic expansions
================================================================================

echo $((1 + 2 - 3 * 4 / 5))
a=$((6 % 7 ** 8 << 9 >> 10 & 11 | 12 ^ 13))
$(((${1:-${SECONDS}} % 12) + 144))
((foo=0))
echo $((bar=1))
echo $((-1, 1))
echo $((! -a || ~ +b || ++c || --d))
echo $((foo-- || bar++))

--------------------------------------------------------------------------------

(program
  (command
    (command_name
      (word))
    (arithmetic_expansion
      (binary_expression
        (binary_expression
          (binary_expression
            (binary_expression
              (number)
              (number))
            (number))
          (number))
        (number))))
  (variable_assignment
    (variable_name)
    (arithmetic_expansion
      (binary_expression
        (binary_expression
          (binary_expression
            (binary_expression
              (binary_expression
                (binary_expression
                  (binary_expression
                    (number)
                    (number))
                  (number))
                (number))
              (number))
            (number))
          (number))
        (number))))
  (command
    (command_name
      (arithmetic_expansion
        (binary_expression
          (parenthesized_expression
            (binary_expression
              (expansion
                (variable_name)
                (expansion
                  (variable_name)))
              (number)))
          (number)))))
  (command
    (command_name
      (arithmetic_expansion
        (binary_expression
          (variable_name)
          (number)))))
  (command
    (command_name
      (word))
    (arithmetic_expansion
      (binary_expression
        (variable_name)
        (number))))
  (command
    (command_name
      (word))
    (arithmetic_expansion
      (unary_expression
        (number))
      (number)))
  (command
    (command_name
      (word))
    (arithmetic_expansion
      (binary_expression
        (binary_expression
          (binary_expression
            (unary_expression
              (unary_expression
                (variable_name)))
            (unary_expression
              (unary_expression
                (variable_name))))
          (unary_expression
            (variable_name)))
        (unary_expression
          (variable_name)))))
  (command
    (command_name
      (word))
    (arithmetic_expansion
      (postfix_expression
        (binary_expression
          (postfix_expression
            (variable_name))
          (variable_name))))))

================================================================================
Concatenation with double backticks
================================================================================

main() {
    local foo="asd"`
        `"fgh"
}

---

(program
  (function_definition
    (word)
    (compound_statement
      (declaration_command
        (variable_assignment
          (variable_name)
          (concatenation
            (string)
            (string)))))))

================================================================================
Brace expressions and lookalikes
================================================================================

echo {1..2}
echo {0..5}
echo {0..2 # not a brace expression
echo }{0..2}
echo {0..n} # not a brace expression
echo {0..n..2} # not a brace expression
echo {0..2}{1..2}

---

(program
  (command
    (command_name (word))
    (brace_expression (number) (number)))
  (command
    (command_name (word))
    (brace_expression (number) (number)))
  (command
    (command_name (word))
    (concatenation (word) (word)))
  (comment)
  (command
    (command_name (word))
    (concatenation
      (word)
      (brace_expression (number) (number))))
  (command
    (command_name (word))
    (concatenation (word) (word) (word)))
  (comment)
  (command
    (command_name (word))
    (concatenation (word) (word) (word)))
  (comment)
  (command
    (command_name (word))
    (concatenation
      (brace_expression (number) (number))
      (brace_expression (number) (number)))))
