74 lines
3.0 KiB
OCaml

open Expr
open Affichage
(* "incantations" qu'il n'est pas nécessaire de comprendre dans un premier
temps : on récupère l'entrée, dans un fichier ou sur le clavier *)
let nom_fichier = ref ""
let recupere_entree () =
Arg.parse [] (fun s -> nom_fichier := s) "";
try
let where_from = match !nom_fichier with
| "" -> stdin
| s -> open_in s in
let lexbuf = Lexing.from_channel where_from in
let parse () = Parser.main Lexer.token lexbuf in
parse ()
with e -> (Printf.printf "problème de saisie\n"; raise e)
(* mettre à true et recompiler si l'on veut voir l'exécution pas à pas de l'automate *)
let trace = ref false
let _ = Stdlib.Parsing.set_trace !trace
let rec affiche_printexpr e env = begin
match e with
| Add(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| Mul(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| Min(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| Eq(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| Gt(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| Lt(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| Gte(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| Lte(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| Band(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| Bor(e1,e2) -> affiche_printexpr e1 env;affiche_printexpr e2 env
| ITE(ec,e1,e2) -> affiche_printexpr ec env;affiche_printexpr e1 env;affiche_printexpr e2 env
| PrInt (e) -> (match (eval e env) with
| VInt(k) -> print_int k
| x -> raise (InvalidTypeException ("Int",x)));affiche_printexpr e env
| LetIn(v,e0,e) -> affiche_printexpr e0 env;affiche_printexpr e (let x=(eval e0 env) in if v="_" then env else (v,x)::env)
| App(e0,e1) -> affiche_printexpr e0 env;(match (eval e0 env) with
| VFunc(v,e) -> affiche_printexpr (LetIn(v,e1,e)) env (* On utilise l'équivalence (fun x->e) y <=> let x=y in e *)
| x -> raise (InvalidTypeException ("Func",x)))
| Const(_) | BConst(_) | Fun (_,_) | Var(_) -> ()
end
(* le traitement d'une expression en entrée *)
let execute e =
try
begin
affiche_expr e;
print_newline ();
affiche_printexpr e Expr.empty_env;
print_newline ();
let v = Expr.eval e Expr.empty_env in
affiche_val v;
print_newline ()
end
with
| InvalidTypeException(expected, valeur) -> print_string "La valeur ";affiche_val valeur;print_string " a été donnée alors que on souhaitait avoir le type ";print_string expected;print_newline ()
| UnknownVariableException(varname, env) -> print_string "Impossible de trouver la variable '";print_string varname;print_string "' dans l'environnement ";dump_env env;print_newline ()
(* la boucle principale *)
let calc () =
try
let saisie = recupere_entree () in
execute saisie; flush stdout
with e -> raise e
let _ = calc()