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
(* 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 *)

View file

@ -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) }

View file

@ -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 <programme> 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)}
| 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
name ^ "\n" ^
(analyse_code_bloc bloc taille_return taille_args taille_var) ^
"RETURN (0) " ^ taille_args ^ "\n\n"
"HALT\n"
| _ -> failwith "spa normal"

View file

@ -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, _) ->

View file

@ -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

View file

@ -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 *)

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 =
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

View file

@ -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 *)