summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex AUVOLAT <alex.auvolat@ens.fr>2013-12-05 23:10:05 +0100
committerAlex AUVOLAT <alex.auvolat@ens.fr>2013-12-05 23:10:05 +0100
commit41149667006a5606cf142a6e73cb6748b1212045 (patch)
tree16812c1043624cb61d3f6c4252a879015ee56347
parent10805760b023e6b37c293b70c48d87ce38078571 (diff)
downloadLPC-Projet-41149667006a5606cf142a6e73cb6748b1212045.tar.gz
LPC-Projet-41149667006a5606cf142a6e73cb6748b1212045.zip
Messages d'erreur plus explicites.
-rw-r--r--src/typing.ml39
1 files changed, 22 insertions, 17 deletions
diff --git a/src/typing.ml b/src/typing.ml
index 407c1d4..620254d 100644
--- a/src/typing.ml
+++ b/src/typing.ml
@@ -1,8 +1,8 @@
open Ast
+(* Gestion des erreurs *)
exception LocError of loc * string
exception Error of string
-
let er_ident i = raise (Error ("Unknown identifier " ^ i))
let er_ident_loc i loc = raise (LocError (loc, "Unknown identifier " ^ i))
let er_not_a_variable i = raise (Error ("Expected '"^i^"' to be a variable"))
@@ -11,6 +11,12 @@ let er_tident_use () = raise (Error ("Er_tident_use"))
let er_double_ref () = raise (Error ("Er_double_ref"))
let er_ref_use ()= raise (Error ("Er_ref_use"))
let er_not_implemented () = raise (Error ("Not implemented"))
+let ty_assert x k = if not x then raise (Error (k))
+let ty_error k = raise (Error (k))
+
+(* AST typés *)
+
+module Smap = Map.Make(String)
type typ =
| T_Int
@@ -34,7 +40,7 @@ and texpr_desc =
| TEIdent of ident
| TEAssign of texpression * texpression
| TECallFun of ident * texpression list (* changé : te -> ident *)
-(* | TECallMethod of texpression * ident * texpression list *) (* changé : te -> ident *)
+ | TECallMethod of texpression * ident * texpression list (* changé : te -> ident *)
| TEUnary of unop * texpression
| TEBinary of texpression * binop * texpression
| TEMember of texpression * ident
@@ -44,8 +50,6 @@ type tstr_expression =
| TSEExpr of texpression
| TSEStr of string
-module Smap = Map.Make(String)
-
type tstatement = {
ts_loc: loc;
@@ -176,44 +180,45 @@ and compute_type env e = match e.e_desc with (* expression -> te_desc,(typ,ref?,
| ENull -> TENull, (Typenull,false,false)
| EIdent i ->
(try let ty,b = find_v i env in (* pb avec (i,bool) *)
- assert (bf ty); (* règle champs p4 *)
+ ty_assert (bf ty) "Malformed type"; (* règle champs p4 *)
TEIdent i,(ty,b,true)
with Not_found -> er_ident i
)
| EAssign (e1,e2) -> let te1,(ty1,_,b3) = get_expr0 env e1 in
let te2,(ty2,_,_) = get_expr0 env e2 in
- assert (b3 = true);
- assert (num ty1); (* type num et ref compatibles ?*)
+ ty_assert (b3 = true) "Can only assign to lvalue";
+ ty_assert (num ty1) "Cannot assign to non-numeric type (pointer type is numeric)";
+ (* type num et ref compatibles ?*)
(TEAssign (te1,te2) ),(ty1,false,false)
| EUnary (op,e) -> let te,(ty,b1,b2) = get_expr0 env e in
(match op with
| PreIncr | PostIncr | PreDecr | PostDecr ->
- assert (b2 = true);
- assert (ty = T_Int);
+ ty_assert (b2 = true) "Can only increment/decrement lvalue";
+ ty_assert (ty = T_Int) "Can only increment/decrement integers";
TEUnary(op,te),(T_Int,b1,false)
| Plus | Minus | Not ->
- assert (ty = T_Int);
+ ty_assert (ty = T_Int) "Can only apply unary plus/minus/not to integers";
TEUnary(op,te),(T_Int,false,false)
| Ref ->
- assert b2;
+ ty_assert b2 "Can only reference lvalues";
TEUnary(op,te),(TPoint ty,false,false) (* verif *)
| Deref ->
let t = (match ty with
| TPoint t -> t
- | _ -> failwith "On attend un type pointeur" ) in
+ | _ -> ty_error "Can only dereference pointer" ) in
TEUnary(op,te), (t,true,false)
)
| EBinary (e1,op,e2) -> let te1,(ty1,_,b1) = get_expr0 env e1 in
let te2,(ty2,_,b2) = get_expr0 env e2 in
(match op with
| Equal | NotEqual ->
- assert (ty1 = ty2);
- assert (num ty1)
+ ty_assert (ty1 = ty2) "Can only apply == or != to two values of same type";
+ ty_assert (num ty1) "Can only apply == or != to pointers"
| Lt | Le | Gt | Ge
| Add | Sub | Mul | Div | Modulo
| Land | Lor ->
- assert (ty1 = T_Int);
- assert (ty2 = T_Int)
+ ty_assert (ty1 = T_Int) "Left operand of binop is not integer";
+ ty_assert (ty2 = T_Int) "Right operand of binop is not integer"
); (* vérifs *)
TEBinary(te1,op,te2),(T_Int,false,false)
| ECall (e,e_list) -> let name = (match e.e_desc with
@@ -225,7 +230,7 @@ and compute_type env e = match e.e_desc with (* expression -> te_desc,(typ,ref?,
let tab = Array.of_list args in
List.iteri
(fun j (te,(ty0,b)) ->
- assert (ty0 = tab.(j) ) )
+ ty_assert (ty0 = tab.(j)) "Invalid type for function argument" )
l ;
(* vérif ici pour adresse/valeur, ici on test seulement
que ce sont les mêmes types, pas d'adressage de pris en compte *)