skullbrain-parser 0.1.0

Parses skullbrain tokens into a concrete syntax tree (CST).
Documentation
use skullbrain_lexer::{Lexer, TokenKind};
use std::{ops::Range, str::Chars};

/// A token with its position in the source code.
pub(crate) struct PositionedToken {
    /// The type of the token.
    kind: TokenKind,
    /// The range of the token in the source code, represented as a
    /// `Range<usize>`.  The `start` and `end` values of the range are
    /// byte offsets within the input string.
    pub(in crate::state) range: Range<usize>,
}

pub(crate) struct PositionTokenIter<'input> {
    iter: Lexer<Chars<'input>>,
    start: usize,
}

impl<'input> PositionTokenIter<'input> {
    pub(super) fn new(input: &'input str) -> Self {
        Self {
            iter: Lexer::new(input.chars()),
            start: 0,
        }
    }
}

impl Iterator for PositionTokenIter<'_> {
    type Item = PositionedToken;
    fn next(&mut self) -> Option<Self::Item> {
        let token = self.iter.next()?;
        let byte_len = token.len_repr() as usize;

        let start = self.start;
        let end = start + byte_len;
        let range = start..end;

        self.start = end;
        Some(PositionedToken::new(token.into_kind(), range))
    }
}

impl PositionedToken {
    pub(in crate::state) const fn new(kind: TokenKind, range: Range<usize>) -> Self {
        Self { kind, range }
    }

    pub(crate) const fn kind(&self) -> &TokenKind {
        &self.kind
    }

    pub(crate) const fn into_range(self) -> Range<usize> {
        self.range
    }

    pub(crate) fn range(&self) -> &Range<usize> {
        &self.range
    }
}