use chumsky::input::{
Input, MapExtra,
};
use chumsky::prelude::*;
use chumsky::extra::ParserExtra;
use crate::{SourceKey, Span, SpanCache};
pub use laburnum_syntax_macro::laburnum_syntax;
pub mod ast;
pub mod lexer;
pub mod node_db;
pub mod stream;
pub use lexer::{Trivia, define_tokens, wrap};
pub use lexer::trivia::print_trivia_bluegum;
pub type LexExtra<'src, E> = chumsky::extra::Full<E, State<'src>, ()>;
pub struct State<'src> {
pub source_key: SourceKey,
pub span_cache: &'src mut SpanCache,
}
impl<'src> State<'src> {
pub fn new(source_key: SourceKey, span_cache: &'src mut SpanCache) -> Self {
Self {
source_key,
span_cache,
}
}
}
impl<'src, I: chumsky::input::Input<'src>>
chumsky::inspector::Inspector<'src, I> for State<'src>
{
type Checkpoint = ();
#[inline(always)]
fn on_token(&mut self, _: &<I as chumsky::input::Input<'src>>::Token) {}
#[inline(always)]
fn on_save<'parse>(
&self,
_: &chumsky::input::Cursor<'src, 'parse, I>,
) -> Self::Checkpoint {
}
#[inline(always)]
fn on_rewind<'parse>(
&mut self,
_: &chumsky::input::Checkpoint<'src, 'parse, I, Self::Checkpoint>,
) {
}
}
pub trait SpanCreator {
fn span_from(&mut self, span: SimpleSpan) -> Span;
}
impl SpanCreator for State<'_> {
fn span_from(&mut self, span: SimpleSpan) -> Span {
self
.span_cache
.create_span(span.start, span.end.saturating_sub(span.start))
}
}
pub trait LaburnumSpanExt<'src, 'b, I, E>
where
I: Input<'src, Span = SimpleSpan>,
E: ParserExtra<'src, I>,
{
fn create_span(&mut self) -> Span
where
E::State: SpanCreator;
fn create_spanned<V>(&mut self, inner: V) -> Spanned<V, Span>
where
E::State: SpanCreator;
}
impl<'src, 'b, I, E> LaburnumSpanExt<'src, 'b, I, E>
for MapExtra<'src, 'b, I, E>
where
I: Input<'src, Span = SimpleSpan>,
E: ParserExtra<'src, I>,
{
fn create_span(&mut self) -> Span
where
E::State: SpanCreator,
{
let simple_span = self.span();
self.state().span_from(simple_span)
}
fn create_spanned<V>(&mut self, inner: V) -> Spanned<V, Span>
where
E::State: SpanCreator,
{
let simple_span = self.span();
Spanned {
inner,
span: self.state().span_from(simple_span),
}
}
}