feat(parser): Support func call
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
||||
pub mod types;
|
||||
mod lexer;
|
||||
pub mod lexer;
|
||||
pub mod parser;
|
||||
pub mod err;
|
||||
+66
-6
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user