-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.ml
122 lines (103 loc) · 3.76 KB
/
main.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
open Expr
open Interpreteur
open Interpreteurmixte
open Compilateur
let compile e =
begin
affiche_prog e;
print_newline();
end
(* stdin désigne l'entrée standard (le clavier) *)
(* lexbuf est un canal ouvert sur stdin *)
let lexbuf c = Lexing.from_channel c
(* on enchaîne les tuyaux: lexbuf est passé à Lexer.token,
et le résultat est donné à Parser.main *)
let parse c = Parser.main Lexer.token (lexbuf c)
(* aide pour l'utilisation du programme *)
let print_help () =
print_string "./fouine [option] fichier \nOptions :\n -debug : pour afficher le programme en entrée\n -machine : Compile le programme et l'exécute\n -interm : affiche le programme compilé sans l'exécuter.\n\t\t\t./fouine -interm toto.code fichier.ml\n"
(* Affichage du code généré pour la machine à pile *)
let rec write_code code fd =
begin
match code with
[] -> ()
| (C k)::q -> Printf.fprintf fd "%s\n" ("C "^(string_of_int(k)));
write_code q fd;
| (A)::q -> Printf.fprintf fd "%s\n" "A";
write_code q fd;
| (M)::q -> Printf.fprintf fd "%s\n" "M";
write_code q fd;
| (S)::q -> Printf.fprintf fd "%s\n" "S";
write_code q fd;
| (P)::q -> Printf.fprintf fd "%s\n" "P";
write_code q fd;
| (LET x)::q -> Printf.fprintf fd "%s\n" ("LET "^x);
write_code q fd;
| (ACCESS x)::q -> Printf.fprintf fd "%s\n" ("ACCESS "^x);
write_code q fd;
| ENDLET::q -> Printf.fprintf fd "%s\n" "ENDLET";
write_code q fd;
end
(* Fonction pour l'option debug qui affiche simplement le programme*)
let opt_debug () =
try
let c = open_in Sys.argv.(2) in
let result = parse c in
affiche_prog result;
close_in c
with
| e -> print_string (Printexc.to_string e)
(* Fonction pour lancer l'interpréteur quand il n'y a pas d'options *)
let no_opt () =
try
let c = open_in Sys.argv.(1) in
let result = parse c in
let deb = ref [] in
match interp result deb with
VInt n -> print_int n;
print_newline(); flush stdout; close_in c
| VFun (x,body,l) -> affiche_prog (Function (x,body)); close_in c
| VFunR (x,body,l) -> affiche_prog (Function (x,body)); close_in c
| VRef _ -> print_string "A reference cannot be printed";
print_newline(); flush stdout; close_in c
| VErr _ -> close_in c; failwith("How did you manage to get an exception to be returned and not raised ?")
with | e -> (print_string (Printexc.to_string e))
(* Execute le programme sur la machine à pile *)
let opt_machine () =
try
let c = open_in Sys.argv.(2) in
let result = parse c in
let (b,progaexec) = purifier result in
let deb = ref [] in
match interpmixte progaexec deb with
VInt n -> print_int n;
print_newline(); flush stdout; close_in c
| VFun (x,body,l) -> affiche_prog (Function (x,body)); close_in c
| VFunR (x,body,l) -> affiche_prog (Function (x,body)); close_in c
| VRef _ -> print_string "A reference cannot be printed";
print_newline(); flush stdout; close_in c
| VErr _ -> close_in c; failwith("How did you manage to get an exception to be returned and not raised ?")
with | e -> (print_string (Printexc.to_string e))
(* Option qui affiche le code de la machine à pile *)
let opt_interm () =
try
let c = open_in Sys.argv.(3) and cp = open_out Sys.argv.(2) in
let result = parse c in
let code = (Compilateur.compile result) in
begin
(write_code code cp);
close_in c;
close_out cp
end
with | e -> (print_string (Printexc.to_string e))
(* Point d'entrée du programme *)
let main () =
try
match Sys.argv.(1) with
| "-debug" -> opt_debug()
| "-machine" -> opt_machine()
| "-interm" -> opt_interm()
| _ -> no_opt ()
with
| _ -> print_help ()
let _ = main()