From 8bb0e28d80989d15b8ff09099dc0f456f64d8a14 Mon Sep 17 00:00:00 2001 From: MCorange Date: Sat, 21 Dec 2024 23:06:02 +0200 Subject: [PATCH] Fix error when parsing a block where if its empty it errors asking for semicolon --- src/parser/expr.rs | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/parser/expr.rs b/src/parser/expr.rs index 226054f..6492b97 100644 --- a/src/parser/expr.rs +++ b/src/parser/expr.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; 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}; @@ -108,12 +108,11 @@ pub fn parse_expr(tokens: &mut Vec, precedence: usize, consume_semi: bool if let Some(_) = utils::check_from_many(tokens, BINOP_LIST) { return Ok(Some(parse_binop(tokens, res, precedence)?)); } 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)); - } - - } - if consume_semi { - _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), "Expected ; at the end of the expression")?; + } } Ok(res) } @@ -138,7 +137,17 @@ fn parse_if(tokens: &mut Vec) -> Result { lerror!(loc.loc(), "Expected test for if statement, got nothing"); 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(tokens, TokenType::Keyword(Keyword::If)) { let branch = IfBranchExpr::ElseIf(Box::new(parse_if(tokens)?)); @@ -181,7 +190,7 @@ fn parse_for_loop(tokens: &mut Vec) -> Result { lerror!(loc.loc(), "Expected init stat for a for loop, got nothing"); 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 { lerror!(loc.loc(), "Expected test comparrison for a for loop, got nothing"); bail!("") @@ -440,14 +449,14 @@ pub fn parse_block(tokens: &mut Vec) -> Result { utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::CurlyL), "")?; let mut items = Vec::new(); while !tokens.is_empty() { + if let Some(_) = utils::check(tokens, TokenType::Delim(Delimiter::CurlyR)) { + break; + } if let Some(item) = parse_item(tokens)? { items.push(item); } else { break; } - if let Some(_) = utils::check(tokens, TokenType::Delim(Delimiter::CurlyR)) { - break; - } } utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::CurlyR), "")?; Ok(Block(items))