macro_rules! unexpected {
($p:expr) => {{
syntax_error!($p, $p.input.cur_span(), SyntaxError::Unexpected)
}};
}
macro_rules! is {
($p:expr,BindingIdent) => {{
let ctx = $p.ctx();
match cur!($p, false) {
Ok(&Word(ref w)) => !ctx.is_reserved_word(&w.clone().into()),
_ => false,
}
}};
($p:expr,IdentRef) => {{
let ctx = $p.ctx();
match cur!($p, false) {
Ok(&Word(ref w)) => !ctx.is_reserved_word(&w.clone().into()),
_ => false,
}
}};
($p:expr,IdentName) => {{
match cur!($p, false) {
Ok(&Word(..)) => true,
_ => false,
}
}};
($p:expr,';') => {{
$p.input.is(&Token::Semi)
|| eof!($p)
|| is!($p, '}')
|| $p.input.had_line_break_before_cur()
}};
($p:expr, $t:tt) => {
$p.input.is(&tok!($t))
};
}
macro_rules! eof {
($p:expr) => {
cur!($p, false).is_err()
};
}
macro_rules! peeked_is {
($p:expr, $t:tt) => {
$p.input.peeked_is(&tok!($t))
};
}
macro_rules! is_one_of {
($p:expr, $($t:tt),+) => {{
false
$(
|| is!($p, $t)
)*
}};
}
macro_rules! assert_and_bump {
($p:expr, $t:tt) => {{
const TOKEN: &Token = &tok!($t);
if cfg!(debug_assertions) && !$p.input.is(TOKEN) {
unreachable!(
"assertion failed: expected {:?}, got {:?}",
TOKEN,
$p.input.cur()
);
}
bump!($p);
}};
}
macro_rules! eat {
($p:expr,';') => {{
trace!("eat(';'): cur={:?}", cur!($p, true));
$p.input.eat(&Token::Semi)
|| eof!($p)
|| is!($p, '}')
|| $p.input.had_line_break_before_cur()
}};
($p:expr, $t:tt) => {{
const TOKEN: &Token = &tok!($t);
if is!($p, $t) {
bump!($p);
true
} else {
false
}
}};
}
macro_rules! eat_exact {
($p:expr, $t:tt) => {{
const TOKEN: &Token = &token_including_semi!($t);
if $p.input.is(TOKEN) {
bump!($p);
true
} else {
false
}
}};
}
macro_rules! expect {
($p:expr, $t:tt) => {{
const TOKEN: &Token = &token_including_semi!($t);
if !eat!($p, $t) {
syntax_error!($p, $p.input.cur_span(), SyntaxError::Expected(TOKEN))
}
}};
}
macro_rules! expect_exact {
($p:expr, $t:tt) => {{
const TOKEN: &Token = &token_including_semi!($t);
if !eat_exact!($p, $t) {
syntax_error!($p, $p.input.cur_span(), SyntaxError::Expected(TOKEN))
}
}};
}
macro_rules! cur {
($p:expr, $required:expr) => {{
let pos = $p.input.last_pos();
let last = Span::new(pos, pos, Default::default());
let is_err_token = match $p.input.cur() {
Some(&$crate::token::Token::Error(..)) => true,
_ => false,
};
if is_err_token {
match $p.input.bump() {
$crate::token::Token::Error(e) => {
::swc_common::errors::DiagnosticBuilder::from($crate::error::ErrorToDiag {
handler: &$p.session.handler,
span: e.span,
error: e.error,
})
.emit();
let err: Result<!, _> = Err(());
err?
}
_ => unreachable!(),
}
}
match $p.input.cur() {
Some(c) => Ok(c),
None => {
if $required {
::swc_common::errors::DiagnosticBuilder::from($crate::error::Eof {
last,
handler: &$p.session.handler,
})
.emit();
}
Err(())
}
}
}};
}
macro_rules! peek {
($p:expr) => {{
assert!(
$p.input.knows_cur(),
"parser should not call peek() without knowing current token.
Current token is {:?}",
cur!($p, false),
);
let pos = cur_pos!($p);
let last = Span::new(pos, pos, Default::default());
match $p.input.peek() {
Some(c) => Ok(c),
None => {
::swc_common::errors::DiagnosticBuilder::from($crate::error::Eof {
last,
handler: &$p.session.handler,
})
.emit();
Err(())
}
}
}};
}
macro_rules! bump {
($p:expr) => {{
assert!(
$p.input.knows_cur(),
"parser should not call bump() without knowing current token"
);
$p.input.bump()
}};
}
macro_rules! cur_pos {
($p:expr) => {{
let pos = $p.input.cur_pos();
pos
}};
}
macro_rules! last_pos {
($p:expr) => {
$p.input.prev_span().hi()
};
}
macro_rules! return_if_arrow {
($p:expr, $expr:expr) => {{
match *$expr {
Expr::Arrow { .. } => return Ok($expr),
_ => {}
}
}};
}
macro_rules! span {
($p:expr, $start:expr) => {{
let start: ::swc_common::BytePos = $start;
let end: ::swc_common::BytePos = last_pos!($p);
if cfg!(debug_assertions) && start > end {
unreachable!(
"assertion failed: (span.start <= span.end).
start = {}, end = {}",
start.0, end.0
)
}
::swc_common::Span::new(start, end, ::swc_common::SyntaxContext::empty())
}};
}
macro_rules! syntax_error {
($p:expr, $err:expr) => {
syntax_error!($p, $p.input.cur_span(), $err)
};
($p:expr, $span:expr, $err:expr) => {{
::swc_common::errors::DiagnosticBuilder::from($crate::error::ErrorToDiag {
handler: $p.session.handler,
span: $span,
error: $err,
})
.emit();
let res: Result<!, _> = Err(());
res?
}};
}