Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strict Mode Lex/Parse #717

Merged
merged 22 commits into from
Oct 5, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move strict_mode flag onto Lexer
  • Loading branch information
Paul Lancaster committed Oct 4, 2020
commit 736aa599b6f37998245b250dda297c3415bb2cf3
12 changes: 12 additions & 0 deletions boa/src/syntax/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ trait Tokenizer<R> {
pub struct Lexer<R> {
cursor: Cursor<R>,
goal_symbol: InputElement,
strict_mode: bool,
}

impl<R> Lexer<R> {
Expand Down Expand Up @@ -95,6 +96,16 @@ impl<R> Lexer<R> {
self.goal_symbol
}

#[inline]
pub(super) fn strict_mode(&self) -> bool {
self.strict_mode
}

#[inline]
pub(super) fn set_strict_mode(&mut self, strict_mode: bool) {
self.strict_mode = strict_mode
}

/// Creates a new lexer.
#[inline]
pub fn new(reader: R) -> Self
Expand All @@ -104,6 +115,7 @@ impl<R> Lexer<R> {
Self {
cursor: Cursor::new(reader),
goal_symbol: Default::default(),
strict_mode: false, // Strict mode off by default.
}
}

Expand Down
10 changes: 10 additions & 0 deletions boa/src/syntax/parser/cursor/buffered_lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ where
.map_err(|e| e.into())
}

#[inline]
pub(super) fn strict_mode(&self) -> bool {
self.lexer.strict_mode()
}

#[inline]
pub(super) fn set_strict_mode(&mut self, strict_mode: bool) {
self.lexer.set_strict_mode(strict_mode)
}

/// Fills the peeking buffer with the next token.
///
/// It will not fill two line terminators one after the other.
Expand Down
10 changes: 10 additions & 0 deletions boa/src/syntax/parser/cursor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ where
self.buffered_lexer.peek(skip_n, true)
}

#[inline]
pub(super) fn strict_mode(&self) -> bool {
self.buffered_lexer.strict_mode()
}

#[inline]
pub(super) fn set_strict_mode(&mut self, strict_mode: bool) {
self.buffered_lexer.set_strict_mode(strict_mode)
}

/// Returns an error if the next token is not of kind `kind`.
///
/// Note: it will consume the next token only if the next token is the expected type.
Expand Down
19 changes: 9 additions & 10 deletions boa/src/syntax/parser/expression/assignment/arrow_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,29 +68,28 @@ where
{
type Output = ArrowFunctionDecl;

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

let next_token = cursor.peek(0)?.ok_or(ParseError::AbruptEnd)?;
let params = if let TokenKind::Punctuator(Punctuator::OpenParen) = &next_token.kind() {
// CoverParenthesizedExpressionAndArrowParameterList
cursor.expect(Punctuator::OpenParen, "arrow function")?;

let params = FormalParameters::new(self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?;
let params = FormalParameters::new(self.allow_yield, self.allow_await).parse(cursor)?;
cursor.expect(Punctuator::CloseParen, "arrow function")?;
params
} else {
let param = BindingIdentifier::new(self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)
.parse(cursor)
.context("arrow function")?;
Box::new([FormalParameter::new(param, None, false)])
};

cursor.peek_expect_no_lineterminator(0)?;

cursor.expect(TokenKind::Punctuator(Punctuator::Arrow), "arrow function")?;
let body = ConciseBody::new(self.allow_in).parse(cursor, strict_mode)?;
let body = ConciseBody::new(self.allow_in).parse(cursor)?;
Ok(ArrowFunctionDecl::new(params, body))
}
}
Expand Down Expand Up @@ -119,16 +118,16 @@ where
{
type Output = StatementList;

fn parse(self, cursor: &mut Cursor<R>, strict_mode: bool) -> Result<Self::Output, ParseError> {
fn parse(self, cursor: &mut Cursor<R>) -> Result<Self::Output, ParseError> {
match cursor.peek(0)?.ok_or(ParseError::AbruptEnd)?.kind() {
TokenKind::Punctuator(Punctuator::OpenBlock) => {
let _ = cursor.next();
let body = FunctionBody::new(false, false).parse(cursor, strict_mode)?;
let body = FunctionBody::new(false, false).parse(cursor)?;
cursor.expect(Punctuator::CloseBlock, "arrow function")?;
Ok(body)
}
_ => Ok(StatementList::from(vec![Return::new(
ExpressionBody::new(self.allow_in, false).parse(cursor, strict_mode)?,
ExpressionBody::new(self.allow_in, false).parse(cursor)?,
None,
)
.into()])),
Expand Down Expand Up @@ -163,7 +162,7 @@ where
{
type Output = Node;

fn parse(self, cursor: &mut Cursor<R>, strict_mode: bool) -> ParseResult {
AssignmentExpression::new(self.allow_in, false, self.allow_await).parse(cursor, strict_mode)
fn parse(self, cursor: &mut Cursor<R>) -> ParseResult {
AssignmentExpression::new(self.allow_in, false, self.allow_await).parse(cursor)
}
}
8 changes: 4 additions & 4 deletions boa/src/syntax/parser/expression/assignment/conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,24 @@ where
{
type Output = Node;

fn parse(self, cursor: &mut Cursor<R>, strict_mode: bool) -> ParseResult {
fn parse(self, cursor: &mut Cursor<R>) -> ParseResult {
let _timer = BoaProfiler::global().start_event("ConditionalExpression", "Parsing");

// TODO: coalesce expression
let lhs = LogicalORExpression::new(self.allow_in, self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?;
.parse(cursor)?;

if let Some(tok) = cursor.peek(0)? {
if tok.kind() == &TokenKind::Punctuator(Punctuator::Question) {
cursor.next()?.expect("? character vanished"); // Consume the token.
let then_clause =
AssignmentExpression::new(self.allow_in, self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?;
.parse(cursor)?;
cursor.expect(Punctuator::Colon, "conditional expression")?;

let else_clause =
AssignmentExpression::new(self.allow_in, self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?;
.parse(cursor)?;
return Ok(ConditionalOp::new(lhs, then_clause, else_clause).into());
}
}
Expand Down
10 changes: 4 additions & 6 deletions boa/src/syntax/parser/expression/assignment/exponentiation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,18 @@ where
{
type Output = Node;

fn parse(self, cursor: &mut Cursor<R>, strict_mode: bool) -> ParseResult {
fn parse(self, cursor: &mut Cursor<R>) -> ParseResult {
let _timer = BoaProfiler::global().start_event("ExponentiationExpression", "Parsing");

if is_unary_expression(cursor)? {
return UnaryExpression::new(self.allow_yield, self.allow_await)
.parse(cursor, strict_mode);
return UnaryExpression::new(self.allow_yield, self.allow_await).parse(cursor);
}

let lhs =
UpdateExpression::new(self.allow_yield, self.allow_await).parse(cursor, strict_mode)?;
let lhs = UpdateExpression::new(self.allow_yield, self.allow_await).parse(cursor)?;
if let Some(tok) = cursor.peek(0)? {
if let TokenKind::Punctuator(Punctuator::Exp) = tok.kind() {
cursor.next()?.expect("** token vanished"); // Consume the token.
return Ok(BinOp::new(NumOp::Exp, lhs, self.parse(cursor, strict_mode)?).into());
return Ok(BinOp::new(NumOp::Exp, lhs, self.parse(cursor)?).into());
}
}
Ok(lhs)
Expand Down
18 changes: 9 additions & 9 deletions boa/src/syntax/parser/expression/assignment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ where
{
type Output = Node;

fn parse(self, cursor: &mut Cursor<R>, strict_mode: bool) -> ParseResult {
fn parse(self, cursor: &mut Cursor<R>) -> ParseResult {
let _timer = BoaProfiler::global().start_event("AssignmentExpression", "Parsing");
cursor.set_goal(InputElement::Div);

Expand All @@ -95,7 +95,7 @@ where
self.allow_yield,
self.allow_await,
)
.parse(cursor, strict_mode)
.parse(cursor)
.map(Node::ArrowFunctionDecl);
}
}
Expand All @@ -115,7 +115,7 @@ where
self.allow_yield,
self.allow_await,
)
.parse(cursor, strict_mode)
.parse(cursor)
.map(Node::ArrowFunctionDecl);
}
}
Expand All @@ -126,7 +126,7 @@ where
self.allow_yield,
self.allow_await,
)
.parse(cursor, strict_mode)
.parse(cursor)
.map(Node::ArrowFunctionDecl);
}
TokenKind::Identifier(_) => {
Expand All @@ -139,7 +139,7 @@ where
self.allow_yield,
self.allow_await,
)
.parse(cursor, strict_mode)
.parse(cursor)
.map(Node::ArrowFunctionDecl);
}
TokenKind::Punctuator(Punctuator::CloseParen) => {
Expand All @@ -153,7 +153,7 @@ where
self.allow_yield,
self.allow_await,
)
.parse(cursor, strict_mode)
.parse(cursor)
.map(Node::ArrowFunctionDecl);
}
}
Expand All @@ -173,7 +173,7 @@ where
cursor.set_goal(InputElement::Div);

let mut lhs = ConditionalExpression::new(self.allow_in, self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?;
.parse(cursor)?;

// Review if we are trying to assign to an invalid left hand side expression.
// TODO: can we avoid cloning?
Expand All @@ -182,7 +182,7 @@ where
TokenKind::Punctuator(Punctuator::Assign) => {
cursor.next()?.expect("= token vanished"); // Consume the token.
if is_assignable(&lhs) {
lhs = Assign::new(lhs, self.parse(cursor, strict_mode)?).into();
lhs = Assign::new(lhs, self.parse(cursor)?).into();
} else {
return Err(ParseError::lex(LexError::Syntax(
"Invalid left-hand side in assignment".into(),
Expand All @@ -194,7 +194,7 @@ where
cursor.next()?.expect("token vanished"); // Consume the token.
if is_assignable(&lhs) {
let binop = p.as_binop().expect("binop disappeared");
let expr = self.parse(cursor, strict_mode)?;
let expr = self.parse(cursor)?;

lhs = BinOp::new(binop, lhs, expr).into();
} else {
Expand Down
6 changes: 3 additions & 3 deletions boa/src/syntax/parser/expression/left_hand_side/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ where
{
type Output = Box<[Node]>;

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

cursor.expect(Punctuator::OpenParen, "arguments")?;
Expand Down Expand Up @@ -98,15 +98,15 @@ where
args.push(
Spread::new(
AssignmentExpression::new(true, self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?,
.parse(cursor)?,
)
.into(),
);
} else {
cursor.set_goal(InputElement::RegExp);
args.push(
AssignmentExpression::new(true, self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?,
.parse(cursor)?,
);
}
}
Expand Down
12 changes: 5 additions & 7 deletions boa/src/syntax/parser/expression/left_hand_side/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,13 @@ where
{
type Output = Node;

fn parse(self, cursor: &mut Cursor<R>, strict_mode: bool) -> ParseResult {
fn parse(self, cursor: &mut Cursor<R>) -> ParseResult {
let _timer = BoaProfiler::global().start_event("CallExpression", "Parsing");

let token = cursor.peek(0)?.ok_or(ParseError::AbruptEnd)?;

let mut lhs = if token.kind() == &TokenKind::Punctuator(Punctuator::OpenParen) {
let args =
Arguments::new(self.allow_yield, self.allow_await).parse(cursor, strict_mode)?;
let args = Arguments::new(self.allow_yield, self.allow_await).parse(cursor)?;
Node::from(Call::new(self.first_member_expr, args))
} else {
let next_token = cursor.next()?.expect("token vanished");
Expand All @@ -84,8 +83,7 @@ where
let token = tok.clone();
match token.kind() {
TokenKind::Punctuator(Punctuator::OpenParen) => {
let args = Arguments::new(self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?;
let args = Arguments::new(self.allow_yield, self.allow_await).parse(cursor)?;
lhs = Node::from(Call::new(lhs, args));
}
TokenKind::Punctuator(Punctuator::Dot) => {
Expand All @@ -109,8 +107,8 @@ where
}
TokenKind::Punctuator(Punctuator::OpenBracket) => {
let _ = cursor.next()?.ok_or(ParseError::AbruptEnd)?; // We move the parser.
let idx = Expression::new(true, self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?;
let idx =
Expression::new(true, self.allow_yield, self.allow_await).parse(cursor)?;
cursor.expect(Punctuator::CloseBracket, "call expression")?;
lhs = GetField::new(lhs, idx).into();
}
Expand Down
13 changes: 6 additions & 7 deletions boa/src/syntax/parser/expression/left_hand_side/member.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,20 @@ where
{
type Output = Node;

fn parse(self, cursor: &mut Cursor<R>, strict_mode: bool) -> ParseResult {
fn parse(self, cursor: &mut Cursor<R>) -> ParseResult {
let _timer = BoaProfiler::global().start_event("MemberExpression", "Parsing");

let mut lhs = if cursor.peek(0)?.ok_or(ParseError::AbruptEnd)?.kind()
== &TokenKind::Keyword(Keyword::New)
{
let _ = cursor.next().expect("new keyword disappeared");
let lhs = self.parse(cursor, strict_mode)?;
let args =
Arguments::new(self.allow_yield, self.allow_await).parse(cursor, strict_mode)?;
let lhs = self.parse(cursor)?;
let args = Arguments::new(self.allow_yield, self.allow_await).parse(cursor)?;
let call_node = Call::new(lhs, args);

Node::from(New::from(call_node))
} else {
PrimaryExpression::new(self.allow_yield, self.allow_await).parse(cursor, strict_mode)?
PrimaryExpression::new(self.allow_yield, self.allow_await).parse(cursor)?
};
while let Some(tok) = cursor.peek(0)? {
match tok.kind() {
Expand Down Expand Up @@ -101,8 +100,8 @@ where
cursor
.next()?
.expect("open bracket punctuator token disappeared"); // We move the parser forward.
let idx = Expression::new(true, self.allow_yield, self.allow_await)
.parse(cursor, strict_mode)?;
let idx =
Expression::new(true, self.allow_yield, self.allow_await).parse(cursor)?;
cursor.expect(Punctuator::CloseBracket, "member expression")?;
lhs = GetField::new(lhs, idx).into();
}
Expand Down
8 changes: 3 additions & 5 deletions boa/src/syntax/parser/expression/left_hand_side/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,16 @@ where
{
type Output = Node;

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

cursor.set_goal(InputElement::TemplateTail);

// TODO: Implement NewExpression: new MemberExpression
let lhs =
MemberExpression::new(self.allow_yield, self.allow_await).parse(cursor, strict_mode)?;
let lhs = MemberExpression::new(self.allow_yield, self.allow_await).parse(cursor)?;
if let Some(tok) = cursor.peek(0)? {
if tok.kind() == &TokenKind::Punctuator(Punctuator::OpenParen) {
return CallExpression::new(self.allow_yield, self.allow_await, lhs)
.parse(cursor, strict_mode);
return CallExpression::new(self.allow_yield, self.allow_await, lhs).parse(cursor);
}
}
Ok(lhs)
Expand Down
Loading