From 559245f1c534e9d42124fac61937e5ddb3f52a99 Mon Sep 17 00:00:00 2001 From: Mysaa Date: Mon, 24 Jan 2022 18:18:27 +0100 Subject: [PATCH] Ajout du let in. --- Rendu0/affichage.ml | 3 ++- Rendu0/expr.ml | 15 +++++++++++---- Rendu0/lexer.mll | 5 ++++- Rendu0/main.ml | 2 ++ Rendu0/parser.mly | 5 +++++ Rendu0/tests/letin.ml | 1 + Rendu0/tests/print.ml | 1 + 7 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 Rendu0/tests/letin.ml create mode 100644 Rendu0/tests/print.ml diff --git a/Rendu0/affichage.ml b/Rendu0/affichage.ml index 76b2dd8..7ba0c14 100644 --- a/Rendu0/affichage.ml +++ b/Rendu0/affichage.ml @@ -39,4 +39,5 @@ let rec affiche_expr e = print_string ")" end | 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 ")" diff --git a/Rendu0/expr.ml b/Rendu0/expr.ml index 5b01902..18847a4 100644 --- a/Rendu0/expr.ml +++ b/Rendu0/expr.ml @@ -14,15 +14,21 @@ type 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 = unit +type env = (string*valeur) list -let empty_env = () +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) @@ -57,4 +63,5 @@ and eval e env = match e with | 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) diff --git a/Rendu0/lexer.mll b/Rendu0/lexer.mll index f56f063..da8349b 100644 --- a/Rendu0/lexer.mll +++ b/Rendu0/lexer.mll @@ -28,5 +28,8 @@ rule token = parse (* la "fonction" aussi s'appelle token .. *) | "if" { IF } | "then" { THEN } | "else" { ELSE } - | "prInt" { PRINT } + | "prInt" { PRINT } + | "let" { LET } + | "in" { IN } + | ['a'-'z']+ as v { VAR (v) } | eof { raise Eof } (* fin du fichier *) diff --git a/Rendu0/main.ml b/Rendu0/main.ml index 844ab98..23866ce 100644 --- a/Rendu0/main.ml +++ b/Rendu0/main.ml @@ -49,6 +49,8 @@ let rec affiche_printexpr e env = begin (* le traitement d'une expression en entrée *) let execute e = begin + affiche_expr e; + print_newline(); affiche_printexpr e Expr.empty_env; print_newline(); let v = Expr.eval e Expr.empty_env in diff --git a/Rendu0/parser.mly b/Rendu0/parser.mly index 38243c6..f7e6c25 100644 --- a/Rendu0/parser.mly +++ b/Rendu0/parser.mly @@ -8,8 +8,10 @@ open Expr (* rappel: dans expr.ml: /* description des lexèmes, ceux-ci sont décrits (par vous) dans lexer.mll */ %token INT /* le lexème INT a un attribut entier */ +%token VAR %token TRUE FALSE %token IF THEN ELSE +%token LET IN %token PRINT %token BAND BOR %token EQ GT LT GTE LTE @@ -17,6 +19,7 @@ open Expr (* rappel: dans expr.ml: %token LPAREN RPAREN %token EOL /* retour à la ligne */ +%nonassoc LET IN %nonassoc IF THEN ELSE %left BAND BOR %left EQ @@ -44,6 +47,7 @@ expression EOL { $1 } /* on veut reconnaître une expression */ expression: /* règles de grammaire pour les expressions */ | INT { Const $1 } + | VAR { Var $1 } | TRUE { BConst true } | FALSE { BConst false } | LPAREN expression RPAREN { $2 } /* on récupère le deuxième élément */ @@ -59,6 +63,7 @@ expression EOL { $1 } /* on veut reconnaître une expression */ | expression BOR expression { Bor($1,$3) } | PRINT expression { PrInt($2) } | IF expression THEN expression ELSE expression { ITE($2,$4,$6)} + | LET VAR EQ expression IN expression { LetIn($2,$4,$6) } | MINUS expression %prec UMINUS { Min(Const 0, $2) } ; diff --git a/Rendu0/tests/letin.ml b/Rendu0/tests/letin.ml new file mode 100644 index 0000000..af9df36 --- /dev/null +++ b/Rendu0/tests/letin.ml @@ -0,0 +1 @@ +let x=3 in (let y=x+2 in x+y) diff --git a/Rendu0/tests/print.ml b/Rendu0/tests/print.ml new file mode 100644 index 0000000..8d709c0 --- /dev/null +++ b/Rendu0/tests/print.ml @@ -0,0 +1 @@ +4+5+(prInt 42+1)