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