Fix conditional parsing
Needed to account for semicolons/newlines. Maybe need to generalize delimiter-separated list of things
This commit is contained in:
parent
f626ca1427
commit
9b62efc830
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user