mod assignment;
mod left_hand_side;
mod primary;
#[cfg(test)]
mod tests;
mod unary;
mod update;
use self::assignment::ExponentiationExpression;
pub(super) use self::{assignment::AssignmentExpression, primary::Initializer};
use super::{AllowAwait, AllowIn, AllowYield, Cursor, ParseResult, TokenParser};
use crate::syntax::lexer::{InputElement, TokenKind};
use crate::{
profiler::BoaProfiler,
syntax::ast::{
node::{BinOp, Node},
Keyword, Punctuator,
},
};
use std::io::Read;
impl PartialEq<Keyword> for Punctuator {
fn eq(&self, _other: &Keyword) -> bool {
false
}
}
impl PartialEq<Punctuator> for Keyword {
fn eq(&self, _other: &Punctuator) -> bool {
false
}
}
macro_rules! expression { ($name:ident, $lower:ident, [$( $op:path ),*], [$( $low_param:ident ),*], $goal:expr, $profile:expr ) => {
impl<R> TokenParser<R> for $name
where
R: Read
{
type Output = Node;
fn parse(self, cursor: &mut Cursor<R>) -> ParseResult {
let _timer = BoaProfiler::global().start_event($profile, "Parsing");
if $goal.is_some() {
cursor.set_goal($goal.unwrap());
}
let mut lhs = $lower::new($( self.$low_param ),*).parse(cursor)?;
while let Some(tok) = cursor.peek(0)? {
match *tok.kind() {
TokenKind::Punctuator(op) if $( op == $op )||* => {
let _ = cursor.next().expect("token disappeared");
lhs = BinOp::new(
op.as_binop().expect("Could not get binary operation."),
lhs,
$lower::new($( self.$low_param ),*).parse(cursor)?
).into();
}
TokenKind::Keyword(op) if $( op == $op )||* => {
let _ = cursor.next().expect("token disappeared");
lhs = BinOp::new(
op.as_binop().expect("Could not get binary operation."),
lhs,
$lower::new($( self.$low_param ),*).parse(cursor)?
).into();
}
_ => break
}
}
Ok(lhs)
}
}
} }
#[derive(Debug, Clone, Copy)]
pub(super) struct Expression {
allow_in: AllowIn,
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl Expression {
pub(super) fn new<I, Y, A>(allow_in: I, allow_yield: Y, allow_await: A) -> Self
where
I: Into<AllowIn>,
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_in: allow_in.into(),
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
Expression,
AssignmentExpression,
[Punctuator::Comma],
[allow_in, allow_yield, allow_await],
None::<InputElement>,
"Expression"
);
#[derive(Debug, Clone, Copy)]
struct LogicalORExpression {
allow_in: AllowIn,
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl LogicalORExpression {
pub(super) fn new<I, Y, A>(allow_in: I, allow_yield: Y, allow_await: A) -> Self
where
I: Into<AllowIn>,
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_in: allow_in.into(),
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
LogicalORExpression,
LogicalANDExpression,
[Punctuator::BoolOr],
[allow_in, allow_yield, allow_await],
None::<InputElement>,
"LogicalOrExpression"
);
#[derive(Debug, Clone, Copy)]
struct LogicalANDExpression {
allow_in: AllowIn,
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl LogicalANDExpression {
pub(super) fn new<I, Y, A>(allow_in: I, allow_yield: Y, allow_await: A) -> Self
where
I: Into<AllowIn>,
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_in: allow_in.into(),
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
LogicalANDExpression,
BitwiseORExpression,
[Punctuator::BoolAnd],
[allow_in, allow_yield, allow_await],
None::<InputElement>,
"LogicalANDExpression"
);
#[derive(Debug, Clone, Copy)]
struct BitwiseORExpression {
allow_in: AllowIn,
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl BitwiseORExpression {
pub(super) fn new<I, Y, A>(allow_in: I, allow_yield: Y, allow_await: A) -> Self
where
I: Into<AllowIn>,
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_in: allow_in.into(),
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
BitwiseORExpression,
BitwiseXORExpression,
[Punctuator::Or],
[allow_in, allow_yield, allow_await],
None::<InputElement>,
"BitwiseORExpression"
);
#[derive(Debug, Clone, Copy)]
struct BitwiseXORExpression {
allow_in: AllowIn,
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl BitwiseXORExpression {
pub(super) fn new<I, Y, A>(allow_in: I, allow_yield: Y, allow_await: A) -> Self
where
I: Into<AllowIn>,
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_in: allow_in.into(),
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
BitwiseXORExpression,
BitwiseANDExpression,
[Punctuator::Xor],
[allow_in, allow_yield, allow_await],
None::<InputElement>,
"BitwiseXORExpression"
);
#[derive(Debug, Clone, Copy)]
struct BitwiseANDExpression {
allow_in: AllowIn,
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl BitwiseANDExpression {
pub(super) fn new<I, Y, A>(allow_in: I, allow_yield: Y, allow_await: A) -> Self
where
I: Into<AllowIn>,
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_in: allow_in.into(),
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
BitwiseANDExpression,
EqualityExpression,
[Punctuator::And],
[allow_in, allow_yield, allow_await],
None::<InputElement>,
"BitwiseANDExpression"
);
#[derive(Debug, Clone, Copy)]
struct EqualityExpression {
allow_in: AllowIn,
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl EqualityExpression {
pub(super) fn new<I, Y, A>(allow_in: I, allow_yield: Y, allow_await: A) -> Self
where
I: Into<AllowIn>,
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_in: allow_in.into(),
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
EqualityExpression,
RelationalExpression,
[
Punctuator::Eq,
Punctuator::NotEq,
Punctuator::StrictEq,
Punctuator::StrictNotEq
],
[allow_in, allow_yield, allow_await],
None::<InputElement>,
"EqualityExpression"
);
#[derive(Debug, Clone, Copy)]
struct RelationalExpression {
allow_in: AllowIn,
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl RelationalExpression {
pub(super) fn new<I, Y, A>(allow_in: I, allow_yield: Y, allow_await: A) -> Self
where
I: Into<AllowIn>,
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_in: allow_in.into(),
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
RelationalExpression,
ShiftExpression,
[
Punctuator::LessThan,
Punctuator::GreaterThan,
Punctuator::LessThanOrEq,
Punctuator::GreaterThanOrEq,
Keyword::InstanceOf,
Keyword::In
],
[allow_yield, allow_await],
None::<InputElement>,
"RelationoalExpression"
);
#[derive(Debug, Clone, Copy)]
struct ShiftExpression {
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl ShiftExpression {
pub(super) fn new<Y, A>(allow_yield: Y, allow_await: A) -> Self
where
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
ShiftExpression,
AdditiveExpression,
[
Punctuator::LeftSh,
Punctuator::RightSh,
Punctuator::URightSh
],
[allow_yield, allow_await],
None::<InputElement>,
"ShiftExpression"
);
#[derive(Debug, Clone, Copy)]
struct AdditiveExpression {
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl AdditiveExpression {
pub(super) fn new<Y, A>(allow_yield: Y, allow_await: A) -> Self
where
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
AdditiveExpression,
MultiplicativeExpression,
[Punctuator::Add, Punctuator::Sub],
[allow_yield, allow_await],
None::<InputElement>,
"AdditiveExpression"
);
#[derive(Debug, Clone, Copy)]
struct MultiplicativeExpression {
allow_yield: AllowYield,
allow_await: AllowAwait,
}
impl MultiplicativeExpression {
pub(super) fn new<Y, A>(allow_yield: Y, allow_await: A) -> Self
where
Y: Into<AllowYield>,
A: Into<AllowAwait>,
{
Self {
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
}
}
}
expression!(
MultiplicativeExpression,
ExponentiationExpression,
[Punctuator::Mul, Punctuator::Div, Punctuator::Mod],
[allow_yield, allow_await],
Some(InputElement::Div),
"MultiplicativeExpression"
);