From e5072b30a9a9374e3dff4b95f6b9ed5a8a7efe4f Mon Sep 17 00:00:00 2001 From: razican Date: Sat, 18 Apr 2020 15:18:53 +0200 Subject: [PATCH] Divided function parsing --- .../syntax/parser/function/arrow_function.rs | 68 +++++++++++++ .../parser/function/function_definition.rs | 53 ++++++++++ boa/src/syntax/parser/function/mod.rs | 99 ++----------------- 3 files changed, 128 insertions(+), 92 deletions(-) create mode 100644 boa/src/syntax/parser/function/arrow_function.rs create mode 100644 boa/src/syntax/parser/function/function_definition.rs diff --git a/boa/src/syntax/parser/function/arrow_function.rs b/boa/src/syntax/parser/function/arrow_function.rs new file mode 100644 index 00000000000..b11b08652e3 --- /dev/null +++ b/boa/src/syntax/parser/function/arrow_function.rs @@ -0,0 +1,68 @@ +//! Arrow function parsing. +//! +//! More information: +//! - [MDN documentation][mdn] +//! - [ECMAScript specification][spec] +//! +//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions +//! [spec]: https://tc39.es/ecma262/#sec-arrow-function-definitions + +use super::read_formal_parameters; +use crate::syntax::{ + ast::{ + node::{FormalParameter, Node}, + punc::Punctuator, + token::TokenKind, + }, + parser::{read_statements, AssignmentExpression, Cursor, ParseError, ParseResult, TokenParser}, +}; + +/// Arrow function parsing. +/// +/// More information: +/// - [MDN documentation][mdn] +/// - [ECMAScript specification][spec] +/// +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions +/// [spec]: https://tc39.es/ecma262/#prod-ArrowFunction +#[derive(Debug, Clone, Copy)] +pub(in crate::syntax::parser) struct ArrowFunction; + +impl TokenParser for ArrowFunction { + fn parse(cursor: &mut Cursor<'_>) -> ParseResult { + let next_token = cursor.next().ok_or(ParseError::AbruptEnd)?; + let params = match &next_token.kind { + TokenKind::Punctuator(Punctuator::OpenParen) => read_formal_parameters(cursor)?, + TokenKind::Identifier(param_name) => vec![FormalParameter { + init: None, + name: param_name.clone(), + is_rest_param: false, + }], + _ => { + return Err(ParseError::Expected( + vec![ + TokenKind::Punctuator(Punctuator::OpenParen), + TokenKind::identifier("identifier"), + ], + next_token.clone(), + "arrow function", + )) + } + }; + + cursor.expect_punc(Punctuator::Arrow, "arrow function")?; + + cursor.skip(|tk| tk.kind == TokenKind::LineTerminator); + let body = match cursor.peek(0) { + Some(tk) if tk.kind == TokenKind::Punctuator(Punctuator::OpenBlock) => { + let _ = cursor.next(); + let body = read_statements(cursor, true).map(Node::StatementList)?; + cursor.expect_punc(Punctuator::CloseBlock, "arrow function")?; + body + } + _ => Node::return_node(AssignmentExpression::parse(cursor)?), + }; + + Ok(Node::arrow_function_decl(params, body)) + } +} diff --git a/boa/src/syntax/parser/function/function_definition.rs b/boa/src/syntax/parser/function/function_definition.rs new file mode 100644 index 00000000000..8be43f10502 --- /dev/null +++ b/boa/src/syntax/parser/function/function_definition.rs @@ -0,0 +1,53 @@ +//! Function definition parsing. +//! +//! More information: +//! - [MDN documentation][mdn] +//! - [ECMAScript specification][spec] +//! +//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function +//! [spec]: https://tc39.es/ecma262/#sec-function-definitions + +use super::read_formal_parameters; +use crate::syntax::{ + ast::{node::Node, punc::Punctuator, token::TokenKind}, + parser::{read_statements, Cursor, ParseError, ParseResult, TokenParser}, +}; + +/// Function expression parsing. +/// +/// More information: +/// - [MDN documentation][mdn] +/// - [ECMAScript specification][spec] +/// +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function +/// [spec]: https://tc39.es/ecma262/#prod-FunctionExpression +#[derive(Debug, Clone, Copy)] +pub(in crate::syntax::parser) struct FunctionExpression; + +impl TokenParser for FunctionExpression { + fn parse(cursor: &mut Cursor<'_>) -> ParseResult { + let name = if let TokenKind::Identifier(name) = + &cursor.peek(0).ok_or(ParseError::AbruptEnd)?.kind + { + Some(name) + } else { + None + }; + if name.is_some() { + // We move the cursor forward. + let _ = cursor.next().expect("nex token disappeared"); + } + + cursor.expect_punc(Punctuator::OpenParen, "function expression")?; + + let params = read_formal_parameters(cursor)?; + + cursor.expect_punc(Punctuator::OpenBlock, "function expression")?; + + let body = read_statements(cursor, true).map(Node::StatementList)?; + + cursor.expect_punc(Punctuator::CloseBlock, "function expression")?; + + Ok(Node::function_decl::<_, &String, _, _>(name, params, body)) + } +} diff --git a/boa/src/syntax/parser/function/mod.rs b/boa/src/syntax/parser/function/mod.rs index 3e1d0995c51..4a56b6cc969 100644 --- a/boa/src/syntax/parser/function/mod.rs +++ b/boa/src/syntax/parser/function/mod.rs @@ -1,4 +1,4 @@ -//! Function parsing. +//! Functions and classes parsing. //! //! More information: //! - [MDN documentation][mdn] @@ -7,62 +7,16 @@ //! [mdn]: https://developer.mozilla.org/en-US/docs/Glossary/Function //! [spec]: https://tc39.es/ecma262/#sec-ecmascript-language-functions-and-classes -use super::{read_statements, AssignmentExpression, Cursor, ParseError, ParseResult, TokenParser}; +mod arrow_function; +mod function_definition; + +use super::{Cursor, ParseError}; use crate::syntax::ast::{ - node::{FormalParameter, FormalParameters, Node}, + node::{FormalParameter, FormalParameters}, punc::Punctuator, token::TokenKind, }; - -/// Arrow function parsing. -/// -/// More information: -/// - [MDN documentation][mdn] -/// - [ECMAScript specification][spec] -/// -/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions -/// [spec]: https://tc39.es/ecma262/#sec-arrow-function-definitions -#[derive(Debug, Clone, Copy)] -pub(super) struct ArrowFunction; - -impl TokenParser for ArrowFunction { - fn parse(cursor: &mut Cursor<'_>) -> ParseResult { - let next_token = cursor.next().ok_or(ParseError::AbruptEnd)?; - let params = match &next_token.kind { - TokenKind::Punctuator(Punctuator::OpenParen) => read_formal_parameters(cursor)?, - TokenKind::Identifier(param_name) => vec![FormalParameter { - init: None, - name: param_name.clone(), - is_rest_param: false, - }], - _ => { - return Err(ParseError::Expected( - vec![ - TokenKind::Punctuator(Punctuator::OpenParen), - TokenKind::identifier("identifier"), - ], - next_token.clone(), - "arrow function", - )) - } - }; - - cursor.expect_punc(Punctuator::Arrow, "arrow function")?; - - cursor.skip(|tk| tk.kind == TokenKind::LineTerminator); - let body = match cursor.peek(0) { - Some(tk) if tk.kind == TokenKind::Punctuator(Punctuator::OpenBlock) => { - let _ = cursor.next(); - let body = read_statements(cursor, true).map(Node::StatementList)?; - cursor.expect_punc(Punctuator::CloseBlock, "arrow function")?; - body - } - _ => Node::return_node(AssignmentExpression::parse(cursor)?), - }; - - Ok(Node::arrow_function_decl(params, body)) - } -} +pub(super) use {arrow_function::ArrowFunction, function_definition::FunctionExpression}; /// Formal parameters parsing. /// @@ -172,42 +126,3 @@ fn read_formal_parameter(cursor: &mut Cursor<'_>) -> Result) -> ParseResult { - let name = if let TokenKind::Identifier(name) = - &cursor.peek(0).ok_or(ParseError::AbruptEnd)?.kind - { - Some(name) - } else { - None - }; - if name.is_some() { - // We move the cursor forward. - let _ = cursor.next().expect("nex token disappeared"); - } - - cursor.expect_punc(Punctuator::OpenParen, "function expression")?; - - let params = read_formal_parameters(cursor)?; - - cursor.expect_punc(Punctuator::OpenBlock, "function expression")?; - - let body = read_statements(cursor, true).map(Node::StatementList)?; - - cursor.expect_punc(Punctuator::CloseBlock, "function expression")?; - - Ok(Node::function_decl::<_, &String, _, _>(name, params, body)) - } -}