Fix error when parsing a block where if its empty it errors asking for semicolon

This commit is contained in:
Gvidas Juknevičius 2024-12-21 23:06:02 +02:00
parent debcf6ad6c
commit 8bb0e28d80
Signed by: MCorange
GPG Key ID: 12B1346D720B7FBB

View File

@ -2,7 +2,7 @@ use std::collections::HashMap;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use crate::{debug, lerror, parser::{typ::parse_type, Punctuation}, tokeniser::Token}; use crate::{debug, error, lerror, parser::{typ::parse_type, Punctuation}, tokeniser::Token};
use super::{ast::{expr::{Block, CallParams, Expr, IfBranchExpr, IfExpr, Path}, literal::Literal, TokenType}, parse_item, utils, Delimiter, Keyword}; use super::{ast::{expr::{Block, CallParams, Expr, IfBranchExpr, IfExpr, Path}, literal::Literal, TokenType}, parse_item, utils, Delimiter, Keyword};
@ -108,12 +108,11 @@ pub fn parse_expr(tokens: &mut Vec<Token>, precedence: usize, consume_semi: bool
if let Some(_) = utils::check_from_many(tokens, BINOP_LIST) { if let Some(_) = utils::check_from_many(tokens, BINOP_LIST) {
return Ok(Some(parse_binop(tokens, res, precedence)?)); return Ok(Some(parse_binop(tokens, res, precedence)?));
} else { } else {
if consume_semi {
_ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), "Expected ; at the end of the expression")?;
}
return Ok(Some(res)); return Ok(Some(res));
} }
}
if consume_semi {
_ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), "Expected ; at the end of the expression")?;
} }
Ok(res) Ok(res)
} }
@ -138,7 +137,17 @@ fn parse_if(tokens: &mut Vec<Token>) -> Result<IfExpr> {
lerror!(loc.loc(), "Expected test for if statement, got nothing"); lerror!(loc.loc(), "Expected test for if statement, got nothing");
bail!("") bail!("")
}; };
let block = parse_block(tokens)?; let block = if let Some(_) = utils::check(tokens, TokenType::Delim(Delimiter::CurlyL)) {
if let Some(_) = utils::check_2_last(tokens, TokenType::Delim(Delimiter::CurlyR)) {
_ = utils::check_consume(tokens, TokenType::Delim(Delimiter::CurlyR));
Block(Vec::new())
} else {
parse_block(tokens)?
}
} else {
lerror!(loc.loc(), "Expected '{{'");
bail!("")
};
if let Some(_) = utils::check_consume(tokens, TokenType::Keyword(Keyword::Else)) { if let Some(_) = utils::check_consume(tokens, TokenType::Keyword(Keyword::Else)) {
if let Some(_) = utils::check(tokens, TokenType::Keyword(Keyword::If)) { if let Some(_) = utils::check(tokens, TokenType::Keyword(Keyword::If)) {
let branch = IfBranchExpr::ElseIf(Box::new(parse_if(tokens)?)); let branch = IfBranchExpr::ElseIf(Box::new(parse_if(tokens)?));
@ -181,7 +190,7 @@ fn parse_for_loop(tokens: &mut Vec<Token>) -> Result<Expr> {
lerror!(loc.loc(), "Expected init stat for a for loop, got nothing"); lerror!(loc.loc(), "Expected init stat for a for loop, got nothing");
bail!("") bail!("")
}; };
_ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), ""); // Semicolon parsed out by parse_item above
let Some(test) = parse_expr(tokens, 0, false)? else { let Some(test) = parse_expr(tokens, 0, false)? else {
lerror!(loc.loc(), "Expected test comparrison for a for loop, got nothing"); lerror!(loc.loc(), "Expected test comparrison for a for loop, got nothing");
bail!("") bail!("")
@ -440,14 +449,14 @@ pub fn parse_block(tokens: &mut Vec<Token>) -> Result<Block> {
utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::CurlyL), "")?; utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::CurlyL), "")?;
let mut items = Vec::new(); let mut items = Vec::new();
while !tokens.is_empty() { while !tokens.is_empty() {
if let Some(_) = utils::check(tokens, TokenType::Delim(Delimiter::CurlyR)) {
break;
}
if let Some(item) = parse_item(tokens)? { if let Some(item) = parse_item(tokens)? {
items.push(item); items.push(item);
} else { } else {
break; break;
} }
if let Some(_) = utils::check(tokens, TokenType::Delim(Delimiter::CurlyR)) {
break;
}
} }
utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::CurlyR), "")?; utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::CurlyR), "")?;
Ok(Block(items)) Ok(Block(items))