slosh/
main.rs

1pub mod config;
2
3use crate::config::VERSION_STRING;
4use bridge_adapters::add_builtin;
5use compile_state::state::SloshVm;
6use slosh_lib::run;
7use slvm::{VMError, VMResult, Value};
8use std::process;
9
10fn modify_vm(vm: &mut SloshVm) {
11    add_builtin(
12        vm,
13        "version",
14        version,
15        "Return the software version string.",
16    );
17}
18
19fn version(vm: &mut SloshVm, registers: &[Value]) -> VMResult<Value> {
20    if !registers.is_empty() {
21        return Err(VMError::new_compile("version: requires no argument"));
22    }
23    Ok(vm.alloc_string(VERSION_STRING.to_string()))
24}
25
26fn main() {
27    let exit_code = run(modify_vm);
28    process::exit(exit_code)
29}
30
31#[cfg(test)]
32mod tests {
33    use compiler_test_utils::exec;
34    use slosh_lib::{ENV, set_builtins_and_shell_builtins, set_initial_load_path};
35    use slvm::{Value, from_i56};
36    use std::fs::{File, create_dir_all};
37    use std::io::Write;
38    use std::ops::DerefMut;
39    use temp_env;
40    use tempfile::TempDir;
41
42    #[test]
43    fn test_load_path_no_home() {
44        // create home dir
45        let tmp_dir = TempDir::with_prefix("test_load_path").unwrap();
46        let home_dir = tmp_dir.path().to_str();
47        let home_path = home_dir.unwrap().to_string();
48
49        let tmp_0 = tmp_dir.path().join("tmp_0");
50        let tmp_1 = tmp_dir.path().join("tmp_1");
51        {
52            // create a dir with an add fcn that adds 1 in  add.slosh
53            create_dir_all(tmp_0.clone()).unwrap();
54            let file_0 = tmp_0.as_path().join("add.slosh");
55            let mut file_0 = File::create(file_0).unwrap();
56            writeln!(file_0, "(def add (fn (x) (+ 1 x)))").unwrap();
57            File::flush(&mut file_0).unwrap();
58
59            // create a dir with an add fcn that adds 2 in add.slosh
60            create_dir_all(tmp_1.clone()).unwrap();
61            let file_1 = tmp_1.as_path().join("add.slosh");
62            let mut file_1 = File::create(file_1).unwrap();
63            writeln!(file_1, "(def add (fn (x) (+ 2 x)))").unwrap();
64            File::flush(&mut file_1).unwrap();
65        }
66
67        let v = temp_env::with_var("HOME", home_dir, || {
68            ENV.with(|env| {
69                let mut vm = env.borrow_mut();
70                set_builtins_and_shell_builtins(vm.deref_mut());
71                set_initial_load_path(
72                    vm.deref_mut(),
73                    vec![
74                        &home_path,
75                        tmp_0.to_str().unwrap().as_ref(),
76                        tmp_1.to_str().unwrap().as_ref(),
77                    ],
78                );
79                _ = exec(vm.deref_mut(), "(load \"add.slosh\")");
80                let v = exec(vm.deref_mut(), "(add 1)");
81                match v {
82                    Value::Int(i) => from_i56(&i),
83                    _ => {
84                        panic!("Value should be an integer");
85                    }
86                }
87            })
88        });
89        assert_eq!(v, 2i64);
90    }
91}