let rec pp_print_statement ppf st= 
  match st.pstmt_t with
      PstmtLabeled(l,st) ->
        fprintf ppf "%a:@\n%a"
          pp_print_identifier l
          pp_print_statement st
    | PstmtCase_Labeled(e,st) ->
        fprintf ppf "case %a:@\n%a"
          pp_print_expression e
          pp_print_statement st
    | PstmtDefault_Labeled st ->
        fprintf ppf "default:@\n%a"
          pp_print_statement st
    | PstmtExpr(None->
        fprintf ppf ";"
    | PstmtExpr(Some e) ->
        fprintf ppf "%a;"
          pp_print_expression e
    | PstmtCompound(decls,stmts) ->
        fprintf ppf "{@\n  @[<v>%a@\n%a@]@\n}"
          (pp_print_list
             ~elem_pp:pp_print_declaration
             ~sep_pp:pp_print_sep_newline)
          decls
          (pp_print_list
             ~elem_pp:pp_print_statement
             ~sep_pp:pp_print_sep_newline)
          stmts
    | PstmtIf(e1,s2,None->
        fprintf ppf "if (%a) then %a"
          pp_print_expression e1
          pp_print_statement s2
    | PstmtIf(e1,s2,Some s3) ->
        fprintf ppf "if (%a) then %a@\nelse %a"
        pp_print_expression e1
        pp_print_statement s2
        pp_print_statement s3
    | PstmtSwitch(e1,s2) ->
        fprintf ppf "switch (%a) %a"
          pp_print_expression e1
          pp_print_statement s2
    | PstmtWhile(e1,s2) ->        
        fprintf ppf "while (%a) %a"
          pp_print_expression e1
          pp_print_statement s2
    | PstmtFor(e1,e2,e3,s4) ->        
        fprintf ppf "for (%a; %a; %a) %a"
          (pp_print_option ~f:pp_print_expression) e1
          (pp_print_option ~f:pp_print_expression) e2
          (pp_print_option ~f:pp_print_expression) e3
          pp_print_statement s4
    | PstmtDoWhile(s1,e2) ->
        fprintf ppf "do %a while (%a);"
          pp_print_statement s1
          pp_print_expression e2
    | PstmtGoto(l) ->
        fprintf ppf "goto %a;"
          pp_print_identifier l
    | PstmtContinue ->
        fprintf ppf "continue;"
    | PstmtBreak ->
        fprintf ppf "break;"
    | PstmtReturn(None->
        fprintf ppf "return;"
    | PstmtReturn(Some e) ->
        fprintf ppf "return %a;"
          pp_print_expression e

and pp_print_declaration ppf decl = 
  match decl.pdecl_t with
    PdeclFunction(sq,dc,[],fbody) ->
      fprintf ppf "@[<hv>%a %a@]@\n%a"
        pp_print_sqlist sq
        pp_print_declarator dc
        pp_print_statement fbody
  | PdeclFunction(sq,dc,argdecls,fbody) ->
      fprintf ppf "@[<hv>%a %a@]@\n  @[<v 2>%a@]%a"
        pp_print_sqlist sq
        pp_print_declarator dc
        (pp_print_list ~elem_pp:pp_print_declaration ~sep_pp:pp_print_sep_newline)
          argdecls
        pp_print_statement fbody
  | PdeclVariable(sq,initdecls) ->
      fprintf ppf
        "@[<hv>%a %a@];"
        pp_print_sqlist sq
        (pp_print_list ~elem_pp:pp_print_initdeclarator ~sep_pp:pp_print_sep_comma)
        initdecls