forth_lexer/
token.rs

1use std::{fmt::Display, ops::RangeBounds};
2
3#[derive(Debug, PartialEq, Default, Copy, Clone)]
4pub struct Data<'a> {
5    pub start: usize,
6    pub end: usize,
7    pub value: &'a str,
8}
9
10impl<'a> Data<'a> {
11    pub fn new(start: usize, end: usize, value: &'a str) -> Data<'a> {
12        Data { start, end, value }
13    }
14}
15
16impl<'a> RangeBounds<usize> for &Data<'a> {
17    fn start_bound(&self) -> std::ops::Bound<&usize> {
18        std::ops::Bound::Included(&self.start)
19    }
20
21    fn end_bound(&self) -> std::ops::Bound<&usize> {
22        std::ops::Bound::Excluded(&self.end)
23    }
24}
25
26#[derive(Debug, PartialEq, Clone)]
27pub enum Token<'a> {
28    Illegal(Data<'a>),
29    Eof(Data<'a>),
30    Colon(Data<'a>),
31    Semicolon(Data<'a>),
32    Word(Data<'a>),
33    Number(Data<'a>),
34    Comment(Data<'a>),
35    StackComment(Data<'a>),
36}
37
38impl<'a> Token<'a> {
39    pub fn get_data(&self) -> &Data<'a> {
40        match self {
41            Token::Illegal(dat) => dat,
42            Token::Eof(dat) => dat,
43            Token::Colon(dat) => dat,
44            Token::Semicolon(dat) => dat,
45            Token::Word(dat) => dat,
46            Token::Number(dat) => dat,
47            Token::Comment(dat) => dat,
48            Token::StackComment(dat) => dat,
49        }
50    }
51}
52
53impl<'a> Display for Token<'a> {
54    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55        match self {
56            Token::Illegal(_) => write!(f, ""),
57            Token::Eof(_) => write!(f, "\0"),
58            Token::Word(value)
59            | Token::Number(value)
60            | Token::StackComment(value)
61            | Token::Comment(value) => write!(f, "{value:?}"),
62            Token::Colon(_) => write!(f, ":"),
63            Token::Semicolon(_) => write!(f, ";"),
64        }
65    }
66}
67
68impl<'a> From<Data<'a>> for Token<'a> {
69    fn from(value: Data<'a>) -> Self {
70        match value.value {
71            ";" => Self::Semicolon(value),
72            ":" => Self::Colon(value),
73            "\0" => Self::Eof(value),
74            _ => {
75                if value.value.chars().all(|b| b.is_ascii_digit()) {
76                    Self::Number(value)
77                } else {
78                    Self::Word(value)
79                }
80            }
81        }
82    }
83}