diff options
-rw-r--r-- | tvix/eval/src/compiler.rs | 26 | ||||
-rw-r--r-- | tvix/eval/src/eval.rs | 6 | ||||
-rw-r--r-- | tvix/eval/src/main.rs | 11 | ||||
-rw-r--r-- | tvix/eval/src/tests/mod.rs | 4 |
4 files changed, 37 insertions, 10 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index c5ec664dc2cf..63a02f68c013 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -13,7 +13,7 @@ //! the code in this module, `debug_assert!` has been used to catch //! mistakes early during development. -use std::path::Path; +use std::path::{Path, PathBuf}; use crate::chunk::Chunk; use crate::errors::{Error, EvalResult}; @@ -35,6 +35,7 @@ pub struct CompilationResult { struct Compiler { chunk: Chunk, warnings: Vec<EvalWarning>, + root_dir: PathBuf, } impl Compiler { @@ -175,7 +176,11 @@ impl Compiler { buf } - rnix::value::Anchor::Relative => todo!("resolve relative to file location"), + rnix::value::Anchor::Relative => { + let mut buf = self.root_dir.clone(); + buf.push(path); + buf + } // This confusingly named variant is actually // angle-bracket lookups, which in C++ Nix desugar @@ -624,8 +629,23 @@ impl Compiler { } } -pub fn compile(ast: rnix::AST) -> EvalResult<CompilationResult> { +pub fn compile(ast: rnix::AST, location: Option<PathBuf>) -> EvalResult<CompilationResult> { + let mut root_dir = match location { + Some(dir) => Ok(dir), + None => std::env::current_dir().map_err(|e| { + Error::PathResolution(format!("could not determine current directory: {}", e)) + }), + }?; + + // If the path passed from the caller points to a file, the + // filename itself needs to be truncated as this must point to a + // directory. + if root_dir.is_file() { + root_dir.pop(); + } + let mut c = Compiler { + root_dir, chunk: Chunk::default(), warnings: vec![], }; diff --git a/tvix/eval/src/eval.rs b/tvix/eval/src/eval.rs index 31280e4cd197..903708f108b3 100644 --- a/tvix/eval/src/eval.rs +++ b/tvix/eval/src/eval.rs @@ -1,8 +1,10 @@ +use std::path::PathBuf; + use rnix::{self, types::TypedNode}; use crate::{errors::EvalResult, value::Value}; -pub fn interpret(code: &str) -> EvalResult<Value> { +pub fn interpret(code: &str, location: Option<PathBuf>) -> EvalResult<Value> { let ast = rnix::parse(code); let errors = ast.errors(); @@ -14,7 +16,7 @@ pub fn interpret(code: &str) -> EvalResult<Value> { println!("{}", ast.root().dump()); } - let result = crate::compiler::compile(ast)?; + let result = crate::compiler::compile(ast, location)?; println!("code: {:?}", result.chunk); for warning in result.warnings { diff --git a/tvix/eval/src/main.rs b/tvix/eval/src/main.rs index 0c4d082783e2..3d0c29688e6d 100644 --- a/tvix/eval/src/main.rs +++ b/tvix/eval/src/main.rs @@ -1,4 +1,8 @@ -use std::{env, fs, path::PathBuf, process}; +use std::{ + env, fs, + path::{Path, PathBuf}, + process, +}; use rustyline::{error::ReadlineError, Editor}; @@ -18,8 +22,9 @@ fn main() { fn run_file(file: &str) { let contents = fs::read_to_string(file).expect("failed to read the input file"); + let path = Path::new(file).to_owned(); - match tvix_eval::interpret(&contents) { + match tvix_eval::interpret(&contents, Some(path)) { Ok(result) => println!("=> {} :: {}", result, result.type_of()), Err(err) => eprintln!("{}", err), } @@ -53,7 +58,7 @@ fn run_prompt() { continue; } - match tvix_eval::interpret(&line) { + match tvix_eval::interpret(&line, None) { Ok(result) => { println!("=> {} :: {}", result, result.type_of()); rl.add_history_entry(line); diff --git a/tvix/eval/src/tests/mod.rs b/tvix/eval/src/tests/mod.rs index ca8c114ba320..313498eeb777 100644 --- a/tvix/eval/src/tests/mod.rs +++ b/tvix/eval/src/tests/mod.rs @@ -11,7 +11,7 @@ fn eval_okay_test(code_path: &str) { let code = std::fs::read_to_string(code_path).expect("should be able to read test code"); let exp = std::fs::read_to_string(exp_path).expect("should be able to read test expectation"); - let result = interpret(&code).expect("evaluation of eval-okay test should succeed"); + let result = interpret(&code, None).expect("evaluation of eval-okay test should succeed"); let result_str = format!("{}", result); assert_eq!( @@ -27,7 +27,7 @@ fn eval_okay_test(code_path: &str) { fn identity(code_path: &str) { let code = std::fs::read_to_string(code_path).expect("should be able to read test code"); - let result = interpret(&code).expect("evaluation of identity test should succeed"); + let result = interpret(&code, None).expect("evaluation of identity test should succeed"); let result_str = format!("{}", result); assert_eq!( |