let rec convert_statement ~env stmt =
let loc = stmt.stmt_pr.ctt_loc in
let sbody =
match stmt.stmt_t with
CTTstmtNull -> PstmtExpr None
| CTTstmtExpr(e) -> PstmtExpr (Some (convert_expr ~env e))
| CTTstmtLabeled(l,s) -> PstmtLabeled(l, convert_statement ~env s)
| CTTstmtCase_Labeled(l,s) ->
PstmtCase_Labeled(const_expr_of_big_int l ~loc, convert_statement ~env s)
| CTTstmtDefault_Labeled(s) ->
PstmtDefault_Labeled(convert_statement ~env s)
| CTTstmtCompound(d,s) ->
let ld =
List.map
(fun (lsclass, ty, id, init) ->
let sq, dc = convert_declarator ~env ty id in
let lsclasses = convert_local_storage_class lsclass in
make_decl
(PdeclVariable
(lsclasses @ sq,
[PinitDecl(dc, Option.map (convert_initializer ~env) init)])))
d
in
let ls = List.map (convert_statement ~env) s in
PstmtCompound(ld, ls)
| CTTstmtIf(e1,s2,s3) ->
PstmtIf(convert_expr ~env e1,
convert_statement ~env s2,
Option.map (convert_statement ~env) s3)
| CTTstmtSwitch(e1,s) ->
PstmtSwitch(convert_expr ~env e1, convert_statement ~env s)
| CTTstmtWhile(e1,s) ->
PstmtWhile(convert_expr ~env e1, convert_statement ~env s)
| CTTstmtDoWhile(s,e1) ->
PstmtDoWhile(convert_statement ~env s, convert_expr ~env e1)
| CTTstmtFor(e1,e2,e3,s) ->
PstmtFor(Option.map (convert_expr ~env) e1,
Option.map (convert_expr ~env) e2,
Option.map (convert_expr ~env) e3,
convert_statement ~env s)
| CTTstmtGoto(id) ->
PstmtGoto(id)
| CTTstmtContinue -> PstmtContinue
| CTTstmtBreak -> PstmtBreak
| CTTstmtReturn(e1) ->
PstmtReturn(Option.map (convert_expr ~env) e1)
in
make_stmt sbody ~orig:stmt