feat(tvix/repl): Allow binding variables at the top-level
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>
This commit is contained in:
parent
ac3d717944
commit
fc63594631
6 changed files with 157 additions and 16 deletions
|
|
@ -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()
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue