-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcnet.ml
78 lines (68 loc) · 3 KB
/
cnet.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
module U = Utils;;
type action =Scanner | Ast | LLVM_IR | Sast | Compile
let () =
let action = ref Compile in
let set_action a () = action := a in
let speclist = [
("-t", Arg.Unit (set_action Scanner), "Print the Scanner Tokens");
("-a", Arg.Unit (set_action Ast), "Print the AST");
("-s", Arg.Unit (set_action Sast), "Print the SAST");
("-l", Arg.Unit (set_action LLVM_IR), "Print the generated LLVM IR");
("-c", Arg.Unit (set_action Compile),
"Check and print the generated LLVM IR (default)");
] in
let usage_msg = "usage: ./cnet.native [-a|-s|-l|-c|-t] [file.cnet]" in
let channel = ref stdin in
Arg.parse speclist (fun filename -> channel := open_in filename) usage_msg;
let lexbuf = Lexing.from_channel !channel in
try
(***************************************************************************
Scanner
**************************************************************************)
let _ = match !action with
Scanner ->
let token_string_list =
let rec next accu =
match Scanner.tokenize lexbuf with
| Parser.EOF -> List.rev (Scanner_pp.pretty_print Parser.EOF :: accu)
| x -> next (Scanner_pp.pretty_print x :: accu)
in next []
in List.iter (fun x -> print_endline x) token_string_list; exit 0;
| _ -> () in
(***************************************************************************
AST
**************************************************************************)
let ast = Parser.program Scanner.tokenize lexbuf in
let _ = match !action with
Ast -> print_string (Ast.string_of_program ast); exit 0
| _ -> () in
(***************************************************************************
SAST
**************************************************************************)
let sast = Semant.check ast in
let _ = match !action with
| Sast -> print_string(Sast.string_of_sprogram sast); exit 0
| _ -> () in
(***************************************************************************
Codegen
**************************************************************************)
let llvm_module = Codegen.translate sast in
let _ = match !action with
LLVM_IR ->
print_string (Llvm.string_of_llmodule llvm_module); exit 0
| Compile -> Llvm_analysis.assert_valid_module llvm_module;
print_string (Llvm.string_of_llmodule llvm_module)
| _ -> ()
in
exit 0;
with
Parsing.Parse_error ->
let err_line = U.line_num lexbuf in
let spec_char = Lexing.lexeme lexbuf in
let _ = Printf.fprintf stderr "Syntax error on line %d near %s\n" err_line
spec_char in
exit 1
| Scanner.ScannerError msg ->
Printf.fprintf stderr "Scanner error: %s\n" msg; exit 1;
| Sast.SemanticError(msg, _) ->
Printf.fprintf stderr "Semantic error: %s\n" msg; exit 1;