source: Deliverables/D2.2/8051/src/LTL/LTLToLIN.ml @ 1462

Last change on this file since 1462 was 1462, checked in by ayache, 8 years ago

Added D5.1: Frama-C plug-in and Lustre wrapper. D2.2 (8051) has been updated accordingly.

File size: 3.7 KB
Line 
1(* This module provides a translation of LTL programs to LIN programs. *)
2
3(* Adapted from Pottier's PP compiler *)
4
5(* ------------------------------------------------------------------------- *)
6
7(* [translate_statement] translates an [LTL] statement into a [LIN]
8   statement. *)
9
10let translate_statement = function
11
12  (* Because [Branch.compress] has been called before, no [St_skip]
13     statement can be reached. *)
14
15  | LTL.St_skip lbl ->
16    LIN.St_goto lbl
17
18  (* Sequential statements. *)
19
20  | LTL.St_comment (s, _) ->
21    LIN.St_comment s
22  | LTL.St_cost (lbl, _) ->
23    LIN.St_cost lbl
24  | LTL.St_int (r, i, _) ->
25    LIN.St_int (r, i)
26  | LTL.St_addr (x, _) ->
27    LIN.St_addr x
28  | LTL.St_pop _ ->
29    LIN.St_pop
30  | LTL.St_push _ ->
31    LIN.St_push
32  | LTL.St_clear_carry _ ->
33    LIN.St_clear_carry
34  | LTL.St_set_carry _ ->
35    LIN.St_set_carry
36  | LTL.St_from_acc (r, _) ->
37    LIN.St_from_acc (r)
38  | LTL.St_to_acc (r, _) ->
39    LIN.St_to_acc r
40  | LTL.St_opaccs (opaccs, _) ->
41    LIN.St_opaccs opaccs
42  | LTL.St_op1 (op1, _) ->
43    LIN.St_op1 op1
44  | LTL.St_op2 (op2, r, _) ->
45    LIN.St_op2 (op2, r)
46  | LTL.St_load _ ->
47    LIN.St_load
48  | LTL.St_store _ ->
49    LIN.St_store
50  | LTL.St_call_id (f, _) ->
51    LIN.St_call_id f
52  | LTL.St_call_ptr (f1, f2, _) ->
53    LIN.St_call_ptr (f1, f2)
54
55  (* Conditional branch statement. In [LIN], control implicitly
56     falls through to the second successor, so only the first
57     successor is explicitly mentioned in the statement. *)
58
59  | LTL.St_condacc (lbl_true, _) ->
60    LIN.St_condacc lbl_true
61
62  (* Statement without a successor. *)
63
64  | LTL.St_return ->
65    LIN.St_return
66
67(* ------------------------------------------------------------------------- *)
68
69(* [translate entry graph] turns an [LTL] control flow graph into
70   a [LIN] sequence of statements. *)
71
72let translate_graph entry graph =
73
74  (* Keep track of the labels that have been visited (initially none), of the
75     labels that must exist within the [LIN] code (initially only the graph's
76     entry point) and of the list of [LIN] statements that are being
77     generated (initially empty). Statements are held in the list in reverse
78     order, for efficiency. The list is reversed once generation is over. *)
79
80  let visited, required, statements =
81    ref Label.Set.empty, ref (Label.Set.singleton entry), ref []
82  in
83
84  (* Instantiate the functor. *)
85
86  let module V = LTLToLINI.Visit (struct
87    let fetch label =
88      Label.Map.find label graph
89    let translate_statement =
90      translate_statement
91    let generate statement =
92      statements := statement :: !statements
93    let require label =
94      required := Label.Set.add label !required
95    let mark label =
96      visited := Label.Set.add label !visited
97    let marked label =
98      Label.Set.mem label !visited
99  end) in
100
101  (* Traverse the control flow graph. *)
102
103  V.visit entry;
104
105  (* Now, get rid of the labels that do not need to exist. Also,
106     reverse the list to re-establish the correct order. *)
107
108  List.filter (function
109    | LIN.St_label l ->
110        Label.Set.mem l !required
111    | _ ->
112        true
113  ) (List.rev !statements)
114
115(* ------------------------------------------------------------------------- *)
116
117(* Extend the translation to procedures and programs. *)
118
119let translate_internal int_fun =
120  (* Compress the graph to eliminate gotos (St_skip) statements. *)
121  let entry, graph = Branch.compress int_fun.LTL.f_entry int_fun.LTL.f_graph in
122  translate_graph entry graph
123
124let translate_funct (name, def) =
125  let def' = match def with
126    | LTL.F_int def -> LIN.F_int (translate_internal def)
127    | LTL.F_ext def -> LIN.F_ext def in
128  (name, def')
129
130let translate (p : LTL.program) : LIN.program =
131  { LIN.vars = p.LTL.vars;
132    LIN.functs = List.map translate_funct p.LTL.functs ;
133    LIN.main = p.LTL.main }
Note: See TracBrowser for help on using the repository browser.