feat: struct (de niveau 1)
This commit is contained in:
parent
cef62a7188
commit
40ee0db98d
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 -> ""
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -138,4 +138,4 @@ let%expect_test "typedef2" =
|
|||
|
||||
let%expect_test "struct1" =
|
||||
runtam "../../fichiersRat/src-rat-tam-test/struct1.rat";
|
||||
[%expect{| 1 |}]
|
||||
[%expect{| 123 |}]
|
Loading…
Reference in a new issue