Skip to content

Commit

Permalink
Lexer reserved keyword identifier strict mode lexing
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Lancaster committed Sep 26, 2020
1 parent b3389b7 commit 0108b80
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 13 deletions.
14 changes: 12 additions & 2 deletions boa/src/syntax/lexer/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ use std::io::Read;
pub(super) struct SingleLineComment;

impl<R> Tokenizer<R> for SingleLineComment {
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand Down Expand Up @@ -58,7 +63,12 @@ impl<R> Tokenizer<R> for SingleLineComment {
pub(super) struct MultiLineComment;

impl<R> Tokenizer<R> for MultiLineComment {
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand Down
31 changes: 30 additions & 1 deletion boa/src/syntax/lexer/identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ use crate::{
};
use std::io::Read;

const STRICT_FORBIDDEN_IDENTIFIERS: [&str; 11] = [
"eval",
"arguments",
"implements",
"interface",
"let",
"package",
"private",
"protected",
"public",
"static",
"yield",
];

/// Identifier lexing.
///
/// More information:
Expand All @@ -31,7 +45,12 @@ impl Identifier {
}

impl<R> Tokenizer<R> for Identifier {
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand All @@ -51,6 +70,16 @@ impl<R> Tokenizer<R> for Identifier {
if let Ok(keyword) = slice.parse() {
TokenKind::Keyword(keyword)
} else {
if strict_mode && STRICT_FORBIDDEN_IDENTIFIERS.contains(&slice) {
return Err(Error::Syntax(
format!(
"using future reserved keyword '{}' not allowed in strict mode",
slice
)
.into(),
start_pos,
));
}
TokenKind::identifier(slice)
}
}
Expand Down
13 changes: 11 additions & 2 deletions boa/src/syntax/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ pub use token::{Token, TokenKind};

trait Tokenizer<R> {
/// Lexes the next token.
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read;
}
Expand Down Expand Up @@ -109,7 +114,11 @@ impl<R> Lexer<R> {
// that means it could be multiple different tokens depending on the input token.
//
// As per https://tc39.es/ecma262/#sec-ecmascript-language-lexical-grammar
pub(crate) fn lex_slash_token(&mut self, start: Position, strict_mode: bool) -> Result<Token, Error>
pub(crate) fn lex_slash_token(
&mut self,
start: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand Down
9 changes: 7 additions & 2 deletions boa/src/syntax/lexer/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::{io::Read, str::FromStr};
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type
#[derive(Debug, Clone, Copy)]
pub(super) struct NumberLiteral {
init: char
init: char,
}

impl NumberLiteral {
Expand Down Expand Up @@ -134,7 +134,12 @@ where
}

impl<R> Tokenizer<R> for NumberLiteral {
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand Down
7 changes: 6 additions & 1 deletion boa/src/syntax/lexer/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,12 @@ impl Operator {
}

impl<R> Tokenizer<R> for Operator {
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand Down
7 changes: 6 additions & 1 deletion boa/src/syntax/lexer/regex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub(super) struct RegexLiteral;

impl<R> Tokenizer<R> for RegexLiteral {
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand Down
7 changes: 6 additions & 1 deletion boa/src/syntax/lexer/spread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ impl SpreadLiteral {
}

impl<R> Tokenizer<R> for SpreadLiteral {
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand Down
7 changes: 6 additions & 1 deletion boa/src/syntax/lexer/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ enum StringTerminator {
}

impl<R> Tokenizer<R> for StringLiteral {
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand Down
7 changes: 6 additions & 1 deletion boa/src/syntax/lexer/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ use std::io::{self, ErrorKind, Read};
pub(super) struct TemplateLiteral;

impl<R> Tokenizer<R> for TemplateLiteral {
fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position, strict_mode: bool) -> Result<Token, Error>
fn lex(
&mut self,
cursor: &mut Cursor<R>,
start_pos: Position,
strict_mode: bool,
) -> Result<Token, Error>
where
R: Read,
{
Expand Down
4 changes: 3 additions & 1 deletion boa/src/syntax/parser/cursor/buffered_lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ where
self.set_goal(InputElement::RegExp);

let strict_mode: bool = false; // TODO enable setting strict mode on/off.
self.lexer.lex_slash_token(start, strict_mode).map_err(|e| e.into())
self.lexer
.lex_slash_token(start, strict_mode)
.map_err(|e| e.into())
}

/// Fills the peeking buffer with the next token.
Expand Down

0 comments on commit 0108b80

Please sign in to comment.