|
|
@ -8,6 +8,7 @@ use crate::{ |
|
|
|
lexer::{Token, TokenKind}, |
|
|
|
lexer::{Token, TokenKind}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
use core::convert::TryFrom; |
|
|
|
use std::io::Read; |
|
|
|
use std::io::Read; |
|
|
|
|
|
|
|
|
|
|
|
/// Lexes a single line comment.
|
|
|
|
/// Lexes a single line comment.
|
|
|
@ -65,27 +66,59 @@ impl<R> Tokenizer<R> for MultiLineComment { |
|
|
|
let _timer = BoaProfiler::global().start_event("MultiLineComment", "Lexing"); |
|
|
|
let _timer = BoaProfiler::global().start_event("MultiLineComment", "Lexing"); |
|
|
|
|
|
|
|
|
|
|
|
let mut new_line = false; |
|
|
|
let mut new_line = false; |
|
|
|
loop { |
|
|
|
while let Some(ch) = cursor.next_char()? { |
|
|
|
if let Some(ch) = cursor.next_byte()? { |
|
|
|
let tried_ch = char::try_from(ch); |
|
|
|
if ch == b'*' && cursor.next_is(b'/')? { |
|
|
|
match tried_ch { |
|
|
|
break; |
|
|
|
Ok(c) if c == '*' && cursor.next_is(b'/')? => { |
|
|
|
} else if ch == b'\n' { |
|
|
|
return Ok(Token::new( |
|
|
|
new_line = true; |
|
|
|
if new_line { |
|
|
|
} |
|
|
|
TokenKind::LineTerminator |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return Err(Error::syntax( |
|
|
|
TokenKind::Comment |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Span::new(start_pos, cursor.pos()), |
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Ok(c) if c == '\r' || c == '\n' || c == '\u{2028}' || c == '\u{2029}' => { |
|
|
|
|
|
|
|
new_line = true |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => {} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Err(Error::syntax( |
|
|
|
"unterminated multiline comment", |
|
|
|
"unterminated multiline comment", |
|
|
|
cursor.pos(), |
|
|
|
cursor.pos(), |
|
|
|
)); |
|
|
|
)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///Lexes a first line Hashbang comment
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// More information:
|
|
|
|
|
|
|
|
/// - [ECMAScript reference][spec]
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// [spec]: https://tc39.es/ecma262/#sec-ecmascript-language-lexical-grammar
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub(super) struct HashbangComment; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<R> Tokenizer<R> for HashbangComment { |
|
|
|
|
|
|
|
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position) -> Result<Token, Error> |
|
|
|
|
|
|
|
where |
|
|
|
|
|
|
|
R: Read, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
let _timer = BoaProfiler::global().start_event("Hashbang", "Lexing"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while let Some(ch) = cursor.next_char()? { |
|
|
|
|
|
|
|
let tried_ch = char::try_from(ch); |
|
|
|
|
|
|
|
match tried_ch { |
|
|
|
|
|
|
|
Ok(c) if c == '\r' || c == '\n' || c == '\u{2028}' || c == '\u{2029}' => break, |
|
|
|
|
|
|
|
_ => {} |
|
|
|
|
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Ok(Token::new( |
|
|
|
Ok(Token::new( |
|
|
|
if new_line { |
|
|
|
TokenKind::Comment, |
|
|
|
TokenKind::LineTerminator |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
TokenKind::Comment |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Span::new(start_pos, cursor.pos()), |
|
|
|
Span::new(start_pos, cursor.pos()), |
|
|
|
)) |
|
|
|
)) |
|
|
|
} |
|
|
|
} |
|
|
|