bool type for binary operations (#5779)

* bool type for binary operations

* fixed type in commands
This commit is contained in:
Fernando Herrera 2022-06-14 20:31:14 -05:00 committed by GitHub
parent fe88d58b1e
commit 8d5848c955
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 3 deletions

View File

@ -39,7 +39,7 @@ impl Command for BuildString {
}),
},
Example {
example: "build-string (1 + 2) = one ' ' plus ' ' two",
example: r#"build-string $"(1 + 2)" = one ' ' plus ' ' two"#,
description: "Builds a string from letters a b c",
result: Some(Value::String {
val: "3=one plus two".to_string(),

View File

@ -161,7 +161,7 @@ impl Command for Char {
SyntaxShape::Any,
"the name of the character to output",
)
.rest("rest", SyntaxShape::String, "multiple Unicode bytes")
.rest("rest", SyntaxShape::Any, "multiple Unicode bytes")
.switch("list", "List all supported character names", Some('l'))
.switch("unicode", "Unicode string i.e. 1f378", Some('u'))
.switch("integer", "Create a codepoint from an integer", Some('i'))

View File

@ -1872,6 +1872,16 @@ pub fn parse_full_cell_path(
.type_scope
.add_type(working_set.type_scope.get_last_output());
let ty = output
.pipelines
.last()
.and_then(|Pipeline { expressions, .. }| expressions.last())
.map(|expr| match expr.expr {
Expr::BinaryOp(..) => expr.ty.clone(),
_ => working_set.type_scope.get_last_output(),
})
.unwrap_or_else(|| working_set.type_scope.get_last_output());
error = error.or(err);
let block_id = working_set.add_block(output);
@ -1881,7 +1891,7 @@ pub fn parse_full_cell_path(
Expression {
expr: Expr::Subexpression(block_id),
span: head_span,
ty: working_set.type_scope.get_last_output(),
ty,
custom_completion: None,
},
true,

View File

@ -929,6 +929,45 @@ mod input_types {
}
}
#[derive(Clone)]
pub struct IfMocked;
impl Command for IfMocked {
fn name(&self) -> &str {
"if"
}
fn usage(&self) -> &str {
"Mock if command"
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build("if")
.required("cond", SyntaxShape::Expression, "condition to check")
.required(
"then_block",
SyntaxShape::Block(Some(vec![])),
"block to run if check succeeds",
)
.optional(
"else_expression",
SyntaxShape::Keyword(b"else".to_vec(), Box::new(SyntaxShape::Expression)),
"expression or block to run if check fails",
)
.category(Category::Core)
}
fn run(
&self,
_engine_state: &EngineState,
_stack: &mut Stack,
_call: &nu_protocol::ast::Call,
_input: nu_protocol::PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
todo!()
}
}
fn add_declations(engine_state: &mut EngineState) {
let delta = {
let mut working_set = StateWorkingSet::new(&engine_state);
@ -942,6 +981,7 @@ mod input_types {
working_set.add_decl(Box::new(AggMin));
working_set.add_decl(Box::new(Collect));
working_set.add_decl(Box::new(WithColumn));
working_set.add_decl(Box::new(IfMocked));
working_set.render()
};
@ -1194,4 +1234,26 @@ mod input_types {
_ => panic!("Expected expression Call not found"),
}
}
#[test]
fn operations_within_blocks_test() {
let mut engine_state = EngineState::new();
add_declations(&mut engine_state);
let mut working_set = StateWorkingSet::new(&engine_state);
let inputs = vec![
r#"let a = 'b'; ($a == 'b') || ($a == 'b')"#,
r#"let a = 'b'; ($a == 'b') || ($a == 'b') && ($a == 'b')"#,
r#"let a = 1; ($a == 1) || ($a == 2) && ($a == 3)"#,
r#"let a = 'b'; if ($a == 'b') || ($a == 'b') { true } else { false }"#,
r#"let a = 1; if ($a == 1) || ($a > 0) { true } else { false }"#,
];
for input in inputs {
let (block, err) = parse(&mut working_set, None, input.as_bytes(), true, &[]);
assert!(err.is_none(), "testing: {}", input);
assert!(block.len() == 2, "testing: {}", input);
}
}
}