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

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

Deliverable D2.2

File size: 3.6 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_from_acc (r, _) ->
35    LIN.St_from_acc (r)
36  | LTL.St_to_acc (r, _) ->
37    LIN.St_to_acc r
38  | LTL.St_opaccs (opaccs, _) ->
39    LIN.St_opaccs opaccs
40  | LTL.St_op1 (op1, _) ->
41    LIN.St_op1 op1
42  | LTL.St_op2 (op2, r, _) ->
43    LIN.St_op2 (op2, r)
44  | LTL.St_load _ ->
45    LIN.St_load
46  | LTL.St_store _ ->
47    LIN.St_store
48  | LTL.St_call_id (f, _) ->
49    LIN.St_call_id f
50
51  (* Conditional branch statement. In [LIN], control implicitly
52     falls through to the second successor, so only the first
53     successor is explicitly mentioned in the statement. *)
54
55  | LTL.St_condacc (lbl_true, _) ->
56    LIN.St_condacc lbl_true
57
58  (* Statement without a successor. *)
59
60  | LTL.St_return ->
61    LIN.St_return
62
63(* ------------------------------------------------------------------------- *)
64
65(* [translate entry graph] turns an [LTL] control flow graph into
66   a [LIN] sequence of statements. *)
67
68let translate_graph entry graph =
69
70  (* Keep track of the labels that have been visited (initially none), of the
71     labels that must exist within the [LIN] code (initially only the graph's
72     entry point) and of the list of [LIN] statements that are being
73     generated (initially empty). Statements are held in the list in reverse
74     order, for efficiency. The list is reversed once generation is over. *)
75
76  let visited, required, statements =
77    ref Label.Set.empty, ref (Label.Set.singleton entry), ref []
78  in
79
80  (* Instantiate the functor. *)
81
82  let module V = LTLToLINI.Visit (struct
83    let fetch label =
84      Label.Map.find label graph
85    let translate_statement =
86      translate_statement
87    let generate statement =
88      statements := statement :: !statements
89    let require label =
90      required := Label.Set.add label !required
91    let mark label =
92      visited := Label.Set.add label !visited
93    let marked label =
94      Label.Set.mem label !visited
95  end) in
96
97  (* Traverse the control flow graph. *)
98
99  V.visit entry;
100
101  (* Now, get rid of the labels that do not need to exist. Also,
102     reverse the list to re-establish the correct order. *)
103
104  List.filter (function
105    | LIN.St_label l ->
106        Label.Set.mem l !required
107    | _ ->
108        true
109  ) (List.rev !statements)
110
111(* ------------------------------------------------------------------------- *)
112
113(* Extend the translation to procedures and programs. *)
114
115let translate_internal int_fun =
116  (* Compress the graph to eliminate gotos (St_skip) statements. *)
117  let entry, graph = Branch.compress int_fun.LTL.f_entry int_fun.LTL.f_graph in
118  translate_graph entry graph
119
120let translate_funct (name, def) =
121  let def' = match def with
122    | LTL.F_int def -> LIN.F_int (translate_internal def)
123    | LTL.F_ext def -> LIN.F_ext def in
124  (name, def')
125
126let translate (p : LTL.program) : LIN.program =
127  { LIN.vars = p.LTL.vars;
128    LIN.functs = List.map translate_funct p.LTL.functs ;
129    LIN.main = p.LTL.main }
Note: See TracBrowser for help on using the repository browser.