diff --git a/src/eval.rs b/src/eval.rs index 309282f..123b901 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -203,6 +203,9 @@ impl<'a> Evaluator<'a> { (Call(name, args), None) } } + While(box test, body) => { + unimplemented!() + } Conditional(box test, then_block, else_block) => { if test.is_reducible() { let (new_test, new_effect) = self.reduce_expr(test); diff --git a/src/parser.rs b/src/parser.rs index 9535f56..4071f23 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -49,6 +49,7 @@ pub enum Expression { Conditional(Box, Box, Option>), Lambda(Function), Block(VecDeque), + While(Box, Vec), } impl fmt::Display for Statement { @@ -326,6 +327,7 @@ impl Parser { Expression::StringLiteral(s) } Some(Keyword(Kw::If)) => try!(self.conditional_expr()), + Some(Keyword(Kw::While)) => try!(self.while_expr()), Some(Identifier(_)) => try!(self.identifier_expr()), Some(Token::LParen) => try!(self.paren_expr()), Some(e) => { @@ -337,6 +339,33 @@ impl Parser { }) } + fn while_expr(&mut self) -> ParseResult { + use tokenizer::Token::*; + use self::Expression::*; + expect!(self, Keyword(Kw::While)); + + let test = try!(self.expression()); + + + let mut body = Vec::new(); + loop { + match self.peek() { + None | + Some(Keyword(Kw::End)) => break, + Some(Semicolon) | Some(Newline) => { + self.next(); + continue; + } + _ => { + let exp = try!(self.expression()); + body.push(exp); + } + } + } + expect!(self, Keyword(Kw::End)); + Ok(While(Box::new(test), body)) + } + fn conditional_expr(&mut self) -> ParseResult { use tokenizer::Token::*; use self::Expression::*;