diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 6d20066..8ba390b 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1,2 +1,3 @@ pub mod graph; +pub mod parser; pub mod types; diff --git a/src/frontend/parser.rs b/src/ast/parser.rs similarity index 79% rename from src/frontend/parser.rs rename to src/ast/parser.rs index 13ee10a..f9d65e6 100644 --- a/src/frontend/parser.rs +++ b/src/ast/parser.rs @@ -3,7 +3,7 @@ use crate::{ ArrayDimension, BinaryOp, BlockStmt, BreakStmt, CompileUnit, ContinueStmt, Expr, ExprValue, FuncDeclStmt, GlobalDeclStmt, IfElseBranch, IfStmt, Param, ReturnStmt, Statement, UnaryOp, VarDeclStmt, VarDeclStmtValue, WhileStmt }, diagnostic::{Diagnositics, span::Span}, - frontend::{ + lexer::{ err::ParseError, types::{Token, TokenValue, TypeIdent}, }, @@ -11,6 +11,7 @@ use crate::{ pub struct Parser { tokens: Vec, + eof_token: Token, pub diagnostics: Diagnositics, pos: usize, } @@ -25,8 +26,16 @@ enum ParseProcessError { } impl Parser { pub fn new(tokens: Vec, diagnostics: Diagnositics) -> Self { + let eof_pos = tokens.last().map_or(0, |token| token.span.end); Self { tokens, + eof_token: Token { + value: TokenValue::Eof, + span: Span { + start: eof_pos, + end: eof_pos, + }, + }, diagnostics, pos: 0, } @@ -34,12 +43,12 @@ impl Parser { pub fn parse(&mut self) -> CompileUnit { self.parse_compile_unit() } - fn peek(&self) -> Option<&Token> { - self.tokens.get(self.pos) + fn peek(&self) -> &Token { + self.tokens.get(self.pos).unwrap_or(&self.eof_token) } - fn next(&mut self) -> Option<&Token> { - let token = self.tokens.get(self.pos); - if token.is_some() { + fn next(&mut self) -> Token { + let token = self.peek().clone(); + if !matches!(token.value, TokenValue::Eof) { self.pos += 1; } token @@ -52,37 +61,37 @@ impl Parser { assert!(self.pos >= n); self.pos -= n; } - fn last(&self) -> Option<&Token> { + fn last(&self) -> &Token { if self.pos == 0 { - None + &self.eof_token } else { - self.tokens.get(self.pos - 1) + self.tokens.get(self.pos - 1).unwrap_or(&self.eof_token) } } + fn is_eof(&self) -> bool { + matches!(self.peek().value, TokenValue::Eof) + } fn must_match_token(&mut self, expected: &TokenValue, diagnostic_text: &'static str) -> Result<(), ParseProcessError> { - if let Some(t) = self.peek() { - if &t.value == expected { - self.advance(1); - Ok(()) - } else { - let token = self.next().unwrap().clone(); - self.diagnostics.add_from_frontend_error( - ParseError::UnexpectedToken(token.value, diagnostic_text), - token.span, - ); - Err(ParseProcessError::ErrorInMatch) - } - - } else { - let span = self.next().unwrap().span; + if &self.peek().value == expected { + self.advance(1); + Ok(()) + } else if self.is_eof() { + let span = self.peek().span; self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof(diagnostic_text), span); Err(ParseProcessError::ErrorInMatch) + } else { + let token = self.next(); + self.diagnostics.add_from_frontend_error( + ParseError::UnexpectedToken(token.value, diagnostic_text), + token.span, + ); + Err(ParseProcessError::ErrorInMatch) } } fn must_have_some(&mut self, diagnostic_text: &'static str) -> Result<(), ParseProcessError> { - if self.peek().is_none() { - let span = self.last().unwrap().span; + if self.is_eof() { + let span = self.last().span; self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof(diagnostic_text), span); return Err(ParseProcessError::ErrorInMatch); @@ -91,8 +100,8 @@ impl Parser { } fn until_next_token(&mut self, expected: &[TokenValue]) { - while let Some(t) = self.peek() { - if expected.contains(&t.value) { + while !self.is_eof() { + if expected.contains(&self.peek().value) { self.advance(1); break; } @@ -101,7 +110,7 @@ impl Parser { } fn parse_compile_unit(&mut self) -> CompileUnit { let mut global_decls = vec![]; - while self.peek().is_some() { + while !self.is_eof() { if let Some(decl) = self.parse_global_decl_stmt() { global_decls.push(decl); } else { @@ -112,7 +121,7 @@ impl Parser { } fn parse_global_decl_stmt(&mut self) -> Option { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); match self.parse_func_decl_stmt() { Ok(func_decl) => return Some(GlobalDeclStmt::FuncDecl(func_decl)), Err(ParseProcessError::ErrorInMatch) => { @@ -127,7 +136,7 @@ impl Parser { }, _ => {} } - let token = self.next().unwrap().clone(); + let token = self.next().clone(); self.diagnostics.add_from_frontend_error( ParseError::UnexpectedToken(token.value, "ident"), token.span, @@ -145,13 +154,13 @@ impl Parser { // } // } fn parse_type_and_name(&mut self, parse_type: ParseType) -> Result<(TypeIdent, String, Span, Span), ParseProcessError> { - assert!(self.peek().is_some()); - let type_token = self.peek().unwrap().clone(); - let type_ident = match self.peek().unwrap().value.as_type_ident() { + assert!(!self.is_eof()); + let type_token = self.peek().clone(); + let type_ident = match self.peek().value.as_type_ident() { Some(ti) => ti, None => { if matches!(parse_type, ParseType::MustParse) { - let token = self.next().unwrap().clone(); + let token = self.next().clone(); self.diagnostics.add_from_frontend_error( ParseError::UnexpectedToken(token.value, "type ident"), token.span, @@ -163,49 +172,45 @@ impl Parser { }; let type_span = type_token.span; self.advance(1); - let name = match self.peek().map(|t| t.value.as_ident()) { - None => { + let name = match self.peek().value.as_ident() { + None if self.is_eof() => { self.diagnostics.add_from_frontend_error( ParseError::ExpectButEof("ident"), type_span, ); return Err(ParseProcessError::ErrorInMatch); }, - Some(None) => { - let next_span = self.peek().unwrap().span; + None => { + let next_span = self.peek().span; self.diagnostics.add_from_frontend_error( ParseError::CantCombineWith(type_token.value), next_span ); return Err(ParseProcessError::ErrorInMatch); } - Some(Some(ident)) => ident, + Some(ident) => ident, }; - let name_span = self.peek().unwrap().span; + let name_span = self.peek().span; self.advance(1); Ok((type_ident, name, type_span, name_span)) } fn parse_func_decl_stmt(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); let (return_type, name, ret_type_span, name_span) = self.parse_type_and_name(ParseType::MustParse)?; - if self - .peek() - .is_some_and(|t| matches!(t.value, TokenValue::LParen)) - { + if matches!(self.peek().value, TokenValue::LParen) { } else { self.back(2); return Err(ParseProcessError::TryNext); } // from here we can be sure it's a function declaration, so we can report error if the syntax is wrong let params = self.parse_param_list()?; - let body = match self.peek().map(|t| &t.value) { - Some(_) => self.parse_block_stmt(ParseType::MustParse)?, - None => { - let span = self.next().unwrap().span; + let body = if self.is_eof() { + let span = self.next().span; self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof("function body"), span); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_block_stmt(ParseType::MustParse)? }; Ok(FuncDeclStmt { return_type: return_type.into(), @@ -217,9 +222,9 @@ impl Parser { }) } fn parse_param_list(&mut self) -> Result, ParseProcessError> { - assert!(self.peek().is_some()); - if self.peek().unwrap().value != TokenValue::LParen { - let token = self.next().unwrap().clone(); + assert!(!self.is_eof()); + if self.peek().value != TokenValue::LParen { + let token = self.next().clone(); self.diagnostics.add_from_frontend_error( ParseError::UnexpectedToken(token.value, "`(`"), token.span, @@ -229,8 +234,8 @@ impl Parser { self.advance(1); let mut params = vec![]; let mut last_is_var = false; - while self.peek().is_some() { - if self.peek().map(|t| &t.value) == Some(&TokenValue::RParen) { + while !self.is_eof() { + if self.peek().value == TokenValue::RParen { self.advance(1); break; } @@ -245,7 +250,7 @@ impl Parser { } Err(_e) => { self.until_next_token(&[TokenValue::RParen]); - if self.last().map(|t| &t.value) == Some(&TokenValue::RParen) { + if self.last().value == TokenValue::RParen { break; } } @@ -254,7 +259,7 @@ impl Parser { Ok(params) } fn parse_param(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); let (param_type, name, type_span, name_span) = self.parse_type_and_name(ParseType::MustParse)?; Ok(Param { param_type: param_type.into(), @@ -272,7 +277,7 @@ impl Parser { // self.advance(1); // Some(()) // } else { - // let token = self.next().unwrap().clone(); + // let token = self.next().clone(); // self.diagnostics // .add_from_frontend_error(ParseError::UnexpectedToken(token.value, "`;`"), token.span); // while let Some(t) = self.peek() { @@ -289,7 +294,7 @@ impl Parser { // } // } fn parse_var_decl_stmt(&mut self, parse_type: ParseType) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); let mut values = vec![]; let (var_type, name, type_span, name_span) = match self.parse_type_and_name(parse_type) { Ok(res) => res, @@ -304,8 +309,8 @@ impl Parser { let dimensions = self.parse_array_dimensions(false)?; values.push(VarDeclStmtValue { name, name_span, dimensions }); let mut last_name = true; // indicate whether the last parsed token is a variable name - while let Some(t) = self.peek() { - if matches!(t.value, TokenValue::Semicolon) { // statement end + while !self.is_eof() { + if matches!(self.peek().value, TokenValue::Semicolon) { // statement end break; } if last_name { // expect a comma after a variable name @@ -313,19 +318,19 @@ impl Parser { last_name = false; } // check eof again - if self.peek().is_none() { - let span = self.last().unwrap().span; + if self.is_eof() { + let span = self.last().span; self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof("`,` or `;`"), span); break; } - if let Some(ident) = self.peek().unwrap().value.as_ident() { - let span = self.next().unwrap().span; + if let Some(ident) = self.peek().value.as_ident() { + let span = self.next().span; let dimensions = self.parse_array_dimensions(false)?; values.push(VarDeclStmtValue { name: ident, name_span: span, dimensions }); last_name = true; } else { - let token = self.next().unwrap().clone(); + let token = self.next().clone(); self.diagnostics.add_from_frontend_error( ParseError::CantCombineWith(TokenValue::TypeIdent(var_type)), token.span, @@ -339,11 +344,11 @@ impl Parser { fn parse_array_dimensions(&mut self, allow_empty_first: bool) -> Result, ParseProcessError> { let mut dimensions = vec![]; - while self.peek().is_some_and(|t| t.value == TokenValue::LBracket) { - let start_span = self.next().unwrap().span; - let value = if self.peek().is_some_and(|t| t.value == TokenValue::RBracket) { + while self.peek().value == TokenValue::LBracket { + let start_span = self.next().span; + let value = if self.peek().value == TokenValue::RBracket { if !allow_empty_first || !dimensions.is_empty() { - let span = self.peek().unwrap().span; + let span = self.peek().span; self.diagnostics.add_from_frontend_error( ParseError::UnexpectedToken(TokenValue::RBracket, "array dimension expression"), span, @@ -354,24 +359,24 @@ impl Parser { } else { Some(self.parse_expr()?) }; - let end_span = match self.peek() { - Some(t) if t.value == TokenValue::RBracket => { - let span = t.span; + let end_span = match &self.peek().value { + TokenValue::RBracket => { + let span = self.peek().span; self.advance(1); span } - Some(_) => { - let token = self.next().unwrap().clone(); + TokenValue::Eof => { + self.diagnostics.add_from_frontend_error(ParseError::ExpectButEof("`]`"), start_span); + return Err(ParseProcessError::ErrorInMatch); + } + _ => { + let token = self.next(); self.diagnostics.add_from_frontend_error( ParseError::UnexpectedToken(token.value, "`]`"), token.span, ); return Err(ParseProcessError::ErrorInMatch); } - None => { - self.diagnostics.add_from_frontend_error(ParseError::ExpectButEof("`]`"), start_span); - return Err(ParseProcessError::ErrorInMatch); - } }; dimensions.push(ArrayDimension { value, @@ -382,13 +387,10 @@ impl Parser { } fn parse_block_stmt(&mut self, parse_type: ParseType) -> Result { - assert!(self.peek().is_some()); - if self - .peek() - .unwrap().value != TokenValue::LBrace - { + assert!(!self.is_eof()); + if self.peek().value != TokenValue::LBrace { if parse_type == ParseType::MustParse { - let token = self.next().unwrap().clone(); + let token = self.next().clone(); self.diagnostics.add_from_frontend_error( ParseError::UnexpectedToken(token.value, "`{`"), token.span, @@ -401,26 +403,18 @@ impl Parser { let mut statements = vec![]; // println!("parse block stmt"); loop { - if self.peek().is_none() { - let span = self.last().unwrap().span; + if self.is_eof() { + let span = self.last().span; self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof("`}`"), span); return Err(ParseProcessError::ErrorInMatch); } - if self - .peek() - .map(|t| matches!(t.value, TokenValue::Semicolon)) - .unwrap() - { + if matches!(self.peek().value, TokenValue::Semicolon) { // like a();; self.advance(1); continue; } - if self - .peek() - .map(|t| matches!(t.value, TokenValue::RBrace)) - .unwrap() - { + if matches!(self.peek().value, TokenValue::RBrace) { self.advance(1); break; } @@ -429,7 +423,7 @@ impl Parser { Ok(stmt) => statements.push(stmt), Err(_) => { self.until_next_token(&[TokenValue::Semicolon, TokenValue::RBrace]); - if self.last().unwrap().value == TokenValue::RBrace { + if self.last().value == TokenValue::RBrace { break; } } @@ -442,7 +436,7 @@ impl Parser { } fn parse_stmt(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); match self.parse_var_decl_stmt(ParseType::TryParse) { Ok(var_decl) => return Ok(Statement::VarDecl(var_decl)), Err(ParseProcessError::ErrorInMatch) => return Err(ParseProcessError::ErrorInMatch), @@ -491,16 +485,12 @@ impl Parser { } fn parse_return_stmt(&mut self) -> Result { - assert!(self.peek().is_some()); - if self.peek().unwrap().value != TokenValue::Return { + assert!(!self.is_eof()); + if self.peek().value != TokenValue::Return { return Err(ParseProcessError::TryNext); } - let span = self.next().unwrap().span; - let value = if self - .peek() - .map(|t| matches!(t.value, TokenValue::Semicolon)) - .unwrap_or(false) - { + let span = self.next().span; + let value = if matches!(self.peek().value, TokenValue::Semicolon) { None } else { Some(self.parse_expr()?) @@ -512,8 +502,8 @@ impl Parser { }) } fn parse_if_stmt(&mut self) -> Result { - assert!(self.peek().is_some()); - if self.peek().unwrap().value != TokenValue::If { + assert!(!self.is_eof()); + if self.peek().value != TokenValue::If { return Err(ParseProcessError::TryNext); } self.advance(1); @@ -525,20 +515,20 @@ impl Parser { let mut ifelse_branch = vec![]; let mut else_branch = None; self.must_have_some("if statement body")?; - if self.peek().unwrap().value != TokenValue::LBrace { + if self.peek().value != TokenValue::LBrace { let stmt = self.parse_stmt()?; then_branch = BlockStmt { statements: vec![stmt] }; } else { then_branch = self.parse_block_stmt(ParseType::MustParse)?; } loop { - if self.peek().is_none() { + if self.is_eof() { break; } - if self.peek().unwrap().value == TokenValue::Else { + if self.peek().value == TokenValue::Else { self.advance(1); self.must_have_some("else body")?; - if self.peek().unwrap().value != TokenValue::If { + if self.peek().value != TokenValue::If { self.back(1); break; } @@ -549,7 +539,7 @@ impl Parser { let condition = self.parse_expr()?; self.must_match_token(&TokenValue::RParen, "`)`")?; let then_branch; - if self.peek().unwrap().value != TokenValue::LBrace { + if self.peek().value != TokenValue::LBrace { let stmt = self.parse_stmt()?; then_branch = BlockStmt { statements: vec![stmt] }; } else { @@ -561,11 +551,11 @@ impl Parser { break; } } - if self.peek().is_some_and(|t| t.value == TokenValue::Else) { + if self.peek().value == TokenValue::Else { // Parse else branch self.advance(1); self.must_have_some("else body")?; - if self.peek().unwrap().value != TokenValue::LBrace { + if self.peek().value != TokenValue::LBrace { let stmt = self.parse_stmt()?; else_branch = Some(BlockStmt { statements: vec![stmt] }); } else { @@ -581,8 +571,8 @@ impl Parser { } fn parse_while_stmt(&mut self) -> Result { - assert!(self.peek().is_some()); - if self.peek().unwrap().value != TokenValue::While { + assert!(!self.is_eof()); + if self.peek().value != TokenValue::While { return Err(ParseProcessError::TryNext); } self.advance(1); @@ -591,7 +581,7 @@ impl Parser { let condition = self.parse_expr()?; self.must_match_token(&TokenValue::RParen, "`)`")?; let body; - if self.peek().unwrap().value != TokenValue::LBrace { + if self.peek().value != TokenValue::LBrace { let stmt = self.parse_stmt()?; body = BlockStmt { statements: vec![stmt] }; } else { @@ -604,9 +594,9 @@ impl Parser { } fn parse_break_stmt(&mut self) -> Result { - assert!(self.peek().is_some()); - let start_span = self.peek().unwrap().span; - if self.peek().unwrap().value == TokenValue::Break { + assert!(!self.is_eof()); + let start_span = self.peek().span; + if self.peek().value == TokenValue::Break { self.advance(1); self.must_match_token(&TokenValue::Semicolon, "`;`")?; Ok(BreakStmt { @@ -618,9 +608,9 @@ impl Parser { } fn parse_continue_stmt(&mut self) -> Result { - assert!(self.peek().is_some()); - let start_span = self.peek().unwrap().span; - if self.peek().unwrap().value == TokenValue::Continue { + assert!(!self.is_eof()); + let start_span = self.peek().span; + if self.peek().value == TokenValue::Continue { self.advance(1); self.must_match_token(&TokenValue::Semicolon, "`;`")?; Ok(ContinueStmt { @@ -646,59 +636,56 @@ impl Parser { // } // } fn parse_primary_atom(&mut self) -> Result { - assert!(self.peek().is_some()); - let token = self.next().unwrap().clone(); + assert!(!self.is_eof()); + let token = self.next().clone(); match token.value { TokenValue::Ident(name) => { - if self - .peek() - .is_some_and(|t| matches!(t.value, TokenValue::LParen)) - { + if matches!(self.peek().value, TokenValue::LParen) { self.advance(1); let mut args = vec![]; loop { - match self.peek() { - Some(t) if matches!(t.value, TokenValue::RParen) => { - let end_span = t.span; + match &self.peek().value { + TokenValue::RParen => { + let end_span = self.peek().span; self.advance(1); return Ok(Expr { value: ExprValue::FuncCall(name, args), span: Span::from_two(token.span, end_span), }); } - Some(_) => {} - None => { + TokenValue::Eof => { self.diagnostics.add_from_frontend_error( ParseError::ExpectButEof("`)`"), token.span, ); return Err(ParseProcessError::ErrorInMatch); } + _ => {} } args.push(self.parse_expr()?); - match self.peek() { - Some(t) if matches!(t.value, TokenValue::Comma) => { + match &self.peek().value { + TokenValue::Comma => { self.advance(1); } - Some(t) if matches!(t.value, TokenValue::RParen) => { - let end_span = t.span; + TokenValue::RParen => { + let end_span = self.peek().span; self.advance(1); return Ok(Expr { value: ExprValue::FuncCall(name, args), span: Span::from_two(token.span, end_span), }); } - Some(_) => { - let token = self.next().unwrap().clone(); + TokenValue::Eof => { self.diagnostics.add_from_frontend_error( - ParseError::UnexpectedToken(token.value, "`,` or `)`"), + ParseError::ExpectButEof("`)`"), token.span, ); return Err(ParseProcessError::ErrorInMatch); } - None => { + _ => { + let token = self.next(); self.diagnostics.add_from_frontend_error( - ParseError::ExpectButEof("`)`"), + ParseError::UnexpectedToken(token.value, "`,` or `)`"), token.span, ); return Err(ParseProcessError::ErrorInMatch); @@ -716,38 +703,37 @@ impl Parser { span: token.span, }), TokenValue::LParen => { - let expr = match self.peek() { - Some(_) => self.parse_expr()?, - None => { + let expr = if self.is_eof() { self.diagnostics.add_from_frontend_error( ParseError::ExpectButEof("expression"), token.span, ); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_expr()? }; - match self.peek() { - Some(t) if matches!(t.value, TokenValue::RParen) => { - let end_span = t.span; + match &self.peek().value { + TokenValue::RParen => { + let end_span = self.peek().span; self.advance(1); Ok(Expr { span: Span::from_two(token.span, end_span), ..expr }) } - Some(_) => { - let token = self.next().unwrap().clone(); + TokenValue::Eof => { + self.diagnostics + .add_from_frontend_error(ParseError::ExpectButEof("`)`"), expr.span); + Err(ParseProcessError::ErrorInMatch) + } + _ => { + let token = self.next(); self.diagnostics.add_from_frontend_error( ParseError::UnexpectedToken(token.value, "`)`"), token.span, ); Err(ParseProcessError::ErrorInMatch) } - None => { - self.diagnostics - .add_from_frontend_error(ParseError::ExpectButEof("`)`"), expr.span); - Err(ParseProcessError::ErrorInMatch) - } } } _ => { @@ -761,34 +747,33 @@ impl Parser { } fn parse_primary(&mut self) -> Result { let mut expr = self.parse_primary_atom()?; - while self.peek().is_some_and(|t| t.value == TokenValue::LBracket) { + while self.peek().value == TokenValue::LBracket { let start_span = expr.span; self.advance(1); - let index = match self.peek() { - Some(_) => self.parse_expr()?, - None => { + let index = if self.is_eof() { self.diagnostics.add_from_frontend_error(ParseError::ExpectButEof("array index expression"), start_span); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_expr()? }; - let end_span = match self.peek() { - Some(t) if t.value == TokenValue::RBracket => { - let span = t.span; + let end_span = match &self.peek().value { + TokenValue::RBracket => { + let span = self.peek().span; self.advance(1); span } - Some(_) => { - let token = self.next().unwrap().clone(); + TokenValue::Eof => { + self.diagnostics.add_from_frontend_error(ParseError::ExpectButEof("`]`"), index.span); + return Err(ParseProcessError::ErrorInMatch); + } + _ => { + let token = self.next(); self.diagnostics.add_from_frontend_error( ParseError::UnexpectedToken(token.value, "`]`"), token.span, ); return Err(ParseProcessError::ErrorInMatch); } - None => { - self.diagnostics.add_from_frontend_error(ParseError::ExpectButEof("`]`"), index.span); - return Err(ParseProcessError::ErrorInMatch); - } }; expr = Expr { value: ExprValue::ArrayAccess { @@ -801,20 +786,19 @@ impl Parser { Ok(expr) } fn parse_unary(&mut self) -> Result { - assert!(self.peek().is_some()); - let token = self.peek().unwrap().clone(); + assert!(!self.is_eof()); + let token = self.peek().clone(); match token.value { TokenValue::Plus => { self.advance(1); - let expr = match self.peek() { - Some(_) => self.parse_unary()?, - None => { + let expr = if self.is_eof() { self.diagnostics.add_from_frontend_error( ParseError::ExpectButEof("expression"), token.span, ); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_unary()? }; let span = Span::from_two(token.span, expr.span); Ok(Expr { @@ -827,15 +811,14 @@ impl Parser { } TokenValue::Minus => { self.advance(1); - let rhs = match self.peek() { - Some(_) => self.parse_unary()?, - None => { + let rhs = if self.is_eof() { self.diagnostics.add_from_frontend_error( ParseError::ExpectButEof("expression"), token.span, ); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_unary()? }; let span = Span::from_two(token.span, rhs.span); Ok(Expr { @@ -848,15 +831,14 @@ impl Parser { } TokenValue::Not => { self.advance(1); - let rhs = match self.peek() { - Some(_) => self.parse_unary()?, - None => { + let rhs = if self.is_eof() { self.diagnostics.add_from_frontend_error( ParseError::ExpectButEof("expression"), token.span, ); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_unary()? }; let span = Span::from_two(token.span, rhs.span); Ok(Expr { @@ -871,23 +853,22 @@ impl Parser { } } fn parse_multiplicative(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); let mut left = self.parse_unary()?; - while let Some(t) = self.peek() { - let op = match t.value { + while !self.is_eof() { + let op = match self.peek().value { TokenValue::Star => BinaryOp::Mul, TokenValue::Slash => BinaryOp::Div, TokenValue::Percent => BinaryOp::Mod, _ => break, }; self.advance(1); - let right = match self.peek() { - Some(_) => self.parse_unary()?, - None => { + let right = if self.is_eof() { self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_unary()? }; let span = Span::from_two(left.span, right.span); left = Expr { @@ -902,22 +883,21 @@ impl Parser { Ok(left) } fn parse_additive(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); let mut left = self.parse_multiplicative()?; - while let Some(t) = self.peek() { - let op = match t.value { + while !self.is_eof() { + let op = match self.peek().value { TokenValue::Plus => BinaryOp::Add, TokenValue::Minus => BinaryOp::Sub, _ => break, }; self.advance(1); - let right = match self.peek() { - Some(_) => self.parse_multiplicative()?, - None => { + let right = if self.is_eof() { self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_multiplicative()? }; let span = Span::from_two(left.span, right.span); left = Expr { @@ -932,10 +912,10 @@ impl Parser { Ok(left) } fn parse_relational(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); let mut left = self.parse_additive()?; - while let Some(t) = self.peek() { - let op = match t.value { + while !self.is_eof() { + let op = match self.peek().value { TokenValue::Less => BinaryOp::Less, TokenValue::Greater => BinaryOp::Greater, TokenValue::LessEqual => BinaryOp::LessEqual, @@ -945,13 +925,12 @@ impl Parser { _ => break, }; self.advance(1); - let right = match self.peek() { - Some(_) => self.parse_additive()?, - None => { + let right = if self.is_eof() { self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_additive()? }; let span = Span::from_two(left.span, right.span); left = Expr { @@ -966,21 +945,20 @@ impl Parser { Ok(left) } fn parse_logical_and(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); let mut left = self.parse_relational()?; - while let Some(t) = self.peek() { - let op = match t.value { + while !self.is_eof() { + let op = match self.peek().value { TokenValue::And => BinaryOp::And, _ => break, }; self.advance(1); - let right = match self.peek() { - Some(_) => self.parse_relational()?, - None => { + let right = if self.is_eof() { self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_relational()? }; let span = Span::from_two(left.span, right.span); left = Expr { @@ -995,21 +973,20 @@ impl Parser { Ok(left) } fn parse_logical_or(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); let mut left = self.parse_logical_and()?; - while let Some(t) = self.peek() { - let op = match t.value { + while !self.is_eof() { + let op = match self.peek().value { TokenValue::Or => BinaryOp::Or, _ => break, }; self.advance(1); - let right = match self.peek() { - Some(_) => self.parse_logical_and()?, - None => { + let right = if self.is_eof() { self.diagnostics .add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_logical_and()? }; let span = Span::from_two(left.span, right.span); left = Expr { @@ -1024,21 +1001,20 @@ impl Parser { Ok(left) } fn parse_assign(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); let lvalue = self.parse_logical_or()?; - if !self.peek().is_some_and(|t| t.value == TokenValue::Equal) { + if self.peek().value != TokenValue::Equal { return Ok(lvalue); } self.advance(1); - let rvalue = match self.peek() { - Some(_) => self.parse_assign()?, - None => { + let rvalue = if self.is_eof() { self.diagnostics.add_from_frontend_error( ParseError::ExpectButEof("expression"), lvalue.span, ); return Err(ParseProcessError::ErrorInMatch); - } + } else { + self.parse_assign()? }; let span = Span::from_two(lvalue.span, rvalue.span); Ok(Expr { @@ -1090,7 +1066,7 @@ impl Parser { | "(" expr ")" */ fn parse_expr(&mut self) -> Result { - assert!(self.peek().is_some()); + assert!(!self.is_eof()); self.parse_assign() } } @@ -1101,7 +1077,7 @@ mod tests { use std::path::Path; use std::fs::File; use crate::ast::graph::AstGraphExt; - use crate::frontend::lexer::Lexer; + use crate::lexer::lexer::Lexer; use crate::utils::case_list::CaseList; use crate::utils::num_sequence::NumberSequence; diff --git a/src/ast/types.rs b/src/ast/types.rs index b9867ce..72260eb 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -1,4 +1,4 @@ -use crate::{diagnostic::span::Span, frontend::types::{Token, TokenValue, TypeIdent}}; +use crate::{diagnostic::span::Span, lexer::types::{TokenValue, TypeIdent}}; use std::fmt; pub struct CompileUnit { diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 24796db..f8a60ca 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -10,8 +10,8 @@ mod tests { use std::path::Path; use std::fs::File; use std::io::Write; - use crate::frontend::lexer::Lexer; - use crate::frontend::parser::Parser; + use crate::ast::parser::Parser; + use crate::lexer::lexer::Lexer; use crate::utils::case_list::CaseList; use crate::utils::num_sequence::NumberSequence; use crate::ir::generator::Generator as IRGenerator; diff --git a/src/diagnostic/mod.rs b/src/diagnostic/mod.rs index ecbe713..0c063cf 100644 --- a/src/diagnostic/mod.rs +++ b/src/diagnostic/mod.rs @@ -1,4 +1,4 @@ -use crate::{diagnostic::span::Span, err::CompileError, frontend::err::FrontendError, ir::err::IRError}; +use crate::{diagnostic::span::Span, err::CompileError, ir::err::IRError, lexer::err::FrontendError}; pub mod span; @@ -98,4 +98,4 @@ r#"int main(){ return 1; }"#); } -} \ No newline at end of file +} diff --git a/src/err.rs b/src/err.rs index 74b1a5b..47e5762 100644 --- a/src/err.rs +++ b/src/err.rs @@ -1,6 +1,6 @@ use thiserror::Error; -use crate::{frontend::err::FrontendError, sema::err::SemaError}; +use crate::{lexer::err::FrontendError, sema::err::SemaError}; #[derive(Debug, Clone, PartialEq, Eq, Error)] pub enum CompileError { diff --git a/src/ir/generator.rs b/src/ir/generator.rs index b829ff4..b81fb6f 100644 --- a/src/ir/generator.rs +++ b/src/ir/generator.rs @@ -663,8 +663,8 @@ mod tests { use std::fs::File; use crate::ast::graph::AstGraphExt; use std::io::Write; - use crate::frontend::lexer::Lexer; - use crate::frontend::parser::Parser; + use crate::ast::parser::Parser; + use crate::lexer::lexer::Lexer; use crate::sema::analyzer::Analyzer; use crate::utils::case_list::CaseList; use crate::utils::num_sequence::NumberSequence; diff --git a/src/frontend/err.rs b/src/lexer/err.rs similarity index 95% rename from src/frontend/err.rs rename to src/lexer/err.rs index 2752a84..c5fb39f 100644 --- a/src/frontend/err.rs +++ b/src/lexer/err.rs @@ -1,6 +1,6 @@ use thiserror::Error; -use crate::frontend::types::{Token, TokenValue}; +use crate::lexer::types::TokenValue; // #[derive(Debug, Clone, PartialEq, Eq, Error)] // pub enum ParseError { @@ -37,4 +37,4 @@ pub enum FrontendError { Lexing(#[from] LexingError), #[error(transparent)] Parse(#[from] ParseError), -} \ No newline at end of file +} diff --git a/src/frontend/lexer.rs b/src/lexer/lexer.rs similarity index 98% rename from src/frontend/lexer.rs rename to src/lexer/lexer.rs index 274f5ef..ce865c6 100644 --- a/src/frontend/lexer.rs +++ b/src/lexer/lexer.rs @@ -1,9 +1,8 @@ -use std::{io::BufRead, str::FromStr}; +use std::str::FromStr; -use codespan_reporting::diagnostic; use thiserror::Error; -use crate::{diagnostic::{Diagnositics, span::{self, Span}}, frontend::{err::LexingError, types::{TokenValue, TypeIdent}}}; +use crate::{diagnostic::{Diagnositics, span::Span}, lexer::{err::LexingError, types::{TokenValue, TypeIdent}}}; use super::types::Token; @@ -359,6 +358,7 @@ fn parse_ident( } #[cfg(test)] mod tests { + use std::io::BufRead; use std::path::Path; use std::fs::File; use crate::utils::case_list::CaseList; diff --git a/src/frontend/mod.rs b/src/lexer/mod.rs similarity index 51% rename from src/frontend/mod.rs rename to src/lexer/mod.rs index a27d605..4245a1d 100644 --- a/src/frontend/mod.rs +++ b/src/lexer/mod.rs @@ -1,4 +1,3 @@ -pub mod types; +pub mod err; pub mod lexer; -pub mod parser; -pub mod err; \ No newline at end of file +pub mod types; diff --git a/src/frontend/types.rs b/src/lexer/types.rs similarity index 97% rename from src/frontend/types.rs rename to src/lexer/types.rs index dacef8a..0789bf4 100644 --- a/src/frontend/types.rs +++ b/src/lexer/types.rs @@ -26,7 +26,7 @@ pub enum TokenValue { If, Else, While, Return, Break, Continue, - // Eof, + Eof, Unrecognized, } impl TokenValue { @@ -80,7 +80,7 @@ impl std::fmt::Display for TokenValue { TokenValue::Return => write!(f, "return"), TokenValue::Break => write!(f, "break"), TokenValue::Continue => write!(f, "continue"), - // TokenValue::Eof => write!(f, ""), + TokenValue::Eof => write!(f, ""), TokenValue::Unrecognized => write!(f, "unrecognized"), } } @@ -102,7 +102,7 @@ pub enum TokenKind { If, Else, While, Return, Break, Continue, - // Eof, + Eof, Unrecognized, } #[derive(Debug, Clone, Copy, PartialEq, Eq, EnumString, AsRefStr)] diff --git a/src/main.rs b/src/main.rs index f3d9f40..2352495 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -mod frontend; +mod lexer; mod ast; mod ir; mod backend; @@ -11,7 +11,7 @@ use std::{fs::File, io::BufRead}; use clap::Parser as ArgParser; -use crate::{frontend::{lexer::Lexer, parser::Parser}, ir::generator::Generator, sema::analyzer::Analyzer}; +use crate::{ast::parser::Parser, ir::generator::Generator, lexer::lexer::Lexer, sema::analyzer::Analyzer}; use crate::backend::generator::Generator as ASMGerenerator; /// Simple minic compiler built by Rust #[derive(ArgParser, Debug)]