1use crate::Span;
2use std::fmt;
3use std::iter::Peekable;
4
5#[derive(Debug, PartialEq, Clone)]
7pub enum TokenType<'t> {
8 Unknown,
10
11 Real(f32),
14 Int(i32),
16 Id(&'t str),
18
19 OpenQASM,
22 Semicolon,
24 Comma,
26 LParen,
28 LSParen,
30 LCParen,
32 RParen,
34 RSParen,
36 RCParen,
38 Arrow,
40 Equals,
42
43 Plus,
46 Minus,
48 Times,
50 Divide,
52 Power,
54
55 QReg,
60 CReg,
62 Barrier,
64 Gate,
66 Measure,
68 Reset,
70 Include,
72 Opaque,
74 If,
76}
77
78#[derive(Debug, Clone)]
79pub struct Token<'t> {
80 pub(crate) token_type: TokenType<'t>,
81 pub(crate) span: Span,
82}
83
84impl<'t> Token<'t> {
85 pub(crate) fn to_tup(self) -> (TokenType<'t>, Span) {
86 (self.token_type, self.span)
87 }
88
89 pub fn span(&self) -> &Span {
90 &self.span
91 }
92
93 pub fn span_mut(&mut self) -> &mut Span {
94 &mut self.span
95 }
96
97 pub fn from_char(ch: char, span: Span) -> Option<Self> {
98 let token_type = match ch {
99 '=' => TokenType::Equals,
100 '+' => TokenType::Plus,
101 '-' => TokenType::Minus,
102 '*' => TokenType::Times,
103 '/' => TokenType::Divide,
104 '^' => TokenType::Power,
105 ';' => TokenType::Semicolon,
106 ',' => TokenType::Comma,
107 '(' => TokenType::LParen,
108 '[' => TokenType::LSParen,
109 '{' => TokenType::LCParen,
110 ')' => TokenType::RParen,
111 ']' => TokenType::RSParen,
112 '}' => TokenType::RCParen,
113 '>' => TokenType::Arrow,
114 _ => return None,
115 };
116
117 Some(Self { token_type, span })
118 }
119
120 pub fn lookup_ident(ident: &'t str, span: Span) -> Self {
121 let token_type = match ident {
122 "qreg" => TokenType::QReg,
123 "creg" => TokenType::CReg,
124 "barrier" => TokenType::Barrier,
125 "gate" => TokenType::Gate,
126 "measure" => TokenType::Measure,
127 "reset" => TokenType::Reset,
128 "include" => TokenType::Include,
129 "opaque" => TokenType::Opaque,
130 "if" => TokenType::If,
131 "OPENQASM" => TokenType::OpenQASM,
132 ident => TokenType::Id(ident),
133 };
134
135 Self { token_type, span }
136 }
137}
138
139impl<'t> PartialEq for Token<'t> {
140 fn eq(&self, other: &Self) -> bool {
141 self.token_type == other.token_type
142 }
143}
144
145impl<'t> From<TokenType<'t>> for Token<'t> {
146 fn from(token_type: TokenType<'t>) -> Self {
147 Self {
148 token_type,
149 span: 0..0,
150 }
151 }
152}
153
154impl<'t> Default for Token<'t> {
155 fn default() -> Self {
157 TokenType::Unknown.into()
158 }
159}
160
161#[derive(Clone)]
162pub struct TokenTree<'t, I: Iterator<Item = Token<'t>>> {
163 pub(crate) input: &'t str,
164 pub(crate) tree: Peekable<I>,
165}
166
167impl<'t, I: Iterator<Item = Token<'t>>> TokenTree<'t, I> {
168 pub fn is_empty(&self) -> bool {
169 self.input.is_empty()
170 }
171}
172
173impl<'t, 's, I, J> PartialEq<TokenTree<'s, J>> for TokenTree<'t, I>
174where
175 I: Clone + Iterator<Item = Token<'t>>,
176 J: Clone + Iterator<Item = Token<'s>>,
177{
178 fn eq(&self, other: &TokenTree<'s, J>) -> bool {
179 let mut other = other.tree.clone();
180 for a in self.tree.clone() {
181 match other.next() {
182 Some(b) if a == b => {}
183 _ => return false,
184 };
185 }
186 true
187 }
188}
189
190impl<'t, I: Clone + Iterator<Item = Token<'t>>> fmt::Debug for TokenTree<'t, I> {
191 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
192 f.debug_list().entries(self.tree.clone()).finish()
193 }
194}
195
196#[test]
197fn lookup_ident_test() {
198 assert_eq!(
199 Token::lookup_ident("opaque", 0..6),
200 TokenType::Opaque.into()
201 );
202}