Properly detect import cycles at runtime.

This commit is contained in:
Jeremy Wall 2019-11-02 15:52:51 -05:00
parent 31d76ec733
commit ad97dfca57
3 changed files with 9 additions and 7 deletions

View File

@ -177,7 +177,12 @@ impl Builtins {
if let &Value::P(Str(ref path)) = val.as_ref() { if let &Value::P(Str(ref path)) = val.as_ref() {
// TODO(jwall): A bit hacky we should probably change import stacks to be pathbufs. // TODO(jwall): A bit hacky we should probably change import stacks to be pathbufs.
let normalized = decorate_error!(path_pos => self.normalize_path(base_path, false, path))?; let normalized = decorate_error!(path_pos => self.normalize_path(base_path, false, path))?;
// first we chack the cache
let path = normalized.to_string_lossy().to_string(); let path = normalized.to_string_lossy().to_string();
if let Some(val) = env.borrow().get_cached_path_val(&path) {
stack.push((val, path_pos));
return Ok(());
}
if import_stack if import_stack
.iter() .iter()
.find(|p| *p == &path) .find(|p| *p == &path)
@ -197,13 +202,15 @@ impl Builtins {
let op_pointer = let op_pointer =
decorate_error!(path_pos => env.borrow_mut().get_ops_for_path(&normalized))?; decorate_error!(path_pos => env.borrow_mut().get_ops_for_path(&normalized))?;
// TODO(jwall): What if we don't have a base path? // TODO(jwall): What if we don't have a base path?
let mut vm = VM::with_pointer(op_pointer, env.clone(), normalized.parent().unwrap()); let mut vm = VM::with_pointer(op_pointer, env.clone(), normalized.parent().unwrap())
.with_import_stack(import_stack.clone());
vm.run()?; vm.run()?;
let result = Rc::new(vm.symbols_to_tuple(true)); let result = Rc::new(vm.symbols_to_tuple(true));
env.borrow_mut().update_path_val(&path, result.clone()); env.borrow_mut().update_path_val(&path, result.clone());
stack.push((result, pos)); stack.push((result, pos));
} }
} }
import_stack.push(path.clone());
return Ok(()); return Ok(());
} }
return Err(Error::new(format!("Invalid Path {:?}", val), pos)); return Err(Error::new(format!("Invalid Path {:?}", val), pos));

View File

@ -842,7 +842,7 @@ where
} }
&C(List(ref elems, _)) => { &C(List(ref elems, _)) => {
for e in elems { for e in elems {
if dbg!(e) == dbg!(&right) { if dbg!(e) == &right {
self.push(Rc::new(P(Bool(true))), pos)?; self.push(Rc::new(P(Bool(true))), pos)?;
return Ok(()); return Ok(());
} }

View File

@ -108,11 +108,6 @@ impl BuildError {
fn render(&self, w: &mut fmt::Formatter) -> fmt::Result { fn render(&self, w: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref pos) = self.pos { if let Some(ref pos) = self.pos {
// FIXME(jwall): we should still be printing the file here.
let file = match pos.file {
Some(ref pb) => pb.to_string_lossy().to_string(),
None => "<eval>".to_string(),
};
write!(w, "{}: {} at {}", self.err_type, self.msg, pos,)?; write!(w, "{}: {} at {}", self.err_type, self.msg, pos,)?;
} else { } else {
write!(w, "{}: {}", self.err_type, self.msg)?; write!(w, "{}: {}", self.err_type, self.msg)?;