# Iteration 7: If statements - if/then/elif/else/fi
# Comprehensive edge cases from tree-sitter-bash, Oil Shell, POSIX spec
# === Basic if/then/fi ===
=== simple if
if true; then echo yes; fi
---
(if (command (word "true")) (command (word "echo") (word "yes")))
---
=== if with test command
if test -f file; then cat file; fi
---
(if (command (word "test") (word "-f") (word "file")) (command (word "cat") (word "file")))
---
=== if with bracket test
if [ -f file ]; then cat file; fi
---
(if (command (word "[") (word "-f") (word "file") (word "]")) (command (word "cat") (word "file")))
---
=== if with pipeline condition
if echo foo | grep foo; then echo found; fi
---
(if (pipe (command (word "echo") (word "foo")) (command (word "grep") (word "foo"))) (command (word "echo") (word "found")))
---
=== if with list condition
if cmd1 && cmd2; then echo both; fi
---
(if (and (command (word "cmd1")) (command (word "cmd2"))) (command (word "echo") (word "both")))
---
=== if with or condition
if cmd1 || cmd2; then echo either; fi
---
(if (or (command (word "cmd1")) (command (word "cmd2"))) (command (word "echo") (word "either")))
---
# === Multiple commands in condition (from tree-sitter-bash) ===
=== multiple commands in condition
if foo; bar; then baz; fi
---
(if (semi (command (word "foo")) (command (word "bar"))) (command (word "baz")))
---
=== three commands in condition
if a; b; c; then d; fi
---
(if (semi (semi (command (word "a")) (command (word "b"))) (command (word "c"))) (command (word "d")))
---
# === If/else ===
=== simple if else
if true; then echo yes; else echo no; fi
---
(if (command (word "true")) (command (word "echo") (word "yes")) (command (word "echo") (word "no")))
---
=== if else with test
if [ "$x" = "y" ]; then echo match; else echo nomatch; fi
---
(if (command (word "[") (word "\"$x\"") (word "=") (word "\"y\"") (word "]")) (command (word "echo") (word "match")) (command (word "echo") (word "nomatch")))
---
=== if else with complex bodies
if test -d dir; then cd dir; ls; else mkdir dir; fi
---
(if (command (word "test") (word "-d") (word "dir")) (semi (command (word "cd") (word "dir")) (command (word "ls"))) (command (word "mkdir") (word "dir")))
---
=== if else multiple commands both branches
if test 1; then echo a; echo b; else echo c; echo d; fi
---
(if (command (word "test") (word "1")) (semi (command (word "echo") (word "a")) (command (word "echo") (word "b"))) (semi (command (word "echo") (word "c")) (command (word "echo") (word "d"))))
---
# === Elif chains ===
=== simple elif
if test 1; then echo one; elif test 2; then echo two; fi
---
(if (command (word "test") (word "1")) (command (word "echo") (word "one")) (if (command (word "test") (word "2")) (command (word "echo") (word "two"))))
---
=== elif with else
if test 1; then echo one; elif test 2; then echo two; else echo other; fi
---
(if (command (word "test") (word "1")) (command (word "echo") (word "one")) (if (command (word "test") (word "2")) (command (word "echo") (word "two")) (command (word "echo") (word "other"))))
---
=== multiple elif
if test 1; then echo one; elif test 2; then echo two; elif test 3; then echo three; fi
---
(if (command (word "test") (word "1")) (command (word "echo") (word "one")) (if (command (word "test") (word "2")) (command (word "echo") (word "two")) (if (command (word "test") (word "3")) (command (word "echo") (word "three")))))
---
=== multiple elif with else
if test 1; then echo one; elif test 2; then echo two; elif test 3; then echo three; else echo other; fi
---
(if (command (word "test") (word "1")) (command (word "echo") (word "one")) (if (command (word "test") (word "2")) (command (word "echo") (word "two")) (if (command (word "test") (word "3")) (command (word "echo") (word "three")) (command (word "echo") (word "other")))))
---
=== four elif chain
if a; then echo a; elif b; then echo b; elif c; then echo c; elif d; then echo d; else echo e; fi
---
(if (command (word "a")) (command (word "echo") (word "a")) (if (command (word "b")) (command (word "echo") (word "b")) (if (command (word "c")) (command (word "echo") (word "c")) (if (command (word "d")) (command (word "echo") (word "d")) (command (word "echo") (word "e"))))))
---
=== elif with complex conditions
if cat file | grep a; then echo a; elif cat file | grep b; then echo b; else exit; fi
---
(if (pipe (command (word "cat") (word "file")) (command (word "grep") (word "a"))) (command (word "echo") (word "a")) (if (pipe (command (word "cat") (word "file")) (command (word "grep") (word "b"))) (command (word "echo") (word "b")) (command (word "exit"))))
---
# === Nested if ===
=== nested if in then
if test 1; then if test 2; then echo both; fi; fi
---
(if (command (word "test") (word "1")) (if (command (word "test") (word "2")) (command (word "echo") (word "both"))))
---
=== nested if in else
if test 1; then echo one; else if test 2; then echo two; fi; fi
---
(if (command (word "test") (word "1")) (command (word "echo") (word "one")) (if (command (word "test") (word "2")) (command (word "echo") (word "two"))))
---
=== deeply nested if
if a; then if b; then if c; then echo deep; fi; fi; fi
---
(if (command (word "a")) (if (command (word "b")) (if (command (word "c")) (command (word "echo") (word "deep")))))
---
=== nested if with elif
if a; then if b; then echo ab; elif c; then echo ac; fi; fi
---
(if (command (word "a")) (if (command (word "b")) (command (word "echo") (word "ab")) (if (command (word "c")) (command (word "echo") (word "ac")))))
---
=== nested if in elif branch
if a; then echo a; elif b; then if c; then echo bc; fi; fi
---
(if (command (word "a")) (command (word "echo") (word "a")) (if (command (word "b")) (if (command (word "c")) (command (word "echo") (word "bc")))))
---
# === If with newlines (alternative to semicolons) ===
=== if with newline before then
if true
then echo yes; fi
---
(if (command (word "true")) (command (word "echo") (word "yes")))
---
=== if with newlines throughout
if true
then
echo yes
fi
---
(if (command (word "true")) (command (word "echo") (word "yes")))
---
=== if else with newlines
if false
then
echo yes
else
echo no
fi
---
(if (command (word "false")) (command (word "echo") (word "yes")) (command (word "echo") (word "no")))
---
=== elif with newlines
if a
then
echo a
elif b
then
echo b
else
echo c
fi
---
(if (command (word "a")) (command (word "echo") (word "a")) (if (command (word "b")) (command (word "echo") (word "b")) (command (word "echo") (word "c"))))
---
=== multiline then body
if true
then
echo one
echo two
echo three
fi
---
(if (command (word "true")) (semi (semi (command (word "echo") (word "one")) (command (word "echo") (word "two"))) (command (word "echo") (word "three"))))
---
# === If in pipelines and lists ===
=== if in pipeline
if true; then echo yes; fi | cat
---
(pipe (if (command (word "true")) (command (word "echo") (word "yes"))) (command (word "cat")))
---
=== if in and list
if true; then echo yes; fi && echo done
---
(and (if (command (word "true")) (command (word "echo") (word "yes"))) (command (word "echo") (word "done")))
---
=== if in or list
if false; then echo yes; fi || echo fallback
---
(or (if (command (word "false")) (command (word "echo") (word "yes"))) (command (word "echo") (word "fallback")))
---
=== if in background
if true; then sleep 10; fi &
---
(background (if (command (word "true")) (command (word "sleep") (word "10"))))
---
=== if after semicolon
echo before; if true; then echo yes; fi
---
(semi (command (word "echo") (word "before")) (if (command (word "true")) (command (word "echo") (word "yes"))))
---
=== multiple if in sequence
if a; then echo a; fi; if b; then echo b; fi
---
(semi (if (command (word "a")) (command (word "echo") (word "a"))) (if (command (word "b")) (command (word "echo") (word "b"))))
---
=== if in complex pipeline
echo start | if true; then cat; fi | wc -l
---
(pipe (command (word "echo") (word "start")) (pipe (if (command (word "true")) (command (word "cat"))) (command (word "wc") (word "-l"))))
---
# === Subshell and brace group in condition ===
=== subshell in condition
if (true); then echo yes; fi
---
(if (subshell (command (word "true"))) (command (word "echo") (word "yes")))
---
=== subshell with commands in condition
if (echo foo; true); then echo yes; fi
---
(if (subshell (semi (command (word "echo") (word "foo")) (command (word "true")))) (command (word "echo") (word "yes")))
---
=== brace group in condition
if { true; }; then echo yes; fi
---
(if (brace-group (command (word "true"))) (command (word "echo") (word "yes")))
---
=== brace group with multiple commands in condition
if { cmd1; cmd2; }; then echo yes; fi
---
(if (brace-group (semi (command (word "cmd1")) (command (word "cmd2")))) (command (word "echo") (word "yes")))
---
# === Subshell and brace group in body ===
=== subshell in then body
if true; then (echo in subshell); fi
---
(if (command (word "true")) (subshell (command (word "echo") (word "in") (word "subshell"))))
---
=== brace group in then body
if true; then { echo in brace; }; fi
---
(if (command (word "true")) (brace-group (command (word "echo") (word "in") (word "brace"))))
---
=== subshell in else body
if false; then echo yes; else (echo no); fi
---
(if (command (word "false")) (command (word "echo") (word "yes")) (subshell (command (word "echo") (word "no"))))
---
# === Complex conditions ===
=== if with negation
if ! test -f file; then echo missing; fi
---
(if (negation (command (word "test") (word "-f") (word "file"))) (command (word "echo") (word "missing")))
---
=== if with double bracket
if [[ -f file ]]; then cat file; fi
---
(if (cond (cond-unary "-f" (cond-term "file"))) (command (word "cat") (word "file")))
---
=== double bracket with pattern
if [[ "$x" == *.txt ]]; then echo text; fi
---
(if (cond (cond-binary "==" (cond-term ""$x"") (cond-term "*.txt"))) (command (word "echo") (word "text")))
---
=== double bracket regex
if [[ "$x" =~ ^[0-9]+$ ]]; then echo number; fi
---
(if (cond (cond-binary "=~" (cond-term ""$x"") (cond-term "^[0-9]+$"))) (command (word "echo") (word "number")))
---
=== test with string comparison
if [ "$(uname)" = "Darwin" ]; then echo mac; fi
---
(if (command (word "[") (word "\"$(uname)\"") (word "=") (word "\"Darwin\"") (word "]")) (command (word "echo") (word "mac")))
---
=== test with numeric comparison
if [ "$x" -gt 10 ]; then echo big; fi
---
(if (command (word "[") (word "\"$x\"") (word "-gt") (word "10") (word "]")) (command (word "echo") (word "big")))
---
=== test with multiple conditions
if [ -f file ] && [ -r file ]; then cat file; fi
---
(if (and (command (word "[") (word "-f") (word "file") (word "]")) (command (word "[") (word "-r") (word "file") (word "]"))) (command (word "cat") (word "file")))
---
=== double bracket with and
if [[ -f file ]] && [[ -r file ]]; then cat file; fi
---
(if (and (cond (cond-unary "-f" (cond-term "file"))) (cond (cond-unary "-r" (cond-term "file")))) (command (word "cat") (word "file")))
---
=== double bracket with or
if [[ -f a ]] || [[ -f b ]]; then echo found; fi
---
(if (or (cond (cond-unary "-f" (cond-term "a"))) (cond (cond-unary "-f" (cond-term "b")))) (command (word "echo") (word "found")))
---
# NOTE: (( )) arithmetic expressions require special parsing
# Currently parsed as nested subshells - proper (( )) support is future work
# === Whitespace variations ===
=== if no space after semicolons
if true;then echo yes;fi
---
(if (command (word "true")) (command (word "echo") (word "yes")))
---
=== if extra spaces
if true ; then echo yes ; fi
---
(if (command (word "true")) (command (word "echo") (word "yes")))
---
=== tabs instead of spaces
if true; then echo yes; fi
---
(if (command (word "true")) (command (word "echo") (word "yes")))
---
=== mixed whitespace
if true ; then echo yes ; fi
---
(if (command (word "true")) (command (word "echo") (word "yes")))
---
# === From tree-sitter-bash ===
=== if with command substitution condition
if test "$(whoami)" = root; then echo root; fi
---
(if (command (word "test") (word "\"$(whoami)\"") (word "=") (word "root")) (command (word "echo") (word "root")))
---
=== if elif else complete
if [ -f a ]; then echo a; elif [ -f b ]; then echo b; else echo none; fi
---
(if (command (word "[") (word "-f") (word "a") (word "]")) (command (word "echo") (word "a")) (if (command (word "[") (word "-f") (word "b") (word "]")) (command (word "echo") (word "b")) (command (word "echo") (word "none"))))
---
=== if with variable assignment condition
if foo=1; then echo set; fi
---
(if (command (word "foo=1")) (command (word "echo") (word "set")))
---
=== if with result variable simple
if result=value; then echo got; fi
---
(if (command (word "result=value")) (command (word "echo") (word "got")))
---
# === Special test cases ===
=== test with equals in value
if [ a = -d ]; then echo match; fi
---
(if (command (word "[") (word "a") (word "=") (word "-d") (word "]")) (command (word "echo") (word "match")))
---
=== bracket test with spaces in quotes
if [ "hello world" = "hello world" ]; then echo same; fi
---
(if (command (word "[") (word "\"hello world\"") (word "=") (word "\"hello world\"") (word "]")) (command (word "echo") (word "same")))
---
=== test with empty string
if [ -z "" ]; then echo empty; fi
---
(if (command (word "[") (word "-z") (word "\"\"") (word "]")) (command (word "echo") (word "empty")))
---
=== test with non-empty string
if [ -n "foo" ]; then echo nonempty; fi
---
(if (command (word "[") (word "-n") (word "\"foo\"") (word "]")) (command (word "echo") (word "nonempty")))
---
# === Null command in body ===
=== empty then with colon
if true; then :; fi
---
(if (command (word "true")) (command (word ":")))
---
=== empty then with colon and else
if false; then :; else echo no; fi
---
(if (command (word "false")) (command (word ":")) (command (word "echo") (word "no")))
---
=== colon in condition
if :; then echo always; fi
---
(if (command (word ":")) (command (word "echo") (word "always")))
---
# === If with redirections in body ===
=== redirect in then body
if true; then echo yes > out.txt; fi
---
(if (command (word "true")) (command (word "echo") (word "yes") (redirect ">" "out.txt")))
---
=== redirect in else body
if false; then echo yes; else echo no > err.txt; fi
---
(if (command (word "false")) (command (word "echo") (word "yes")) (command (word "echo") (word "no") (redirect ">" "err.txt")))
---
=== multiple redirects in body
if true; then cat < in.txt > out.txt; fi
---
(if (command (word "true")) (command (word "cat") (redirect "<" "in.txt") (redirect ">" "out.txt")))
---
=== pipeline with redirects in body
if true; then cat file | grep foo > matches.txt; fi
---
(if (command (word "true")) (pipe (command (word "cat") (word "file")) (command (word "grep") (word "foo") (redirect ">" "matches.txt"))))
---
# === Complex real-world examples ===
=== git status check
if git status > /dev/null; then echo repo; fi
---
(if (command (word "git") (word "status") (redirect ">" "/dev/null")) (command (word "echo") (word "repo")))
---
=== command existence check
if command -v git > /dev/null; then echo found; fi
---
(if (command (word "command") (word "-v") (word "git") (redirect ">" "/dev/null")) (command (word "echo") (word "found")))
---
=== file readable and not empty
if [ -r "$file" ] && [ -s "$file" ]; then cat "$file"; fi
---
(if (and (command (word "[") (word "-r") (word "\"$file\"") (word "]")) (command (word "[") (word "-s") (word "\"$file\"") (word "]"))) (command (word "cat") (word "\"$file\"")))
---
=== complex elif with pipelines
if cat a | grep x; then echo ax; elif cat b | grep x; then echo bx; elif cat c | grep x; then echo cx; else echo none; fi
---
(if (pipe (command (word "cat") (word "a")) (command (word "grep") (word "x"))) (command (word "echo") (word "ax")) (if (pipe (command (word "cat") (word "b")) (command (word "grep") (word "x"))) (command (word "echo") (word "bx")) (if (pipe (command (word "cat") (word "c")) (command (word "grep") (word "x"))) (command (word "echo") (word "cx")) (command (word "echo") (word "none")))))
---
=== if in subshell
(if true; then echo yes; fi)
---
(subshell (if (command (word "true")) (command (word "echo") (word "yes"))))
---
=== if in brace group
{ if true; then echo yes; fi; }
---
(brace-group (if (command (word "true")) (command (word "echo") (word "yes"))))
---
=== chained if statements with and
if a; then echo a; fi && if b; then echo b; fi
---
(and (if (command (word "a")) (command (word "echo") (word "a"))) (if (command (word "b")) (command (word "echo") (word "b"))))
---
=== if with here string condition
if cat <<< "test"; then echo yes; fi
---
(if (command (word "cat") (redirect "<<<" ""test"")) (command (word "echo") (word "yes")))
---