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
|
| 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 *)
|
||||||
|
|
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 *)
|
(* 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) }
|
||||||
|
|
|
@ -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)}
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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, _) ->
|
||||||
|
|
|
@ -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 *)
|
||||||
|
|
|
@ -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 *)
|
||||||
|
|
20
src/type.ml
20
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 =
|
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
|
||||||
|
|
|
@ -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 *)
|
||||||
|
|
Loading…
Reference in a new issue