(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: [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_id: Redir_DLess
                            fd: 16777215
                            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: 16777215
                            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:16777215 arg_word:{(2)} spids:[154])]
                    )
                  ]
                  spids: [16777215 128]
                )
              ]
              spids: [16777215 158]
            )
          ]
          spids: [105 107 161 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_id:Redir_GreatAnd fd:16777215 arg_word:{(2)} spids:[188])]
            )
          ]
          spids: [165 167 192 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_id:Redir_GreatAnd fd:16777215 arg_word:{(2)} spids:[217])]
            )
          ]
          spids: [196 198 221 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: [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:16777215 arg_word:{(2)} spids:[264])]
              spids: [235 245]
            )
          ]
          spids: [225 227 268 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_id:Redir_GreatAnd fd:16777215 arg_word:{(2)} spids:[281])]
            )
          ]
          spids: [271 272 285 16777215]
        )
      ]
      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'))})
  ]
)