71 lines
2.0 KiB
Rust
71 lines
2.0 KiB
Rust
use itertools::PeekingNext;
|
|
|
|
use super::statement_node::{ExpressionStatement, PrintStatement, Statement};
|
|
use crate::{
|
|
ast::{
|
|
parser::{InnerASTParsingError, Parser, Result},
|
|
statement::statement_node::VariableAssignmentStatement,
|
|
},
|
|
lexer::token::{self, Token, TokenType},
|
|
};
|
|
|
|
impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> {
|
|
pub fn statement(&mut self) -> Result<Statement> {
|
|
self.print_statement()
|
|
}
|
|
|
|
fn print_statement(&mut self) -> Result<Statement> {
|
|
if let Some(Token { location: loc, .. }) = self
|
|
.token_iter
|
|
.peeking_next(|t| matches!(t.token_type, token::TokenType::Print))
|
|
{
|
|
let expr = self.expression()?;
|
|
if let token::TokenType::Semicolon = self.token_iter.peek().token_type {
|
|
self.token_iter.next();
|
|
Ok(PrintStatement::new(expr).into())
|
|
} else {
|
|
Err(loc.wrap(InnerASTParsingError::ExpectedSemi))
|
|
}
|
|
} else {
|
|
self.variable_assignment_statement()
|
|
}
|
|
}
|
|
|
|
fn variable_assignment_statement(&mut self) -> Result<Statement> {
|
|
if matches!(
|
|
self.token_iter.peek_nth(0).token_type,
|
|
TokenType::Identifier(_)
|
|
) && matches!(self.token_iter.peek_nth(1).token_type, TokenType::Equal)
|
|
{
|
|
let ident = if let TokenType::Identifier(ident) = self.token_iter.next().token_type {
|
|
ident
|
|
} else {
|
|
unreachable!()
|
|
};
|
|
self.token_iter.next();
|
|
let expr = self.expression()?;
|
|
|
|
let token = self.token_iter.peek();
|
|
if let token::TokenType::Semicolon = token.token_type {
|
|
self.token_iter.next();
|
|
Ok(VariableAssignmentStatement::new(ident, expr).into())
|
|
} else {
|
|
Err(token.location.wrap(InnerASTParsingError::ExpectedSemi))
|
|
}
|
|
} else {
|
|
self.expression_statement()
|
|
}
|
|
}
|
|
|
|
fn expression_statement(&mut self) -> Result<Statement> {
|
|
let expr = self.expression()?;
|
|
let token = self.token_iter.peek();
|
|
if let TokenType::Semicolon = token.token_type {
|
|
self.token_iter.next();
|
|
Ok(ExpressionStatement::new(expr).into())
|
|
} else {
|
|
Err(token.location.wrap(InnerASTParsingError::ExpectedSemi))
|
|
}
|
|
}
|
|
}
|