scarf_parser/preprocessor/
mod.rs1pub mod cache;
7pub(crate) mod conditional_compilation;
8pub(crate) mod define;
9pub(crate) mod error;
10pub(crate) mod implicit_nettype;
11pub(crate) mod include;
12pub(crate) mod keywords;
13pub(crate) mod line;
14pub mod state;
15pub(crate) mod text_macro;
16pub(crate) mod timescale;
17pub(crate) mod unconnected;
18use crate::*;
19pub use cache::*;
20use conditional_compilation::*;
21use define::*;
22pub use error::*;
23pub(crate) use implicit_nettype::DefaultNettype;
24use implicit_nettype::*;
25use include::*;
26use keywords::*;
27use line::*;
28pub use state::*;
29use std::collections::VecDeque;
30use text_macro::*;
31use timescale::*;
32pub(crate) use timescale::{Timescale, TimescaleUnit, TimescaleValue};
33pub(crate) use unconnected::UnconnectedDrive;
34use unconnected::*;
35
36pub struct TokenIterator<'s, T: Iterator<Item = SpannedToken<'s>>> {
43 iter: T,
44 extras: VecDeque<SpannedToken<'s>>,
45}
46
47impl<'s, T: Iterator<Item = SpannedToken<'s>>> Iterator
48 for TokenIterator<'s, T>
49{
50 type Item = SpannedToken<'s>;
51 fn next(&mut self) -> Option<Self::Item> {
52 if let Some(extra_token) = self.extras.pop_front() {
53 Some(extra_token)
54 } else {
55 self.iter.next()
56 }
57 }
58}
59
60impl<'s, T: Iterator<Item = SpannedToken<'s>>> TokenIterator<'s, T> {
61 pub fn new(iter: T) -> Self {
62 Self {
63 iter,
64 extras: VecDeque::default(),
65 }
66 }
67
68 pub fn prepend_tokens<I>(&mut self, extra_tokens: I)
69 where
70 I: Iterator<Item = SpannedToken<'s>>
71 + ExactSizeIterator
72 + std::iter::DoubleEndedIterator,
73 {
74 self.extras.reserve(extra_tokens.len());
75 for extra_token in extra_tokens.rev() {
76 self.extras.push_front(extra_token);
77 }
78 }
79
80 pub fn peek(&mut self) -> Option<&SpannedToken<'s>> {
81 if self.extras.is_empty() {
82 if let Some(next_token) = self.iter.next() {
83 self.extras.push_back(next_token);
84 }
85 }
86 self.extras.front()
87 }
88}
89
90pub(crate) fn preprocess_helper<'s>(
91 src: &mut TokenIterator<'s, impl Iterator<Item = SpannedToken<'s>>>,
92 dest: &mut Vec<SpannedToken<'s>>,
93 state: &mut PreprocessorState<'s>,
94 cache: &'s PreprocessorCache<'s>,
95) -> Result<(), PreprocessorError<'s>> {
96 let mut enclosures: Vec<Token<'s>> = vec![];
97 if state.in_define() || state.in_define_arg() {
98 while let Some(mut spanned_token) = src.next() {
99 match spanned_token.0 {
100 Token::Bslash => loop {
101 match src.next() {
102 None => dest.push(spanned_token),
103 Some(next_token) => match next_token.0 {
104 Token::Newline => (),
105 Token::Bslash => {
106 dest.push(spanned_token);
107 spanned_token = next_token;
108 continue;
109 }
110 _ => {
111 dest.push(spanned_token);
112 dest.push(next_token)
113 }
114 },
115 };
116 break;
117 },
118 Token::Newline => {
119 return Err(PreprocessorError::NewlineInDefine(
120 spanned_token.1,
121 ));
122 }
123 Token::Paren if state.in_define_arg() => {
124 enclosures.push(Token::Paren);
125 dest.push(spanned_token);
126 }
127 Token::Bracket if state.in_define_arg() => {
128 enclosures.push(Token::Bracket);
129 dest.push(spanned_token);
130 }
131 Token::Brace if state.in_define_arg() => {
132 enclosures.push(Token::Brace);
133 dest.push(spanned_token);
134 }
135 Token::EParen if state.in_define_arg() => {
136 match enclosures.pop() {
137 Some(Token::Paren) => dest.push(spanned_token),
138 None => {
139 return Err(
140 PreprocessorError::EndOfFunctionArgument(
141 spanned_token,
142 ),
143 );
144 }
145 _ => {
146 return Err(
147 PreprocessorError::IncompleteMacroWithToken(
148 spanned_token,
149 ),
150 );
151 }
152 }
153 }
154 Token::EBracket if state.in_define_arg() => {
155 match enclosures.pop() {
156 Some(Token::Bracket) => dest.push(spanned_token),
157 _ => {
158 return Err(
159 PreprocessorError::IncompleteMacroWithToken(
160 spanned_token,
161 ),
162 );
163 }
164 }
165 }
166 Token::EBrace if state.in_define_arg() => {
167 match enclosures.pop() {
168 Some(Token::Brace) => dest.push(spanned_token),
169 _ => {
170 return Err(
171 PreprocessorError::IncompleteMacroWithToken(
172 spanned_token,
173 ),
174 );
175 }
176 }
177 }
178 Token::Comma if state.in_define_arg() => {
179 if enclosures.is_empty() {
180 return Err(PreprocessorError::EndOfFunctionArgument(
181 spanned_token,
182 ));
183 } else {
184 dest.push(spanned_token)
185 }
186 }
187 Token::BlockComment(_) | Token::OnelineComment(_) => (),
188 Token::TextMacro(macro_name) if state.in_define_arg() => {
189 preprocess_macro(
190 src,
191 state,
192 cache,
193 (macro_name, spanned_token.1),
194 )?;
195 }
196 _ => dest.push(spanned_token),
197 }
198 }
199 Ok(())
200 } else {
201 while let Some(spanned_token) = src.next() {
202 match spanned_token.0 {
203 Token::DirResetall => {
204 state.reset_all(spanned_token.1);
205 }
206 Token::DirInclude => {
207 let include_span = cache.retain_span(spanned_token.1);
208 preprocess_include(src, dest, state, cache, include_span)?;
209 }
210 Token::DirUndefineall => {
211 state.undefineall();
212 }
213 Token::DirBeginKeywords => {
214 preprocess_keyword_standard(
215 src,
216 dest,
217 state,
218 cache,
219 spanned_token.1,
220 )?;
221 }
222 Token::DirDefine => {
223 preprocess_define(src, state, cache, spanned_token.1)?;
224 }
225 Token::DirElse => {
226 return Err(PreprocessorError::Else(spanned_token.1));
227 }
228 Token::DirElsif => {
229 return Err(PreprocessorError::Elsif(spanned_token.1));
230 }
231 Token::DirEndKeywords => {
232 return Err(PreprocessorError::EndKeywords(
233 spanned_token.1,
234 ));
235 }
236 Token::DirEndif => {
237 return Err(PreprocessorError::Endif(spanned_token.1));
238 }
239 Token::DirIfdef => {
240 preprocess_ifdef(
241 src,
242 dest,
243 state,
244 cache,
245 spanned_token.1,
246 true,
247 )?;
248 }
249 Token::DirIfndef => {
250 preprocess_ifdef(
251 src,
252 dest,
253 state,
254 cache,
255 spanned_token.1,
256 false,
257 )?;
258 }
259 Token::TextMacro(macro_name) => {
260 preprocess_macro(
261 src,
262 state,
263 cache,
264 (macro_name, spanned_token.1),
265 )?;
266 }
267 Token::DirUndef => {
268 preprocess_undefine(src, state, spanned_token.1)?;
269 }
270 Token::DirTimescale => {
271 preprocess_timescale(src, state, cache, spanned_token.1)?;
272 }
273 Token::DirDefaultNettype => {
274 preprocess_default_nettype(
275 src,
276 state,
277 cache,
278 spanned_token.1,
279 )?;
280 }
281 Token::DirUnconnectedDrive => {
282 preprocess_unconnected_drive(src, state, spanned_token.1)?;
283 }
284 Token::DirNounconnectedDrive => {
285 preprocess_nounconnected_drive(state, spanned_token.1)?;
286 }
287 Token::DirCelldefine => {
288 state.add_cell_define(true, spanned_token.1);
289 }
290 Token::DirEndcelldefine => {
291 state.add_cell_define(false, spanned_token.1);
292 }
293 Token::DirLine => {
294 preprocess_line(src, state, cache, spanned_token.1)?;
295 }
296 Token::DirUnderscoreFile => dest.push(SpannedToken(
297 Token::StringLiteral(
298 state.get_line_directive_file(&spanned_token.1),
299 ),
300 spanned_token.1,
301 )),
302 Token::DirUnderscoreLine => dest.push(SpannedToken(
303 Token::UnsignedNumber(
304 state.get_line_directive_line(&spanned_token.1, cache),
305 ),
306 spanned_token.1,
307 )),
308 Token::BlockComment(_)
309 | Token::OnelineComment(_)
310 | Token::Newline => {
311 #[cfg(feature = "parse_lossless")]
312 {
313 dest.push(spanned_token)
314 }
315 }
316 token if token.keyword_replace(&state.curr_standard) => {
317 let new_token = SpannedToken(
318 Token::SimpleIdentifier(token.as_str()),
319 spanned_token.1,
320 );
321 dest.push(new_token)
322 }
323 _ => dest.push(spanned_token),
324 }
325 }
326 Ok(())
327 }
328}
329
330pub(crate) fn preprocess_single<'s>(
331 src: &mut TokenIterator<'s, impl Iterator<Item = SpannedToken<'s>>>,
332 state: &mut PreprocessorState<'s>,
333 cache: &'s PreprocessorCache<'s>,
334) -> Result<Option<SpannedToken<'s>>, PreprocessorError<'s>> {
335 loop {
336 match src.next() {
337 None => {
338 break Ok(None);
339 }
340 Some(SpannedToken(Token::BlockComment(_), _)) => (),
341 Some(SpannedToken(Token::TextMacro(macro_name), macro_span)) => {
342 preprocess_macro(src, state, cache, (macro_name, macro_span))?;
343 }
344 other => break Ok(other),
345 }
346 }
347}
348
349pub fn preprocess<'s>(
350 src: impl Iterator<Item = SpannedToken<'s>>,
351 state: &mut PreprocessorState<'s>,
352 cache: &'s PreprocessorCache<'s>,
353) -> Result<Vec<SpannedToken<'s>>, PreprocessorError<'s>> {
354 let mut token_iter = TokenIterator::new(src);
355 let mut dest = Vec::new();
356 preprocess_helper(&mut token_iter, &mut dest, state, cache)?;
357 Ok(dest)
358}