Merge branch 'feat/parser'

This commit is contained in:
2026-05-09 20:23:46 +08:00
2 changed files with 68 additions and 8 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
pub mod types;
mod lexer;
pub mod lexer;
pub mod parser;
pub mod err;
+67 -7
View File
@@ -12,7 +12,7 @@ use crate::{
pub struct Parser {
tokens: Vec<Token>,
diagnostics: Diagnositics,
pub diagnostics: Diagnositics,
pos: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -31,7 +31,9 @@ impl Parser {
pos: 0,
}
}
pub fn parse(&mut self) {}
pub fn parse(&mut self) -> CompileUnit {
self.parse_compile_unit()
}
fn peek(&self) -> Option<&Token> {
self.tokens.get(self.pos)
}
@@ -366,10 +368,68 @@ impl Parser {
assert!(self.peek().is_some());
let token = self.next().unwrap().clone();
match token.value {
TokenValue::Ident(name) => Some(Expr {
value: ExprValue::Var(name),
span: token.span,
}),
TokenValue::Ident(name) => {
if self
.peek()
.is_some_and(|t| matches!(t.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;
self.advance(1);
return Some(Expr {
value: ExprValue::FuncCall(name, args),
span: Span::from_two(token.span, end_span),
});
}
Some(_) => {}
None => {
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("`)`"),
token.span,
);
return None;
}
}
args.push(self.parse_expr()?);
match self.peek() {
Some(t) if matches!(t.value, TokenValue::Comma) => {
self.advance(1);
}
Some(t) if matches!(t.value, TokenValue::RParen) => {
let end_span = t.span;
self.advance(1);
return Some(Expr {
value: ExprValue::FuncCall(name, args),
span: Span::from_two(token.span, end_span),
});
}
Some(_) => {
let token = self.next().unwrap().clone();
self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "`,` or `)`"),
token.span,
);
return None;
}
None => {
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("`)`"),
token.span,
);
return None;
}
}
}
}
Some(Expr {
value: ExprValue::Var(name),
span: token.span,
})
},
TokenValue::IntLit(value) => Some(Expr {
value: ExprValue::IntLit(value),
span: token.span,
@@ -709,4 +769,4 @@ mod tests {
test_case("0-3,14-25");
// test_case("0-3,14-25");
}
}
}