....('\n---', '${array[0]}') { (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{(Lit_Digits 0)})) spids: [0 5] ) } ('\n---', '${array[5+5]}') { (BracedVarSub token: bracket_op: (ArrayIndex expr: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{(Lit_Digits 5)}) right: (ArithWord w:{(Lit_Digits 5)}) ) ) spids: [0 7] ) } ('\n---', '${array[@]}') {(BracedVarSub token: bracket_op:(WholeArray op_id:Lit_At) spids:[0 5])} ('\n---', '${array[*]}') {(BracedVarSub token: bracket_op:(WholeArray op_id:Arith_Star) spids:[0 5])} ('\n---', '${#}') {(${ VSub_Pound '#')} ('\n---', '${!}') {(${ VSub_Bang '!')} ('\n---', '${?}') {(${ VSub_QMark '?')} ('\n---', '${var}') {(${ VSub_Name var)} ('\n---', '${15}') {(${ VSub_Number 15)} ('\n---', '${#var}') {(BracedVarSub token: prefix_op:VSub_Pound spids:[0 3])} ('\n---', '${!ref}') {(BracedVarSub token: prefix_op:VSub_Bang spids:[0 3])} ('\n---', '${##}') {(BracedVarSub token: prefix_op:VSub_Pound spids:[0 3])} ('\n---', '${array[0]}') { (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{(Lit_Digits 0)})) spids: [0 5] ) } ('\n---', '${array[@]}') {(BracedVarSub token: bracket_op:(WholeArray op_id:Lit_At) spids:[0 5])} ('\n---', '${#array[0]}') { (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (ArrayIndex expr:(ArithWord w:{(Lit_Digits 0)})) spids: [0 6] ) } ('\n---', '${!array[0]}') { (BracedVarSub token: prefix_op: VSub_Bang bracket_op: (ArrayIndex expr:(ArithWord w:{(Lit_Digits 0)})) spids: [0 6] ) } ('\n---', '${var#prefix}') { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Pound arg_word:{(prefix)}) spids: [0 4] ) } ('\n---', '${!var#prefix}') { (BracedVarSub token: prefix_op: VSub_Bang suffix_op: (StringUnary op_id:VOp1_Pound arg_word:{(prefix)}) spids: [0 5] ) } ('\n---', '${#var#prefix}') [, ] ('\n---', '${##2}') [, ] ('\n---', '${#@}') {(BracedVarSub token: prefix_op:VSub_Pound spids:[0 3])} ('\n---', '${#11}') {(BracedVarSub token: prefix_op:VSub_Pound spids:[0 3])} ('\n---', '${#str}') {(BracedVarSub token: prefix_op:VSub_Pound spids:[0 3])} ('\n---', '${#array[0]}') { (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (ArrayIndex expr:(ArithWord w:{(Lit_Digits 0)})) spids: [0 6] ) } ('\n---', '${#array["key"]}') { (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (ArrayIndex expr:(ArithWord w:{(DQ (key))})) spids: [0 8] ) } --MULTI ('\n---', 'a=(1 2 3)') {(Lit_VarLike 'a=') (ArrayLiteralPart words:[{(1)} {(2)} {(3)}])} a=(1 2 3) 0 (line_span line_id:0 col:0 length:2) ('\n---', 'foo') {(foo)} foo 0 (line_span line_id:0 col:0 length:3) ('\n---', '\\$') {(EscapedLiteralPart token:)} \$ 0 (line_span line_id:0 col:0 length:2) ('\n---', "''") {(SQ )} '' 16777215 ('\n---', "'sq'") {(SQ )} 'sq' 1 (line_span line_id:0 col:1 length:2) ('\n---', '""') {(DQ )} "" 16777215 ('\n---', '"dq"') {(DQ (dq))} "dq" 1 (line_span line_id:0 col:1 length:2) ('\n---', '$(echo command sub)') { (CommandSubPart command_list: (CommandList children:[(C {(echo)} {(command)} {(sub)})]) left_token: spids: [0 6] ) } $(echo command sub) 0 (line_span.. line_id:0 col:0 length:2) ('\n---', '$(( 1 + 2 ))') { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{(Lit_Digits 1)}) right: (ArithWord w:{(Lit_Digits 2)}) ) spids: [0 9] ) } $(( 1 + 2 )) 0 (line_span line_id:0 col:0 length:3) ('\n---', '~user') {(Lit_Tilde '~') (user)} ~user 0 (line_span line_id:0 col:0 length:1) ('\n---', '${var#}') { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Pound arg_word:{}) spids: [0 3] ) } ${var#} 0 (line_span line_id:0 col:0 length:2) ('\n---', '${var/pat/replace}') { (BracedVarSub token: suffix_op: (PatSub pat:{(pat)} replace:{(replace)} do_all:F do_prefix:F do_suffix:F) spids: [0 6] ) } ('\n---', '${var//pat/replace}') { (BracedVarSub token: suffix_op: (PatSub pat:{(pat)} replace:{(replace)} do_all:T do_prefix:F do_suffix:F) spids: [0 7] ) } ('\n---', '${var/%pat/replace}') { (BracedVarSub token: suffix_op: (PatSub pat:{(pat)} replace:{(replace)} do_all:F do_prefix:F do_suffix:T) spids: [0 7] ) } ('\n---', '${var/#pat/replace}') { (BracedVarSub token: suffix_op: (PatSub pat:{(pat)} replace:{(replace)} do_all:F do_prefix:T do_suffix:F) spids: [0 7] ) } ('\n---', '${var/pat}') { (BracedVarSub token: suffix_op: (PatSub pat:{(pat)} do_all:F do_prefix:F do_suffix:F) spids: [0 4] ) } ('\n---', '${var//pat}') { (BracedVarSub token: suffix_op: (PatSub pat:{(pat)} do_all:T do_prefix:F do_suffix:F) spids: [0 5] ) } ('\n---', '${var/pat//}') { (BracedVarSub token: suffix_op: (PatSub pat:{(pat)} replace:{(Lit_Slash /)} do_all:F do_prefix:F do_suffix:F) spids: [0 6] ) } ('\n---', '${var/pat///}') { (BracedVarSub token: suffix_op: (PatSub pat: {(pat)} replace: {(Lit_Slash /) (Lit_Slash /)} do_all: F do_prefix: F do_suffix: F ) spids: [0 7] ) } ('\n---', '${var/pat/"//"}') { (BracedVarSub token: suffix_op: (PatSub pat:{(pat)} replace:{(DQ (//))} do_all:F do_prefix:F do_suffix:F) spids: [0 8] ) } ('\n---', '${var////\\\\/}') { (BracedVarSub token: suffix_op: (PatSub pat: {(Lit_Slash /)} replace: {(EscapedLiteralPart token:) (Lit_Slash /)} do_all: T do_prefix: F do_suffix: F ) spids: [0 8] ) } --- ls "foo" () {(ls)} {(DQ (foo))} (TokenWord token:) --- $(( 1 + 2 )) () { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{(Lit_Digits 1)}) right: (ArithWord w:{(Lit_Digits 2)}) ) spids: [0 9] ) } (TokenWord token:) --- $(echo $(( 1 )) ) () { (CommandSubPart command_list: (CommandList children: [(C {(echo)} {(ArithSubPart anode:(ArithWord w:{(Lit_Digits 1)}) spids:[3 8])})] ) left_token: spids: [0 10] ) } (TokenWord token:) --- echo ${#array[@]} b () {(echo)} { (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [2 8] ) } {(b)} (TokenWord token:) --- echo $(( ${#array[@]} )) () {(echo)} { (ArithSubPart anode: (ArithWord w: { (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [4 10] ) } ) spids: [2 13] ) } (TokenWord token:) --- echo ${@%suffix} () {(echo)} { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Percent arg_word:{(suffix)}) spids: [2 6] ) } (TokenWord token:) --- ${@} () {(${ VSub_At '@')} (TokenWord token:) --- echo ${var,,} () {(echo.)} { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_DComma arg_word:{}) spids: [2 5] ) } (TokenWord token:) --- echo ${var,,?} () {(echo)} { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_DComma arg_word:{('?')}) spids: [2 6] ) } (TokenWord token:) --- ${\ foo} () {(${ VSub_Name foo)} (TokenWord token:) --- ${foo\ } () {(${ VSub_Name foo)} (TokenWord token:) --- ${foo#\ yo} () { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Pound arg_word:{(yo)}) spids: [0 5] ) } (TokenWord token:) --- "${foo#\ yo}" () { (DQ (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Pound arg_word:{(yo)}) spids: [1 6] ) ) } (TokenWord token:) --- 1 + 2 () {(Lit_Digits 1)} (TokenWord token:) {(Lit_Digits 2)} (TokenWord token:) --- a + b () {(Lit_ArithVarLike a)} (TokenWord token:) {(Lit_ArithVarLike b)} (TokenWord token:) --- $a * $b () {($ VSub_Name '$a')} (TokenWord token:) {($ VSub_Name '$b')} (TokenWord token:) --- ${a} * ${b} () {(${ VSub_Name a)} (TokenWord token:) {(${ VSub_Name b)} (TokenWord token:) --- $(echo 1) * $(echo 2) () { (CommandSubPart command_list: (CommandList children:[(C {(echo)} {(1)})]) left_token: spids: [0 4] ) } (TokenWord token:) { (CommandSubPart command_list: (CommandList children:[(C {(echo)} {(2)})]) left_token: spids: [8 12] ) } (TokenWord token:) --- `echo 1` + 2 () { (CommandSubPart command_list: (CommandList children:[(C {(echo)} {(1)})]) left_token: spids: [0 4] ) } (TokenWord token:) {(Lit_Digits 2)} (TokenWord token:) --- $((1 + 2)) * $((3 + 4)) () { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{(Lit_Digits 1)}) right: (ArithWord w:{(Lit_Digits 2)}) ) spids: [0 7] ) } (TokenWord token:) { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{(Lit_Digits 3)}) right: (ArithWord w:{(Lit_Digits 4)}) ) spids: [11 18] ) } (TokenWord token:) --- 'single quoted' () {(SQ <'single quoted'>)} (TokenWord token:) --- "${a}" + "${b}" () {(DQ (${ VSub_Name a))} (TokenWord token:) {(DQ (${ VSub_Name b))} (TokenWord token:) --- $# + $$ () {($ VSub_Pound '$#')} (TokenWord token:) {($ VSub_Dollar '$$')} (TokenWord token:) --- $(( x[0] < 5 )) () { (ArithSubPart anode: (ArithBinary op_id: Arith_Less left: (ArithBinary op_id: Arith_LBracket left: (ArithVarRef name:x) right: (ArithWord w:{(Lit_Digits 0)}) ) right: (ArithWord w:{(Lit_Digits 5)}) ) spids: [0 12] ) } (TokenWord token:) --- $(( ++i )) () {(ArithSubPart anode:(UnaryAssign op_id:Arith_DPlus child:(LhsName name:i)) spids:[0 6])} (TokenWord token:) --- $(( i++ )) () {(ArithSubPart anode:(UnaryAssign op_id:Node_PostDPlus child:(LhsName name:i)) spids:[0 6])} (TokenWord token:) --- $(( x -= 1)) () { (ArithSubPart anode: (BinaryAssign op_id: Arith_MinusEqual left: (LhsName name:x) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [0 8] ) } (TokenWord token:) --- $(( x |= 1)) () { (ArithSubPart anode: (BinaryAssign op_id: Arith_PipeEqual left: (LhsName name:x) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [0 8] ) } (TokenWord token:) --- $(( x[0] = 1 )) () { (ArithSubPart anode: (BinaryAssign op_id: Arith_Equal left......... ---------------------------------------------------------------------- Ran 16 tests in 0.037s OK : (LhsIndexedName name:x index:(ArithWord w:{(Lit_Digits 0)})) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [0 12] ) } (TokenWord token:) --- $(( 1 | 0 )) () { (ArithSubPart anode: (ArithBinary op_id: Arith_Pipe left: (ArithWord w:{(Lit_Digits 1)}) right: (ArithWord w:{(Lit_Digits 0)}) ) spids: [0 9] ) } (TokenWord token:) --- $((0x$size)) () { (ArithSubPart anode: (ArithWord w:{(Lit_Digits 0) (Lit_ArithVarLike x) ($ VSub_Name '$size')}) spids: [0 5] ) } (TokenWord token:) ('\n---', '$(( f(x) ))') {(ArithSubPart anode:(FuncCall func:(ArithVarRef name:f) args:[(ArithVarRef name:x)]) spids:[0 8])} ('\n---', '$(( f(1, 2, 3, 4) ))') { (ArithSubPart anode: (FuncCall func: (ArithVarRef name:f) args: [ (ArithWord w:{(Lit_Digits 1)}) (ArithWord w:{(Lit_Digits 2)}) (ArithWord w:{(Lit_Digits 3)}) (ArithWord w:{(Lit_Digits 4)}) ] ) spids: [0 17] ) } ('\n---', '${foo:0}') { (BracedVarSub token: suffix_op: (Slice begin:(ArithWord w:{(Lit_Digits 0)})) spids: [0 4] ) } ('\n---', '${foo:0:1}') { (BracedVarSub token: suffix_op: (Slice begin:(ArithWord w:{(Lit_Digits 0)}) length:(ArithWord w:{(Lit_Digits 1)})) spids: [0 6] ) } ('\n---', '${foo:1+2:2+3}') { (BracedVarSub token: suffix_op: (Slice begin: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{(Lit_Digits 1)}) right: (ArithWord w:{(Lit_Digits 2)}) ) length: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{(Lit_Digits 2)}) right: (ArithWord w:{(Lit_Digits 3)}) ) ) spids: [0 10] ) } ('\n---', '${foo::1}') { (BracedVarSub token: suffix_op: (Slice length:(ArithWord w:{(Lit_Digits 1)})) spids: [0 5] ) } ('\n---', '${var:-default]}') { (BracedVarSub token: suffix_op: (StringUnary op_id:VTest_ColonHyphen arg_word:{('default]')}) spids: [0 4] ) } ('\n---', '${var#}') { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Pound arg_word:{}) spids: [0 3] ) } ('\n---', '${var#prefix}') { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Pound arg_word:{(prefix)}) spids: [0 4] ) } ('\n---', '${var##}') { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_DPound arg_word:{}) spids: [0 3] ) } ('\n---', '${var##prefix}') { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_DPound arg_word:{(prefix)}) spids: [0 4] ) } ('\n---', '${var%suffix}') { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Percent arg_word:{(suffix)}) spids: [0 4] ) } ('\n---', '${var%%suffix}') { (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_DPercent arg_word:{(suffix)}) spids: [0 4] ) } ('\n---', '${name}') {(${ VSub_Name name)} ('\n---', '${name[0]}') { (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{(Lit_Digits 0)})) spids: [0 5] ) } ('\n---', '${array[@]}') {(BracedVarSub token: bracket_op:(WholeArray op_id:Lit_At) spids:[0 5])}