feat: debut struct
This commit is contained in:
parent
8a4e107ecd
commit
951a1a441b
10
src/ast.ml
10
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 *)
|
||||
|
|
0
src/fichiersRat/src-rat-tam-test/struct1.rat
Normal file
0
src/fichiersRat/src-rat-tam-test/struct1.rat
Normal 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) }
|
||||
|
|
|
@ -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)}
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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, _) ->
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *)
|
||||
|
|
22
src/type.ml
22
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
|
||||
|
|
|
@ -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 *)
|
||||
|
|
Loading…
Reference in a new issue