Browse Source

Await expression parsing

pull/836/head
Paul Lancaster 4 years ago
parent
commit
9aa6c77b0e
  1. 59
      boa/src/syntax/ast/node/await_expr/mod.rs
  2. 7
      boa/src/syntax/ast/node/mod.rs
  3. 58
      boa/src/syntax/parser/expression/await_expr.rs
  4. 2
      boa/src/syntax/parser/expression/mod.rs
  5. 8
      boa/src/syntax/parser/expression/primary/object_initializer/mod.rs
  6. 4
      boa/src/syntax/parser/expression/unary.rs
  7. 4
      boa/src/syntax/parser/statement/mod.rs

59
boa/src/syntax/ast/node/await_expr/mod.rs

@ -0,0 +1,59 @@
//! Await expression node.
use super::Node;
use crate::{exec::Executable, BoaProfiler, Context, Result, Value};
use gc::{Finalize, Trace};
use std::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
///
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]:
/// [mdn]:
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct AwaitExpr {
expr: Box<Node>,
}
impl Executable for AwaitExpr {
fn run(&self, interpreter: &mut Context) -> Result<Value> {
let _timer = BoaProfiler::global().start_event("AwaitExpression", "exec");
unimplemented!("Await expression execution");
}
}
impl AwaitExpr {
/// Implements the display formatting with indentation.
pub(super) fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result {
writeln!(f, "await ")?;
self.expr.display(f, indentation)
}
}
impl<T> From<T> for AwaitExpr
where
T: Into<Box<Node>>,
{
fn from(e: T) -> Self {
Self { expr: e.into() }
}
}
impl fmt::Display for AwaitExpr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.display(f, 0)
}
}
impl From<AwaitExpr> for Node {
fn from(awaitexpr: AwaitExpr) -> Self {
Self::AwaitExpr(awaitexpr)
}
}

7
boa/src/syntax/ast/node/mod.rs

@ -1,6 +1,7 @@
//! This module implements the `Node` structure, which composes the AST.
pub mod array;
pub mod await_expr;
pub mod block;
pub mod break_node;
pub mod call;
@ -21,6 +22,7 @@ pub mod try_node;
pub use self::{
array::ArrayDecl,
await_expr::AwaitExpr,
block::Block,
break_node::Break,
call::Call,
@ -71,6 +73,9 @@ pub enum Node {
/// An async function expression node. [More information](./declaration/struct.AsyncFunctionExpr.html).
AsyncFunctionExpr(AsyncFunctionExpr),
/// An await expression node. [More information](./await_expr/struct.AwaitExpression.html).
AwaitExpr(AwaitExpr),
/// A binary operator node. [More information](./operator/struct.BinOp.html).
BinOp(BinOp),
@ -251,6 +256,7 @@ impl Node {
Self::ConstDeclList(ref decl) => Display::fmt(decl, f),
Self::AsyncFunctionDecl(ref decl) => decl.display(f, indentation),
Self::AsyncFunctionExpr(ref expr) => expr.display(f, indentation),
Self::AwaitExpr(ref expr) => expr.display(f, indentation),
}
}
}
@ -261,6 +267,7 @@ impl Executable for Node {
match *self {
Node::AsyncFunctionDecl(ref decl) => decl.run(interpreter),
Node::AsyncFunctionExpr(ref function_expr) => function_expr.run(interpreter),
Node::AwaitExpr(ref expr) => expr.run(interpreter),
Node::Call(ref call) => call.run(interpreter),
Node::Const(Const::Null) => Ok(Value::null()),
Node::Const(Const::Num(num)) => Ok(Value::rational(num)),

58
boa/src/syntax/parser/expression/await_expr.rs

@ -0,0 +1,58 @@
//! Await expression parsing.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript specification][spec]
//!
//! [mdn]:
//! [spec]:
use super::unary::UnaryExpression;
use crate::syntax::{
ast::{node::AwaitExpr, Keyword},
lexer::TokenKind,
parser::{AllowYield, Cursor, ParseError, TokenParser},
};
use std::io::Read;
/// Parses a await expression.
///
/// More information:
/// - [MDN documentation][mdn]
/// - [ECMAScript specification][spec]
///
/// [mdn]:
/// [spec]:
#[derive(Debug, Clone, Copy)]
pub(in crate::syntax::parser) struct AwaitExpression {
allow_yield: AllowYield,
}
impl AwaitExpression {
/// Creates a new `AwaitExpression` parser.
pub(in crate::syntax::parser) fn new<Y>(allow_yield: Y) -> Self
where
Y: Into<AllowYield>,
{
Self {
allow_yield: allow_yield.into(),
}
}
}
impl<R> TokenParser<R> for AwaitExpression
where
R: Read,
{
type Output = AwaitExpr;
fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError> {
cursor.expect(
TokenKind::Keyword(Keyword::Await),
"Await expression parsing",
)?;
let expr = UnaryExpression::new(self.allow_yield, true).parse(cursor)?;
Ok(expr.into())
}
}

2
boa/src/syntax/parser/expression/mod.rs

@ -15,6 +15,8 @@ mod tests;
mod unary;
mod update;
pub(in crate::syntax::parser) mod await_expr;
use self::assignment::ExponentiationExpression;
pub(super) use self::{assignment::AssignmentExpression, primary::Initializer};
use super::{AllowAwait, AllowIn, AllowYield, Cursor, ParseResult, TokenParser};

8
boa/src/syntax/parser/expression/primary/object_initializer/mod.rs

@ -141,6 +141,14 @@ where
return Ok(node::PropertyDefinition::property(prop_name, val));
}
// TODO GeneratorMethod
if prop_name.as_str() == "async" {
// TODO - AsyncMethod.
// TODO - AsyncGeneratorMethod
}
if cursor
.next_if(TokenKind::Punctuator(Punctuator::OpenParen))?
.is_some()

4
boa/src/syntax/parser/expression/unary.rs

@ -33,14 +33,14 @@ use std::io::Read;
/// [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 {
pub(in crate::syntax::parser) 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
pub(in crate::syntax::parser) fn new<Y, A>(allow_yield: Y, allow_await: A) -> Self
where
Y: Into<AllowYield>,
A: Into<AllowAwait>,

4
boa/src/syntax/parser/statement/mod.rs

@ -42,6 +42,7 @@ use crate::{
syntax::{
ast::{node, Keyword, Node, Punctuator},
lexer::{Error as LexError, InputElement, TokenKind},
parser::expression::await_expr::AwaitExpression,
},
BoaProfiler,
};
@ -110,6 +111,9 @@ where
let tok = cursor.peek(0)?.ok_or(ParseError::AbruptEnd)?;
match tok.kind() {
TokenKind::Keyword(Keyword::Await) => AwaitExpression::new(self.allow_yield)
.parse(cursor)
.map(Node::from),
TokenKind::Keyword(Keyword::If) => {
IfStatement::new(self.allow_yield, self.allow_await, self.allow_return)
.parse(cursor)

Loading…
Cancel
Save