浏览代码

LibJS: Implement null and undefined literals

0xtechnobabble 5 年之前
父节点
当前提交
cfd710eb31
共有 6 个文件被更改,包括 61 次插入0 次删除
  1. 22 0
      Libraries/LibJS/AST.cpp
  2. 28 0
      Libraries/LibJS/AST.h
  3. 1 0
      Libraries/LibJS/Lexer.cpp
  4. 7 0
      Libraries/LibJS/Parser.cpp
  5. 2 0
      Libraries/LibJS/Token.cpp
  6. 1 0
      Libraries/LibJS/Token.h

+ 22 - 0
Libraries/LibJS/AST.cpp

@@ -349,6 +349,18 @@ void BooleanLiteral::dump(int indent) const
     printf("BooleanLiteral %s\n", m_value ? "true" : "false");
     printf("BooleanLiteral %s\n", m_value ? "true" : "false");
 }
 }
 
 
+void UndefinedLiteral::dump(int indent) const
+{
+    print_indent(indent);
+    printf("undefined\n");
+}
+
+void NullLiteral::dump(int indent) const
+{
+    print_indent(indent);
+    printf("null\n");
+}
+
 void FunctionDeclaration::dump(int indent) const
 void FunctionDeclaration::dump(int indent) const
 {
 {
     bool first_time = true;
     bool first_time = true;
@@ -617,4 +629,14 @@ Value BooleanLiteral::execute(Interpreter&) const
     return Value(m_value);
     return Value(m_value);
 }
 }
 
 
+Value UndefinedLiteral::execute(Interpreter&) const
+{
+    return js_undefined();
+}
+
+Value NullLiteral::execute(Interpreter&) const
+{
+    return js_null();
+}
+
 }
 }

+ 28 - 0
Libraries/LibJS/AST.h

@@ -380,6 +380,34 @@ private:
     String m_value;
     String m_value;
 };
 };
 
 
+class NullLiteral final : public Literal {
+public:
+    explicit NullLiteral()
+    {
+    }
+
+    virtual Value execute(Interpreter&) const override;
+    virtual void dump(int indent) const override;
+
+private:
+    virtual const char* class_name() const override { return "NullLiteral"; }
+
+    String m_value;
+};
+
+class UndefinedLiteral final : public Literal {
+public:
+    explicit UndefinedLiteral()
+    {
+    }
+
+    virtual Value execute(Interpreter&) const override;
+    virtual void dump(int indent) const override;
+
+private:
+    virtual const char* class_name() const override { return "UndefinedLiteral"; }
+};
+
 class Identifier final : public Expression {
 class Identifier final : public Expression {
 public:
 public:
     explicit Identifier(String string)
     explicit Identifier(String string)

+ 1 - 0
Libraries/LibJS/Lexer.cpp

@@ -60,6 +60,7 @@ Lexer::Lexer(StringView source)
         s_keywords.set("let", TokenType::Let);
         s_keywords.set("let", TokenType::Let);
         s_keywords.set("new", TokenType::New);
         s_keywords.set("new", TokenType::New);
         s_keywords.set("null", TokenType::NullLiteral);
         s_keywords.set("null", TokenType::NullLiteral);
+        s_keywords.set("undefined", TokenType::UndefinedLiteral);
         s_keywords.set("return", TokenType::Return);
         s_keywords.set("return", TokenType::Return);
         s_keywords.set("true", TokenType::BoolLiteral);
         s_keywords.set("true", TokenType::BoolLiteral);
         s_keywords.set("try", TokenType::Try);
         s_keywords.set("try", TokenType::Try);

+ 7 - 0
Libraries/LibJS/Parser.cpp

@@ -223,6 +223,12 @@ NonnullOwnPtr<Expression> Parser::parse_primary_expression()
         return make<BooleanLiteral>(consume().bool_value());
         return make<BooleanLiteral>(consume().bool_value());
     case TokenType::StringLiteral:
     case TokenType::StringLiteral:
         return make<StringLiteral>(consume().string_value());
         return make<StringLiteral>(consume().string_value());
+    case TokenType::NullLiteral:
+        consume();
+        return make<NullLiteral>();
+    case TokenType::UndefinedLiteral:
+        consume();
+        return make<UndefinedLiteral>();
     case TokenType::CurlyOpen:
     case TokenType::CurlyOpen:
         return parse_object_expression();
         return parse_object_expression();
     default:
     default:
@@ -498,6 +504,7 @@ bool Parser::match_expression() const
     return type == TokenType::BoolLiteral
     return type == TokenType::BoolLiteral
         || type == TokenType::NumericLiteral
         || type == TokenType::NumericLiteral
         || type == TokenType::StringLiteral
         || type == TokenType::StringLiteral
+        || type == TokenType::UndefinedLiteral
         || type == TokenType::NullLiteral
         || type == TokenType::NullLiteral
         || type == TokenType::Identifier
         || type == TokenType::Identifier
         || type == TokenType::New
         || type == TokenType::New

+ 2 - 0
Libraries/LibJS/Token.cpp

@@ -183,6 +183,8 @@ const char* Token::name(TokenType type)
         return "Try";
         return "Try";
     case TokenType::Typeof:
     case TokenType::Typeof:
         return "Typeof";
         return "Typeof";
+    case TokenType::UndefinedLiteral:
+        return "UndefinedLiteral";
     case TokenType::UnsignedShiftRight:
     case TokenType::UnsignedShiftRight:
         return "UnsignedShiftRight";
         return "UnsignedShiftRight";
     case TokenType::UnsignedShiftRightEquals:
     case TokenType::UnsignedShiftRightEquals:

+ 1 - 0
Libraries/LibJS/Token.h

@@ -107,6 +107,7 @@ enum class TokenType {
     Tilde,
     Tilde,
     Try,
     Try,
     Typeof,
     Typeof,
+    UndefinedLiteral,
     UnsignedShiftRight,
     UnsignedShiftRight,
     UnsignedShiftRightEquals,
     UnsignedShiftRightEquals,
     UnterminatedStringLiteral,
     UnterminatedStringLiteral,