mirror of
https://github.com/nushell/nushell.git
synced 2025-04-22 04:08:20 +02:00
Use Vec
for Closure
captures (#10940)
# Description Changes the `captures` field in `Closure` from a `HashMap` to a `Vec` and makes `Stack::captures_to_stack` take an owned `Vec` instead of a borrowed `HashMap`. This eliminates the conversion to a `Vec` inside `captures_to_stack` and makes it possible to avoid clones altogether when using an owned `Closure` (which is the case for most commands). Additionally, using a `Vec` reduces the size of `Value` by 8 bytes (down to 72). # User-Facing Changes Breaking API change for `nu-protocol`.
This commit is contained in:
parent
7a3cbf43e8
commit
60da7abbc7
@ -42,7 +42,7 @@ fn get_prompt_string(
|
|||||||
.and_then(|v| match v {
|
.and_then(|v| match v {
|
||||||
Value::Closure { val, .. } => {
|
Value::Closure { val, .. } => {
|
||||||
let block = engine_state.get_block(val.block_id);
|
let block = engine_state.get_block(val.block_id);
|
||||||
let mut stack = stack.captures_to_stack(&val.captures);
|
let mut stack = stack.captures_to_stack(val.captures);
|
||||||
// Use eval_subexpression to force a redirection of output, so we can use everything in prompt
|
// Use eval_subexpression to force a redirection of output, so we can use everything in prompt
|
||||||
let ret_val =
|
let ret_val =
|
||||||
eval_subexpression(engine_state, &mut stack, block, PipelineData::empty());
|
eval_subexpression(engine_state, &mut stack, block, PipelineData::empty());
|
||||||
|
@ -252,7 +252,7 @@ pub(crate) fn add_columnar_menu(
|
|||||||
let menu_completer = NuMenuCompleter::new(
|
let menu_completer = NuMenuCompleter::new(
|
||||||
val.block_id,
|
val.block_id,
|
||||||
span,
|
span,
|
||||||
stack.captures_to_stack(&val.captures),
|
stack.captures_to_stack(val.captures.clone()),
|
||||||
engine_state,
|
engine_state,
|
||||||
only_buffer_difference,
|
only_buffer_difference,
|
||||||
);
|
);
|
||||||
@ -334,7 +334,7 @@ pub(crate) fn add_list_menu(
|
|||||||
let menu_completer = NuMenuCompleter::new(
|
let menu_completer = NuMenuCompleter::new(
|
||||||
val.block_id,
|
val.block_id,
|
||||||
span,
|
span,
|
||||||
stack.captures_to_stack(&val.captures),
|
stack.captures_to_stack(val.captures.clone()),
|
||||||
engine_state,
|
engine_state,
|
||||||
only_buffer_difference,
|
only_buffer_difference,
|
||||||
);
|
);
|
||||||
@ -452,7 +452,7 @@ pub(crate) fn add_description_menu(
|
|||||||
let menu_completer = NuMenuCompleter::new(
|
let menu_completer = NuMenuCompleter::new(
|
||||||
val.block_id,
|
val.block_id,
|
||||||
span,
|
span,
|
||||||
stack.captures_to_stack(&val.captures),
|
stack.captures_to_stack(val.captures.clone()),
|
||||||
engine_state,
|
engine_state,
|
||||||
only_buffer_difference,
|
only_buffer_difference,
|
||||||
);
|
);
|
||||||
|
@ -81,7 +81,7 @@ impl Command for EachWhile {
|
|||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
|
@ -96,7 +96,7 @@ impl Command for UpdateCells {
|
|||||||
// the block to run on each cell
|
// the block to run on each cell
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let block: Closure = call.req(&engine_state, stack, 0)?;
|
let block: Closure = call.req(&engine_state, stack, 0)?;
|
||||||
let mut stack = stack.captures_to_stack(&block.captures);
|
let mut stack = stack.captures_to_stack(block.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ impl Command for Collect {
|
|||||||
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
||||||
|
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let mut stack_captures = stack.captures_to_stack(&capture_block.captures);
|
let mut stack_captures = stack.captures_to_stack(capture_block.captures.clone());
|
||||||
|
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
let input: Value = input.into_value(call.head);
|
let input: Value = input.into_value(call.head);
|
||||||
@ -71,8 +71,8 @@ impl Command for Collect {
|
|||||||
redirect_env(engine_state, stack, &stack_captures);
|
redirect_env(engine_state, stack, &stack_captures);
|
||||||
// for when we support `data | let x = $in;`
|
// for when we support `data | let x = $in;`
|
||||||
// remove the variables added earlier
|
// remove the variables added earlier
|
||||||
for var_id in capture_block.captures.keys() {
|
for (var_id, _) in capture_block.captures {
|
||||||
stack_captures.remove_var(*var_id);
|
stack_captures.remove_var(var_id);
|
||||||
}
|
}
|
||||||
if let Some(u) = saved_positional {
|
if let Some(u) = saved_positional {
|
||||||
stack_captures.remove_var(u);
|
stack_captures.remove_var(u);
|
||||||
|
@ -72,7 +72,7 @@ impl Command for Do {
|
|||||||
let capture_errors = call.has_flag("capture-errors");
|
let capture_errors = call.has_flag("capture-errors");
|
||||||
let has_env = call.has_flag("env");
|
let has_env = call.has_flag("env");
|
||||||
|
|
||||||
let mut callee_stack = caller_stack.captures_to_stack(&block.captures);
|
let mut callee_stack = caller_stack.captures_to_stack(block.captures);
|
||||||
let block = engine_state.get_block(block.block_id);
|
let block = engine_state.get_block(block.block_id);
|
||||||
|
|
||||||
let params: Vec<_> = block
|
let params: Vec<_> = block
|
||||||
|
@ -61,7 +61,7 @@ impl<'a> StyleComputer<'a> {
|
|||||||
let block = self.engine_state.get_block(val.block_id).clone();
|
let block = self.engine_state.get_block(val.block_id).clone();
|
||||||
// Because captures_to_stack() clones, we don't need to use with_env() here
|
// Because captures_to_stack() clones, we don't need to use with_env() here
|
||||||
// (contrast with_env() usage in `each` or `do`).
|
// (contrast with_env() usage in `each` or `do`).
|
||||||
let mut stack = self.stack.captures_to_stack(&val.captures);
|
let mut stack = self.stack.captures_to_stack(val.captures.clone());
|
||||||
|
|
||||||
// Support 1-argument blocks as well as 0-argument blocks.
|
// Support 1-argument blocks as well as 0-argument blocks.
|
||||||
if let Some(var) = block.signature.get_positional(0) {
|
if let Some(var) = block.signature.get_positional(0) {
|
||||||
|
@ -182,7 +182,7 @@ mod test {
|
|||||||
ast::{CellPath, PathMember},
|
ast::{CellPath, PathMember},
|
||||||
engine::Closure,
|
engine::Closure,
|
||||||
};
|
};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashSet;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_value() {
|
fn from_value() {
|
||||||
@ -243,7 +243,7 @@ mod test {
|
|||||||
Value::closure(
|
Value::closure(
|
||||||
Closure {
|
Closure {
|
||||||
block_id: 0,
|
block_id: 0,
|
||||||
captures: HashMap::new(),
|
captures: Vec::new(),
|
||||||
},
|
},
|
||||||
span,
|
span,
|
||||||
),
|
),
|
||||||
|
@ -41,7 +41,7 @@ impl Command for Explain {
|
|||||||
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
||||||
let block = engine_state.get_block(capture_block.block_id);
|
let block = engine_state.get_block(capture_block.block_id);
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
|
|
||||||
let elements = get_pipeline_elements(engine_state, &mut stack, block)?;
|
let elements = get_pipeline_elements(engine_state, &mut stack, block)?;
|
||||||
|
|
||||||
|
2
crates/nu-command/src/env/export_env.rs
vendored
2
crates/nu-command/src/env/export_env.rs
vendored
@ -37,7 +37,7 @@ impl Command for ExportEnv {
|
|||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let capture_block: Closure = call.req(engine_state, caller_stack, 0)?;
|
let capture_block: Closure = call.req(engine_state, caller_stack, 0)?;
|
||||||
let block = engine_state.get_block(capture_block.block_id);
|
let block = engine_state.get_block(capture_block.block_id);
|
||||||
let mut callee_stack = caller_stack.captures_to_stack(&capture_block.captures);
|
let mut callee_stack = caller_stack.captures_to_stack(capture_block.captures);
|
||||||
|
|
||||||
let _ = eval_block(
|
let _ = eval_block(
|
||||||
engine_state,
|
engine_state,
|
||||||
|
2
crates/nu-command/src/env/with_env.rs
vendored
2
crates/nu-command/src/env/with_env.rs
vendored
@ -85,7 +85,7 @@ fn with_env(
|
|||||||
|
|
||||||
let capture_block: Closure = call.req(engine_state, stack, 1)?;
|
let capture_block: Closure = call.req(engine_state, stack, 1)?;
|
||||||
let block = engine_state.get_block(capture_block.block_id);
|
let block = engine_state.get_block(capture_block.block_id);
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
|
|
||||||
let mut env: HashMap<String, Value> = HashMap::new();
|
let mut env: HashMap<String, Value> = HashMap::new();
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ with 'transpose' first."#
|
|||||||
let outer_ctrlc = engine_state.ctrlc.clone();
|
let outer_ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
|
@ -58,7 +58,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
|
|||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
|
@ -246,7 +246,7 @@ fn group_closure(
|
|||||||
|
|
||||||
for value in values {
|
for value in values {
|
||||||
if let Some(capture_block) = &block {
|
if let Some(capture_block) = &block {
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures.clone());
|
||||||
let block = engine_state.get_block(capture_block.block_id);
|
let block = engine_state.get_block(capture_block.block_id);
|
||||||
let pipeline = eval_block(
|
let pipeline = eval_block(
|
||||||
engine_state,
|
engine_state,
|
||||||
|
@ -125,7 +125,7 @@ fn insert(
|
|||||||
let capture_block = Closure::from_value(replacement)?;
|
let capture_block = Closure::from_value(replacement)?;
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
|
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ impl Command for Items {
|
|||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
|
@ -128,7 +128,7 @@ impl Command for ParEach {
|
|||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let outer_ctrlc = engine_state.ctrlc.clone();
|
let outer_ctrlc = engine_state.ctrlc.clone();
|
||||||
let block_id = capture_block.block_id;
|
let block_id = capture_block.block_id;
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
let redirect_stdout = call.redirect_stdout;
|
let redirect_stdout = call.redirect_stdout;
|
||||||
let redirect_stderr = call.redirect_stderr;
|
let redirect_stderr = call.redirect_stderr;
|
||||||
|
@ -98,7 +98,7 @@ impl Command for Reduce {
|
|||||||
|
|
||||||
let fold: Option<Value> = call.get_flag(engine_state, stack, "fold")?;
|
let fold: Option<Value> = call.get_flag(engine_state, stack, "fold")?;
|
||||||
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let block = engine_state.get_block(capture_block.block_id);
|
let block = engine_state.get_block(capture_block.block_id);
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ fn rename(
|
|||||||
if let Some(capture_block) = call.get_flag::<Closure>(engine_state, stack, "block")? {
|
if let Some(capture_block) = call.get_flag::<Closure>(engine_state, stack, "block")? {
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let stack = stack.captures_to_stack(&capture_block.captures);
|
let stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
Some((engine_state, block, stack, orig_env_vars, orig_env_hidden))
|
Some((engine_state, block, stack, orig_env_vars, orig_env_hidden))
|
||||||
|
@ -86,7 +86,7 @@ impl Command for SkipUntil {
|
|||||||
|
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
|
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
|
@ -91,7 +91,7 @@ impl Command for SkipWhile {
|
|||||||
|
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
|
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
|
@ -82,7 +82,7 @@ impl Command for TakeUntil {
|
|||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
||||||
|
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
|
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
|
@ -82,7 +82,7 @@ impl Command for TakeWhile {
|
|||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
||||||
|
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
|
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
|
@ -122,7 +122,7 @@ fn update(
|
|||||||
let capture_block = Closure::from_value(replacement)?;
|
let capture_block = Closure::from_value(replacement)?;
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
|
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ fn upsert(
|
|||||||
let capture_block = Closure::from_value(replacement)?;
|
let capture_block = Closure::from_value(replacement)?;
|
||||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||||
|
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ pub fn boolean_fold(
|
|||||||
|
|
||||||
let block = engine_state.get_block(block_id);
|
let block = engine_state.get_block(block_id);
|
||||||
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id);
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
|
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
|
@ -59,7 +59,7 @@ not supported."#
|
|||||||
let span = call.head;
|
let span = call.head;
|
||||||
|
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
let mut stack = stack.captures_to_stack(&closure.captures);
|
let mut stack = stack.captures_to_stack(closure.captures);
|
||||||
let block = engine_state.get_block(closure.block_id).clone();
|
let block = engine_state.get_block(closure.block_id).clone();
|
||||||
|
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
|
@ -102,7 +102,7 @@ used as the next argument to the closure, otherwise generation stops.
|
|||||||
let block = engine_state.get_block(capture_block.item.block_id).clone();
|
let block = engine_state.get_block(capture_block.item.block_id).clone();
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.item.captures);
|
let mut stack = stack.captures_to_stack(capture_block.item.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
let redirect_stdout = call.redirect_stdout;
|
let redirect_stdout = call.redirect_stdout;
|
||||||
|
@ -114,7 +114,7 @@ used as the next argument to the closure, otherwise generation stops.
|
|||||||
let block = engine_state.get_block(capture_block.item.block_id).clone();
|
let block = engine_state.get_block(capture_block.item.block_id).clone();
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let mut stack = stack.captures_to_stack(&capture_block.item.captures);
|
let mut stack = stack.captures_to_stack(capture_block.item.captures);
|
||||||
let orig_env_vars = stack.env_vars.clone();
|
let orig_env_vars = stack.env_vars.clone();
|
||||||
let orig_env_hidden = stack.env_hidden.clone();
|
let orig_env_hidden = stack.env_hidden.clone();
|
||||||
let redirect_stdout = call.redirect_stdout;
|
let redirect_stdout = call.redirect_stdout;
|
||||||
|
@ -524,19 +524,15 @@ pub fn eval_expression(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
Expr::RowCondition(block_id) | Expr::Closure(block_id) => {
|
Expr::RowCondition(block_id) | Expr::Closure(block_id) => {
|
||||||
let mut captures = HashMap::new();
|
let block_id = *block_id;
|
||||||
let block = engine_state.get_block(*block_id);
|
let captures = engine_state
|
||||||
|
.get_block(block_id)
|
||||||
|
.captures
|
||||||
|
.iter()
|
||||||
|
.map(|&id| stack.get_var(id, expr.span).map(|var| (id, var)))
|
||||||
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
for var_id in &block.captures {
|
Ok(Value::closure(Closure { block_id, captures }, expr.span))
|
||||||
captures.insert(*var_id, stack.get_var(*var_id, expr.span)?);
|
|
||||||
}
|
|
||||||
Ok(Value::closure(
|
|
||||||
Closure {
|
|
||||||
block_id: *block_id,
|
|
||||||
captures,
|
|
||||||
},
|
|
||||||
expr.span,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
Expr::Block(block_id) => Ok(Value::block(*block_id, expr.span)),
|
Expr::Block(block_id) => Ok(Value::block(*block_id, expr.span)),
|
||||||
Expr::List(x) => {
|
Expr::List(x) => {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::{BlockId, Value, VarId};
|
use crate::{BlockId, Value, VarId};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -7,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Closure {
|
pub struct Closure {
|
||||||
pub block_id: BlockId,
|
pub block_id: BlockId,
|
||||||
pub captures: HashMap<VarId, Value>,
|
pub captures: Vec<(VarId, Value)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -138,19 +138,13 @@ impl Stack {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn captures_to_stack(&self, captures: &HashMap<VarId, Value>) -> Stack {
|
pub fn captures_to_stack(&self, captures: Vec<(VarId, Value)>) -> Stack {
|
||||||
// FIXME: this is probably slow
|
// FIXME: this is probably slow
|
||||||
let mut env_vars = self.env_vars.clone();
|
let mut env_vars = self.env_vars.clone();
|
||||||
env_vars.push(HashMap::new());
|
env_vars.push(HashMap::new());
|
||||||
|
|
||||||
// FIXME make this more efficient
|
|
||||||
let mut vars = vec![];
|
|
||||||
for (id, val) in captures {
|
|
||||||
vars.push((*id, val.clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack {
|
Stack {
|
||||||
vars,
|
vars: captures,
|
||||||
env_vars,
|
env_vars,
|
||||||
env_hidden: self.env_hidden.clone(),
|
env_hidden: self.env_hidden.clone(),
|
||||||
active_overlays: self.active_overlays.clone(),
|
active_overlays: self.active_overlays.clone(),
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::ast::{CellPath, MatchPattern, PathMember};
|
use crate::ast::{CellPath, MatchPattern, PathMember};
|
||||||
@ -496,7 +495,7 @@ impl FromValue for Closure {
|
|||||||
Value::Closure { val, .. } => Ok(val),
|
Value::Closure { val, .. } => Ok(val),
|
||||||
Value::Block { val, .. } => Ok(Closure {
|
Value::Block { val, .. } => Ok(Closure {
|
||||||
block_id: val,
|
block_id: val,
|
||||||
captures: HashMap::new(),
|
captures: Vec::new(),
|
||||||
}),
|
}),
|
||||||
v => Err(ShellError::CantConvert {
|
v => Err(ShellError::CantConvert {
|
||||||
to_type: "Closure".into(),
|
to_type: "Closure".into(),
|
||||||
|
Loading…
Reference in New Issue
Block a user