....(CompoundWord parts: [ (Token id: Id.Lit_Chars length: 2 col: 0 line: (SourceLine line_num:1 content:"hi'\n" src:(source.MainFile path:hi)) ) (SingleQuoted left: (Token id:Id.Left_SingleQuote length:1 col:2 line:...0x7f5e392df628) sval: "\nsingle quoted" right: (Token id: Id.Right_SingleQuote length: 1 col: 13 line: (SourceLine line_num:2 content:"single quoted'\"double\n" src:...0x7f5e392f11b8) ) ) (DoubleQuoted left: (Token id:Id.Left_DoubleQuote length:1 col:14 line:...0x7f5e392df680) parts: [ (Token id:Id.Lit_Chars length:7 col:15 line:...0x7f5e392df680) (Token id: Id.Lit_Chars length: 7 col: 0 line: (SourceLine line_num:3 content:"quoted\n" src:...0x7f5e392f11b8) ) ] right: (Token id: Id.Right_DoubleQuote length: 1 col: 0 line: (SourceLine line_num:4 content:"\"there\n" src:...0x7f5e392f11b8) ) ) (Token id:Id.Lit_Chars length:5 col:1 line:...0x7f5e392df788) ] ) s = '\'\nsingle quoted\'"double\nquoted\n"' s = "'\nsingle quoted'" s = 'hi' (CompoundWord parts: [ (Token id: Id.Lit_VarLike length: 4 col: 4 line: (SourceLine line_num:1 content:"ls; foo=42" src:(source.MainFile path:"")) ) (Token id:Id.Lit_Chars length:2 col:8 line:...0x7f5e392df6d8) ] ) (CompoundWord parts: [ (Token id: Id.Lit_VarLike length: 5 col: 4 line: (SourceLine line_num:1 content:"ls; foo+=X" src:(source.MainFile path:"")) ) (Token id:Id.Lit_Chars length:1 col:9 line:...0x7f5e392df7e0) ] ) --- ${array[0]} { (BracedVarSub left: token: var_name: array bracket_op: (bracket_op.ArrayIndex expr:{}) right: ) } --- ${array[5+5]} { (BracedVarSub left: token: var_name: array bracket_op: (bracket_op.ArrayIndex expr: (arith_expr.Binary op: left: {} right: {} ) ) right: ) } --- ${array[@]} { (BracedVarSub left: token: var_name: array bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) right: ) } --- ${array[*]} { (BracedVarSub left: token: var_name: array bracket_op: (bracket_op.WholeArray op_id:Id.Arith_Star) right: ) } --- ${#} {(${ Id.VSub_Pound "#")} --- ${!} {(${ Id.VSub_Bang "!")} --- ${?} {(${ Id.VSub_QMark "?")} --- ${var} {(${ Id.VSub_Name var)} --- ${15} {(${ Id.VSub_Number 15)} --- ${#var} { (BracedVarSub left: token: var_name: var prefix_op: right: ) } --- ${!ref} { (BracedVarSub left: token: var_name: ref prefix_op: right: ) } --- ${##} { (BracedVarSub left: token: var_name: "#" prefix_op: right: ) } --- ${array[0]} { (BracedVarSub left: token: var_name: array bracket_op: (bracket_op.ArrayIndex expr:{}) right: ) } --- ${array[@]} { (BracedVarSub left: token: var_name: array bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) right: ) } --- ${#array[0]} { (BracedVarSub left:..... token: var_name: array prefix_op: bracket_op: (bracket_op.ArrayIndex expr:{}) right: ) } --- ${!array[0]} { (BracedVarSub left: token: var_name: array prefix_op: bracket_op: (bracket_op.ArrayIndex expr:{}) right: ) } --- ${var#prefix} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } --- ${!var#prefix} { (BracedVarSub left: token: var_name: var prefix_op: suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } ('\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: --- ${#@} { (BracedVarSub left: token: var_name: "@" prefix_op: right: ) } --- ${#11} { (BracedVarSub left: token: var_name: 11 prefix_op: right: ) } --- ${#str} { (BracedVarSub left: token: var_name: str prefix_op: right: ) } --- ${#array[0]} { (BracedVarSub left: token: var_name: array prefix_op: bracket_op: (bracket_op.ArrayIndex expr:{}) right: ) } --- ${#array["key"]} { (BracedVarSub left: token: var_name: array prefix_op: bracket_op: (bracket_op.ArrayIndex expr:{(DQ )}) right: ) } --- @words {(word_part.Splice blame_tok: var_name:words)} --- .@words { } --- .@words. { } ('\n---', '@words[') Got expected ParseError: ('\n---', '@words.') Got expected ParseError: { words: [{} {} {}] right: ) } a=(1 2 3) (Token id: 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)) ) {} foo (Token id: Id.Lit_Chars length: 3 col: 0 line: (SourceLine line_num:1 content:foo src:(source.MainFile path:word_parse_test.py)) ) {(word_part.EscapedLiteral token: ch:"$")} \$ (Token id: Id.Lit_EscapedChar length: 2 col: 0 line: (SourceLine line_num:1 content:"\\$" src:(source.MainFile path:word_parse_test.py)) ) {(SQ "")} '' (Token id: Id.Left_SingleQuote length: 1 col: 0 line: (SourceLine line_num:1 content:"''" src:(source.MainFile path:word_parse_test.py)) ) {(SQ sq)} 'sq' (Token id: Id.Left_SingleQuote length: 1 col: 0 line: (SourceLine line_num:1 content:"'sq'" src:(source.MainFile path:word_par.se_test.py)) ) {(DQ )} "" (Token id: Id.Left_DoubleQuote length: 1 col: 0 line: (SourceLine line_num:1 content:"\"\"" src:(source.MainFile path:word_parse_test.py)) ) {(DQ )} "dq" (Token id: Id.Left_DoubleQuote length: 1 col: 0 line: (SourceLine line_num:1 content:"\"dq\"" src:(source.MainFile path:word_parse_test.py)) ) { (CommandSub left_token: child: (command.Simple blame_tok: more_env: [] words: [{} {} {}] do_fork: T ) right: ) } $(echo command sub) (Token id: Id.Left_DollarParen length: 2 col: 0 line: (SourceLine line_num: 1 content: "$(echo command sub)" src: (source.MainFile path:word_parse_test.py) ) ) { (word_part.ArithSub left: anode: (arith_expr.Binary op: left: {} right: {} ) right: ) } $(( 1 + 2 )) (Token id: Id.Left_DollarDParen length: 3 col: 0 line: (SourceLine line_num:1 content:"$(( 1 + 2 ))" src:(source.MainFile path:word_parse_test.py)) ) { } ~user (Token id: Id.Lit_Tilde length: 1 col: 0 line: (SourceLine line_num:1 content:"~user" src:(source.MainFile path:word_parse_test.py)) ) { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } ${var#} (Token id: 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} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: {} replace_mode: Id.Undefined_Tok slash_tok: ) right: ) } --- ${var//pat/replace} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: {} replace_mode: Id.Lit_Slash slash_tok: ) right: ) } --- ${var/%pat/replace} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: {} replace_mode: Id.Lit_Percent slash_tok: ) right: ) } --- ${var/#pat/replace} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: {} replace_mode: Id.Lit_Pound slash_tok: ) right: ) } --- ${var/pat} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: (rhs_word__Empty) replace_mode: Id.Undefined_Tok slash_tok: ) right: ) } --- ${var//pat} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: (rhs_word__Empty) replace_mode: Id.Lit_Slash slash_tok: ) right: ) } --- ${var/pat//} { (BracedVarSub .left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: {} replace_mode: Id.Undefined_Tok slash_tok: ) right: ) } --- ${var/pat///} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: { } replace_mode: Id.Undefined_Tok slash_tok: ) right: ) } --- ${var/pat/"//"} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: {(DQ )} replace_mode: Id.Undefined_Tok slash_tok: ) right: ) } --- ${var////\\/} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.PatSub pat: {} replace: {(word_part.EscapedLiteral token: ch:"\\") } replace_mode: Id.Lit_Slash slash_tok: ) right: ) } --- ls "foo" () {}{(DQ )}--- $(( 1 + 2 )) () { (word_part.ArithSub left: anode: (arith_expr.Binary op: left: {} right: {} ) right: ) }--- $(echo $(( 1 )) ) () { (CommandSub left_token: child: (command.Simple blame_tok: more_env: [] words: [ {} { (word_part.ArithSub left: anode: {} right: ) } ] do_fork: T ) right: ) }--- echo ${#array[@]} b () {}{ (BracedVarSub left: token: var_name: array prefix_op: bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) right: ) }{}--- echo $(( ${#array[@]} )) () {}{ (word_part.ArithSub left: anode: { (BracedVarSub left: token: var_name: array prefix_op: bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) right: ) } right: ) }--- echo ${@%suffix} () {}{ (BracedVarSub left: token: var_name: "@" suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) }--- ${@} () {(${ Id.VSub_At "@")}--- echo ${var,,} () {}{ (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) }--- echo ${var,,?} () {}{ (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: . ) }--- ${\ foo} () {(${ Id.VSub_Name foo)}--- ${foo\ } () {(${ Id.VSub_Name foo)}--- ${foo#\ yo} () { (BracedVarSub left: token: var_name: foo suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) }--- "${foo#\ yo}" () { (DQ (BracedVarSub left: token: var_name: foo suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) ) }--- 1 + 2 () {}{}--- a + b () {}{}--- $a * $b () {($ a)}{($ b)}--- ${a} * ${b} () {(${ Id.VSub_Name a)}{(${ Id.VSub_Name b)}--- $(echo 1) * $(echo 2) () { (CommandSub left_token: child: (command.Simple blame_tok: more_env: [] words: [{} {}] do_fork: T ) right: ) }{ (CommandSub left_token: child: (command.Simple blame_tok: more_env: [] words: [{} {}] do_fork: T ) right: ) }--- `echo 1` + 2 () { (CommandSub left_token: child: (command.Simple blame_tok: more_env: [] words: [{} {}] do_fork: T ) right: ) }{}--- $((1 + 2)) * $((3 + 4)) () { (word_part.ArithSub left: anode: (arith_expr.Binary op: left: {} right: {} ) right: ) }{ (word_part.ArithSub left: anode: (arith_expr.Binary op: left: {} right: {} ) 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 left: anode: (arith_expr.Binary op: left: (arith_expr.Binary op: left: right: {} ) right: {} ) right: ) }--- $(( ++i )) () { (word_part.ArithSub left: anode: (arith_expr.UnaryAssign op_id:Id.Arith_DPlus child:) right: ) }--- $(( i++ )) () { (word_part.ArithSub left: anode: (arith_expr.UnaryAssign op_id:Id.Node_PostDPlus child:) right: ) }--- $(( x -= 1)) () { (word_part.ArithSub left: anode: (arith_expr.BinaryAssign op_id: Id.Arith_MinusEqual left: right: {} ) right: ) }--- $(( x |= 1)) () { (word_part.ArithSub left: anode: (arith_expr.BinaryAssign op_id: Id.Arith_PipeEqual left: right: {} ) right: ) }--- $(( x[0] = 1 )) () { (word_part.ArithSub left: anode: (arith_expr.BinaryAssign op_id: Id.Arith_Equal left: (arith_expr.Binary op: left: right: {} ) right: {} ) right: ) }--- $(( 1 | 0 )) () { (word_part.ArithSub left: anode: (arith_expr.Binary op: left: {} right: {} ) right: ) }--- $((0x$size)) () { (word_part.ArithSub left: anode: { ($ size)} right: ) } --- $(( (1+2) )) { (word_part.ArithSub left: anode: (arith_expr.Binary op: left: {} right: {} ) right: ) } --- $(( (1+2) )) { (word_part.ArithSub left: anode: (arith_expr.Binary op: left: {} right: {} ) right: ) } --- ${foo:0} { (BracedVarSub left: token: var_name: foo suffix_op: (suffix_op.Slice begin:{}) right: ) } --- ${foo:0:1} { (BracedVarSub left: token: var_name: foo suffix_op: (suffix_op.Slice begin:{} length:{}) right: ) } --- ${foo:1+2:2+3} { (BracedVarSub left: token: var_name: foo suffix_op: (suffix_op.Slice begin: (arith_expr.Binary op: left: {} right: {} ) length: (arith_expr.Binary op: left: {} right: {} ) ) right: ) } --- ${foo::1} { (BracedVarSub left: token: var_name: foo suffix_op: (suffix_op.Slice begin:(arith_expr__EmptyZero) length:{}) right: ) } --- ${var:-default]} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } --- ~/git/oilshell/oil { } --- ~andy/git/oilshell/oil { } --- ~andy_c/git/oilshell/oil { } --- ~andy.c/git/oilshell/oil { } --- ~andy-c/git/oilshell/oil { .... ---------------------------------------------------------------------- Ran 22 tests in 0.088s OK } --- ~andy-c:git/oilshell/oil { } --- ${var#} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } --- ${var#prefix} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } --- ${var##} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } --- ${var##prefix} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } --- ${var%suffix} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } --- ${var%%suffix} { (BracedVarSub left: token: var_name: var suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } --- ${name} {(${ Id.VSub_Name name)} --- ${name[0]} { (BracedVarSub left: token: var_name: name bracket_op: (bracket_op.ArrayIndex expr:{}) right: ) } --- ${array[@]} { (BracedVarSub left: token: var_name: array bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) right: ) }