source: Deliverables/D2.2/8051-indexed-labels-branch/src/LTL/LTLToLIN.ml @ 1349

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