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
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate nanoid;
mod data;
pub mod builtins;
pub mod call_stack;
pub mod cli_args;
pub mod codegen;
pub mod primes;
pub mod program;
pub mod runner;
pub mod snapshot;
pub mod util;
use dirs::home_dir;
use std::fs;
use std::path::Path;
pub use primes::{Calcit, CalcitItems};
pub fn load_core_snapshot() -> Result<snapshot::Snapshot, String> {
let bytes = include_bytes!("./cirru/calcit-core.cirru");
let core_content = String::from_utf8_lossy(bytes).to_string();
let core_data = cirru_edn::parse(&core_content)?;
snapshot::load_snapshot_data(core_data)
}
pub fn run_program(
init_fn: &str,
params: CalcitItems,
program_code: &program::ProgramCodeData,
) -> Result<Calcit, String> {
let (init_ns, init_def) = util::string::extract_ns_def(init_fn)?;
match runner::preprocess::preprocess_ns_def(&init_ns, &init_def, &program_code, &init_def, None) {
Ok(_) => (),
Err(failure) => {
println!("\nfailed preprocessing, {}", failure);
call_stack::display_stack(&failure)?;
return Err(failure);
}
}
match program::lookup_evaled_def(&init_ns, &init_def) {
None => Err(format!("entry not initialized: {}/{}", init_ns, init_def)),
Some(entry) => match entry {
Calcit::Fn(_, f_ns, _, def_scope, args, body) => {
let result = runner::run_fn(¶ms, &def_scope, &args, &body, &f_ns, &program_code);
match result {
Ok(v) => Ok(v),
Err(failure) => {
println!("\nfailed, {}", failure);
call_stack::display_stack(&failure)?;
Err(failure)
}
}
}
_ => Err(format!("expected function entry, got: {}", entry)),
},
}
}
pub fn load_module(path: &str, base_dir: &Path) -> Result<snapshot::Snapshot, String> {
let mut file_path = String::from(path);
if file_path.ends_with('/') {
file_path.push_str("compact.cirru");
}
let fullpath: String = if file_path.starts_with("./") {
let new_path = base_dir.join(file_path);
new_path.to_str().unwrap().to_string()
} else if file_path.starts_with('/') {
file_path
} else {
match home_dir() {
Some(buf) => {
let home = buf.as_path();
let p = home.join(".config/calcit/modules/").join(file_path);
p.to_str().unwrap().to_string()
}
None => return Err(String::from("failed to load $HOME")),
}
};
println!("loading module: {}", fullpath);
let content = fs::read_to_string(&fullpath).expect(&format!("expected Cirru snapshot {:?}", fullpath));
let data = cirru_edn::parse(&content)?;
let snapshot = snapshot::load_snapshot_data(data)?;
Ok(snapshot)
}