瀏覽代碼

LibJS: Handle HTML-style comments

Stephan Unverwerth 5 年之前
父節點
當前提交
9477efe970
共有 3 個文件被更改,包括 63 次插入16 次删除
  1. 40 16
      Libraries/LibJS/Lexer.cpp
  2. 3 0
      Libraries/LibJS/Lexer.h
  3. 20 0
      Libraries/LibJS/Tests/comments-basic.js

+ 40 - 16
Libraries/LibJS/Lexer.cpp

@@ -167,6 +167,36 @@ void Lexer::consume_exponent()
     }
 }
 
+bool Lexer::match(char a, char b) const
+{
+    if (m_position >= m_source.length())
+        return false;
+
+    return m_current_char == a
+        && m_source[m_position] == b;
+}
+
+bool Lexer::match(char a, char b, char c) const
+{
+    if (m_position + 1 >= m_source.length())
+        return false;
+
+    return m_current_char == a
+        && m_source[m_position] == b
+        && m_source[m_position + 1] == c;
+}
+
+bool Lexer::match(char a, char b, char c, char d) const
+{
+    if (m_position + 2 >= m_source.length())
+        return false;
+
+    return m_current_char == a
+        && m_source[m_position] == b
+        && m_source[m_position + 1] == c
+        && m_source[m_position + 2] == d;
+}
+
 bool Lexer::is_eof() const
 {
     return m_current_char == EOF;
@@ -184,17 +214,17 @@ bool Lexer::is_identifier_middle() const
 
 bool Lexer::is_line_comment_start() const
 {
-    return m_current_char == '/' && m_position < m_source.length() && m_source[m_position] == '/';
+    return match('/', '/') || match('<', '!', '-', '-') || match('-', '-', '>');
 }
 
 bool Lexer::is_block_comment_start() const
 {
-    return m_current_char == '/' && m_position < m_source.length() && m_source[m_position] == '*';
+    return match('/', '*');
 }
 
 bool Lexer::is_block_comment_end() const
 {
-    return m_current_char == '*' && m_position < m_source.length() && m_source[m_position] == '/';
+    return match('*', '/');
 }
 
 bool Lexer::is_numeric_literal_start() const
@@ -328,19 +358,13 @@ Token Lexer::next()
     } else {
         // There is only one four-char operator: >>>=
         bool found_four_char_token = false;
-        if (m_position + 2 < m_source.length()) {
-            if (m_current_char == '>'
-                && m_source[m_position] == '>'
-                && m_source[m_position + 1] == '>'
-                && m_source[m_position + 2] == '=') {
-
-                found_four_char_token = true;
-                consume();
-                consume();
-                consume();
-                consume();
-                token_type = TokenType::UnsignedShiftRightEquals;
-            }
+        if (match('>', '>', '>', '=')) {
+            found_four_char_token = true;
+            consume();
+            consume();
+            consume();
+            consume();
+            token_type = TokenType::UnsignedShiftRightEquals;
         }
 
         bool found_three_char_token = false;

+ 3 - 0
Libraries/LibJS/Lexer.h

@@ -56,6 +56,9 @@ private:
     bool is_block_comment_start() const;
     bool is_block_comment_end() const;
     bool is_numeric_literal_start() const;
+    bool match(char, char) const;
+    bool match(char, char, char) const;
+    bool match(char, char, char, char) const;
 
     void syntax_error(const char*);
 

+ 20 - 0
Libraries/LibJS/Tests/comments-basic.js

@@ -0,0 +1,20 @@
+try {
+    var i = 0;
+
+    // i++;
+    /* i++; */
+    /*
+    i++;
+    */
+    <!-- i++; --> i++;
+    <!-- i++;
+    i++;
+    --> i++;
+
+    assert(i === 1);
+
+    console.log('PASS');
+} catch (e) {
+    console.log('FAIL: ' + e);
+}
+