This repository has been archived by the owner on May 31, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpassePlacementRat.ml
143 lines (127 loc) · 5.19 KB
/
passePlacementRat.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
(* Auteurs : Benjamin Coupry & Eliès Jurquet *)
(* Module de la passe de gestion des identifiants *)
module PassePlacementRat : Passe.Passe with type t1 = Ast.AstType.programme and type t2 = Ast.AstPlacement.programme =
struct
open Tds
(* open Exceptions *)
open Ast
open AstType
open AstPlacement
open Type
type t1 = AstType.programme
type t2 = AstPlacement.programme
(* analyse_placement_instruction : instruction -> int -> string -> int *)
(* Paramètre i : l'instruction a placer en memoire *)
(* Paramètre base : l'e deplacement initial dans le registre *)
(* Paramètre reg : le registre de travail *)
(* Calcule les deplacements des instructions *)
let rec analyse_placement_instruction i base reg =
match i with
| Declaration(_, info) ->
begin
match info_ast_to_info info with
| InfoVar(_, t, _, _) ->
begin
modifier_adresse_info base reg info;
getTaille t
end
| _ -> failwith "Erreur interne."
end
| Conditionnelle (_, t, e) ->
begin
analyse_placement_bloc t base reg;
analyse_placement_bloc e base reg;
0
end
| TantQue(_, b) ->
begin
analyse_placement_bloc b base reg;
0
end
| Switch (_, cl) ->
(* Analyse de l expression comparee *)
let _ = analyse_placement_listcase cl base reg in
0
| _ -> 0
(* analyse_placement_listcase : case list -> int -> string -> unit *)
(* Paramètre cl : liste de case a placer en memoire *)
(* Paramètre base : le deplacement initial dans le registre *)
(* Paramètre reg : le registre de travail *)
(* Calcule les deplacements des case *)
(* renvoie unit *)
and analyse_placement_listcase cl base reg =
let _ = List.map (analyse_placement_case base reg) cl in ()
(* analyse_placement_case : int -> string -> case -> unit *)
(* Paramètre case : lcase a placer en memoire *)
(* Paramètre base : le deplacement initial dans le registre *)
(* Paramètre reg : le registre de travail *)
(* Calcule les deplacements du case *)
(* renvoie unit *)
and analyse_placement_case base reg case=
match case with
| CaseTid(_, il, _) ->
begin
analyse_placement_bloc il base reg;
end
| CaseEntier(_, il, _) ->
begin
analyse_placement_bloc il base reg;
end
| CaseTrue (il, _) ->
begin
analyse_placement_bloc il base reg;
end
| CaseFalse (il, _) ->
begin
analyse_placement_bloc il base reg;
end
| CaseDefault(il, _) ->
begin
analyse_placement_bloc il base reg;
end
(* analyse_placement_bloc : AstType.bloc -> int -> string -> unit *)
(* Paramètre li : bloc d'instructions a placer en memoire *)
(* Paramètre base : le deplacement initial dans le registre *)
(* Paramètre reg : le registre de travail *)
(* calcule les deplacements des instructions *)
(*renvoie unit*)
and analyse_placement_bloc li base reg =
let _ = List.fold_left (fun t qt -> t + (analyse_placement_instruction qt t reg)) base li in ()
(* Solution alternative :
Sinon on reverse la liste d'instructions pour pouvoir appliquer un fold_right dessus.
Dans le fold_right la queue traitée réprésente la position où l'on écrit l'instruction et
la tête représente l'instruction à traiter. De plus, analyse_placement_instruction nous renvoie
la taille de l'instruction à traitrer. Ainsi, l'écriture suivante se fait à qt + taille.
let _ = List.fold_right (fun t qt -> qt + (analyse_placement_instruction t qt reg)) (List.rev li) base in ()*)
(* analyse_placement_parametre : info_ast -> int -> int *)
(* Paramètre info : l'info faisant reference au parametre a placer *)
(* Paramètre base : le deplacement initial dans le registre *)
(* Calcule les deplacement et le placement memoire d'un bloc de parametres *)
(* renvoie unit *)
let analyse_placement_parametre info base =
match info_ast_to_info info with
| InfoVar(_, t, _, _) ->
begin
let _ = modifier_adresse_info (base - getTaille t) "LB" info in getTaille t
end
| _ -> failwith ("Erreur interne : erreur placement paramètre.")
(* analyse_placement_parametre : info_ast list -> int *)
(* Paramètre info : liste de case a placer en memoire *)
(* Paramètre base : le deplacement initial dans le registre *)
(* calcule les deplacement et le placement memoire d'un bloc de parametres *)
(*renvoie unit*)
let analyse_placement_parametres lp =
List.fold_left (fun d p -> d + analyse_placement_parametre p (-d)) 0 (List.rev lp)
(* analyse_placement_fonction : AstType.fonction -> AstPlacement.fonction *)
(* Paramètre AstType.Fonction : fonction dont il faut placer les parametres et le corps *)
(*renvoie unit*)
let analyse_placement_fonction (AstType.Fonction(info, lp, li, e)) =
let _ = analyse_placement_parametres lp in
analyse_placement_bloc li 3 "LB";
Fonction(info, lp, li, e)
(* analyser : t1 -> t2 *)
let analyser (AstType.Programme(fonctions, prog)) =
let nfonctions = List.map analyse_placement_fonction fonctions in
analyse_placement_bloc prog 0 "SB";
Programme (nfonctions, prog)
end