Skip to content

Commit

Permalink
check load path
Browse files Browse the repository at this point in the history
  • Loading branch information
gpwclark committed Feb 8, 2024
1 parent 1777a98 commit 80daaae
Show file tree
Hide file tree
Showing 4 changed files with 286 additions and 100 deletions.
111 changes: 108 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions slosh/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ glob = "0.3"
[dev-dependencies]
regex = "1.10.2"
lazy_static = "1.4.0"
tempdir = "0.3.7"
temp-env = "0.3.6"

[build-dependencies]
chrono = "0.4.7"
Expand Down
106 changes: 57 additions & 49 deletions slosh/src/load_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,55 +63,7 @@ pub(crate) fn load_internal(vm: &mut SloshVm, name: &'static str) -> VMResult<Va
let fname = if fs::metadata::<&Path>(name.as_ref()).is_ok() {
Ok(Cow::Borrowed(name))
} else {
let i_g = vm.intern("*load-path*");
if let Some(g) = vm.global_intern_slot(i_g) {
if let Value::Vector(h) = vm.get_global(g) {
let paths = vm.get_vector(h);
let mut found = None;
for path in paths {
match path {
Value::StringConst(i) => {
let mut p = PathBuf::new();
p.push(vm.get_interned(*i));
p.push(name);
if p.exists() {
if let Ok(p) = p.into_os_string().into_string() {
found = Some(p.into());
break;
}
}
}
Value::String(h) => {
let mut p = PathBuf::new();
p.push(vm.get_string(*h));
p.push(name);
if p.exists() {
if let Ok(p) = p.into_os_string().into_string() {
found = Some(p.into());
break;
}
}
}
_ => {}
}
}
if let Some(p) = found {
Ok(p)
} else {
Err(VMError::new(
"io",
format!("{name}: not found on *load-path*!"),
))
}
} else {
Err(VMError::new(
"io",
format!("{name}: *load-path* not a vector!"),
))
}
} else {
Err(VMError::new("io", format!("{name}: *load-path* not set!")))
}
find_file_in_load_path(vm, name)
};
let mut reader = match fname {
Ok(fname) => match std::fs::File::open(&*fname) {
Expand Down Expand Up @@ -152,6 +104,62 @@ pub(crate) fn load_internal(vm: &mut SloshVm, name: &'static str) -> VMResult<Va
Ok(last)
}

/// Find file name in global variable *load-path*.
///
/// *load-path* is a vector of paths and the paths are searched in index order
/// for the file name of the path to be loaded.
fn find_file_in_load_path<'a, 'b>(vm: &'a mut SloshVm, name: &'b str) -> VMResult<Cow<'a, str>> {
let i_g = vm.intern("*load-path*");
if let Some(g) = vm.global_intern_slot(i_g) {
if let Value::Vector(h) = vm.get_global(g) {
let paths = vm.get_vector(h);
let mut found = None;
for path in paths {
match path {
Value::StringConst(i) => {
let mut p = PathBuf::new();
p.push(vm.get_interned(*i));
p.push(name);
if p.exists() && !p.is_dir() {
if let Ok(p) = p.into_os_string().into_string() {
found = Some(p.into());
break;
}
}
}
Value::String(h) => {
let mut p = PathBuf::new();
p.push(vm.get_string(*h));
p.push(name);
if p.exists() && !p.is_dir() {
if let Ok(p) = p.into_os_string().into_string() {
found = Some(p.into());
break;
}
}
}
_ => {}
}
}
if let Some(p) = found {
Ok(p)
} else {
Err(VMError::new(
"io",
format!("{name}: not found on *load-path*!"),
))
}
} else {
Err(VMError::new(
"io",
format!("{name}: *load-path* not a vector!"),
))
}
} else {
Err(VMError::new("io", format!("{name}: *load-path* not set!")))
}
}

fn load(vm: &mut SloshVm, registers: &[Value]) -> VMResult<Value> {
if registers.len() != 1 {
return Err(VMError::new_compile(
Expand Down
Loading

0 comments on commit 80daaae

Please sign in to comment.