74 lines
3.0 KiB
OCaml
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()
|