feat: struct (de niveau 1)

This commit is contained in:
Guillotin Damien 2021-12-13 21:22:01 +01:00
parent cef62a7188
commit 40ee0db98d
7 changed files with 129 additions and 47 deletions

View file

@ -188,6 +188,8 @@ type bloc = instruction list
| AffichageInt of expression | AffichageInt of expression
| AffichageRat of expression | AffichageRat of expression
| AffichageBool of expression | AffichageBool of expression
| AffichagePointeur of expression
| AffichageStruct of expressionn
| Conditionnelle of expression * bloc * bloc | Conditionnelle of expression * bloc * bloc
| TantQue of expression * bloc | TantQue of expression * bloc
| Retour of expression | Retour of expression

View file

@ -1,5 +1,7 @@
main{ main{
typedef Point = struct { int x int y }; typedef Point = struct { int x int y int z };
Point p = {1 2} Point p = {1 2 3};
print (p.x); print (p.x);
print (p.y);
print (p.z);
} }

View file

@ -12,44 +12,98 @@ struct
type t1 = Ast.AstPlacement.programme type t1 = Ast.AstPlacement.programme
type t2 = string type t2 = string
let rec analyse_code_affectable a = let rec getTailleAvant aff n =
match aff with
| Dref(aff2, _) -> getTailleAvant aff2 n
| Ident(info) ->
begin
match info_ast_to_info info with
| InfoVar(_, Struct(l_typstr), _, _) ->
let tai, _ = List.fold_left (
fun (res, trouv) (t, s) ->
(* print_endline (string_of_bool trouv);
print_endline (s ^ " " ^ n);
print_endline (string_of_bool (s = n)); *)
if s = n or trouv then
(res, true)
else
(res + (getTaille t), false)
) (0, false) l_typstr
in tai
end
and getTailleAttribut aff n =
match aff with
| Dref(aff2, _) -> getTailleAttribut aff2 n
| Ident(info) ->
begin
match info_ast_to_info info with
| InfoVar(_, Struct(l_typstr), _, _) ->
List.fold_right (
fun (t, s) res ->
if s = n then
getTaille t
else
res
) l_typstr 0
end
and analyse_code_affectable a =
match a with match a with
| Dref(aff, t) -> | Dref(aff, t) ->
analyse_code_affectable aff ^ analyse_code_affectable aff ^
"LOADI (" ^ (string_of_int (getTaille t)) ^ ")\n" "LOADI (" ^ (string_of_int (getTaille t)) ^ ")\n"
| Ident(i) -> | Ident(i) ->
match info_ast_to_info i with begin
| InfoVar(_, t, base, reg) -> "LOAD (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int base) ^ "[" ^ reg ^ "]\n" match info_ast_to_info i with
| InfoConst(_,v) -> "LOADL " ^ (string_of_int v) ^ "\n" | InfoVar(_, t, base, reg) -> "LOAD (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int base) ^ "[" ^ reg ^ "]\n"
| _ -> failwith "w-wtf bwo y-you okay -.-" | InfoConst(_,v) -> "LOADL " ^ (string_of_int v) ^ "\n"
| _ -> failwith "w-wtf bwo y-you okay -.-"
let rec analyse_code_expression e = end
| Attribut(a, i) ->
begin
let rec extraction_info aff =
match aff with
| Dref(aff2, _) -> extraction_info aff2
| Ident(info) -> info
| Attribut(aff2, info) -> info
in
match (info_ast_to_info (extraction_info a)) with
| InfoVar(_, t, base, reg) ->
let InfoVar(n, _, _, _) = info_ast_to_info i in
let t_avant = getTailleAvant a n in
"LOAD (" ^ (string_of_int (getTailleAttribut a n)) ^ ") " ^ (string_of_int (base + t_avant)) ^ "[" ^ reg ^ "]\n"
| _ -> failwith "toujours pas bon"
end
and analyse_code_expression e =
match e with match e with
| AppelFonction(i, le) -> | AppelFonction(i, le) ->
begin begin
let InfoFun(nom,_,_) = info_ast_to_info i in let InfoFun(nom,_,_) = info_ast_to_info i in
(List.fold_right (fun e res -> analyse_code_expression e ^ res) le "") ^ (List.fold_right (fun e res -> analyse_code_expression e ^ res) le "") ^
"CALL (ST) " ^ nom ^ "\n" "CALL (ST) " ^ nom ^ "\n"
end end
| Booleen(b) -> | Booleen(b) ->
if b then if b then
"LOADL 1\n" "LOADL 1\n"
else else
"LOADL 0\n" "LOADL 0\n"
| Entier(n) -> | Entier(n) ->
"LOADL " ^ (string_of_int n) ^ "\n" "LOADL " ^ (string_of_int n) ^ "\n"
| Unaire(u, e) -> | Unaire(u, e) ->
(analyse_code_expression e) ^ (analyse_code_expression e) ^
begin begin
match u with match u with
| Numerateur -> "POP (0) 1\n" | Numerateur -> "POP (0) 1\n"
| Denominateur -> "POP (1) 1\n" | Denominateur -> "POP (1) 1\n"
end end
| Binaire(b, e1, e2) -> | Binaire(b, e1, e2) ->
(analyse_code_expression e1) ^ (analyse_code_expression e1) ^
(analyse_code_expression e2) ^ (analyse_code_expression e2) ^
@ -68,14 +122,16 @@ let rec analyse_code_expression e =
| Affectable(a) -> analyse_code_affectable a | Affectable(a) -> analyse_code_affectable a
| Null -> "SUBR MVoid\n" | Null -> "SUBR MVoid\n"
| NewType(t) -> | NewType(t) ->
"LOADL " ^ (string_of_int (getTaille t)) ^ "\n" ^ "LOADL " ^ (string_of_int (getTaille t)) ^ "\n" ^
"SUBR MAlloc\n" "SUBR MAlloc\n"
| Adresse(i) -> | Adresse(i) ->
let InfoVar(_, _, base, reg) = info_ast_to_info i in let InfoVar(_, _, base, reg) = info_ast_to_info i in
"LOADL " ^ (string_of_int base) ^ "\n" "LOADL " ^ (string_of_int base) ^ "\n"
| Tuple(l_expr) ->
List.fold_right (fun e res -> analyse_code_expression e ^ res) l_expr ""
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
@ -84,34 +140,40 @@ and analyse_code_instruction i taille_return taille_args taille_var =
"PUSH " ^ (string_of_int (getTaille t)) ^ "\n" ^ "PUSH " ^ (string_of_int (getTaille t)) ^ "\n" ^
analyse_code_expression e ^ analyse_code_expression e ^
"STORE (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int base) ^ "[" ^ reg ^ "]\n" "STORE (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int base) ^ "[" ^ reg ^ "]\n"
| Affectation(a, e) -> | Affectation(a, e) ->
begin begin
match a with match a with
| Ident(i) -> | Ident(i) ->
begin begin
match (info_ast_to_info i) with match (info_ast_to_info i) with
| InfoVar (_, t, base, reg) -> | InfoVar (_, t, base, reg) ->
(analyse_code_expression e) ^ (analyse_code_expression e) ^
"STORE (" ^ string_of_int (getTaille t) ^ ") " ^ (string_of_int base) ^ "[" ^ reg ^ "]\n" "STORE (" ^ string_of_int (getTaille t) ^ ") " ^ (string_of_int base) ^ "[" ^ reg ^ "]\n"
| _ -> failwith ("Erreur interne : symbole non reconnnu") | _ -> failwith "Erreur interne : symbole non reconnnu"
end end
| Dref(a, t) -> | Dref(a, t) ->
(analyse_code_expression e) ^ (analyse_code_expression e) ^
(analyse_code_affectable a) ^ (analyse_code_affectable a) ^
"STOREI (" ^ string_of_int (getTaille t) ^ ")\n" "STOREI (" ^ string_of_int (getTaille t) ^ ")\n"
| Attribut(aff, info) -> | Attribut(aff, info) ->
(analyse_code_affectable a) begin
(* TODO *) match (info_ast_to_info info) with
end | InfoVar(n, t, base, reg) ->
let t_avant = getTailleAvant aff n in
(analyse_code_expression e) ^
"STORE (" ^ (string_of_int (getTailleAttribut aff n)) ^ ") " ^ (string_of_int (base + t_avant)) ^ "[" ^ reg ^ "]\n"
| _ -> failwith "toujours pas bon"
end
end
| AffichageInt(e) -> | AffichageInt(e) ->
(analyse_code_expression e) ^ (analyse_code_expression e) ^
"SUBR IOut\n" "SUBR IOut\n"
| AffichageRat(e) -> | AffichageRat(e) ->
(analyse_code_expression e) ^ (analyse_code_expression e) ^
"CALL (ST) ROut\n" "CALL (ST) ROut\n"
@ -120,6 +182,19 @@ and analyse_code_instruction i taille_return taille_args taille_var =
(analyse_code_expression e) ^ (analyse_code_expression e) ^
"SUBR BOut\n" "SUBR BOut\n"
| AffichagePointeur(e) ->
(analyse_code_expression e) ^
"SUBR BOut\n"
| AffichageStruct(le) ->
List.fold_right (
fun e res ->
res ^
(analyse_code_expression e) ^
"SUBR BOut\n"
) le ""
| Conditionnelle(e, b1, b2) -> | Conditionnelle(e, b1, b2) ->
let etiq1 = getEtiquette () in let etiq1 = getEtiquette () in
let etiq2 = getEtiquette () in let etiq2 = getEtiquette () in
@ -146,7 +221,7 @@ and analyse_code_instruction i taille_return taille_args taille_var =
(analyse_code_expression e) ^ (analyse_code_expression e) ^
"POP (" ^ taille_return ^ ") " ^ taille_var ^ "\n" ^ "POP (" ^ taille_return ^ ") " ^ taille_var ^ "\n" ^
"RETURN (" ^ taille_return ^ ") " ^ taille_args ^ "\n" "RETURN (" ^ taille_return ^ ") " ^ taille_args ^ "\n"
| Empty -> "" | Empty -> ""

View file

@ -37,8 +37,7 @@ let rec analyse_placement_instruction i base reg =
and analyse_placement_bloc base reg bloc = and analyse_placement_bloc base reg bloc =
match bloc with match bloc with
| [] -> | [] -> base
base
| t::q -> | t::q ->
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

View file

@ -42,7 +42,7 @@ let rec analyse_tds_affectable tds a modif =
begin begin
match (info_ast_to_info info) with match (info_ast_to_info info) with
| InfoVar _ -> AstTds.Ident(info) | InfoVar _ -> AstTds.Ident(info)
| InfoConst(_) -> | InfoConst _ ->
begin begin
if modif then if modif then
failwith "bah non en fait" failwith "bah non en fait"
@ -54,24 +54,26 @@ let rec analyse_tds_affectable tds a modif =
end end
| AstSyntax.Attribut(aff, str) -> | AstSyntax.Attribut(aff, str) ->
let n_aff = analyse_tds_affectable tds aff modif in let rec extraction_info aff =
let rec extraction_info af = match aff with
match af with | Dref(aff2) -> extraction_info aff2
| Dref(af2) -> extraction_info af2
| Ident(info) -> info | Ident(info) -> info
| Attribut(aff2, info) -> info
in in
match info_ast_to_info (extraction_info n_aff) with let n_aff = analyse_tds_affectable tds aff modif in
| InfoVar(n,t,_,_) as info -> let info = extraction_info n_aff in
match info_ast_to_info info with
| InfoVar(_, t, _, _) ->
match t with match t with
| Struct(l_att) -> | Struct(l_att) ->
if List.fold_right (fun (t2,n) res -> if str = n then true else res) l_att false then let t = List.fold_right (fun (t, n) res -> if str = n then t else res) l_att Undefined in
AstTds.Attribut(n_aff, info_to_info_ast info) if t != Undefined then
AstTds.Attribut(n_aff, info_to_info_ast (InfoVar(str, t, 0, "")))
else else
raise (MauvaiseUtilisationIdentifiant n) raise (MauvaiseUtilisationIdentifiant str)
| _ -> raise (MauvaiseUtilisationIdentifiant str)
| _ -> raise (MauvaiseUtilisationIdentifiant n)
| _ -> raise (MauvaiseUtilisationIdentifiant n) | _ -> raise (MauvaiseUtilisationIdentifiant str)
(* analyse_tds_expression : AstSyntax.expression -> AstTds.expression *) (* analyse_tds_expression : AstSyntax.expression -> AstTds.expression *)
(* Paramètre tds : la table des symboles courante *) (* Paramètre tds : la table des symboles courante *)
@ -163,13 +165,14 @@ let rec analyse_tds_instruction tds i =
begin begin
match chercherLocalement tds n with match chercherLocalement tds n with
| None -> | None ->
let nt = recherche_type tds t in
(* L'identifiant n'est pas trouvé dans la tds locale, (* L'identifiant n'est pas trouvé dans la tds locale,
il n'a donc pas été déclaré dans le bloc courant *) il n'a donc pas été déclaré dans le bloc courant *)
(* Vérification de la bonne utilisation des identifiants dans l'expression *) (* Vérification de la bonne utilisation des identifiants dans l'expression *)
(* et obtention de l'expression transformée *) (* et obtention de l'expression transformée *)
let ne = analyse_tds_expression tds e in let ne = analyse_tds_expression tds e in
(* Création de l'information associée à l'identfiant *) (* Création de l'information associée à l'identfiant *)
let info = InfoVar (n,Undefined, 0, "") in let info = InfoVar (n, nt, 0, "") in
(* Création du pointeur sur l'information *) (* Création du pointeur sur l'information *)
let ia = info_to_info_ast info in let ia = info_to_info_ast info in
(* Ajout de l'information (pointeur) dans la tds *) (* Ajout de l'information (pointeur) dans la tds *)
@ -177,7 +180,6 @@ let rec analyse_tds_instruction tds i =
(* Renvoie de la nouvelle déclaration où le nom a été remplacé par l'information (* Renvoie de la nouvelle déclaration où le nom a été remplacé par l'information
et l'expression remplacée par l'expression issue de l'analyse *) et l'expression remplacée par l'expression issue de l'analyse *)
let nt = recherche_type tds t in
AstTds.Declaration (nt, ia, ne) AstTds.Declaration (nt, ia, ne)
| Some _ -> | Some _ ->
(* L'identifiant est trouvé dans la tds locale, (* L'identifiant est trouvé dans la tds locale,

View file

@ -152,6 +152,8 @@ let rec analyse_type_instruction opt i =
| Int -> AstType.AffichageInt(ne) | Int -> AstType.AffichageInt(ne)
| Rat -> AstType.AffichageRat(ne) | Rat -> AstType.AffichageRat(ne)
| Bool -> AstType.AffichageBool(ne) | Bool -> AstType.AffichageBool(ne)
| Pointeur _ -> AstType.AffichagePointeur(ne)
| Struct _ -> AstType.AffichageStruct(ne)
| _ -> failwith "un truc chelou" | _ -> failwith "un truc chelou"
end end

View file

@ -138,4 +138,4 @@ let%expect_test "typedef2" =
let%expect_test "struct1" = let%expect_test "struct1" =
runtam "../../fichiersRat/src-rat-tam-test/struct1.rat"; runtam "../../fichiersRat/src-rat-tam-test/struct1.rat";
[%expect{| 1 |}] [%expect{| 123 |}]