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
| AffichageRat of expression
| AffichageBool of expression
| AffichagePointeur of expression
| AffichageStruct of expressionn
| Conditionnelle of expression * bloc * bloc
| TantQue of expression * bloc
| Retour of expression

View file

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

View file

@ -12,44 +12,98 @@ struct
type t1 = Ast.AstPlacement.programme
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
| Dref(aff, t) ->
| Dref(aff, t) ->
analyse_code_affectable aff ^
"LOADI (" ^ (string_of_int (getTaille t)) ^ ")\n"
| Ident(i) ->
match info_ast_to_info i with
| InfoVar(_, t, base, reg) -> "LOAD (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int base) ^ "[" ^ reg ^ "]\n"
| InfoConst(_,v) -> "LOADL " ^ (string_of_int v) ^ "\n"
| _ -> failwith "w-wtf bwo y-you okay -.-"
let rec analyse_code_expression e =
begin
match info_ast_to_info i with
| InfoVar(_, t, base, reg) -> "LOAD (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int base) ^ "[" ^ reg ^ "]\n"
| InfoConst(_,v) -> "LOADL " ^ (string_of_int v) ^ "\n"
| _ -> failwith "w-wtf bwo y-you okay -.-"
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
| AppelFonction(i, le) ->
| AppelFonction(i, le) ->
begin
let InfoFun(nom,_,_) = info_ast_to_info i in
(List.fold_right (fun e res -> analyse_code_expression e ^ res) le "") ^
"CALL (ST) " ^ nom ^ "\n"
end
| Booleen(b) ->
if b then
"LOADL 1\n"
else
"LOADL 0\n"
| Entier(n) ->
| Entier(n) ->
"LOADL " ^ (string_of_int n) ^ "\n"
| Unaire(u, e) ->
| Unaire(u, e) ->
(analyse_code_expression e) ^
begin
match u with
| Numerateur -> "POP (0) 1\n"
| Denominateur -> "POP (1) 1\n"
end
| Binaire(b, e1, e2) ->
(analyse_code_expression e1) ^
(analyse_code_expression e2) ^
@ -68,14 +122,16 @@ let rec analyse_code_expression e =
| Affectable(a) -> analyse_code_affectable a
| Null -> "SUBR MVoid\n"
| NewType(t) ->
"LOADL " ^ (string_of_int (getTaille t)) ^ "\n" ^
"SUBR MAlloc\n"
| Adresse(i) ->
let InfoVar(_, _, base, reg) = info_ast_to_info i in
"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 =
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" ^
analyse_code_expression e ^
"STORE (" ^ (string_of_int (getTaille t)) ^ ") " ^ (string_of_int base) ^ "[" ^ reg ^ "]\n"
| Affectation(a, e) ->
begin
match a with
| Ident(i) ->
| Ident(i) ->
begin
match (info_ast_to_info i) with
| InfoVar (_, t, base, reg) ->
(analyse_code_expression e) ^
"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
| Dref(a, t) ->
(analyse_code_expression e) ^
(analyse_code_affectable a) ^
(analyse_code_affectable a) ^
"STOREI (" ^ string_of_int (getTaille t) ^ ")\n"
| Attribut(aff, info) ->
(analyse_code_affectable a)
(* TODO *)
end
begin
match (info_ast_to_info info) with
| 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) ->
(analyse_code_expression e) ^
(analyse_code_expression e) ^
"SUBR IOut\n"
| AffichageRat(e) ->
(analyse_code_expression e) ^
"CALL (ST) ROut\n"
@ -120,6 +182,19 @@ and analyse_code_instruction i taille_return taille_args taille_var =
(analyse_code_expression e) ^
"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) ->
let etiq1 = 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) ^
"POP (" ^ taille_return ^ ") " ^ taille_var ^ "\n" ^
"RETURN (" ^ taille_return ^ ") " ^ taille_args ^ "\n"
| Empty -> ""

View file

@ -37,8 +37,7 @@ let rec analyse_placement_instruction i base reg =
and analyse_placement_bloc base reg bloc =
match bloc with
| [] ->
base
| [] -> base
| t::q ->
let taille = analyse_placement_instruction t base reg in
analyse_placement_bloc (base + taille) reg q

View file

@ -42,7 +42,7 @@ let rec analyse_tds_affectable tds a modif =
begin
match (info_ast_to_info info) with
| InfoVar _ -> AstTds.Ident(info)
| InfoConst(_) ->
| InfoConst _ ->
begin
if modif then
failwith "bah non en fait"
@ -54,24 +54,26 @@ let rec analyse_tds_affectable tds a modif =
end
| AstSyntax.Attribut(aff, str) ->
let n_aff = analyse_tds_affectable tds aff modif in
let rec extraction_info af =
match af with
| Dref(af2) -> extraction_info af2
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 n_aff) with
| InfoVar(n,t,_,_) as info ->
let n_aff = analyse_tds_affectable tds aff modif in
let info = extraction_info n_aff in
match info_ast_to_info info with
| InfoVar(_, t, _, _) ->
match t with
| Struct(l_att) ->
if List.fold_right (fun (t2,n) res -> if str = n then true else res) l_att false then
AstTds.Attribut(n_aff, info_to_info_ast info)
let t = List.fold_right (fun (t, n) res -> if str = n then t else res) l_att Undefined in
if t != Undefined then
AstTds.Attribut(n_aff, info_to_info_ast (InfoVar(str, t, 0, "")))
else
raise (MauvaiseUtilisationIdentifiant n)
| _ -> raise (MauvaiseUtilisationIdentifiant n)
raise (MauvaiseUtilisationIdentifiant str)
| _ -> raise (MauvaiseUtilisationIdentifiant str)
| _ -> raise (MauvaiseUtilisationIdentifiant n)
| _ -> raise (MauvaiseUtilisationIdentifiant str)
(* analyse_tds_expression : AstSyntax.expression -> AstTds.expression *)
(* Paramètre tds : la table des symboles courante *)
@ -163,13 +165,14 @@ let rec analyse_tds_instruction tds i =
begin
match chercherLocalement tds n with
| None ->
let nt = recherche_type tds t in
(* L'identifiant n'est pas trouvé dans la tds locale,
il n'a donc pas été déclaré dans le bloc courant *)
(* Vérification de la bonne utilisation des identifiants dans l'expression *)
(* et obtention de l'expression transformée *)
let ne = analyse_tds_expression tds e in
(* 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 *)
let ia = info_to_info_ast info in
(* 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
et l'expression remplacée par l'expression issue de l'analyse *)
let nt = recherche_type tds t in
AstTds.Declaration (nt, ia, ne)
| Some _ ->
(* 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)
| Rat -> AstType.AffichageRat(ne)
| Bool -> AstType.AffichageBool(ne)
| Pointeur _ -> AstType.AffichagePointeur(ne)
| Struct _ -> AstType.AffichageStruct(ne)
| _ -> failwith "un truc chelou"
end

View file

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