(command.CommandList
  children: [
    (command.If
      arms: [
        (if_arm
          cond: 
            (condition.Shell
              commands: [
                (command.Sentence
                  child: 
                    (command.DBracket
                      expr: 
                        (bool_expr.Binary
                          op_id: Id.BoolBinary_EqualTilde
                          left: {(DQ ($ Id.VSub_DollarName '$BASH_VERSION'))}
                          right: {<Id.Lit_Other '^'> <3>}
                        )
                    )
                  terminator: <Id.Op_Semi _>
                )
              ]
            )
          action: [
            (C {<echo>} {(SQ <'quinedb requires bash 4!'>)})
            (command.ControlFlow token:<Id.ControlFlow_Exit exit> arg_word:{<1>})
          ]
          spids: [4 20]
        )
      ]
    )
    (C {<declare>} {<-A>} {<db>})
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:db)
          op: assign_op.Equal
          rhs: {(sh_array_literal left:<Id.Op_LParen _>)}
          spids: [44]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:PREAMBLE)
          op: assign_op.Equal
          rhs: 
            {
              (command_sub
                left_token: <Id.Left_DollarParen '$('>
                child: 
                  (command.Simple
                    words: [{<cat>}]
                    redirects: [
                      (redir
                        op: <Id.Redir_DLess '<<'>
                        loc: (redir_loc.Fd fd:0)
                        arg: 
                          (redir_param.HereDoc
                            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'>
                            ]
                          )
                      )
                    ]
                    do_fork: T
                  )
              )
            }
          spids: [50]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:POSTAMBLE)
          op: assign_op.Equal
          rhs: 
            {
              (command_sub
                left_token: <Id.Left_DollarParen '$('>
                child: 
                  (command.Simple
                    words: [{<cat>}]
                    redirects: [
                      (redir
                        op: <Id.Redir_DLess '<<'>
                        loc: (redir_loc.Fd fd:0)
                        arg: 
                          (redir_param.HereDoc
                            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'>
                            ]
                          )
                      )
                    ]
                    do_fork: T
                  )
              )
            }
          spids: [71]
        )
      ]
    )
    (command.ShFunction
      name: pr_str
      body: (BraceGroup children:[(C {<printf>} {(DQ <'%q'>)} {(DQ ($ Id.VSub_Number '$1'))})])
    )
    (command.Case
      to_match: {(DQ ($ Id.VSub_Number '$1'))}
      arms: [
        (case_arm
          pat_list: [{(DQ <get>)}]
          action: [
            (command.If
              arms: [
                (if_arm
                  cond: 
                    (condition.Shell
                      commands: [
                        (command.Sentence
                          child: 
                            (C {<Id.Lit_LBracket '['>} 
                              {
                                (braced_var_sub
                                  token: <Id.VSub_Name db>
                                  bracket_op: 
                                    (bracket_op.ArrayIndex
                                      expr: {(DQ ($ Id.VSub_Number '$2'))}
                                    )
                                  suffix_op: (suffix_op.Unary tok:<Id.VTest_Plus '+'> arg_word:{<_>})
                                )
                              } {<Id.Lit_RBracket ']'>}
                            )
                          terminator: <Id.Op_Semi _>
                        )
                      ]
                    )
                  action: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:v)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (braced_var_sub
                                token: <Id.VSub_Name db>
                                bracket_op: (bracket_op.ArrayIndex expr:{(DQ ($ Id.VSub_Number '$2'))})
                              )
                            }
                          spids: [201]
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {<echo>}
                        {
                          (DQ 
                            (command_sub
                              left_token: <Id.Left_DollarParen '$('>
                              child: (C {<pr_str>} {(DQ ($ Id.VSub_DollarName '$v'))})
                            )
                          )
                        }
                      ]
                      redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})]
                      do_fork: T
                    )
                  ]
                  spids: [180 198]
                )
              ]
            )
          ]
          spids: [174 177 231 -1]
        )
        (case_arm
          pat_list: [{(DQ <set>)}]
          action: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.IndexedName name:db index:{(DQ ($ Id.VSub_Number '$2'))})
                  op: assign_op.Equal
                  rhs: {(DQ ($ Id.VSub_Number '$3'))}
                  spids: [240]
                )
              ]
            )
            (command.Simple
              words: [{<echo>} {(SQ <OK>)}]
              redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})]
              do_fork: T
            )
          ]
          spids: [234 237 264 -1]
        )
        (case_arm
          pat_list: [{(DQ <delete>)}]
          action: [
            (C {<unset>} 
              {<Id.Lit_ArrayLhsOpen 'db['> (DQ ($ Id.VSub_Number '$2')) <Id.Lit_RBracket ']'>}
            )
            (command.Simple
              words: [{<echo>} {(SQ <OK>)}]
              redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})]
              do_fork: T
            )
          ]
          spids: [267 270 292 -1]
        )
        (case_arm
          pat_list: [{(DQ <keys>)}]
          action: [
            (command.ForEach
              iter_name: k
              iter_words: [
                {
                  (DQ 
                    (braced_var_sub
                      token: <Id.VSub_Name db>
                      prefix_op: (Id.VSub_Bang)
                      bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At)
                    )
                  )
                }
              ]
              do_arg_iter: F
              body: 
                (command.DoGroup
                  children: [
                    (command.Sentence
                      child: 
                        (C {<echo>} 
                          {
                            (DQ 
                              (command_sub
                                left_token: <Id.Left_DollarParen '$('>
                                child: (C {<pr_str>} {(DQ ($ Id.VSub_DollarName '$k'))})
                              )
                            )
                          }
                        )
                      terminator: <Id.Op_Semi _>
                    )
                  ]
                )
              redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})]
            )
          ]
          spids: [295 298 339 -1]
        )
        (case_arm
          pat_list: [{<Id.Lit_Star '*'>}]
          action: [
            (command.Simple
              words: [{<echo>} {(DQ <'USAGE: quinedb [get k | set k v | delete k | keys]'>)}]
              redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})]
              do_fork: T
            )
          ]
          spids: [342 343 356 -1]
        )
      ]
    )
    (command.ShFunction
      name: print_db
      body: 
        (BraceGroup
          children: [
            (C {<echo>} {(DQ <'db=('>)})
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:i)
                  op: assign_op.Equal
                  rhs: {<0>}
                  spids: [378]
                )
              ]
            )
            (command.ForEach
              iter_name: k
              iter_words: [
                {
                  (DQ 
                    (braced_var_sub
                      token: <Id.VSub_Name db>
                      prefix_op: (Id.VSub_Bang)
                      bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At)
                    )
                  )
                }
              ]
              do_arg_iter: F
              body: 
                (command.DoGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: 
                            (sh_lhs_expr.IndexedName
                              name: escaped_keys
                              index: {($ Id.VSub_DollarName '$i')}
                            )
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Id.Left_DollarParen '$('>
                                child: (C {<pr_str>} {(DQ ($ Id.VSub_DollarName '$k'))})
                              )
                            }
                          spids: [402]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:i)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (word_part.ArithSub
                                anode: 
                                  (arith_expr.Binary
                                    op_id: Id.Arith_Plus
                                    left: <Id.Lit_ArithVarLike i>
                                    right: {<Id.Lit_Digits 1>}
                                  )
                              )
                            }
                          spids: [416]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:IFS)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (single_quoted
                        left: <Id.Left_DollarSingleQuote '$\''>
                        tokens: [<Id.Char_OneChar '\\n'>]
                        multiline: F
                      )
                    }
                  spids: [433]
                )
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:sorted)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (sh_array_literal
                        left: <Id.Op_LParen _>
                        words: [
                          {
                            (command_sub
                              left_token: <Id.Left_DollarParen '$('>
                              child: 
                                (command.Pipeline
                                  children: [
                                    (command.ForEach
                                      iter_name: l
                                      iter_words: [
                                        {
                                          (braced_var_sub
                                            token: <Id.VSub_Name escaped_keys>
                                            bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At)
                                          )
                                        }
                                      ]
                                      do_arg_iter: F
                                      body: 
                                        (command.DoGroup
                                          children: [
                                            (command.Sentence
                                              child: (C {<echo>} {($ Id.VSub_DollarName '$l')})
                                              terminator: <Id.Op_Semi _>
                                            )
                                          ]
                                        )
                                    )
                                    (C {<sort>})
                                  ]
                                  negated: F
                                )
                            )
                          }
                        ]
                      )
                    }
                  spids: [438]
                )
              ]
            )
            (C {<unset>} {<IFS>})
            (command.ForEach
              iter_name: k
              iter_words: [
                {
                  (DQ 
                    (braced_var_sub
                      token: <Id.VSub_Name sorted>
                      bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At)
                    )
                  )
                }
              ]
              do_arg_iter: F
              body: 
                (command.DoGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:unescaped)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Id.Left_DollarParen '$('>
                                child: (C {<eval>} {(DQ <'echo '> ($ Id.VSub_DollarName '$k'))})
                              )
                            }
                          spids: [496]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:v)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (braced_var_sub
                                token: <Id.VSub_Name db>
                                bracket_op: 
                                  (bracket_op.ArrayIndex
                                    expr: {(DQ ($ Id.VSub_DollarName '$unescaped'))}
                                  )
                              )
                            }
                          spids: [507]
                        )
                      ]
                    )
                    (C {<echo>} 
                      {
                        (DQ <'    ['> ($ Id.VSub_DollarName '$k') <']='> 
                          (command_sub
                            left_token: <Id.Left_DollarParen '$('>
                            child: (C {<pr_str>} {(DQ ($ Id.VSub_DollarName '$v'))})
                          )
                        )
                      }
                    )
                  ]
                )
            )
            (C {<echo>} {(DQ <')'>)})
          ]
        )
    )
    (command.CommandList
      children: [
        (command.Sentence
          child: (C {<echo>} {(DQ ($ Id.VSub_DollarName '$PREAMBLE'))})
          terminator: <Id.Op_Semi _>
        )
        (C {<echo>})
      ]
    )
    (command.CommandList
      children: [(command.Sentence child:(C {<print_db>}) terminator:<Id.Op_Semi _>) (C {<echo>})]
    )
    (C {<echo>} 
      {(SQ <'PREAMBLE=$(cat <<'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) <EOF> 
        (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>)
      }
    )
    (C {<echo>} {(DQ ($ Id.VSub_DollarName '$PREAMBLE'))})
    (C {<echo>} {<EOF>})
    (command.CommandList
      children: [
        (command.Sentence
          child: (C {<echo>} {(word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\)'>)})
          terminator: <Id.Op_Semi _>
        )
        (C {<echo>})
      ]
    )
    (C {<echo>} 
      {(SQ <'POSTAMBLE=$(cat <<'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) <EOF> 
        (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>)
      }
    )
    (C {<echo>} {(DQ ($ Id.VSub_DollarName '$POSTAMBLE'))})
    (C {<echo>} {<EOF>})
    (command.CommandList
      children: [
        (command.Sentence
          child: (C {<echo>} {(word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\)'>)})
          terminator: <Id.Op_Semi _>
        )
        (C {<echo>})
      ]
    )
    (C {<echo>} {(DQ ($ Id.VSub_DollarName '$POSTAMBLE'))})
  ]
)