Implement if
This commit is contained in:
parent
f15c8ef2ef
commit
f0c759d92a
@ -12,18 +12,7 @@ use crate::{token, tree, Result, Value, VariableMap};
|
||||
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||
pub fn eval(string: &str) -> Result<Value> {
|
||||
let mut context = VariableMap::new();
|
||||
let eval = eval_with_context(string, &mut context);
|
||||
|
||||
match eval {
|
||||
Ok(output) => {
|
||||
if output.is_empty() {
|
||||
Ok(Value::Map(context))
|
||||
} else {
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
eval_with_context(string, &mut context)
|
||||
}
|
||||
|
||||
/// Evaluate the given expression string with the given context.
|
||||
|
@ -58,18 +58,54 @@ impl Macro for If {
|
||||
fn info(&self) -> MacroInfo<'static> {
|
||||
MacroInfo {
|
||||
identifier: "if",
|
||||
description: "Evaluates the first argument. If true, it does the second argument. If false, it does the third argument",
|
||||
group: "general",
|
||||
description: "Evaluates the first argument. If true, it does the second argument.",
|
||||
group: "logic",
|
||||
inputs: vec![
|
||||
ValueType::List(vec![
|
||||
ValueType::Boolean,
|
||||
ValueType::Any,
|
||||
]),
|
||||
ValueType::List(vec![
|
||||
ValueType::Function,
|
||||
ValueType::Any,
|
||||
])],
|
||||
}
|
||||
}
|
||||
|
||||
fn run(&self, argument: &Value) -> Result<Value> {
|
||||
let argument = argument.as_fixed_len_list(2)?;
|
||||
let (condition, if_true) = (&argument[0], &argument[1]);
|
||||
let condition = if let Ok(function) = condition.as_function() {
|
||||
function.run()?.as_boolean()?
|
||||
} else {
|
||||
condition.as_boolean()?
|
||||
};
|
||||
|
||||
if condition {
|
||||
Ok(if_true.clone())
|
||||
} else {
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IfElse;
|
||||
|
||||
impl Macro for IfElse {
|
||||
fn info(&self) -> MacroInfo<'static> {
|
||||
MacroInfo {
|
||||
identifier: "if_else",
|
||||
description: "Evaluates the first argument. If true, it does the second argument. If false, it does the third argument",
|
||||
group: "logic",
|
||||
inputs: vec![
|
||||
ValueType::List(vec![
|
||||
ValueType::Boolean,
|
||||
ValueType::Any,
|
||||
ValueType::Any
|
||||
]),
|
||||
ValueType::List(vec![
|
||||
ValueType::Function,
|
||||
ValueType::Any,
|
||||
ValueType::Any
|
||||
])],
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ pub mod time;
|
||||
///
|
||||
/// This list is used to match identifiers with macros and to provide info to
|
||||
/// the shell.
|
||||
pub const MACRO_LIST: [&'static dyn Macro; 56] = [
|
||||
pub const MACRO_LIST: [&'static dyn Macro; 57] = [
|
||||
&collections::Count,
|
||||
&collections::CreateTable,
|
||||
&collections::Get,
|
||||
@ -80,6 +80,7 @@ pub const MACRO_LIST: [&'static dyn Macro; 56] = [
|
||||
&gui::Plot,
|
||||
&gui::Gui,
|
||||
&logic::If,
|
||||
&logic::IfElse,
|
||||
&logic::Loop,
|
||||
&network::Download,
|
||||
&package_management::CoprRepositories,
|
||||
|
@ -68,9 +68,6 @@ impl VariableMap {
|
||||
if argument.is_empty() {
|
||||
return self.call_function(function_identifier, &value);
|
||||
}
|
||||
|
||||
let value_type = value.value_type();
|
||||
|
||||
let list = Value::List(vec![value, argument.clone()]);
|
||||
|
||||
return self.call_function(function_identifier, &list);
|
||||
|
@ -20,20 +20,20 @@ fn r#if() {
|
||||
assert_eq!(Value::Integer(1), value);
|
||||
|
||||
let value = eval("if(false, 1)").unwrap();
|
||||
assert!(value.is_empty());
|
||||
assert_eq!(Value::Empty, value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn r#if_else() {
|
||||
let value = eval("if(true, 1, 2)").unwrap();
|
||||
let value = eval("if_else(true, 1, 2)").unwrap();
|
||||
assert_eq!(Value::Integer(1), value);
|
||||
|
||||
let value = eval("if(false, 1, 2)").unwrap();
|
||||
let value = eval("if_else(false, 1, 2)").unwrap();
|
||||
assert_eq!(Value::Integer(2), value);
|
||||
|
||||
let value = eval("if(true, '1', '2')").unwrap();
|
||||
let value = eval("if_else(true, '1', '2')").unwrap();
|
||||
assert_eq!(Value::Integer(1), value);
|
||||
|
||||
let value = eval("if(false, '1', '2')").unwrap();
|
||||
let value = eval("if_else(false, '1', '2')").unwrap();
|
||||
assert_eq!(Value::Integer(2), value);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user