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 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_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_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}