## Coverage Report

#### Created: 2025-09-08 21:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /home/noah/src/ruchy/src/frontend/parser/core.rs

    Line
    Count
    Source
    1
    //! Core parser implementation with main entry points
    2
    3
    use super::{ParserState, *};
    4
    5
    pub struct Parser<'a> {
    6
        state: ParserState<'a>,
    7
    }
    8
    9
    impl<'a> Parser<'a> {
    10
        #[must_use]
    11
    0
        pub fn new(input: &'a str) -> Self {
    12
    0
            Self {
    13
    0
                state: ParserState::new(input),
    14
    0
            }
    15
    0
        }
    16
    17
        /// Get all errors encountered during parsing
    18
        #[must_use]
    19
    0
        pub fn get_errors(&self) -> &[ErrorNode] {
    20
    0
            self.state.get_errors()
    21
    0
        }
    22
    23
        /// Parse the input into an expression or block of expressions
    24
        ///
    25
        /// Parse a complete program or expression
    26
        ///
    27
        /// # Examples
    28
        ///
    29
        /// ```
    30
        /// use ruchy::Parser;
    31
        ///
    32
        /// let mut parser = Parser::new("42");
    33
        /// let ast = parser.parse().expect("Failed to parse");
    34
        /// ```
    35
        ///
    36
        /// ```
    37
        /// use ruchy::Parser;
    38
        ///
    39
        /// let mut parser = Parser::new("let x = 10 in x + 1");
    40
        /// let ast = parser.parse().expect("Failed to parse");
    41
        /// ```
    42
        ///
    43
        /// # Errors
    44
        ///
    45
        /// Returns an error if:
    46
        /// - The input is empty
    47
        /// - Syntax errors are encountered
    48
        /// - Unexpected tokens are found
    49
        ///
    50
        /// # Panics
    51
        ///
    52
        /// Should not panic in normal operation. Uses `expect` on verified conditions.
    53
        /// # Errors
    54
        ///
    55
        /// Returns an error if the operation fails
    56
    0
        pub fn parse(&mut self) -> Result<Expr> {
    57
            // Parse multiple top-level expressions/statements as a block
    58
    0
            let mut exprs = Vec::new();
    59
    60
    0
            while self.state.tokens.peek().is_some() {
    61
    0
                let attributes = utils::parse_attributes(&mut self.state)?;
    62
    0
                let mut expr = super::parse_expr_recursive(&mut self.state)?;
    63
    0
                expr.attributes = attributes;
    64
    0
                exprs.push(expr);
    65
    66
                // Skip optional semicolons
    67
    0
                if let Some((Token::Semicolon, _)) = self.state.tokens.peek() {
    68
    0
                    self.state.tokens.advance();
    69
    0
                }
    70
            }
    71
    72
    0
            if exprs.is_empty() {
    73
    0
                bail!("Empty program");
    74
    0
            } else if exprs.len() == 1 {
    75
    0
                Ok(exprs.into_iter().next().expect("checked: non-empty vec"))
    76
            } else {
    77
    0
                Ok(Expr {
    78
    0
                    kind: ExprKind::Block(exprs),
    79
    0
                    span: Span { start: 0, end: 0 }, // Simplified span for now
    80
    0
                    attributes: Vec::new(),
    81
    0
                })
    82
            }
    83
    0
        }
    84
    85
        /// Parse a single expression
    86
        ///
    87
        /// # Examples
    88
        ///
    89
        /// ```
    90
        /// use ruchy::Parser;
    91
        ///
    92
        /// let mut parser = Parser::new("1 + 2 * 3");
    93
        /// let expr = parser.parse_expr().expect("Failed to parse expression");
    94
        /// ```
    95
        ///
    96
        /// # Errors
    97
        ///
    98
        /// Returns an error if the input cannot be parsed as a valid expression
    99
        /// # Errors
    100
        ///
    101
        /// Returns an error if the operation fails
    102
    0
        pub fn parse_expr(&mut self) -> Result<Expr> {
    103
    0
            super::parse_expr_recursive(&mut self.state)
    104
    0
        }
    105
    106
        /// Parse an expression with operator precedence
    107
        ///
    108
        /// # Examples
    109
        ///
    110
        /// ```
    111
        /// use ruchy::Parser;
    112
        ///
    113
        /// let mut parser = Parser::new("1 + 2 * 3");
    114
        /// // Parse with minimum precedence 0 to get all operators
    115
        /// let expr = parser.parse_expr_with_precedence(0).expect("Failed to parse expression");
    116
        /// ```
    117
        ///
    118
        /// # Errors
    119
        ///
    120
        /// Returns an error if the expression cannot be parsed or contains syntax errors
    121
        /// # Errors
    122
        ///
    123
        /// Returns an error if the operation fails
    124
    0
        pub fn parse_expr_with_precedence(&mut self, min_prec: i32) -> Result<Expr> {
    125
    0
            super::parse_expr_with_precedence_recursive(&mut self.state, min_prec)
    126
    0
        }
    127
    }