*** Running test-parse-osh --- (command.CommandList children: [ (command.Simple blame_tok: more_env: [] words: [{} {<-s>} {} {}] redirects: [] do_fork: T ) (command.ShAssignment left: words: [ {($ Id.VSub_DollarName myglobal)} { (SingleQuoted left: tokens: [ ] right: ) } { (BracedVarSub left: token: var_name: z suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } ] right: ) ) (command.Simple blame_tok: <'spec/bin/argv.py'> more_env: [] words: [{<'spec/bin/argv.py'>} {}] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env: [] words: [ {} { child: (expr.FuncCall func: (expr.Var name:) args: (ArgList left: pos_args: [(expr.Var name:)] named_args: [] right: ) ) right: ) } ] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env:[] words:[{}] redirects:[] do_fork:T) (command.Simple blame_tok: more_env: [] words: [ {} {} {<_>} {(SQ <'1 2'>)} { (BracedVarSub left: token: var_name: myglobal suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) } ] redirects: [] do_fork: T ) (command.Simple blame_tok: <'spec/bin/argv.py'> more_env: [] words: [{<'spec/bin/argv.py'>} {}] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env: [] words: [ {} { child: (expr.FuncCall func: (expr.Var name:) args: (ArgList left: pos_args: [(expr.Var name:)] named_args: [] right: ) ) right: ) } ] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env:[] words:[{}] redirects:[] do_fork:T) (command.ForEach keyword: iter_names: [item] iterable: (for_iter.YshExpr e:(expr.Var name:) blame:) body: (BraceGroup left: children: [ (command.Simple blame_tok: more_env: [] words: [{} {(DQ <' '> ($ Id.VSub_DollarName item))}] redirects: [] do_fork: T ) ] redirects: [] right: ) redirects: [] ) ] ) --- (command.CommandList children: [ (command.ShFunction name_tok: name: argv body: (BraceGroup left: children: [ (command.Sentence child: (command.Simple blame_tok: <'spec/bin/argv.py'> more_env: [] words: [{<'spec/bin/argv.py'>} {(DQ ($ Id.VSub_At '@'))}] redirects: [] do_fork: T ) terminator: ) ] redirects: [] right: ) ) (command.ShAssignment left: token: var_name: regex bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) right: ) ) } ] ) semi_tok: body: (command.DoGroup left: children: [ (command.ShAssignment left: pairs: [ (AssignPair left: lhs: (sh_lhs.IndexedName left: name: flags index: { (BracedVarSub left: token: var_name: flags prefix_op: bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) right: ) } ) op: assign_op.Equal rhs: {(DQ <'--regex='> ($ Id.VSub_DollarName r))} ) ] redirects: [] ) ] right: ) redirects: [] ) (command.Simple blame_tok: more_env: [] words: [ {} { (DQ (BracedVarSub left: token: var_name: flags bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) right: ) ) } ] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env: [] words: [{} {<-s>} {} {}] redirects: [] do_fork: T ) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (ShArrayLiteral left: words: [{} {}] right: ) ) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (ShArrayLiteral left: words: [] right: ) ) (command.ForEach keyword: iter_names: [r] iterable: (for_iter.Words words:[{}]) semi_tok: body: (command.DoGroup left: children: [ (command.Simple blame_tok: more_env: [] words: [ {} { } {(DQ <'--regex='> ($ Id.VSub_DollarName r))} ] redirects: [] do_fork: T ) ] right: ) redirects: [] ) (command.Simple blame_tok: more_env: [] words: [{} {}] redirects: [] do_fork: T ) ] ) --- (command.CommandList children: [ (command.Simple blame_tok: more_env: [] words: [{} {(SQ <'This is a shell script with OSH extensions!'>)}] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env:[] words:[{}] redirects:[] do_fork:T) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (expr.Binary op: left: (expr.Const c:) right: (expr.Binary op: left: (expr.Const c:) right: (expr.Const c:) ) ) ) (command.Simple blame_tok: more_env: [] words: [{} {(DQ <'x: '> ($ Id.VSub_DollarName x))}] redirects: [] do_fork: T ) (command.Mutation keyword: lhs: [(y_lhs.Var name:)] op: rhs: (expr.Const c:) ) (command.Simple blame_tok: more_env: [] words: [{} {(DQ <'x: '> ($ Id.VSub_DollarName x))}] redirects: [] do_fork: T ) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (expr.List left: elts: [ (expr.Const c:) (expr.Const c:) (expr.Const c:) ] ctx: expr_context.Store ) ) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (expr.Binary op: left: (Subscript left: obj: (expr.Var name:) index: (expr.Const c:) ) right: (expr.Const c:) ) ) (command.Simple blame_tok: more_env: [] words: [{} {(DQ <'y: '> ($ Id.VSub_DollarName y))}] redirects: [] do_fork: T ) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (expr.Binary op: left: (expr.Var name:) right: (expr.List left: elts: [(expr.Const c:) (expr.Const c:)] ctx: expr_context.Store ) ) ) (command.Simple blame_tok: more_env: [] words: [{} {} {}] redirects: [] do_fork: T ) (command.ShAssignment left: )} ) ] redirects: [] ) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (DQ <'Oil string'>) ) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (expr.Binary op: left: (expr.Var name:) right: (expr.Var name:) ) ) (command.Simple blame_tok: more_env: [] words: [{} {(DQ <'str3 = '> ($ Id.VSub_DollarName str3))}] redirects: [] do_fork: T ) ] ) --- (command.CommandList children: [ (command.ShFunction name_tok: name: argv body: (BraceGroup left: children: [ (command.Simple blame_tok: more_env: [] words: [ {} {<-c>} {(SQ <'import sys;print(sys.argv[1:])'>)} {} ] redirects: [] do_fork: T ) ] redirects: [] right: ) ) (command.ShFunction name_tok: name: show body: (BraceGroup left: children: [ (command.Simple blame_tok: more_env: [] words: [{} {(SQ <'====='>)}] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env: [] words: [{} {}] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env: [] words: [{}] redirects: [] do_fork: T ) ] redirects: [] right: ) ) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (ShArrayLiteral left: words: [ {} {} { <.sh>} (word.BracedTree parts: [(word_part.BracedTuple words:[{} {}]) <.com>] ) {(SQ )} { (DQ <'dq '> (BracedVarSub left: token: var_name: x suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) ) } ] right: ) ) (command.Simple blame_tok: more_env: [] words: [{} {}] redirects: [] do_fork: T ) (command.VarDecl keyword: lhs: [(NameType name:)] rhs: (CommandSub left_token: child: (command.Simple blame_tok: more_env: [] words: [ {} {} {} { <.sh>} (word.BracedTree parts: [(word_part.BracedTuple words:[{} {}]) <.com>] ) {(SQ )} { (DQ <'dq '> (BracedVarSub left: token: var_name: x suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) ) } ] redirects: [] do_fork: T ) right: ) ) (command.Simple blame_tok: more_env: [] words: [{} {($ Id.VSub_DollarName cmd_sub)}] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env: [] words: [ {} { (word_part.ExprSub left: child: (expr.Binary op: left: (expr.Binary op: left:(SQ <'quoted '>) right:(SQ <'words '>)) right: (DQ <'dq '> (BracedVarSub left: token: var_name: x suffix_op: (suffix_op.Unary op: arg_word:{}) right: ) ) ) right: ) } ] redirects: [] do_fork: T ) ] ) --- (command.CommandList children: [ (command.Simple blame_tok: more_env: [] words: [ {} { (SingleQuoted left: tokens: [ ] right: ) } ] redirects: [] do_fork: T ) (command.VarDecl keyword: lhs: [(NameType name: typ:(TypeExpr tok: name:Int))] rhs: (expr.Binary op: left: (expr.Const c:) right: (expr.Binary op: left: (expr.Const c:) right: (expr.Const c:) ) ) ) (command.Simple blame_tok: more_env: [] words: [{} { child: (command.Simple blame_tok: more_env: [] words: [{} {}] redirects: [] do_fork: T ) right: ) right: (DQ (CommandSub left_token: child: (command.Simple blame_tok: more_env: [] words: [{} {}] redirects: [] do_fork: T ) right: ) ) ) ) (command.Simple blame_tok: more_env: [] words: [{} { children: [ (command.Sentence child: (command.Simple blame_tok: <'spec/bin/argv.py'> more_env: [] words: [{<'spec/bin/argv.py'>} {(DQ ($ Id.VSub_At '@'))}] redirects: [] do_fork: T ) terminator: ) ] redirects: [] right: ) ) (command.ShAssignment left: )} ) ] redirects: [] ) (command.ShAssignment left: more_env: [] words: [ {} {<-n>} {(DQ (${ Id.VSub_Name CONFIG_HAVE_FOO))} {} ] redirects: [] do_fork: T ) terminator: ) ] ) then_kw: action: [ (command.ShAssignment left: more_env: [] words: [ {} {<-n>} {(DQ (${ Id.VSub_Name CONFIG_HAVE_BAR))} {} ] redirects: [] do_fork: T ) terminator: ) ] ) then_kw: action: [ (command.ShAssignment left: )} ) ] redirects: [] ) ] spids: [92 107] ) ] else_action: [] fi_kw: redirects: [] ) (command.Simple blame_tok: more_env: [] words: [{} {(${ Id.VSub_Name flags)}] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env: [] words: [{} {<-o>} {}] redirects: [] do_fork: T ) (command.Simple blame_tok: more_env: [] words: [{} {<-s>} {} {}] redirects: [] do_fork: T ) (command.Mutation keyword: lhs: [(y_lhs.Var name:)] op: rhs: (DQ ) ) (command.Mutation keyword: lhs: [(y_lhs.Var name:)] op: rhs: (DQ <'/etc/path with spaces'>) ) (command.Mutation keyword: lhs: [(y_lhs.Var name:)] op: rhs: (ShArrayLiteral left: words: [] right: ) ) (command.If if_kw: arms: [ (IfArm keyword: cond: (condition.Shell commands: [ (command.Sentence child: (command.Simple blame_tok: more_env: [] words: [{} {<-n>} {($ Id.VSub_DollarName CONFIG_HAVE_FOO)}] redirects: [] do_fork: T ) terminator: ) ] ) then_kw: action: [ (command.Simple blame_tok: more_env: [] words: [{} {<-->} {<--foo> }] redirects: [] do_fork: T ) ] ) --- (command.CommandList children: [ (command.ShAssignment left: children: [ (command.Simple blame_tok: more_env: [] words: [{} { ) ) (command.ShFunction name_tok: name: f body: (BraceGroup left: children: [ (command.Simple blame_tok: more_env: [] words: [{} { ) ) (command.Simple blame_tok: more_env:[] words:[{}] redirects:[] do_fork:T) ] ) OK test-parse-osh *** Running test-run-osh ysh/testdata/array-rewrite-1.sh --- ['--regex=old1', '--regex=old2'] append :flags2 "--regex=$r" ^~~~~~ 'ysh/testdata/array-rewrite-1.sh':40: 'append' expected a List as a typed arg append :flags2 "--regex=$r" ^~~~~~ 'ysh/testdata/array-rewrite-1.sh':40: 'append' expected a List as a typed arg [] ysh/testdata/array-rewrite-2.sh --- ['--foo=/etc/path', 'with', 'spaces'] ['--foo=/etc/path with spaces'] ysh/testdata/sigil-pairs.sh --- ===== ['@ARGV'] ===== ['@ARGV'] ===== ['@ARGV'] ysh/testdata/array-splice-demo.osh --- shopt -s oil-parse-at static-word-eval ^~~~~ 'ysh/testdata/array-splice-demo.osh':2: 'shopt' got invalid option 'oil-parse-at' ['@myarray'] len=3 append myarray _ '1 2' ${myglobal:-default} ^~~~~~ 'ysh/testdata/array-splice-demo.osh':11: 'append' expected a List as a typed arg ['@myarray'] len=3 global line default ysh/testdata/assign.osh skipping ysh/testdata/assign.osh ysh/testdata/hello.osh --- This is a shell script with OSH extensions! x: 7 x: 8 y: 20 list2 = (Cell exported: F readonly: F nameref: F val: (value.List items: [(value.Int i:1) (value.Int i:2) (value.Int i:3) (value.Int i:4) (value.Int i:5)] ) ) str3 = shell stringOil string ysh/testdata/no-dynamic-scope.osh skipping ysh/testdata/no-dynamic-scope.osh OK test-run-osh *** Running test-run-ysh --- + Call in expression context: 3 + Inline call that coerces to string: 3 3 + Inline calls can be part of a word: --length=3 33 + Caveat: can't double quote. It would break programs. Should we add an option 'shopt -s parse_dparen'? --length=3 + Just as you can splice @myarray spam eggs ham + You can also splice the result of a function returning a sequence: Notes: - the Dict->reverse() method is from Python. hello world Parts: aaa BB c join(parts): aaaBBc + Another way of doing it, without creating another variable: aaaBBc j => aaa:BB:c When IFS is the default, split(j) => aaa:BB:c When IFS is :, split(j) => aaa BB c + Since there is no word splitting of unquoted $(ls), here is an idiom: bin/ lib/ --- hello 42 --- Hello world! first line second line Some string Some string $myvar Some string Some st Some s 11 DefaultValueIfFooIsMissingOrEmpty --- perhaps it's already here 42 I am just a normal string I am just a normal string and I am just a normal string I am just a normal string_ I am some string \n Hello world! I'm just a string it's true I really do it's true I really do Not a file I'm an abstraction I'm passed hi failure 2023 Here I am! could be anything really date: unrecognized option '--wrong-flag' Try 'date --help' for more information. there was an error number 2023-11-30 2023 OK test-run-ysh ysh/run.sh: 3 tests passed.