refactor(frontend): Move parser to ast folder, use TokenValue::Eof to replace None

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