(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!">)}) (C {(exit)} {(1)})] spids: [-1 20] ) ] spids: [-1 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_id: Redir_DLess fd: -1 body: {("#!/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") } do_expansion: False here_end: EOF was_filled: True spids: [54] ) ] ) ] ) left_token: <Left_CommandSub "$("> spids: [51 59] ) } 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_id: Redir_DLess fd: -1 body: {("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") } do_expansion: False here_end: EOF was_filled: True spids: [66] ) ] ) ] ) left_token: <Left_CommandSub "$("> spids: [63 71] ) } spids: [62] ) ] spids: [62] ) (FuncDef name: pr_str body: (BraceGroup children: [(C {(printf)} {(DQ ("%q"))} {(DQ ($ VSub_Number "$1"))})] spids: [79] ) spids: [74 78] ) (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: [114 123] ) } {(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: [132 139] ) } spids: [131] ) ] spids: [131] ) (SimpleCommand words: [ {(echo)} { (DQ (CommandSubPart command_list: (CommandList children: [(C {(pr_str)} {(DQ ($ VSub_Name "$v"))})] ) left_token: <Left_CommandSub "$("> spids: [145 151] ) ) } ] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[154])] ) ] spids: [-1 128] ) ] spids: [-1 158] ) ] spids: [105 107 161 -1] ) (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_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[188])] ) ] spids: [165 167 192 -1] ) (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_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[217])] ) ] spids: [196 198 221 -1] ) (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: [237 243] ) ) } ] do_arg_iter: False 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: [252 258] ) ) } ) terminator: <Op_Semi ";"> ) ] spids: [247 262] ) redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[264])] spids: [235 245] ) ] spids: [225 227 268 -1] ) (case_arm pat_list: [{(Lit_Other "*")}] action: [ (SimpleCommand words: [{(echo)} {(DQ ("USAGE: quinedb [get k | set k v | delete k | keys]"))}] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[281])] ) ] spids: [271 272 285 -1] ) ] spids: [95 101 287] ) (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:[307])] spids: [307] ) (ForEach iter_name: k iter_words: [ { (DQ (BracedVarSub token: <VSub_Name db> prefix_op: VSub_Bang bracket_op: (WholeArray op_id:Lit_At) spids: [318 324] ) ) } ] do_arg_iter: False 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: [336 342] ) } ) (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: [346 351] ) } spids: [345] ) ] spids: [345] ) ] spids: [328 354] ) spids: [316 326] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:IFS) op: Equal rhs: {(SQ <Lit_EscapedChar "\\n">)} spids: [362] ) (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: [376 381] ) } ] do_arg_iter: False body: (DoGroup children: [ (Sentence child: (C {(echo)} {($ VSub_Name "$l")}) terminator: <Op_Semi ";"> ) ] spids: [384 391] ) spids: [375 382] ) (C {(sort)}) ] negated: False ) ] ) left_token: <Left_CommandSub "$("> spids: [369 396] ) } ] ) } spids: [367] ) ] spids: [362] ) (C {(unset)} {(IFS)}) (ForEach iter_name: k iter_words: [ { (DQ (BracedVarSub token: <VSub_Name sorted> bracket_op: (WholeArray op_id:Lit_At) spids: [413 418] ) ) } ] do_arg_iter: False 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: [426 433] ) } spids: [425] ) ] spids: [425] ) (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: [437 444] ) } spids: [436] ) ] spids: [436] ) (C {(echo)} { (DQ (" [") ($ VSub_Name "$k") ("]=") (CommandSubPart command_list: (CommandList children: [(C {(pr_str)} {(DQ ($ VSub_Name "$v"))})] ) left_token: <Left_CommandSub "$("> spids: [453 459] ) ) } ) ] spids: [422 463] ) spids: [411 420] ) (C {(echo)} {(DQ (")"))}) ] spids: [297] ) spids: [294 297] ) (Sentence child:(C {(echo)} {(DQ ($ VSub_Name "$PREAMBLE"))}) terminator:<Op_Semi ";">) (C {(echo)}) (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)}) (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)}) (Sentence child: (C {(echo)} {(EscapedLiteralPart token:<Lit_EscapedChar "\\)">)}) terminator: <Op_Semi ";"> ) (C {(echo)}) (C {(echo)} {(DQ ($ VSub_Name "$POSTAMBLE"))}) ] )