let rec print_stmt n s =
    let print = function
        CTTstmtNull -> ";"
      | CTTstmtExpr e -> (print_expr e)^";"
      | CTTstmtLabeled( l, s ) -> l^": "^(print_stmt 0 s)
      | CTTstmtCase_Labeled( n, s ) -> "case "^(string_of_big_int n)^": "^(print_stmt 0 s)
      | CTTstmtDefault_Labeled s -> "default: "^(print_stmt 0 s)
      | CTTstmtCompound( declaration_list, statement_list ) ->
          "{\n"
          ^(let rec continue = function
              [] -> ""
            | d::l -> (print_variable_declaration (n + 1) d)^(continue l)
          in
          continue declaration_list)
          ^(let rec continue = function
              [] -> ""
            | s::l -> (print_stmt (n + 1) s)^(continue l)
          in
          continue statement_list)
          ^"}"
      | CTTstmtIf( e, s1, None ) ->
          "if ( "^(print_expr e)^" )\n"
          ^(print_stmt (n + 1) s1)
      | CTTstmtIf( e, s1, Some s2 ) ->
          "if ( "^(print_expr e)^" )\n"
          ^(print_stmt (n + 1) s1)
          ^(indent n)^"else\n"
          ^(print_stmt (n + 1) s2)
      | CTTstmtSwitch( e, s ) ->
          "switch ( "^(print_expr e)^" )\n"
          ^(print_stmt n s)
      | CTTstmtWhile( e, s ) ->
          "while ( "^(print_expr e)^" )\n"
          ^(print_stmt n s)
      | CTTstmtDoWhile( s, e ) ->
          "do\n"
          ^(print_stmt n s)
          ^"while ( "^(print_expr e)^" )"
      | CTTstmtFor( e1, e2, e3, s ) ->
          let print_expr = function
              None -> ""
            | Some e -> print_expr e
          in
          "for ( "^(print_expr e1)^"; "^(print_expr e2)^"; "^(print_expr e3)^" )\n"
          ^(print_stmt n s)
      | CTTstmtGoto s -> "goto "^s^";"
      | CTTstmtContinue -> "continue;"
      | CTTstmtBreak -> "break;"
      | CTTstmtReturn None -> "return;"
      |        CTTstmtReturn (Some e) -> "return "^(print_expr e)^";"
    in
    (indent n)^(print s.stmt_t)^"\n"