1#![doc = include_str!("../README.md")]
2
3mod char;
4mod comment;
5mod float;
6mod int;
7mod keyword;
8mod lexer;
9mod string;
10
11pub use float::Float;
12pub use int::Int;
13pub use keyword::Keyword;
14pub use lexer::Token;
15
16#[derive(Debug, Clone)]
18pub struct Lexeme<'l> {
19 pub token: Token,
21 pub span: core::ops::Range<usize>,
26 pub slice: &'l str,
28}
29
30impl<'l> core::ops::Deref for Lexeme<'l> {
31 type Target = Token;
32
33 fn deref(&self) -> &Self::Target {
34 &self.token
35 }
36}
37
38impl<'l> AsRef<str> for Lexeme<'l> {
39 fn as_ref(&self) -> &'l str {
40 self.slice
41 }
42}
43
44impl<'l> Lexeme<'l> {
45 pub fn keyword(&self) -> Option<Keyword> {
47 if self.token == Token::Identifier {
48 self.slice.parse().ok()
49 } else {
50 None
51 }
52 }
53
54 pub fn comment(&self) -> Option<String> {
56 if self.token == Token::Comment {
57 comment::extract(self.slice)
58 } else {
59 None
60 }
61 }
62
63 pub fn char(&self) -> Option<char> {
65 if self.token == Token::Char {
66 char::extract(self.slice)
67 } else {
68 None
69 }
70 }
71
72 pub fn string(&self) -> Option<String> {
74 if self.token == Token::String {
75 string::extract(self.slice)
76 } else {
77 None
78 }
79 }
80
81 pub fn int<T: Int>(&self) -> Option<T> {
83 if self.token == Token::Int {
84 int::extract(self.slice)
85 } else {
86 None
87 }
88 }
89
90 pub fn float<T: Float>(&self) -> Option<T> {
92 if self.token == Token::Float {
93 float::extract(self.slice)
94 } else {
95 None
96 }
97 }
98}
99
100pub struct Lexer<'l> {
115 inner: logos::Lexer<'l, Token>,
116}
117
118impl<'l> From<&'l str> for Lexer<'l> {
119 fn from(s: &'l str) -> Self {
120 Self {
121 inner: logos::Lexer::new(s),
122 }
123 }
124}
125
126impl<'l> Iterator for Lexer<'l> {
127 type Item = Lexeme<'l>;
128
129 fn next(&mut self) -> Option<Self::Item> {
130 self.inner.next().map(|token| {
131 let span = self.inner.span();
132 let slice = self.inner.slice();
133 Lexeme { token, span, slice }
134 })
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 #[test]
141 fn it_works() {
142 let result = 2 + 2;
143 assert_eq!(result, 4);
144 }
145}