diff options
author | Aspen Smith <root@gws.fyi> | 2024-07-05T03·46-0400 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2024-07-05T16·40+0000 |
commit | fc63594631590547c9a31001806095f2e079a20e (patch) | |
tree | bed08e994d56fb224a62be6ab371f9cd1fec17e6 /tvix/cli/src/main.rs | |
parent | ac3d717944412b17d7dcd18006c2f9f522b1b3f7 (diff) |
feat(tvix/repl): Allow binding variables at the top-level r/8346
Allow binding variables at the REPL's toplevel in the same way the Nix REPL does, using the syntax <ident> = <expr>. This fully, strictly evaluates the value and sets it in the repl's "env", which gets passed in at the toplevel when evaluating expressions. The laziness behavior differs from Nix's, but I think this is good: ❯ nix repl Welcome to Nix version 2.3.18. Type :? for help. nix-repl> x = builtins.trace "x" 1 nix-repl> x trace: x 1 nix-repl> x 1 vs tvix: tvix-repl> x = builtins.trace "x" 1 trace: "x" :: string tvix-repl> x => 1 :: int tvix-repl> x => 1 :: int Bug: https://b.tvl.fyi/issues/371 Change-Id: Ieb2d626b7195fa87be638c9a4dae2eee45eb9ab1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/11954 Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI Autosubmit: aspen <root@gws.fyi>
Diffstat (limited to 'tvix/cli/src/main.rs')
-rw-r--r-- | tvix/cli/src/main.rs | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/tvix/cli/src/main.rs b/tvix/cli/src/main.rs index 686513b77cc4..c4c70d2a1777 100644 --- a/tvix/cli/src/main.rs +++ b/tvix/cli/src/main.rs @@ -1,7 +1,10 @@ +mod assignment; mod repl; use clap::Parser; use repl::Repl; +use smol_str::SmolStr; +use std::collections::HashMap; use std::rc::Rc; use std::{fs, path::PathBuf}; use tracing::{instrument, Level, Span}; @@ -150,18 +153,15 @@ impl AllowIncomplete { #[derive(Debug, Clone, Copy, PartialEq, Eq)] struct IncompleteInput; -/// Interprets the given code snippet, printing out warnings, errors -/// and the result itself. The return value indicates whether -/// evaluation succeeded. -#[instrument(skip_all, fields(indicatif.pb_show=1))] -fn interpret( +/// Interprets the given code snippet, printing out warnings and errors and returning the result +fn evaluate( tvix_store_io: Rc<TvixStoreIO>, code: &str, path: Option<PathBuf>, args: &Args, - explain: bool, allow_incomplete: AllowIncomplete, -) -> Result<bool, IncompleteInput> { + env: Option<&HashMap<SmolStr, Value>>, +) -> Result<Option<Value>, IncompleteInput> { let span = Span::current(); span.pb_start(); span.pb_set_style(&tvix_tracing::PB_SPINNER_STYLE); @@ -173,6 +173,9 @@ fn interpret( ); eval.strict = args.strict; eval.builtins.extend(impure_builtins()); + if let Some(env) = env { + eval.env = Some(env); + } add_derivation_builtins(&mut eval, Rc::clone(&tvix_store_io)); add_fetcher_builtins(&mut eval, Rc::clone(&tvix_store_io)); add_import_builtins(&mut eval, tvix_store_io); @@ -226,7 +229,25 @@ fn interpret( } } - if let Some(value) = result.value.as_ref() { + Ok(result.value) +} + +/// Interprets the given code snippet, printing out warnings, errors +/// and the result itself. The return value indicates whether +/// evaluation succeeded. +#[instrument(skip_all, fields(indicatif.pb_show=1))] +fn interpret( + tvix_store_io: Rc<TvixStoreIO>, + code: &str, + path: Option<PathBuf>, + args: &Args, + explain: bool, + allow_incomplete: AllowIncomplete, + env: Option<&HashMap<SmolStr, Value>>, +) -> Result<bool, IncompleteInput> { + let result = evaluate(tvix_store_io, code, path, args, allow_incomplete, env)?; + + if let Some(value) = result.as_ref() { if explain { println!("=> {}", value.explain()); } else { @@ -235,7 +256,7 @@ fn interpret( } // inform the caller about any errors - Ok(result.errors.is_empty()) + Ok(result.is_some()) } /// Interpret the given code snippet, but only run the Tvix compiler @@ -298,6 +319,7 @@ fn main() { &args, false, AllowIncomplete::RequireComplete, + None, // TODO(aspen): Pass in --arg/--argstr here ) .unwrap() { @@ -325,6 +347,7 @@ fn run_file(io_handle: Rc<TvixStoreIO>, mut path: PathBuf, args: &Args) { args, false, AllowIncomplete::RequireComplete, + None, ) .unwrap() }; |