Merge branch 'feat/parser'
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
pub mod types;
|
pub mod types;
|
||||||
mod lexer;
|
pub mod lexer;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod err;
|
pub mod err;
|
||||||
+67
-7
@@ -12,7 +12,7 @@ use crate::{
|
|||||||
|
|
||||||
pub struct Parser {
|
pub struct Parser {
|
||||||
tokens: Vec<Token>,
|
tokens: Vec<Token>,
|
||||||
diagnostics: Diagnositics,
|
pub diagnostics: Diagnositics,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
@@ -31,7 +31,9 @@ impl Parser {
|
|||||||
pos: 0,
|
pos: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn parse(&mut self) {}
|
pub fn parse(&mut self) -> CompileUnit {
|
||||||
|
self.parse_compile_unit()
|
||||||
|
}
|
||||||
fn peek(&self) -> Option<&Token> {
|
fn peek(&self) -> Option<&Token> {
|
||||||
self.tokens.get(self.pos)
|
self.tokens.get(self.pos)
|
||||||
}
|
}
|
||||||
@@ -366,10 +368,68 @@ impl Parser {
|
|||||||
assert!(self.peek().is_some());
|
assert!(self.peek().is_some());
|
||||||
let token = self.next().unwrap().clone();
|
let token = self.next().unwrap().clone();
|
||||||
match token.value {
|
match token.value {
|
||||||
TokenValue::Ident(name) => Some(Expr {
|
TokenValue::Ident(name) => {
|
||||||
value: ExprValue::Var(name),
|
if self
|
||||||
span: token.span,
|
.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 {
|
TokenValue::IntLit(value) => Some(Expr {
|
||||||
value: ExprValue::IntLit(value),
|
value: ExprValue::IntLit(value),
|
||||||
span: token.span,
|
span: token.span,
|
||||||
@@ -709,4 +769,4 @@ mod tests {
|
|||||||
test_case("0-3,14-25");
|
test_case("0-3,14-25");
|
||||||
// test_case("0-3,14-25");
|
// test_case("0-3,14-25");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user