diff --git a/Rendu0/affichage.ml b/Rendu0/affichage.ml index 7ba0c14..f0a395b 100644 --- a/Rendu0/affichage.ml +++ b/Rendu0/affichage.ml @@ -1,12 +1,13 @@ open Expr -let affiche_val v = match v with +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 (* fonction d'affichage *) -let rec affiche_expr e = +and affiche_expr e = let aff_aux s a b = begin print_string s; @@ -41,3 +42,5 @@ let rec affiche_expr e = | PrInt(e1) -> print_string "PrInt(";affiche_expr e1;print_string ")" | Var(x) -> print_string "Var(";print_string x;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)) + | App(e1,e2) -> aff_aux "App(" e1 e2 diff --git a/Rendu0/expr.ml b/Rendu0/expr.ml index 18847a4..e0f79b5 100644 --- a/Rendu0/expr.ml +++ b/Rendu0/expr.ml @@ -16,8 +16,10 @@ type expr = | PrInt of expr | Var of string | LetIn of string*expr*expr + | Fun of string*expr + | App of expr*expr -type valeur = VInt of int | VBool of bool +type valeur = VInt of int | VBool of bool | VFunc of string*expr type env = (string*valeur) list @@ -40,6 +42,7 @@ and intBoolOp op e1 e2 env = match (eval e1 env, eval e2 env) with and eval e env = match e with | Const(k) -> VInt k | BConst(b) -> VBool b + | Fun(v,e) -> VFunc(v,e) | Add(e1,e2) -> intIntOp ( + ) e1 e2 env | Mul(e1,e2) -> intIntOp ( * ) e1 e2 env | Min(e1,e2) -> intIntOp ( - ) e1 e2 env @@ -65,3 +68,6 @@ and eval e env = match e with | _ -> raise InvalidTypeException) | Var(v) -> readVar env v UnknownVariableException | 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) diff --git a/Rendu0/lexer.mll b/Rendu0/lexer.mll index da8349b..93048a6 100644 --- a/Rendu0/lexer.mll +++ b/Rendu0/lexer.mll @@ -31,5 +31,7 @@ rule token = parse (* la "fonction" aussi s'appelle token .. *) | "prInt" { PRINT } | "let" { LET } | "in" { IN } + | "fun" { FUN } + | "->" { MAPSTO } | ['a'-'z']+ as v { VAR (v) } | eof { raise Eof } (* fin du fichier *) diff --git a/Rendu0/parser.mly b/Rendu0/parser.mly index f7e6c25..4d4ad8b 100644 --- a/Rendu0/parser.mly +++ b/Rendu0/parser.mly @@ -11,6 +11,7 @@ open Expr (* rappel: dans expr.ml: %token VAR %token TRUE FALSE %token IF THEN ELSE +%token FUN MAPSTO %token LET IN %token PRINT %token BAND BOR @@ -20,10 +21,12 @@ open Expr (* rappel: dans expr.ml: %token EOL /* retour à la ligne */ %nonassoc LET IN +%nonassoc FUN MAPSTO %nonassoc IF THEN ELSE %left BAND BOR %left EQ %nonassoc GT LT GTE LTE +%nonassoc APP %left PLUS MINUS /* associativité gauche: a+b+c, c'est (a+b)+c */ %left TIMES /* associativité gauche: a*b*c, c'est (a*b)*c */ %nonassoc PRINT @@ -42,10 +45,10 @@ open Expr (* rappel: dans expr.ml: main: /* <- le point d'entrée (cf. + haut, "start") */ expression EOL { $1 } /* on veut reconnaître une expression */ - ; +; - expression: /* règles de grammaire pour les expressions */ +expression: /* règles de grammaire pour les expressions */ | INT { Const $1 } | VAR { Var $1 } | TRUE { BConst true } @@ -64,6 +67,16 @@ expression EOL { $1 } /* on veut reconnaître une expression */ | PRINT expression { PrInt($2) } | IF expression THEN expression ELSE expression { ITE($2,$4,$6)} | LET VAR EQ expression IN expression { LetIn($2,$4,$6) } + | FUN VAR MAPSTO expression { Fun($2,$4) } | MINUS expression %prec UMINUS { Min(Const 0, $2) } + | expression sexpr %prec APP { App($1,$2) } + ; + +sexpr: + | INT { Const $1 } + | VAR { Var $1 } + | TRUE { BConst true } + | FALSE { BConst false } + | LPAREN expression RPAREN { $2 } ;