From 273ba73754e9b10f768830d5a6835bf3d14e0d8a Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Sun, 9 Oct 2022 23:46:51 -0400 Subject: feat(tvix/eval): Initial resolution of `<...>` paths This commit implements (lazy) resolution of `<...>` paths via either the NIX_PATH environment variable, or the -I command-line flag - both handled via EvalOptions. As a result, EvalOptions can no longer derive Copy, meaning we have to clone it at each line of the repl - this is probably not a huge deal as repl performance is not exactly an inner loop and we're not cloning very much. Internally, this works by creating a thunk which pushes a constant containing the string inside the brackets to the stack, then a new opcode to resolve that path via the `NixPath`. To get that opcode to work, we now have to pass in the NixPath when constructing the VM. This (intentionally) leaves out proper implementation of path resolution via `findFile` (cppnix just calls whatever identifier called findFile is in scope!!!) as that's widely considered a bit of a misfeature, but if we do decide to implement that down the road it likely wouldn't be more than a few extra ops within the thunk introduced here. Change-Id: Ibc979b7e425b65cbe88599940520239a4a10cee2 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6918 Autosubmit: grfn Reviewed-by: tazjin Tested-by: BuildkiteCI --- tvix/eval/src/compiler/mod.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'tvix/eval/src/compiler/mod.rs') diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index 941b945a8bb6..cfb0ee64a6d8 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -188,7 +188,7 @@ impl Compiler<'_> { fn compile(&mut self, slot: LocalIdx, expr: &ast::Expr) { match expr { ast::Expr::Literal(literal) => self.compile_literal(literal), - ast::Expr::Path(path) => self.compile_path(path), + ast::Expr::Path(path) => self.compile_path(slot, path), ast::Expr::Str(s) => self.compile_str(slot, s), ast::Expr::UnaryOp(op) => self.compile_unary_op(slot, op), @@ -249,7 +249,7 @@ impl Compiler<'_> { self.emit_constant(value, node); } - fn compile_path(&mut self, node: &ast::Path) { + fn compile_path(&mut self, slot: LocalIdx, node: &ast::Path) { // TODO(tazjin): placeholder implementation while waiting for // https://github.com/nix-community/rnix-parser/pull/96 @@ -274,13 +274,24 @@ impl Compiler<'_> { let mut buf = self.root_dir.clone(); buf.push(&raw_path); buf - } else { + } else if raw_path.starts_with('<') { // TODO: decide what to do with findFile + if raw_path.len() == 2 { + return self.emit_error( + node, + ErrorKind::PathResolution("Empty <> path not allowed".into()), + ); + } + let path = &raw_path[1..(raw_path.len() - 1)]; + // Make a thunk to resolve the path (without using `findFile`, at least for now?) + return self.thunk(slot, node, move |c, _| { + c.emit_constant(path.into(), node); + c.push_op(OpCode::OpFindFile, node); + }); + } else { self.emit_error( node, - ErrorKind::NotImplemented( - "other path types (e.g. <...> lookups) not yet implemented", - ), + ErrorKind::NotImplemented("other path types not yet implemented"), ); return; }; -- cgit 1.4.1