artichoke_core/
parser.rs

1//! Parse code on an Artichoke interpreter.
2
3use core::fmt;
4
5/// Manage parser state, active filename context, and line number metadata.
6///
7/// Parsers maintain a stack of `Context`s which are modified as successive
8/// sources are parsed, for example as a set of nested `require`s.
9pub trait Parser {
10    /// Concrete type for parser context.
11    type Context;
12    /// Error type for Parser APIs.
13    type Error;
14
15    /// Reset parser state to initial values.
16    ///
17    /// # Errors
18    ///
19    /// If the parser state is inaccessible, an error is returned.
20    fn reset_parser(&mut self) -> Result<(), Self::Error>;
21
22    /// Fetch the current line number from the parser state.
23    ///
24    /// # Errors
25    ///
26    /// If the parser state is inaccessible, an error is returned.
27    fn fetch_lineno(&self) -> Result<usize, Self::Error>;
28
29    /// Increment line number and return the new value.
30    ///
31    /// # Errors
32    ///
33    /// If the parser state is inaccessible, an error is returned.
34    ///
35    /// This function returns [`IncrementLinenoError`] if the increment results
36    /// in an overflow of the internal parser line number counter.
37    fn add_fetch_lineno(&mut self, val: usize) -> Result<usize, Self::Error>;
38
39    /// Set the currently active context by modifying the parser stack.
40    ///
41    /// # Errors
42    ///
43    /// If the parser state is inaccessible, an error is returned.
44    fn push_context(&mut self, context: Self::Context) -> Result<(), Self::Error>;
45
46    /// Remove the current active context and return it.
47    ///
48    /// # Errors
49    ///
50    /// If the parser state is inaccessible, an error is returned.
51    fn pop_context(&mut self) -> Result<Option<Self::Context>, Self::Error>;
52
53    /// Return a reference to the currently active context.
54    ///
55    /// # Errors
56    ///
57    /// If the parser state is inaccessible, an error is returned.
58    fn peek_context(&self) -> Result<Option<&Self::Context>, Self::Error>;
59}
60
61/// Errors encountered when incrementing line numbers on parser state.
62///
63/// Errors include overflows of the interpreters line counter.
64#[non_exhaustive]
65#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
66pub enum IncrementLinenoError {
67    /// An overflow occurred when incrementing the line number.
68    ///
69    /// This error is reported based on the internal parser storage width
70    /// and contains the max value the parser can store.
71    Overflow(usize),
72}
73
74impl fmt::Display for IncrementLinenoError {
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        match self {
77            Self::Overflow(max) => write!(f, "Parser exceeded maximum line count: {max}"),
78        }
79    }
80}
81
82#[cfg(feature = "std")]
83impl std::error::Error for IncrementLinenoError {}