This repository has been archived on 2024-01-18. You can view files and clone it, but cannot push or open issues or pull requests.
compilation/cours/cours-02/marthe.ml
Adrien Guatto abf23ab803 Cours 02
2023-09-27 18:49:08 +02:00

55 lines
1.8 KiB
OCaml

open Ast
let parse lexbuf = Parser.phrase Lexer.token lexbuf
let interpret : e -> int =
(* Le paramètre [env] est une liste associative contenant la valeur associée
aux indices de sommation.
La fonction d'évaluation est définie par cas sur la forme de l'arbre. *)
let rec aux env = function
(* Pour évaluer une expression de la forme "e1 + e2", on évalue [e1] en un
entier, on évalue [e2] en un autre entier, puis on fait la somme des deux
entiers. *)
| EPlus (e1, e2) -> aux env e1 + aux env e2
(* Même raisonnement pour la multiplication. *)
| EMult (e1, e2) -> aux env e1 * aux env e2
(* Une expression qui est un entier s'évalue en cet entier. *)
| EInt x -> x
(* Pour évaluer une expression de la forme "sum (x, start, stop, body)". *)
| ESum (x, start, stop, body) ->
(* On évalue [start]. *)
let vstart = aux env start
(* On évalue [stop]. *)
and vstop = aux env stop
in
(* On itère sur toutes les valeurs [i] de [start] à [stop] et on accumule
les sommes intermédiaires dans la variable [accu]. *)
let rec iter i accu =
if i > vstop then
accu
else
(* L'évaluation de [body] se fait dans un environnement où l'indice
[x] est associé à la valeur [i]. *)
iter (i + 1) (accu + aux ((x, i) :: env) body)
in
iter vstart 0
(* Une expression qui est variable s'évalue en la valeur associée à cette
variable dans l'environnement. *)
| EVar x ->
List.assoc x env
in
aux []
let process filename =
let cin = open_in filename in
let ast = parse (Lexing.from_channel cin) in
let x = interpret ast in
Printf.printf "Result: %d\n%!" x
let main =
Array.iteri (fun i filename -> if i >= 1 then process filename) Sys.argv