.....('\n---', '${array[0]}') {(braced_var_sub token: bracket_op:(bracket_op.ArrayIndex expr:{}))}('\n---', '${array[5+5]}') { (braced_var_sub token: bracket_op: (bracket_op.ArrayIndex expr: (arith_expr.Binary op_id: Id.Arith_Plus left: {} right: {} ) ) ) }('\n---', '${array[@]}') {(braced_var_sub token: bracket_op:(bracket_op.WholeArray op_id:Id.Lit_At))}('\n---', '${array[*]}') {(braced_var_sub token: bracket_op:(bracket_op.WholeArray op_id:Id.Arith_Star))}('\n---', '${#}') {(${ Id.VSub_Pound '#')}('\n---', '${!}') {(${ Id.VSub_Bang '!')}('\n---', '${?}') {(${ Id.VSub_QMark '?')}('\n---', '${var}') {(${ Id.VSub_Name var)}('\n---', '${15}') {(${ Id.VSub_Number 15)}('\n---', '${#var}') {(braced_var_sub token: prefix_op:(Id.VSub_Pound))}('\n---', '${!ref}') {(braced_var_sub token: prefix_op:(Id.VSub_Bang))}('\n---', '${##}') {(braced_var_sub token: prefix_op:(Id.VSub_Pound))}('\n---', '${array[0]}') {(braced_var_sub token: bracket_op:(bracket_op.ArrayIndex expr:{}))}('\n---', '${array[@]}') {(braced_var_sub token: bracket_op:(bracket_op.WholeArray op_id:Id.Lit_At))}('\n---', '${#array[0]}') { (braced_var_sub token: prefix_op: (Id.VSub_Pound) bracket_op: (bracket_op.ArrayIndex expr:{}) ) }('\n---', '${!array[0]}') { (braced_var_sub token: prefix_op: (Id.VSub_Bang) bracket_op: (bracket_op.ArrayIndex expr:{}) ) }('\n---', '${var#prefix}') { (braced_var_sub token: suffix_op: (suffix_op.Unary op_id:Id.VOp1_Pound arg_word:{}) ) }('\n---', '${!var#prefix}') { (braced_var_sub token: prefix_op: (Id.VSub_Bang) suffix_op: (suffix_op.Unary op_id:Id.VOp1_Pound arg_word:{}) ) }('\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: ('\n---', '--foo=$func()') {<--foo> args:(arg_list))}('\n---', '$func()trailer') {(word_part.FuncCall name: args:(arg_list)) }('\n---', '--foo=$func()trailer') {<--foo> args:(arg_list)) }('\n---...', '${#@}') {(braced_var_sub token: prefix_op:(Id.VSub_Pound))}('\n---', '${#11}') {(braced_var_sub token: prefix_op:(Id.VSub_Pound))}('\n---', '${#str}') {(braced_var_sub token: prefix_op:(Id.VSub_Pound))}('\n---', '${#array[0]}') { (braced_var_sub token: prefix_op: (Id.VSub_Pound) bracket_op: (bracket_op.ArrayIndex expr:{}) ) }('\n---', '${#array["key"]}') { (braced_var_sub token: prefix_op: (Id.VSub_Pound) bracket_op: (bracket_op.ArrayIndex expr:{(DQ )}) ) }('\n---', '@words') {(word_part.Splice name:)}('\n---', '.@words') {<.> }('\n---', '.@words.') {<.> <.>}('\n---', '@words[') Got expected ParseError: ('\n---', '@words.') Got expected ParseError: ('\n---', '@func()') {(word_part.FuncCall name: args:(arg_list))}('\n---', '$(echo @func())') { (command_sub left_token: child: (C {} {(word_part.FuncCall name: args:(arg_list))}) ) }('\n---', '$(($(echo @func())))') { (word_part.ArithSub anode: { (command_sub left_token: child: (C {} {(word_part.FuncCall name: args:(arg_list))}) ) } ) }('\n---', '@func().') Got expected ParseError: {)}\$ 0 (line_span line_id:0 col:0 length:2) {(SQ )}'' 0 (line_span line_id:0 col:0 length:1) {(SQ )}'sq' 0 (line_span line_id:0 col:0 length:1) {(DQ )}"" 0 (line_span line_id:0 col:0 length:1) {(DQ )}"dq" 0 (line_span line_id:0 col:0 length:1) {(command_sub left_token: child:(C {} {} {}))}$(echo command sub) 0 (line_span line_id:0 col:0 length:2) { (word_part.ArithSub anode: (arith_expr.Binary op_id:Id.Arith_Plus left:{} right:{}) ) }$(( 1 + 2 )) 0 (line_span line_id:0 col:0 length:3) {}~user 0 (line_span line_id:0 col:0 length:5) {(braced_var_sub token: suffix_op:(suffix_op.Unary op_id:Id.VOp1_Pound arg_word:{}))}${var#} 0 (line_span line_id:0 col:0 length:2) ('\n---', '${var/pat/replace}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat:{} replace:{} replace_mode:Id.Undefined_Tok) ) }('\n---', '${var//pat/replace}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat:{} replace:{} replace_mode:Id.Lit_Slash) ) }('\n---', '${var/%pat/replace}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat:{} replace:{} replace_mode:Id.Lit_Percent) ) }('\n---', '${var/#pat/replace}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat:{} replace:{} replace_mode:Id.Lit_Pound) ) }('\n---', '${var/pat}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat:{} replace_mode:Id.Undefined_Tok) ) }('\n---', '${var//pat}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat:{} replace_mode:Id.Lit_Slash) ) }('\n---', '${var/pat//}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat:{} replace:{} replace_mode:Id.Undefined_Tok) ) }('\n---', '${var/pat///}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat: {} replace: { } replace_mode: Id.Undefined_Tok ) ) }('\n---', '${var/pat/"//"}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat:{} replace:{(DQ <'//'>)} replace_mode:Id.Undefined_Tok) ) }('\n---', '${var////\\\\/}') { (braced_var_sub token: suffix_op: (suffix_op.PatSub pat: {} replace: {(word_part.EscapedLiteral token:) } replace_mode: Id.Lit_Slash ) ) }--- ls "foo" () {}{(DQ )}--- $(( 1 + 2 )) () { (word_part.ArithSub anode: (arith_expr.Binary op_id:Id.Arith_Plus left:{} right:{}) ) }--- $(echo $(( 1 )) ) () { (command_sub left_token: child: (C {} {(word_part.ArithSub anode:{})}) ) }--- echo ${#array[@]} b () {}{ (braced_var_sub token: prefix_op: (Id.VSub_Pound) bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) ) }{}--- echo $(( ${#array[@]} )) () {}{ (word_part.ArithSub anode: { (braced_var_sub token: prefix_op: (Id.VSub_Pound) bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) ) } ) }--- echo ${@%suffix} () {}{ (braced_var_sub token: suffix_op: (suffix_op.Unary op_id:Id.VOp1_Percent arg_word:{}) ) }--- ${@} () {(${ Id.VSub_At '@')}--- echo ${var,,} () {}{(braced_var_sub token: suffix_op:(suffix_op.Unary op_id:Id.VOp1_DComma arg_word:{}))}--- echo ${var,,?} () {}{ (braced_var_sub token: suffix_op: (suffix_op.Unary op_id:Id.VOp1_DComma arg_word:{<'?'>}) ) }--- ${\ foo} () {(${ Id.VSub_Name foo)}--- ${foo\ } () {(${ Id.VSub_Name foo)}--- ${foo#\ yo} () { (braced_var_sub token: suffix_op: (suffix_op.Unary op_id:Id.VOp1_Pound arg_word:{}) ) }--- "${foo#\ yo}" () { (DQ (braced_var_sub token: suffix_op: (suffix_op.Unary op_id:Id.VOp1_Pound arg_word:{}) ) ) }--- 1 + 2 () {}{}--- a + b () {}{}--- $a * $b () {($ Id.VSub_DollarName '$a')}{($ Id.VSub_DollarName '$b')}--- ${a} * ${b} () {(${ Id.VSub_Name a)}{(${ Id.VSub_Name b)}--- $(echo 1) * $(echo 2) () {(command_sub left_token: child:(C {} {<1>}))}{(command_sub left_token: child:(C {} {<2>}))}--- `echo 1` + 2 () {(command_sub left_token: child:(C {} {<1>}))}{}--- $((1 + 2)) * $((3 + 4)) () { (word_part.ArithSub anode: (arith_expr.Binary op_id:Id.Arith_Plus left:{} right:{}) ) }{ (word_part.ArithSub anode: (arith_expr.Binary op_id:Id.Arith_Plus left:{} right:{}) ) }--- 'single quoted' () {(SQ <'single quoted'>)}--- "${a}" + "${b}" () {(DQ (${ Id.VSub_Name a))}{(DQ (${ Id.VSub_Name b))}--- $# + $$ () {($ Id.VSub_Pound '$#')}{($ Id.VSub_Dollar '$$')}--- $(( x[0] < 5 )) () { (word_part.ArithSub anode: (arith_expr.Binary op_id: Id.Arith_Less left: (arith_expr.Binary op_id: Id.Arith_LBracket left: right: {} ) right: {} ) ) }--- $(( ++i )) () {(word_part.ArithSub anode:(arith_expr.UnaryAssign op_id:Id.Arith_DPlus child:))}--- $(( i++ )) () { (word_part.ArithSub anode: (arith_expr.UnaryAssign op_id:Id.Node_PostDPlus child:) ) }--- $(( x -= 1)) () { (word_part.ArithSub anode: (arith_expr.BinaryAssign op_id: Id.Arith_MinusEqual left: right: {} ) ) }--- $(( x |= 1)) () { (word_part.ArithSub anode: (arith_expr.BinaryAssign op_id: Id.Arith_PipeEqual left: right: {} ) ) }--- $(( x[0] = 1 )) () { (word_part.ArithSub anode: (arith_expr.BinaryAssign op_id: Id.Arith_Equal left: (arith_expr.Binary op_id: Id.Arith_LBracket left: right: {} ) right: {} ) ) }--- $(( 1 | 0 )) () { (word_part.ArithSub anode: (arith_expr.Binary op_id:Id.Arith_Pipe left:{} right:{}) ) }--- $((0x$size)) () {(word_part.ArithSub anode:{ ($ Id.VSub_DollarName '$size')})}('\n---', '$(( (1+2) ))') { (word_part.ArithSub anode: (arith_expr.Binary op_id:Id.Arith_Plus left:{} right:{}) ) }('\n---', '$(( (1+2) ))') { (word_part.ArithSub anode: (arith_expr.Binary op_id:Id.Arith_Plus left:{} right:{}) ) }('\n---', '${foo:0}') {(braced_var_sub token: suffix_op:(suffix_op.Slice begin:{}))}('\n---', '${foo:0:1}') { (braced_var_sub token: suffix_op: (suffix_op.Slice begin:{} length:{}) ) }('\n---', '${foo:1+2:2+3}') { (braced_var_sub token: suffix_op: (suffix_op.Slice begin: (arith_expr.Binary op_id: Id.Arith_Plus left: {} right: {} ) length: (arith_expr.Binary op_id: Id.Arith_Plus left: {} right: {} ) ) ) }('\n---', '${foo::1}') {(braced_var_sub token: suffix_op:(suffix_op.Slice length:{}))}('\n---', '${var:-default]}') { (braced_var_sub token: suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:{<'default]'>}) ) }('\n---', '~/git/oilshell/oil') { <'/git/oilshell/oil'>}('\n---', '~andy/git/oilshell/oil') { <'/git/oilshell/oil'>}('\n---', '~andy_c/git/oilshell/oil') { <'/git/oilshell/oil'>}('\n---', '~andy.c/git/oilshell/oil') { <'/git/oilshell/oil'>}('\n---', '~andy-c/git/oilshell/oil') { <'/git/oilshell/oil'>}('\n---', '~andy-c:git/oilshell/oil') { <'git/oilshell/oil'>}('\n---', '${var#}') {(braced_var_sub token: suffix_op:(suffix_op.Unary op_id:Id.VOp1_Pound arg_word:{}))}('\n---', '${var#prefix}') { (braced_var_sub token: suffix_op: (suffix_op.Unary op_id:Id.VOp1_Pound arg_word:{}) ) }('\n---', '${var##}') {(braced_var_sub token: suffix_op:(suffix_op.Unary op_id:Id.VOp1_DPound arg_word:{}))}('\n---', '${var##prefix}') { (braced_var_sub token: suffix_op: (suffix_op.Unary op_id:Id.VOp1_DPound arg_word:{}) ) }('\n---', '${var%suffix}') { (braced_var_sub token: suffix_op: (suffix_op.Unary op_... ---------------------------------------------------------------------- Ran 21 tests in 0.096s OK id:Id.VOp1_Percent arg_word:{}) ) }('\n---', '${var%%suffix}') { (braced_var_sub token: suffix_op: (suffix_op.Unary op_id:Id.VOp1_DPercent arg_word:{}) ) }('\n---', '${name}') {(${ Id.VSub_Name name)}('\n---', '${name[0]}') {(braced_var_sub token: bracket_op:(bracket_op.ArrayIndex expr:{}))}('\n---', '${array[@]}') {(braced_var_sub token: bracket_op:(bracket_op.WholeArray op_id:Id.Lit_At))}