131 lines
4 KiB
OCaml
131 lines
4 KiB
OCaml
|
(* 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
|