======================================================================
Statement ellipsis
======================================================================

...
cat ...
... --force

---

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

======================================================================
Metavariables
======================================================================

echo $FOO
$FOO

---

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

======================================================================
Simple expansion
======================================================================

$$A
"$$A"

---

(program
  (command
    (command_name
      (concatenation
        (simple_expansion
          (special_variable_name))
        (word))))
  (command
    (command_name
      (string
        (simple_expansion
          (special_variable_name))
        (string_content)))))

======================================================================
Concatenation
======================================================================

$a.$b

---

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

======================================================================
All-caps shell variables
======================================================================

echo "${BAR}"
echo ${BAR}
${BAR}

---

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

======================================================================
Metavariable matching a variable
======================================================================

echo ${$X}
echo ${$X#/}

---

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

======================================================================
Ellipsis in unquoted concatenation
======================================================================

$a...
...$a

---

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

======================================================================
Ellipsis in quoted concatenation
======================================================================

"$a..."
"...$a"

---

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

======================================================================
Case (switch) with metavariables and ellipses
======================================================================

case $X in
  a)
    ;;
  *)
esac

---

(program
  (case_statement
    (simple_expansion (variable_name))
    (case_item (word))
    (case_item (extglob_pattern))))

======================================================================
For loop with metavariable and ellipsis
======================================================================

for $X in ...; do
  ...
done

---

(program
  (for_statement
    (semgrep_metavariable)
    (word)
    (do_group (command (command_name (word))))))

======================================================================
Function definition
======================================================================

function $FOO() {
 ...
}

---

(program
  (function_definition
    (semgrep_metavariable)
    (compound_statement (command (command_name (word))))))


======================================================================
Function definition with metavariable, redirect, and 'if' body
======================================================================

function $F() {
  ...
} 2>&1
function $F if ...; then ...; fi

---

(program
  (function_definition
    (semgrep_metavariable)
    (compound_statement (command (command_name (word))))
    (file_redirect (file_descriptor) (number)))
  (function_definition
    (semgrep_metavariable)
    (if_statement
      (command (command_name (word)))
      (command (command_name (word))))))

======================================================================
Arithmetic expansion with metavariables and ellipses
======================================================================

echo $(( $X + ... ))
echo $(( ... ))
echo $(( <... $X ...> ))
x=$(( $...ARGS ))

---

(program
  (command
    (command_name (word))
    (arithmetic_expansion
      (binary_expression
        (simple_expansion (variable_name))
        (word))))
  (command
    (command_name (word))
    (arithmetic_expansion (word)))
  (command
    (command_name (word))
    (arithmetic_expansion
      (semgrep_deep_expression
        (simple_expansion (variable_name)))))
  (variable_assignment
    (variable_name)
    (arithmetic_expansion
      (simple_expansion (semgrep_named_ellipsis)))))

======================================================================
C-style for loop with ellipses
======================================================================

for (( ...; ...; ... )); do ...; done

---

(program
  (c_style_for_statement
    (word)
    (word)
    (word)
    (do_group (command (command_name (word))))))

======================================================================
Metavariable in declaration
======================================================================

declare -r $VAR

---

(program
  (declaration_command
    (word)
    (semgrep_metavariable)))

======================================================================
Metavariable in assignment
======================================================================

$MUT=x
$MUT+=x

---

(program
  (variable_assignment
    (semgrep_metavar_eq)
    (word))
  (variable_assignment
    (semgrep_metavar_pluseq)
    (word)))

======================================================================
Environment variable assignment before command
======================================================================

${PATH}=/bin command arg

---

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

======================================================================
Metavariable in assignment before command
======================================================================

$X=42 Y=x command arg
$X= 42 command

---

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

======================================================================
Metavariable in assignment with a '#' value
======================================================================

$X=#foo

---

(program
  (variable_assignment
    (semgrep_metavar_eq)
    (word)))

======================================================================
Metavariable in multiple assignments
======================================================================

$X=1 Y=2

---

(program
  (variable_assignments
    (variable_assignment
      (semgrep_metavar_eq)
      (number))
    (variable_assignment
      (variable_name)
      (number))))

======================================================================
Metavariable assignment in C-style for loop
======================================================================

for (( $I=0; $I<$N; $I++ )); do ...; done

---

(program
  (c_style_for_statement
    (variable_assignment
      (semgrep_metavar_eq)
      (number))
    (binary_expression
      (simple_expansion
        (variable_name))
      (simple_expansion
        (variable_name)))
    (postfix_expression
      (simple_expansion
        (variable_name)))
    (do_group
      (command
        (command_name
          (word))))))

======================================================================
Array declaration and assignment (TODO)
======================================================================

declare -a $ARR

---

(program (declaration_command (word) (semgrep_metavariable)))

======================================================================
Deep expressions
======================================================================

<... a ...>
a <... b ...>
a <... 'b'$c ...>

---

(program
  (command
    (command_name
      (semgrep_deep_expression
        (word))))
  (command
    (command_name
      (word))
    (semgrep_deep_expression
      (word)))
  (command
    (command_name
      (word))
    (semgrep_deep_expression
      (concatenation
        (raw_string)
        (simple_expansion
          (variable_name))))))

======================================================================
Named ellipses
======================================================================

apt-get install $...ARGS
$...ARGS and more
"$...X"
"foo$...Xbar"

---

(program
  (command
    (command_name
      (word))
    (word)
    (simple_expansion
      (semgrep_named_ellipsis)))
  (command
    (command_name
      (simple_expansion
        (semgrep_named_ellipsis)))
    (word)
    (word))
  (command
    (command_name
      (string
        (simple_expansion
          (semgrep_named_ellipsis)))))
  (command
    (command_name
      (string
        (string_content)
        (simple_expansion
          (semgrep_named_ellipsis))
        (string_content)))))

================================================================================
Pipeline followed by a redirected statement
================================================================================

a | b | c
d > f
while read -r x; do echo "$x"; done 3<<<"$X"

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

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

================================================================================
Arithmetic unary operators bind tighter than binary operators
================================================================================

echo $(( -a + b ))
echo $(( -2 ** 2 ))

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

(program
  (command
    (command_name
      (word))
    (arithmetic_expansion
      (binary_expression
        (unary_expression
          (variable_name))
        (variable_name))))
  (command
    (command_name
      (word))
    (arithmetic_expansion
      (binary_expression
        (unary_expression
          (number))
        (number)))))

================================================================================
Arithmetic '**' and assignments are right-associative
================================================================================

echo $(( 2 ** 3 ** 2 ))
(( a = b = 1 ))

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

(program
  (command
    (command_name
      (word))
    (arithmetic_expansion
      (binary_expression
        (number)
        (binary_expression
          (number)
          (number)))))
  (compound_statement
    (binary_expression
      (variable_name)
      (binary_expression
        (variable_name)
        (number)))))

================================================================================
Arithmetic ternary is right-associative; assignments share a precedence
================================================================================

echo $(( x ? y : z ? 1 : 0 ))
(( a = b += 1 ))

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

(program
  (command
    (command_name
      (word))
    (arithmetic_expansion
      (ternary_expression
        (variable_name)
        (variable_name)
        (ternary_expression
          (variable_name)
          (number)
          (number)))))
  (compound_statement
    (binary_expression
      (variable_name)
      (binary_expression
        (variable_name)
        (number)))))

================================================================================
Ellipsis before the closing keyword of a block
================================================================================

while ...; do ... done
if ...; then ... else ... fi
{ ...; ... }

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

(program
  (while_statement
    condition: (command
      name: (command_name
        (word)))
    body: (do_group
      (command
        name: (command_name
          (word)))))
  (if_statement
    condition: (command
      name: (command_name
        (word)))
    (command
      name: (command_name
        (word)))
    (else_clause
      (command
        name: (command_name
          (word)))))
  (compound_statement
    (command
      name: (command_name
        (word)))
    (command
      name: (command_name
        (word)))))

================================================================================
Only an ellipsis may end a block without a terminator
================================================================================

for i in a; do ... x; echo done; done

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

(program
  (for_statement
    variable: (variable_name)
    value: (word)
    body: (do_group
      (command
        name: (command_name
          (word))
        argument: (word))
      (command
        name: (command_name
          (word))
        argument: (word)))))

================================================================================
Ellipsis as a command, a function name and a command argument
================================================================================

... > out
...() { ...; }
echo ... x

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

(program
  (redirected_statement
    body: (command
      name: (command_name
        (word)))
    redirect: (file_redirect
      destination: (word)))
  (function_definition
    name: (word)
    body: (compound_statement
      (command
        name: (command_name
          (word)))))
  (command
    name: (command_name
      (word))
    argument: (word)
    argument: (word)))
