*** Running test-parse-osh --- (command.CommandList children:[ (C (w ) (w (SingleQuoted left: sval:"one\ntwo" right: ) ) ) (command.VarDecl keyword: lhs:[ (NameType left: name:a typ:(TypeExpr tok: name:Int) ) ] rhs:(expr.Binary op: left:(Const Expr_DecInt _) right:(expr.Binary op: left:(Const Expr_DecInt _) right:(Const Expr_DecInt _) ) ) ) (C (w ) (w rhs:(Var b) ) terminator: ) (C (w ) (w )) ] ) (command.Mutation keyword: lhs:[] op: rhs:(Const Expr_DecInt _) ) (command.VarDecl keyword: lhs:[(NameType left: name:y)] rhs:(Var a) ) (command.VarDecl keyword: lhs:[(NameType left: name:z)] rhs:(Var b) ) (C (w ) (w )) (command.VarDecl keyword: lhs:[(NameType left: name:mycmd)] rhs:(expr.Binary op: left:(CommandSub left_token: child:(C (w ) (w )) right: ) right:(DQ (CommandSub left_token: child:(C (w ) (w )) right: ) ) ) ) (C (w ) (w left:(${ VSub_Name b) right:(DQ (${ VSub_Name b)) ) ) (C (w ) (w left:(expr.Binary op: left:(Const Expr_DecInt _) right:(Const Expr_DecInt _) ) right:(Const Expr_DecInt _) ) ) (C (w ) (w left:(Const Expr_DecInt _) right:(Const Expr_DecInt _) ) ) (C (w ) (w left:(Const Expr_DecInt _) right:(Const Expr_DecInt _) ) ) (C (w ) (w children:[ (C (w ) (w ) ) (command.ShFunction name_tok: name:f body:(BraceGroup left: children:[ (C (w ) (w ) ) (C (w )) ] ) --- (command.CommandList children:[ (C (w ) (w (SQ "This is a shell script with OSH extensions!")) ) (C (w )) (command.VarDecl keyword: lhs:[(NameType left: name:x)] rhs:(expr.Binary op: left:(Const Expr_DecInt _) right:(expr.Binary op: left:(Const Expr_DecInt _) right:(Const Expr_DecInt _) ) ) ) (C (w ) (w (DQ ($ x)))) (command.Mutation keyword: lhs:[] op: ($ x)))) (command.VarDecl keyword: lhs:[(NameType left: name:mylist)] rhs:(expr.List left: elts:[(Const Expr_DecInt _) (Const Expr_DecInt _) (Const Expr_DecInt _)] ctx:expr_context.Store ) ) (command.VarDecl keyword: lhs:[(NameType left: name:y)] rhs:(expr.Binary op: left:(Subscript left: obj:(Var mylist) index:(Const Expr_DecInt _) ) right:(Const Expr_DecInt _) ) ) (C (w ) (w (DQ ($ y)))) (command.VarDecl keyword: lhs:[(NameType left: name:list2)] rhs:(expr.Binary op: left:(Var mylist) right:(expr.List left: elts:[(Const Expr_DecInt _) (Const Expr_DecInt _)] ctx:expr_context.Store ) ) ) (C (w ) (w ) (w )) (command.ShAssignment left: lhs:[(NameType left: name:str2)] rhs:(DQ ) ) (command.VarDecl keyword: lhs:[(NameType left: name:str3)] rhs:(expr.Binary op: left:(Var str1) right:(Var str2)) ) (C (w ) (w (DQ children:[ (command.Sentence child:(C (w ) (w (DQ ($ VSub_At))) ) terminator: ) ] right: ) ) (command.ShAssignment left: arms:[ (IfArm keyword:...0x7f70b0aeef58 cond:(List_of_command (command.Sentence child:(C (w ) (w ) (w (DQ (${ VSub_Name CONFIG_HAVE_FOO))) (w ) ) terminator: ) ) then_kw: action:[ (command.ShAssignment left:) (w ) (w (DQ (${ VSub_Name CONFIG_HAVE_BAR))) (w ) ) terminator: ) ) then_kw: action:[ (command.ShAssignment left:)) ) ] ) ] then_tok:...0x7f70b07cfef0 ) ] else_action:[] fi_kw: ) (C (w ) (w (${ VSub_Name flags))) (C (w ) (w ) (w )) (C (w ) (w ) (w ) (w ) ) (command.Mutation keyword: lhs:[] op: rhs:(DQ ) ) (command.Mutation keyword: lhs:[] op: words:[] right: ) ) (command.If if_kw: arms:[ (IfArm keyword:...0x7f70b07d4808 cond:(List_of_command (command.Sentence child:(C (w ) (w ) (w ($ CONFIG_HAVE_FOO)) ) terminator: ) ) then_kw: action:[ (command.Simple blame_tok: more_env:[] words:[ (w ) (w ) (w pos_args:[(Var flags)] named_args:[] right: ) is_last_cmd:F ) ] then_tok:...0x7f70b07de258 ) ] else_action:[] fi_kw: ) (command.If if_kw: arms:[ (IfArm keyword:...0x7f70b07de738 cond:(List_of_command (command.Sentence child:(C (w ) (w ) (w ($ CONFIG_HAVE_BAR)) ) terminator: ) ) then_kw: action:[ (command.Simple blame_tok: more_env:[] words:[ (w ) (w ) (w ) ] typed_args:(ArgList left: pos_args:[(Var flags)] named_args:[] right: ) is_last_cmd:F ) ] then_tok:...0x7f70b07de940 ) ] else_action:[] fi_kw: ) (C (w ) (w )) ] ) --- (command.CommandList children:[ (command.ShFunction name_tok: name:argv body:(BraceGroup left: children:[ (command.Sentence child:(C (w ) (w (DQ ($ VSub_At))) ) terminator: ) ] right: ) ) (command.ShAssignment left: words:[(w ) (w )] right: ) ) ) ] ) (command.ShAssignment left: words:[] right: ) ) ) ] ) (command.ForEach keyword: iter_names:[r] iterable:(for_iter.Words words:[ (w (DQ (BracedVarSub left: name_tok: var_name:regex bracket_op:(bracket_op.WholeArray op_id:Lit_At) right: ) ) ) ] ) semi_tok: body:(command.DoGroup left: children:[ (command.ShAssignment left: pairs:[ (AssignPair left:...0x7f95feae9600 lhs:(sh_lhs.IndexedName left:...0x7f95feae9600 name:flags index:(w (BracedVarSub left: name_tok: var_name:flags prefix_op: bracket_op:(bracket_op.WholeArray op_id:Lit_At) right: ) ) ) op:assign_op.Equal rhs:(w (DQ name_tok: var_name:flags bracket_op:(bracket_op.WholeArray op_id:Lit_At) right: ) ) ) ) (C (w ) (w ) (w ) (w ) ) (command.VarDecl keyword: lhs:[(NameType left: name:regex2)] rhs:(ShArrayLiteral left: words:[(w ) (w )] right: ) ) (command.VarDecl keyword: lhs:[(NameType left: name:flags2)] rhs:(ShArrayLiteral left: words:[] right: ) ) (command.ForEach keyword: iter_names:[r] iterable:(for_iter.Words words:[(w )]) semi_tok: body:(command.DoGroup left: children:[ (command.Simple blame_tok: more_env:[] words:[(w ) (w (DQ pos_args:[(Var flags2)] named_args:[] right: ) is_last_cmd:F ) ] right: ) ) (C (w ) (w )) ] ) --- (command.CommandList children:[ (C (w ) (w ) (w ) (w ) ) (command.ShAssignment left: words:[ (w ($ myglobal)) (w (SingleQuoted left: sval:"line\n" right: ) ) (w (BracedVarSub left: name_tok: var_name:z suffix_op:(suffix_op.Unary op: arg_word:(w ) ) right: ) ) ] right: ) ) (C (w ) (w ) ) (C (w ) (w child:(expr.FuncCall func:(Var len) args:(ArgList left: pos_args:[(Var myarray)] named_args:[] right: ) ) right: ) ) ) (C (w )) (command.Simple blame_tok: more_env:[] words:[ (w ) (w ) (w (SQ "1 2")) (w (BracedVarSub left: name_tok: var_name:myglobal suffix_op:(suffix_op.Unary op: arg_word:(w ) ) right: ) ) ] typed_args:(ArgList left: pos_args:[(Var myarray)] named_args:[] right: ) is_last_cmd:F ) (C (w ) (w ) ) (C (w ) (w child:(expr.FuncCall func:(Var len) args:(ArgList left: pos_args:[(Var myarray)] named_args:[] right: ) ) right: ) ) ) (C (w )) (command.ForEach keyword: iter_names:[item] iterable:(for_iter.YshExpr e:(Var myarray) blame:) body:(BraceGroup left: children:[(C (w ) (w (DQ ($ item))))] right: ) ) ] ) --- (command.CommandList children:[ (command.ShFunction name_tok: name:argv body:(BraceGroup left: children:[ (C (w ) (w ) (w (SQ "import sys;print(sys.argv[1:])")) (w ) ) ] right: ) ) (command.ShFunction name_tok: name:show body:(BraceGroup left: children:[ (C (w ) (w (SQ "====="))) (C (w ) (w )) (C (w )) ] right: ) ) (command.VarDecl keyword: lhs:[(NameType left: name:strarray)] rhs:(ShArrayLiteral left: words:[ (w ) (w ) (w ) (word.BracedTree parts:[ (word_part.BracedTuple words:[(w ) (w )] ) ] ) (w (SQ sq)) (w (DQ (BracedVarSub left: name_tok: var_name:x suffix_op:(suffix_op.Unary op: arg_word:(w ) ) right: ) ) ) ] right: ) ) (C (w ) (w )) (command.VarDecl keyword: lhs:[(NameType left: name:cmd_sub)] rhs:(CommandSub left_token: child:(C (w ) (w ) (w ) (w ) (word.BracedTree parts:[ (word_part.BracedTuple words:[(w ) (w )] ) ] ) (w (SQ sq)) (w (DQ (BracedVarSub left: name_tok: var_name:x suffix_op:(suffix_op.Unary op: arg_word:(w ) ) right: ) ) ) ) right: ) ) (C (w ) (w ($ cmd_sub))) (C (w ) (w (word_part.ExprSub left: child:(expr.Binary op: left:(expr.Binary op: left:(SQ "quoted ") right:(SQ "words ") ) right:(DQ (BracedVarSub left: name_tok: var_name:x suffix_op:(suffix_op.Unary op: arg_word:(w ) ) right: ) ) ) right: ) ) ) ] ) OK test-parse-osh *** Running test-run-osh ysh/testdata/array-rewrite-1.sh --- ['--regex=old1', '--regex=old2'] append "--regex=$r" (flags2) ^ ysh/testdata/array-rewrite-1.sh:40: 'append' doesn't accept flag -- append "--regex=$r" (flags2) ^ ysh/testdata/array-rewrite-1.sh:40: 'append' doesn't accept flag -- [] 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 ['@myarray'] len=6 global line default _ 1 2 global 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 pp cell list2 ^~~~ ysh/testdata/hello.osh:26: 'pp' got invalid action 'cell' 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 2025 Here I am! could be anything really date: unrecognized option '--wrong-flag' Try 'date --help' for more information. there was an error number 2025-01-01 2025 OK test-run-ysh ysh/run.sh: 3 tests passed.