Add else if control flow.

This commit is contained in:
Stephen Chung 2020-03-02 17:04:56 +08:00
parent cc87214750
commit ed8d2ac20f
4 changed files with 48 additions and 37 deletions

View File

@ -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 # Working with generic functions
Generic functions can be used in Rhai, but you'll need to register separate instances for each concrete type: 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 # 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 ```rust
// Override the built-in function 'to_int' // Override the built-in function 'to_int'
@ -445,9 +457,10 @@ this() & that(); // both this() and that() are evaluated
```rust ```rust
if true { if true {
print("it's true!"); print("It's true!");
} } else if true {
else { print("It's true again!");
} else {
print("It's false!"); print("It's false!");
} }
``` ```
@ -456,11 +469,10 @@ else {
```rust ```rust
let x = 10; let x = 10;
while x > 0 { while x > 0 {
print(x); print(x);
if x == 5 { if x == 5 { break; }
break;
}
x = x - 1; x = x - 1;
} }
``` ```
@ -499,18 +511,6 @@ fn add(x, y) {
print(add(2, 3)) 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 ## Arrays
You can create arrays of values, and then access them with numeric indices. You can create arrays of values, and then access them with numeric indices.

View File

@ -818,18 +818,6 @@ impl Engine {
last_result last_result
} }
Stmt::If(guard, body) => self
.eval_expr(scope, guard)?
.downcast::<bool>()
.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 Stmt::IfElse(guard, body, else_body) => self
.eval_expr(scope, guard)? .eval_expr(scope, guard)?
.downcast::<bool>() .downcast::<bool>()
@ -837,8 +825,10 @@ impl Engine {
.and_then(|guard_val| { .and_then(|guard_val| {
if *guard_val { if *guard_val {
self.eval_stmt(scope, body) self.eval_stmt(scope, body)
} else if else_body.is_some() {
self.eval_stmt(scope, else_body.as_ref().unwrap())
} else { } else {
self.eval_stmt(scope, else_body) Ok(Box::new(()))
} }
}), }),

View File

@ -155,8 +155,7 @@ pub struct FnDef {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Stmt { pub enum Stmt {
If(Box<Expr>, Box<Stmt>), IfElse(Box<Expr>, Box<Stmt>, Option<Box<Stmt>>),
IfElse(Box<Expr>, Box<Stmt>, Box<Stmt>),
While(Box<Expr>, Box<Stmt>), While(Box<Expr>, Box<Stmt>),
Loop(Box<Stmt>), Loop(Box<Stmt>),
For(String, Box<Expr>, Box<Stmt>), For(String, Box<Expr>, Box<Stmt>),
@ -1308,14 +1307,19 @@ fn parse_if<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<Stmt, ParseEr
match input.peek() { match input.peek() {
Some(&(Token::Else, _)) => { Some(&(Token::Else, _)) => {
input.next(); 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( Ok(Stmt::IfElse(
Box::new(guard), Box::new(guard),
Box::new(body), 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)),
} }
} }

View File

@ -7,4 +7,21 @@ fn test_if() {
assert_eq!(engine.eval::<i64>("if true { 55 }"), Ok(55)); assert_eq!(engine.eval::<i64>("if true { 55 }"), Ok(55));
assert_eq!(engine.eval::<i64>("if false { 55 } else { 44 }"), Ok(44)); assert_eq!(engine.eval::<i64>("if false { 55 } else { 44 }"), Ok(44));
assert_eq!(engine.eval::<i64>("if true { 55 } else { 44 }"), Ok(55)); assert_eq!(engine.eval::<i64>("if true { 55 } else { 44 }"), Ok(55));
assert_eq!(
engine.eval::<i64>("if false { 55 } else if true { 33 } else { 44 }"),
Ok(33)
);
assert_eq!(
engine.eval::<i64>(
r"
if false { 55 }
else if false { 33 }
else if false { 66 }
else if false { 77 }
else if false { 88 }
else { 44 }
"
),
Ok(44)
);
} }