===================================
Pipelines
===================================

whoami | cat
cat foo | grep -v bar

---

(program
  (pipeline
    (command
      name: (command_name (word)))
    (command
      name: (command_name (word))))
  (pipeline
    (command
      name: (command_name (word))
      argument: (word))
    (command
      name: (command_name (word))
      argument: (word)
      argument: (word))))

===================================
Lists
===================================

a | b && c && d; d e f || e g

---

(program
  (list
    (list
      (pipeline
        (command (command_name (word)))
        (command (command_name (word))))
      (command (command_name (word))))
    (command (command_name (word))))
  (list
    (command (command_name (word)) (word) (word))
    (command (command_name (word)) (word))))

====================================
While statements
====================================

while something happens; do
  echo a
  echo b
done

---

(program
  (while_statement
    condition: (command
      name: (command_name (word))
      argument: (word))
    body: (do_group
      (command name: (command_name (word)) argument: (word))
      (command name: (command_name (word)) argument: (word)))))

====================================
Until statements
====================================

until something happens; do
  echo a
  echo b
done

---

(program
  (while_statement
    condition: (command
      name: (command_name (word))
      argument: (word))
    body: (do_group
      (command name: (command_name (word)) argument: (word))
      (command name: (command_name (word)) argument: (word)))))

====================================
While statements with IO redirects
====================================

while read line; do
  echo $line
done < <(cat file)

---

(program
  (redirected_statement
    body: (while_statement
      condition: (command
        name: (command_name (word))
        argument: (word))
      body: (do_group
        (command
          name: (command_name (word))
          argument: (simple_expansion (variable_name)))))
    redirect: (file_redirect
      destination: (process_substitution (command
        name: (command_name (word))
        argument: (word))))))

====================================
For statements
====================================

for a in 1 2 $(seq 5 10); do
  echo $a
done

for ARG; do
  echo $ARG
  ARG=''
done

---

(program
  (for_statement
    variable: (variable_name)
    value: (word)
    value: (word)
    value: (command_substitution (command
      name: (command_name (word))
      argument: (word)
      argument: (word)))
    body: (do_group
      (command
        name: (command_name (word))
        argument: (simple_expansion (variable_name)))))
  (for_statement
    variable: (variable_name)
    body: (do_group
      (command
        name: (command_name (word))
        argument: (simple_expansion (variable_name)))
      (variable_assignment
        name: (variable_name)
        value: (raw_string)))))

====================================
Select statements
====================================

select choice in X Y $(ls); do
  echo $choice
  break
done

select ARG; do
  echo $ARG
  ARG=''
done

---

(program
  (for_statement
    (variable_name)
      (word)
      (word)
      (command_substitution (command (command_name (word))))
    (do_group
      (command
        (command_name (word))
        (simple_expansion (variable_name)))
      (command (command_name (word)))))
  (for_statement
    (variable_name)
    (do_group
      (command
        (command_name (word))
        (simple_expansion (variable_name)))
      (variable_assignment (variable_name) (raw_string)))))

====================================
C-style for statements
====================================

for (( c=1; c<=5; c++ ))
do
  echo $c
done

for (( c=1; c<=5; c++ )) {
	echo $c
}

for (( ; ; ))
do
  echo 'forever'
done

---

(program
  (c_style_for_statement
    (word)
    (binary_expression (word) (word))
    (word)
    (do_group
      (command (command_name (word)) (simple_expansion (variable_name)))))
  (c_style_for_statement
    (word)
    (binary_expression (word) (word))
    (word)
    (compound_statement
      (command (command_name (word)) (simple_expansion (variable_name)))))
  (c_style_for_statement
    (do_group
      (command (command_name (word)) (raw_string)))))

====================================
If statements
====================================

if cat some_file | grep -v ok; then
  echo one
elif cat other_file | grep -v ok; then
  echo two
else
  exit
fi

---

(program
  (if_statement
    (pipeline
      (command (command_name (word)) (word))
      (command (command_name (word)) (word) (word)))
    (command (command_name (word)) (word))
    (elif_clause
      (pipeline
        (command (command_name (word)) (word))
        (command (command_name (word)) (word) (word)))
      (command (command_name (word)) (word)))
    (else_clause
      (command (command_name (word))))))

====================================
If statements with conditional expressions
====================================

if [ "$(uname)" == 'Darwin' ]; then
  echo one
fi

---

(program
  (if_statement
    (test_command (binary_expression
      (string (command_substitution (command (command_name (word)))))
      (raw_string)))
    (command (command_name (word)) (word))))

====================================
Case statements
====================================

case "opt" in
  a)
    echo a
    ;;

  b)
    echo b
    ;&

  c)
    echo c;;
esac

case "$Z" in
  ab*|cd*) ef
esac

case $dest in
  *.[1357])
    exit $?
    ;;
esac

---

(program
  (case_statement (string)
    (case_item (word)
      (command (command_name (word)) (word)))
    (case_item (word)
      (command (command_name (word)) (word)))
    (case_item (word)
      (command (command_name (word)) (word))))
  (case_statement (string (simple_expansion (variable_name)))
    (case_item (word) (word)
      (command (command_name (word)))))
  (case_statement (simple_expansion (variable_name))
    (case_item (concatenation (word) (word))
      (command (command_name (word)) (simple_expansion (special_variable_name))))))

=============================
Test commands
=============================

if [[ "$lsb_dist" != 'Ubuntu' || $(ver_to_int "$lsb_release") < $(ver_to_int '14.04') ]]; then
	return 1
fi

---

(program
  (if_statement
    (test_command (binary_expression
      (binary_expression
        (binary_expression
          (string (simple_expansion (variable_name)))
          (raw_string))
        (command_substitution (command
          (command_name (word))
          (string (simple_expansion (variable_name))))))
      (command_substitution (command (command_name (word)) (raw_string)))))
    (command (command_name (word)) (word))))


=============================
Test commands with ternary
=============================

if (( 1 < 2 ? 1 : 2 )); then
	return 1
fi

---

(program
  (if_statement
    (test_command
      (ternary_expression
        (binary_expression (word) (word))
        (word) (word)))
    (command
      (command_name (word)) (word))))

=============================
Test commands with regexes
=============================

[[ "35d8b" =~ ^[0-9a-fA-F] ]]
[[ $CMD =~ (^|;)update_terminal_cwd($|;) ]]
[[ ! " ${completions[*]} " =~ " $alias_cmd " ]]
! [[ "$a" =~ ^a|b\ *c|d$ ]]
[[ "$1" =~ ^${var}${var}*=..* ]]
[[ "$1" =~ ^\-${var}+ ]]
[[ ${var1} == *${var2}* ]]
[[ "$server" =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]
[[ "$primary_wins" =~ ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) ]]

---

(program
  (test_command
    (binary_expression
      (string)
      (regex)))
  (test_command
    (binary_expression
      (simple_expansion (variable_name))
      (regex)))
  (test_command
    (unary_expression
      (binary_expression
        (string (expansion (subscript (variable_name) (word))))
        (string (simple_expansion (variable_name))))))
  (negated_command
    (test_command
      (binary_expression
        (string (simple_expansion (variable_name)))
        (regex))))
  (test_command
    (binary_expression
      (string (simple_expansion (variable_name)))
      (regex)))
  (test_command
    (binary_expression
      (string (simple_expansion (variable_name)))
      (regex)))
  (test_command
    (binary_expression
      (expansion (variable_name))
      (regex)))
  (test_command
    (binary_expression
      (string (simple_expansion (variable_name)))
      (regex)))
  (test_command
    (binary_expression
      (string (simple_expansion (variable_name)))
      (regex))))

===============================
Subshells
===============================

(
  ./start-server --port=80
) &

---

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

===============================
Function definitions
===============================

do_something() {
  echo ok
}

run_subshell_command() (
  true
)

run_test_command() [[ -e foo ]]

function do_something_else() {
  a | xargs -I{} find xml/{} -type f
}

function do_yet_another_thing {
  echo ok
} 2>&1

---

(program
  (function_definition
    (word)
    (compound_statement (command (command_name (word)) (word))))
  (function_definition
      (word)
      (subshell (command (command_name (word)))))
  (function_definition
      (word)
      (test_command (unary_expression (test_operator) (word))))
  (function_definition
    (word)
    (compound_statement
      (pipeline
        (command (command_name (word)))
        (command
          (command_name (word))
          (concatenation (word))
          (word)
          (concatenation (word))
          (word)
          (word)))))
  (redirected_statement (function_definition
    (word)
    (compound_statement (command (command_name (word)) (word))))
    (file_redirect (file_descriptor) (word))))

=========================================
Variable declaration: declare & typeset
=========================================

declare var1
typeset -i -r var2=42 var3=10

---

(program
  (declaration_command (variable_name))
  (declaration_command (word) (word)
    (variable_assignment (variable_name) (word))
    (variable_assignment (variable_name) (word))))

=========================================
Variable declaration: readonly
=========================================

readonly var1
readonly var2=42

---

(program
  (declaration_command (variable_name))
  (declaration_command (variable_assignment (variable_name) (word))))

=========================================
Variable declaration: local
=========================================

local a=42 b
local -r c

---

(program
  (declaration_command
    (variable_assignment (variable_name) (word))
    (variable_name))
  (declaration_command
    (word)
    (variable_name)))

=========================================
Variable declaration: export
=========================================

export PATH
export FOOBAR PATH="$PATH:/usr/foobar/bin"

---

(program
  (declaration_command (variable_name))
  (declaration_command
    (variable_name)
    (variable_assignment (variable_name) (string (simple_expansion (variable_name))))))

===========================================================
Variable declaration: command substitution with semi-colon
===========================================================

_path=$(
  while statement; do
    cd ".."
  done;
  echo $PWD
)

---

(program
  (variable_assignment (variable_name)
    (command_substitution
      (while_statement
        (command (command_name (word)))
        (do_group (command (command_name (word)) (string))))
      (command (command_name (word)) (simple_expansion (variable_name))))))

===========================================
Expressions passed to declaration commands
===========================================

export "$(echo ${key} | tr [:lower:] [:upper:])=${p_key#*=}"

---

(program
  (declaration_command
    (string
      (command_substitution
        (pipeline
          (command (command_name (word)) (expansion (variable_name)))
          (command (command_name (word)) (concatenation (word)) (concatenation (word)))))
      (expansion (variable_name) (word)))))

=========================================
Unset commands
=========================================

unset A
unset "$variable_name"
unsetenv -f ONE TWO

---

(program
  (unset_command (variable_name))
  (unset_command (string (simple_expansion (variable_name))))
  (unset_command (word) (variable_name) (variable_name)))

===========================================
Compound statements
===========================================

a () {
    ls || { echo "b"; return 0; }
    echo c
}

{ echo "a"
  echo "b"
} >&2

---

(program
  (function_definition (word) (compound_statement
    (list
      (command (command_name (word)))
      (compound_statement
        (command (command_name (word)) (string))
        (command (command_name (word)) (word))))
    (command (command_name (word)) (word))))
  (redirected_statement
    (compound_statement (command (command_name (word)) (string)) (command (command_name (word)) (string)))
    (file_redirect (word))))
