Skip to content

Commit

Permalink
Merge c2bf1b3 into e82dee1
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Lancaster authored Oct 9, 2020
2 parents e82dee1 + c2bf1b3 commit 5ad0aff
Show file tree
Hide file tree
Showing 8 changed files with 309 additions and 6 deletions.
12 changes: 12 additions & 0 deletions boa/src/syntax/ast/keyword.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ pub enum Keyword {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
Await,

/// The `async` keyword.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-AsyncMethod
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
Async,

/// The `break` keyword.
///
/// More information:
Expand Down Expand Up @@ -454,6 +464,7 @@ impl Keyword {
pub fn as_str(self) -> &'static str {
match self {
Self::Await => "await",
Self::Async => "async",
Self::Break => "break",
Self::Case => "case",
Self::Catch => "catch",
Expand Down Expand Up @@ -526,6 +537,7 @@ impl FromStr for Keyword {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"await" => Ok(Self::Await),
"async" => Ok(Self::Async),
"break" => Ok(Self::Break),
"case" => Ok(Self::Case),
"catch" => Ok(Self::Catch),
Expand Down
92 changes: 92 additions & 0 deletions boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use crate::{
exec::Executable,
syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList},
BoaProfiler, Context, Result, Value,
};
use gc::{Finalize, Trace};
use std::fmt;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// Async Function Declaration.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-async-function-prototype-properties
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct AsyncFunctionDecl {
name: Box<str>,
parameters: Box<[FormalParameter]>,
body: StatementList,
}

impl AsyncFunctionDecl {
/// Creates a new async function declaration.
pub(in crate::syntax) fn new<N, P, B>(name: N, parameters: P, body: B) -> Self
where
N: Into<Box<str>>,
P: Into<Box<[FormalParameter]>>,
B: Into<StatementList>,
{
Self {
name: name.into(),
parameters: parameters.into(),
body: body.into(),
}
}

/// Gets the name of the async function declaration.
pub fn name(&self) -> &str {
&self.name
}

/// Gets the list of parameters of the async function declaration.
pub fn parameters(&self) -> &[FormalParameter] {
&self.parameters
}

/// Gets the body of the async function declaration.
pub fn body(&self) -> &[Node] {
self.body.statements()
}

/// Implements the display formatting with indentation.
pub(in crate::syntax::ast::node) fn display(
&self,
f: &mut fmt::Formatter<'_>,
indentation: usize,
) -> fmt::Result {
write!(f, "async function {}(", self.name)?;
join_nodes(f, &self.parameters)?;
f.write_str(") {{")?;

self.body.display(f, indentation + 1)?;

writeln!(f, "}}")
}
}

impl Executable for AsyncFunctionDecl {
fn run(&self, interpreter: &mut Context) -> Result<Value> {
let _timer = BoaProfiler::global().start_event("AsyncFunctionDecl", "exec");
unimplemented!("Execute AsyncFunctionDecl");
Ok(Value::undefined())
}
}

impl From<AsyncFunctionDecl> for Node {
fn from(decl: AsyncFunctionDecl) -> Self {
Self::AsyncFunctionDecl(decl)
}
}

impl fmt::Display for AsyncFunctionDecl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.display(f, 0)
}
}
94 changes: 94 additions & 0 deletions boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use crate::{
exec::Executable,
syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList},
Context, Result, Value,
};
use gc::{Finalize, Trace};
use std::fmt;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// AsyncFunctionExpr.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-AsyncFunctionExpression
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/async_function
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct AsyncFunctionExpr {
name: Option<Box<str>>,
parameters: Box<[FormalParameter]>,
body: StatementList,
}

impl AsyncFunctionExpr {
/// Creates a new function expression
pub(in crate::syntax) fn new<N, P, B>(name: N, parameters: P, body: B) -> Self
where
N: Into<Option<Box<str>>>,
P: Into<Box<[FormalParameter]>>,
B: Into<StatementList>,
{
Self {
name: name.into(),
parameters: parameters.into(),
body: body.into(),
}
}

/// Gets the name of the function declaration.
pub fn name(&self) -> Option<&str> {
self.name.as_ref().map(Box::as_ref)
}

/// Gets the list of parameters of the function declaration.
pub fn parameters(&self) -> &[FormalParameter] {
&self.parameters
}

/// Gets the body of the function declaration.
pub fn body(&self) -> &[Node] {
self.body.statements()
}

/// Implements the display formatting with indentation.
pub(in crate::syntax::ast::node) fn display(
&self,
f: &mut fmt::Formatter<'_>,
indentation: usize,
) -> fmt::Result {
f.write_str("function")?;
if let Some(ref name) = self.name {
write!(f, " {}", name)?;
}
f.write_str("(")?;
join_nodes(f, &self.parameters)?;
f.write_str(") {{")?;

self.body.display(f, indentation + 1)?;

writeln!(f, "}}")
}
}

impl Executable for AsyncFunctionExpr {
fn run(&self, interpreter: &mut Context) -> Result<Value> {
unimplemented!("Execute AsyncFunctionExpr");
}
}

impl fmt::Display for AsyncFunctionExpr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.display(f, 0)
}
}

impl From<AsyncFunctionExpr> for Node {
fn from(expr: AsyncFunctionExpr) -> Self {
Self::AsyncFunctionExpr(expr)
}
}
4 changes: 4 additions & 0 deletions boa/src/syntax/ast/node/declaration/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Declaration nodes
pub mod arrow_function_decl;
pub mod async_function_decl;
pub mod async_function_expr;
pub mod const_decl_list;
pub mod function_decl;
pub mod function_expr;
Expand All @@ -9,6 +11,8 @@ pub mod var_decl_list;

pub use self::{
arrow_function_decl::ArrowFunctionDecl,
async_function_decl::AsyncFunctionDecl,
async_function_expr::AsyncFunctionExpr,
const_decl_list::{ConstDecl, ConstDeclList},
function_decl::FunctionDecl,
function_expr::FunctionExpr,
Expand Down
16 changes: 13 additions & 3 deletions boa/src/syntax/ast/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ pub use self::{
call::Call,
conditional::{ConditionalOp, If},
declaration::{
ArrowFunctionDecl, ConstDecl, ConstDeclList, FunctionDecl, FunctionExpr, LetDecl,
LetDeclList, VarDecl, VarDeclList,
ArrowFunctionDecl, AsyncFunctionDecl, AsyncFunctionExpr, ConstDecl, ConstDeclList,
FunctionDecl, FunctionExpr, LetDecl, LetDeclList, VarDecl, VarDeclList,
},
field::{GetConstField, GetField},
identifier::Identifier,
Expand Down Expand Up @@ -65,6 +65,12 @@ pub enum Node {
/// An assignment operator node. [More information](./operator/struct.Assign.html).
Assign(Assign),

/// An async function declaration node. [More information](./declaration/struct.AsyncFunctionDecl.html).
AsyncFunctionDecl(AsyncFunctionDecl),

/// An async function expression node. [More information](./declaration/struct.AsyncFunctionExpr.html).
AsyncFunctionExpr(AsyncFunctionExpr),

/// A binary operator node. [More information](./operator/struct.BinOp.html).
BinOp(BinOp),

Expand Down Expand Up @@ -104,7 +110,7 @@ pub enum Node {
/// A function declaration node. [More information](./declaration/struct.FunctionDecl.html).
FunctionDecl(FunctionDecl),

/// A function expressino node. [More information](./declaration/struct.FunctionExpr.html).
/// A function expression node. [More information](./declaration/struct.FunctionExpr.html).
FunctionExpr(FunctionExpr),

/// Provides access to an object types' constant properties. [More information](./declaration/struct.GetConstField.html).
Expand Down Expand Up @@ -243,6 +249,8 @@ impl Node {
Self::Assign(ref op) => Display::fmt(op, f),
Self::LetDeclList(ref decl) => Display::fmt(decl, f),
Self::ConstDeclList(ref decl) => Display::fmt(decl, f),
Self::AsyncFunctionDecl(ref decl) => decl.display(f, indentation),
Self::AsyncFunctionExpr(ref expr) => expr.display(f, indentation),
}
}
}
Expand All @@ -251,6 +259,8 @@ impl Executable for Node {
fn run(&self, interpreter: &mut Context) -> Result<Value> {
let _timer = BoaProfiler::global().start_event("Executable", "exec");
match *self {
Node::AsyncFunctionDecl(ref decl) => decl.run(interpreter),
Node::AsyncFunctionExpr(ref function_expr) => function_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)),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//! Async Function expression parsing.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript specification][spec]
//!
//! [mdn]:
//! [spec]:
use crate::{
syntax::{
ast::node::AsyncFunctionExpr,
parser::{Cursor, ParseError, TokenParser},
},
BoaProfiler,
};

use std::io::Read;

/// Async Function expression parsing.
///
/// More information:
/// - [MDN documentation][mdn]
/// - [ECMAScript specification][spec]
///
/// [mdn]:
/// [spec]:
#[derive(Debug, Clone, Copy)]
pub(super) struct AsyncFunctionExpression;

impl<R> TokenParser<R> for AsyncFunctionExpression
where
R: Read,
{
type Output = AsyncFunctionExpr;

fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError> {
let _timer = BoaProfiler::global().start_event("AsyncFunctionExpression", "Parsing");

unimplemented!("Async function expression parse");
}
}
8 changes: 6 additions & 2 deletions boa/src/syntax/parser/expression/primary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
//! [spec]: https://tc39.es/ecma262/#prod-PrimaryExpression
mod array_initializer;
mod async_function_expression;
mod function_expression;
mod object_initializer;
#[cfg(test)]
mod tests;

use self::{
array_initializer::ArrayLiteral, function_expression::FunctionExpression,
object_initializer::ObjectLiteral,
array_initializer::ArrayLiteral, async_function_expression::AsyncFunctionExpression,
function_expression::FunctionExpression, object_initializer::ObjectLiteral,
};
use super::Expression;
use crate::{
Expand Down Expand Up @@ -77,6 +78,9 @@ where
TokenKind::Keyword(Keyword::Function) => {
FunctionExpression.parse(cursor).map(Node::from)
}
TokenKind::Keyword(Keyword::Async) => {
AsyncFunctionExpression.parse(cursor).map(Node::from)
}
TokenKind::Punctuator(Punctuator::OpenParen) => {
cursor.set_goal(InputElement::RegExp);
let expr =
Expand Down
Loading

0 comments on commit 5ad0aff

Please sign in to comment.