Ajout des fonctions.
This commit is contained in:
parent
bd7489bf59
commit
08ee9787f2
@ -3,18 +3,17 @@ open Expr
|
|||||||
let rec affiche_val v = match v with
|
let rec affiche_val v = match v with
|
||||||
| VInt k -> print_int k
|
| VInt k -> print_int k
|
||||||
| VBool b -> print_string (if b then "Vrai" else "Faux")
|
| 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 *)
|
(* fonction d'affichage *)
|
||||||
and affiche_expr e =
|
and affiche_expr e =
|
||||||
let aff_aux s a b =
|
let aff_aux s a b =
|
||||||
begin
|
begin
|
||||||
print_string s;
|
print_string s;
|
||||||
affiche_expr a;
|
affiche_expr a;
|
||||||
print_string ", ";
|
print_string ", ";
|
||||||
affiche_expr b;
|
affiche_expr b;
|
||||||
print_string ")"
|
print_string ")"
|
||||||
end
|
end
|
||||||
in
|
in
|
||||||
match e with
|
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 ")"
|
| 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))
|
| Fun(v,e) -> affiche_val (VFunc(v,e))
|
||||||
| App(e1,e2) -> aff_aux "App(" e1 e2
|
| 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
open List
|
||||||
|
|
||||||
(* définition des différents types : tout est à reprendre et étendre *)
|
(* définition des différents types : tout est à reprendre et étendre *)
|
||||||
type expr =
|
type expr =
|
||||||
Const of int
|
Const of int
|
||||||
@ -25,24 +27,56 @@ type env = (string*valeur) list
|
|||||||
|
|
||||||
let empty_env = []
|
let empty_env = []
|
||||||
|
|
||||||
exception InvalidTypeException
|
exception InvalidTypeException of (string*valeur) (** expected, given **)
|
||||||
exception UnknownVariableException
|
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
|
let rec readVar env v0 e = match env with
|
||||||
| [] -> raise e
|
| [] -> raise e
|
||||||
| (v,x)::t -> if (v0 = v) then x else readVar t v0 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
|
let rec intIntOp op e1 e2 env = match (eval e1 env, eval e2 env) with
|
||||||
| VInt k1,VInt k2 -> VInt(op k1 k2)
|
| 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
|
and intBoolOp op e1 e2 env = match (eval e1 env, eval e2 env) with
|
||||||
| VInt k1,VInt k2 -> VBool(op k1 k2)
|
| 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 *)
|
(* sémantique opérationnelle à grands pas *)
|
||||||
and eval e env = match e with
|
and eval e env = match e with
|
||||||
| Const(k) -> VInt k
|
| Const(k) -> VInt k
|
||||||
| BConst(b) -> VBool b
|
| 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
|
| Add(e1,e2) -> intIntOp ( + ) e1 e2 env
|
||||||
| Mul(e1,e2) -> intIntOp ( * ) e1 e2 env
|
| Mul(e1,e2) -> intIntOp ( * ) e1 e2 env
|
||||||
| Min(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
|
| Eq(e1,e2) -> (match (eval e1 env, eval e2 env) with
|
||||||
| VInt k1,VInt k2 -> VBool (k1=k2)
|
| VInt k1,VInt k2 -> VBool (k1=k2)
|
||||||
| VBool k1,VBool 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
|
| Band(e1,e2) -> (match (eval e1 env, eval e2 env) with
|
||||||
| VBool b1,VBool b2 -> VBool (b1 && b2)
|
| 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
|
| Bor(e1,e2) -> (match (eval e1 env, eval e2 env) with
|
||||||
| VBool b1,VBool b2 -> VBool (b1 || b2)
|
| 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
|
| ITE(ec,e1,e2) -> (match (eval ec env) with
|
||||||
| VBool bc -> eval (if bc then e1 else e2) env
|
| VBool bc -> eval (if bc then e1 else e2) env
|
||||||
| _ -> raise InvalidTypeException)
|
| x -> raise (InvalidTypeException ("Bool",x)))
|
||||||
| PrInt e1 -> (match (eval e1 env) with
|
| PrInt e1 -> (match (eval e1 env) with
|
||||||
| VInt k -> VInt k
|
| VInt k -> VInt k
|
||||||
| _ -> raise InvalidTypeException)
|
| x -> raise (InvalidTypeException ("Int",x)))
|
||||||
| Var(v) -> readVar env v UnknownVariableException
|
| Var(v) -> readVar env v (UnknownVariableException (v,env))
|
||||||
| LetIn(v,e0,e1) -> eval e1 ((v,eval e0 env)::env)
|
| LetIn(v,e0,e1) -> eval e1 ((v,eval e0 env)::env)
|
||||||
| App(e0,e1) -> (match (eval e0 env) with
|
| 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 *)
|
| 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)))
|
||||||
|
|
||||||
|
|||||||
@ -43,20 +43,24 @@ let rec affiche_printexpr e env = begin
|
|||||||
match e with
|
match e with
|
||||||
| PrInt e -> (match (eval e env) with
|
| PrInt e -> (match (eval e env) with
|
||||||
| VInt(k) -> print_int k;print_newline ()
|
| VInt(k) -> print_int k;print_newline ()
|
||||||
| _ -> raise InvalidTypeException)
|
| x -> raise (InvalidTypeException ("Int",x)))
|
||||||
| _ -> ()
|
| _ -> ()
|
||||||
end
|
end
|
||||||
(* le traitement d'une expression en entrée *)
|
(* le traitement d'une expression en entrée *)
|
||||||
let execute e =
|
let execute e =
|
||||||
|
try
|
||||||
begin
|
begin
|
||||||
affiche_expr e;
|
affiche_expr e;
|
||||||
print_newline();
|
print_newline ();
|
||||||
affiche_printexpr e Expr.empty_env;
|
affiche_printexpr e Expr.empty_env;
|
||||||
print_newline();
|
print_newline ();
|
||||||
let v = Expr.eval e Expr.empty_env in
|
let v = Expr.eval e Expr.empty_env in
|
||||||
affiche_val v;
|
affiche_val v;
|
||||||
print_newline()
|
print_newline ()
|
||||||
end
|
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 *)
|
(* la boucle principale *)
|
||||||
let calc () =
|
let calc () =
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user