(* projet Caml : ivaluateur d'une session Caml *) open List ;; (* declaration du type typ *) type typ = TEntier | TBool | TFonction of typ * typ ;; (* declaration du type expr *) type expr = Vrai | Faux | Variable of string | Constante of int | Et of expr*expr | Ou of expr*expr | Non of expr | Inf of expr*expr | InfEgal of expr*expr | Sup of expr*expr | SupEgal of expr*expr | Egal of expr*expr | Different of expr*expr | Oppose of expr | Addition of expr*expr | Soustraction of expr*expr | Produit of expr*expr | Division of expr*expr | Modulo of expr*expr | Fonction of (string*typ)*expr | Application of expr*expr | LetIn of (string * expr) list * expr | If of expr*expr*expr ;; (* declaration du type valeur *) type valeur = VEntier of int | VBool of bool | VFermeture of (string*typ)*expr*((string*valeur) list)*((string*typ) list) ;; (* declaration du type instruction *) type instruction = Declaration of string*expr | Expression of expr ;; (* declaration du type session *) type session = instruction list ;; (* declaration de l'exception TypeException *) exception TypeException of string;; exception ValeurException of string;; (* on choisit de representer l'environnement par une liste de couples (variable,valeur) avec variable de type string et valeur de type valeur *) let env_cur = ref [] ;; (* on utilise une rifirence pour pouvoir modifier plus tard l'environnement *) (* on choisit de reprisenter l'environnement de typage par une autre liste de couples (variable,type) *) let env_type = ref [] ;; (* fonction qui modifie l'environnement courant en ajoutant une liaison en tete de liste *) let ajt_env_cur = fun liaison -> env_cur:=(liaison::(!env_cur)) ;; (* fonction qui modifie l'environnement de typage en ajoutant un couple (variable,type) en tete de liste *) let ajt_env_type = fun couple -> env_type:=(couple::(!env_type)) ;; (* fonction qui renvoie true si var est dans env et false sinon *) let rec dans_env = fun var env -> match env with [] -> false | liaison::env -> if (fst liaison)=var then true else (dans_env var env) ;; (* appliquee a une liste de couples (variable,valeur), cette fonction renvoie true si au moins une variable est liee a plusieurs valeurs et false sinon *) let rec liee_plusieurs_fois = function [] -> false | x::l -> if (dans_env (fst x) l) then true else liee_plusieurs_fois l ;; (* fonction qui renvoie la valeur ou le type de la variable var dans env *) let rec val_ou_type_de = fun var -> function [] -> raise (TypeException (var^" n'est pas defini")) | k::l -> if (fst k) = var then (snd k) else val_ou_type_de var l ;; (* listevar_str: une fonction utilisee dans la representation de Let et LetIn dans expr_str *) (* expr_str: fonction qui transforme une expression en chaine de caracteres *) let rec expr_str = let rec listevar_str = function [] -> "" | [(var,exp)] -> var^"="^(expr_str exp) | (var,exp)::liste -> var^"="^(expr_str exp)^" and "^(listevar_str liste) in function Vrai -> "true" | Faux -> "false" | Et(e1,e2) -> "("^(expr_str e1)^" && "^(expr_str e2)^")" | Ou(e1,e2) -> "("^(expr_str e1)^" or "^(expr_str e2)^")" | Non(e) -> "(not "^(expr_str e)^")" | Inf(e1,e2) -> "("^(expr_str e1)^" < "^(expr_str e2)^")" | InfEgal(e1,e2) -> "("^(expr_str e1)^" <= "^(expr_str e2)^")" | Sup(e1,e2) -> "("^(expr_str e1)^" > "^(expr_str e2)^")" | SupEgal(e1,e2) -> "("^(expr_str e1)^" >= "^(expr_str e2)^")" | Egal(e1,e2) -> "("^(expr_str e1)^" = "^(expr_str e2)^")" | Different(e1,e2) -> "("^(expr_str e1)^" <> "^(expr_str e2)^")" | Variable(s) -> s | Constante(n) -> string_of_int(n) | Oppose(e) -> "(-"^(expr_str e)^")" | Addition(e1,e2) -> "("^(expr_str e1)^" + "^(expr_str e2)^")" | Soustraction(e1,e2) -> "("^(expr_str e1)^" - "^(expr_str e2)^")" | Produit(e1,e2) -> "("^(expr_str e1)^" * "^(expr_str e2)^")" | Division(e1,e2) -> "("^(expr_str e1)^" / "^(expr_str e2)^")" | Modulo(e1,e2) -> "("^(expr_str e1)^" mod "^(expr_str e2)^")" | Fonction((var,t),corps) -> "(fun "^var^" -> "^(expr_str corps)^")" | Application(e1,e2) -> "("^(expr_str e1)^" "^(expr_str e2)^")" | LetIn(mini_env, e) -> "(let " ^ (listevar_str mini_env) ^ " in " ^ (expr_str e) ^ ")" | If(e1,e2,e3) -> "(if "^(expr_str e1)^" then "^(expr_str e2)^" else "^(expr_str e3)^")" ;; (* fonction qui transforme une valeur en chaine de caracteres *) let rec val_str = function VEntier(n) -> string_of_int(n) | VBool(b) -> string_of_bool(b) | VFermeture((param,t),corps,envv_def,envt_def) -> let rec env_str = function [] ->"" | ((variable,valeur)::env) -> if env=[] then "("^variable^","^(val_str valeur)^")" else "("^variable^","^(val_str valeur)^");"^(env_str env) in "< "^param^" ~> "^(expr_str corps)^" , ["^(env_str envv_def)^"] >" ;; (* fonction qui transforme un typ en chaine de caracteres *) let rec type_str = function TEntier -> "int" | TBool -> "bool" | TFonction(type1,type2) -> "("^(type_str type1)^") -> ("^(type_str type2)^")" ;; (* fonction qui affiche une expression *) let afficher_expr = fun expression -> print_string (expr_str expression) ;; (* fonction qui affiche une valeur *) let afficher_val = fun valeur -> print_string (val_str valeur) ;; (* fonction qui affiche un typ *) let afficher_type = fun typ -> print_string (type_str typ) ;; (* fonction qui renvoie le type d'une expression passee en argument *) let rec typer = fun envt -> function Vrai -> TBool | Faux -> TBool | Et(e1,e2) -> if ((typer envt e1)=TBool) then if ((typer envt e2)=TBool) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type bool")) | Ou(e1,e2) -> if ((typer envt e1)=TBool) then if ((typer envt e2)=TBool) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type bool")) | Non(e) -> if ((typer envt e)=TBool) then TBool else raise (TypeException ("L'expression "^(expr_str e)^" n'est pas de type bool")) | Inf(e1,e2) -> if ((typer envt e1)=TEntier) then (if ((typer envt e2)=TEntier) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int"))) else (if ((typer envt e1)=TBool) then (if ((typer envt e2)=TBool) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool"))) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool"))) | InfEgal(e1,e2) -> if ((typer envt e1)=TEntier) then (if ((typer envt e2)=TEntier) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int"))) else (if ((typer envt e1)=TBool) then (if ((typer envt e2)=TBool) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool"))) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool"))) | Sup(e1,e2) -> if ((typer envt e1)=TEntier) then (if ((typer envt e2)=TEntier) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int"))) else (if ((typer envt e1)=TBool) then (if ((typer envt e2)=TBool) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool"))) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool"))) | SupEgal(e1,e2) -> if ((typer envt e1)=TEntier) then (if ((typer envt e2)=TEntier) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int"))) else (if ((typer envt e1)=TBool) then (if ((typer envt e2)=TBool) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool"))) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool"))) | Egal(e1,e2) -> if ((typer envt e1)=TEntier) then (if ((typer envt e2)=TEntier) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int"))) else (if ((typer envt e1)=TBool) then (if ((typer envt e2)=TBool) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool"))) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool"))) | Different(e1,e2) -> if ((typer envt e1)=TEntier) then (if ((typer envt e2)=TEntier) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int"))) else (if ((typer envt e1)=TBool) then (if ((typer envt e2)=TBool) then TBool else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool"))) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool"))) | Variable(s) -> val_ou_type_de s envt | Constante(n) -> TEntier | Oppose(e) -> if (typer envt e)=TEntier then TEntier else raise (TypeException ("L'expression "^(expr_str e)^" n'est pas de type int")) | Addition(e1,e2) -> if (typer envt e1)=TEntier then if (typer envt e2)=TEntier then TEntier else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int")) | Soustraction(e1,e2) -> if (typer envt e1)=TEntier then if (typer envt e2)=TEntier then TEntier else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int")) | Produit(e1,e2) -> if (typer envt e1)=TEntier then if (typer envt e2)=TEntier then TEntier else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int.")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int.")) | Division(e1,e2) -> if (typer envt e1)=TEntier then if (typer envt e2)=TEntier then TEntier else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int.")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int.")) | Modulo(e1,e2) -> if (typer envt e1)=TEntier then if (typer envt e2)=TEntier then TEntier else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int")) | Fonction((param,t),corps) -> TFonction(t,(typer ((param,t)::envt) corps)) | Application(fonction,argument) -> let t=(typer envt fonction) in (match t with TFonction(t1,t2) -> if t1=(typer envt argument) then t2 else raise (TypeException ("L'expression "^(expr_str argument)^ " n'est pas de type "^(type_str t1))) | _ -> raise (TypeException ((expr_str fonction)^" n'est pas de type fonctionnel"))) | If(e1,e2,e3) -> if (typer envt e1)=TBool then let t=(typer envt e2) in (if t=(typer envt e3) then t else raise (TypeException ("L'expression "^(expr_str e3)^" n'est pas de type "^(type_str t)))) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type bool")) | LetIn (mini_env, exp) -> (match mini_env with [] -> raise (TypeException ("Erreur de syntaxe")) | l -> if not(liee_plusieurs_fois l) then (* fonction auxiliaire qui a une liste de couples (variable,expression) renvoie une liste de couples (variable,type) correspondante *) (let aux = map (fun (x,y) -> (x,typer envt y)) in typer ((aux l)@envt) exp) else raise (TypeException ("Erreur de syntaxe : au moins une des variables est liee a plusieurs valeurs"))) ;; (* fonction qui convertit une valeur en bool *) let valeur_bool = function VBool(b) -> b | _ ->raise (ValeurException ("Erreur")) ;; (* fonction qui convertit une valeur en entier *) let valeur_int = function VEntier(n) -> n | _ -> raise (ValeurException ("Erreur")) ;; (* fonction qui permet d'evaluer une expression *) let rec evaluer = fun envv -> fun envt -> function Vrai -> VBool(true) | Faux -> VBool(false) | Et(e1,e2) -> if ((typer envt e1)<>TBool) then raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type bool")) else if ((typer envt e2)<>TBool) then raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else VBool((valeur_bool(evaluer envv envt e1))&&(valeur_bool(evaluer envv envt e2))) | Ou(e1,e2) -> if ((typer envt e1)<>TBool) then raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type bool")) else if ((typer envt e2)<>TBool) then raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else VBool((valeur_bool(evaluer envv envt e1))||(valeur_bool(evaluer envv envt e2))) | Non(e) -> if (typer envt e)<>TBool then raise (TypeException ("L' expression "^(expr_str e)^" n'est pas de type bool")) else VBool(not(valeur_bool(evaluer envv envt e))) | Inf(e1,e2) -> if ((typer envt e1)=TEntier) then if ((typer envt e2)=TEntier) then VBool((valeur_int(evaluer envv envt e1))<(valeur_int(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else if ((typer envt e1)=TBool) then if ((typer envt e2)=TBool) then VBool((valeur_bool(evaluer envv envt e1))<(valeur_bool(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool")) | InfEgal(e1,e2) -> if ((typer envt e1)=TEntier) then if ((typer envt e2)=TEntier) then VBool((valeur_int(evaluer envv envt e1))<=(valeur_int(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else if ((typer envt e1)=TBool) then if ((typer envt e2)=TBool) then VBool((valeur_bool(evaluer envv envt e1))<=(valeur_bool(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool")) | Sup(e1,e2) -> if ((typer envt e1)=TEntier) then if ((typer envt e2)=TEntier) then VBool((valeur_int(evaluer envv envt e1))>(valeur_int(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else if ((typer envt e1)=TBool) then if ((typer envt e2)=TBool) then VBool((valeur_bool(evaluer envv envt e1))>(valeur_bool(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool")) | SupEgal(e1,e2) -> if ((typer envt e1)=TEntier) then if ((typer envt e2)=TEntier) then VBool((valeur_int(evaluer envv envt e1))>=(valeur_int(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else if ((typer envt e1)=TBool) then if ((typer envt e2)=TBool) then VBool((valeur_bool(evaluer envv envt e1))>=(valeur_bool(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool")) | Egal(e1,e2) -> if ((typer envt e1)=TEntier) then if ((typer envt e2)=TEntier) then VBool((valeur_int(evaluer envv envt e1))=(valeur_int(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else if ((typer envt e1)=TBool) then if ((typer envt e2)=TBool) then VBool((valeur_bool(evaluer envv envt e1))=(valeur_bool(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool")) | Different(e1,e2) -> if ((typer envt e1)=TEntier) then if ((typer envt e2)=TEntier) then VBool((valeur_int(evaluer envv envt e1))<>(valeur_int(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else if ((typer envt e1)=TBool) then if ((typer envt e2)=TBool) then VBool((valeur_bool(evaluer envv envt e1))<>(valeur_bool(evaluer envv envt e2))) else raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type bool")) else raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int ou bool")) | Variable(s) -> val_ou_type_de s envv | Constante(n) -> VEntier(n) | Oppose(e) -> if (typer envt e)<>TEntier then raise (TypeException ((expr_str e)^" n'est pas de type int")) else VEntier(-(valeur_int (evaluer envv envt e))) | Addition(e1,e2) -> if ((typer envt e1)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int")) else if ((typer envt e2)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else VEntier((valeur_int(evaluer envv envt e1))+(valeur_int(evaluer envv envt e2))) | Soustraction(e1,e2) -> if ((typer envt e1)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int")) else if ((typer envt e2)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else VEntier((valeur_int(evaluer envv envt e1))-(valeur_int(evaluer envv envt e2))) | Produit(e1,e2) -> if ((typer envt e1)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int")) else if ((typer envt e2)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else VEntier((valeur_int(evaluer envv envt e1))*(valeur_int(evaluer envv envt e2))) | Division(e1,e2) -> if ((typer envt e1)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int")) else if ((typer envt e2)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else VEntier((valeur_int(evaluer envv envt e1))/(valeur_int(evaluer envv envt e2))) | Modulo(e1,e2) -> if ((typer envt e1)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type int")) else if ((typer envt e2)<>TEntier) then raise (TypeException ("L'expression "^(expr_str e2)^" n'est pas de type int")) else VEntier((valeur_int(evaluer envv envt e1))mod(valeur_int(evaluer envv envt e2))) | Fonction((param,t),corps) -> VFermeture((param,t),corps,!(env_cur),!(env_type)) | Application(e1,e2) -> let v=evaluer envv envt e1 in (match v with VFermeture((param,t),corps,envv_def,envt_def) -> evaluer ((param,(evaluer envv envt e2))::envv_def) ((param,t)::envt_def) corps | _ -> raise (TypeException "Erreur" )) | If(e1,e2,e3) -> if ((typer envt e1)<>TBool) then raise (TypeException ("L'expression "^(expr_str e1)^" n'est pas de type bool")) else if ((typer envt e2)<>(typer envt e3)) then raise (TypeException ("Les expressions "^(expr_str e2)^" et "^(expr_str e3)^" ne sont pas de meme types.")) else if ((evaluer envv envt e1)=VBool(true)) then (evaluer envv envt e2) else (evaluer envv envt e3) | LetIn (mini_env, exp) -> (match mini_env with [] -> raise (TypeException ("Erreur de syntaxe")) | l -> if not(liee_plusieurs_fois l) then (let aux1 = map (fun (x,y) -> (x,evaluer envv envt y)) and aux2 = map (fun (x,y) -> (x,typer envt y)) in evaluer ((aux1 l)@envv) ((aux2 l)@envt) exp) else raise (TypeException ("Erreur de syntaxe : au moins une des variables est liee a plusieurs valeurs"))) ;; let rec simplifier = function Et(Faux,_) -> Faux | Et(_,Faux) -> Faux | Et(e1,e2) -> Et(simplifier e1,simplifier e2) | Ou(Vrai,_) -> Vrai | Ou(_,Vrai) -> Vrai | Ou(e1,e2) -> Ou(simplifier e1,simplifier e2) | Non(Vrai) -> Faux | Non(Faux) -> Vrai | Non(e) -> Non(simplifier e) | Inf(e1,e2) -> Inf(simplifier e1,simplifier e2) | InfEgal(e1,e2) -> InfEgal(simplifier e1,simplifier e2) | Sup(e1,e2) -> Sup(simplifier e1,simplifier e2) | SupEgal(e1,e2) -> SupEgal(simplifier e1,simplifier e2) | Egal(e1,e2) -> Egal(simplifier e1,simplifier e2) | Different(e1,e2) -> Different(simplifier e1,simplifier e2) | Oppose(Constante(n)) -> Constante(-n) | Oppose(e) -> Oppose(simplifier e) | Addition(Constante(n1),Constante(n2)) -> Constante(n1+n2) | Addition(e1,e2) -> Addition(simplifier e1,simplifier e2) | Soustraction(Constante(n1),Constante(n2)) -> Constante(n1-n2) | Soustraction(e1,e2) -> Soustraction(simplifier e1,simplifier e2) | Produit(Constante(n1),Constante(n2)) -> Constante(n1*n2) | Produit(e1,e2) -> Produit(simplifier e1,simplifier e2) | Division(Constante(n1),Constante(n2)) -> Constante(n1/n2) | Division(e1,e2) -> Division(simplifier e1,simplifier e2) | Modulo(Constante(n1),Constante(n2)) -> Constante(n1 mod n2) | Modulo(e1,e2) -> Modulo(simplifier e1,simplifier e2) | Fonction((param,t),corps) -> Fonction((param,t),simplifier corps) | Application(e1,e2) -> Application(simplifier e1,simplifier e2) | If(Vrai,e1,e2) -> e1 | If(Faux,e1,e2) -> e2 | If(e1,e2,e3) -> If(simplifier e1,simplifier e2,simplifier e3) | e -> e ;; let executer_instruction = function | Declaration(variable,exp) -> begin print_string("# let "^variable^"="); afficher_expr(exp); print_newline(); ajt_env_type (variable,typer !env_type exp); ajt_env_cur (variable,evaluer !env_cur !env_type exp); print_string("val "^variable^" : "); afficher_type(typer !env_type exp); print_string(" = "); afficher_val(evaluer !env_cur !env_type exp); print_newline() end | Expression(e) -> begin print_string("# "); afficher_expr(e); print_newline(); print_string("- : "); afficher_type(typer !env_type e); print_string(" = "); afficher_val(evaluer !env_cur !env_type e); print_newline() end ;; let executer_session = let rec aux = function [] -> () | x::l -> begin try (executer_instruction x) with TypeException(s) -> begin (*print_string ("TypeException");*) print_string(s); print_newline() end | ValeurException(s) -> begin (*print_string("ValeurException");*) print_string(s); print_newline() end | _ -> print_string("Erreur"); print_newline() end; (*executer_instruction x;*) aux l in fun session -> begin env_cur:=[]; env_type:=[]; aux session end ;;