Add else to if
This commit is contained in:
parent
132a640df2
commit
30b914e7b7
@ -120,6 +120,7 @@ impl Engine {
|
|||||||
let result3 = self.call_fn("clone", Some(a3), None, None, None, None, None);
|
let result3 = self.call_fn("clone", Some(a3), None, None, None, None, None);
|
||||||
let result4 = self.call_fn("clone", Some(a4), None, None, None, None, None);
|
let result4 = self.call_fn("clone", Some(a4), None, None, None, None, None);
|
||||||
let result5 = self.call_fn("clone", Some(a5), None, None, None, None, None);
|
let result5 = self.call_fn("clone", Some(a5), None, None, None, None, None);
|
||||||
|
|
||||||
match (result1, result2, result3, result4, result5) {
|
match (result1, result2, result3, result4, result5) {
|
||||||
(Ok(r1), Ok(r2), Ok(r3), Ok(r4), Ok(r5)) => {
|
(Ok(r1), Ok(r2), Ok(r3), Ok(r4), Ok(r5)) => {
|
||||||
new_scope.push((f.params[0].clone(), r1));
|
new_scope.push((f.params[0].clone(), r1));
|
||||||
@ -480,6 +481,20 @@ impl Engine {
|
|||||||
Err(_) => Err(EvalError::IfGuardMismatch)
|
Err(_) => Err(EvalError::IfGuardMismatch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Stmt::IfElse(ref guard, ref body, ref else_body) => {
|
||||||
|
let guard_result = try!(self.eval_expr(scope, guard));
|
||||||
|
match guard_result.downcast::<bool>() {
|
||||||
|
Ok(g) => {
|
||||||
|
if *g {
|
||||||
|
self.eval_stmt(scope, body)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.eval_stmt(scope, else_body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => Err(EvalError::IfGuardMismatch)
|
||||||
|
}
|
||||||
|
}
|
||||||
Stmt::While(ref guard, ref body) => {
|
Stmt::While(ref guard, ref body) => {
|
||||||
loop {
|
loop {
|
||||||
let guard_result = try!(self.eval_expr(scope, guard));
|
let guard_result = try!(self.eval_expr(scope, guard));
|
||||||
@ -684,6 +699,20 @@ fn test_if() {
|
|||||||
else {
|
else {
|
||||||
assert!(false);
|
assert!(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Ok(result) = engine.eval("if false { 55 } else { 44 }".to_string()).unwrap().downcast::<i32>() {
|
||||||
|
assert_eq!(*result, 44);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert!(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(result) = engine.eval("if true { 55 } else { 44 }".to_string()).unwrap().downcast::<i32>() {
|
||||||
|
assert_eq!(*result, 55);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert!(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -13,13 +13,13 @@ mod parser;
|
|||||||
|
|
||||||
// Todo (in no particular order):
|
// Todo (in no particular order):
|
||||||
// * Doc some examples
|
// * Doc some examples
|
||||||
// * Hello world
|
|
||||||
// * Functions and methods
|
|
||||||
// * Registering types
|
|
||||||
// * Maintaining state
|
// * Maintaining state
|
||||||
// * Overloading
|
// * Overloading
|
||||||
// * How it works
|
// * How it works
|
||||||
// * Vectors
|
// * Vectors
|
||||||
|
// * Return
|
||||||
|
// * Break
|
||||||
|
// * Tighten parser?
|
||||||
// * Errors with positions?
|
// * Errors with positions?
|
||||||
// * Remove empty box values?
|
// * Remove empty box values?
|
||||||
|
|
||||||
|
@ -84,8 +84,8 @@ pub struct FnDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Stmt { If(Box<Expr>, Box<Stmt>), While(Box<Expr>, Box<Stmt>), Var(String, Option<Box<Expr>>),
|
pub enum Stmt { If(Box<Expr>, Box<Stmt>), IfElse(Box<Expr>, Box<Stmt>, Box<Stmt>), While(Box<Expr>, Box<Stmt>),
|
||||||
Block(Box<Vec<Stmt>>), Expr(Box<Expr>) }
|
Var(String, Option<Box<Expr>>), Block(Box<Vec<Stmt>>), Expr(Box<Expr>) }
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Expr { IntConst(i32), Identifier(String), StringConst(String), FnCall(String, Box<Vec<Expr>>),
|
pub enum Expr { IntConst(i32), Identifier(String), StringConst(String), FnCall(String, Box<Vec<Expr>>),
|
||||||
@ -93,7 +93,7 @@ pub enum Expr { IntConst(i32), Identifier(String), StringConst(String), FnCall(S
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Token { IntConst(i32), Identifier(String), StringConst(String), LCurly, RCurly, LParen, RParen, LSquare, RSquare,
|
pub enum Token { IntConst(i32), Identifier(String), StringConst(String), LCurly, RCurly, LParen, RParen, LSquare, RSquare,
|
||||||
Plus, Minus, Multiply, Divide, Semicolon, Colon, Comma, Period, Equals, True, False, Var, If, While,
|
Plus, Minus, Multiply, Divide, Semicolon, Colon, Comma, Period, Equals, True, False, Var, If, Else, While,
|
||||||
LessThan, GreaterThan, Bang, LessThanEqual, GreaterThanEqual, EqualTo, NotEqualTo, Pipe, Or, Ampersand, And, Fn,
|
LessThan, GreaterThan, Bang, LessThanEqual, GreaterThanEqual, EqualTo, NotEqualTo, Pipe, Or, Ampersand, And, Fn,
|
||||||
LexErr(LexError) }
|
LexErr(LexError) }
|
||||||
|
|
||||||
@ -151,6 +151,9 @@ impl<'a> Iterator for TokenIterator<'a> {
|
|||||||
else if out == "if" {
|
else if out == "if" {
|
||||||
return Some(Token::If);
|
return Some(Token::If);
|
||||||
}
|
}
|
||||||
|
else if out == "else" {
|
||||||
|
return Some(Token::Else);
|
||||||
|
}
|
||||||
else if out == "while" {
|
else if out == "while" {
|
||||||
return Some(Token::While);
|
return Some(Token::While);
|
||||||
}
|
}
|
||||||
@ -482,7 +485,16 @@ fn parse_if<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<Stmt, ParseEr
|
|||||||
let guard = try!(parse_expr(input));
|
let guard = try!(parse_expr(input));
|
||||||
let body = try!(parse_block(input));
|
let body = try!(parse_block(input));
|
||||||
|
|
||||||
Ok(Stmt::If(Box::new(guard), Box::new(body)))
|
match input.peek() {
|
||||||
|
Some(& Token::Else) => {
|
||||||
|
input.next();
|
||||||
|
let else_body = try!(parse_block(input));
|
||||||
|
Ok(Stmt::IfElse(Box::new(guard), Box::new(body), Box::new(else_body)))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
Ok(Stmt::If(Box::new(guard), Box::new(body)))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_while<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<Stmt, ParseError> {
|
fn parse_while<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<Stmt, ParseError> {
|
||||||
|
Loading…
Reference in New Issue
Block a user