Browse Source

Arrow parse (#1051)

* Tests showing arrow func assignment parsing

* Peek ahead 3 for arrow func

* More tests (with correct syntax), removed debug statements
pull/1056/head
Paul Lancaster 4 years ago committed by GitHub
parent
commit
e2f9ecd593
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      boa/src/syntax/parser/cursor/buffered_lexer/mod.rs
  2. 2
      boa/src/syntax/parser/cursor/buffered_lexer/tests.rs
  3. 2
      boa/src/syntax/parser/expression/assignment/arrow_function.rs
  4. 2
      boa/src/syntax/parser/expression/assignment/mod.rs
  5. 193
      boa/src/syntax/parser/function/tests.rs

4
boa/src/syntax/parser/cursor/buffered_lexer/mod.rs

@ -11,7 +11,7 @@ use std::io::Read;
mod tests; mod tests;
/// The maximum number of tokens which can be peeked ahead. /// The maximum number of tokens which can be peeked ahead.
const MAX_PEEK_SKIP: usize = 2; const MAX_PEEK_SKIP: usize = 3;
/// The fixed size of the buffer used for storing values that are peeked ahead. /// The fixed size of the buffer used for storing values that are peeked ahead.
/// ///
@ -46,6 +46,8 @@ where
None::<Token>, None::<Token>,
None::<Token>, None::<Token>,
None::<Token>, None::<Token>,
None::<Token>,
None::<Token>,
], ],
read_index: 0, read_index: 0,
write_index: 0, write_index: 0,

2
boa/src/syntax/parser/cursor/buffered_lexer/tests.rs

@ -208,7 +208,7 @@ fn peek_skip_next_till_end() {
let mut cur = BufferedLexer::from(&b"a b c d e f g h i"[..]); let mut cur = BufferedLexer::from(&b"a b c d e f g h i"[..]);
let mut peeked: [Option<Token>; super::MAX_PEEK_SKIP + 1] = let mut peeked: [Option<Token>; super::MAX_PEEK_SKIP + 1] =
[None::<Token>, None::<Token>, None::<Token>]; [None::<Token>, None::<Token>, None::<Token>, None::<Token>];
loop { loop {
for (i, peek) in peeked.iter_mut().enumerate() { for (i, peek) in peeked.iter_mut().enumerate() {

2
boa/src/syntax/parser/expression/assignment/arrow_function.rs

@ -70,8 +70,8 @@ where
fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError> { fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError> {
let _timer = BoaProfiler::global().start_event("ArrowFunction", "Parsing"); let _timer = BoaProfiler::global().start_event("ArrowFunction", "Parsing");
let next_token = cursor.peek(0)?.ok_or(ParseError::AbruptEnd)?; let next_token = cursor.peek(0)?.ok_or(ParseError::AbruptEnd)?;
let params = if let TokenKind::Punctuator(Punctuator::OpenParen) = &next_token.kind() { let params = if let TokenKind::Punctuator(Punctuator::OpenParen) = &next_token.kind() {
// CoverParenthesizedExpressionAndArrowParameterList // CoverParenthesizedExpressionAndArrowParameterList
cursor.expect(Punctuator::OpenParen, "arrow function")?; cursor.expect(Punctuator::OpenParen, "arrow function")?;

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

@ -145,7 +145,7 @@ where
TokenKind::Punctuator(Punctuator::CloseParen) => { TokenKind::Punctuator(Punctuator::CloseParen) => {
// Need to check if the token after the close paren is an arrow, if so then this is an ArrowFunction // Need to check if the token after the close paren is an arrow, if so then this is an ArrowFunction
// otherwise it is an expression of the form (b). // otherwise it is an expression of the form (b).
if let Some(t) = cursor.peek(2)? { if let Some(t) = cursor.peek(3)? {
if t.kind() == &TokenKind::Punctuator(Punctuator::Arrow) if t.kind() == &TokenKind::Punctuator(Punctuator::Arrow)
{ {
return ArrowFunction::new( return ArrowFunction::new(

193
boa/src/syntax/parser/function/tests.rs

@ -1,6 +1,7 @@
use crate::syntax::{ use crate::syntax::{
ast::node::{ ast::node::{
ArrowFunctionDecl, BinOp, FormalParameter, FunctionDecl, Identifier, Node, Return, ArrowFunctionDecl, BinOp, FormalParameter, FunctionDecl, Identifier, LetDecl, LetDeclList,
Node, Return,
}, },
ast::op::NumOp, ast::op::NumOp,
parser::tests::check_parser, parser::tests::check_parser,
@ -176,3 +177,193 @@ fn check_arrow_empty_return_semicolon_insertion() {
.into()], .into()],
); );
} }
#[test]
fn check_arrow_assignment() {
check_parser(
"let foo = (a) => { return a };",
vec![LetDeclList::from(vec![LetDecl::new::<_, Option<Node>>(
Identifier::from("foo"),
Some(
ArrowFunctionDecl::new(
vec![FormalParameter::new("a", None, false)],
vec![Return::new::<Node, Option<_>, Option<_>>(
Some(Identifier::from("a").into()),
None,
)
.into()],
)
.into(),
),
)])
.into()],
);
}
#[test]
fn check_arrow_assignment_nobrackets() {
check_parser(
"let foo = (a) => a;",
vec![LetDeclList::from(vec![LetDecl::new::<_, Option<Node>>(
Identifier::from("foo"),
Some(
ArrowFunctionDecl::new(
vec![FormalParameter::new("a", None, false)],
vec![Return::new::<Node, Option<_>, Option<_>>(
Some(Identifier::from("a").into()),
None,
)
.into()],
)
.into(),
),
)])
.into()],
);
}
#[test]
fn check_arrow_assignment_noparenthesis() {
check_parser(
"let foo = a => { return a };",
vec![LetDeclList::from(vec![LetDecl::new::<_, Option<Node>>(
Identifier::from("foo"),
Some(
ArrowFunctionDecl::new(
vec![FormalParameter::new("a", None, false)],
vec![Return::new::<Node, Option<_>, Option<_>>(
Some(Identifier::from("a").into()),
None,
)
.into()],
)
.into(),
),
)])
.into()],
);
}
#[test]
fn check_arrow_assignment_noparenthesis_nobrackets() {
check_parser(
"let foo = a => a;",
vec![LetDeclList::from(vec![LetDecl::new::<_, Option<Node>>(
Identifier::from("foo"),
Some(
ArrowFunctionDecl::new(
vec![FormalParameter::new("a", None, false)],
vec![Return::new::<Node, Option<_>, Option<_>>(
Some(Identifier::from("a").into()),
None,
)
.into()],
)
.into(),
),
)])
.into()],
);
}
#[test]
fn check_arrow_assignment_2arg() {
check_parser(
"let foo = (a, b) => { return a };",
vec![LetDeclList::from(vec![LetDecl::new::<_, Option<Node>>(
Identifier::from("foo"),
Some(
ArrowFunctionDecl::new(
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, false),
],
vec![Return::new::<Node, Option<_>, Option<_>>(
Some(Identifier::from("a").into()),
None,
)
.into()],
)
.into(),
),
)])
.into()],
);
}
#[test]
fn check_arrow_assignment_2arg_nobrackets() {
check_parser(
"let foo = (a, b) => a;",
vec![LetDeclList::from(vec![LetDecl::new::<_, Option<Node>>(
Identifier::from("foo"),
Some(
ArrowFunctionDecl::new(
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, false),
],
vec![Return::new::<Node, Option<_>, Option<_>>(
Some(Identifier::from("a").into()),
None,
)
.into()],
)
.into(),
),
)])
.into()],
);
}
#[test]
fn check_arrow_assignment_3arg() {
check_parser(
"let foo = (a, b, c) => { return a };",
vec![LetDeclList::from(vec![LetDecl::new::<_, Option<Node>>(
Identifier::from("foo"),
Some(
ArrowFunctionDecl::new(
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, false),
FormalParameter::new("c", None, false),
],
vec![Return::new::<Node, Option<_>, Option<_>>(
Some(Identifier::from("a").into()),
None,
)
.into()],
)
.into(),
),
)])
.into()],
);
}
#[test]
fn check_arrow_assignment_3arg_nobrackets() {
check_parser(
"let foo = (a, b, c) => a;",
vec![LetDeclList::from(vec![LetDecl::new::<_, Option<Node>>(
Identifier::from("foo"),
Some(
ArrowFunctionDecl::new(
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, false),
FormalParameter::new("c", None, false),
],
vec![Return::new::<Node, Option<_>, Option<_>>(
Some(Identifier::from("a").into()),
None,
)
.into()],
)
.into(),
),
)])
.into()],
);
}

Loading…
Cancel
Save