diff --git a/README.md b/README.md index e0003a47..6f9c78ae 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,18 @@ fn main() { } ``` +To return a `Dynamic` value, simply `Box` it and return it. + +```rust +fn decide(yes_no: bool) -> Dynamic { + if yes_no { + Box::new(42_i64) + } else { + Box::new("hello world!".to_string()) // remember &str is not supported + } +} +``` + # Working with generic functions Generic functions can be used in Rhai, but you'll need to register separate instances for each concrete type: @@ -217,7 +229,7 @@ You can also see in this example how you can register multiple functions (or in # Override built-in functions -Any similarly-named function defined in a script with the correct argument types overrides any built-in function. +Any similarly-named function defined in a script overrides any built-in function. ```rust // Override the built-in function 'to_int' @@ -445,9 +457,10 @@ this() & that(); // both this() and that() are evaluated ```rust if true { - print("it's true!"); -} -else { + print("It's true!"); +} else if true { + print("It's true again!"); +} else { print("It's false!"); } ``` @@ -456,11 +469,10 @@ else { ```rust let x = 10; + while x > 0 { print(x); - if x == 5 { - break; - } + if x == 5 { break; } x = x - 1; } ``` @@ -499,18 +511,6 @@ fn add(x, y) { print(add(2, 3)) ``` -To return a `Dynamic` value, simply `Box` it and return it. - -```rust -fn decide(yes_no: bool) -> Dynamic { - if yes_no { - Box::new(42_i64) - } else { - Box::new("hello world!".to_string()) // remember &str is not supported - } -} -``` - ## Arrays You can create arrays of values, and then access them with numeric indices. diff --git a/src/engine.rs b/src/engine.rs index ef466481..156fa342 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -818,18 +818,6 @@ impl Engine { last_result } - Stmt::If(guard, body) => self - .eval_expr(scope, guard)? - .downcast::() - .map_err(|_| EvalAltResult::ErrorIfGuard) - .and_then(|guard_val| { - if *guard_val { - self.eval_stmt(scope, body) - } else { - Ok(Box::new(())) - } - }), - Stmt::IfElse(guard, body, else_body) => self .eval_expr(scope, guard)? .downcast::() @@ -837,8 +825,10 @@ impl Engine { .and_then(|guard_val| { if *guard_val { self.eval_stmt(scope, body) + } else if else_body.is_some() { + self.eval_stmt(scope, else_body.as_ref().unwrap()) } else { - self.eval_stmt(scope, else_body) + Ok(Box::new(())) } }), diff --git a/src/parser.rs b/src/parser.rs index 8f9db5f0..001252d3 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -155,8 +155,7 @@ pub struct FnDef { #[derive(Debug, Clone)] pub enum Stmt { - If(Box, Box), - IfElse(Box, Box, Box), + IfElse(Box, Box, Option>), While(Box, Box), Loop(Box), For(String, Box, Box), @@ -1308,14 +1307,19 @@ fn parse_if<'a>(input: &mut Peekable>) -> Result { input.next(); - let else_body = parse_block(input)?; + + let else_body = match input.peek() { + Some(&(Token::If, _)) => parse_if(input)?, + _ => parse_block(input)?, + }; + Ok(Stmt::IfElse( Box::new(guard), Box::new(body), - Box::new(else_body), + Some(Box::new(else_body)), )) } - _ => Ok(Stmt::If(Box::new(guard), Box::new(body))), + _ => Ok(Stmt::IfElse(Box::new(guard), Box::new(body), None)), } } diff --git a/tests/if_block.rs b/tests/if_block.rs index 94775618..7440e448 100644 --- a/tests/if_block.rs +++ b/tests/if_block.rs @@ -7,4 +7,21 @@ fn test_if() { assert_eq!(engine.eval::("if true { 55 }"), Ok(55)); assert_eq!(engine.eval::("if false { 55 } else { 44 }"), Ok(44)); assert_eq!(engine.eval::("if true { 55 } else { 44 }"), Ok(55)); + assert_eq!( + engine.eval::("if false { 55 } else if true { 33 } else { 44 }"), + Ok(33) + ); + assert_eq!( + engine.eval::( + r" + if false { 55 } + else if false { 33 } + else if false { 66 } + else if false { 77 } + else if false { 88 } + else { 44 } + " + ), + Ok(44) + ); }