Parser refactoring WIP.

This commit is contained in:
Jesse Brault 2026-08-20 10:19:05 -05:00
parent dbbcda638f
commit a4b9b958e9

View File

@ -71,16 +71,6 @@ pub fn parse_expression(input: &str) -> ParseResult<Expression> {
(expression, diagnostics) (expression, diagnostics)
} }
#[deprecated]
pub fn parse_let_statement(input: &str) -> ParseResult<Option<LetStatement>> {
let mut parser = Parser::new(input);
let mut diagnostics = Vec::new();
diagnostics.append(&mut parser.advance());
let (let_statement, mut ds) = parser.let_statement();
diagnostics.append(&mut ds);
(let_statement, diagnostics)
}
macro_rules! matches_expression_first { macro_rules! matches_expression_first {
( $token_kind : expr ) => { ( $token_kind : expr ) => {
matches!( matches!(
@ -96,12 +86,34 @@ macro_rules! matches_expression_first {
}; };
} }
const EXPRESSION_FIRSTS: [TokenKind; 7] = [
TokenKind::IntegerLiteral,
TokenKind::DoubleLiteral,
TokenKind::LongLiteral,
TokenKind::String,
TokenKind::Minus,
TokenKind::SelfKw,
TokenKind::Identifier,
];
macro_rules! matches_statement_first { macro_rules! matches_statement_first {
( $token_kind : expr ) => { ( $token_kind : expr ) => {
matches!($token_kind, TokenKind::Let) || matches_expression_first!($token_kind) matches!($token_kind, TokenKind::Let) || matches_expression_first!($token_kind)
}; };
} }
const STATEMENT_FIRSTS: [TokenKind; 8] = {
let mut firsts: [TokenKind; 8] = [TokenKind::Let; 8];
let mut i = 0;
while i < EXPRESSION_FIRSTS.len() {
firsts[i + 1] = EXPRESSION_FIRSTS[i];
i += 1;
}
firsts
};
macro_rules! matches_type_use_first { macro_rules! matches_type_use_first {
( $token_kind: expr ) => { ( $token_kind: expr ) => {
matches!($token_kind, TokenKind::LeftSquare | TokenKind::Identifier) matches!($token_kind, TokenKind::LeftSquare | TokenKind::Identifier)
@ -291,15 +303,6 @@ impl<'a> Parser<'a> {
} }
} }
fn get_current(&self) -> &Token {
match &self.current {
None => {
panic!("Unexpected end of input");
}
Some(token) => token,
}
}
fn sample_input(&self, start: usize, end: usize) -> &'a str { fn sample_input(&self, start: usize, end: usize) -> &'a str {
&self.input[start..end] &self.input[start..end]
} }
@ -322,7 +325,7 @@ impl<'a> Parser<'a> {
let mut diagnostics = vec![]; let mut diagnostics = vec![];
while self.current.is_some() { while self.current.is_some() {
let current = self.get_current(); let current = self.current.as_ref().unwrap(); // loop checks for Some
match current.kind() { match current.kind() {
TokenKind::Fn | TokenKind::Extern | TokenKind::Class => { TokenKind::Fn | TokenKind::Extern | TokenKind::Class => {
let (_, mut ds) = self.module_level_declaration( let (_, mut ds) = self.module_level_declaration(
@ -359,7 +362,16 @@ impl<'a> Parser<'a> {
classes: &mut Vec<Class>, classes: &mut Vec<Class>,
) -> ParseResult<()> { ) -> ParseResult<()> {
let mut diagnostics = Vec::new(); let mut diagnostics = Vec::new();
let current = self.get_current(); let current = match self.current.as_ref() {
None => {
diagnostics.push(Self::get_expected_but_found_eoi(
&[TokenKind::Fn, TokenKind::Extern, TokenKind::Class],
self.input.len(),
));
return ((), diagnostics);
}
Some(current) => current,
};
match current.kind() { match current.kind() {
TokenKind::Fn => { TokenKind::Fn => {
let (maybe_function, mut ds) = self.function(); let (maybe_function, mut ds) = self.function();
@ -512,7 +524,8 @@ impl<'a> Parser<'a> {
let mut maybe_constructor: Option<Constructor> = None; let mut maybe_constructor: Option<Constructor> = None;
while self.current.is_some() && !self.peek_current(TokenKind::End) { while self.current.is_some() && !self.peek_current(TokenKind::End) {
match self.get_current().kind() { match self.current.as_ref().unwrap().kind() {
// checked in loop
TokenKind::Public => { TokenKind::Public => {
let (_, mut ds) = self.public_class_member( let (_, mut ds) = self.public_class_member(
&mut fields, &mut fields,
@ -623,7 +636,7 @@ impl<'a> Parser<'a> {
let mut diagnostics = Vec::new(); let mut diagnostics = Vec::new();
if self.current.is_some() { if self.current.is_some() {
let current = self.get_current(); let current = self.current.as_ref().unwrap(); // loop checks for Some
return match current.kind() { return match current.kind() {
TokenKind::LeftSquare => { TokenKind::LeftSquare => {
diagnostics.append(&mut self.advance()); // [ diagnostics.append(&mut self.advance()); // [
@ -685,7 +698,9 @@ impl<'a> Parser<'a> {
let mut diagnostics = Vec::new(); let mut diagnostics = Vec::new();
let mut generic_arguments: Vec<TypeUse> = vec![]; let mut generic_arguments: Vec<TypeUse> = vec![];
while self.current.is_some() && matches_type_use_first!(self.get_current().kind()) { while self.current.is_some()
&& matches_type_use_first!(self.current.as_ref().unwrap().kind())
{
let (type_use, mut ds) = self.type_use(); let (type_use, mut ds) = self.type_use();
diagnostics.append(&mut ds); diagnostics.append(&mut ds);
if let Some(type_use) = type_use { if let Some(type_use) = type_use {
@ -736,7 +751,9 @@ impl<'a> Parser<'a> {
let mut extends_list: Vec<TypeUse> = vec![]; let mut extends_list: Vec<TypeUse> = vec![];
if self.current.is_some() && self.peek_current(TokenKind::Colon) { if self.current.is_some() && self.peek_current(TokenKind::Colon) {
diagnostics.append(&mut self.advance()); // : diagnostics.append(&mut self.advance()); // :
while self.current.is_some() && matches_type_use_first!(self.get_current().kind()) { while self.current.is_some()
&& matches_type_use_first!(self.current.as_ref().unwrap().kind())
{
let (maybe_type_use, mut ds) = self.type_use(); let (maybe_type_use, mut ds) = self.type_use();
diagnostics.append(&mut ds); diagnostics.append(&mut ds);
if let Some(type_use) = maybe_type_use { if let Some(type_use) = maybe_type_use {
@ -925,7 +942,17 @@ impl<'a> Parser<'a> {
} }
fn statement(&mut self) -> ParseResult<Option<Statement>> { fn statement(&mut self) -> ParseResult<Option<Statement>> {
let current = self.get_current(); let current = match self.current.as_ref() {
None => {
let mut ds = Diagnostics::new();
ds.push(Self::get_expected_but_found_eoi(
&STATEMENT_FIRSTS,
self.input.len(),
));
return (None, ds);
}
Some(current) => current,
};
match current.kind() { match current.kind() {
TokenKind::Let => { TokenKind::Let => {
let (maybe_let_statement, diagnostics) = self.let_statement(); let (maybe_let_statement, diagnostics) = self.let_statement();
@ -1086,7 +1113,7 @@ impl<'a> Parser<'a> {
diagnostics.append(&mut ds); diagnostics.append(&mut ds);
while self.current.is_some() { while self.current.is_some() {
let current = self.get_current(); let current = self.current.as_ref().unwrap();
match current.kind() { match current.kind() {
TokenKind::Lt => { TokenKind::Lt => {
let previous_cloned = current.clone(); let previous_cloned = current.clone();
@ -1142,7 +1169,7 @@ impl<'a> Parser<'a> {
diagnostics.append(&mut ds); diagnostics.append(&mut ds);
while self.current.is_some() { while self.current.is_some() {
let current = self.get_current(); let current = self.current.as_ref().unwrap();
match current.kind() { match current.kind() {
TokenKind::Plus => { TokenKind::Plus => {
diagnostics.append(&mut self.advance()); // plus diagnostics.append(&mut self.advance()); // plus
@ -1187,7 +1214,7 @@ impl<'a> Parser<'a> {
diagnostics.append(&mut ds); diagnostics.append(&mut ds);
while self.current.is_some() { while self.current.is_some() {
let current = self.get_current(); let current = self.current.as_ref().unwrap();
match current.kind() { match current.kind() {
TokenKind::Star => { TokenKind::Star => {
diagnostics.append(&mut self.advance()); // multiply diagnostics.append(&mut self.advance()); // multiply
@ -1246,7 +1273,7 @@ impl<'a> Parser<'a> {
// first, collect all consecutive operators // first, collect all consecutive operators
let mut operator_tokens = vec![]; let mut operator_tokens = vec![];
while self.current.is_some() { while self.current.is_some() {
let current = self.get_current(); let current = self.current.as_ref().unwrap();
match current.kind() { match current.kind() {
TokenKind::Minus => { TokenKind::Minus => {
operator_tokens.push(current.clone()); // unfortunately necessary operator_tokens.push(current.clone()); // unfortunately necessary
@ -1285,7 +1312,7 @@ impl<'a> Parser<'a> {
diagnostics.append(&mut ds); diagnostics.append(&mut ds);
while self.current.is_some() { while self.current.is_some() {
let current = self.get_current(); let current = self.current.as_ref().unwrap();
match current.kind() { match current.kind() {
TokenKind::LeftParentheses => { TokenKind::LeftParentheses => {
let (call, mut ds) = self.call(base); let (call, mut ds) = self.call(base);
@ -1300,7 +1327,17 @@ impl<'a> Parser<'a> {
} }
fn expression_base(&mut self) -> ParseResult<Expression> { fn expression_base(&mut self) -> ParseResult<Expression> {
let current = self.get_current(); let current = match self.current.as_ref() {
None => {
let mut ds = Diagnostics::new();
ds.push(Self::get_expected_but_found_eoi(
&EXPRESSION_FIRSTS,
self.input.len(),
));
return (todo!(), ds);
}
Some(current) => current,
};
let mut diagnostics = Vec::new(); let mut diagnostics = Vec::new();
match current.kind() { match current.kind() {
TokenKind::IntegerLiteral => { TokenKind::IntegerLiteral => {