(* définition des différents types : tout est à reprendre et étendre *) type expr = Const of int | BConst of bool | Add of expr*expr | Mul of expr*expr | Min of expr*expr | Eq of expr*expr | Gt of expr*expr | Lt of expr*expr | Gte of expr*expr | Lte of expr*expr | Band of expr*expr | Bor of expr*expr | ITE of expr*expr*expr | PrInt of expr type valeur = VInt of int | VBool of bool type env = unit let empty_env = () exception InvalidTypeException 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 and intBoolOp op e1 e2 env = match (eval e1 env, eval e2 env) with | VInt k1,VInt k2 -> VBool(op k1 k2) | _ -> raise InvalidTypeException (* sémantique opérationnelle à grands pas *) and eval e env = match e with | Const(k) -> VInt k | BConst(b) -> VBool b | Add(e1,e2) -> intIntOp ( + ) e1 e2 env | Mul(e1,e2) -> intIntOp ( * ) e1 e2 env | Min(e1,e2) -> intIntOp ( - ) e1 e2 env | Gt(e1,e2) -> intBoolOp ( > ) e1 e2 env | Lt(e1,e2) -> intBoolOp ( < ) e1 e2 env | Gte(e1,e2) -> intBoolOp ( >= ) e1 e2 env | Lte(e1,e2) -> intBoolOp ( <= ) e1 e2 env | 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) | Band(e1,e2) -> (match (eval e1 env, eval e2 env) with | VBool b1,VBool b2 -> VBool (b1 && b2) | _ -> raise InvalidTypeException) | Bor(e1,e2) -> (match (eval e1 env, eval e2 env) with | VBool b1,VBool b2 -> VBool (b1 || b2) | _ -> raise InvalidTypeException) | ITE(ec,e1,e2) -> (match (eval ec env) with | VBool bc -> eval (if bc then e1 else e2) env | _ -> raise InvalidTypeException) | PrInt e1 -> (match (eval e1 env) with | VInt k -> VInt k | _ -> raise InvalidTypeException)