Skip to content

Commit

Permalink
Added missing files
Browse files Browse the repository at this point in the history
  • Loading branch information
Razican committed Apr 25, 2020
1 parent a54546e commit e3e6d52
Show file tree
Hide file tree
Showing 3 changed files with 252 additions and 0 deletions.
79 changes: 79 additions & 0 deletions boa/src/syntax/parser/expression/assignment/conditional.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Conditional operator parsing.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript specification][spec]
//!
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
//! [spec]: https://tc39.es/ecma262/#sec-conditional-operator

use crate::syntax::{
ast::{node::Node, punc::Punctuator, token::TokenKind},
parser::{
expression::{AssignmentExpression, LogicalORExpression},
AllowAwait, AllowIn, AllowYield, Cursor, ParseResult, TokenParser,
},
};

/// Conditional expression parsing.
///
/// More information:
/// - [MDN documentation][mdn]
/// - [ECMAScript specification][spec]
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
/// [spec]: https://tc39.es/ecma262/#prod-ConditionalExpression
#[derive(Debug, Clone, Copy)]
pub(in crate::syntax::parser::expression) struct ConditionalExpression {
allow_in: AllowIn,
allow_yield: AllowYield,
allow_await: AllowAwait,
}

impl ConditionalExpression {
/// Creates a new `ConditionalExpression` parser.
pub(in crate::syntax::parser::expression) 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(),
}
}
}

impl TokenParser for ConditionalExpression {
type Output = Node;

fn parse(self, cursor: &mut Cursor<'_>) -> ParseResult {
// TODO: coalesce expression
let lhs = LogicalORExpression::new(self.allow_in, self.allow_yield, self.allow_await)
.parse(cursor)?;

if let Some(tok) = cursor.next() {
if tok.kind == TokenKind::Punctuator(Punctuator::Question) {
let then_clause =
AssignmentExpression::new(self.allow_in, self.allow_yield, self.allow_await)
.parse(cursor)?;
cursor.expect(Punctuator::Colon, "conditional expression")?;

let else_clause =
AssignmentExpression::new(self.allow_in, self.allow_yield, self.allow_await)
.parse(cursor)?;
return Ok(Node::conditional_op(lhs, then_clause, else_clause));
} else {
cursor.back();
}
}

Ok(lhs)
}
}
94 changes: 94 additions & 0 deletions boa/src/syntax/parser/expression/assignment/exponentiation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//! Exponentiation operator parsing.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript specification][spec]
//!
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation
//! [spec]: https://tc39.es/ecma262/#sec-exp-operator

use crate::syntax::{
ast::{
keyword::Keyword,
node::Node,
op::{BinOp, NumOp},
punc::Punctuator,
token::TokenKind,
},
parser::{
expression::{unary::UnaryExpression, update::UpdateExpression},
AllowAwait, AllowYield, Cursor, ParseResult, TokenParser,
},
};

/// Parses an exponentiation expression.
///
/// More information:
/// - [MDN documentation][mdn]
/// - [ECMAScript specification][spec]
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation
/// [spec]: https://tc39.es/ecma262/#prod-ExponentiationExpression
#[derive(Debug, Clone, Copy)]
pub(in crate::syntax::parser::expression) struct ExponentiationExpression {
allow_yield: AllowYield,
allow_await: AllowAwait,
}

impl ExponentiationExpression {
/// Creates a new `ExponentiationExpression` parser.
pub(in crate::syntax::parser::expression) 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(),
}
}
}

impl ExponentiationExpression {
/// Checks by looking at the next token to see whether it's a unary operator or not.
fn is_unary_expression(cursor: &mut Cursor<'_>) -> bool {
if let Some(tok) = cursor.peek(0) {
match tok.kind {
TokenKind::Keyword(Keyword::Delete)
| TokenKind::Keyword(Keyword::Void)
| TokenKind::Keyword(Keyword::TypeOf)
| TokenKind::Punctuator(Punctuator::Add)
| TokenKind::Punctuator(Punctuator::Sub)
| TokenKind::Punctuator(Punctuator::Not)
| TokenKind::Punctuator(Punctuator::Neg) => true,
_ => false,
}
} else {
false
}
}
}

impl TokenParser for ExponentiationExpression {
type Output = Node;

fn parse(self, cursor: &mut Cursor<'_>) -> ParseResult {
if Self::is_unary_expression(cursor) {
return UnaryExpression::new(self.allow_yield, self.allow_await).parse(cursor);
}

let lhs = UpdateExpression::new(self.allow_yield, self.allow_await).parse(cursor)?;
if let Some(tok) = cursor.next() {
if let TokenKind::Punctuator(Punctuator::Exp) = tok.kind {
return Ok(Node::bin_op(
BinOp::Num(NumOp::Exp),
lhs,
self.parse(cursor)?,
));
} else {
cursor.back();
}
}
Ok(lhs)
}
}
79 changes: 79 additions & 0 deletions boa/src/syntax/parser/expression/unary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Unary operator parsing.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript specification][spec]
//!
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Unary
//! [spec]: https://tc39.es/ecma262/#sec-unary-operators

use crate::syntax::{
ast::{keyword::Keyword, node::Node, op::UnaryOp, punc::Punctuator, token::TokenKind},
parser::{
expression::update::UpdateExpression, AllowAwait, AllowYield, Cursor, ParseError,
ParseResult, TokenParser,
},
};

/// Parses a unary expression.
///
/// More information:
/// - [MDN documentation][mdn]
/// - [ECMAScript specification][spec]
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Unary
/// [spec]: https://tc39.es/ecma262/#prod-UnaryExpression
#[derive(Debug, Clone, Copy)]
pub(super) struct UnaryExpression {
allow_yield: AllowYield,
allow_await: AllowAwait,
}

impl UnaryExpression {
/// Creates a new `UnaryExpression` parser.
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(),
}
}
}

impl TokenParser for UnaryExpression {
type Output = Node;

fn parse(self, cursor: &mut Cursor<'_>) -> ParseResult {
let tok = cursor.next().ok_or(ParseError::AbruptEnd)?;
match tok.kind {
TokenKind::Keyword(Keyword::Delete) => {
Ok(Node::unary_op(UnaryOp::Delete, self.parse(cursor)?))
}
TokenKind::Keyword(Keyword::Void) => {
Ok(Node::unary_op(UnaryOp::Void, self.parse(cursor)?))
}
TokenKind::Keyword(Keyword::TypeOf) => {
Ok(Node::unary_op(UnaryOp::TypeOf, self.parse(cursor)?))
}
TokenKind::Punctuator(Punctuator::Add) => {
Ok(Node::unary_op(UnaryOp::Plus, self.parse(cursor)?))
}
TokenKind::Punctuator(Punctuator::Sub) => {
Ok(Node::unary_op(UnaryOp::Minus, self.parse(cursor)?))
}
TokenKind::Punctuator(Punctuator::Neg) => {
Ok(Node::unary_op(UnaryOp::Tilde, self.parse(cursor)?))
}
TokenKind::Punctuator(Punctuator::Not) => {
Ok(Node::unary_op(UnaryOp::Not, self.parse(cursor)?))
}
_ => {
cursor.back();
UpdateExpression::new(self.allow_yield, self.allow_await).parse(cursor)
}
}
}
}

0 comments on commit e3e6d52

Please sign in to comment.