Ajout des fonctions. Pratique pour faire du fonctionnel.

This commit is contained in:
Mysaa 2022-01-24 19:45:45 +01:00
parent 559245f1c5
commit bd7489bf59
Signed by: Mysaa
GPG Key ID: 7054D5D6A90F084F
4 changed files with 29 additions and 5 deletions

View File

@ -1,12 +1,13 @@
open Expr open Expr
let 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
(* fonction d'affichage *) (* fonction d'affichage *)
let rec 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;
@ -41,3 +42,5 @@ let rec affiche_expr e =
| PrInt(e1) -> print_string "PrInt(";affiche_expr e1;print_string ")" | PrInt(e1) -> print_string "PrInt(";affiche_expr e1;print_string ")"
| Var(x) -> print_string "Var(";print_string x;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 ")" | 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

View File

@ -16,8 +16,10 @@ type expr =
| PrInt of expr | PrInt of expr
| Var of string | Var of string
| LetIn of string*expr*expr | 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 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 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)
| 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
@ -65,3 +68,6 @@ and eval e env = match e with
| _ -> raise InvalidTypeException) | _ -> raise InvalidTypeException)
| Var(v) -> readVar env v UnknownVariableException | Var(v) -> readVar env v UnknownVariableException
| 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
| VFunc(v,e) -> eval (LetIn(v,e1,e)) env (* On utilise l'équivalence (fun x->e) y <=> let x=y in e *)
| _ -> raise InvalidTypeException)

View File

@ -31,5 +31,7 @@ rule token = parse (* la "fonction" aussi s'appelle token .. *)
| "prInt" { PRINT } | "prInt" { PRINT }
| "let" { LET } | "let" { LET }
| "in" { IN } | "in" { IN }
| "fun" { FUN }
| "->" { MAPSTO }
| ['a'-'z']+ as v { VAR (v) } | ['a'-'z']+ as v { VAR (v) }
| eof { raise Eof } (* fin du fichier *) | eof { raise Eof } (* fin du fichier *)

View File

@ -11,6 +11,7 @@ open Expr (* rappel: dans expr.ml:
%token <string> VAR %token <string> VAR
%token TRUE FALSE %token TRUE FALSE
%token IF THEN ELSE %token IF THEN ELSE
%token FUN MAPSTO
%token LET IN %token LET IN
%token PRINT %token PRINT
%token BAND BOR %token BAND BOR
@ -20,10 +21,12 @@ open Expr (* rappel: dans expr.ml:
%token EOL /* retour à la ligne */ %token EOL /* retour à la ligne */
%nonassoc LET IN %nonassoc LET IN
%nonassoc FUN MAPSTO
%nonassoc IF THEN ELSE %nonassoc IF THEN ELSE
%left BAND BOR %left BAND BOR
%left EQ %left EQ
%nonassoc GT LT GTE LTE %nonassoc GT LT GTE LTE
%nonassoc APP
%left PLUS MINUS /* associativité gauche: a+b+c, c'est (a+b)+c */ %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 */ %left TIMES /* associativité gauche: a*b*c, c'est (a*b)*c */
%nonassoc PRINT %nonassoc PRINT
@ -42,10 +45,10 @@ open Expr (* rappel: dans expr.ml:
main: /* <- le point d'entrée (cf. + haut, "start") */ main: /* <- le point d'entrée (cf. + haut, "start") */
expression EOL { $1 } /* on veut reconnaître une expression */ 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 } | INT { Const $1 }
| VAR { Var $1 } | VAR { Var $1 }
| TRUE { BConst true } | TRUE { BConst true }
@ -64,6 +67,16 @@ expression EOL { $1 } /* on veut reconnaître une expression */
| PRINT expression { PrInt($2) } | PRINT expression { PrInt($2) }
| IF expression THEN expression ELSE expression { ITE($2,$4,$6)} | IF expression THEN expression ELSE expression { ITE($2,$4,$6)}
| LET VAR EQ expression IN expression { LetIn($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) } | 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 }
; ;