jnfzefunzun
This commit is contained in:
parent
ae1324106a
commit
c0df3ccd47
16
rapport.md
16
rapport.md
|
@ -11,6 +11,7 @@ Le but de ce projet est d'ajouter différentes fonctionnalités au langage RAT.
|
||||||
Pour chacune de ses implantations, il a fallut modiffier les codes correspondants aux différentes étapes de la compilation. La modification du `lexer` (pour reconnaitre les nouveaux mots), le parser (pour reconnaitre la nouvelle grammaire) et les différentes passes pour vérifier la cohérence sémantique du code RAT à compiler.
|
Pour chacune de ses implantations, il a fallut modiffier les codes correspondants aux différentes étapes de la compilation. La modification du `lexer` (pour reconnaitre les nouveaux mots), le parser (pour reconnaitre la nouvelle grammaire) et les différentes passes pour vérifier la cohérence sémantique du code RAT à compiler.
|
||||||
|
|
||||||
## Modifications générales de l'AST
|
## Modifications générales de l'AST
|
||||||
|
|
||||||
Lors de l'ajout des différentes extensions, nous avons évidement du modifier l'AST pour l'adapter aux différents ajouts. Le plus gros ajout, qui est commun a plusieurs extensions, est l'affectable. L'affect, comme son nom l'indique, va désigner un objet pouvant être affecté. Avant l'ajout des différentes expression, il n'y avait que les identificateurs qui pouvaient faire office d'affectbale mais maintenant, il y a les `dref`, les `attribut` d'un objet de type `struct` ou encore les identifiants.
|
Lors de l'ajout des différentes extensions, nous avons évidement du modifier l'AST pour l'adapter aux différents ajouts. Le plus gros ajout, qui est commun a plusieurs extensions, est l'affectable. L'affect, comme son nom l'indique, va désigner un objet pouvant être affecté. Avant l'ajout des différentes expression, il n'y avait que les identificateurs qui pouvaient faire office d'affectbale mais maintenant, il y a les `dref`, les `attribut` d'un objet de type `struct` ou encore les identifiants.
|
||||||
De plus, pour chaque nouveau type, il a fallu ajouter dans l'AST de la passe typage, dans les instructions, un type print tel que `printStruct` pour les structs.
|
De plus, pour chaque nouveau type, il a fallu ajouter dans l'AST de la passe typage, dans les instructions, un type print tel que `printStruct` pour les structs.
|
||||||
|
|
||||||
|
@ -20,3 +21,18 @@ L'implenation des pointeurs a commencé par l'ajout du type `Pointeur of typ`. A
|
||||||
En ce qui concerne les modifications de l'AST, nous avons ajouté la `dref` pour l'affectable. Les nouvelles expressions apportés sont `Null`, `NewType` et `Adresse`. \
|
En ce qui concerne les modifications de l'AST, nous avons ajouté la `dref` pour l'affectable. Les nouvelles expressions apportés sont `Null`, `NewType` et `Adresse`. \
|
||||||
Les modifications apportées à la passe TDS est l'utilisation que de `dref` et d'`Adresse` doit être utilisé sur des identifiants déjà existant. Dans le cas contraire, une exception d'utilisation d'identifiant est levé. \
|
Les modifications apportées à la passe TDS est l'utilisation que de `dref` et d'`Adresse` doit être utilisé sur des identifiants déjà existant. Dans le cas contraire, une exception d'utilisation d'identifiant est levé. \
|
||||||
Le plus gros du travail pour les pointeurs a été réalisé sur la passe de typage. En effet, cette passe doit vérifier que les objets sont typement compatibles. L'expression `Null` est
|
Le plus gros du travail pour les pointeurs a été réalisé sur la passe de typage. En effet, cette passe doit vérifier que les objets sont typement compatibles. L'expression `Null` est
|
||||||
|
|
||||||
|
## Incrémentation
|
||||||
|
|
||||||
|
Cette fonctionnalité est très simple à implémenter, on remplace simplement toutes les instances de `a += b` par `a = a + b`.
|
||||||
|
On a ainsi dans `parler.mly`
|
||||||
|
```
|
||||||
|
| aff=a PLUS EQUAL exp=e PV {Affectation (aff, Binaire (Plus, Affectable(aff), exp))}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Type nommé
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,21 @@ struct
|
||||||
type t1 = Ast.AstPlacement.programme
|
type t1 = Ast.AstPlacement.programme
|
||||||
type t2 = string
|
type t2 = string
|
||||||
|
|
||||||
|
(*
|
||||||
|
getTailleAvant:
|
||||||
|
affectable -> t2 -> int
|
||||||
|
Description:
|
||||||
|
Avoir la taille avant l'attribut n dans un struct
|
||||||
|
Parameters:
|
||||||
|
- aff : affectable de type struct
|
||||||
|
- n : nom de l'attribut
|
||||||
|
Returns:
|
||||||
|
La taille prise par les attribut avant n
|
||||||
|
*)
|
||||||
let rec getTailleAvant aff n =
|
let rec getTailleAvant aff n =
|
||||||
match aff with
|
match aff with
|
||||||
| Dref(aff2, _) -> getTailleAvant aff2 n
|
| Dref(aff2, _) -> getTailleAvant aff2 n
|
||||||
|
|
||||||
| Ident(info) ->
|
| Ident(info) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info info with
|
match info_ast_to_info info with
|
||||||
|
@ -28,6 +40,7 @@ let rec getTailleAvant aff n =
|
||||||
in tai
|
in tai
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| Attribut(aff2, info) ->
|
| Attribut(aff2, info) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info info with
|
match info_ast_to_info info with
|
||||||
|
@ -38,15 +51,27 @@ let rec getTailleAvant aff n =
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(*
|
||||||
|
getType:
|
||||||
|
affectable -> typ
|
||||||
|
Description:
|
||||||
|
Avoir le type d'un affectable
|
||||||
|
Parameters:
|
||||||
|
- aff : affectable dont on veut avoir le type
|
||||||
|
Returns:
|
||||||
|
Le type de l'affectable
|
||||||
|
*)
|
||||||
and getType aff =
|
and getType aff =
|
||||||
match aff with
|
match aff with
|
||||||
| Dref(aff2, _) -> getType aff2
|
| Dref(aff2, _) -> getType aff2
|
||||||
|
|
||||||
| Ident(info) ->
|
| Ident(info) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info info with
|
match info_ast_to_info info with
|
||||||
| InfoVar(_, t, _, _) -> t
|
| InfoVar(_, t, _, _) -> t
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| Attribut(aff2, info) ->
|
| Attribut(aff2, info) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info info with
|
match info_ast_to_info info with
|
||||||
|
@ -67,9 +92,21 @@ and getType aff =
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(*
|
||||||
|
getTailleAttribut:
|
||||||
|
affectable -> t2 -> int
|
||||||
|
Description:
|
||||||
|
Avoir la taille d'un attribut d'un affectable de type struct
|
||||||
|
Parameters:
|
||||||
|
- aff : affectable de l'attribut
|
||||||
|
- n : nom de l'attribut
|
||||||
|
Returns:
|
||||||
|
La taille de l'attribut
|
||||||
|
*)
|
||||||
and getTailleAttribut aff n =
|
and getTailleAttribut aff n =
|
||||||
match aff with
|
match aff with
|
||||||
| Dref(aff2, _) -> getTailleAttribut aff2 n
|
| Dref(aff2, _) -> getTailleAttribut aff2 n
|
||||||
|
|
||||||
| Ident(info) ->
|
| Ident(info) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info info with
|
match info_ast_to_info info with
|
||||||
|
@ -83,17 +120,30 @@ and getTailleAttribut aff n =
|
||||||
) l_typstr 0
|
) l_typstr 0
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| Attribut(_, _) -> getTaille (getType aff)
|
| Attribut(_, _) -> getTaille (getType aff)
|
||||||
|
|
||||||
|
(*
|
||||||
|
getBase:
|
||||||
|
affectable -> int
|
||||||
|
Description:
|
||||||
|
Avoir la base d'un affectable
|
||||||
|
Parameters:
|
||||||
|
- aff : affectable dont on veut avoir la base
|
||||||
|
Returns:
|
||||||
|
La base de l'affectable
|
||||||
|
*)
|
||||||
and getBase aff =
|
and getBase aff =
|
||||||
match aff with
|
match aff with
|
||||||
| Dref (a,_) -> getBase a
|
| Dref (a,_) -> getBase a
|
||||||
|
|
||||||
| Ident(i) ->
|
| Ident(i) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info i with
|
match info_ast_to_info i with
|
||||||
| InfoVar(_, _, base, _) -> base
|
| InfoVar(_, _, base, _) -> base
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| Attribut(a,i) ->
|
| Attribut(a,i) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info i with
|
match info_ast_to_info i with
|
||||||
|
@ -105,24 +155,55 @@ and getBase aff =
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(*
|
||||||
|
getBase:
|
||||||
|
affectable -> t2
|
||||||
|
Description:
|
||||||
|
Avoir le registre d'un affectable
|
||||||
|
Parameters:
|
||||||
|
- aff : affectable dont on veut avoir le registre
|
||||||
|
Returns:
|
||||||
|
Le registre de l'affectable
|
||||||
|
*)
|
||||||
and getReg aff =
|
and getReg aff =
|
||||||
match aff with
|
match aff with
|
||||||
| Dref (a,_) -> getReg a
|
| Dref (a,_) -> getReg a
|
||||||
|
|
||||||
| Ident(i) ->
|
| Ident(i) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info i with
|
match info_ast_to_info i with
|
||||||
| InfoVar(_, _, _, reg) -> reg
|
| InfoVar(_, _, _, reg) -> reg
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| Attribut(a,_) -> getReg a
|
| Attribut(a,_) -> getReg a
|
||||||
|
|
||||||
|
(*
|
||||||
|
extraction_info:
|
||||||
|
affectable -> info_ast
|
||||||
|
Description:
|
||||||
|
Avoir l'info d'un affectable
|
||||||
|
Parameters:
|
||||||
|
- aff : affectable dont on veut avoir l'info
|
||||||
|
Returns:
|
||||||
|
L'info de l'affectable
|
||||||
|
*)
|
||||||
and extraction_info aff =
|
and extraction_info aff =
|
||||||
match aff with
|
match aff with
|
||||||
| Dref(aff2, _) -> extraction_info aff2
|
| Dref(aff2, _) -> extraction_info aff2
|
||||||
| Ident(info) -> info
|
| Ident(info) -> info
|
||||||
| Attribut(aff2, _) -> extraction_info aff2
|
| Attribut(aff2, _) -> extraction_info aff2
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_code_affectable:
|
||||||
|
affectable -> t2
|
||||||
|
Description:
|
||||||
|
Convertir un affectable en code TAM
|
||||||
|
Parameters:
|
||||||
|
- aff : affectable que l'on veut convertir
|
||||||
|
Returns:
|
||||||
|
Le code TAM de l'affectable
|
||||||
|
*)
|
||||||
and analyse_code_affectable a =
|
and analyse_code_affectable a =
|
||||||
match a with
|
match a with
|
||||||
| Dref(aff, t) ->
|
| Dref(aff, t) ->
|
||||||
|
@ -142,6 +223,16 @@ and analyse_code_affectable a =
|
||||||
let reg = getReg a in
|
let reg = getReg a in
|
||||||
"LOAD (" ^ (string_of_int (getTaille (getType a))) ^ ") " ^ (string_of_int (base)) ^ "[" ^ reg ^ "]\n"
|
"LOAD (" ^ (string_of_int (getTaille (getType a))) ^ ") " ^ (string_of_int (base)) ^ "[" ^ reg ^ "]\n"
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_code_expression:
|
||||||
|
expression -> t2
|
||||||
|
Description:
|
||||||
|
Convertir une expression en code TAM
|
||||||
|
Parameters:
|
||||||
|
- e : expression que l'on veut convertir
|
||||||
|
Returns:
|
||||||
|
Le code TAM correspondant
|
||||||
|
*)
|
||||||
and analyse_code_expression e =
|
and analyse_code_expression e =
|
||||||
match e with
|
match e with
|
||||||
| AppelFonction(i, le) ->
|
| AppelFonction(i, le) ->
|
||||||
|
@ -204,6 +295,19 @@ and analyse_code_expression e =
|
||||||
|
|
||||||
| Nothing -> ""
|
| Nothing -> ""
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_code_instruction:
|
||||||
|
instruction -> t2 -> t2 -> t2 -> t2
|
||||||
|
Description:
|
||||||
|
Convertir une instruction en code TAM
|
||||||
|
Parameters:
|
||||||
|
- i : instruction que l'on veut ecrire en TAM
|
||||||
|
- taille_return : taille du retour si on est dans une fonction
|
||||||
|
- taille_args : taille des arguments si on est dans une fonction
|
||||||
|
- taille_var : taille des varibales local a une fonction ou a un bloc
|
||||||
|
Returns:
|
||||||
|
Le code TAM correpondant à l'instruction
|
||||||
|
*)
|
||||||
and analyse_code_instruction i taille_return taille_args taille_var =
|
and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
match i with
|
match i with
|
||||||
| Declaration(i, e) ->
|
| Declaration(i, e) ->
|
||||||
|
@ -268,7 +372,6 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
"SUBR IOut\n"
|
"SUBR IOut\n"
|
||||||
|
|
||||||
| AffichageStruct(e, t) ->
|
| AffichageStruct(e, t) ->
|
||||||
|
|
||||||
let rec affichage base reg t0 =
|
let rec affichage base reg t0 =
|
||||||
match t0 with
|
match t0 with
|
||||||
| Struct(l_typstr) ->
|
| Struct(l_typstr) ->
|
||||||
|
@ -284,6 +387,7 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
"LOADL ' '\n" ^
|
"LOADL ' '\n" ^
|
||||||
"SUBR COut\n"
|
"SUBR COut\n"
|
||||||
,taille + (getTaille t))
|
,taille + (getTaille t))
|
||||||
|
|
||||||
| Int -> (
|
| Int -> (
|
||||||
res ^
|
res ^
|
||||||
"LOAD (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int taille) ^ "[" ^ reg ^ "]\n" ^
|
"LOAD (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int taille) ^ "[" ^ reg ^ "]\n" ^
|
||||||
|
@ -291,6 +395,7 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
"LOADL ' '\n" ^
|
"LOADL ' '\n" ^
|
||||||
"SUBR COut\n"
|
"SUBR COut\n"
|
||||||
,taille + (getTaille t))
|
,taille + (getTaille t))
|
||||||
|
|
||||||
| Rat -> (
|
| Rat -> (
|
||||||
res ^
|
res ^
|
||||||
"LOAD (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int taille) ^ "[" ^ reg ^ "]\n" ^
|
"LOAD (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int taille) ^ "[" ^ reg ^ "]\n" ^
|
||||||
|
@ -298,6 +403,7 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
"LOADL ' '\n" ^
|
"LOADL ' '\n" ^
|
||||||
"SUBR COut\n"
|
"SUBR COut\n"
|
||||||
,taille + (getTaille t))
|
,taille + (getTaille t))
|
||||||
|
|
||||||
| Pointeur(_) -> (
|
| Pointeur(_) -> (
|
||||||
res ^
|
res ^
|
||||||
"LOADL '@'\n" ^
|
"LOADL '@'\n" ^
|
||||||
|
@ -307,6 +413,7 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
"LOADL ' '\n" ^
|
"LOADL ' '\n" ^
|
||||||
"SUBR COut\n"
|
"SUBR COut\n"
|
||||||
,taille + (getTaille t))
|
,taille + (getTaille t))
|
||||||
|
|
||||||
| Struct(_) -> (
|
| Struct(_) -> (
|
||||||
res ^
|
res ^
|
||||||
"LOADL '{'\n" ^
|
"LOADL '{'\n" ^
|
||||||
|
@ -317,7 +424,9 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
"LOADL ' '\n" ^
|
"LOADL ' '\n" ^
|
||||||
"SUBR COut\n"
|
"SUBR COut\n"
|
||||||
,taille + (getTaille t))
|
,taille + (getTaille t))
|
||||||
|
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
|
|
||||||
) ("LOADL ' '\nSUBR COut\n", base) l_t in
|
) ("LOADL ' '\nSUBR COut\n", base) l_t in
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
|
@ -354,6 +463,7 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
begin
|
begin
|
||||||
match a with
|
match a with
|
||||||
| Dref(_, _) -> failwith "Internal Error"
|
| Dref(_, _) -> failwith "Internal Error"
|
||||||
|
|
||||||
| Ident(i) ->
|
| Ident(i) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info i with
|
match info_ast_to_info i with
|
||||||
|
@ -361,6 +471,7 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
affichage base reg t
|
affichage base reg t
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| Attribut(_, i) ->
|
| Attribut(_, i) ->
|
||||||
match info_ast_to_info i with
|
match info_ast_to_info i with
|
||||||
| InfoVar(_, t, _, _) ->
|
| InfoVar(_, t, _, _) ->
|
||||||
|
@ -369,6 +480,7 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
affichage base reg t
|
affichage base reg t
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| AppelFonction(i, le) ->
|
| AppelFonction(i, le) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info i with
|
match info_ast_to_info i with
|
||||||
|
@ -380,22 +492,6 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
"CALL (ST) " ^ nom ^ "\n" ^
|
"CALL (ST) " ^ nom ^ "\n" ^
|
||||||
(affichage base reg t) ^
|
(affichage base reg t) ^
|
||||||
"POP (0) " ^ (string_of_int (getTaille t)) ^ "\n"
|
"POP (0) " ^ (string_of_int (getTaille t)) ^ "\n"
|
||||||
(* List.fold_right (
|
|
||||||
fun (t, _) res ->
|
|
||||||
let i =
|
|
||||||
match t with
|
|
||||||
| Bool -> AffichageBool(Nothing)
|
|
||||||
| Int -> AffichageInt(Nothing)
|
|
||||||
| Rat -> AffichageRat(Nothing)
|
|
||||||
| Pointeur(_) -> AffichagePointeur(Nothing)
|
|
||||||
| Struct(l_ts) -> AffichageStruct(Tuple(List.map (fun _ -> Nothing) l_ts), t)
|
|
||||||
| _ -> failwith "Internal Error"
|
|
||||||
in
|
|
||||||
"LOADL ' '\n" ^
|
|
||||||
"SUBR COut\n" ^
|
|
||||||
(analyse_code_instruction i "0" "0" "0") ^
|
|
||||||
res
|
|
||||||
) l_typstr "LOADL ' '\nSUBR COut\n" *)
|
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
|
@ -435,6 +531,18 @@ and analyse_code_instruction i taille_return taille_args taille_var =
|
||||||
|
|
||||||
| Empty -> ""
|
| Empty -> ""
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_code_bloc:
|
||||||
|
bloc -> t2 -> t2 -> t2
|
||||||
|
Description:
|
||||||
|
Convertir un bloc en code TAM
|
||||||
|
Parameters:
|
||||||
|
- bloc : bloc que l'on veut ecrire en TAM
|
||||||
|
- taille_return : taille du retour si on est dans une fonction
|
||||||
|
- taille_args : taille des arguments si on est dans une fonction
|
||||||
|
Returns:
|
||||||
|
Le code TAM correpondant au bloc
|
||||||
|
*)
|
||||||
and analyse_code_bloc bloc taille_return taille_args =
|
and analyse_code_bloc bloc taille_return taille_args =
|
||||||
let taille_var = string_of_int (List.fold_right (fun e res -> taille_variables_declarees e + res) bloc 0) in
|
let taille_var = string_of_int (List.fold_right (fun e res -> taille_variables_declarees e + res) bloc 0) in
|
||||||
List.fold_right (
|
List.fold_right (
|
||||||
|
@ -442,6 +550,16 @@ and analyse_code_bloc bloc taille_return taille_args =
|
||||||
) bloc "" ^
|
) bloc "" ^
|
||||||
"POP (0) " ^ taille_var ^ "\n"
|
"POP (0) " ^ taille_var ^ "\n"
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_code_fonction:
|
||||||
|
fonction -> t2 -> t2 -> t2
|
||||||
|
Description:
|
||||||
|
Convertir une fonction en code TAM
|
||||||
|
Parameters:
|
||||||
|
- fonction : fonction à convertir
|
||||||
|
Returns:
|
||||||
|
Le code TAM de la fonction
|
||||||
|
*)
|
||||||
and analyse_code_fonction (AstPlacement.Fonction(info, _, bloc)) =
|
and analyse_code_fonction (AstPlacement.Fonction(info, _, bloc)) =
|
||||||
match info_ast_to_info info with
|
match info_ast_to_info info with
|
||||||
| InfoFun(name, t, l_t) ->
|
| InfoFun(name, t, l_t) ->
|
||||||
|
@ -453,6 +571,16 @@ and analyse_code_fonction (AstPlacement.Fonction(info, _, bloc)) =
|
||||||
|
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_code_fonction:
|
||||||
|
prgramme -> t2
|
||||||
|
Description:
|
||||||
|
Convertir un programme en code TAM
|
||||||
|
Parameters:
|
||||||
|
- programme : programme à convertir
|
||||||
|
Returns:
|
||||||
|
Le code TAM du programme
|
||||||
|
*)
|
||||||
let analyser (AstPlacement.Programme(fonctions, prog)) =
|
let analyser (AstPlacement.Programme(fonctions, prog)) =
|
||||||
let code = getEntete () in
|
let code = getEntete () in
|
||||||
let code = code ^ List.fold_right (fun e res -> (analyse_code_fonction e) ^ res) fonctions "" in
|
let code = code ^ List.fold_right (fun e res -> (analyse_code_fonction e) ^ res) fonctions "" in
|
||||||
|
|
|
@ -11,6 +11,18 @@ struct
|
||||||
type t2 = Ast.AstPlacement.programme
|
type t2 = Ast.AstPlacement.programme
|
||||||
|
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_placement_instruction:
|
||||||
|
instruction -> int -> string -> int
|
||||||
|
Description:
|
||||||
|
Modifie le placement des info (base et registre) et retourne le nombre de place prise
|
||||||
|
Parameters:
|
||||||
|
- i : l'instruction à analyser
|
||||||
|
- base : la base actuel
|
||||||
|
- reg : le registre actuel
|
||||||
|
Returns:
|
||||||
|
La place prise par l'instruction
|
||||||
|
*)
|
||||||
let rec analyse_placement_instruction i base reg =
|
let rec analyse_placement_instruction i base reg =
|
||||||
match i with
|
match i with
|
||||||
| AstType.Declaration(info, _) ->
|
| AstType.Declaration(info, _) ->
|
||||||
|
@ -34,6 +46,19 @@ let rec analyse_placement_instruction i base reg =
|
||||||
|
|
||||||
| _ -> 0
|
| _ -> 0
|
||||||
|
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_placement_bloc:
|
||||||
|
int -> string -> AstType.bloc -> int
|
||||||
|
Description:
|
||||||
|
Analyse le bloc instruction par instruction (base et registre) et retourne le nombre de place prise par le bloc
|
||||||
|
Parameters:
|
||||||
|
- base : la base actuel
|
||||||
|
- reg : le registre actuel
|
||||||
|
- bloc : bloc à analyser
|
||||||
|
Returns:
|
||||||
|
La place prise en mémoire par le bloc
|
||||||
|
*)
|
||||||
and analyse_placement_bloc base reg bloc =
|
and analyse_placement_bloc base reg bloc =
|
||||||
match bloc with
|
match bloc with
|
||||||
| [] -> base
|
| [] -> base
|
||||||
|
@ -41,6 +66,17 @@ and analyse_placement_bloc base reg bloc =
|
||||||
let taille = analyse_placement_instruction t base reg in
|
let taille = analyse_placement_instruction t base reg in
|
||||||
analyse_placement_bloc (base + taille) reg q
|
analyse_placement_bloc (base + taille) reg q
|
||||||
|
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_placement_fonction:
|
||||||
|
AstType.fonction -> AstPlacement.fonction
|
||||||
|
Description:
|
||||||
|
Analyse le placement d'une fonction
|
||||||
|
Parameters:
|
||||||
|
- fonction : La fonction à analyser
|
||||||
|
Returns:
|
||||||
|
La fonction analysée
|
||||||
|
*)
|
||||||
and analyse_placement_fonction (AstType.Fonction(info, l_typinfo, bloc)) =
|
and analyse_placement_fonction (AstType.Fonction(info, l_typinfo, bloc)) =
|
||||||
let _ = List.fold_right (fun x res_q ->
|
let _ = List.fold_right (fun x res_q ->
|
||||||
begin
|
begin
|
||||||
|
@ -51,9 +87,22 @@ and analyse_placement_fonction (AstType.Fonction(info, l_typinfo, bloc)) =
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
) l_typinfo 0 in
|
) l_typinfo 0 in
|
||||||
|
|
||||||
|
(* Avec les 3 places prises par l'enregistrement d'activation, l'analyse du bloc commence à 3 *)
|
||||||
let _ = analyse_placement_bloc 3 "LB" bloc in
|
let _ = analyse_placement_bloc 3 "LB" bloc in
|
||||||
Fonction(info, l_typinfo, bloc)
|
Fonction(info, l_typinfo, bloc)
|
||||||
|
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyser:
|
||||||
|
AstType -> AstPlacement
|
||||||
|
Description:
|
||||||
|
Analyser un programme
|
||||||
|
Parameters:
|
||||||
|
- programme : Le programme à analyser
|
||||||
|
Returns:
|
||||||
|
Le programme analysée
|
||||||
|
*)
|
||||||
let analyser (AstType.Programme(fonctions, prog)) =
|
let analyser (AstType.Programme(fonctions, prog)) =
|
||||||
let n_fonctions = List.map analyse_placement_fonction fonctions in
|
let n_fonctions = List.map analyse_placement_fonction fonctions in
|
||||||
let _ = analyse_placement_bloc 0 "SB" prog in
|
let _ = analyse_placement_bloc 0 "SB" prog in
|
||||||
|
|
|
@ -11,6 +11,7 @@ struct
|
||||||
type t1 = Ast.AstSyntax.programme
|
type t1 = Ast.AstSyntax.programme
|
||||||
type t2 = Ast.AstTds.programme
|
type t2 = Ast.AstTds.programme
|
||||||
|
|
||||||
|
|
||||||
(*
|
(*
|
||||||
recherche_type:
|
recherche_type:
|
||||||
tds -> typ -> typ
|
tds -> typ -> typ
|
||||||
|
@ -21,10 +22,6 @@ struct
|
||||||
- t : le type que l'on cherche
|
- t : le type que l'on cherche
|
||||||
Returns:
|
Returns:
|
||||||
Le type d'un typedef
|
Le type d'un typedef
|
||||||
Pre-conditions:
|
|
||||||
- True
|
|
||||||
Post-conditions:
|
|
||||||
- True
|
|
||||||
Exceptions:
|
Exceptions:
|
||||||
- IdentifiantNonDeclare
|
- IdentifiantNonDeclare
|
||||||
*)
|
*)
|
||||||
|
@ -46,6 +43,7 @@ let rec recherche_type tds t =
|
||||||
Struct n_l_typstr
|
Struct n_l_typstr
|
||||||
| _ -> t
|
| _ -> t
|
||||||
|
|
||||||
|
|
||||||
(*
|
(*
|
||||||
analyse_tds_affectable:
|
analyse_tds_affectable:
|
||||||
tds -> AstSyntax.affectable -> bool -> AstTds.affectable
|
tds -> AstSyntax.affectable -> bool -> AstTds.affectable
|
||||||
|
@ -57,10 +55,6 @@ let rec recherche_type tds t =
|
||||||
- modif : permet de savoir s'il sagit d'un affectable dans une expression ou dans une affectation
|
- modif : permet de savoir s'il sagit d'un affectable dans une expression ou dans une affectation
|
||||||
Returns:
|
Returns:
|
||||||
Un nouvel AstTds.affectable
|
Un nouvel AstTds.affectable
|
||||||
Pre-conditions:
|
|
||||||
- True
|
|
||||||
Post-conditions:
|
|
||||||
- True
|
|
||||||
Exceptions:
|
Exceptions:
|
||||||
- IdentifiantNonDeclare
|
- IdentifiantNonDeclare
|
||||||
- MauvaiseUtilisationIdentifiant
|
- MauvaiseUtilisationIdentifiant
|
||||||
|
@ -102,10 +96,6 @@ let rec analyse_tds_affectable tds a modif =
|
||||||
- aff : Affectable dont on veut extraire l'info
|
- aff : Affectable dont on veut extraire l'info
|
||||||
Returns:
|
Returns:
|
||||||
L'info de l'affectable
|
L'info de l'affectable
|
||||||
Pre-conditions:
|
|
||||||
- True
|
|
||||||
Post-conditions:
|
|
||||||
- True
|
|
||||||
*)
|
*)
|
||||||
let rec extraction_info aff =
|
let rec extraction_info aff =
|
||||||
match aff with
|
match aff with
|
||||||
|
@ -124,13 +114,14 @@ let rec analyse_tds_affectable tds a modif =
|
||||||
let t = List.fold_right (fun (t, n) res -> if str = n then t else res) l_att Undefined in
|
let t = List.fold_right (fun (t, n) res -> if str = n then t else res) l_att Undefined in
|
||||||
if t != Undefined then
|
if t != Undefined then
|
||||||
AstTds.Attribut(n_aff, info_to_info_ast (InfoVar(str, t, 0, "")))
|
AstTds.Attribut(n_aff, info_to_info_ast (InfoVar(str, t, 0, "")))
|
||||||
else (** L'attribut ne correspond à aucun attribut du struct *)
|
else (* L'attribut ne correspond à aucun attribut du struct *)
|
||||||
raise (MauvaiseUtilisationIdentifiant str)
|
raise (MauvaiseUtilisationIdentifiant str)
|
||||||
| _ -> (** Il faut que l'objet sur le quel on appelle l'attribut soit un struct *)
|
| _ -> (* Il faut que l'objet sur le quel on appelle l'attribut soit un struct *)
|
||||||
raise (MauvaiseUtilisationIdentifiant str)
|
raise (MauvaiseUtilisationIdentifiant str)
|
||||||
end (** Ce ne peut etre qu'un InfoVar *)
|
end (* Ce ne peut etre qu'un InfoVar *)
|
||||||
| _ -> raise (MauvaiseUtilisationIdentifiant str)
|
| _ -> raise (MauvaiseUtilisationIdentifiant str)
|
||||||
|
|
||||||
|
|
||||||
(*
|
(*
|
||||||
analyse_tds_affectable:
|
analyse_tds_affectable:
|
||||||
tds -> AstSyntax.expression -> AstTds.expression
|
tds -> AstSyntax.expression -> AstTds.expression
|
||||||
|
@ -141,10 +132,6 @@ let rec analyse_tds_affectable tds a modif =
|
||||||
- e : l'expression à analyser
|
- e : l'expression à analyser
|
||||||
Returns:
|
Returns:
|
||||||
Une nouvelle AstTds.expression
|
Une nouvelle AstTds.expression
|
||||||
Pre-conditions:
|
|
||||||
- True
|
|
||||||
Post-conditions:
|
|
||||||
- True
|
|
||||||
Exceptions:
|
Exceptions:
|
||||||
- IdentifiantNonDeclare
|
- IdentifiantNonDeclare
|
||||||
- MauvaiseUtilisationIdentifiant
|
- MauvaiseUtilisationIdentifiant
|
||||||
|
@ -216,10 +203,6 @@ let rec analyse_tds_expression tds e =
|
||||||
- td : le typedef à analyser
|
- td : le typedef à analyser
|
||||||
Returns:
|
Returns:
|
||||||
Une nouvelle AstTds.affectable
|
Une nouvelle AstTds.affectable
|
||||||
Pre-conditions:
|
|
||||||
- True
|
|
||||||
Post-conditions:
|
|
||||||
- True
|
|
||||||
Exceptions:
|
Exceptions:
|
||||||
- DoubleDeclaration
|
- DoubleDeclaration
|
||||||
*)
|
*)
|
||||||
|
@ -234,28 +217,21 @@ let analyse_tds_typedef tds (AstSyntax.TypeDef(n, t)) =
|
||||||
raise (DoubleDeclaration n)
|
raise (DoubleDeclaration n)
|
||||||
end
|
end
|
||||||
|
|
||||||
(* analyse_tds_instruction : AstSyntax.instruction -> tds -> AstTds.instruction *)
|
|
||||||
(* Paramètre tds : la table des symboles courante *)
|
|
||||||
(* Paramètre i : l'instruction à analyser *)
|
|
||||||
(* Vérifie la bonne utilisation des identifiants et tranforme l'instruction
|
|
||||||
en une instruction de type AstTds.instruction *)
|
|
||||||
(* Erreur si mauvaise utilisation des identifiants *)
|
|
||||||
(*
|
(*
|
||||||
analyse_tds_typedef:
|
analyse_tds_instruction:
|
||||||
tds -> AstSyntax.typedef -> AstTds.instruction
|
tds -> AstSyntax.instruction -> AstTds.instruction
|
||||||
Description:
|
Description:
|
||||||
Transforme les typedef de l'AstSyntax en AstTds.instructions
|
Vérifie la bonne utilisation des identifiants et tranforme l'instruction en une instruction de type AstTds.instruction
|
||||||
Parameters:
|
Parameters:
|
||||||
- tds : la table des symboles courante
|
- tds : la table des symboles courante
|
||||||
- td : le typedef à analyser
|
- i : l'instruction à analyser
|
||||||
Returns:
|
Returns:
|
||||||
Une nouvelle AstTds.affectable
|
Une nouvelle AstTds.instruction
|
||||||
Pre-conditions:
|
|
||||||
- True
|
|
||||||
Post-conditions:
|
|
||||||
- True
|
|
||||||
Exceptions:
|
Exceptions:
|
||||||
- DoubleDeclaration
|
- DoubleDeclaration
|
||||||
|
- IdentifiantNonDeclare
|
||||||
|
- MauvaiseUtilisationIdentifiant
|
||||||
*)
|
*)
|
||||||
let rec analyse_tds_instruction tds i =
|
let rec analyse_tds_instruction tds i =
|
||||||
match i with
|
match i with
|
||||||
|
@ -367,38 +343,47 @@ let rec analyse_tds_instruction tds i =
|
||||||
analyse_tds_typedef tds td
|
analyse_tds_typedef tds td
|
||||||
|
|
||||||
|
|
||||||
(* analyse_tds_bloc : AstSyntax.bloc -> AstTds.bloc *)
|
|
||||||
(* Paramètre tds : la table des symboles courante *)
|
|
||||||
(* Paramètre li : liste d'instructions à analyser *)
|
|
||||||
(* Vérifie la bonne utilisation des identifiants et tranforme le bloc
|
|
||||||
en un bloc de type AstTds.bloc *)
|
|
||||||
(* Erreur si mauvaise utilisation des identifiants *)
|
|
||||||
and analyse_tds_bloc tds li =
|
|
||||||
(* Entrée dans un nouveau bloc, donc création d'une nouvelle tds locale
|
|
||||||
pointant sur la table du bloc parent *)
|
|
||||||
let tdsbloc = creerTDSFille tds in
|
|
||||||
(* Analyse des instructions du bloc avec la tds du nouveau bloc
|
|
||||||
Cette tds est modifiée par effet de bord *)
|
|
||||||
let nli = List.map (analyse_tds_instruction tdsbloc) li in
|
|
||||||
(* afficher_locale tdsbloc ; *) (* décommenter pour afficher la table locale *)
|
|
||||||
nli
|
|
||||||
|
|
||||||
|
|
||||||
(* analyse_tds_fonction : AstSyntax.fonction -> AstTds.fonction *)
|
|
||||||
(* Paramètre tds : la table des symboles courante *)
|
|
||||||
(* Paramètre : la fonction à analyser *)
|
|
||||||
(* Vérifie la bonne utilisation des identifiants et tranforme la fonction
|
|
||||||
en une fonction de type AstTds.fonction *)
|
|
||||||
(* Erreur si mauvaise utilisation des identifiants *)
|
|
||||||
(*
|
(*
|
||||||
tds ->
|
analyse_tds_bloc:
|
||||||
AstSyntax.fonction[typ * string * (typ * string) list * bloc] ->
|
tds -> AstSyntax.bloc -> AstTds.bloc
|
||||||
AstTds.fonction[typ * Tds.info_ast * (typ * Tds.info_ast ) list * bloc]
|
Description:
|
||||||
|
Vérifie la bonne utilisation des identifiants et tranforme le bloc en un bloc de type AstTds.bloc
|
||||||
|
Parameters:
|
||||||
|
- tds : la table des symboles courante
|
||||||
|
- li : la liste d'instructions (bloc) à analyser
|
||||||
|
Returns:
|
||||||
|
Un nouvel AstTds.bloc
|
||||||
|
*)
|
||||||
|
and analyse_tds_bloc tds li =
|
||||||
|
(* Entrée dans un nouveau bloc, donc création d'une nouvelle tds locale pointant sur la table du bloc parent *)
|
||||||
|
let tdsbloc = creerTDSFille tds in
|
||||||
|
|
||||||
|
(* Analyse des instructions du bloc avec la tds du nouveau bloc, cette tds est modifiée par effet de bord *)
|
||||||
|
let nli = List.map (analyse_tds_instruction tdsbloc) li in
|
||||||
|
|
||||||
|
(* afficher_locale tdsbloc ; *) (* décommenter pour afficher la table locale *)
|
||||||
|
nli
|
||||||
|
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_tds_fonction:
|
||||||
|
tds -> AstSyntax.fonction -> AstTds.fonction
|
||||||
|
Description:
|
||||||
|
Vérifie la bonne utilisation des identifiants et tranforme la fonction en une fonction de type AstTds.fonction
|
||||||
|
Parameters:
|
||||||
|
- maintds : la table des symboles courante
|
||||||
|
- f : la fonction à analyser
|
||||||
|
Returns:
|
||||||
|
Une nouvelle AstTds.instruction
|
||||||
|
Exceptions:
|
||||||
|
- DoubleDeclaration
|
||||||
*)
|
*)
|
||||||
let analyse_tds_fonction maintds (AstSyntax.Fonction(t, str, l_typstr, bloc)) =
|
let analyse_tds_fonction maintds (AstSyntax.Fonction(t, str, l_typstr, bloc)) =
|
||||||
begin
|
begin
|
||||||
match chercherLocalement maintds str with
|
match chercherLocalement maintds str with
|
||||||
| Some _ -> raise (DoubleDeclaration str)
|
| Some _ -> (* L'identifiant est trouvé dans la tds locale, il a donc déjà été déclaré dans le bloc courant *)
|
||||||
|
raise (DoubleDeclaration str)
|
||||||
|
|
||||||
| None ->
|
| None ->
|
||||||
begin
|
begin
|
||||||
(* Copie de la tds globale dans la tds locale au bloc *)
|
(* Copie de la tds globale dans la tds locale au bloc *)
|
||||||
|
@ -436,11 +421,17 @@ let analyse_tds_fonction maintds (AstSyntax.Fonction(t, str, l_typstr, bloc)) =
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
(* analyser : AstSyntax.ast -> AstTds.ast *)
|
|
||||||
(* Paramètre : le programme à analyser *)
|
(*
|
||||||
(* Vérifie la bonne utilisation des identifiants et tranforme le programme
|
analyser:
|
||||||
en un programme de type AstTds.ast *)
|
AstSyntax.ast -> AstTds.ast
|
||||||
(* Erreur si mauvaise utilisation des identifiants *)
|
Description:
|
||||||
|
Vérifie la bonne utilisation des identifiants et tranforme le programme en un programme de type AstTds.ast
|
||||||
|
Parameters:
|
||||||
|
- p : le programme à analyser
|
||||||
|
Returns:
|
||||||
|
L'AstTds correspondant au programme
|
||||||
|
*)
|
||||||
let analyser (AstSyntax.Programme (typedefs,fonctions,prog)) =
|
let analyser (AstSyntax.Programme (typedefs,fonctions,prog)) =
|
||||||
let tds = creerTDSMere () in
|
let tds = creerTDSMere () in
|
||||||
let _ = List.map (analyse_tds_typedef tds) typedefs in
|
let _ = List.map (analyse_tds_typedef tds) typedefs in
|
||||||
|
|
|
@ -12,6 +12,16 @@ struct
|
||||||
type t2 = Ast.AstType.programme
|
type t2 = Ast.AstType.programme
|
||||||
|
|
||||||
|
|
||||||
|
(*
|
||||||
|
analyse_type_affectable:
|
||||||
|
AstTds.affectable -> affectable * typ
|
||||||
|
Description:
|
||||||
|
Vérifie le bon typage d'un affectable
|
||||||
|
Parameters:
|
||||||
|
- a : affectable a analyser
|
||||||
|
Returns:
|
||||||
|
Le nouvel affectable et son type
|
||||||
|
*)
|
||||||
let rec analyse_type_affectable a =
|
let rec analyse_type_affectable a =
|
||||||
match a with
|
match a with
|
||||||
| AstTds.Dref(a) ->
|
| AstTds.Dref(a) ->
|
||||||
|
@ -20,6 +30,7 @@ let rec analyse_type_affectable a =
|
||||||
| (na, Pointeur t) -> (AstType.Dref(na, t), t)
|
| (na, Pointeur t) -> (AstType.Dref(na, t), t)
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| AstTds.Ident(info) ->
|
| AstTds.Ident(info) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info info with
|
match info_ast_to_info info with
|
||||||
|
@ -27,6 +38,7 @@ let rec analyse_type_affectable a =
|
||||||
| InfoConst _ -> (AstType.Ident(info), Int)
|
| InfoConst _ -> (AstType.Ident(info), Int)
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| AstTds.Attribut(aff, info) ->
|
| AstTds.Attribut(aff, info) ->
|
||||||
begin
|
begin
|
||||||
let (n_aff, _) = analyse_type_affectable aff in
|
let (n_aff, _) = analyse_type_affectable aff in
|
||||||
|
@ -37,53 +49,63 @@ let rec analyse_type_affectable a =
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
(* analyse_tds_expression : AstTds.expression -> (AstType.expression, type) *)
|
(*
|
||||||
(* Paramètre tds : la table des symboles courante *)
|
analyse_type_expression:
|
||||||
(* Paramètre e : l'expression à analyser *)
|
AstTds.expression -> AstType.expression * typ
|
||||||
(* Vérifie la bonne utilisation des identifiants et tranforme l'expression
|
Description:
|
||||||
en une expression de type AstType.expression *)
|
Vérifie la bonne utilisation des identifiants et tranforme l'expression en une expression de type AstType.expression
|
||||||
(* Erreur si mauvaise utilisation des identifiants *)
|
Parameters:
|
||||||
|
- e : l'expression à analyser
|
||||||
|
Returns:
|
||||||
|
Une nouvelle AstType.expression
|
||||||
|
Exceptions:
|
||||||
|
- TypesParametresInattendus
|
||||||
|
- TypeInattendu
|
||||||
|
- TypeBinaireInattendu
|
||||||
|
*)
|
||||||
let rec analyse_type_expression e =
|
let rec analyse_type_expression e =
|
||||||
match e with
|
match e with
|
||||||
| AstTds.AppelFonction(info, l_expr) ->
|
| AstTds.AppelFonction(info, l_expr) ->
|
||||||
begin
|
|
||||||
let n_l_expr, l_type = List.split (List.map analyse_type_expression l_expr) in
|
let n_l_expr, l_type = List.split (List.map analyse_type_expression l_expr) in
|
||||||
match info_ast_to_info info with
|
begin
|
||||||
| InfoFun(_, t, l_type_fun) ->
|
match info_ast_to_info info with
|
||||||
if (est_compatible_list l_type_fun l_type) then
|
| InfoFun(_, t, l_type_fun) ->
|
||||||
(AstType.AppelFonction(info, n_l_expr), t)
|
if (est_compatible_list l_type_fun l_type) then
|
||||||
else
|
(AstType.AppelFonction(info, n_l_expr), t)
|
||||||
raise (TypesParametresInattendus(l_type_fun, l_type))
|
else (* Les types mis en paramètre ne correpondent pas au types demandés *)
|
||||||
| _ -> failwith "Internal Error"
|
raise (TypesParametresInattendus(l_type_fun, l_type))
|
||||||
end
|
| _ -> failwith "Internal Error"
|
||||||
|
end
|
||||||
|
|
||||||
| AstTds.Unaire(u, expr) ->
|
| AstTds.Unaire(u, expr) ->
|
||||||
begin
|
begin
|
||||||
match (analyse_type_expression expr) with
|
match (analyse_type_expression expr) with
|
||||||
| n_expr, Rat ->
|
| n_expr, Rat ->
|
||||||
begin
|
begin
|
||||||
match u with
|
match u with
|
||||||
| AstSyntax.Numerateur -> (AstType.Unaire(Numerateur, n_expr), Int)
|
| AstSyntax.Numerateur -> (AstType.Unaire(Numerateur, n_expr), Int)
|
||||||
| AstSyntax.Denominateur -> (AstType.Unaire(Denominateur, n_expr), Int)
|
| AstSyntax.Denominateur -> (AstType.Unaire(Denominateur, n_expr), Int)
|
||||||
end
|
end
|
||||||
| _, t -> raise (TypeInattendu(t, Rat))
|
| _, t -> (* Il n'y a pas d'opérateur unaire autre que ceux sur les rat *)
|
||||||
end
|
raise (TypeInattendu(t, Rat))
|
||||||
|
end
|
||||||
|
|
||||||
| AstTds.Binaire(b, expr_1, expr_2) ->
|
| AstTds.Binaire(b, expr_1, expr_2) ->
|
||||||
begin
|
|
||||||
let (n_expr_1, t1) = analyse_type_expression expr_1 in
|
let (n_expr_1, t1) = analyse_type_expression expr_1 in
|
||||||
let (n_expr_2, t2) = analyse_type_expression expr_2 in
|
let (n_expr_2, t2) = analyse_type_expression expr_2 in
|
||||||
match (b, t1, t2) with
|
begin
|
||||||
| Fraction, Int, Int -> (AstType.Binaire(Fraction, n_expr_1, n_expr_2), Rat)
|
match (b, t1, t2) with
|
||||||
| Plus, Int, Int -> (AstType.Binaire(PlusInt, n_expr_1, n_expr_2), Int)
|
| Fraction, Int, Int -> (AstType.Binaire(Fraction, n_expr_1, n_expr_2), Rat)
|
||||||
| Mult, Int, Int -> (AstType.Binaire(MultInt, n_expr_1, n_expr_2), Int)
|
| Plus, Int, Int -> (AstType.Binaire(PlusInt, n_expr_1, n_expr_2), Int)
|
||||||
| Equ, Int ,Int -> (AstType.Binaire(EquInt, n_expr_1, n_expr_2), Bool)
|
| Mult, Int, Int -> (AstType.Binaire(MultInt, n_expr_1, n_expr_2), Int)
|
||||||
| Inf, Int, Int -> (AstType.Binaire(Inf, n_expr_1, n_expr_2), Bool)
|
| Equ, Int ,Int -> (AstType.Binaire(EquInt, n_expr_1, n_expr_2), Bool)
|
||||||
| Plus, Rat, Rat -> (AstType.Binaire(PlusRat, n_expr_1, n_expr_2), Rat)
|
| Inf, Int, Int -> (AstType.Binaire(Inf, n_expr_1, n_expr_2), Bool)
|
||||||
| Mult, Rat, Rat -> (AstType.Binaire(MultRat, n_expr_1, n_expr_2), Rat)
|
| Plus, Rat, Rat -> (AstType.Binaire(PlusRat, n_expr_1, n_expr_2), Rat)
|
||||||
| Equ, Bool ,Bool -> (AstType.Binaire(EquBool, n_expr_1, n_expr_2), Bool)
|
| Mult, Rat, Rat -> (AstType.Binaire(MultRat, n_expr_1, n_expr_2), Rat)
|
||||||
| _, _, _ -> raise (TypeBinaireInattendu(b, t1, t2))
|
| Equ, Bool ,Bool -> (AstType.Binaire(EquBool, n_expr_1, n_expr_2), Bool)
|
||||||
end
|
| _, _, _ -> (* Opérations avec erreur de type *)
|
||||||
|
raise (TypeBinaireInattendu(b, t1, t2))
|
||||||
|
end
|
||||||
|
|
||||||
| AstTds.Booleen(b) -> (AstType.Booleen(b), Bool)
|
| AstTds.Booleen(b) -> (AstType.Booleen(b), Bool)
|
||||||
|
|
||||||
|
@ -111,12 +133,20 @@ let rec analyse_type_expression e =
|
||||||
let n_l_expr, l_type = List.split (List.map analyse_type_expression l_expr) in
|
let n_l_expr, l_type = List.split (List.map analyse_type_expression l_expr) in
|
||||||
(AstType.Tuple(n_l_expr), Struct(List.map (fun e -> (e, "")) l_type))
|
(AstType.Tuple(n_l_expr), Struct(List.map (fun e -> (e, "")) l_type))
|
||||||
|
|
||||||
(* analyse_tds_instruction : AstTds.instruction -> tds -> AstType.instruction *)
|
|
||||||
(* Paramètre tds : la table des symboles courante *)
|
(*
|
||||||
(* Paramètre i : l'instruction à analyser *)
|
analyse_type_instruction:
|
||||||
(* Vérifie la bonne utilisation des identifiants et tranforme l'instruction
|
typ option -> AstTds.instruction -> AstType.instruction
|
||||||
en une instruction de type AstType.instruction *)
|
Description:
|
||||||
(* Erreur si mauvaise utilisation des identifiants *)
|
Vérifie la bonne utilisation des identifiants et tranforme l'instruction en une instruction de type AstType.instruction
|
||||||
|
Parameters:
|
||||||
|
- opt : permet de savoir si on est dans le main, ou dans une fonction
|
||||||
|
- i : l'instruction à analyser
|
||||||
|
Returns:
|
||||||
|
Une nouvelle AstType.instruction
|
||||||
|
Exceptions:
|
||||||
|
- TypeInattendu
|
||||||
|
*)
|
||||||
let rec analyse_type_instruction opt i =
|
let rec analyse_type_instruction opt i =
|
||||||
match i with
|
match i with
|
||||||
| AstTds.Declaration (t, info, e) ->
|
| AstTds.Declaration (t, info, e) ->
|
||||||
|
@ -137,6 +167,7 @@ let rec analyse_type_instruction opt i =
|
||||||
| (na, Pointeur _) -> AstType.Affectation(na, ne)
|
| (na, Pointeur _) -> AstType.Affectation(na, ne)
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| AstTds.Ident info ->
|
| AstTds.Ident info ->
|
||||||
begin
|
begin
|
||||||
match (info_ast_to_info info) with
|
match (info_ast_to_info info) with
|
||||||
|
@ -147,6 +178,7 @@ let rec analyse_type_instruction opt i =
|
||||||
raise (TypeInattendu(nt, t))
|
raise (TypeInattendu(nt, t))
|
||||||
| _ -> failwith "Internal Error"
|
| _ -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| AstTds.Attribut(aff2, info) ->
|
| AstTds.Attribut(aff2, info) ->
|
||||||
begin
|
begin
|
||||||
match info_ast_to_info info with
|
match info_ast_to_info info with
|
||||||
|
@ -161,8 +193,8 @@ let rec analyse_type_instruction opt i =
|
||||||
end
|
end
|
||||||
|
|
||||||
| AstTds.Affichage e ->
|
| AstTds.Affichage e ->
|
||||||
|
let (ne, nt) = analyse_type_expression e in
|
||||||
begin
|
begin
|
||||||
let (ne, nt) = analyse_type_expression e in
|
|
||||||
match nt with
|
match nt with
|
||||||
| Int -> AstType.AffichageInt(ne)
|
| Int -> AstType.AffichageInt(ne)
|
||||||
| Rat -> AstType.AffichageRat(ne)
|
| Rat -> AstType.AffichageRat(ne)
|
||||||
|
@ -173,62 +205,64 @@ let rec analyse_type_instruction opt i =
|
||||||
end
|
end
|
||||||
|
|
||||||
| AstTds.Conditionnelle (e, b1, b2) ->
|
| AstTds.Conditionnelle (e, b1, b2) ->
|
||||||
begin
|
let (ne, nt) = analyse_type_expression e in
|
||||||
let (ne, nt) = analyse_type_expression e in
|
let nb1 = analyse_type_bloc opt b1 in
|
||||||
let nb1 = analyse_type_bloc opt b1 in
|
let nb2 = analyse_type_bloc opt b2 in
|
||||||
let nb2 = analyse_type_bloc opt b2 in
|
if (est_compatible Bool nt) then
|
||||||
if (est_compatible Bool nt) then
|
AstType.Conditionnelle(ne, nb1, nb2)
|
||||||
AstType.Conditionnelle(ne, nb1, nb2)
|
else
|
||||||
else
|
raise (TypeInattendu(nt, Bool))
|
||||||
raise (TypeInattendu(nt, Bool))
|
|
||||||
end
|
|
||||||
|
|
||||||
| AstTds.TantQue (e, b) ->
|
| AstTds.TantQue (e, b) ->
|
||||||
begin
|
let (ne, nt) = analyse_type_expression e in
|
||||||
let (ne, nt) = analyse_type_expression e in
|
if (est_compatible nt Bool) then
|
||||||
if (est_compatible nt Bool) then
|
let nb = analyse_type_bloc opt b in
|
||||||
let nb = analyse_type_bloc opt b in
|
AstType.TantQue(ne, nb)
|
||||||
AstType.TantQue(ne, nb)
|
else
|
||||||
else
|
raise (TypeInattendu(nt, Bool))
|
||||||
raise (TypeInattendu(nt, Bool))
|
|
||||||
end
|
|
||||||
|
|
||||||
| AstTds.Retour (e) ->
|
| AstTds.Retour (e) ->
|
||||||
begin
|
begin
|
||||||
match opt with
|
match opt with
|
||||||
| Some(t) ->
|
| Some(t) ->
|
||||||
let (ne, nt) = analyse_type_expression e in
|
let (ne, nt) = analyse_type_expression e in
|
||||||
if est_compatible t nt then
|
if est_compatible t nt then
|
||||||
AstType.Retour(ne)
|
AstType.Retour(ne)
|
||||||
else
|
else
|
||||||
raise (TypeInattendu(nt, t))
|
raise (TypeInattendu(nt, t))
|
||||||
| None -> failwith "Internal Error"
|
| None -> failwith "Internal Error"
|
||||||
end
|
end
|
||||||
|
|
||||||
| AstTds.Empty -> AstType.Empty
|
| AstTds.Empty -> AstType.Empty
|
||||||
|
|
||||||
|
|
||||||
(* analyse_type_bloc : AstTds.bloc -> AstType.bloc *)
|
(*
|
||||||
(* Paramètre tds : la table des symboles courante *)
|
analyse_type_bloc:
|
||||||
(* Paramètre li : liste d'instructions à analyser *)
|
typ option -> AstTds.bloc -> AstType.bloc
|
||||||
(* Vérifie la bonne utilisation des identifiants et tranforme le bloc
|
Description:
|
||||||
en un bloc de type AstType.bloc *)
|
Vérifie la bonne utilisation des identifiants et tranforme le bloc en un bloc de type AstType.bloc
|
||||||
(* Erreur si mauvaise utilisation des identifiants *)
|
Parameters:
|
||||||
|
- opt : permet de savoir si on est dans le main, ou dans une fonction
|
||||||
|
- li : les instructions (bloc) à analyser
|
||||||
|
Returns:
|
||||||
|
Un nouvel AstType.bloc
|
||||||
|
*)
|
||||||
and analyse_type_bloc opt li =
|
and analyse_type_bloc opt li =
|
||||||
let nli = List.map (analyse_type_instruction opt) li in
|
let nli = List.map (analyse_type_instruction opt) li in
|
||||||
nli
|
nli
|
||||||
|
|
||||||
|
|
||||||
(* analyse_type_fonction : AstTds.fonction -> AstType.fonction *)
|
|
||||||
(* Paramètre tds : la table des symboles courante *)
|
|
||||||
(* Paramètre : la fonction à analyser *)
|
|
||||||
(* Vérifie la bonne utilisation des identifiants et tranforme la fonction
|
|
||||||
en une fonction de type AstType.fonction *)
|
|
||||||
(* Erreur si mauvaise utilisation des identifiants *)
|
|
||||||
(*
|
(*
|
||||||
tds ->
|
analyse_type_fonction:
|
||||||
AstTds.fonction[typ * string * (typ * string) list * bloc] ->
|
typ option -> AstTds.fonction -> AstType.fonction
|
||||||
AstType.fonction[typ * Tds.info_ast * (typ * Tds.info_ast ) list * bloc]
|
Description:
|
||||||
|
Vérifie la bonne utilisation des identifiants et tranforme la fonction en une fonction de type AstTds.fonction
|
||||||
|
Parameters:
|
||||||
|
- opt : permet de savoir si on est dans le main, ou dans une fonction
|
||||||
|
- f : la fonction à analyser
|
||||||
|
Returns:
|
||||||
|
Une nouvelle AstTds.instruction
|
||||||
|
Exceptions:
|
||||||
|
- TypeInattendu
|
||||||
*)
|
*)
|
||||||
let analyse_type_fonction opt (AstTds.Fonction(t, info, l_typinfo, bloc)) =
|
let analyse_type_fonction opt (AstTds.Fonction(t, info, l_typinfo, bloc)) =
|
||||||
match opt with
|
match opt with
|
||||||
|
@ -245,12 +279,16 @@ let analyse_type_fonction opt (AstTds.Fonction(t, info, l_typinfo, bloc)) =
|
||||||
raise (TypeInattendu(t, t_ret))
|
raise (TypeInattendu(t, t_ret))
|
||||||
| None -> failwith "Internal Error"
|
| None -> failwith "Internal Error"
|
||||||
|
|
||||||
|
(*
|
||||||
(* analyser : AstTds.ast -> AstType.ast *)
|
analyser:
|
||||||
(* Paramètre : le programme à analyser *)
|
AstTds.ast -> AstType.ast
|
||||||
(* Vérifie la bonne utilisation des identifiants et tranforme le programme
|
Description:
|
||||||
en un programme de type AstType.ast *)
|
Vérifie la bonne utilisation des identifiants et tranforme le programme en un programme de type AstType.ast
|
||||||
(* Erreur si mauvaise utilisation des identifiants *)
|
Parameters:
|
||||||
|
- p : le programme à analyser
|
||||||
|
Returns:
|
||||||
|
L'AstType correspondant au programme
|
||||||
|
*)
|
||||||
let analyser (AstTds.Programme(fonctions, prog)) =
|
let analyser (AstTds.Programme(fonctions, prog)) =
|
||||||
let nf = List.map (fun (AstTds.Fonction(t, info, l_typinfo, bloc)) ->
|
let nf = List.map (fun (AstTds.Fonction(t, info, l_typinfo, bloc)) ->
|
||||||
analyse_type_fonction (Some t) (AstTds.Fonction(t, info, l_typinfo, bloc))) fonctions in
|
analyse_type_fonction (Some t) (AstTds.Fonction(t, info, l_typinfo, bloc))) fonctions in
|
||||||
|
|
Loading…
Reference in a new issue