....(CompoundWord
  parts:[
    (Token
      id:Lit_Chars
      length:2
      col:0
      line:(SourceLine line_num:1 content:"hi'\n" src:(source.MainFile path:hi))
    )
    (SingleQuoted
      left:(Token id:Left_SingleQuote length:1 col:2 line:...0x7f52c59d7730)
      sval:"\nsingle quoted"
      right:(Token
        id:Right_SingleQuote
        length:1
        col:13
        line:(SourceLine
          line_num:2
          content:"single quoted'\"double\n"
          src:...0x7f52c59681b8
        )
      )
    )
    (DoubleQuoted
      left:(Token id:Left_DoubleQuote length:1 col:14 line:...0x7f52c59d7788)
      parts:[
        (Token id:Lit_Chars length:7 col:15 line:...0x7f52c59d7788)
        (Token
          id:Lit_Chars
          length:7
          col:0
          line:(SourceLine line_num:3 content:"quoted\n" src:...0x7f52c59681b8)
        )
      ]
      right:(Token
        id:Right_DoubleQuote
        length:1
        col:0
        line:(SourceLine line_num:4 content:"\"there\n" src:...0x7f52c59681b8)
      )
    )
    (Token id:Lit_Chars length:5 col:1 line:...0x7f52c59d7890)
  ]
)

s = '\'\nsingle quoted\'"double\nquoted\n"'
s = "'\nsingle quoted'"
s = 'hi'
(CompoundWord
  parts:[
    (Token
      id:Lit_VarLike
      length:4
      col:4
      line:(SourceLine
        line_num:1
        content:"ls; foo=42"
        src:(source.MainFile path:"")
      )
    )
    (Token id:Lit_Chars length:2 col:8 line:...0x7f52c59d77e0)
  ]
)

(CompoundWord
  parts:[
    (Token
      id:Lit_VarLike
      length:5
      col:4
      line:(SourceLine
        line_num:1
        content:"ls; foo+=X"
        src:(source.MainFile path:"")
      )
    )
    (Token id:Lit_Chars length:1 col:9 line:...0x7f52c59d7e68)
  ]
)


--- ${array[0]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    bracket_op:(bracket_op.ArrayIndex expr:(w <Lit_Digits 0>))
    right:<Right_DollarBrace "}">
  )
)


--- ${array[5+5]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    bracket_op:(bracket_op.ArrayIndex
      expr:(arith_expr.Binary
        op:<Arith_Plus "+">
        left:(w <Lit_Digits 5>)
        right:(w <Lit_Digits 5>)
      )
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${array[@]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    bracket_op:(bracket_op.WholeArray op_id:Lit_At)
    right:<Right_DollarBrace "}">
  )
)


--- ${array[*]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    bracket_op:(bracket_op.WholeArray op_id:Arith_Star)
    right:<Right_DollarBrace "}">
  )
)


--- ${#}

(w (${ VSub_Pound "#"))


--- ${!}

(w (${ VSub_Bang "!"))


--- ${?}

(w (${ VSub_QMark "?"))


--- ${var}

(w (${ VSub_Name var))


--- ${15}

(w (${ VSub_Number 15))


--- ${#var}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    prefix_op:<VSub_Pound "#">
    right:<Right_DollarBrace "}">
  )
)


--- ${!ref}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name ref>
    var_name:ref
    prefix_op:<VSub_Bang "!">
    right:<Right_DollarBrace "}">
  )
)


--- ${##}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Pound "#">
    var_name:"#"
    prefix_op:<VSub_Pound "#">
    right:<Right_DollarBrace "}">
  )
)


--- ${array[0]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    bracket_op:(bracket_op.ArrayIndex expr:(w <Lit_Digits 0>))
    right:<Right_DollarBrace "}">
  )
)


--- ${array[@]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    bracket_op:(bracket_op.WholeArray op_id:Lit_At)
    right:<Right_DollarBrace "}">
  )
)


--- ${#array[0]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    prefix_op:<VSub_Pound "#">
    bracket_op:(bracket_op.ArrayIndex expr:(w..... <Lit_Digits 0>))
    right:<Right_DollarBrace "}">
  )
)


--- ${!array[0]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    prefix_op:<VSub_Bang "!">
    bracket_op:(bracket_op.ArrayIndex expr:(w <Lit_Digits 0>))
    right:<Right_DollarBrace "}">
  )
)


--- ${var#prefix}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary
      op:<VOp1_Pound "#">
      arg_word:(w <Lit_Chars prefix>)
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${!var#prefix}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    prefix_op:<VSub_Bang "!">
    suffix_op:(suffix_op.Unary
      op:<VOp1_Pound "#">
      arg_word:(w <Lit_Chars prefix>)
    )
    right:<Right_DollarBrace "}">
  )
)

('\n---', '${#var#prefix}')
Got expected ParseError: 
('\n---', '${##2}')
Got expected ParseError: 
--MULTI
('\n---', '${undef:-')
Got expected ParseError: 
('\n---', '${undef:-$')
Got expected ParseError: 
('\n---', '${undef:-$F')
Got expected ParseError: 
('\n---', '${x@')
Got expected ParseError: 
('\n---', '${x@Q')
Got expected ParseError: 
('\n---', '${x%')
Got expected ParseError: 
('\n---', '${x/')
Got expected ParseError: 
('\n---', '${x/a/')
Got expected ParseError: 
('\n---', '${x/a/b')
Got expected ParseError: 
('\n---', '${x:')
Got expected ParseError: 

--- ${#@}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_At "@">
    var_name:"@"
    prefix_op:<VSub_Pound "#">
    right:<Right_DollarBrace "}">
  )
)


--- ${#11}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Number 11>
    var_name:11
    prefix_op:<VSub_Pound "#">
    right:<Right_DollarBrace "}">
  )
)


--- ${#str}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name str>
    var_name:str
    prefix_op:<VSub_Pound "#">
    right:<Right_DollarBrace "}">
  )
)


--- ${#array[0]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    prefix_op:<VSub_Pound "#">
    bracket_op:(bracket_op.ArrayIndex expr:(w <Lit_Digits 0>))
    right:<Right_DollarBrace "}">
  )
)


--- ${#array["key"]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    prefix_op:<VSub_Pound "#">
    bracket_op:(bracket_op.ArrayIndex expr:(w (DQ <Lit_Chars key>)))
    right:<Right_DollarBrace "}">
  )
)


--- @words

(w (word_part.Splice blame_tok:<Lit_Splice "@words"> var_name:words))


--- .@words

(w <Lit_Chars .> <Lit_Splice "@words">)


--- .@words.

(w <Lit_Chars .> <Lit_Splice "@words"> <Lit_Chars .>)

('\n---', '@words[')
Got expected ParseError: 
('\n---', '@words.')
Got expected ParseError: 
(w
  <Lit_VarLike "a=">
  (ShArrayLiteral
    left:<Op_LParen "(">
    words:[(w <Lit_Chars 1>) (w <Lit_Chars 2>) (w <Lit_Chars 3>)]
    right:<Right_ShArrayLiteral ")">
  )
)

a=(1 2 3)
(Token
  id:Lit_VarLike
  length:2
  col:0
  line:(SourceLine
    line_num:1
    content:"a=(1 2 3)"
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w <Lit_Chars foo>)

foo
(Token
  id:Lit_Chars
  length:3
  col:0
  line:(SourceLine
    line_num:1
    content:foo
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w (word_part.EscapedLiteral token:<Lit_EscapedChar "\\$"> ch:"$"))

\$
(Token
  id:Lit_EscapedChar
  length:2
  col:0
  line:(SourceLine
    line_num:1
    content:"\\$"
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w (SQ ""))

''
(Token
  id:Left_SingleQuote
  length:1
  col:0
  line:(SourceLine
    line_num:1
    content:"''"
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w (SQ sq))

'sq'
(Token
  id:Left_SingleQuote
  length:1
  col:0
  line:(SourceLine
    line_num:1
    content:"'sq'"
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w (DQ))

""
(Token
  id:Left_DoubleQuote
  length:1
  col:0
  line:(SourceLine
    line_num:1
    content:"\"\""
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w (DQ <Lit_Chars dq>).)

"dq"
(Token
  id:Left_DoubleQuote
  length:1
  col:0
  line:(SourceLine
    line_num:1
    content:"\"dq\""
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w
  (CommandSub
    left_token:<Left_DollarParen "$(">
    child:(C (w <Lit_Chars echo>) (w <Lit_Chars command>) (w <Lit_Chars sub>))
    right:<Eof_RParen ")">
  )
)

$(echo command sub)
(Token
  id:Left_DollarParen
  length:2
  col:0
  line:(SourceLine
    line_num:1
    content:"$(echo command sub)"
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.Binary
      op:<Arith_Plus "+">
      left:(w <Lit_Digits 1>)
      right:(w <Lit_Digits 2>)
    )
    right:<Right_DollarDParen ")">
  )
)

$(( 1 + 2 ))
(Token
  id:Left_DollarDParen
  length:3
  col:0
  line:(SourceLine
    line_num:1
    content:"$(( 1 + 2 ))"
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w <Lit_Tilde "~"> <Lit_Chars user>)

~user
(Token
  id:Lit_Tilde
  length:1
  col:0
  line:(SourceLine
    line_num:1
    content:"~user"
    src:(source.MainFile path:word_parse_test.py)
  )
)

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary op:<VOp1_Pound "#"> arg_word:(w))
    right:<Right_DollarBrace "}">
  )
)

${var#}
(Token
  id:Left_DollarBrace
  length:2
  col:0
  line:(SourceLine
    line_num:1
    content:"${var#}"
    src:(source.MainFile path:word_parse_test.py)
  )
)


--- ${var/pat/replace}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Chars pat>)
      replace:(w <Lit_Chars replace>)
      replace_mode:Undefined_Tok
      slash_tok:<VOp2_Slash />
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var//pat/replace}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Chars pat>)
      replace:(w <Lit_Chars replace>)
      replace_mode:Lit_Slash
      slash_tok:<VOp2_Slash />
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var/%pat/replace}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Chars pat>)
      replace:(w <Lit_Chars replace>)
      replace_mode:Lit_Percent
      slash_tok:<VOp2_Slash />
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var/#pat/replace}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Chars pat>)
      replace:(w <Lit_Chars replace>)
      replace_mode:Lit_Pound
      slash_tok:<VOp2_Slash />
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var/pat}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Chars pat>)
      replace:(rhs_word.Empty)
      replace_mode:Undefined_Tok
      slash_tok:<VOp2_Slash />
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var//pat}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Chars pat>)
      replace:(rhs_word.Empty)
      replace_mode:Lit_Slash
      slash_tok:<VOp2_Slash />
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var/pat//}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Chars pat>)
      replace:(w <Lit_Slash />)
      replace_mode:Undefined_Tok
      slash_tok:<VOp2_Slash />
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var/pat///}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Chars pat>)
      replace:(w <Lit_Slash /> <Lit_Slash />)
      replace_mode:Undefined_Tok
      slash_tok:<VOp2_Slash />
    )
    right:<..Right_DollarBrace "}">
  )
)


--- ${var/pat/"//"}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Chars pat>)
      replace:(w (DQ <Lit_Chars //>))
      replace_mode:Undefined_Tok
      slash_tok:<VOp2_Slash />
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var////\\/}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.PatSub
      pat:(w <Lit_Slash />)
      replace:(w
        (word_part.EscapedLiteral token:<Lit_EscapedChar "\\\\"> ch:"\\")
        <Lit_Slash />
      )
      replace_mode:Lit_Slash
      slash_tok:<VOp2_Slash />
    )
    right:<Right_DollarBrace "}">
  )
)

---
ls "foo"
()
(w <Lit_Chars ls>)
(w (DQ <Lit_Chars foo>))
<Eof_Real "">
---
$(( 1 + 2 ))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.Binary
      op:<Arith_Plus "+">
      left:(w <Lit_Digits 1>)
      right:(w <Lit_Digits 2>)
    )
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
$(echo $(( 1 )) )
()
(w
  (CommandSub
    left_token:<Left_DollarParen "$(">
    child:(C
      (w <Lit_Chars echo>)
      (w
        (word_part.ArithSub
          left:<Left_DollarDParen "$((">
          anode:(w <Lit_Digits 1>)
          right:<Right_DollarDParen ")">
        )
      )
    )
    right:<Eof_RParen ")">
  )
)
<Eof_Real "">
---
echo ${#array[@]} b
()
(w <Lit_Chars echo>)
(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    prefix_op:<VSub_Pound "#">
    bracket_op:(bracket_op.WholeArray op_id:Lit_At)
    right:<Right_DollarBrace "}">
  )
)
(w <Lit_Chars b>)
<Eof_Real "">
---
echo $(( ${#array[@]} ))
()
(w <Lit_Chars echo>)
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(w
      (BracedVarSub
        left:<Left_DollarBrace "${">
        name_tok:<VSub_Name array>
        var_name:array
        prefix_op:<VSub_Pound "#">
        bracket_op:(bracket_op.WholeArray op_id:Lit_At)
        right:<Right_DollarBrace "}">
      )
    )
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
echo ${@%suffix}
()
(w <Lit_Chars echo>)
(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_At "@">
    var_name:"@"
    suffix_op:(suffix_op.Unary
      op:<VOp1_Percent "%">
      arg_word:(w <Lit_Chars suffix>)
    )
    right:<Right_DollarBrace "}">
  )
)
<Eof_Real "">
---
${@}
()
(w (${ VSub_At "@"))
<Eof_Real "">
---
echo ${var,,}
()
(w <Lit_Chars echo>)
(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary op:<VOp1_DComma ",,"> arg_word:(w))
    right:<Right_DollarBrace "}">
  )
)
<Eof_Real "">
---
echo ${var,,?}
()
(w <Lit_Chars echo>)
(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary
      op:<VOp1_DComma ",,">
      arg_word:(w <Lit_Other "?">)
    )
    right:<Right_DollarBrace "}">
  )
)
<Eof_Real "">
---
${\
foo}
()
(w (${ VSub_Name foo))
<Eof_Real "">
---
${foo\
}
()
(w (${ VSub_Name foo))
<Eof_Real "">
---
${foo#\
yo}
()
(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name foo>
    var_name:foo
    suffix_op:(suffix_op.Unary op:<VOp1_Pound "#"> arg_word:(w <Lit_Chars yo>))
    right:<Right_DollarBrace "}">
  )
)
<Eof_Real "">
---
"${foo#\
yo}"
()
(w
  (DQ
    (BracedVarSub
      left:<Left_DollarBrace "${">
      name_tok:<VSub_Name foo>
      var_name:foo
      suffix_op:(suffix_op.Unary
        op:<VOp1_Pound "#">
        arg_word:(w <Lit_Chars yo>)
      )
      right:<Right_DollarBrace "}">
    )
  )
)
<Eof_Real "">
---
1 + 2
()
(w <Lit_Digits 1>)
<Arith_Plus "+">
(w <Lit_Digits 2>)
<Eof_Real "">
---
a + b
()
(w <Lit_ArithVarLike a>)
<Arith_Plus "+">
(w <Lit_ArithVarLike b>)
<Eof_Real "">
---
$a * $b
()
(w ($ a))
<Arith_Star "*">
(w ($ b))
<Eof_Real "">
---
${a} * ${b}
()
(w (${ VSub_Name a))
<Arith_Star "*">
(w (${ VSub_Name b))
<Eof_Real "">
---
$(echo 1) * ...$(echo 2)
()
(w
  (CommandSub
    left_token:<Left_DollarParen "$(">
    child:(C (w <Lit_Chars echo>) (w <Lit_Chars 1>))
    right:<Eof_RParen ")">
  )
)
<Arith_Star "*">
(w
  (CommandSub
    left_token:<Left_DollarParen "$(">
    child:(C (w <Lit_Chars echo>) (w <Lit_Chars 2>))
    right:<Eof_RParen ")">
  )
)
<Eof_Real "">
---
`echo 1` + 2
()
(w
  (CommandSub
    left_token:<Left_Backtick "`">
    child:(C (w <Lit_Chars echo>) (w <Lit_Chars 1>))
    right:<Backtick_Right "`">
  )
)
<Arith_Plus "+">
(w <Lit_Digits 2>)
<Eof_Real "">
---
$((1 + 2)) * $((3 + 4))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.Binary
      op:<Arith_Plus "+">
      left:(w <Lit_Digits 1>)
      right:(w <Lit_Digits 2>)
    )
    right:<Right_DollarDParen ")">
  )
)
<Arith_Star "*">
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.Binary
      op:<Arith_Plus "+">
      left:(w <Lit_Digits 3>)
      right:(w <Lit_Digits 4>)
    )
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
'single quoted'
()
(w (SQ "single quoted"))
<Eof_Real "">
---
"${a}" + "${b}"
()
(w (DQ (${ VSub_Name a)))
<Arith_Plus "+">
(w (DQ (${ VSub_Name b)))
<Eof_Real "">
---
$# + $$
()
(w ($ VSub_Pound))
<Arith_Plus "+">
(w ($ VSub_Dollar))
<Eof_Real "">
---
$(( x[0] < 5 ))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.Binary
      op:<Arith_Less "<">
      left:(arith_expr.Binary
        op:<Arith_LBracket "[">
        left:<Lit_ArithVarLike x>
        right:(w <Lit_Digits 0>)
      )
      right:(w <Lit_Digits 5>)
    )
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
$(( ++i ))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.UnaryAssign op_id:Arith_DPlus child:<Lit_ArithVarLike i>)
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
$(( i++ ))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.UnaryAssign
      op_id:Node_PostDPlus
      child:<Lit_ArithVarLike i>
    )
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
$(( x -= 1))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.BinaryAssign
      op_id:Arith_MinusEqual
      left:<Lit_ArithVarLike x>
      right:(w <Lit_Digits 1>)
    )
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
$(( x |= 1))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.BinaryAssign
      op_id:Arith_PipeEqual
      left:<Lit_ArithVarLike x>
      right:(w <Lit_Digits 1>)
    )
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
$(( x[0] = 1 ))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.BinaryAssign
      op_id:Arith_Equal
      left:(arith_expr.Binary
        op:<Arith_LBracket "[">
        left:<Lit_ArithVarLike x>
        right:(w <Lit_Digits 0>)
      )
      right:(w <Lit_Digits 1>)
    )
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
$(( 1 | 0 ))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.Binary
      op:<Arith_Pipe "|">
      left:(w <Lit_Digits 1>)
      right:(w <Lit_Digits 0>)
    )
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">
---
$((0x$size))
()
(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(w <Lit_Digits 0> <Lit_ArithVarLike x> ($ size))
    right:<Right_DollarDParen ")">
  )
)
<Eof_Real "">

--- $(( (1+2) ))

(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.Binary
      op:<Arith_Plus "+">
      left:(w <Lit_Digits 1>)
      right:(w <Lit_Digits 2>)
    )
    right:<Right_DollarDParen ")">
  )
)


--- $(( (1+2) ))

(w
  (word_part.ArithSub
    left:<Left_DollarDParen "$((">
    anode:(arith_expr.Binary
      op:<Arith_Plus "+">
      left:(w <Lit_Digits 1>)
      right:(w <Lit_Digits 2>)
    )
    right:<Right_DollarDParen ")">
  )
)


--- ${foo:0}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name foo>
    var_name:foo
    suffix_op:(suffix_op.S......lice begin:(w <Lit_Digits 0>))
    right:<Arith_RBrace "}">
  )
)


--- ${foo:0:1}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name foo>
    var_name:foo
    suffix_op:(suffix_op.Slice
      begin:(w <Lit_Digits 0>)
      length:(w <Lit_Digits 1>)
    )
    right:<Arith_RBrace "}">
  )
)


--- ${foo:1+2:2+3}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name foo>
    var_name:foo
    suffix_op:(suffix_op.Slice
      begin:(arith_expr.Binary
        op:<Arith_Plus "+">
        left:(w <Lit_Digits 1>)
        right:(w <Lit_Digits 2>)
      )
      length:(arith_expr.Binary
        op:<Arith_Plus "+">
        left:(w <Lit_Digits 2>)
        right:(w <Lit_Digits 3>)
      )
    )
    right:<Arith_RBrace "}">
  )
)


--- ${foo::1}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name foo>
    var_name:foo
    suffix_op:(suffix_op.Slice
      begin:(arith_expr.EmptyZero)
      length:(w <Lit_Digits 1>)
    )
    right:<Arith_RBrace "}">
  )
)


--- ${var:-default]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary
      op:<VTest_ColonHyphen ":-">
      arg_word:(w <Lit_Chars "default]">)
    )
    right:<Right_DollarBrace "}">
  )
)


--- ~/git/oilshell/oil

(w
  <Lit_Tilde "~">
  <Lit_Slash />
  <Lit_Chars git>
  <Lit_Slash />
  <Lit_Chars oilshell>
  <Lit_Slash />
  <Lit_Chars oil>
)


--- ~andy/git/oilshell/oil

(w
  <Lit_Tilde "~">
  <Lit_Chars andy>
  <Lit_Slash />
  <Lit_Chars git>
  <Lit_Slash />
  <Lit_Chars oilshell>
  <Lit_Slash />
  <Lit_Chars oil>
)


--- ~andy_c/git/oilshell/oil

(w
  <Lit_Tilde "~">
  <Lit_Chars andy_c>
  <Lit_Slash />
  <Lit_Chars git>
  <Lit_Slash />
  <Lit_Chars oilshell>
  <Lit_Slash />
  <Lit_Chars oil>
)


--- ~andy.c/git/oilshell/oil

(w
  <Lit_Tilde "~">
  <Lit_Chars andy.c>
  <Lit_Slash />
  <Lit_Chars git>
  <Lit_Slash />
  <Lit_Chars oilshell>
  <Lit_Slash />
  <Lit_Chars oil>
)


--- ~andy-c/git/oilshell/oil

(w
  <Lit_Tilde "~">
  <Lit_Chars andy-c>
  <Lit_Slash />
  <Lit_Chars git>
  <Lit_Slash />
  <Lit_Chars oilshell>
  <Lit_Slash />
  <Lit_Chars oil>
)


--- ~andy-c:git/oilshell/oil

(w
  <Lit_Tilde "~">
  <Lit_Chars andy-c>
  <Lit_Colon ":">
  <Lit_Chars git>
  <Lit_Slash />
  <Lit_Chars oilshell>
  <Lit_Slash />
  <Lit_Chars oil>
)


--- ${var#}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary op:<VOp1_Pound "#"> arg_word:(w))
    right:<Right_DollarBrace "}">
  )
)


--- ${var#prefix}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary
      op:<VOp1_Pound "#">
      arg_word:(w <Lit_Chars prefix>)
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var##}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary op:<VOp1_DPound "##"> arg_word:(w))
    right:<Right_DollarBrace "}">
  )
)


--- ${var##prefix}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary
      op:<VOp1_DPound "##">
      arg_word:(w <Lit_Chars prefix>)
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var%suffix}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary
      op:<VOp1_Percent "%">
      arg_word:(w <Lit_Chars suffix>)
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${var%%suffix}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name var>
    var_name:var
    suffix_op:(suffix_op.Unary
      op:<VOp1_DPercent "%%">
      arg_word:(w <Lit_Chars suffix>)
    )
    right:<Right_DollarBrace "}">
  )
)


--- ${name}

(w (${ VSub_Name name))


--- ${name[0]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name name>
    var_name:name
    bracket_op:(bracket_op.ArrayIndex expr:(w <Lit_Digits 0>))
    right:<Righ.
----------------------------------------------------------------------
Ran 22 tests in 0.152s

OK
t_DollarBrace "}">
  )
)


--- ${array[@]}

(w
  (BracedVarSub
    left:<Left_DollarBrace "${">
    name_tok:<VSub_Name array>
    var_name:array
    bracket_op:(bracket_op.WholeArray op_id:Lit_At)
    right:<Right_DollarBrace "}">
  )
)