source: Deliverables/D2.2/8051/src/clight/clightFold.ml @ 624

Last change on this file since 624 was 624, checked in by ayache, 9 years ago

Bug fixs and signed division hack in D2.2.

File size: 6.7 KB
RevLine 
[619]1
2(** This module provides folding functions over the constructors of the
3    [Clight]'s AST. *)
4
5
6let ctype_subs = function
7  | Clight.Tvoid | Clight.Tint _ | Clight.Tfloat _ | Clight.Tcomp_ptr _ -> []
8  | Clight.Tpointer ctype | Clight.Tarray (ctype, _) -> [ctype]
9  | Clight.Tfunction (args, res) -> args @ [res]
10  | Clight.Tstruct (_, fields) | Clight.Tunion (_, fields) ->
11    List.map snd fields
12
13let ctype_fill_subs ctype sub_ctypes = match ctype, sub_ctypes with
14  | Clight.Tvoid, _ | Clight.Tint _, _ | Clight.Tfloat _, _
15  | Clight.Tcomp_ptr _, _ -> ctype
16  | Clight.Tpointer _, ctype :: _ -> Clight.Tpointer ctype
17  | Clight.Tarray (_, size), ctype :: _ -> Clight.Tarray (ctype, size)
18  | Clight.Tfunction _, _ ->
19    let (args, res) = MiscPottier.split_last sub_ctypes in
20    Clight.Tfunction (args, res)
21  | Clight.Tstruct (name, fields), _ ->
22    let fields = List.map2 (fun (x, _) ctype -> (x, ctype)) fields sub_ctypes in
23    Clight.Tstruct (name, fields)
24  | Clight.Tunion (name, fields), _ ->
25    let fields = List.map2 (fun (x, _) ctype -> (x, ctype)) fields sub_ctypes in
26    Clight.Tunion (name, fields)
27  | _ -> assert false (* wrong arguments, do not use on these values *)
28
29let rec ctype f t =
30  let sub_ctypes_res = List.map (ctype f) (ctype_subs t) in
31  f t sub_ctypes_res
32
33
34let expr_subs = function
[624]35  | Clight.Expr (expr_descr, ctype) -> ([ctype], [expr_descr])
[619]36
37let expr_descr_subs = function
38  | Clight.Econst_int _ | Clight.Econst_float _ | Clight.Evar _ -> ([], [])
39  | Clight.Ederef e | Clight.Eaddrof e | Clight.Eunop (_, e)
40  | Clight.Efield (e, _) -> ([], [e])
41  | Clight.Ebinop (_, e1, e2) | Clight.Eandbool (e1, e2)
42  | Clight.Eorbool (e1, e2) -> ([], [e1 ; e2])
43  | Clight.Ecast (ctype, e) -> ([ctype], [e])
44  | Clight.Econdition (e1, e2, e3) -> ([], [e1 ; e2 ; e3])
45  | Clight.Esizeof ctype -> ([ctype], [])
46  | Clight.Ecost (_, e) -> ([], [e])
47  | Clight.Ecall (_, e1, e2) -> ([], [e1 ; e2])
48
[624]49let expr_fill_subs e sub_ctypes sub_expr_descrs =
50  match e, sub_ctypes, sub_expr_descrs with
51  | Clight.Expr _, ctype :: _, expr_descr :: _ ->
[619]52    Clight.Expr (expr_descr, ctype)
53  | _ -> assert false (* wrong arguments, do not use on these values *)
54
55let expr_descr_fill_subs e sub_ctypes sub_exprs = 
56  match e, sub_ctypes, sub_exprs with
57  | Clight.Econst_int _, _, _ | Clight.Econst_float _, _, _
58  | Clight.Evar _, _, _ -> e
59  | Clight.Ederef _, _, e :: _ -> Clight.Ederef e
60  | Clight.Eaddrof _, _, e :: _ -> Clight.Eaddrof e
61  | Clight.Eunop (unop, _), _, e :: _ -> Clight.Eunop (unop, e)
62  | Clight.Ebinop (binop, _, _), _, e1 :: e2 :: _ ->
63    Clight.Ebinop (binop, e1, e2)
64  | Clight.Ecast _, ctype :: _, e :: _ -> Clight.Ecast (ctype, e)
65  | Clight.Econdition _, _, e1 :: e2 :: e3 :: _ ->
66    Clight.Econdition (e1, e2, e3)
[624]67  | Clight.Eandbool (_, _), _, e1 :: e2 :: _ ->
68    Clight.Eandbool (e1, e2)
69  | Clight.Eorbool (_, _), _, e1 :: e2 :: _ ->
70    Clight.Eorbool (e1, e2)
71  | Clight.Esizeof _, ctype :: _, _ -> Clight.Esizeof ctype
[619]72  | Clight.Efield (_, field_name), _, e :: _ -> Clight.Efield (e, field_name)
[624]73  | Clight.Ecost (lbl, _), _, e :: _ -> Clight.Ecost (lbl, e)
74  | Clight.Ecall (id, _, _), _, e1 :: e2 :: _ -> Clight.Ecall (id, e1, e2)
[619]75  | _ -> assert false (* wrong arguments, do not use on these values *)
76
[624]77let rec expr f_ctype f_expr f_expr_descr e =
78  let (sub_ctypes, sub_expr_descrs) = expr_subs e in
[619]79  let sub_expr_descrs_res =
80    List.map (expr_descr f_ctype f_expr f_expr_descr) sub_expr_descrs in
81  let sub_ctypes_res = List.map (ctype f_ctype) sub_ctypes in
[624]82  f_expr e sub_ctypes_res sub_expr_descrs_res
[619]83
84and expr_descr f_ctype f_expr f_expr_descr e =
85  let (sub_ctypes, sub_exprs) = expr_descr_subs e in
86  let sub_exprs_res =
[624]87    List.map (expr f_ctype f_expr f_expr_descr) sub_exprs in
[619]88  let sub_ctypes_res = List.map (ctype f_ctype) sub_ctypes in
89  f_expr_descr e sub_ctypes_res sub_exprs_res
[624]90
91
92let rec labeled_statements_subs = function
93  | Clight.LSdefault stmt -> [stmt]
94  | Clight.LScase (_, stmt, lbl_stmts) ->
95    stmt :: (labeled_statements_subs lbl_stmts)
96
97let statement_subs = function
98  | Clight.Sskip | Clight.Sbreak | Clight.Scontinue | Clight.Sreturn None
99  | Clight.Sgoto _ -> ([], [])
100  | Clight.Sassign (e1, e2) -> ([e1 ; e2], [])
101  | Clight.Scall (None, e, args) -> (e :: args, [])
102  | Clight.Scall (Some e1, e2, args) -> (e1 :: e2 :: args, [])
103  | Clight.Ssequence (stmt1, stmt2) -> ([], [stmt1 ; stmt2])
104  | Clight.Sifthenelse (e, stmt1, stmt2) -> ([e], [stmt1 ; stmt2])
105  | Clight.Swhile (e, stmt) | Clight.Sdowhile (e, stmt) -> ([e], [stmt])
106  | Clight.Sfor (stmt1, e, stmt2, stmt3) -> ([e], [stmt1 ; stmt2 ; stmt3])
107  | Clight.Sreturn (Some e) -> ([e], [])
108  | Clight.Sswitch (e, lbl_stmts) -> ([e], labeled_statements_subs lbl_stmts)
109  | Clight.Slabel (_, stmt) | Clight.Scost (_, stmt) -> ([], [stmt])
110
111let rec labeled_statements_fill_subs lbl_stmts sub_statements =
112  match lbl_stmts, sub_statements with
113    | Clight.LSdefault _, stmt :: _ -> Clight.LSdefault stmt
114    | Clight.LScase (i, _, lbl_stmts), stmt :: sub_statements ->
115      Clight.LScase (i, stmt,
116                     labeled_statements_fill_subs lbl_stmts sub_statements)
117    | _ -> assert false (* wrong arguments, do not use on these values *)
118
119let statement_fill_subs statement sub_exprs sub_statements =
120  match statement, sub_exprs, sub_statements with
121    | Clight.Sskip, _, _ | Clight.Sbreak, _, _ | Clight.Scontinue, _, _
122    | Clight.Sreturn None, _, _ | Clight.Sgoto _, _, _ -> statement
123    | Clight.Sassign _, e1 :: e2 :: _, _ -> Clight.Sassign (e1, e2)
124    | Clight.Scall (None, _, _), e :: args, _ ->
125      Clight.Scall (None, e, args)
126    | Clight.Scall (Some _, _, _), e1 :: e2 :: args, _ ->
127      Clight.Scall (Some e1, e2, args)
128    | Clight.Ssequence _, _, stmt1 :: stmt2 :: _ ->
129      Clight.Ssequence (stmt1, stmt2)
130    | Clight.Sifthenelse _, e :: _, stmt1 :: stmt2 :: _ ->
131      Clight.Sifthenelse (e, stmt1, stmt2)
132    | Clight.Swhile _, e :: _, stmt :: _ ->
133      Clight.Swhile (e, stmt)
134    | Clight.Sdowhile _, e :: _, stmt :: _ ->
135      Clight.Sdowhile (e, stmt)
136    | Clight.Sfor _, e :: _, stmt1 :: stmt2 :: stmt3 :: _ ->
137      Clight.Sfor (stmt1, e, stmt2, stmt3)
138    | Clight.Sreturn (Some _), e :: _, _ -> Clight.Sreturn (Some e)
139    | Clight.Sswitch (_, lbl_stmts), e :: _, _ ->
140      Clight.Sswitch (e, labeled_statements_fill_subs lbl_stmts sub_statements)
141    | Clight.Slabel (lbl, _), _, stmt :: _ -> Clight.Slabel (lbl, stmt)
142    | Clight.Scost (lbl, _), _, stmt :: _ -> Clight.Scost (lbl, stmt)
143    | _ -> assert false (* wrong arguments, do not use on these values *)
144
145let rec statement f_ctype f_expr f_expr_descr f_statement stmt =
146  let (sub_exprs, sub_stmts) = statement_subs stmt in
147  let sub_exprs_res = List.map (expr f_ctype f_expr f_expr_descr) sub_exprs in
148  let sub_stmts_res =
149    List.map (statement f_ctype f_expr f_expr_descr f_statement) sub_stmts in
150  f_statement stmt sub_exprs_res sub_stmts_res
Note: See TracBrowser for help on using the repository browser.