Split blocks and closures (#7075)

* Split closures and blocks

* Tests mostly working

* finish last fixes, passes all tests

* fmt
This commit is contained in:
JT
2022-11-10 21:21:49 +13:00
committed by GitHub
parent 921a66554e
commit 63433f1bc8
57 changed files with 576 additions and 220 deletions

View File

@ -19,11 +19,7 @@ impl Command for Def {
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("def_name", SyntaxShape::String, "definition name")
.required("params", SyntaxShape::Signature, "parameters")
.required(
"block",
SyntaxShape::Block(Some(vec![])),
"body of the definition",
)
.required("body", SyntaxShape::Closure(None), "body of the definition")
.category(Category::Core)
}

View File

@ -19,11 +19,7 @@ impl Command for DefEnv {
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("def_name", SyntaxShape::String, "definition name")
.required("params", SyntaxShape::Signature, "parameters")
.required(
"block",
SyntaxShape::Block(Some(vec![])),
"body of the definition",
)
.required("block", SyntaxShape::Block, "body of the definition")
.category(Category::Core)
}

View File

@ -1,6 +1,6 @@
use nu_engine::{eval_block, CallExt};
use nu_protocol::ast::Call;
use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack};
use nu_protocol::engine::{Closure, Command, EngineState, Stack};
use nu_protocol::{
Category, Example, ListStream, PipelineData, RawStream, ShellError, Signature, SyntaxShape,
Type, Value,
@ -20,8 +20,8 @@ impl Command for Do {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("do")
.required("closure", SyntaxShape::Any, "the closure to run")
.input_output_types(vec![(Type::Any, Type::Any)])
.required("block", SyntaxShape::Any, "the block to run")
.switch(
"ignore-errors",
"ignore shell errors as the block runs",
@ -43,7 +43,7 @@ impl Command for Do {
call: &Call,
input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let block: CaptureBlock = call.req(engine_state, stack, 0)?;
let block: Closure = call.req(engine_state, stack, 0)?;
let rest: Vec<Value> = call.rest(engine_state, stack, 1)?;
let ignore_errors = call.has_flag("ignore-errors");
let capture_errors = call.has_flag("capture-errors");

View File

@ -19,11 +19,7 @@ impl Command for ExportDef {
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("name", SyntaxShape::String, "definition name")
.required("params", SyntaxShape::Signature, "parameters")
.required(
"block",
SyntaxShape::Block(Some(vec![])),
"body of the definition",
)
.required("block", SyntaxShape::Block, "body of the definition")
.category(Category::Core)
}

View File

@ -19,11 +19,7 @@ impl Command for ExportDefEnv {
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("name", SyntaxShape::String, "definition name")
.required("params", SyntaxShape::Signature, "parameters")
.required(
"block",
SyntaxShape::Block(Some(vec![])),
"body of the definition",
)
.required("block", SyntaxShape::Block, "body of the definition")
.category(Category::Core)
}

View File

@ -1,6 +1,6 @@
use nu_engine::{eval_block, eval_expression, CallExt};
use nu_protocol::ast::Call;
use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack};
use nu_protocol::engine::{Closure, Command, EngineState, Stack};
use nu_protocol::{
Category, Example, IntoInterruptiblePipelineData, ListStream, PipelineData, Signature, Span,
SyntaxShape, Type, Value,
@ -31,11 +31,7 @@ impl Command for For {
SyntaxShape::Keyword(b"in".to_vec(), Box::new(SyntaxShape::Any)),
"range of the loop",
)
.required(
"block",
SyntaxShape::Block(Some(vec![])),
"the block to run",
)
.required("block", SyntaxShape::Block, "the block to run")
.switch(
"numbered",
"returned a numbered item ($it.index and $it.item)",
@ -75,7 +71,7 @@ impl Command for For {
.expect("internal error: missing keyword");
let values = eval_expression(engine_state, stack, keyword_expr)?;
let capture_block: CaptureBlock = call.req(engine_state, stack, 2)?;
let capture_block: Closure = call.req(engine_state, stack, 2)?;
let numbered = call.has_flag("numbered");

View File

@ -1,8 +1,8 @@
use nu_engine::{eval_block, eval_expression, eval_expression_with_input, CallExt};
use nu_protocol::ast::Call;
use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack};
use nu_protocol::engine::{Block, Command, EngineState, Stack};
use nu_protocol::{
Category, Example, FromValue, PipelineData, ShellError, Signature, SyntaxShape, Type, Value,
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Type, Value,
};
#[derive(Clone)]
@ -23,7 +23,7 @@ impl Command for If {
.required("cond", SyntaxShape::Expression, "condition to check")
.required(
"then_block",
SyntaxShape::Block(Some(vec![])),
SyntaxShape::Block,
"block to run if check succeeds",
)
.optional(
@ -51,7 +51,7 @@ impl Command for If {
input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let cond = call.positional_nth(0).expect("checked through parser");
let then_block: CaptureBlock = call.req(engine_state, stack, 1)?;
let then_block: Block = call.req(engine_state, stack, 1)?;
let else_case = call.positional_nth(2);
let result = eval_expression(engine_state, stack, cond)?;
@ -59,10 +59,9 @@ impl Command for If {
Value::Bool { val, .. } => {
if *val {
let block = engine_state.get_block(then_block.block_id);
let mut stack = stack.captures_to_stack(&then_block.captures);
eval_block(
engine_state,
&mut stack,
stack,
block,
input,
call.redirect_stdout,
@ -71,14 +70,10 @@ impl Command for If {
} 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 result = eval_expression(engine_state, stack, else_expr)?;
let else_block: CaptureBlock = FromValue::from_value(&result)?;
let mut stack = stack.captures_to_stack(&else_block.captures);
let block = engine_state.get_block(block_id);
eval_block(
engine_state,
&mut stack,
stack,
block,
input,
call.redirect_stdout,

View File

@ -18,11 +18,7 @@ impl Command for Module {
Signature::build("module")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("module_name", SyntaxShape::String, "module name")
.required(
"block",
SyntaxShape::Block(Some(vec![])),
"body of the module",
)
.required("block", SyntaxShape::Block, "body of the module")
.category(Category::Core)
}