From 08ee9787f283dac02173322b3423b456bc60c9ad Mon Sep 17 00:00:00 2001 From: Mysaa Date: Mon, 24 Jan 2022 23:53:08 +0100 Subject: [PATCH] Ajout des fonctions. --- Rendu0/affichage.ml | 45 +++++++++++++++++++++++++++------ Rendu0/expr.ml | 61 ++++++++++++++++++++++++++++++++++++--------- Rendu0/main.ml | 12 ++++++--- 3 files changed, 95 insertions(+), 23 deletions(-) diff --git a/Rendu0/affichage.ml b/Rendu0/affichage.ml index f0a395b..b2c4a8e 100644 --- a/Rendu0/affichage.ml +++ b/Rendu0/affichage.ml @@ -3,18 +3,17 @@ open Expr let rec affiche_val v = match v with | VInt k -> print_int k | VBool b -> print_string (if b then "Vrai" else "Faux") - | VFunc (v,e) -> print_string "fun ";print_string v;print_string " -> ";affiche_expr e - + | VFunc (v,e) -> print_string "Fun(";print_string v;print_string " -> ";affiche_expr e;print_string ")" (* fonction d'affichage *) and affiche_expr e = let aff_aux s a b = begin - print_string s; - affiche_expr a; - print_string ", "; - affiche_expr b; - print_string ")" + print_string s; + affiche_expr a; + print_string ", "; + affiche_expr b; + print_string ")" end in match e with @@ -44,3 +43,35 @@ and affiche_expr e = | LetIn(x,e0,e1) -> print_string "LetIn(";print_string x;print_string ",";affiche_expr e0;print_string ",";affiche_expr e1;print_string ")" | Fun(v,e) -> affiche_val (VFunc(v,e)) | App(e1,e2) -> aff_aux "App(" e1 e2 + +let dump_env_line x = + let (e,v) = x in + begin + print_string e; + print_string " -> "; + affiche_val v + end + +let dump_env env = + begin + print_string "["; + let rec aux l = + begin + match l with + | [] -> () + | [e] -> dump_env_line e + | e::t -> + begin + dump_env_line e; + print_string ";"; + aux t + end + end + in aux env; + print_string "]" + end + + + + + diff --git a/Rendu0/expr.ml b/Rendu0/expr.ml index e0f79b5..9b3e9cd 100644 --- a/Rendu0/expr.ml +++ b/Rendu0/expr.ml @@ -1,3 +1,5 @@ +open List + (* définition des différents types : tout est à reprendre et étendre *) type expr = Const of int @@ -25,24 +27,56 @@ type env = (string*valeur) list let empty_env = [] -exception InvalidTypeException -exception UnknownVariableException +exception InvalidTypeException of (string*valeur) (** expected, given **) +exception UnknownVariableException of (string*env) (** query, env **) + + +let valToConstExpr v = match v with + | VInt(k) -> Const(k) + | VBool(b) -> BConst(b) + | VFunc(var,e) -> Fun(var,e) let rec readVar env v0 e = match env with | [] -> raise e | (v,x)::t -> if (v0 = v) then x else readVar t v0 e +let rec decontextifier e env = match e with + | Const(_) | BConst(_)-> e + | Fun(v,e) -> Fun(v,decontextifier e (filter (fun (var,x)->not (v=var)) env)) (* On enlève de l'environnement toutes les occurences de v *) + | Add(e1,e2) -> Add(decontextifier e1 env, decontextifier e2 env) + | Mul(e1,e2) -> Mul(decontextifier e1 env, decontextifier e2 env) + | Min(e1,e2) -> Min(decontextifier e1 env, decontextifier e2 env) + | Gt(e1,e2) -> Gt(decontextifier e1 env, decontextifier e2 env) + | Lt(e1,e2) -> Lt(decontextifier e1 env, decontextifier e2 env) + | Gte(e1,e2) -> Gte(decontextifier e1 env, decontextifier e2 env) + | Lte(e1,e2) -> Lte(decontextifier e1 env, decontextifier e2 env) + | Eq(e1,e2) -> Eq(decontextifier e1 env, decontextifier e2 env) + | Band(e1,e2) -> Band(decontextifier e1 env, decontextifier e2 env) + | Bor(e1,e2) -> Bor(decontextifier e1 env, decontextifier e2 env) + | ITE(ec,e1,e2) -> ITE(decontextifier ec env, decontextifier e1 env, decontextifier e2 env) + | PrInt e1 -> PrInt(decontextifier e1 env) + | Var(v) -> + begin + try + valToConstExpr (readVar env v (UnknownVariableException (v,env))) + with UnknownVariableException(_,_) -> Var(v) (* Si ce n'est pas dans le contexte, on ne décontextualise pas *) + end + | LetIn(v,e0,e1) -> LetIn(v,decontextifier e0 env, decontextifier e1 (filter (fun (var,x)->not (v=var)) env)) + | App(e0,e1) -> App(decontextifier e0 env, decontextifier e1 env) + let rec intIntOp op e1 e2 env = match (eval e1 env, eval e2 env) with | VInt k1,VInt k2 -> VInt(op k1 k2) - | _ -> raise InvalidTypeException + | x,VInt k2 -> raise (InvalidTypeException ("Int",x)) + | _,y -> raise (InvalidTypeException ("Int",y)) and intBoolOp op e1 e2 env = match (eval e1 env, eval e2 env) with | VInt k1,VInt k2 -> VBool(op k1 k2) - | _ -> raise InvalidTypeException + | x,VInt k2 -> raise (InvalidTypeException ("Int",x)) + | _,y -> raise (InvalidTypeException ("Int",y)) (* sémantique opérationnelle à grands pas *) and eval e env = match e with | Const(k) -> VInt k | BConst(b) -> VBool b - | Fun(v,e) -> VFunc(v,e) + | Fun(v,e) -> VFunc(v,decontextifier e (filter (fun (var,_)->not (v=var)) env)) (* On enlève de l'environnement toutes les occurences de v *) | Add(e1,e2) -> intIntOp ( + ) e1 e2 env | Mul(e1,e2) -> intIntOp ( * ) e1 e2 env | Min(e1,e2) -> intIntOp ( - ) e1 e2 env @@ -53,21 +87,24 @@ and eval e env = match e with | Eq(e1,e2) -> (match (eval e1 env, eval e2 env) with | VInt k1,VInt k2 -> VBool (k1=k2) | VBool k1,VBool k2 -> VBool (k1=k2) - | _ -> raise InvalidTypeException) + | (x,y) -> raise (InvalidTypeException ("mismatch",x))) | Band(e1,e2) -> (match (eval e1 env, eval e2 env) with | VBool b1,VBool b2 -> VBool (b1 && b2) - | _ -> raise InvalidTypeException) + | x,VBool k2 -> raise (InvalidTypeException ("Bool",x)) + | _,y -> raise (InvalidTypeException ("Bool",y))) | Bor(e1,e2) -> (match (eval e1 env, eval e2 env) with | VBool b1,VBool b2 -> VBool (b1 || b2) - | _ -> raise InvalidTypeException) + | x,VBool k2 -> (raise (InvalidTypeException ("Bool",x))) + | _,y -> raise (InvalidTypeException ("Bool",y))) | ITE(ec,e1,e2) -> (match (eval ec env) with | VBool bc -> eval (if bc then e1 else e2) env - | _ -> raise InvalidTypeException) + | x -> raise (InvalidTypeException ("Bool",x))) | PrInt e1 -> (match (eval e1 env) with | VInt k -> VInt k - | _ -> raise InvalidTypeException) - | Var(v) -> readVar env v UnknownVariableException + | x -> raise (InvalidTypeException ("Int",x))) + | Var(v) -> readVar env v (UnknownVariableException (v,env)) | LetIn(v,e0,e1) -> eval e1 ((v,eval e0 env)::env) | App(e0,e1) -> (match (eval e0 env) with | VFunc(v,e) -> eval (LetIn(v,e1,e)) env (* On utilise l'équivalence (fun x->e) y <=> let x=y in e *) - | _ -> raise InvalidTypeException) + | x -> raise (InvalidTypeException ("Func",x))) + diff --git a/Rendu0/main.ml b/Rendu0/main.ml index 23866ce..3e55fd5 100644 --- a/Rendu0/main.ml +++ b/Rendu0/main.ml @@ -43,20 +43,24 @@ let rec affiche_printexpr e env = begin match e with | PrInt e -> (match (eval e env) with | VInt(k) -> print_int k;print_newline () - | _ -> raise InvalidTypeException) + | x -> raise (InvalidTypeException ("Int",x))) | _ -> () end (* le traitement d'une expression en entrée *) let execute e = + try begin affiche_expr e; - print_newline(); + print_newline (); affiche_printexpr e Expr.empty_env; - print_newline(); + print_newline (); let v = Expr.eval e Expr.empty_env in affiche_val v; - print_newline() + print_newline () end + with + | InvalidTypeException(expected, valeur) -> print_string "La valeur ";affiche_val valeur;print_string " a été donnée alors que on souhaitait avoir le type ";print_string expected;print_newline () + | UnknownVariableException(varname, env) -> print_string "Impossible de trouver la variable '";print_string varname;print_string "' dans l'environnement ";dump_env env;print_newline () (* la boucle principale *) let calc () =