(command.CommandList
  children: [
    (command.If
      arms: [
        (if_arm
          cond: [
            (command.Sentence
              child: 
                (command.DBracket
                  expr: 
                    (bool_expr.BoolBinary
                      op_id: BoolBinary_EqualTilde
                      left: {(DQ ($ VSub_DollarName '$BASH_VERSION'))}
                      right: {(Lit_Other '^') (3)}
                    )
                )
              terminator: <Op_Semi ';'>
            )
          ]
          action: [
            (C {(echo)} {(SQ <'quinedb requires bash 4!'>)})
            (command.ControlFlow token:<ControlFlow_Exit exit> arg_word:{(1)})
          ]
        )
      ]
    )
    (command.Assignment
      keyword: Assign_Declare
      flags: [-A]
      pairs: [(assign_pair lhs:(lhs_expr.LhsName name:db) op:Equal)]
    )
    (command.Assignment
      keyword: Assign_None
      pairs: [(assign_pair lhs:(lhs_expr.LhsName name:db) op:Equal rhs:{(word_part.ArrayLiteralPart)})]
    )
    (command.Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (lhs_expr.LhsName name:PREAMBLE)
          op: Equal
          rhs: 
            {
              (word_part.CommandSubPart
                command_list: 
                  (command.CommandList
                    children: [
                      (command.SimpleCommand
                        words: [{(cat)}]
                        redirects: [
                          (redir.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 '$('>
              )
            }
        )
      ]
    )
    (command.Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (lhs_expr.LhsName name:POSTAMBLE)
          op: Equal
          rhs: 
            {
              (word_part.CommandSubPart
                command_list: 
                  (command.CommandList
                    children: [
                      (command.SimpleCommand
                        words: [{(cat)}]
                        redirects: [
                          (redir.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 '$('>
              )
            }
        )
      ]
    )
    (command.FuncDef
      name: pr_str
      body: (command.BraceGroup children:[(C {(printf)} {(DQ ('%q'))} {(DQ ($ VSub_Number '$1'))})])
    )
    (command.Case
      to_match: {(DQ ($ VSub_Number '$1'))}
      arms: [
        (case_arm
          pat_list: [{(DQ (get))}]
          action: [
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (command.Sentence
                      child: 
                        (C {(Lit_Other '[')} 
                          {
                            (word_part.BracedVarSub
                              token: <VSub_Name db>
                              bracket_op: 
                                (bracket_op.ArrayIndex
                                  expr: (arith_expr.ArithWord w:{(DQ ($ VSub_Number '$2'))})
                                )
                              suffix_op: (suffix_op.StringUnary op_id:VTest_Plus arg_word:{(_)})
                            )
                          } {(Lit_Other ']')}
                        )
                      terminator: <Op_Semi ';'>
                    )
                  ]
                  action: [
                    (command.Assignment
                      keyword: Assign_None
                      pairs: [
                        (assign_pair
                          lhs: (lhs_expr.LhsName name:v)
                          op: Equal
                          rhs: 
                            {
                              (word_part.BracedVarSub
                                token: <VSub_Name db>
                                bracket_op: 
                                  (bracket_op.ArrayIndex
                                    expr: (arith_expr.ArithWord w:{(DQ ($ VSub_Number '$2'))})
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.SimpleCommand
                      words: [
                        {(echo)}
                        {
                          (DQ 
                            (word_part.CommandSubPart
                              command_list: 
                                (command.CommandList
                                  children: [(C {(pr_str)} {(DQ ($ VSub_DollarName '$v'))})]
                                )
                              left_token: <Left_CommandSub '$('>
                            )
                          )
                        }
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                  ]
                )
              ]
            )
          ]
        )
        (case_arm
          pat_list: [{(DQ (set))}]
          action: [
            (command.Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: 
                    (lhs_expr.LhsIndexedName
                      name: db
                      index: (arith_expr.ArithWord w:{(DQ ($ VSub_Number '$2'))})
                    )
                  op: Equal
                  rhs: {(DQ ($ VSub_Number '$3'))}
                )
              ]
            )
            (command.SimpleCommand
              words: [{(echo)} {(SQ <OK>)}]
              redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
            )
          ]
        )
        (case_arm
          pat_list: [{(DQ (delete))}]
          action: [
            (C {(unset)} {(Lit_ArrayLhsOpen 'db[') (DQ ($ VSub_Number '$2')) (Lit_Other ']')})
            (command.SimpleCommand
              words: [{(echo)} {(SQ <OK>)}]
              redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
            )
          ]
        )
        (case_arm
          pat_list: [{(DQ (keys))}]
          action: [
            (command.ForEach
              iter_name: k
              iter_words: [
                {
                  (DQ 
                    (word_part.BracedVarSub
                      token: <VSub_Name db>
                      prefix_op: VSub_Bang
                      bracket_op: (bracket_op.WholeArray op_id:Lit_At)
                    )
                  )
                }
              ]
              do_arg_iter: F
              body: 
                (command.DoGroup
                  children: [
                    (command.Sentence
                      child: 
                        (C {(echo)} 
                          {
                            (DQ 
                              (word_part.CommandSubPart
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(pr_str)} {(DQ ($ VSub_DollarName '$k'))})]
                                  )
                                left_token: <Left_CommandSub '$('>
                              )
                            )
                          }
                        )
                      terminator: <Op_Semi ';'>
                    )
                  ]
                )
              redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
            )
          ]
        )
        (case_arm
          pat_list: [{(Lit_Other '*')}]
          action: [
            (command.SimpleCommand
              words: [{(echo)} {(DQ ('USAGE: quinedb [get k | set k v | delete k | keys]'))}]
              redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
            )
          ]
        )
      ]
    )
    (command.FuncDef
      name: print_db
      body: 
        (command.BraceGroup
          children: [
            (C {(echo)} {(DQ ('db=('))})
            (command.Assignment
              keyword: Assign_None
              pairs: [(assign_pair lhs:(lhs_expr.LhsName name:i) op:Equal rhs:{(0)})]
            )
            (command.ForEach
              iter_name: k
              iter_words: [
                {
                  (DQ 
                    (word_part.BracedVarSub
                      token: <VSub_Name db>
                      prefix_op: VSub_Bang
                      bracket_op: (bracket_op.WholeArray op_id:Lit_At)
                    )
                  )
                }
              ]
              do_arg_iter: F
              body: 
                (command.DoGroup
                  children: [
                    (command.Assignment
                      keyword: Assign_None
                      pairs: [
                        (assign_pair
                          lhs: 
                            (lhs_expr.LhsIndexedName
                              name: escaped_keys
                              index: (arith_expr.ArithWord w:{($ VSub_DollarName '$i')})
                            )
                          op: Equal
                          rhs: 
                            {
                              (word_part.CommandSubPart
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(pr_str)} {(DQ ($ VSub_DollarName '$k'))})]
                                  )
                                left_token: <Left_CommandSub '$('>
                              )
                            }
                        )
                      ]
                    )
                    (command.Assignment
                      keyword: Assign_None
                      pairs: [
                        (assign_pair
                          lhs: (lhs_expr.LhsName name:i)
                          op: Equal
                          rhs: 
                            {
                              (word_part.ArithSubPart
                                anode: 
                                  (arith_expr.ArithBinary
                                    op_id: Arith_Plus
                                    left: (arith_expr.ArithVarRef token:<Lit_ArithVarLike i>)
                                    right: (arith_expr.ArithWord w:{(Lit_Digits 1)})
                                  )
                              )
                            }
                        )
                      ]
                    )
                  ]
                )
            )
            (command.Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (lhs_expr.LhsName name:IFS)
                  op: Equal
                  rhs: 
                    {
                      (word_part.SingleQuotedPart
                        left: <Left_DollarSingleQuote "$'">
                        tokens: [<Char_OneChar '\\n'>]
                      )
                    }
                )
                (assign_pair
                  lhs: (lhs_expr.LhsName name:sorted)
                  op: Equal
                  rhs: 
                    {
                      (word_part.ArrayLiteralPart
                        words: [
                          {
                            (word_part.CommandSubPart
                              command_list: 
                                (command.CommandList
                                  children: [
                                    (command.Pipeline
                                      children: [
                                        (command.ForEach
                                          iter_name: l
                                          iter_words: [
                                            {
                                              (word_part.BracedVarSub
                                                token: <VSub_Name escaped_keys>
                                                bracket_op: (bracket_op.WholeArray op_id:Lit_At)
                                              )
                                            }
                                          ]
                                          do_arg_iter: F
                                          body: 
                                            (command.DoGroup
                                              children: [
                                                (command.Sentence
                                                  child: (C {(echo)} {($ VSub_DollarName '$l')})
                                                  terminator: <Op_Semi ';'>
                                                )
                                              ]
                                            )
                                        )
                                        (C {(sort)})
                                      ]
                                      negated: F
                                    )
                                  ]
                                )
                              left_token: <Left_CommandSub '$('>
                            )
                          }
                        ]
                      )
                    }
                )
              ]
            )
            (C {(unset)} {(IFS)})
            (command.ForEach
              iter_name: k
              iter_words: [
                {
                  (DQ 
                    (word_part.BracedVarSub
                      token: <VSub_Name sorted>
                      bracket_op: (bracket_op.WholeArray op_id:Lit_At)
                    )
                  )
                }
              ]
              do_arg_iter: F
              body: 
                (command.DoGroup
                  children: [
                    (command.Assignment
                      keyword: Assign_None
                      pairs: [
                        (assign_pair
                          lhs: (lhs_expr.LhsName name:unescaped)
                          op: Equal
                          rhs: 
                            {
                              (word_part.CommandSubPart
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(eval)} {(DQ ('echo ') ($ VSub_DollarName '$k'))})]
                                  )
                                left_token: <Left_CommandSub '$('>
                              )
                            }
                        )
                      ]
                    )
                    (command.Assignment
                      keyword: Assign_None
                      pairs: [
                        (assign_pair
                          lhs: (lhs_expr.LhsName name:v)
                          op: Equal
                          rhs: 
                            {
                              (word_part.BracedVarSub
                                token: <VSub_Name db>
                                bracket_op: 
                                  (bracket_op.ArrayIndex
                                    expr: 
                                      (arith_expr.ArithWord
                                        w: {(DQ ($ VSub_DollarName '$unescaped'))}
                                      )
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ ('    [') ($ VSub_DollarName '$k') (']=') 
                          (word_part.CommandSubPart
                            command_list: 
                              (command.CommandList
                                children: [(C {(pr_str)} {(DQ ($ VSub_DollarName '$v'))})]
                              )
                            left_token: <Left_CommandSub '$('>
                          )
                        )
                      }
                    )
                  ]
                )
            )
            (C {(echo)} {(DQ (')'))})
          ]
        )
    )
    (command.CommandList
      children: [
        (command.Sentence
          child: (C {(echo)} {(DQ ($ VSub_DollarName '$PREAMBLE'))})
          terminator: <Op_Semi ';'>
        )
        (C {(echo)})
      ]
    )
    (command.CommandList
      children: [(command.Sentence child:(C {(print_db)}) terminator:<Op_Semi ';'>) (C {(echo)})]
    )
    (C {(echo)} 
      {(SQ <'PREAMBLE=$(cat <<'>) (word_part.EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (EOF) 
        (word_part.EscapedLiteralPart token:<Lit_EscapedChar "\\'">)
      }
    )
    (C {(echo)} {(DQ ($ VSub_DollarName '$PREAMBLE'))})
    (C {(echo)} {(EOF)})
    (command.CommandList
      children: [
        (command.Sentence
          child: (C {(echo)} {(word_part.EscapedLiteralPart token:<Lit_EscapedChar '\\)'>)})
          terminator: <Op_Semi ';'>
        )
        (C {(echo)})
      ]
    )
    (C {(echo)} 
      {(SQ <'POSTAMBLE=$(cat <<'>) (word_part.EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (EOF) 
        (word_part.EscapedLiteralPart token:<Lit_EscapedChar "\\'">)
      }
    )
    (C {(echo)} {(DQ ($ VSub_DollarName '$POSTAMBLE'))})
    (C {(echo)} {(EOF)})
    (command.CommandList
      children: [
        (command.Sentence
          child: (C {(echo)} {(word_part.EscapedLiteralPart token:<Lit_EscapedChar '\\)'>)})
          terminator: <Op_Semi ';'>
        )
        (C {(echo)})
      ]
    )
    (C {(echo)} {(DQ ($ VSub_DollarName '$POSTAMBLE'))})
  ]
)