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
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

View File

@ -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)

View File

@ -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 *)

View File

@ -11,6 +11,7 @@ open Expr (* rappel: dans expr.ml:
%token <string> 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 }
;