(CommandList children: [ (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_EqualTilde left: {(DQ ($ VSub_Name '$BASH_VERSION'))} right: {(Lit_Other '^') (3)} ) ) terminator: <Op_Semi ';'> ) ] action: [ (C {(echo)} {(SQ <'quinedb requires bash 4!'>)}) (ControlFlow token:<ControlFlow_Exit exit> arg_word:{(1)}) ] spids: [16777215 20] ) ] spids: [16777215 34] ) (Assignment keyword: Assign_Declare flags: [-A] pairs: [(assign_pair lhs:(LhsName name:db) op:Equal spids:[41])] spids: [37] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:db) op:Equal rhs:{(ArrayLiteralPart)} spids:[44])] spids: [44] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:PREAMBLE) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (SimpleCommand words: [{(cat)}] redirects: [ (HereDoc op: <Redir_DLess '<<'> fd: 16777215 here_begin: {(SQ <EOF>)} here_end_span_id: 67 stdin_parts: [ ('#!/usr/bin/env bash\n') ('\n') ('if [[ "$BASH_VERSION" =~ ^3 ]]; then\n') (" echo 'quinedb requires bash 4!'\n") (' exit 1\n') ('fi\n') ('\n') ('declare -A db\n') ] ) ] ) ] ) left_token: <Left_CommandSub '$('> spids: [51 68] ) } spids: [50] ) ] spids: [50] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:POSTAMBLE) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (SimpleCommand words: [{(cat)}] redirects: [ (HereDoc op: <Redir_DLess '<<'> fd: 16777215 here_begin: {(SQ <EOF>)} here_end_span_id: 140 stdin_parts: [ ('pr_str () {\n') (' printf "%q" "$1"\n') ('}\n') ('\n') ('case "$1" in\n') (' "get")\n') (' if [ ${db["$2"]+_} ]; then\n') (' v=${db["$2"]}\n') (' echo "$(pr_str "$v")" >&2\n') (' fi\n') (' ;;\n') (' "set")\n') (' db["$2"]="$3"\n') (" echo 'OK' >&2\n") (' ;;\n') (' "delete")\n') (' unset db["$2"]\n') (" echo 'OK' >&2\n") (' ;;\n') (' "keys")\n') ( ' for k in "${!db[@]}"; do echo "$(pr_str "$k")"; done >&2\n' ) (' ;;\n') (' *)\n') ( ' echo "USAGE: quinedb [get k | set k v | delete k | keys]" >&2\n' ) (' ;;\n') ('esac\n') ('\n') ('# print self\n') ('\n') ('print_db(){\n') (' echo "db=("\n') (' i=0\n') (' for k in "${!db[@]}"; do\n') (' escaped_keys[$i]=$(pr_str "$k")\n') (' i=$((i+1))\n') (' done\n') ('\n') (' # sort the keys for deterministic printing\n') ( " IFS=$'\\n' sorted=($(for l in ${escaped_keys[@]}; do echo $l; done | sort))\n" ) (' unset IFS\n') ('\n') (' for k in "${sorted[@]}"; do\n') (' unescaped=$(eval "echo $k")\n') (' v=${db["$unescaped"]}\n') (' echo " [$k]=$(pr_str "$v")"\n') (' done\n') (' echo ")"\n') ('}\n') ('\n') ('echo "$PREAMBLE"; echo\n') ('print_db; echo\n') ("echo 'PREAMBLE=$(cat <<'\\'EOF\\'\n") ('echo "$PREAMBLE"\n') ('echo EOF\n') ('echo \\); echo\n') ("echo 'POSTAMBLE=$(cat <<'\\'EOF\\'\n") ('echo "$POSTAMBLE"\n') ('echo EOF\n') ('echo \\); echo\n') ('echo "$POSTAMBLE"\n') ] ) ] ) ] ) left_token: <Left_CommandSub '$('> spids: [72 141] ) } spids: [71] ) ] spids: [71] ) (FuncDef name: pr_str body: (BraceGroup children: [(C {(printf)} {(DQ ('%q'))} {(DQ ($ VSub_Number '$1'))})] spids: [149] ) spids: [144 148] ) (Case to_match: {(DQ ($ VSub_Number '$1'))} arms: [ (case_arm pat_list: [{(DQ (get))}] action: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other '[')} { (BracedVarSub token: <VSub_Name db> bracket_op: (ArrayIndex expr:(ArithWord w:{(DQ ($ VSub_Number '$2'))})) suffix_op: (StringUnary op_id:VTest_Plus arg_word:{(_)}) spids: [184 193] ) } {(Lit_Other ']')} ) terminator: <Op_Semi ';'> ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:v) op: Equal rhs: { (BracedVarSub token: <VSub_Name db> bracket_op: (ArrayIndex expr:(ArithWord w:{(DQ ($ VSub_Number '$2'))})) spids: [202 209] ) } spids: [201] ) ] spids: [201] ) (SimpleCommand words: [ {(echo)} { (DQ (CommandSubPart command_list: (CommandList children: [(C {(pr_str)} {(DQ ($ VSub_Name '$v'))})] ) left_token: <Left_CommandSub '$('> spids: [215 221] ) ) } ] redirects: [(Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})] ) ] spids: [16777215 198] ) ] spids: [16777215 228] ) ] spids: [174 177 231 16777215] ) (case_arm pat_list: [{(DQ (set))}] action: [ (C {(db) (Lit_Other '[') (DQ ($ VSub_Number '$2')) (Lit_Other ']') (Lit_Other '=') (DQ ($ VSub_Number '$3')) } ) (SimpleCommand words: [{(echo)} {(SQ <OK>)}] redirects: [(Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})] ) ] spids: [234 237 262 16777215] ) (case_arm pat_list: [{(DQ (delete))}] action: [ (C {(unset)} {(db) (Lit_Other '[') (DQ ($ VSub_Number '$2')) (Lit_Other ']')}) (SimpleCommand words: [{(echo)} {(SQ <OK>)}] redirects: [(Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})] ) ] spids: [265 268 291 16777215] ) (case_arm pat_list: [{(DQ (keys))}] action: [ (ForEach iter_name: k iter_words: [ { (DQ (BracedVarSub token: <VSub_Name db> prefix_op: VSub_Bang bracket_op: (WholeArray op_id:Lit_At) spids: [307 313] ) ) } ] do_arg_iter: F body: (DoGroup children: [ (Sentence child: (C {(echo)} { (DQ (CommandSubPart command_list: (CommandList children: [(C {(pr_str)} {(DQ ($ VSub_Name '$k'))})] ) left_token: <Left_CommandSub '$('> spids: [322 328] ) ) } ) terminator: <Op_Semi ';'> ) ] spids: [317 332] ) redirects: [(Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})] spids: [305 315] ) ] spids: [294 297 338 16777215] ) (case_arm pat_list: [{(Lit_Other '*')}] action: [ (SimpleCommand words: [{(echo)} {(DQ ('USAGE: quinedb [get k | set k v | delete k | keys]'))}] redirects: [(Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})] ) ] spids: [341 342 355 16777215] ) ] spids: [165 171 357] ) (FuncDef name: print_db body: (BraceGroup children: [ (C {(echo)} {(DQ ('db=('))}) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:i) op:Equal rhs:{(0)} spids:[377])] spids: [377] ) (ForEach iter_name: k iter_words: [ { (DQ (BracedVarSub token: <VSub_Name db> prefix_op: VSub_Bang bracket_op: (WholeArray op_id:Lit_At) spids: [388 394] ) ) } ] do_arg_iter: F body: (DoGroup children: [ (C {(escaped_keys) (Lit_Other '[') ($ VSub_Name '$i') (Lit_Other ']') (Lit_Other '=') (CommandSubPart command_list: (CommandList children: [(C {(pr_str)} {(DQ ($ VSub_Name '$k'))})] ) left_token: <Left_CommandSub '$('> spids: [406 412] ) } ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:i) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithVarRef name:i) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [416 421] ) } spids: [415] ) ] spids: [415] ) ] spids: [398 424] ) spids: [386 396] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:IFS) op: Equal rhs: { (SingleQuotedPart left: <Left_DollarSingleQuote "$'"> tokens: [<Char_OneChar '\\n'>] spids: [433 435] ) } spids: [432] ) (assign_pair lhs: (LhsName name:sorted) op: Equal rhs: { (ArrayLiteralPart words: [ { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (ForEach iter_name: l iter_words: [ { (BracedVarSub token: <VSub_Name escaped_keys> bracket_op: (WholeArray op_id:Lit_At) spids: [446 451] ) } ] do_arg_iter: F body: (DoGroup children: [ (Sentence child: (C {(echo)} {($ VSub_Name '$l')}) terminator: <Op_Semi ';'> ) ] spids: [454 461] ) spids: [445 452] ) (C {(sort)}) ] negated: F ) ] ) left_token: <Left_CommandSub '$('> spids: [439 466] ) } ] ) } spids: [437] ) ] spids: [432] ) (C {(unset)} {(IFS)}) (ForEach iter_name: k iter_words: [ { (DQ (BracedVarSub token: <VSub_Name sorted> bracket_op: (WholeArray op_id:Lit_At) spids: [483 488] ) ) } ] do_arg_iter: F body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:unescaped) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [(C {(eval)} {(DQ ('echo ') ($ VSub_Name '$k'))})] ) left_token: <Left_CommandSub '$('> spids: [496 503] ) } spids: [495] ) ] spids: [495] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:v) op: Equal rhs: { (BracedVarSub token: <VSub_Name db> bracket_op: (ArrayIndex expr: (ArithWord w:{(DQ ($ VSub_Name '$unescaped'))}) ) spids: [507 514] ) } spids: [506] ) ] spids: [506] ) (C {(echo)} { (DQ (' [') ($ VSub_Name '$k') (']=') (CommandSubPart command_list: (CommandList children: [(C {(pr_str)} {(DQ ($ VSub_Name '$v'))})] ) left_token: <Left_CommandSub '$('> spids: [523 529] ) ) } ) ] spids: [492 533] ) spids: [481 490] ) (C {(echo)} {(DQ (')'))}) ] spids: [367] ) spids: [364 367] ) (CommandList children: [ (Sentence child: (C {(echo)} {(DQ ($ VSub_Name '$PREAMBLE'))}) terminator: <Op_Semi ';'> ) (C {(echo)}) ] ) (CommandList children: [(Sentence child:(C {(print_db)}) terminator:<Op_Semi ';'>) (C {(echo)})] ) (C {(echo)} {(SQ <'PREAMBLE=$(cat <<'>) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (EOF) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) } ) (C {(echo)} {(DQ ($ VSub_Name '$PREAMBLE'))}) (C {(echo)} {(EOF)}) (CommandList children: [ (Sentence child: (C {(echo)} {(EscapedLiteralPart token:<Lit_EscapedChar '\\)'>)}) terminator: <Op_Semi ';'> ) (C {(echo)}) ] ) (C {(echo)} {(SQ <'POSTAMBLE=$(cat <<'>) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (EOF) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) } ) (C {(echo)} {(DQ ($ VSub_Name '$POSTAMBLE'))}) (C {(echo)} {(EOF)}) (CommandList children: [ (Sentence child: (C {(echo)} {(EscapedLiteralPart token:<Lit_EscapedChar '\\)'>)}) terminator: <Op_Semi ';'> ) (C {(echo)}) ] ) (C {(echo)} {(DQ ($ VSub_Name '$POSTAMBLE'))}) ] )