documentation run

This commit is contained in:
Sebastian Hugentobler 2025-05-26 12:53:40 +02:00
parent eefbcc8ae2
commit 3cbeab3434
Signed by: shu
SSH key fingerprint: SHA256:ppcx6MlixdNZd5EUM1nkHOKoyQYoJwzuQKXM6J/t66M

View file

@ -81,6 +81,7 @@ struct Parser {
impl Parser {
/// Create a new parser instance, fail if the tokens vector is empty.
/// Initialize the current token to the first token in the list.
fn new(tokens: Vec<Token>) -> Result<Self, ParserError> {
let current_token = tokens.first().ok_or(ParserError::NoTokens)?.clone();
@ -92,6 +93,8 @@ impl Parser {
}
/// Parse all tokens to a list of statements for execution.
/// Continue parsing until reaching the end of the token stream.
/// Handle errors by logging them and synchronizing to continue parsing.
fn run(&mut self) -> Result<Vec<Statement>, ParserError> {
let mut statements = Vec::new();
@ -110,7 +113,8 @@ impl Parser {
/// Check if any of the provided types match the type of the current token.
///
/// If so, advance the current token.
/// If so, advance the current token and return true.
/// Otherwise, return false without advancing.
fn matches(&mut self, types: &[TokenType]) -> bool {
let matches = types.iter().any(|x| self.check(x));
matches.then(|| self.advance());
@ -151,7 +155,7 @@ impl Parser {
}
/// Consume the current token if its token type matches the provided token_type and advance the
/// current token. Otherwise return None..
/// current token. Otherwise return None.
fn consume(&mut self, token_type: &TokenType) -> Option<&Token> {
if self.check(token_type) {
self.advance().ok()
@ -185,6 +189,7 @@ impl Parser {
self.assignment()
}
/// Parse a declaration.
fn declaration(&mut self) -> Result<Statement, ParserError> {
if self.matches(&[Class]) {
self.class_declaration()
@ -197,6 +202,7 @@ impl Parser {
}
}
/// Parse a statement.
fn statement(&mut self) -> Result<Statement, ParserError> {
if self.matches(&[For]) {
self.for_statement()
@ -215,7 +221,7 @@ impl Parser {
}
}
/// Build up a while statement from a for statement.
/// Parse a for statement by desugaring it into a while loop.
fn for_statement(&mut self) -> Result<Statement, ParserError> {
let line = self.current_token.line;
self.consume(&LeftParen)
@ -264,6 +270,8 @@ impl Parser {
Ok(body)
}
/// Parse an if statement with a condition, then branch, and optional else branch.
/// The condition must be enclosed in parentheses.
fn if_statement(&mut self) -> Result<Statement, ParserError> {
let line = self.current_token.line;
self.consume(&LeftParen)
@ -288,6 +296,8 @@ impl Parser {
})
}
/// Parse a print statement, which consists of an expression followed by a semicolon.
/// The expression's value will be printed during execution.
fn print_statement(&mut self) -> Result<Statement, ParserError> {
let value = self.expression()?;
let line = self.current_token.line;
@ -297,6 +307,8 @@ impl Parser {
Ok(Statement::Print(value))
}
/// Parse a return statement, which may include a return value expression.
/// The return value is optional - if not provided, nil is returned implicitly.
fn return_statement(&mut self) -> Result<Statement, ParserError> {
let keyword = self.previous()?.clone();
let value = if self.check(&Semicolon) {
@ -311,6 +323,8 @@ impl Parser {
Ok(Statement::Return { keyword, value })
}
/// Parse a class declaration with a name, optional superclass, and methods.
/// A class can inherit from a superclass using the '<' operator.
fn class_declaration(&mut self) -> Result<Statement, ParserError> {
let line = self.current_token.line;
let name = self
@ -347,6 +361,8 @@ impl Parser {
})
}
/// Parse a variable declaration with a name and optional initializer.
/// If no initializer is provided, the variable is initialized to nil.
fn var_declaration(&mut self) -> Result<Statement, ParserError> {
let line = self.current_token.line;
let name = self
@ -369,6 +385,8 @@ impl Parser {
})
}
/// Parse a while statement with a condition and body.
/// The condition must be enclosed in parentheses.
fn while_statement(&mut self) -> Result<Statement, ParserError> {
let line = self.current_token.line;
self.consume(&LeftParen)
@ -387,6 +405,8 @@ impl Parser {
})
}
/// Parse an expression statement, which is an expression followed by a semicolon.
/// The expression is evaluated for its side effects.
fn expression_statement(&mut self) -> Result<Statement, ParserError> {
let expr = self.expression()?;
let line = self.current_token.line;
@ -396,6 +416,8 @@ impl Parser {
Ok(Statement::Expression(expr))
}
/// Parse a function declaration with a name, parameters, and body.
/// Used for both standalone functions and class methods.
fn function(&mut self) -> Result<Statement, ParserError> {
let line = self.current_token.line;
let name = self
@ -433,6 +455,8 @@ impl Parser {
Ok(Statement::Function { name, params, body })
}
/// Parse a block of statements enclosed in braces.
/// A block creates a new scope for variable declarations.
fn block(&mut self) -> Result<Vec<Statement>, ParserError> {
let mut statements = Vec::new();
@ -447,6 +471,8 @@ impl Parser {
Ok(statements)
}
/// Parse an assignment expression, which can assign to a variable or object property.
/// Assignment is right-associative, so we recursively parse the right side.
fn assignment(&mut self) -> Result<Expression, ParserError> {
let expr = self.or()?;
@ -473,6 +499,7 @@ impl Parser {
}
}
/// Parse a logical expression with a specific operator (AND or OR).
fn logical_operator<F>(
&mut self,
operator: TokenType,
@ -497,10 +524,12 @@ impl Parser {
Ok(expr)
}
/// Parse a logical OR expression.
fn or(&mut self) -> Result<Expression, ParserError> {
self.logical_operator(Or, Self::and)
}
/// Parse a logical AND expression.
fn and(&mut self) -> Result<Expression, ParserError> {
self.logical_operator(And, Self::equality)
}
@ -540,6 +569,7 @@ impl Parser {
}
}
/// Parse a call expression or property access.
fn call(&mut self) -> Result<Expression, ParserError> {
let mut expr = self.primary()?;
@ -565,6 +595,8 @@ impl Parser {
Ok(expr)
}
/// Complete parsing a function call after seeing the opening parenthesis.
/// Parse the arguments and closing parenthesis.
fn finish_call(&mut self, callee: Expression) -> Result<Expression, ParserError> {
let mut args = Vec::new();
@ -643,6 +675,8 @@ impl Parser {
}
}
/// Synchronize the parser after an error by advancing to the next statement boundary.
/// This allows parsing to continue after encountering a syntax error.
fn synchronize(&mut self) {
let _ = self.advance();
while !self.is_at_end()