68 lines
2.3 KiB
OCaml
68 lines
2.3 KiB
OCaml
(* 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
|
|
| Var of string
|
|
| LetIn of string*expr*expr
|
|
|
|
type valeur = VInt of int | VBool of bool
|
|
|
|
type env = (string*valeur) list
|
|
|
|
let empty_env = []
|
|
|
|
exception InvalidTypeException
|
|
exception UnknownVariableException
|
|
|
|
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 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)
|
|
| Var(v) -> readVar env v UnknownVariableException
|
|
| LetIn(v,e0,e1) -> eval e1 ((v,eval e0 env)::env)
|