Fix conditional parsing

Needed to account for semicolons/newlines. Maybe need to generalize
delimiter-separated list of things
This commit is contained in:
greg 2016-12-31 17:02:49 -08:00
parent f626ca1427
commit 9b62efc830
3 changed files with 26 additions and 6 deletions

View File

@ -1,2 +1,8 @@
if 20 then
if 34 then 20 else 40 end a = 20
b = 30
c = 40
a + b + c
else
Null
end

View File

@ -58,7 +58,8 @@ fn run_noninteractive(filename: &str, compile: bool) {
let ast = match parse(&tokens, &[]) { let ast = match parse(&tokens, &[]) {
Ok(ast) => ast, Ok(ast) => ast,
Err(err) => { Err(err) => {
println!("Parse error: {:?}", err); println!("Parse error: {:?}", err.msg);
println!("Remaining tokens: {:?}", err.remaining_tokens);
std::process::exit(1) std::process::exit(1)
} }
}; };

View File

@ -82,11 +82,12 @@ pub type ParseResult<T> = Result<T, ParseError>;
#[derive(Debug)] #[derive(Debug)]
pub struct ParseError { pub struct ParseError {
pub msg: String, pub msg: String,
pub remaining_tokens: Vec<Token>,
} }
impl ParseError { impl ParseError {
fn result_from_str<T>(msg: &str) -> ParseResult<T> { fn result_from_str<T>(msg: &str) -> ParseResult<T> {
Err(ParseError { msg: msg.to_string() }) Err(ParseError { msg: msg.to_string(), remaining_tokens: vec!() })
} }
} }
@ -171,7 +172,11 @@ impl Parser {
match result { match result {
Ok(node) => ast.push(node), 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(Identifier(_)) => try!(self.identifier_expr()),
Some(Token::LParen) => try!(self.paren_expr()), Some(Token::LParen) => try!(self.paren_expr()),
Some(e) => { 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"), None => return ParseError::result_from_str("Expected primary expression received EoI"),
}) })
@ -333,6 +338,10 @@ impl Parser {
loop { loop {
match self.peek() { match self.peek() {
None | Some(Keyword(Kw::Else)) | Some(Keyword(Kw::End)) => break, None | Some(Keyword(Kw::Else)) | Some(Keyword(Kw::End)) => break,
Some(Semicolon) | Some(Newline) => {
self.next();
continue;
}
_ => { _ => {
let exp = try!(self.expression()); let exp = try!(self.expression());
then_block.push_back(exp); then_block.push_back(exp);
@ -345,6 +354,10 @@ impl Parser {
loop { loop {
match self.peek() { match self.peek() {
None | Some(Keyword(Kw::End)) => break, None | Some(Keyword(Kw::End)) => break,
Some(Semicolon) | Some(Newline) => {
self.next();
continue;
}
_ => { _ => {
let exp = try!(self.expression()); let exp = try!(self.expression());
else_exprs.push_back(exp); else_exprs.push_back(exp);