1use super::translate_files;
2use super::BasicError;
3use super::DefaultHandler;
4use super::Handler;
5use super::Loader;
6use super::RcStr;
7use super::Source;
8use super::Val;
9use super::Vm;
10
11pub fn main() {
12 let mut loader = Loader::new();
13 let mut module_name: Option<RcStr> = None;
14 let mut state = State::Normal;
15 let mut test_flag = false;
16
17 for arg in std::env::args() {
18 let arg: &str = &arg;
19
20 match &state {
21 State::Normal => match arg {
22 "-m" => state = State::Module,
23 "-t" => test_flag = true,
24 _ => loader.add_source_root(arg),
25 },
26 State::Module => {
27 module_name = Some(arg.to_owned().into());
28 state = State::Normal;
29 }
30 }
31 }
32
33 let module_name = if let Some(module_name) = module_name {
34 module_name
35 } else {
36 eprintln!("Start module name not specified");
37 std::process::exit(1);
38 };
39
40 let result = if test_flag {
41 run_tests(&mut loader, &module_name)
42 } else {
43 run(&mut loader, &module_name)
44 };
45
46 match result {
47 Ok(()) => {}
48 Err(error) => {
49 eprintln!("{}", error.format());
50 std::process::exit(1);
51 }
52 }
53}
54
55fn run(loader: &mut Loader, module_name: &RcStr) -> Result<(), BasicError> {
56 let files = loader.load(&module_name)?;
57 let code = translate_files(files)?;
58 let mut vm = Vm::new(DefaultHandler);
59 match vm.exec(&code) {
60 Ok(_) => Ok(()),
61 Err(error) => Err(BasicError {
62 marks: vm.trace().clone(),
63 message: format!("{}", error),
64 help: None,
65 }),
66 }
67}
68
69fn run_tests(loader: &mut Loader, module_name: &RcStr) -> Result<(), BasicError> {
70 use std::fmt::Write;
71 let child_modules = loader.list_child_modules(module_name)?;
72 let mut test_src = String::new();
73 let test_out = &mut test_src;
74 let mut test_prefixes = Vec::new();
75
76 for child_module in child_modules {
77 writeln!(test_out, "import {}", child_module).unwrap();
78 test_prefixes.push(format!("{}#", child_module).into());
79 }
80
81 loader.add_source(
82 Source {
83 name: "[test]".into(),
84 data: test_src.into(),
85 }
86 .into(),
87 );
88
89 let files = loader.load(&"[test]".into())?;
90 let code = translate_files(files)?;
91 let mut vm = Vm::new(DefaultHandler);
92
93 println!("testing {}", module_name);
94 let r = vm.exec_and_run_tests(&code, &test_prefixes);
95 err_trace(&mut vm, r)
96}
97
98fn err_trace<H: Handler, T>(vm: &mut Vm<H>, r: Result<T, Val>) -> Result<T, BasicError> {
99 match r {
100 Ok(t) => Ok(t),
101 Err(error) => Err(BasicError {
102 marks: vm.trace().clone(),
103 message: format!("{}", error),
104 help: None,
105 }),
106 }
107}
108
109enum State {
110 Normal,
111 Module,
112}