diff options
Diffstat (limited to 'tvix/eval')
-rw-r--r-- | tvix/eval/Cargo.toml | 11 | ||||
-rw-r--r-- | tvix/eval/src/eval.rs | 145 | ||||
-rw-r--r-- | tvix/eval/src/lib.rs | 2 | ||||
-rw-r--r-- | tvix/eval/src/main.rs | 106 |
4 files changed, 1 insertions, 263 deletions
diff --git a/tvix/eval/Cargo.toml b/tvix/eval/Cargo.toml index 1b24f6401343..e4282507d7ec 100644 --- a/tvix/eval/Cargo.toml +++ b/tvix/eval/Cargo.toml @@ -8,13 +8,8 @@ edition = "2021" [lib] name = "tvix_eval" -[[bin]] -name = "tvix-eval" -required-features = [ "repl" ] - [dependencies] smol_str = "0.1" -rustyline = { version = "10.0.0", optional = true } dirs = "4.0.0" path-clean = "0.1" tabwriter = "1.2" @@ -23,7 +18,6 @@ codemap = "0.1.3" codemap-diagnostic = "0.1.1" proptest = { version = "1.0.0", default_features = false, features = ["std", "alloc", "break-dead-code", "tempfile"], optional = true } test-strategy = { version = "0.2.1", optional = true } -clap = { version = "3.2.22", optional = true, features = ["derive", "env"] } serde = "1.0" serde_json = "1.0" regex = "1.6.0" @@ -39,15 +33,12 @@ itertools = "0.10.3" tempdir = "0.3.7" [features] -default = [ "repl", "impure", "arbitrary", "nix_tests", "backtrace_overflow" ] +default = [ "impure", "arbitrary", "nix_tests", "backtrace_overflow" ] # Enables running the Nix language test suite from the original C++ # Nix implementation (at version 2.3) against Tvix. nix_tests = [] -# Enables building the binary (tvix-eval REPL) -repl = [ "rustyline", "clap" ] - # Enables operations in the VM which depend on the ability to perform I/O impure = [] diff --git a/tvix/eval/src/eval.rs b/tvix/eval/src/eval.rs deleted file mode 100644 index bfd827e2ca5b..000000000000 --- a/tvix/eval/src/eval.rs +++ /dev/null @@ -1,145 +0,0 @@ -use std::path::PathBuf; - -use crate::{ - builtins::global_builtins, - errors::{Error, ErrorKind, EvalResult}, - nix_search_path::NixSearchPath, - observer::{DisassemblingObserver, NoOpObserver, TracingObserver}, - pretty_ast::pretty_print_expr, - value::Value, - SourceCode, -}; - -/// Runtime options for the Tvix interpreter -#[derive(Debug, Clone, Default)] -#[cfg_attr(feature = "repl", derive(clap::Parser))] -pub struct Options { - /// Dump the raw AST to stdout before interpreting - #[cfg_attr(feature = "repl", clap(long, env = "TVIX_DISPLAY_AST"))] - display_ast: bool, - - /// Dump the bytecode to stdout before evaluating - #[cfg_attr(feature = "repl", clap(long, env = "TVIX_DUMP_BYTECODE"))] - dump_bytecode: bool, - - /// Trace the runtime of the VM - #[cfg_attr(feature = "repl", clap(long, env = "TVIX_TRACE_RUNTIME"))] - trace_runtime: bool, - - /// Print warnings - #[cfg_attr( - feature = "repl", - clap(long, env = "TVIX_WARNINGS", default_value = "true") - )] - warnings: bool, - - /// A colon-separated list of directories to use to resolve `<...>`-style paths - #[cfg_attr(feature = "repl", clap(long, short = 'I', env = "NIX_PATH"))] - nix_search_path: Option<NixSearchPath>, - - #[cfg_attr(feature = "repl", clap(long))] - pub raw: bool, -} - -impl Options { - #[cfg(test)] - pub(crate) fn test_options() -> Options { - Options { - warnings: false, - ..Options::default() - } - } -} - -pub fn interpret(code: &str, location: Option<PathBuf>, options: Options) -> EvalResult<Value> { - let source = SourceCode::new(); - let file = source.add_file( - location - .as_ref() - .map(|p| p.to_string_lossy().to_string()) - .unwrap_or_else(|| "[tvix-repl]".into()), - code.into(), - ); - - let parsed = rnix::ast::Root::parse(code); - let errors = parsed.errors(); - - if !errors.is_empty() { - let err = Error { - kind: ErrorKind::ParseErrors(errors.to_vec()), - span: file.span, - }; - err.fancy_format_stderr(&source); - return Err(err); - } - - // If we've reached this point, there are no errors. - let root_expr = parsed - .tree() - .expr() - .expect("expression should exist if no errors occured"); - - if options.display_ast { - println!("{}", pretty_print_expr(&root_expr)); - } - - let builtins = crate::compiler::prepare_globals(Box::new(global_builtins(source.clone()))); - let result = if options.dump_bytecode { - crate::compiler::compile( - &root_expr, - location, - file.clone(), - builtins, - &mut DisassemblingObserver::new(source.clone(), std::io::stderr()), - ) - } else { - crate::compiler::compile( - &root_expr, - location, - file.clone(), - builtins, - &mut NoOpObserver::default(), - ) - }?; - - if options.warnings { - for warning in result.warnings { - warning.fancy_format_stderr(&source); - } - } - - for error in &result.errors { - error.fancy_format_stderr(&source); - } - - if let Some(err) = result.errors.last() { - return Err(err.clone()); - } - - let result = if options.trace_runtime { - crate::vm::run_lambda( - options.nix_search_path.unwrap_or_default(), - &mut TracingObserver::new(std::io::stderr()), - result.lambda, - ) - } else { - crate::vm::run_lambda( - options.nix_search_path.unwrap_or_default(), - &mut NoOpObserver::default(), - result.lambda, - ) - }; - - if let Err(err) = &result { - err.fancy_format_stderr(&source); - } - - result.map(|r| { - if options.warnings { - for warning in r.warnings { - warning.fancy_format_stderr(&source); - } - } - r.value - }) -} diff --git a/tvix/eval/src/lib.rs b/tvix/eval/src/lib.rs index 43a085108258..8697c752f392 100644 --- a/tvix/eval/src/lib.rs +++ b/tvix/eval/src/lib.rs @@ -16,7 +16,6 @@ mod builtins; mod chunk; mod compiler; mod errors; -mod eval; pub mod observer; mod opcode; mod pretty_ast; @@ -44,7 +43,6 @@ use std::sync::Arc; pub use crate::builtins::global_builtins; pub use crate::compiler::{compile, prepare_globals}; pub use crate::errors::{Error, ErrorKind, EvalResult}; -pub use crate::eval::{interpret, Options}; pub use crate::pretty_ast::pretty_print_expr; pub use crate::source::SourceCode; pub use crate::value::Value; diff --git a/tvix/eval/src/main.rs b/tvix/eval/src/main.rs deleted file mode 100644 index bef48d07a0c4..000000000000 --- a/tvix/eval/src/main.rs +++ /dev/null @@ -1,106 +0,0 @@ -use std::{fs, path::PathBuf}; - -use clap::Parser; -use rustyline::{error::ReadlineError, Editor}; -use tvix_eval::Value; - -#[derive(Parser)] -struct Args { - /// Path to a script to evaluate - script: Option<PathBuf>, - - #[clap(long, short = 'E')] - expr: Option<String>, - - #[clap(flatten)] - eval_options: tvix_eval::Options, -} - -fn main() { - let args = Args::parse(); - - if let Some(file) = args.script { - run_file(file, args.eval_options) - } else if let Some(expr) = args.expr { - let raw = args.eval_options.raw; - if let Ok(result) = tvix_eval::interpret(&expr, None, args.eval_options) { - println_result(&result, raw); - } - } else { - run_prompt(args.eval_options) - } -} - -fn run_file(mut path: PathBuf, eval_options: tvix_eval::Options) { - if path.is_dir() { - path.push("default.nix"); - } - let contents = fs::read_to_string(&path).expect("failed to read the input file"); - let raw = eval_options.raw; - match tvix_eval::interpret(&contents, Some(path), eval_options) { - Ok(result) => println_result(&result, raw), - Err(err) => eprintln!("{}", err), - } -} - -fn println_result(result: &Value, raw: bool) { - if raw { - println!("{}", result.to_str().unwrap().as_str()) - } else { - println!("=> {} :: {}", result, result.type_of()) - } -} - -fn state_dir() -> Option<PathBuf> { - let mut path = dirs::data_dir(); - if let Some(p) = path.as_mut() { - p.push("tvix") - } - path -} - -fn run_prompt(eval_options: tvix_eval::Options) { - let mut rl = Editor::<()>::new().expect("should be able to launch rustyline"); - - let history_path = match state_dir() { - // Attempt to set up these paths, but do not hard fail if it - // doesn't work. - Some(mut path) => { - let _ = std::fs::create_dir_all(&path); - path.push("history.txt"); - let _ = rl.load_history(&path); - Some(path) - } - - None => None, - }; - - loop { - let readline = rl.readline("tvix-repl> "); - match readline { - Ok(line) => { - if line.is_empty() { - continue; - } - - rl.add_history_entry(&line); - match tvix_eval::interpret(&line, None, eval_options.clone()) { - Ok(result) => { - println!("=> {} :: {}", result, result.type_of()); - } - Err(_) => { /* interpret takes care of error formatting */ } - } - } - Err(ReadlineError::Interrupted) | Err(ReadlineError::Eof) => break, - - Err(err) => { - eprintln!("error: {}", err); - break; - } - } - } - - if let Some(path) = history_path { - rl.save_history(&path).unwrap(); - } -} |