diff --git a/conditional.schala b/conditional.schala index ccd7cfa..7aa4477 100644 --- a/conditional.schala +++ b/conditional.schala @@ -1,2 +1,8 @@ - -if 34 then 20 else 40 end +if 20 then + a = 20 + b = 30 + c = 40 + a + b + c +else + Null +end diff --git a/src/main.rs b/src/main.rs index ef81027..ec2a0d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,7 +58,8 @@ fn run_noninteractive(filename: &str, compile: bool) { let ast = match parse(&tokens, &[]) { Ok(ast) => ast, Err(err) => { - println!("Parse error: {:?}", err); + println!("Parse error: {:?}", err.msg); + println!("Remaining tokens: {:?}", err.remaining_tokens); std::process::exit(1) } }; diff --git a/src/parser.rs b/src/parser.rs index 3ed5d20..68ca577 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -82,11 +82,12 @@ pub type ParseResult = Result; #[derive(Debug)] pub struct ParseError { pub msg: String, + pub remaining_tokens: Vec, } impl ParseError { fn result_from_str(msg: &str) -> ParseResult { - Err(ParseError { msg: msg.to_string() }) + Err(ParseError { msg: msg.to_string(), remaining_tokens: vec!() }) } } @@ -171,7 +172,11 @@ impl Parser { match result { Ok(node) => ast.push(node), - Err(err) => return Err(err), + Err(mut err) => { + err.remaining_tokens = self.tokens.clone(); + err.remaining_tokens.reverse(); + return Err(err) + } } } @@ -317,7 +322,7 @@ impl Parser { Some(Identifier(_)) => try!(self.identifier_expr()), Some(Token::LParen) => try!(self.paren_expr()), Some(e) => { - return ParseError::result_from_str("Expected primary expression"); + return ParseError::result_from_str(&format!("Expected primary expression, got {:?}", e)); } None => return ParseError::result_from_str("Expected primary expression received EoI"), }) @@ -333,6 +338,10 @@ impl Parser { loop { match self.peek() { None | Some(Keyword(Kw::Else)) | Some(Keyword(Kw::End)) => break, + Some(Semicolon) | Some(Newline) => { + self.next(); + continue; + } _ => { let exp = try!(self.expression()); then_block.push_back(exp); @@ -345,6 +354,10 @@ impl Parser { loop { match self.peek() { None | Some(Keyword(Kw::End)) => break, + Some(Semicolon) | Some(Newline) => { + self.next(); + continue; + } _ => { let exp = try!(self.expression()); else_exprs.push_back(exp);