From b5965ee8ef714b3e9d446f01f233b5584d2a64b6 Mon Sep 17 00:00:00 2001 From: JT Date: Mon, 25 Oct 2021 19:31:39 +1300 Subject: [PATCH] WIP --- crates/nu-cli/src/completions.rs | 16 +- crates/nu-cli/src/syntax_highlight.rs | 8 +- crates/nu-cli/src/validation.rs | 5 +- .../nu-command/src/conversions/into/binary.rs | 8 +- .../src/conversions/into/command.rs | 7 +- .../src/conversions/into/filesize.rs | 8 +- crates/nu-command/src/conversions/into/int.rs | 8 +- crates/nu-command/src/core_commands/alias.rs | 5 +- crates/nu-command/src/core_commands/def.rs | 5 +- crates/nu-command/src/core_commands/do_.rs | 17 +- .../src/core_commands/export_def.rs | 5 +- crates/nu-command/src/core_commands/for_.rs | 35 ++-- crates/nu-command/src/core_commands/help.rs | 21 ++- crates/nu-command/src/core_commands/hide.rs | 5 +- crates/nu-command/src/core_commands/if_.rs | 25 +-- crates/nu-command/src/core_commands/let_.rs | 9 +- crates/nu-command/src/core_commands/module.rs | 5 +- crates/nu-command/src/core_commands/source.rs | 11 +- crates/nu-command/src/core_commands/use_.rs | 5 +- crates/nu-command/src/default_context.rs | 11 +- crates/nu-command/src/env/let_env.rs | 9 +- crates/nu-command/src/example_test.rs | 12 +- crates/nu-command/src/experimental/git.rs | 5 +- .../src/experimental/git_checkout.rs | 7 +- .../src/experimental/list_git_branches.rs | 5 +- crates/nu-command/src/filesystem/cd.rs | 9 +- crates/nu-command/src/filesystem/cp.rs | 9 +- crates/nu-command/src/filesystem/ls.rs | 7 +- crates/nu-command/src/filesystem/mkdir.rs | 7 +- crates/nu-command/src/filesystem/mv.rs | 9 +- crates/nu-command/src/filesystem/rm.rs | 15 +- crates/nu-command/src/filesystem/touch.rs | 9 +- crates/nu-command/src/filters/each.rs | 54 ++++--- crates/nu-command/src/filters/get.rs | 7 +- crates/nu-command/src/filters/length.rs | 5 +- crates/nu-command/src/filters/lines.rs | 5 +- crates/nu-command/src/filters/select.rs | 7 +- crates/nu-command/src/filters/where_.rs | 20 +-- crates/nu-command/src/filters/wrap.rs | 7 +- crates/nu-command/src/formats/from/command.rs | 5 +- crates/nu-command/src/formats/from/json.rs | 5 +- crates/nu-command/src/strings/build_string.rs | 7 +- crates/nu-command/src/strings/size.rs | 13 +- crates/nu-command/src/strings/split/chars.rs | 5 +- crates/nu-command/src/strings/split/column.rs | 14 +- .../nu-command/src/strings/split/command.rs | 11 +- crates/nu-command/src/strings/split/row.rs | 12 +- crates/nu-command/src/system/benchmark.rs | 11 +- crates/nu-command/src/system/ps.rs | 5 +- crates/nu-command/src/system/run_external.rs | 69 +++----- crates/nu-command/src/system/sys.rs | 5 +- crates/nu-command/src/viewers/griddle.rs | 9 +- crates/nu-command/src/viewers/table.rs | 5 +- crates/nu-engine/src/call_ext.rs | 46 ++++-- crates/nu-engine/src/documentation.rs | 38 +++-- crates/nu-engine/src/eval.rs | 102 ++++++------ crates/nu-parser/tests/test_parser.rs | 5 +- crates/nu-protocol/src/engine/command.rs | 5 +- crates/nu-protocol/src/signature.rs | 8 +- src/main.rs | 150 ++++++++---------- 60 files changed, 502 insertions(+), 455 deletions(-) diff --git a/crates/nu-cli/src/completions.rs b/crates/nu-cli/src/completions.rs index 0bd47c507b..837d633f6e 100644 --- a/crates/nu-cli/src/completions.rs +++ b/crates/nu-cli/src/completions.rs @@ -10,19 +10,20 @@ use reedline::Completer; const SEP: char = std::path::MAIN_SEPARATOR; +#[derive(Clone)] pub struct NuCompleter { - engine_state: Box, + engine_state: EngineState, } impl NuCompleter { - pub fn new(engine_state: Box) -> Self { + pub fn new(engine_state: EngineState) -> Self { Self { engine_state } } } impl Completer for NuCompleter { fn complete(&self, line: &str, pos: usize) -> Vec<(reedline::Span, String)> { - let mut working_set = StateWorkingSet::new(&*self.engine_state); + let mut working_set = StateWorkingSet::new(&self.engine_state); let offset = working_set.next_span_start(); let pos = offset + pos; let (output, _err) = parse(&mut working_set, Some("completer"), line.as_bytes(), false); @@ -71,11 +72,10 @@ impl Completer for NuCompleter { let (block, ..) = parse(&mut working_set, None, custom_completion.as_bytes(), false); - let context = EvaluationContext { - engine_state: self.engine_state.clone(), - stack: Stack::default(), - }; - let result = eval_block(&context, &block, PipelineData::new()); + + let mut stack = Stack::default(); + let result = + eval_block(&self.engine_state, &mut stack, &block, PipelineData::new()); let v: Vec<_> = match result { Ok(pd) => pd diff --git a/crates/nu-cli/src/syntax_highlight.rs b/crates/nu-cli/src/syntax_highlight.rs index a8878b23c0..5ecbdcab20 100644 --- a/crates/nu-cli/src/syntax_highlight.rs +++ b/crates/nu-cli/src/syntax_highlight.rs @@ -2,21 +2,19 @@ use nu_ansi_term::Style; use nu_parser::{flatten_block, parse, FlatShape}; use nu_protocol::engine::{EngineState, StateWorkingSet}; use reedline::{Highlighter, StyledText}; -use std::{cell::RefCell, rc::Rc}; pub struct NuHighlighter { - pub engine_state: Rc>, + pub engine_state: EngineState, } impl Highlighter for NuHighlighter { fn highlight(&self, line: &str) -> StyledText { let (shapes, global_span_offset) = { - let engine_state = self.engine_state.borrow(); - let mut working_set = StateWorkingSet::new(&*engine_state); + let mut working_set = StateWorkingSet::new(&self.engine_state); let (block, _) = parse(&mut working_set, None, line.as_bytes(), false); let shapes = flatten_block(&working_set, &block); - (shapes, engine_state.next_span_start()) + (shapes, self.engine_state.next_span_start()) }; let mut output = StyledText::default(); diff --git a/crates/nu-cli/src/validation.rs b/crates/nu-cli/src/validation.rs index 85bf9538ae..058bc303c5 100644 --- a/crates/nu-cli/src/validation.rs +++ b/crates/nu-cli/src/validation.rs @@ -5,13 +5,12 @@ use nu_protocol::engine::{EngineState, StateWorkingSet}; use reedline::{ValidationResult, Validator}; pub struct NuValidator { - pub engine_state: Rc>, + pub engine_state: EngineState, } impl Validator for NuValidator { fn validate(&self, line: &str) -> ValidationResult { - let engine_state = self.engine_state.borrow(); - let mut working_set = StateWorkingSet::new(&*engine_state); + let mut working_set = StateWorkingSet::new(&self.engine_state); let (_, err) = parse(&mut working_set, None, line.as_bytes(), false); if matches!(err, Some(ParseError::UnexpectedEof(..))) { diff --git a/crates/nu-command/src/conversions/into/binary.rs b/crates/nu-command/src/conversions/into/binary.rs index 0658cdb0e3..e6c697e56f 100644 --- a/crates/nu-command/src/conversions/into/binary.rs +++ b/crates/nu-command/src/conversions/into/binary.rs @@ -1,6 +1,6 @@ use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, }; @@ -26,11 +26,12 @@ impl Command for SubCommand { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - into_binary(context, call, input) + into_binary(call, input) } fn examples(&self) -> Vec { @@ -85,7 +86,6 @@ impl Command for SubCommand { } fn into_binary( - _context: &EvaluationContext, call: &Call, input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/conversions/into/command.rs b/crates/nu-command/src/conversions/into/command.rs index 37741e7f4a..a745834dc7 100644 --- a/crates/nu-command/src/conversions/into/command.rs +++ b/crates/nu-command/src/conversions/into/command.rs @@ -1,7 +1,7 @@ use nu_engine::get_full_help; use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, IntoPipelineData, PipelineData, Signature, Value, }; @@ -23,12 +23,13 @@ impl Command for Into { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { Ok(Value::String { - val: get_full_help(&Into.signature(), &[], context), + val: get_full_help(&Into.signature(), &[], engine_state), span: call.head, } .into_pipeline_data()) diff --git a/crates/nu-command/src/conversions/into/filesize.rs b/crates/nu-command/src/conversions/into/filesize.rs index bb2a2a8135..a5aa0d6c19 100644 --- a/crates/nu-command/src/conversions/into/filesize.rs +++ b/crates/nu-command/src/conversions/into/filesize.rs @@ -1,6 +1,6 @@ use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, }; @@ -26,11 +26,12 @@ impl Command for SubCommand { fn run( &self, - context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - into_filesize(context, call, input) + into_filesize(call, input) } fn examples(&self) -> Vec { @@ -113,7 +114,6 @@ impl Command for SubCommand { } fn into_filesize( - _context: &EvaluationContext, call: &Call, input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/conversions/into/int.rs b/crates/nu-command/src/conversions/into/int.rs index b0b29a2dc7..a4f31f2d70 100644 --- a/crates/nu-command/src/conversions/into/int.rs +++ b/crates/nu-command/src/conversions/into/int.rs @@ -1,6 +1,6 @@ use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, }; @@ -26,11 +26,12 @@ impl Command for SubCommand { fn run( &self, - context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - into_int(context, call, input) + into_int(call, input) } fn examples(&self) -> Vec { @@ -89,7 +90,6 @@ impl Command for SubCommand { } fn into_int( - _context: &EvaluationContext, call: &Call, input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/core_commands/alias.rs b/crates/nu-command/src/core_commands/alias.rs index 971d04443f..3ed9b97d84 100644 --- a/crates/nu-command/src/core_commands/alias.rs +++ b/crates/nu-command/src/core_commands/alias.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -26,7 +26,8 @@ impl Command for Alias { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/core_commands/def.rs b/crates/nu-command/src/core_commands/def.rs index 4d3808bc71..3eb3a6307e 100644 --- a/crates/nu-command/src/core_commands/def.rs +++ b/crates/nu-command/src/core_commands/def.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -27,7 +27,8 @@ impl Command for Def { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/core_commands/do_.rs b/crates/nu-command/src/core_commands/do_.rs index 09f6351b7a..2b38dd4277 100644 --- a/crates/nu-command/src/core_commands/do_.rs +++ b/crates/nu-command/src/core_commands/do_.rs @@ -1,6 +1,6 @@ use nu_engine::{eval_block, CallExt}; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -28,18 +28,19 @@ impl Command for Do { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let block_id = call.positional[0] .as_block() .expect("internal error: expected block"); - let rest: Vec = call.rest(context, 1)?; + let rest: Vec = call.rest(engine_state, stack, 1)?; - let block = context.engine_state.get_block(block_id); + let block = engine_state.get_block(block_id); - let mut state = context.enter_scope(); + let mut stack = stack.enter_scope(); let params: Vec<_> = block .signature @@ -50,7 +51,7 @@ impl Command for Do { for param in params.iter().zip(&rest) { if let Some(var_id) = param.0.var_id { - state.add_var(var_id, param.1.clone()) + stack.add_var(var_id, param.1.clone()) } } @@ -68,7 +69,7 @@ impl Command for Do { call.head }; - state.add_var( + stack.add_var( param .var_id .expect("Internal error: rest positional parameter lacks var_id"), @@ -79,6 +80,6 @@ impl Command for Do { ) } } - eval_block(&state, block, input) + eval_block(&engine_state, &mut stack, block, input) } } diff --git a/crates/nu-command/src/core_commands/export_def.rs b/crates/nu-command/src/core_commands/export_def.rs index 2ab2430b15..910716c9f3 100644 --- a/crates/nu-command/src/core_commands/export_def.rs +++ b/crates/nu-command/src/core_commands/export_def.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -27,7 +27,8 @@ impl Command for ExportDef { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/core_commands/for_.rs b/crates/nu-command/src/core_commands/for_.rs index 2a52296dfd..1539690e2d 100644 --- a/crates/nu-command/src/core_commands/for_.rs +++ b/crates/nu-command/src/core_commands/for_.rs @@ -1,6 +1,6 @@ use nu_engine::{eval_block, eval_expression}; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value}; #[derive(Clone)] @@ -37,7 +37,8 @@ impl Command for For { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { @@ -48,25 +49,25 @@ impl Command for For { let keyword_expr = call.positional[1] .as_keyword() .expect("internal error: missing keyword"); - let values = eval_expression(context, keyword_expr)?; + let values = eval_expression(engine_state, stack, keyword_expr)?; let block = call.positional[2] .as_block() .expect("internal error: expected block"); - let context = context.clone(); + let engine_state = engine_state.clone(); + let mut stack = stack.enter_scope(); match values { Value::List { vals, span } => Ok(vals .into_iter() .map(move |x| { - let block = context.engine_state.get_block(block); + let block = engine_state.get_block(block); - let mut state = context.enter_scope(); + let mut stack = stack.clone(); + stack.add_var(var_id, x); - state.add_var(var_id, x); - - match eval_block(&state, block, PipelineData::new()) { + match eval_block(&engine_state, &mut stack, block, PipelineData::new()) { Ok(value) => Value::List { vals: value.collect(), span, @@ -78,13 +79,13 @@ impl Command for For { Value::Range { val, span } => Ok(val .into_range_iter()? .map(move |x| { - let block = context.engine_state.get_block(block); + let block = engine_state.get_block(block); - let mut state = context.enter_scope(); + let mut stack = stack.enter_scope(); - state.add_var(var_id, x); + stack.add_var(var_id, x); - match eval_block(&state, block, PipelineData::new()) { + match eval_block(&engine_state, &mut stack, block, PipelineData::new()) { Ok(value) => Value::List { vals: value.collect(), span, @@ -94,13 +95,13 @@ impl Command for For { }) .into_pipeline_data()), x => { - let block = context.engine_state.get_block(block); + let block = engine_state.get_block(block); - let mut state = context.enter_scope(); + let mut stack = stack.enter_scope(); - state.add_var(var_id, x); + stack.add_var(var_id, x); - eval_block(&state, block, PipelineData::new()) + eval_block(&engine_state, &mut stack, block, PipelineData::new()) } } } diff --git a/crates/nu-command/src/core_commands/help.rs b/crates/nu-command/src/core_commands/help.rs index dc96f3bc48..990acb4c71 100644 --- a/crates/nu-command/src/core_commands/help.rs +++ b/crates/nu-command/src/core_commands/help.rs @@ -1,6 +1,6 @@ use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, span, Example, IntoPipelineData, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Value, }; @@ -36,11 +36,12 @@ impl Command for Help { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { - help(context, call) + help(engine_state, stack, call) } fn examples(&self) -> Vec { @@ -74,12 +75,16 @@ impl Command for Help { } } -fn help(context: &EvaluationContext, call: &Call) -> Result { +fn help( + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, +) -> Result { let head = call.head; - let find: Option> = call.get_flag(context, "find")?; - let rest: Vec> = call.rest(context, 0)?; + let find: Option> = call.get_flag(engine_state, stack, "find")?; + let rest: Vec> = call.rest(engine_state, stack, 0)?; - let full_commands = context.get_signatures_with_examples(); + let full_commands = engine_state.get_signatures_with_examples(); if let Some(f) = find { let search_string = f.item; @@ -164,7 +169,7 @@ fn help(context: &EvaluationContext, call: &Call) -> Result Result { diff --git a/crates/nu-command/src/core_commands/if_.rs b/crates/nu-command/src/core_commands/if_.rs index 16217142d0..0ea5c8785d 100644 --- a/crates/nu-command/src/core_commands/if_.rs +++ b/crates/nu-command/src/core_commands/if_.rs @@ -1,6 +1,6 @@ use nu_engine::{eval_block, eval_expression}; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -28,7 +28,8 @@ impl Command for If { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { @@ -38,24 +39,26 @@ impl Command for If { .expect("internal error: expected block"); let else_case = call.positional.get(2); - let result = eval_expression(context, cond)?; + let result = eval_expression(engine_state, stack, cond)?; match result { Value::Bool { val, span } => { if val { - let block = context.engine_state.get_block(then_block); - let state = context.enter_scope(); - eval_block(&state, block, input) + let block = engine_state.get_block(then_block); + let mut stack = stack.enter_scope(); + eval_block(&engine_state, &mut stack, block, input) } else if let Some(else_case) = else_case { if let Some(else_expr) = else_case.as_keyword() { if let Some(block_id) = else_expr.as_block() { - let block = context.engine_state.get_block(block_id); - let state = context.enter_scope(); - eval_block(&state, block, input) + let block = engine_state.get_block(block_id); + let mut stack = stack.enter_scope(); + eval_block(&engine_state, &mut stack, block, input) } else { - eval_expression(context, else_expr).map(|x| x.into_pipeline_data()) + eval_expression(&engine_state, stack, else_expr) + .map(|x| x.into_pipeline_data()) } } else { - eval_expression(context, else_case).map(|x| x.into_pipeline_data()) + eval_expression(&engine_state, stack, else_case) + .map(|x| x.into_pipeline_data()) } } else { Ok(PipelineData::new()) diff --git a/crates/nu-command/src/core_commands/let_.rs b/crates/nu-command/src/core_commands/let_.rs index 64a7437b0a..3e3a942cd3 100644 --- a/crates/nu-command/src/core_commands/let_.rs +++ b/crates/nu-command/src/core_commands/let_.rs @@ -1,6 +1,6 @@ use nu_engine::eval_expression; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -27,7 +27,8 @@ impl Command for Let { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { @@ -39,11 +40,11 @@ impl Command for Let { .as_keyword() .expect("internal error: missing keyword"); - let rhs = eval_expression(context, keyword_expr)?; + let rhs = eval_expression(&engine_state, stack, keyword_expr)?; //println!("Adding: {:?} to {}", rhs, var_id); - context.add_var(var_id, rhs); + stack.add_var(var_id, rhs); Ok(PipelineData::new()) } } diff --git a/crates/nu-command/src/core_commands/module.rs b/crates/nu-command/src/core_commands/module.rs index d7e59882ac..2476e6ab95 100644 --- a/crates/nu-command/src/core_commands/module.rs +++ b/crates/nu-command/src/core_commands/module.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -26,7 +26,8 @@ impl Command for Module { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/core_commands/source.rs b/crates/nu-command/src/core_commands/source.rs index 17881b2152..6b9cc78852 100644 --- a/crates/nu-command/src/core_commands/source.rs +++ b/crates/nu-command/src/core_commands/source.rs @@ -1,6 +1,6 @@ use nu_engine::{eval_block, CallExt}; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape, Value}; /// Source a file for environment variables. @@ -26,15 +26,16 @@ impl Command for Source { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { // Note: this hidden positional is the block_id that corresponded to the 0th position // it is put here by the parser - let block_id: i64 = call.req(context, 1)?; + let block_id: i64 = call.req(engine_state, stack, 1)?; - let block = context.engine_state.get_block(block_id as usize).clone(); - eval_block(context, &block, input) + let block = engine_state.get_block(block_id as usize).clone(); + eval_block(engine_state, stack, &block, input) } } diff --git a/crates/nu-command/src/core_commands/use_.rs b/crates/nu-command/src/core_commands/use_.rs index ed3781b385..dfcc0124ec 100644 --- a/crates/nu-command/src/core_commands/use_.rs +++ b/crates/nu-command/src/core_commands/use_.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -20,7 +20,8 @@ impl Command for Use { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index 1fe5d90ec3..b1ba99470b 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -1,5 +1,3 @@ -use std::{cell::RefCell, rc::Rc}; - use nu_protocol::{ engine::{EngineState, StateWorkingSet}, Signature, @@ -7,11 +5,10 @@ use nu_protocol::{ use crate::*; -pub fn create_default_context() -> Rc> { - let engine_state = Rc::new(RefCell::new(EngineState::new())); +pub fn create_default_context() -> EngineState { + let mut engine_state = EngineState::new(); let delta = { - let engine_state = engine_state.borrow(); - let mut working_set = StateWorkingSet::new(&*engine_state); + let mut working_set = StateWorkingSet::new(&engine_state); macro_rules! bind_command { ( $command:expr ) => { @@ -90,7 +87,7 @@ pub fn create_default_context() -> Rc> { }; { - EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta); + EngineState::merge_delta(&mut engine_state, delta); } engine_state diff --git a/crates/nu-command/src/env/let_env.rs b/crates/nu-command/src/env/let_env.rs index 112cfa40df..21801939cf 100644 --- a/crates/nu-command/src/env/let_env.rs +++ b/crates/nu-command/src/env/let_env.rs @@ -1,6 +1,6 @@ use nu_engine::eval_expression; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -27,7 +27,8 @@ impl Command for LetEnv { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { @@ -39,12 +40,12 @@ impl Command for LetEnv { .as_keyword() .expect("internal error: missing keyword"); - let rhs = eval_expression(context, keyword_expr)?; + let rhs = eval_expression(engine_state, stack, keyword_expr)?; let rhs = rhs.as_string()?; //println!("Adding: {:?} to {}", rhs, var_id); - context.add_env_var(env_var, rhs); + stack.add_env_var(env_var, rhs); Ok(PipelineData::new()) } } diff --git a/crates/nu-command/src/example_test.rs b/crates/nu-command/src/example_test.rs index 8b41ead793..8bda299baf 100644 --- a/crates/nu-command/src/example_test.rs +++ b/crates/nu-command/src/example_test.rs @@ -3,7 +3,7 @@ use std::{cell::RefCell, rc::Rc}; use nu_engine::eval_block; use nu_parser::parse; use nu_protocol::{ - engine::{Command, EngineState, EvaluationContext, StateWorkingSet}, + engine::{Command, EngineState, EvaluationContext, Stack, StateWorkingSet}, PipelineData, Value, }; @@ -37,7 +37,6 @@ pub fn test_examples(cmd: impl Command + 'static) { let start = std::time::Instant::now(); let (block, delta) = { - let engine_state = engine_state; let mut working_set = StateWorkingSet::new(&*engine_state); let (output, err) = parse(&mut working_set, None, example.example.as_bytes(), false); @@ -48,14 +47,11 @@ pub fn test_examples(cmd: impl Command + 'static) { (output, working_set.render()) }; - EngineState::merge_delta(&mut *engine_state, delta); + EngineState::merge_delta(&mut engine_state, delta); - let state = EvaluationContext { - engine_state: engine_state.clone(), - stack: nu_protocol::engine::Stack::new(), - }; + let mut stack = Stack::new(); - match eval_block(&state, &block, PipelineData::new()) { + match eval_block(&engine_state, &mut stack, &block, PipelineData::new()) { Err(err) => panic!("test eval error in `{}`: {:?}", example.example, err), Ok(result) => { let result = result.into_value(); diff --git a/crates/nu-command/src/experimental/git.rs b/crates/nu-command/src/experimental/git.rs index 57fe52c218..f4c9cf1f13 100644 --- a/crates/nu-command/src/experimental/git.rs +++ b/crates/nu-command/src/experimental/git.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, Signature, Value}; #[derive(Clone)] @@ -20,7 +20,8 @@ impl Command for Git { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/experimental/git_checkout.rs b/crates/nu-command/src/experimental/git_checkout.rs index 02b1ac01a5..0c8be2564f 100644 --- a/crates/nu-command/src/experimental/git_checkout.rs +++ b/crates/nu-command/src/experimental/git_checkout.rs @@ -1,6 +1,6 @@ use nu_engine::eval_expression; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -25,7 +25,8 @@ impl Command for GitCheckout { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { @@ -34,7 +35,7 @@ impl Command for GitCheckout { let block = &call.positional[0]; - let out = eval_expression(context, block)?; + let out = eval_expression(engine_state, stack, block)?; let out = out.as_string()?; diff --git a/crates/nu-command/src/experimental/list_git_branches.rs b/crates/nu-command/src/experimental/list_git_branches.rs index 065b5bf2c0..a11c85efbf 100644 --- a/crates/nu-command/src/experimental/list_git_branches.rs +++ b/crates/nu-command/src/experimental/list_git_branches.rs @@ -4,6 +4,8 @@ use std::process::Command as ProcessCommand; use std::process::Stdio; use nu_protocol::ast::Call; +use nu_protocol::engine::EngineState; +use nu_protocol::engine::Stack; use nu_protocol::engine::{Command, EvaluationContext}; use nu_protocol::IntoPipelineData; use nu_protocol::PipelineData; @@ -28,7 +30,8 @@ impl Command for ListGitBranches { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/filesystem/cd.rs b/crates/nu-command/src/filesystem/cd.rs index cbde266c49..5bb1dd928b 100644 --- a/crates/nu-command/src/filesystem/cd.rs +++ b/crates/nu-command/src/filesystem/cd.rs @@ -1,6 +1,6 @@ use nu_engine::CallExt; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -21,11 +21,12 @@ impl Command for Cd { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { - let path: Option = call.opt(context, 0)?; + let path: Option = call.opt(engine_state, stack, 0)?; let path = match path { Some(path) => { @@ -41,7 +42,7 @@ impl Command for Cd { //FIXME: this only changes the current scope, but instead this environment variable //should probably be a block that loads the information from the state in the overlay - context.add_env_var("PWD".into(), path); + stack.add_env_var("PWD".into(), path); Ok(PipelineData::new()) } } diff --git a/crates/nu-command/src/filesystem/cp.rs b/crates/nu-command/src/filesystem/cp.rs index 71d5a255ac..0283f8d1a6 100644 --- a/crates/nu-command/src/filesystem/cp.rs +++ b/crates/nu-command/src/filesystem/cp.rs @@ -5,7 +5,7 @@ use super::util::get_interactive_confirmation; use nu_engine::CallExt; use nu_path::canonicalize_with; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape, Value}; use crate::filesystem::util::FileStructure; @@ -38,12 +38,13 @@ impl Command for Cp { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { - let source: String = call.req(context, 0)?; - let destination: String = call.req(context, 1)?; + let source: String = call.req(engine_state, stack, 0)?; + let destination: String = call.req(engine_state, stack, 1)?; let interactive = call.has_flag("interactive"); let force = call.has_flag("force"); diff --git a/crates/nu-command/src/filesystem/ls.rs b/crates/nu-command/src/filesystem/ls.rs index 8c35698bb2..6458af7b96 100644 --- a/crates/nu-command/src/filesystem/ls.rs +++ b/crates/nu-command/src/filesystem/ls.rs @@ -1,7 +1,7 @@ use chrono::{DateTime, Utc}; use nu_engine::eval_expression; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -27,12 +27,13 @@ impl Command for Ls { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { let pattern = if let Some(expr) = call.positional.get(0) { - let result = eval_expression(context, expr)?; + let result = eval_expression(engine_state, stack, expr)?; let mut result = result.as_string()?; let path = std::path::Path::new(&result); diff --git a/crates/nu-command/src/filesystem/mkdir.rs b/crates/nu-command/src/filesystem/mkdir.rs index 43990605b6..adb91f5d8a 100644 --- a/crates/nu-command/src/filesystem/mkdir.rs +++ b/crates/nu-command/src/filesystem/mkdir.rs @@ -3,7 +3,7 @@ use std::env::current_dir; use nu_engine::CallExt; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{ IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value, ValueStream, }; @@ -32,13 +32,14 @@ impl Command for Mkdir { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { let path = current_dir()?; let mut directories = call - .rest::(context, 0)? + .rest::(engine_state, stack, 0)? .into_iter() .map(|dir| path.join(dir)) .peekable(); diff --git a/crates/nu-command/src/filesystem/mv.rs b/crates/nu-command/src/filesystem/mv.rs index ba709729e1..1e6069b8b1 100644 --- a/crates/nu-command/src/filesystem/mv.rs +++ b/crates/nu-command/src/filesystem/mv.rs @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf}; use super::util::get_interactive_confirmation; use nu_engine::CallExt; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -38,13 +38,14 @@ impl Command for Mv { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { // TODO: handle invalid directory or insufficient permissions when moving - let source: String = call.req(context, 0)?; - let destination: String = call.req(context, 1)?; + let source: String = call.req(engine_state, stack, 0)?; + let destination: String = call.req(engine_state, stack, 1)?; let interactive = call.has_flag("interactive"); let force = call.has_flag("force"); diff --git a/crates/nu-command/src/filesystem/rm.rs b/crates/nu-command/src/filesystem/rm.rs index d64764d780..35d0f252a3 100644 --- a/crates/nu-command/src/filesystem/rm.rs +++ b/crates/nu-command/src/filesystem/rm.rs @@ -7,7 +7,7 @@ use super::util::get_interactive_confirmation; use nu_engine::CallExt; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{ IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value, ValueStream, }; @@ -59,15 +59,20 @@ impl Command for Rm { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { - rm(context, call) + rm(engine_state, stack, call) } } -fn rm(context: &EvaluationContext, call: &Call) -> Result { +fn rm( + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, +) -> Result { let trash = call.has_flag("trash"); let permanent = call.has_flag("permanent"); let interactive = call.has_flag("interactive"); @@ -98,7 +103,7 @@ fn rm(context: &EvaluationContext, call: &Call) -> Result(context, 0)? + .rest::(engine_state, stack, 0)? .into_iter() .map(|path| current_path.join(path)) .peekable(); diff --git a/crates/nu-command/src/filesystem/touch.rs b/crates/nu-command/src/filesystem/touch.rs index 3d323c71db..85c79d0a24 100644 --- a/crates/nu-command/src/filesystem/touch.rs +++ b/crates/nu-command/src/filesystem/touch.rs @@ -2,7 +2,7 @@ use std::fs::OpenOptions; use nu_engine::CallExt; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -29,12 +29,13 @@ impl Command for Touch { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { - let target: String = call.req(context, 0)?; - let rest: Vec = call.rest(context, 1)?; + let target: String = call.req(engine_state, stack, 0)?; + let rest: Vec = call.rest(engine_state, stack, 1)?; for (index, item) in vec![target].into_iter().chain(rest).enumerate() { match OpenOptions::new().write(true).create(true).open(&item) { diff --git a/crates/nu-command/src/filters/each.rs b/crates/nu-command/src/filters/each.rs index d963fcb35c..789c42c751 100644 --- a/crates/nu-command/src/filters/each.rs +++ b/crates/nu-command/src/filters/each.rs @@ -1,6 +1,6 @@ use nu_engine::eval_block; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value}; #[derive(Clone)] @@ -53,7 +53,8 @@ impl Command for Each { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { @@ -62,7 +63,8 @@ impl Command for Each { .expect("internal error: expected block"); let numbered = call.has_flag("numbered"); - let context = context.clone(); + let engine_state = engine_state.clone(); + let mut stack = stack.clone(); let span = call.head; match input { @@ -70,14 +72,14 @@ impl Command for Each { .into_range_iter()? .enumerate() .map(move |(idx, x)| { - let block = context.engine_state.get_block(block_id); + let block = engine_state.get_block(block_id); - let state = context.enter_scope(); + let mut stack = stack.enter_scope(); if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { if numbered { - state.add_var( + stack.add_var( *var_id, Value::Record { cols: vec!["index".into(), "item".into()], @@ -92,12 +94,12 @@ impl Command for Each { }, ); } else { - state.add_var(*var_id, x); + stack.add_var(*var_id, x); } } } - match eval_block(&state, block, PipelineData::new()) { + match eval_block(&engine_state, &mut stack, block, PipelineData::new()) { Ok(v) => v, Err(error) => Value::Error { error }.into_pipeline_data(), } @@ -108,13 +110,13 @@ impl Command for Each { .into_iter() .enumerate() .map(move |(idx, x)| { - let block = context.engine_state.get_block(block_id); + let block = engine_state.get_block(block_id); - let state = context.enter_scope(); + let mut stack = stack.enter_scope(); if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { if numbered { - state.add_var( + stack.add_var( *var_id, Value::Record { cols: vec!["index".into(), "item".into()], @@ -129,12 +131,12 @@ impl Command for Each { }, ); } else { - state.add_var(*var_id, x); + stack.add_var(*var_id, x); } } } - match eval_block(&state, block, PipelineData::new()) { + match eval_block(&engine_state, &mut stack, block, PipelineData::new()) { Ok(v) => v, Err(error) => Value::Error { error }.into_pipeline_data(), } @@ -144,13 +146,13 @@ impl Command for Each { PipelineData::Stream(stream) => Ok(stream .enumerate() .map(move |(idx, x)| { - let block = context.engine_state.get_block(block_id); + let block = engine_state.get_block(block_id); - let state = context.enter_scope(); + let mut stack = stack.enter_scope(); if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { if numbered { - state.add_var( + stack.add_var( *var_id, Value::Record { cols: vec!["index".into(), "item".into()], @@ -165,12 +167,12 @@ impl Command for Each { }, ); } else { - state.add_var(*var_id, x); + stack.add_var(*var_id, x); } } } - match eval_block(&state, block, PipelineData::new()) { + match eval_block(&engine_state, &mut stack, block, PipelineData::new()) { Ok(v) => v, Err(error) => Value::Error { error }.into_pipeline_data(), } @@ -182,12 +184,12 @@ impl Command for Each { let mut output_vals = vec![]; for (col, val) in cols.into_iter().zip(vals.into_iter()) { - let block = context.engine_state.get_block(block_id); + let block = engine_state.get_block(block_id); - let state = context.enter_scope(); + let mut stack = stack.enter_scope(); if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - state.add_var( + stack.add_var( *var_id, Value::Record { cols: vec!["column".into(), "value".into()], @@ -204,7 +206,7 @@ impl Command for Each { } } - match eval_block(&state, block, PipelineData::new())? { + match eval_block(&engine_state, &mut stack, block, PipelineData::new())? { PipelineData::Value(Value::Record { mut cols, mut vals, .. }) => { @@ -227,16 +229,16 @@ impl Command for Each { .into_pipeline_data()) } PipelineData::Value(x) => { - let block = context.engine_state.get_block(block_id); + let block = engine_state.get_block(block_id); - let state = context.enter_scope(); + let mut stack = stack.enter_scope(); if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - state.add_var(*var_id, x); + stack.add_var(*var_id, x); } } - eval_block(&state, block, PipelineData::new()) + eval_block(&engine_state, &mut stack, block, PipelineData::new()) } } } diff --git a/crates/nu-command/src/filters/get.rs b/crates/nu-command/src/filters/get.rs index fd4084e2bf..e7b38df853 100644 --- a/crates/nu-command/src/filters/get.rs +++ b/crates/nu-command/src/filters/get.rs @@ -1,6 +1,6 @@ use nu_engine::CallExt; use nu_protocol::ast::{Call, CellPath}; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -25,11 +25,12 @@ impl Command for Get { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - let cell_path: CellPath = call.req(context, 0)?; + let cell_path: CellPath = call.req(engine_state, stack, 0)?; input .follow_cell_path(&cell_path.members) diff --git a/crates/nu-command/src/filters/length.rs b/crates/nu-command/src/filters/length.rs index 5c7967fe8e..9fa4543dd4 100644 --- a/crates/nu-command/src/filters/length.rs +++ b/crates/nu-command/src/filters/length.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, Signature, Value}; #[derive(Clone)] @@ -20,7 +20,8 @@ impl Command for Length { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/filters/lines.rs b/crates/nu-command/src/filters/lines.rs index ec59b9d619..bb1db993af 100644 --- a/crates/nu-command/src/filters/lines.rs +++ b/crates/nu-command/src/filters/lines.rs @@ -2,7 +2,7 @@ use std::cell::RefCell; use std::rc::Rc; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, Value, ValueStream}; #[derive(Clone)] @@ -25,7 +25,8 @@ impl Command for Lines { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/filters/select.rs b/crates/nu-command/src/filters/select.rs index 6849c545c1..5c4c7f4723 100644 --- a/crates/nu-command/src/filters/select.rs +++ b/crates/nu-command/src/filters/select.rs @@ -1,6 +1,6 @@ use nu_engine::CallExt; use nu_protocol::ast::{Call, CellPath}; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{ Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, }; @@ -27,11 +27,12 @@ impl Command for Select { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - let columns: Vec = call.rest(context, 0)?; + let columns: Vec = call.rest(engine_state, stack, 0)?; let span = call.head; select(span, columns, input) diff --git a/crates/nu-command/src/filters/where_.rs b/crates/nu-command/src/filters/where_.rs index a65aacf157..5397cddd01 100644 --- a/crates/nu-command/src/filters/where_.rs +++ b/crates/nu-command/src/filters/where_.rs @@ -1,6 +1,6 @@ use nu_engine::eval_expression; use nu_protocol::ast::{Call, Expr, Expression}; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -21,13 +21,15 @@ impl Command for Where { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let cond = call.positional[0].clone(); - let context = context.enter_scope(); + let engine_state = engine_state.clone(); + let mut stack = stack.enter_scope(); let (var_id, cond) = match cond { Expression { @@ -40,9 +42,9 @@ impl Command for Where { match input { PipelineData::Stream(stream) => Ok(stream .filter(move |value| { - context.add_var(var_id, value.clone()); + stack.add_var(var_id, value.clone()); - let result = eval_expression(&context, &cond); + let result = eval_expression(&engine_state, &mut stack, &cond); match result { Ok(result) => result.is_true(), @@ -53,9 +55,9 @@ impl Command for Where { PipelineData::Value(Value::List { vals, span }) => Ok(vals .into_iter() .filter(move |value| { - context.add_var(var_id, value.clone()); + stack.add_var(var_id, value.clone()); - let result = eval_expression(&context, &cond); + let result = eval_expression(&engine_state, &mut stack, &cond); match result { Ok(result) => result.is_true(), @@ -64,9 +66,9 @@ impl Command for Where { }) .into_pipeline_data()), PipelineData::Value(x) => { - context.add_var(var_id, x.clone()); + stack.add_var(var_id, x.clone()); - let result = eval_expression(&context, &cond)?; + let result = eval_expression(&engine_state, &mut stack, &cond)?; if result.is_true() { Ok(x.into_pipeline_data()) diff --git a/crates/nu-command/src/filters/wrap.rs b/crates/nu-command/src/filters/wrap.rs index 9c924800e7..311f72dbea 100644 --- a/crates/nu-command/src/filters/wrap.rs +++ b/crates/nu-command/src/filters/wrap.rs @@ -1,6 +1,6 @@ use nu_engine::CallExt; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -21,12 +21,13 @@ impl Command for Wrap { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let span = call.head; - let name: String = call.req(context, 0)?; + let name: String = call.req(engine_state, stack, 0)?; match input { PipelineData::Value(Value::List { vals, .. }) => Ok(vals diff --git a/crates/nu-command/src/formats/from/command.rs b/crates/nu-command/src/formats/from/command.rs index 23b3d84f6f..36dd21af8e 100644 --- a/crates/nu-command/src/formats/from/command.rs +++ b/crates/nu-command/src/formats/from/command.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, ShellError, Signature, Value}; #[derive(Clone)] @@ -20,7 +20,8 @@ impl Command for From { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, _call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/formats/from/json.rs b/crates/nu-command/src/formats/from/json.rs index 598544aafd..db5af67197 100644 --- a/crates/nu-command/src/formats/from/json.rs +++ b/crates/nu-command/src/formats/from/json.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Value}; #[derive(Clone)] @@ -68,7 +68,8 @@ impl Command for FromJson { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/strings/build_string.rs b/crates/nu-command/src/strings/build_string.rs index 4e80d1128f..1cea5a1a46 100644 --- a/crates/nu-command/src/strings/build_string.rs +++ b/crates/nu-command/src/strings/build_string.rs @@ -1,6 +1,6 @@ use nu_engine::eval_expression; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{ Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, }; @@ -44,14 +44,15 @@ impl Command for BuildString { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { let output = call .positional .iter() - .map(|expr| eval_expression(context, expr).map(|val| val.into_string())) + .map(|expr| eval_expression(engine_state, stack, expr).map(|val| val.into_string())) .collect::, ShellError>>()?; Ok(Value::String { diff --git a/crates/nu-command/src/strings/size.rs b/crates/nu-command/src/strings/size.rs index b40f3abf4d..0f919f5774 100644 --- a/crates/nu-command/src/strings/size.rs +++ b/crates/nu-command/src/strings/size.rs @@ -3,7 +3,7 @@ extern crate unicode_segmentation; use unicode_segmentation::UnicodeSegmentation; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{ Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Type, Value, }; @@ -26,11 +26,12 @@ impl Command for Size { fn run( &self, - context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - size(context, call, input) + size(call, input) } fn examples(&self) -> Vec { @@ -101,11 +102,7 @@ impl Command for Size { } } -fn size( - _context: &EvaluationContext, - call: &Call, - input: PipelineData, -) -> Result { +fn size(call: &Call, input: PipelineData) -> Result { let span = call.head; Ok(input .map(move |v| match v.as_string() { diff --git a/crates/nu-command/src/strings/split/chars.rs b/crates/nu-command/src/strings/split/chars.rs index e0ceaa9cb8..f71f8913a8 100644 --- a/crates/nu-command/src/strings/split/chars.rs +++ b/crates/nu-command/src/strings/split/chars.rs @@ -1,6 +1,6 @@ use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Type, Value, }; @@ -39,7 +39,8 @@ impl Command for SubCommand { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/strings/split/column.rs b/crates/nu-command/src/strings/split/column.rs index 3b7bcae082..d2b370d9d6 100644 --- a/crates/nu-command/src/strings/split/column.rs +++ b/crates/nu-command/src/strings/split/column.rs @@ -1,7 +1,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, IntoPipelineData, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value, }; @@ -34,22 +34,24 @@ impl Command for SubCommand { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - split_column(context, call, input) + split_column(engine_state, stack, call, input) } } fn split_column( - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let name_span = call.head; - let separator: Spanned = call.req(context, 0)?; - let rest: Vec> = call.rest(context, 1)?; + let separator: Spanned = call.req(engine_state, stack, 0)?; + let rest: Vec> = call.rest(engine_state, stack, 1)?; let collapse_empty = call.has_flag("collapse-empty"); Ok(input diff --git a/crates/nu-command/src/strings/split/command.rs b/crates/nu-command/src/strings/split/command.rs index 2afaaee625..e25ea589b7 100644 --- a/crates/nu-command/src/strings/split/command.rs +++ b/crates/nu-command/src/strings/split/command.rs @@ -1,7 +1,7 @@ use nu_engine::get_full_help; use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, IntoPipelineData, PipelineData, Signature, Value, }; @@ -23,12 +23,17 @@ impl Command for SplitCommand { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { Ok(Value::String { - val: get_full_help(&SplitCommand.signature(), &SplitCommand.examples(), context), + val: get_full_help( + &SplitCommand.signature(), + &SplitCommand.examples(), + engine_state, + ), span: call.head, } .into_pipeline_data()) diff --git a/crates/nu-command/src/strings/split/row.rs b/crates/nu-command/src/strings/split/row.rs index 6b24e2c792..5bf8ae02a8 100644 --- a/crates/nu-command/src/strings/split/row.rs +++ b/crates/nu-command/src/strings/split/row.rs @@ -1,7 +1,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, IntoPipelineData, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value, }; @@ -27,21 +27,23 @@ impl Command for SubCommand { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - split_row(context, call, input) + split_row(engine_state, stack, call, input) } } fn split_row( - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let name_span = call.head; - let separator: Spanned = call.req(context, 0)?; + let separator: Spanned = call.req(engine_state, stack, 0)?; Ok(input .flat_map(move |x| split_row_helper(&x, &separator, name_span)) diff --git a/crates/nu-command/src/system/benchmark.rs b/crates/nu-command/src/system/benchmark.rs index 932b8b1265..7913c16719 100644 --- a/crates/nu-command/src/system/benchmark.rs +++ b/crates/nu-command/src/system/benchmark.rs @@ -2,7 +2,7 @@ use std::time::Instant; use nu_engine::eval_block; use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] @@ -27,18 +27,19 @@ impl Command for Benchmark { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { let block = call.positional[0] .as_block() .expect("internal error: expected block"); - let block = context.engine_state.get_block(block); + let block = engine_state.get_block(block); - let state = context.enter_scope(); + let mut stack = stack.enter_scope(); let start_time = Instant::now(); - eval_block(&state, block, PipelineData::new())?; + eval_block(&engine_state, &mut stack, block, PipelineData::new())?; let end_time = Instant::now(); println!("{} ms", (end_time - start_time).as_millis()); Ok(PipelineData::new()) diff --git a/crates/nu-command/src/system/ps.rs b/crates/nu-command/src/system/ps.rs index 6e5072ae73..d816a4472f 100644 --- a/crates/nu-command/src/system/ps.rs +++ b/crates/nu-command/src/system/ps.rs @@ -1,6 +1,6 @@ use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, Example, IntoPipelineData, PipelineData, ShellError, Signature, Value, }; use sysinfo::{ProcessExt, System, SystemExt}; @@ -30,7 +30,8 @@ impl Command for Ps { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 9ac2817a48..84a74dc974 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -1,19 +1,21 @@ use std::borrow::Cow; use std::cell::RefCell; +use std::collections::HashMap; use std::env; use std::io::{BufRead, BufReader, Write}; use std::process::{ChildStdin, Command as CommandSys, Stdio}; use std::rc::Rc; use std::sync::mpsc; +use nu_protocol::engine::{EngineState, Stack}; use nu_protocol::{ ast::{Call, Expression}, engine::{Command, EvaluationContext}, ShellError, Signature, SyntaxShape, Value, }; -use nu_protocol::{IntoPipelineData, PipelineData, Span, ValueStream}; +use nu_protocol::{IntoPipelineData, PipelineData, Span, Spanned, ValueStream}; -use nu_engine::eval_expression; +use nu_engine::{eval_expression, CallExt}; const OUTPUT_BUFFER_SIZE: usize = 8192; @@ -37,52 +39,34 @@ impl Command for External { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - let command = ExternalCommand::try_new(call, context)?; + let name: Spanned = call.req(engine_state, stack, 0)?; + let args: Vec = call.rest(engine_state, stack, 1)?; + let last_expression = call.has_flag("last_expression"); + let env_vars = stack.get_env_vars(); + + let command = ExternalCommand { + name, + args, + last_expression, + env_vars, + }; command.run_with_input(input) } } -pub struct ExternalCommand<'call, 'contex> { - pub name: &'call Expression, - pub args: &'call [Expression], - pub context: &'contex EvaluationContext, +pub struct ExternalCommand { + pub name: Spanned, + pub args: Vec, pub last_expression: bool, + pub env_vars: HashMap, } -impl<'call, 'contex> ExternalCommand<'call, 'contex> { - pub fn try_new( - call: &'call Call, - context: &'contex EvaluationContext, - ) -> Result { - if call.positional.is_empty() { - return Err(ShellError::ExternalNotSupported(call.head)); - } - - Ok(Self { - name: &call.positional[0], - args: &call.positional[1..], - context, - last_expression: call.has_flag("last_expression"), - }) - } - - pub fn get_name(&self) -> Result { - let value = eval_expression(self.context, self.name)?; - value.as_string() - } - - pub fn get_args(&self) -> Vec { - self.args - .iter() - .filter_map(|expr| eval_expression(self.context, expr).ok()) - .filter_map(|value| value.as_string().ok()) - .collect() - } - +impl ExternalCommand { pub fn run_with_input(&self, input: PipelineData) -> Result { let mut process = self.create_command(); @@ -91,8 +75,7 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> { let path = env::current_dir().unwrap(); process.current_dir(path); - let envs = self.context.stack.get_env_vars(); - process.envs(envs); + process.envs(&self.env_vars); // If the external is not the last command, its output will get piped // either as a string or binary @@ -195,8 +178,8 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> { // for minimal builds cwd is unused let mut process = CommandSys::new("cmd"); process.arg("/c"); - process.arg(&self.get_name().unwrap()); - for arg in self.get_args() { + process.arg(&self.name.item); + for arg in &self.args { // Clean the args before we use them: // https://stackoverflow.com/questions/1200235/how-to-pass-a-quoted-pipe-character-to-cmd-exe // cmd.exe needs to have a caret to escape a pipe @@ -205,7 +188,7 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> { } process } else { - let cmd_with_args = vec![self.get_name().unwrap(), self.get_args().join(" ")].join(" "); + let cmd_with_args = vec![self.name.item.clone(), self.args.join(" ")].join(" "); let mut process = CommandSys::new("sh"); process.arg("-c").arg(cmd_with_args); process diff --git a/crates/nu-command/src/system/sys.rs b/crates/nu-command/src/system/sys.rs index 8541b4649b..b1aa54daa2 100644 --- a/crates/nu-command/src/system/sys.rs +++ b/crates/nu-command/src/system/sys.rs @@ -1,6 +1,6 @@ use nu_protocol::{ ast::Call, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Value, }; use sysinfo::{ComponentExt, DiskExt, NetworkExt, ProcessorExt, System, SystemExt, UserExt}; @@ -25,7 +25,8 @@ impl Command for Sys { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { diff --git a/crates/nu-command/src/viewers/griddle.rs b/crates/nu-command/src/viewers/griddle.rs index 462c476abd..fb752a58a8 100644 --- a/crates/nu-command/src/viewers/griddle.rs +++ b/crates/nu-command/src/viewers/griddle.rs @@ -2,7 +2,7 @@ use lscolors::{LsColors, Style}; use nu_engine::CallExt; use nu_protocol::{ ast::{Call, PathMember}, - engine::{Command, EvaluationContext}, + engine::{Command, EngineState, EvaluationContext, Stack}, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value, }; use nu_term_grid::grid::{Alignment, Cell, Direction, Filling, Grid, GridOptions}; @@ -48,13 +48,14 @@ prints out the list properly."# fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - let width_param: Option = call.get_flag(context, "width")?; + let width_param: Option = call.get_flag(engine_state, stack, "width")?; let color_param: bool = call.has_flag("color"); - let separator_param: Option = call.get_flag(context, "separator")?; + let separator_param: Option = call.get_flag(engine_state, stack, "separator")?; match input { PipelineData::Value(Value::List { vals, .. }) => { diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index 131207f552..2fca815b68 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::{Call, PathMember}; -use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack}; use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, Span, Value}; use nu_table::StyledString; use std::collections::HashMap; @@ -24,7 +24,8 @@ impl Command for Table { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { diff --git a/crates/nu-engine/src/call_ext.rs b/crates/nu-engine/src/call_ext.rs index 9e311600a2..1ea0ef163e 100644 --- a/crates/nu-engine/src/call_ext.rs +++ b/crates/nu-engine/src/call_ext.rs @@ -1,37 +1,50 @@ -use nu_protocol::{ast::Call, engine::EvaluationContext, ShellError}; +use nu_protocol::{ + ast::Call, + engine::{EngineState, EvaluationContext, Stack}, + ShellError, +}; use crate::{eval_expression, FromValue}; pub trait CallExt { fn get_flag( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, name: &str, ) -> Result, ShellError>; fn rest( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, starting_pos: usize, ) -> Result, ShellError>; fn opt( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, pos: usize, ) -> Result, ShellError>; - fn req(&self, context: &EvaluationContext, pos: usize) -> Result; + fn req( + &self, + engine_state: &EngineState, + stack: &mut Stack, + pos: usize, + ) -> Result; } impl CallExt for Call { fn get_flag( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, name: &str, ) -> Result, ShellError> { if let Some(expr) = self.get_flag_expr(name) { - let result = eval_expression(context, &expr)?; + let result = eval_expression(engine_state, stack, &expr)?; FromValue::from_value(&result).map(Some) } else { Ok(None) @@ -40,13 +53,14 @@ impl CallExt for Call { fn rest( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, starting_pos: usize, ) -> Result, ShellError> { let mut output = vec![]; for expr in self.positional.iter().skip(starting_pos) { - let result = eval_expression(context, expr)?; + let result = eval_expression(engine_state, stack, expr)?; output.push(FromValue::from_value(&result)?); } @@ -55,20 +69,26 @@ impl CallExt for Call { fn opt( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, pos: usize, ) -> Result, ShellError> { if let Some(expr) = self.nth(pos) { - let result = eval_expression(context, &expr)?; + let result = eval_expression(engine_state, stack, &expr)?; FromValue::from_value(&result).map(Some) } else { Ok(None) } } - fn req(&self, context: &EvaluationContext, pos: usize) -> Result { + fn req( + &self, + engine_state: &EngineState, + stack: &mut Stack, + pos: usize, + ) -> Result { if let Some(expr) = self.nth(pos) { - let result = eval_expression(context, &expr)?; + let result = eval_expression(engine_state, stack, &expr)?; FromValue::from_value(&result) } else { Err(ShellError::AccessBeyondEnd( diff --git a/crates/nu-engine/src/documentation.rs b/crates/nu-engine/src/documentation.rs index c028625d77..ce9c3b52b9 100644 --- a/crates/nu-engine/src/documentation.rs +++ b/crates/nu-engine/src/documentation.rs @@ -1,5 +1,8 @@ use itertools::Itertools; -use nu_protocol::{engine::EvaluationContext, Example, Signature, Span, Value}; +use nu_protocol::{ + engine::{EngineState, EvaluationContext}, + Example, Signature, Span, Value, +}; use std::collections::HashMap; const COMMANDS_DOCS_DIR: &str = "docs/commands"; @@ -22,14 +25,13 @@ impl Default for DocumentationConfig { } } -fn generate_doc(name: &str, context: &EvaluationContext) -> (Vec, Vec) { +fn generate_doc(name: &str, engine_state: &EngineState) -> (Vec, Vec) { let mut cols = vec![]; let mut vals = vec![]; - let command = context - .engine_state + let command = engine_state .find_decl(name.as_bytes()) - .map(|decl_id| context.engine_state.get_decl(decl_id)) + .map(|decl_id| engine_state.get_decl(decl_id)) .unwrap_or_else(|| panic!("Expected command '{}' from names to be in registry", name)); cols.push("name".to_string()); @@ -57,7 +59,7 @@ fn generate_doc(name: &str, context: &EvaluationContext) -> (Vec, Vec (Vec, Vec Value { - let signatures = context.get_signatures(); +pub fn generate_docs(engine_state: &EngineState) -> Value { + let signatures = engine_state.get_signatures(); // cmap will map parent commands to it's subcommands e.g. to -> [to csv, to yaml, to bson] let mut cmap: HashMap> = HashMap::new(); @@ -98,11 +100,11 @@ pub fn generate_docs(context: &EvaluationContext) -> Value { if !cmap.contains_key(&sig.name) { continue; } - let mut row_entries = generate_doc(&sig.name, context); + let mut row_entries = generate_doc(&sig.name, engine_state); // Iterate over all the subcommands of the parent command let mut sub_table = Vec::new(); for sub_name in cmap.get(&sig.name).unwrap_or(&Vec::new()) { - let (cols, vals) = generate_doc(sub_name, context); + let (cols, vals) = generate_doc(sub_name, engine_state); sub_table.push(Value::Record { cols, vals, @@ -148,7 +150,7 @@ fn retrieve_doc_link(name: &str) -> Option { pub fn get_documentation( sig: &Signature, examples: &[Example], - context: &EvaluationContext, + engine_state: &EngineState, config: &DocumentationConfig, ) -> String { let cmd_name = &sig.name; @@ -168,7 +170,7 @@ pub fn get_documentation( let mut subcommands = vec![]; if !config.no_subcommands { - let signatures = context.get_signatures(); + let signatures = engine_state.get_signatures(); for sig in signatures { if sig.name.starts_with(&format!("{} ", cmd_name)) { subcommands.push(format!(" {} - {}", sig.name, sig.usage)); @@ -324,15 +326,11 @@ fn get_flags_section(signature: &Signature) -> String { long_desc } -pub fn get_brief_help( - sig: &Signature, - examples: &[Example], - context: &EvaluationContext, -) -> String { +pub fn get_brief_help(sig: &Signature, examples: &[Example], engine_state: &EngineState) -> String { get_documentation( sig, examples, - context, + engine_state, &DocumentationConfig { no_subcommands: false, no_color: false, @@ -341,6 +339,6 @@ pub fn get_brief_help( ) } -pub fn get_full_help(sig: &Signature, examples: &[Example], context: &EvaluationContext) -> String { - get_documentation(sig, examples, context, &DocumentationConfig::default()) +pub fn get_full_help(sig: &Signature, examples: &[Example], engine_state: &EngineState) -> String { + get_documentation(sig, examples, engine_state, &DocumentationConfig::default()) } diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index 630067b03e..91901b3de2 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -1,5 +1,5 @@ use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement}; -use nu_protocol::engine::EvaluationContext; +use nu_protocol::engine::{EngineState, EvaluationContext, Stack}; use nu_protocol::{ IntoPipelineData, PipelineData, Range, ShellError, Span, Spanned, Type, Unit, Value, }; @@ -19,32 +19,33 @@ pub fn eval_operator(op: &Expression) -> Result { } fn eval_call( - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - let decl = context.engine_state.get_decl(call.decl_id); + let decl = engine_state.get_decl(call.decl_id); if call.named.iter().any(|(flag, _)| flag.item == "help") { - let full_help = get_full_help(&decl.signature(), &decl.examples(), context); + let full_help = get_full_help(&decl.signature(), &decl.examples(), engine_state); Ok(Value::String { val: full_help, span: call.head, } .into_pipeline_data()) } else if let Some(block_id) = decl.get_block_id() { - let mut state = context.enter_scope(); + let mut stack = stack.enter_scope(); for (arg, param) in call.positional.iter().zip( decl.signature() .required_positional .iter() .chain(decl.signature().optional_positional.iter()), ) { - let result = eval_expression(&state, arg)?; + let result = eval_expression(engine_state, &mut stack, arg)?; let var_id = param .var_id .expect("internal error: all custom parameters must have var_ids"); - state.add_var(var_id, result); + stack.add_var(var_id, result); } if let Some(rest_positional) = decl.signature().rest_positional { @@ -54,7 +55,7 @@ fn eval_call( decl.signature().required_positional.len() + decl.signature().optional_positional.len(), ) { - let result = eval_expression(&state, arg)?; + let result = eval_expression(&engine_state, &mut stack, arg)?; rest_items.push(result); } @@ -64,7 +65,7 @@ fn eval_call( Span::unknown() }; - state.add_var( + stack.add_var( rest_positional .var_id .expect("Internal error: rest positional parameter lacks var_id"), @@ -81,11 +82,11 @@ fn eval_call( for call_named in &call.named { if call_named.0.item == named.long { if let Some(arg) = &call_named.1 { - let result = eval_expression(&state, arg)?; + let result = eval_expression(&engine_state, &mut stack, arg)?; - state.add_var(var_id, result); + stack.add_var(var_id, result); } else { - state.add_var( + stack.add_var( var_id, Value::Bool { val: true, @@ -98,7 +99,7 @@ fn eval_call( } if !found && named.arg.is_none() { - state.add_var( + stack.add_var( var_id, Value::Bool { val: false, @@ -108,27 +109,27 @@ fn eval_call( } } } - let block = context.engine_state.get_block(block_id); - eval_block(&state, block, input) + let block = engine_state.get_block(block_id); + eval_block(engine_state, &mut stack, block, input) } else { - decl.run(context, call, input) + decl.run(engine_state, stack, call, input) } } fn eval_external( - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, name: &str, name_span: &Span, args: &[Expression], input: PipelineData, last_expression: bool, ) -> Result { - let decl_id = context - .engine_state + let decl_id = engine_state .find_decl("run_external".as_bytes()) .ok_or_else(|| ShellError::ExternalNotSupported(*name_span))?; - let command = context.engine_state.get_decl(decl_id); + let command = engine_state.get_decl(decl_id); let mut call = Call::new(); @@ -153,11 +154,12 @@ fn eval_external( )) } - command.run(context, &call, input) + command.run(engine_state, stack, &call, input) } pub fn eval_expression( - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, expr: &Expression, ) -> Result { match &expr.expr { @@ -173,13 +175,13 @@ pub fn eval_expression( val: *f, span: expr.span, }), - Expr::ValueWithUnit(e, unit) => match eval_expression(context, e)? { + Expr::ValueWithUnit(e, unit) => match eval_expression(engine_state, stack, e)? { Value::Int { val, .. } => Ok(compute(val, unit.item, unit.span)), _ => Err(ShellError::CantConvert("unit value".into(), e.span)), }, Expr::Range(from, next, to, operator) => { let from = if let Some(f) = from { - eval_expression(context, f)? + eval_expression(engine_state, stack, f)? } else { Value::Nothing { span: Span::unknown(), @@ -187,7 +189,7 @@ pub fn eval_expression( }; let next = if let Some(s) = next { - eval_expression(context, s)? + eval_expression(engine_state, stack, s)? } else { Value::Nothing { span: Span::unknown(), @@ -195,7 +197,7 @@ pub fn eval_expression( }; let to = if let Some(t) = to { - eval_expression(context, t)? + eval_expression(engine_state, stack, t)? } else { Value::Nothing { span: Span::unknown(), @@ -207,7 +209,7 @@ pub fn eval_expression( span: expr.span, }) } - Expr::Var(var_id) => context + Expr::Var(var_id) => stack .get_var(*var_id) .map_err(move |_| ShellError::VariableNotFoundAtRuntime(expr.span)), Expr::CellPath(cell_path) => Ok(Value::CellPath { @@ -215,32 +217,40 @@ pub fn eval_expression( span: expr.span, }), Expr::FullCellPath(cell_path) => { - let value = eval_expression(context, &cell_path.head)?; + let value = eval_expression(engine_state, stack, &cell_path.head)?; value.follow_cell_path(&cell_path.tail) } - Expr::RowCondition(_, expr) => eval_expression(context, expr), + Expr::RowCondition(_, expr) => eval_expression(engine_state, stack, expr), Expr::Call(call) => { // FIXME: protect this collect with ctrl-c Ok(Value::List { - vals: eval_call(context, call, PipelineData::new())?.collect(), + vals: eval_call(engine_state, stack, call, PipelineData::new())?.collect(), span: expr.span, }) } Expr::ExternalCall(name, span, args) => { // FIXME: protect this collect with ctrl-c Ok(Value::List { - vals: eval_external(context, name, span, args, PipelineData::new(), true)? - .collect(), + vals: eval_external( + engine_state, + stack, + name, + span, + args, + PipelineData::new(), + true, + )? + .collect(), span: expr.span, }) } Expr::Operator(_) => Ok(Value::Nothing { span: expr.span }), Expr::BinaryOp(lhs, op, rhs) => { let op_span = op.span; - let lhs = eval_expression(context, lhs)?; + let lhs = eval_expression(engine_state, stack, lhs)?; let op = eval_operator(op)?; - let rhs = eval_expression(context, rhs)?; + let rhs = eval_expression(engine_state, stack, rhs)?; match op { Operator::Plus => lhs.add(op_span, &rhs), @@ -264,13 +274,13 @@ pub fn eval_expression( } } Expr::Subexpression(block_id) => { - let block = context.engine_state.get_block(*block_id); + let block = engine_state.get_block(*block_id); - let state = context.enter_scope(); + let mut stack = stack.enter_scope(); // FIXME: protect this collect with ctrl-c Ok(Value::List { - vals: eval_block(&state, block, PipelineData::new())?.collect(), + vals: eval_block(engine_state, &mut stack, block, PipelineData::new())?.collect(), span: expr.span, }) } @@ -281,7 +291,7 @@ pub fn eval_expression( Expr::List(x) => { let mut output = vec![]; for expr in x { - output.push(eval_expression(context, expr)?); + output.push(eval_expression(engine_state, stack, expr)?); } Ok(Value::List { vals: output, @@ -291,14 +301,14 @@ pub fn eval_expression( Expr::Table(headers, vals) => { let mut output_headers = vec![]; for expr in headers { - output_headers.push(eval_expression(context, expr)?.as_string()?); + output_headers.push(eval_expression(engine_state, stack, expr)?.as_string()?); } let mut output_rows = vec![]; for val in vals { let mut row = vec![]; for expr in val { - row.push(eval_expression(context, expr)?); + row.push(eval_expression(engine_state, stack, expr)?); } output_rows.push(Value::Record { cols: output_headers.clone(), @@ -311,7 +321,7 @@ pub fn eval_expression( span: expr.span, }) } - Expr::Keyword(_, _, expr) => eval_expression(context, expr), + Expr::Keyword(_, _, expr) => eval_expression(engine_state, stack, expr), Expr::String(s) => Ok(Value::String { val: s.clone(), span: expr.span, @@ -330,7 +340,8 @@ pub fn eval_expression( } pub fn eval_block( - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, block: &Block, mut input: PipelineData, ) -> Result { @@ -342,14 +353,15 @@ pub fn eval_block( expr: Expr::Call(call), .. } => { - input = eval_call(context, call, input)?; + input = eval_call(engine_state, stack, call, input)?; } Expression { expr: Expr::ExternalCall(name, name_span, args), .. } => { input = eval_external( - context, + engine_state, + stack, name, name_span, args, @@ -359,7 +371,7 @@ pub fn eval_block( } elem => { - input = eval_expression(context, elem)?.into_pipeline_data(); + input = eval_expression(engine_state, stack, elem)?.into_pipeline_data(); } } } diff --git a/crates/nu-parser/tests/test_parser.rs b/crates/nu-parser/tests/test_parser.rs index da45d1f1c4..1b708f27e6 100644 --- a/crates/nu-parser/tests/test_parser.rs +++ b/crates/nu-parser/tests/test_parser.rs @@ -2,7 +2,7 @@ use nu_parser::ParseError; use nu_parser::*; use nu_protocol::{ ast::{Expr, Expression, Pipeline, Statement}, - engine::{Command, EngineState, StateWorkingSet}, + engine::{Command, EngineState, Stack, StateWorkingSet}, Signature, SyntaxShape, }; @@ -32,7 +32,8 @@ impl Command for Let { fn run( &self, - _context: &nu_protocol::engine::EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, _call: &nu_protocol::ast::Call, _input: nu_protocol::PipelineData, ) -> Result { diff --git a/crates/nu-protocol/src/engine/command.rs b/crates/nu-protocol/src/engine/command.rs index a8b3a5581d..6a6955c182 100644 --- a/crates/nu-protocol/src/engine/command.rs +++ b/crates/nu-protocol/src/engine/command.rs @@ -1,6 +1,6 @@ use crate::{ast::Call, value::Value, BlockId, Example, PipelineData, ShellError, Signature}; -use super::EvaluationContext; +use super::{EngineState, EvaluationContext, Stack}; pub trait Command: Send + Sync + CommandClone { fn name(&self) -> &str; @@ -17,7 +17,8 @@ pub trait Command: Send + Sync + CommandClone { fn run( &self, - context: &EvaluationContext, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result; diff --git a/crates/nu-protocol/src/signature.rs b/crates/nu-protocol/src/signature.rs index 4c2a36313b..b7037a4bc6 100644 --- a/crates/nu-protocol/src/signature.rs +++ b/crates/nu-protocol/src/signature.rs @@ -1,7 +1,9 @@ use crate::ast::Call; use crate::engine::Command; use crate::engine::CommandClone; +use crate::engine::EngineState; use crate::engine::EvaluationContext; +use crate::engine::Stack; use crate::BlockId; use crate::PipelineData; use crate::SyntaxShape; @@ -357,7 +359,8 @@ impl Command for Predeclaration { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, _call: &Call, _input: PipelineData, ) -> Result { @@ -386,7 +389,8 @@ impl Command for BlockCommand { fn run( &self, - _context: &EvaluationContext, + _engine_state: &EngineState, + _stack: &mut Stack, _call: &Call, _input: PipelineData, ) -> Result { diff --git a/src/main.rs b/src/main.rs index 0ccece42fb..9a2726c8af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,7 @@ use nu_parser::parse; use nu_protocol::{ ast::Call, engine::{EngineState, EvaluationContext, Stack, StateWorkingSet}, - ShellError, Value, + IntoPipelineData, PipelineData, ShellError, Value, }; use reedline::{Completer, CompletionActionHandler, DefaultPrompt, LineBuffer, Prompt}; @@ -82,14 +82,13 @@ fn main() -> Result<()> { miette_hook(x); })); - let engine_state = create_default_context(); + let mut engine_state = create_default_context(); if let Some(path) = std::env::args().nth(1) { let file = std::fs::read(&path).into_diagnostic()?; let (block, delta) = { - let engine_state = engine_state.borrow(); - let mut working_set = StateWorkingSet::new(&*engine_state); + let mut working_set = StateWorkingSet::new(&engine_state); let (output, err) = parse(&mut working_set, Some(&path), &file, false); if let Some(err) = err { report_error(&working_set, &err); @@ -99,20 +98,16 @@ fn main() -> Result<()> { (output, working_set.render()) }; - EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta); + EngineState::merge_delta(&mut engine_state, delta); - let state = EvaluationContext { - engine_state: engine_state.clone(), - stack: nu_protocol::engine::Stack::new(), - }; + let mut stack = nu_protocol::engine::Stack::new(); - match eval_block(&state, &block, Value::nothing()) { - Ok(value) => { - println!("{}", value.into_string()); + match eval_block(&engine_state, &mut stack, &block, PipelineData::new()) { + Ok(pipeline_data) => { + println!("{}", pipeline_data.collect_string()); } Err(err) => { - let engine_state = engine_state.borrow(); - let working_set = StateWorkingSet::new(&*engine_state); + let working_set = StateWorkingSet::new(&engine_state); report_error(&working_set, &err); @@ -127,28 +122,9 @@ fn main() -> Result<()> { let completer = NuCompleter::new(engine_state.clone()); let mut entry_num = 0; - let mut line_editor = Reedline::create() - .into_diagnostic()? - .with_history(Box::new( - FileBackedHistory::with_file(1000, "history.txt".into()).into_diagnostic()?, - )) - .into_diagnostic()? - .with_highlighter(Box::new(NuHighlighter { - engine_state: engine_state.clone(), - })) - .with_completion_action_handler(Box::new(FuzzyCompletion { - completer: Box::new(completer), - })) - // .with_completion_action_handler(Box::new( - // ListCompletionHandler::default().with_completer(Box::new(completer)), - // )) - .with_validator(Box::new(NuValidator { - engine_state: engine_state.clone(), - })); - let default_prompt = DefaultPrompt::new(1); let mut nu_prompt = NushellPrompt::new(); - let stack = nu_protocol::engine::Stack::new(); + let mut stack = nu_protocol::engine::Stack::new(); // Load config startup file if let Some(mut config_path) = nu_path::config_dir() { @@ -162,15 +138,34 @@ fn main() -> Result<()> { let config_filename = config_path.to_string_lossy().to_owned(); if let Ok(contents) = std::fs::read_to_string(&config_path) { - eval_source(engine_state.clone(), &stack, &contents, &config_filename); + eval_source(&mut engine_state, &mut stack, &contents, &config_filename); } } } loop { + let mut line_editor = Reedline::create() + .into_diagnostic()? + .with_history(Box::new( + FileBackedHistory::with_file(1000, "history.txt".into()).into_diagnostic()?, + )) + .into_diagnostic()? + .with_highlighter(Box::new(NuHighlighter { + engine_state: engine_state.clone(), + })) + .with_completion_action_handler(Box::new(FuzzyCompletion { + completer: Box::new(completer.clone()), + })) + // .with_completion_action_handler(Box::new( + // ListCompletionHandler::default().with_completer(Box::new(completer)), + // )) + .with_validator(Box::new(NuValidator { + engine_state: engine_state.clone(), + })); + let prompt = update_prompt( PROMPT_COMMAND, - engine_state.clone(), + &engine_state, &stack, &mut nu_prompt, &default_prompt, @@ -184,25 +179,27 @@ fn main() -> Result<()> { if s.trim() == "exit" { break; } else if s.trim() == "vars" { - engine_state.borrow().print_vars(); + engine_state.print_vars(); continue; } else if s.trim() == "decls" { - engine_state.borrow().print_decls(); + engine_state.print_decls(); continue; } else if s.trim() == "blocks" { - engine_state.borrow().print_blocks(); + engine_state.print_blocks(); continue; } else if s.trim() == "stack" { stack.print_stack(); continue; } else if s.trim() == "contents" { - engine_state.borrow().print_contents(); + engine_state.print_contents(); continue; } + let mut engine_state = engine_state.clone(); + eval_source( - engine_state.clone(), - &stack, + &mut engine_state, + &mut stack, &s, &format!("entry #{}", entry_num), ); @@ -229,16 +226,19 @@ fn main() -> Result<()> { } } -fn print_value(value: Value, state: &EvaluationContext) -> Result<(), ShellError> { +fn print_value(value: Value, engine_state: &EngineState) -> Result<(), ShellError> { // If the table function is in the declarations, then we can use it // to create the table value that will be printed in the terminal - let engine_state = state.engine_state.borrow(); let output = match engine_state.find_decl("table".as_bytes()) { Some(decl_id) => { - let table = engine_state - .get_decl(decl_id) - .run(state, &Call::new(), value)?; - table.into_string() + let mut stack = Stack::new(); + let table = engine_state.get_decl(decl_id).run( + engine_state, + &mut stack, + &Call::new(), + value.into_pipeline_data(), + )?; + table.collect_string() } None => value.into_string(), }; @@ -254,7 +254,7 @@ fn print_value(value: Value, state: &EvaluationContext) -> Result<(), ShellError fn update_prompt<'prompt>( env_variable: &str, - engine_state: Rc>, + engine_state: &EngineState, stack: &Stack, nu_prompt: &'prompt mut NushellPrompt, default_prompt: &'prompt DefaultPrompt, @@ -271,8 +271,7 @@ fn update_prompt<'prompt>( } let (block, delta) = { - let ref_engine_state = engine_state.borrow(); - let mut working_set = StateWorkingSet::new(&ref_engine_state); + let mut working_set = StateWorkingSet::new(&engine_state); let (output, err) = parse(&mut working_set, None, prompt_command.as_bytes(), false); if let Some(err) = err { report_error(&working_set, &err); @@ -281,26 +280,13 @@ fn update_prompt<'prompt>( (output, working_set.render()) }; - EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta); + let mut stack = stack.clone(); - let state = nu_protocol::engine::EvaluationContext { - engine_state: engine_state.clone(), - stack: stack.clone(), - }; - - let evaluated_prompt = match eval_block(&state, &block, Value::nothing()) { - Ok(value) => match value.as_string() { - Ok(prompt) => prompt, - Err(err) => { - let engine_state = engine_state.borrow(); - let working_set = StateWorkingSet::new(&*engine_state); - report_error(&working_set, &err); - return default_prompt as &dyn Prompt; - } - }, + let evaluated_prompt = match eval_block(&engine_state, &mut stack, &block, PipelineData::new()) + { + Ok(pipeline_data) => pipeline_data.collect_string(), Err(err) => { - let engine_state = engine_state.borrow(); - let working_set = StateWorkingSet::new(&*engine_state); + let working_set = StateWorkingSet::new(&engine_state); report_error(&working_set, &err); return default_prompt as &dyn Prompt; } @@ -312,14 +298,13 @@ fn update_prompt<'prompt>( } fn eval_source( - engine_state: Rc>, - stack: &Stack, + engine_state: &mut EngineState, + stack: &mut Stack, source: &str, fname: &str, ) -> bool { let (block, delta) = { - let engine_state = engine_state.borrow(); - let mut working_set = StateWorkingSet::new(&*engine_state); + let mut working_set = StateWorkingSet::new(&engine_state); let (output, err) = parse( &mut working_set, Some(fname), // format!("entry #{}", entry_num) @@ -333,26 +318,19 @@ fn eval_source( (output, working_set.render()) }; - EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta); + EngineState::merge_delta(engine_state, delta); - let state = nu_protocol::engine::EvaluationContext { - engine_state: engine_state.clone(), - stack: stack.clone(), - }; - - match eval_block(&state, &block, Value::nothing()) { - Ok(value) => { - if let Err(err) = print_value(value, &state) { - let engine_state = engine_state.borrow(); - let working_set = StateWorkingSet::new(&*engine_state); + match eval_block(&engine_state, stack, &block, PipelineData::new()) { + Ok(pipeline_data) => { + if let Err(err) = print_value(pipeline_data.into_value(), &engine_state) { + let working_set = StateWorkingSet::new(&engine_state); report_error(&working_set, &err); return false; } } Err(err) => { - let engine_state = engine_state.borrow(); - let working_set = StateWorkingSet::new(&*engine_state); + let working_set = StateWorkingSet::new(&engine_state); report_error(&working_set, &err); return false;