feat: debut struct

This commit is contained in:
Guillotin Damien 2021-12-13 16:37:58 +01:00
parent 8a4e107ecd
commit 951a1a441b
10 changed files with 104 additions and 51 deletions

View file

@ -28,6 +28,8 @@ type affectable =
| Dref of affectable | Dref of affectable
(* Identifiant *) (* Identifiant *)
| Ident of string | Ident of string
(* Structure *)
| Attribut of affectable * string
(* Déclaration d'un nouveau type *) (* Déclaration d'un nouveau type *)
type typedef = TypeDef of string * typ type typedef = TypeDef of string * typ
@ -52,6 +54,8 @@ type expression =
| NewType of typ | NewType of typ
(* Adresse *) (* Adresse *)
| Adresse of string | Adresse of string
(* Tuple of expressions *)
| Tuple of expression list
(* Instructions de Rat *) (* Instructions de Rat *)
type bloc = instruction list type bloc = instruction list
@ -96,6 +100,8 @@ struct
| Dref of affectable | Dref of affectable
(* Identifiant *) (* Identifiant *)
| Ident of Tds.info_ast | Ident of Tds.info_ast
(* Structure *)
| Attribut of affectable * Tds.info_ast
(* Expressions existantes dans notre langage *) (* Expressions existantes dans notre langage *)
(* ~ expression de l'AST syntaxique où les noms des identifiants ont été (* ~ expression de l'AST syntaxique où les noms des identifiants ont été
@ -110,6 +116,7 @@ struct
| Null | Null
| NewType of typ | NewType of typ
| Adresse of Tds.info_ast | Adresse of Tds.info_ast
| Tuple of expression list
(* instructions existantes dans notre langage *) (* instructions existantes dans notre langage *)
(* ~ instruction de l'AST syntaxique où les noms des identifiants ont été (* ~ instruction de l'AST syntaxique où les noms des identifiants ont été
@ -154,6 +161,8 @@ type affectable =
| Dref of affectable * typ | Dref of affectable * typ
(* Identifiant *) (* Identifiant *)
| Ident of Tds.info_ast | Ident of Tds.info_ast
(* Structure *)
| Attribut of affectable * Tds.info_ast
(* Expressions existantes dans Rat *) (* Expressions existantes dans Rat *)
(* = expression de AstTds *) (* = expression de AstTds *)
@ -167,6 +176,7 @@ type expression =
| Null | Null
| NewType of typ | NewType of typ
| Adresse of Tds.info_ast | Adresse of Tds.info_ast
| Tuple of expression list
(* instructions existantes Rat *) (* instructions existantes Rat *)
(* = instruction de AstTds + informations associées aux identificateurs, mises à jour *) (* = instruction de AstTds + informations associées aux identificateurs, mises à jour *)

View file

@ -13,7 +13,7 @@
(* on utilise une table pour les mots-clefs de façon à éviter l'ajout *) (* on utilise une table pour les mots-clefs de façon à éviter l'ajout *)
(* d'états à l'automate résultant *) (* d'états à l'automate résultant *)
let ident = let ident =
let kws = Hashtbl.create 17 in let kws = Hashtbl.create 18 in
List.iter (fun (kw, token) -> Hashtbl.add kws kw token) List.iter (fun (kw, token) -> Hashtbl.add kws kw token)
[ [
"const", CONST; "const", CONST;
@ -33,6 +33,7 @@
"null", NULL; "null", NULL;
"new", NEW; "new", NEW;
"typedef", TYPEDEF; "typedef", TYPEDEF;
"struct", STRUCT;
]; ];
fun id -> fun id ->
match Hashtbl.find_opt kws id with match Hashtbl.find_opt kws id with
@ -68,6 +69,7 @@ rule token = parse
| "*" { MULT } | "*" { MULT }
| "<" { INF } | "<" { INF }
| "&" { AMP } | "&" { AMP }
| "." { PT }
(* constantes entières *) (* constantes entières *)
| ("-")?['0'-'9']+ as i { ENTIER (int_of_string i) } | ("-")?['0'-'9']+ as i { ENTIER (int_of_string i) }

View file

@ -40,6 +40,8 @@ open Ast.AstSyntax
%token NEW %token NEW
%token AMP %token AMP
%token TYPEDEF %token TYPEDEF
%token PT
%token STRUCT
(* Type de l'attribut synthétisé des non-terminaux *) (* Type de l'attribut synthétisé des non-terminaux *)
%type <programme> prog %type <programme> prog
@ -99,6 +101,7 @@ typ :
| RAT {Rat} | RAT {Rat}
| t1=typ MULT {Pointeur (t1)} | t1=typ MULT {Pointeur (t1)}
| t1=TID {TIdent (t1)} | t1=TID {TIdent (t1)}
| STRUCT AO p=dp AF {Struct (p)}
e : e :
| CALL n=ID PO lp=cp PF {AppelFonction (n,lp)} | CALL n=ID PO lp=cp PF {AppelFonction (n,lp)}
@ -117,6 +120,7 @@ e :
| NULL {Null} | NULL {Null}
| PO NEW t1=typ PF {NewType (t1)} | PO NEW t1=typ PF {NewType (t1)}
| AMP n=ID {Adresse (n)} | AMP n=ID {Adresse (n)}
| AO c1=cp AF {Tuple(c1)}
cp : cp :
| {[]} | {[]}
@ -125,3 +129,4 @@ cp :
a : a :
| n=ID {Ident (n)} | n=ID {Ident (n)}
| PO MULT a1=a PF {Dref (a1)} | PO MULT a1=a PF {Dref (a1)}
| PO aff=a PT n=ID PF {Attribut (aff, n)}

View file

@ -161,7 +161,7 @@ and analyse_code_fonction (AstPlacement.Fonction(info, l_typinfo, bloc)) =
let taille_args = string_of_int (List.fold_right (fun e res -> getTaille e + res) l_t 0) in let taille_args = string_of_int (List.fold_right (fun e res -> getTaille e + res) l_t 0) in
name ^ "\n" ^ name ^ "\n" ^
(analyse_code_bloc bloc taille_return taille_args taille_var) ^ (analyse_code_bloc bloc taille_return taille_args taille_var) ^
"RETURN (0) " ^ taille_args ^ "\n\n" "HALT\n"
| _ -> failwith "spa normal" | _ -> failwith "spa normal"

View file

@ -12,13 +12,6 @@ struct
type t2 = Ast.AstPlacement.programme type t2 = Ast.AstPlacement.programme
(* let rec analyse_placement_affectable a =
begin
match a with
| AstType.Dref(aff) ->
| AstType.Ident(i) ->
end *)
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, _) ->

View file

@ -53,6 +53,26 @@ let rec analyse_tds_affectable tds a modif =
end end
end 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
| Ident(info) -> info
in
match info_ast_to_info (extraction_info n_aff) with
| InfoVar(n,t,_,_) as info ->
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)
else
raise (MauvaiseUtilisationIdentifiant n)
| _ -> raise (MauvaiseUtilisationIdentifiant n)
| _ -> raise (MauvaiseUtilisationIdentifiant n)
(* 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 *)
(* Paramètre e : l'expression à analyser *) (* Paramètre e : l'expression à analyser *)
@ -101,6 +121,7 @@ let rec analyse_tds_expression tds e =
| AstSyntax.NewType(t) -> AstTds.NewType(t) | AstSyntax.NewType(t) -> AstTds.NewType(t)
| AstSyntax.Adresse(n) -> | AstSyntax.Adresse(n) ->
let info = chercherGlobalement tds n in let info = chercherGlobalement tds n in
begin
match info with match info with
| None -> | None ->
raise (IdentifiantNonDeclare n) raise (IdentifiantNonDeclare n)
@ -110,6 +131,10 @@ let rec analyse_tds_expression tds e =
| InfoVar _ -> AstTds.Adresse(i) | InfoVar _ -> AstTds.Adresse(i)
| _ -> raise (MauvaiseUtilisationIdentifiant(n)) | _ -> raise (MauvaiseUtilisationIdentifiant(n))
end end
end
| AstSyntax.Tuple(le) ->
let n_le = List.map (fun e -> analyse_tds_expression tds e) le in
AstTds.Tuple(n_le)
let rec analyse_tds_typedef tds (AstSyntax.TypeDef(n, t)) = let rec analyse_tds_typedef tds (AstSyntax.TypeDef(n, t)) =
begin begin
@ -153,7 +178,7 @@ let rec analyse_tds_instruction tds i =
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 let nt = recherche_type tds t in
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,
il a donc déjà été déclaré dans le bloc courant *) il a donc déjà été déclaré dans le bloc courant *)

View file

@ -27,6 +27,14 @@ let rec analyse_type_affectable a =
| InfoConst _ -> (AstType.Ident(info), Int) | InfoConst _ -> (AstType.Ident(info), Int)
| InfoFun _ -> failwith "c chelou frr" | InfoFun _ -> failwith "c chelou frr"
end end
| AstTds.Attribut(aff, info) ->
begin
let (n_aff, _) = analyse_type_affectable aff in
match info_ast_to_info info with
| InfoVar(_, t, _, _) ->
(AstType.Attribut(n_aff, info), t)
| _ -> failwith "heuuuu wtf, c cringe"
end
(* analyse_tds_expression : AstTds.expression -> (AstType.expression, type) *) (* analyse_tds_expression : AstTds.expression -> (AstType.expression, type) *)
@ -95,6 +103,10 @@ let rec analyse_type_expression e =
let _ = modifier_type_info (Pointeur(t)) info in let _ = modifier_type_info (Pointeur(t)) info in
(AstType.Adresse(info), Pointeur(t)) (AstType.Adresse(info), Pointeur(t))
| AstTds.Tuple(l_expr) ->
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))
(* analyse_tds_instruction : AstTds.instruction -> tds -> AstType.instruction *) (* analyse_tds_instruction : AstTds.instruction -> tds -> AstType.instruction *)
(* Paramètre tds : la table des symboles courante *) (* Paramètre tds : la table des symboles courante *)
(* Paramètre i : l'instruction à analyser *) (* Paramètre i : l'instruction à analyser *)

View file

@ -1,4 +1,4 @@
type typ = Bool | Int | Rat | Pointeur of typ | TIdent of string | Undefined type typ = Bool | Int | Rat | Pointeur of typ | TIdent of string | Struct of (typ * string) list | Undefined
let rec string_of_type t = let rec string_of_type t =
match t with match t with
@ -6,6 +6,7 @@ let rec string_of_type t =
| Int -> "Int" | Int -> "Int"
| Rat -> "Rat" | Rat -> "Rat"
| Pointeur(t_p) -> "*" ^ string_of_type t_p | Pointeur(t_p) -> "*" ^ string_of_type t_p
| Struct(l_typstr) -> "{" ^ (List.fold_right (fun (t, s) res -> string_of_type t ^ " : " ^ s ^ " " ^ res) l_typstr "}")
| Undefined -> "Undefined" | Undefined -> "Undefined"
@ -15,8 +16,17 @@ let rec est_compatible t1 t2 =
| Int, Int -> true | Int, Int -> true
| Rat, Rat -> true | Rat, Rat -> true
| Pointeur(t_p1), Pointeur(t_p2) -> est_compatible t_p1 t_p2 | Pointeur(t_p1), Pointeur(t_p2) -> est_compatible t_p1 t_p2
| Struct(l_typstr1), Struct(l_typstr2) ->
let (l_typ1, _) = List.split l_typstr1 in
let (l_typ2, _) = List.split l_typstr2 in
est_compatible_list l_typ1 l_typ2
| _ -> false | _ -> false
and est_compatible_list lt1 lt2 =
try
List.for_all2 est_compatible lt1 lt2
with Invalid_argument _ -> false
let%test _ = est_compatible Bool Bool let%test _ = est_compatible Bool Bool
let%test _ = est_compatible Int Int let%test _ = est_compatible Int Int
let%test _ = est_compatible Rat Rat let%test _ = est_compatible Rat Rat
@ -34,11 +44,6 @@ let%test _ = not (est_compatible Undefined Int)
let%test _ = not (est_compatible Undefined Rat) let%test _ = not (est_compatible Undefined Rat)
let%test _ = not (est_compatible Undefined Bool) let%test _ = not (est_compatible Undefined Bool)
let est_compatible_list lt1 lt2 =
try
List.for_all2 est_compatible lt1 lt2
with Invalid_argument _ -> false
let%test _ = est_compatible_list [] [] let%test _ = est_compatible_list [] []
let%test _ = est_compatible_list [Int ; Rat] [Int ; Rat] let%test _ = est_compatible_list [Int ; Rat] [Int ; Rat]
let%test _ = est_compatible_list [Bool ; Rat ; Bool] [Bool ; Rat ; Bool] let%test _ = est_compatible_list [Bool ; Rat ; Bool] [Bool ; Rat ; Bool]
@ -47,12 +52,13 @@ let%test _ = not (est_compatible_list [Int] [Rat ; Int])
let%test _ = not (est_compatible_list [Int ; Rat] [Rat ; Int]) let%test _ = not (est_compatible_list [Int ; Rat] [Rat ; Int])
let%test _ = not (est_compatible_list [Bool ; Rat ; Bool] [Bool ; Rat ; Bool ; Int]) let%test _ = not (est_compatible_list [Bool ; Rat ; Bool] [Bool ; Rat ; Bool ; Int])
let getTaille t = let rec getTaille t =
match t with match t with
| Int -> 1 | Int -> 1
| Bool -> 1 | Bool -> 1
| Rat -> 2 | Rat -> 2
| Pointeur(_) -> 1 | Pointeur(_) -> 1
| Struct(l_typestr) -> List.fold_right (fun (t, _) res -> (getTaille t) + res) l_typestr 0
| Undefined -> 0 | Undefined -> 0
let%test _ = getTaille Int = 1 let%test _ = getTaille Int = 1

View file

@ -1,5 +1,5 @@
(* Types manipulés dans Rat *) (* Types manipulés dans Rat *)
type typ = Bool | Int | Rat | Pointeur of typ | TIdent of string | Undefined type typ = Bool | Int | Rat | Pointeur of typ | TIdent of string | Struct of (typ * string) list | Undefined
(* string_of_type : typ -> string *) (* string_of_type : typ -> string *)
(* transforme un typ en chaîne de caractère *) (* transforme un typ en chaîne de caractère *)