-
Notifications
You must be signed in to change notification settings - Fork 0
/
occ.ml
66 lines (54 loc) · 1.83 KB
/
occ.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
open LibUtil
let llvm_backend = ref false
module type BACKEND = sig
type cunit
val codegen : Ll.prog -> cunit
val write : out_channel -> cunit -> unit
end
module DefaultBackend : BACKEND = struct
type cunit = Cunit.cunit
let codegen = Phase2.compile_prog
let write oc cu = Cunit.output_cunit cu oc
end
module LLVMBackend : BACKEND =
struct
type cunit = Buffer.t
let codegen prog =
let cmd = "llc -march x86 -O0 - -o -" in
let sprintf = Printf.sprintf in
let i, o = Unix.open_process cmd in
let () = Ll.serialize_prog prog (output_string o) in
let () = close_out o in
let buf = Buffer.of_channel i in
(match Unix.close_process (i, o) with
| Unix.WEXITED i when i <> 0 ->
raise (Platform.AsmLinkError (cmd, sprintf "Stopped with %d." i))
| Unix.WSIGNALED i ->
raise (Platform.AsmLinkError (cmd, sprintf "Signaled with %d." i))
| Unix.WSTOPPED i ->
raise (Platform.AsmLinkError (cmd, sprintf "Stopped with %d." i))
| _ -> ());
buf
let write = Buffer.output_buffer
end
module Make (Backend : BACKEND) : sig
val compile : Lexing.lexbuf -> Backend.cunit
val compile_file : string -> string -> unit
val write : out_channel -> Backend.cunit -> unit
end = struct
let compile (buf : Lexing.lexbuf) : Backend.cunit =
try
Backend.codegen (Phase1.compile_prog (Parser.toplevel Lexer.token buf))
with Parsing.Parse_error ->
failwith (Printf.sprintf "Parse error at %s."
(Range.string_of_range (Lexer.lex_range buf)))
let write = Backend.write
let compile_file ifile ofile =
let ich = open_in ifile in
let och = open_out ofile in
let buf = Lexing.from_channel ich in
Lexer.reset_lexbuf ifile buf;
Backend.write och (compile buf);
close_in ich;
close_out och
end