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
extern crate ansi_term;
extern crate getopts;
extern crate itertools;
extern crate jcompilerlib;
extern crate llvm_sys;
extern crate matches;
extern crate quickcheck;
extern crate rand;
extern crate regex;
extern crate tempfile;
use getopts::Options;
use jcompilerlib::compiler;
use std::env;
fn main() {
let args: Vec<_> = env::args().collect();
let mut opts = Options::new();
opts.optflag("h", "help", "print usage");
opts.optflag("v", "version", "print jcompiler version");
opts.optflag("", "verbose", "print AST, IR, etc.");
opts.optflag("m", "mem-usage", "binary will print memory usage");
opts.optopt("", "llvm-opt", "LLVM optimization level (0 to 3)", "LVL");
opts.optopt(
"",
"strip",
"strip symbols from the binary (default: yes)",
"yes|no",
);
let default_triple_cstring = compiler::get_default_target_triple();
let default_triple = default_triple_cstring.to_str().unwrap();
opts.optopt(
"",
"target",
&format!("LLVM target triple (default: {})", default_triple),
"TARGET",
);
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(_) => {
jcompilerlib::print_usage(&args[0], opts);
std::process::exit(1);
}
};
if matches.opt_present("h") {
jcompilerlib::print_usage(&args[0], opts);
return;
}
if matches.opt_present("v") {
println!("jcompiler {}", env!("CARGO_PKG_VERSION"));
return;
}
if matches.free.len() != 1 {
jcompilerlib::print_usage(&args[0], opts);
std::process::exit(1);
}
let llvm_opt_level: u8 = match matches.opt_str("llvm-opt") {
Some(lvlstr) => match lvlstr.parse::<u8>() {
Ok(n) if n <= 3 => n,
_ => {
println!("Unrecognized choice \"{}\" for --llvm-opt; need \"0\", \"1\", \"2\", or \"3\".", lvlstr);
return;
}
},
_ => 0,
};
let do_strip = match matches.opt_str("strip") {
Some(ans) => match &ans[..] {
"yes" => true,
"no" => false,
_ => {
println!(
"Unrecognized choice \"{}\" for --strip; need \"yes\" or \"no\".",
ans
);
return;
}
},
_ => true,
};
match jcompilerlib::compile(
&matches.free[0],
matches.opt_str("target"),
llvm_opt_level,
do_strip,
matches.opt_present("mem-usage"),
matches.opt_present("verbose"),
None,
) {
Ok(_) => {}
Err(e) => {
eprintln!("{}", e);
std::process::exit(2);
}
};
}