rcpp 0.1.3

An attempt to implement the C++20 standard. This is mostly to have fun & learn rust
use antlr_rust::token::Token;
use antlr_rust::token_factory::TokenFactory;
use antlr_rust::{TidAble, TokenSource};

use std::borrow::Cow;
use std::collections::VecDeque;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::sync::atomic::{AtomicIsize, Ordering};
use std::sync::Arc;

use super::structs::FilePreTokPos;

pub trait HasEOF {
    fn getEOF() -> Self;
    fn getInvalid() -> Self;
}

#[derive(Debug, Clone)]
pub struct AntlrToken<T: Clone + Debug + HasEOF> {
    data: FilePreTokPos<T>,
    index: Arc<AtomicIsize>,
}

impl<T: Clone + Debug + HasEOF> AntlrToken<T> {
    pub fn new(data: FilePreTokPos<T>, index: isize) -> Self {
        Self {
            data,
            index: Arc::new(AtomicIsize::new(index)),
        }
    }
}

impl<T: Clone + Debug + HasEOF> std::fmt::Display for AntlrToken<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.data.tokPos.tok.fmt(f)
    }
}

impl<T: Clone + Debug + HasEOF + 'static> Token for AntlrToken<T> {
    type Data = FilePreTokPos<T>;

    fn get_channel(&self) -> isize {
        antlr_rust::token::TOKEN_DEFAULT_CHANNEL
    }

    fn get_start(&self) -> isize {
        self.data.tokPos.start.try_into().unwrap()
    }

    fn get_stop(&self) -> isize {
        self.data.tokPos.end.try_into().unwrap()
    }

    fn get_line(&self) -> isize {
        isize::try_from(self.data.file.getRowColumn(self.data.tokPos.start).0).unwrap()
    }

    fn get_column(&self) -> isize {
        isize::try_from(self.data.file.getRowColumn(self.data.tokPos.start).1).unwrap()
    }

    fn set_text(&mut self, _text: <Self::Data as ToOwned>::Owned) {
        unimplemented!()
    }

    fn get_token_index(&self) -> isize {
        self.index.load(Ordering::Relaxed)
    }

    fn set_token_index(&self, v: isize) {
        self.index.store(v, Ordering::Relaxed);
    }

    fn to_owned(&self) -> antlr_rust::token::OwningToken {
        unimplemented!()
    }

    fn get_token_type(&self) -> isize {
        unsafe { *std::ptr::addr_of!(self.data.tokPos.tok).cast::<isize>() }
    }

    fn get_text(&self) -> &Self::Data {
        &self.data
    }
}

#[derive(Debug)]
pub struct AntlrLexerWrapperFactory<'a, U: Clone + Debug + HasEOF> {
    _phantom: &'a PhantomData<U>,
}

impl<'a, U: Clone + Debug + HasEOF + 'static> TokenFactory<'a> for AntlrLexerWrapperFactory<'a, U> {
    type Inner = AntlrToken<U>;

    type Tok = Box<Self::Inner>;

    type Data = FilePreTokPos<U>;

    type From = Cow<'static, str>;

    fn create<T>(
        &self,
        _: Option<&mut T>,
        _: isize,
        _: Option<<Self::Data as ToOwned>::Owned>,
        _: isize,
        _: isize,
        _: isize,
        _: isize,
        _: isize,
    ) -> Self::Tok
    where
        T: antlr_rust::char_stream::CharStream<Self::From> + ?Sized,
    {
        todo!()
    }

    fn create_invalid() -> Self::Tok {
        Box::new(AntlrToken::new(
            FilePreTokPos::new_meta(U::getInvalid()),
            -1,
        ))
    }

    fn get_data(_: Self::From) -> std::borrow::Cow<'static, Self::Data> {
        todo!()
    }
}

unsafe impl<'a, T: Clone + Debug + HasEOF + 'static> TidAble<'a>
    for AntlrLexerWrapperFactory<'a, T>
{
    type Static = ();
}

#[derive(Debug)]
pub struct AntlrLexerWrapper<'a, T: Clone + Debug + HasEOF> {
    pd: &'a PhantomData<AntlrToken<T>>,
    tokens: VecDeque<FilePreTokPos<T>>,
    idx: isize,
    file: String,
}

impl<'a, T: Clone + Debug + HasEOF> AntlrLexerWrapper<'a, T> {
    pub const fn new(tokens: VecDeque<FilePreTokPos<T>>, file: String) -> Self {
        Self {
            pd: &PhantomData,
            tokens,
            idx: 0,
            file,
        }
    }
}

impl<'a, T: Clone + Debug + HasEOF + 'static> TokenSource<'a> for AntlrLexerWrapper<'a, T> {
    type TF = AntlrLexerWrapperFactory<'a, T>;

    fn next_token(&mut self) -> <Self::TF as TokenFactory<'a>>::Tok {
        if let Some(tok) = self.tokens.pop_front() {
            self.idx += 1;
            Box::new(AntlrToken::new(tok, self.idx))
        } else {
            Box::new(AntlrToken::new(
                FilePreTokPos::new_meta(T::getEOF()),
                self.idx,
            ))
        }
    }

    fn get_input_stream(&mut self) -> Option<&mut dyn antlr_rust::int_stream::IntStream> {
        unimplemented!()
    }

    fn get_source_name(&self) -> String {
        self.file.clone()
    }

    fn get_token_factory(&self) -> &'a Self::TF {
        unimplemented!()
    }
}

unsafe impl<'a, T: Clone + Debug + HasEOF + 'static> TidAble<'a> for AntlrLexerWrapper<'a, T> {
    type Static = ();
}