-
Notifications
You must be signed in to change notification settings - Fork 0
/
passe.ml
130 lines (101 loc) · 3.96 KB
/
passe.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
(* Interface définissant une passe *)
module type Passe =
sig
(* type des AST en entrée de la passe *)
type t1
(* type des AST en sortie de la passe *)
type t2
(* fonction d'analyse qui tranforme un AST de type t1
en un AST de type t2 en réalisant des vérifications *)
val analyser : t1 -> t2
end
(* Passe unit -> unit *)
(* Ne fait rien *)
(* Nécessaire aux compilateurs intermédiaires (non complets) *)
module PasseNop : Passe with type t1 = unit and type t2 = unit =
struct
type t1 = unit
type t2 = unit
let analyser _ = ()
end
(* Passe AstSyntax.programme -> unit *)
(* Ne fait rien *)
(* Nécessaire aux compilateurs intermédiaires (non complets) *)
module PasseTdsNop : Passe with type t1 = Ast.AstSyntax.programme and type t2 = unit =
struct
type t1 = Ast.AstSyntax.programme
type t2 = unit
let analyser _ = ()
end
(* Passe unit -> string *)
(* Ne fait rien *)
(* Nécessaire aux compilateurs intermédiaires (non complets) *)
module PasseCodeNopNop : Passe with type t1 = unit and type t2 = string =
struct
type t1 = unit
type t2 = string
let analyser _ = ""
end
(* Passe AstTds.programme -> unit *)
(* Ne fait rien *)
(* Nécessaire aux compilateurs intermédiaires (non complets) *)
module PasseTypeNop : Passe with type t1 = Ast.AstTds.programme and type t2 = unit =
struct
type t1 = Ast.AstTds.programme
type t2 = unit
let analyser _ = ()
end
(* Passe AstType.programme -> unit *)
(* Ne fait rien *)
(* Nécessaire aux compilateurs intermédiaires (non complets) *)
module PassePlacementNop : Passe with type t1 = Ast.AstType.programme and type t2 = unit =
struct
type t1 = Ast.AstType.programme
type t2 = unit
let analyser _ = ()
end
(* Passe AstPlacement.programme -> string *)
(* Affiche les adresses des variables *)
(* Pour tester les paramètres des fonctions, il est nécessaire de les mettre en retour *)
module PasseVerifPlacement : Passe with type t1 = Ast.AstPlacement.programme and type t2 = (string *(string*(int*string)) list) list =
struct
open Tds
type t1 = Ast.AstPlacement.programme
type t2 = (string *(string*(int*string)) list) list
(* Renvoie l'adresse d'une variable dans le cas d'une déclaration *)
let rec analyser_instruction i =
match i with
| Ast.AstType.Declaration (info,_) ->
begin
match Tds.info_ast_to_info info with
| InfoVar (n,_,d,r) -> [(n,(d,r))]
| _ -> []
end
| Ast.AstType.Conditionnelle(_,bt,be) -> (List.flatten (List.map (analyser_instruction) bt))@(List.flatten (List.map (analyser_instruction) be))
| Ast.AstType.TantQue (_,b) -> (List.flatten (List.map (analyser_instruction) b))
| _ -> [] ;;
let analyser_param info =
match Tds.info_ast_to_info info with
| InfoVar (n,_,d,r) -> [(n,(d,r))]
| _ -> []
(* Renvoie la suite des adresses des variables déclarées dans la fonction *)
(* Ainsi qu'une adresse d'identifiant si le retour est un identifiant *)
let analyser_fonction (Ast.AstPlacement.Fonction(info,lp,li)) =
(*La liste des paramètres n'est plus présente, pour tester le placement des paramètres, on utilisera une astuce :
il faudra écrire un programme qui renvoie le paramètre *)
match info_ast_to_info info with
| InfoFun(n,_,_) -> [(n,(List.flatten (List.map analyser_param lp))@(List.flatten (List.map (analyser_instruction) li)))]
| _ -> failwith "Internal error"
(* Renvoie la suite des adresses des variables déclarées dans les fonctions et dans le programme principal *)
let analyser (Ast.AstPlacement.Programme (fonctions, prog)) =
("main", List.flatten (List.map (analyser_instruction) prog))::(List.flatten (List.map (analyser_fonction) fonctions))
end
(* Passe AstPlacement.programme -> string *)
(* Ne fait rien *)
(* Nécessaire aux compilateurs intermédiaires (non complets) *)
module PasseCodeNop : Passe with type t1 = Ast.AstPlacement.programme and type t2 = string =
struct
type t1 = Ast.AstPlacement.programme
type t2 = string
let analyser _ = ""
end