diff --git a/src/ast.ml b/src/ast.ml index e5cdb9f..61ce0d2 100644 --- a/src/ast.ml +++ b/src/ast.ml @@ -28,6 +28,8 @@ type affectable = | Dref of affectable (* Identifiant *) | Ident of string + (* Structure *) + | Attribut of affectable * string (* Déclaration d'un nouveau type *) type typedef = TypeDef of string * typ @@ -52,6 +54,8 @@ type expression = | NewType of typ (* Adresse *) | Adresse of string + (* Tuple of expressions *) + | Tuple of expression list (* Instructions de Rat *) type bloc = instruction list @@ -96,6 +100,8 @@ struct | Dref of affectable (* Identifiant *) | Ident of Tds.info_ast + (* Structure *) + | Attribut of affectable * Tds.info_ast (* Expressions existantes dans notre langage *) (* ~ expression de l'AST syntaxique où les noms des identifiants ont été @@ -110,6 +116,7 @@ struct | Null | NewType of typ | Adresse of Tds.info_ast + | Tuple of expression list (* instructions existantes dans notre langage *) (* ~ instruction de l'AST syntaxique où les noms des identifiants ont été @@ -154,6 +161,8 @@ type affectable = | Dref of affectable * typ (* Identifiant *) | Ident of Tds.info_ast + (* Structure *) + | Attribut of affectable * Tds.info_ast (* Expressions existantes dans Rat *) (* = expression de AstTds *) @@ -167,6 +176,7 @@ type expression = | Null | NewType of typ | Adresse of Tds.info_ast + | Tuple of expression list (* instructions existantes Rat *) (* = instruction de AstTds + informations associées aux identificateurs, mises à jour *) diff --git a/src/fichiersRat/src-rat-tam-test/struct1.rat b/src/fichiersRat/src-rat-tam-test/struct1.rat new file mode 100644 index 0000000..e69de29 diff --git a/src/lexer.mll b/src/lexer.mll index 42b2989..a7b05f4 100644 --- a/src/lexer.mll +++ b/src/lexer.mll @@ -13,7 +13,7 @@ (* on utilise une table pour les mots-clefs de façon à éviter l'ajout *) (* d'états à l'automate résultant *) let ident = - let kws = Hashtbl.create 17 in + let kws = Hashtbl.create 18 in List.iter (fun (kw, token) -> Hashtbl.add kws kw token) [ "const", CONST; @@ -33,6 +33,7 @@ "null", NULL; "new", NEW; "typedef", TYPEDEF; + "struct", STRUCT; ]; fun id -> match Hashtbl.find_opt kws id with @@ -68,6 +69,7 @@ rule token = parse | "*" { MULT } | "<" { INF } | "&" { AMP } +| "." { PT } (* constantes entières *) | ("-")?['0'-'9']+ as i { ENTIER (int_of_string i) } diff --git a/src/parser.mly b/src/parser.mly index 2b9f7c7..0ea32c2 100644 --- a/src/parser.mly +++ b/src/parser.mly @@ -40,6 +40,8 @@ open Ast.AstSyntax %token NEW %token AMP %token TYPEDEF +%token PT +%token STRUCT (* Type de l'attribut synthétisé des non-terminaux *) %type prog @@ -99,6 +101,7 @@ typ : | RAT {Rat} | t1=typ MULT {Pointeur (t1)} | t1=TID {TIdent (t1)} +| STRUCT AO p=dp AF {Struct (p)} e : | CALL n=ID PO lp=cp PF {AppelFonction (n,lp)} @@ -117,6 +120,7 @@ e : | NULL {Null} | PO NEW t1=typ PF {NewType (t1)} | AMP n=ID {Adresse (n)} +| AO c1=cp AF {Tuple(c1)} cp : | {[]} @@ -124,4 +128,5 @@ cp : a : | n=ID {Ident (n)} -| PO MULT a1=a PF {Dref (a1)} \ No newline at end of file +| PO MULT a1=a PF {Dref (a1)} +| PO aff=a PT n=ID PF {Attribut (aff, n)} \ No newline at end of file diff --git a/src/passeCodeRatToTam.ml b/src/passeCodeRatToTam.ml index 74724d4..785dd68 100644 --- a/src/passeCodeRatToTam.ml +++ b/src/passeCodeRatToTam.ml @@ -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 name ^ "\n" ^ (analyse_code_bloc bloc taille_return taille_args taille_var) ^ - "RETURN (0) " ^ taille_args ^ "\n\n" + "HALT\n" | _ -> failwith "spa normal" diff --git a/src/passePlacementRat.ml b/src/passePlacementRat.ml index 1171cc3..4eaa4cc 100644 --- a/src/passePlacementRat.ml +++ b/src/passePlacementRat.ml @@ -12,13 +12,6 @@ struct 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 = match i with | AstType.Declaration(info, _) -> diff --git a/src/passeTdsRat.ml b/src/passeTdsRat.ml index bf0233b..3d0366a 100644 --- a/src/passeTdsRat.ml +++ b/src/passeTdsRat.ml @@ -52,6 +52,26 @@ let rec analyse_tds_affectable tds a modif = | InfoFun _ -> raise (MauvaiseUtilisationIdentifiant(n)) 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 *) (* Paramètre tds : la table des symboles courante *) @@ -101,15 +121,20 @@ let rec analyse_tds_expression tds e = | AstSyntax.NewType(t) -> AstTds.NewType(t) | AstSyntax.Adresse(n) -> let info = chercherGlobalement tds n in - match info with - | None -> - raise (IdentifiantNonDeclare n) - | Some i -> - begin - match (info_ast_to_info i) with - | InfoVar _ -> AstTds.Adresse(i) - | _ -> raise (MauvaiseUtilisationIdentifiant(n)) - end + begin + match info with + | None -> + raise (IdentifiantNonDeclare n) + | Some i -> + begin + match (info_ast_to_info i) with + | InfoVar _ -> AstTds.Adresse(i) + | _ -> raise (MauvaiseUtilisationIdentifiant(n)) + 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)) = begin @@ -135,30 +160,30 @@ en une instruction de type AstTds.instruction *) let rec analyse_tds_instruction tds i = match i with | AstSyntax.Declaration (t, n, e) -> - begin - match chercherLocalement tds n with - | None -> - (* 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 - (* Création du pointeur sur l'information *) - let ia = info_to_info_ast info in - (* Ajout de l'information (pointeur) dans la tds *) - ajouter tds n ia; - (* 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 *) + begin + match chercherLocalement tds n with + | None -> + (* 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 + (* Création du pointeur sur l'information *) + let ia = info_to_info_ast info in + (* Ajout de l'information (pointeur) dans la tds *) + ajouter tds n ia; + (* 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 - Declaration (nt, ia, ne) - | Some _ -> - (* L'identifiant est trouvé dans la tds locale, - il a donc déjà été déclaré dans le bloc courant *) - raise (DoubleDeclaration n) - end + let nt = recherche_type tds t in + AstTds.Declaration (nt, ia, ne) + | Some _ -> + (* L'identifiant est trouvé dans la tds locale, + il a donc déjà été déclaré dans le bloc courant *) + raise (DoubleDeclaration n) + end | AstSyntax.Affectation (aff, e) -> begin let ne = analyse_tds_expression tds e in diff --git a/src/passeTypeRat.ml b/src/passeTypeRat.ml index b0fd01c..2c5418a 100644 --- a/src/passeTypeRat.ml +++ b/src/passeTypeRat.ml @@ -27,6 +27,14 @@ let rec analyse_type_affectable a = | InfoConst _ -> (AstType.Ident(info), Int) | InfoFun _ -> failwith "c chelou frr" 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) *) @@ -94,6 +102,10 @@ let rec analyse_type_expression e = let InfoVar(_, t, _, _) = info_ast_to_info info in let _ = modifier_type_info (Pointeur(t)) info in (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 *) (* Paramètre tds : la table des symboles courante *) diff --git a/src/type.ml b/src/type.ml index 2bd7634..c7e7eeb 100644 --- a/src/type.ml +++ b/src/type.ml @@ -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 = match t with @@ -6,6 +6,7 @@ let rec string_of_type t = | Int -> "Int" | Rat -> "Rat" | 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" @@ -15,7 +16,16 @@ let rec est_compatible t1 t2 = | Int, Int -> true | Rat, Rat -> true | Pointeur(t_p1), Pointeur(t_p2) -> est_compatible t_p1 t_p2 - | _ -> false + | 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 + +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 Int Int @@ -34,11 +44,6 @@ let%test _ = not (est_compatible Undefined Int) let%test _ = not (est_compatible Undefined Rat) 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 [Int ; Rat] [Int ; Rat] 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 [Bool ; Rat ; Bool] [Bool ; Rat ; Bool ; Int]) -let getTaille t = +let rec getTaille t = match t with | Int -> 1 | Bool -> 1 | Rat -> 2 | Pointeur(_) -> 1 + | Struct(l_typestr) -> List.fold_right (fun (t, _) res -> (getTaille t) + res) l_typestr 0 | Undefined -> 0 let%test _ = getTaille Int = 1 diff --git a/src/type.mli b/src/type.mli index 05ec110..a3cb6ee 100644 --- a/src/type.mli +++ b/src/type.mli @@ -1,5 +1,5 @@ (* 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 *) (* transforme un typ en chaîne de caractère *)