From b800276347a8785737862d42f17c676198e1c785 Mon Sep 17 00:00:00 2001 From: Dan Klishch Date: Sat, 20 Jan 2024 21:41:38 -0500 Subject: [PATCH] JSSpecCompiler: Parse true, false, this, undefined, and null --- .../CodeGenerators/JSSpecCompiler/AST/AST.h | 5 +++++ .../JSSpecCompiler/AST/ASTPrinting.cpp | 5 +++++ .../JSSpecCompiler/Parser/Lexer.cpp | 4 ++-- .../JSSpecCompiler/Parser/TextParser.cpp | 18 +++++++++++++++++ .../JSSpecCompiler/Parser/Token.h | 2 +- .../JSSpecCompiler/Tests/spec-parsing.xml | 20 +++++++++++++++++++ .../Tests/spec-parsing.xml.expectation | 19 ++++++++++++++++++ 7 files changed, 70 insertions(+), 3 deletions(-) diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h index 93d9f79fb1..817eb17432 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h @@ -134,6 +134,11 @@ protected: class WellKnownNode : public Expression { public: enum Type { + False, + Null, + This, + True, + Undefined, ZeroArgumentFunctionCall, // Update WellKnownNode::dump_tree after adding an entry here }; diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp index ec5f4108a2..da8c71bb02 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp @@ -38,6 +38,11 @@ void ErrorNode::dump_tree(StringBuilder& builder) void WellKnownNode::dump_tree(StringBuilder& builder) { static constexpr StringView type_to_name[] = { + "False"sv, + "Null"sv, + "This"sv, + "True"sv, + "Undefined"sv, "ZeroArgumentFunctionCall"sv, }; dump_node(builder, "WellKnownNode {}", type_to_name[m_type]); diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/Lexer.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/Lexer.cpp index cd1e8f186b..0025705fee 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/Lexer.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/Lexer.cpp @@ -158,8 +158,8 @@ void tokenize_tree(SpecificationParsingContext& ctx, TokenizerState& state, XML: if (contents.length() >= 2 && contents.starts_with('"') && contents.ends_with('"')) tokens.append({ TokenType::String, contents.substring_view(1, contents.length() - 2), move(child_location) }); - else if (contents == "undefined") - tokens.append({ TokenType::Undefined, contents, move(child_location) }); + else if (contents.is_one_of("undefined", "null", "this", "true", "false")) + tokens.append({ TokenType::WellKnownValue, contents, move(child_location) }); else tokens.append({ TokenType::Identifier, contents, move(child_location) }); return; diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp index 173d1322de..8a607d5559 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp @@ -298,6 +298,24 @@ TextParseErrorOr TextParser::parse_expression() NullableTree expression; if (token.type == TokenType::Identifier) { expression = make_ref_counted(token.data); + } else if (token.type == TokenType::WellKnownValue) { + static constexpr struct { + StringView name; + WellKnownNode::Type type; + } translations[] = { + { "false"sv, WellKnownNode::Type::False }, + { "null"sv, WellKnownNode::Type::Null }, + { "this"sv, WellKnownNode::Type::This }, + { "true"sv, WellKnownNode::Type::True }, + { "undefined"sv, WellKnownNode::Type::Undefined }, + }; + for (auto [name, type] : translations) { + if (token.data == name) { + expression = make_ref_counted(type); + break; + } + } + VERIFY(expression); } else if (token.type == TokenType::Number) { expression = make_ref_counted(MUST(Crypto::BigFraction::from_string(token.data))); } else if (token.type == TokenType::String) { diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/Token.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/Token.h index 066cbcc19b..fb2aa2a34d 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/Token.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/Token.h @@ -48,7 +48,7 @@ constexpr i32 closing_bracket_precedence = 18; F(String, -1, Invalid, Invalid, Invalid, "string literal") \ F(Superscript, 4, Invalid, Power, Invalid, "subscript") \ F(UnaryMinus, 3, Minus, Invalid, Invalid, "unary minus") \ - F(Undefined, -1, Invalid, Invalid, Invalid, "constant") \ + F(WellKnownValue, -1, Invalid, Invalid, Invalid, "constant") \ F(Word, -1, Invalid, Invalid, Invalid, "word") enum class TokenType { diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-parsing.xml b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-parsing.xml index 6a75ee8bf7..2c8c1d7c0c 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-parsing.xml +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-parsing.xml @@ -13,4 +13,24 @@ + +

2 WellKnownConstants ( a )

+ +
    +
  1. + If a is undefined, then +
      +
    1. Let b be null.
    2. +
    3. Return true.
    4. +
    +
  2. +
  3. Else, +
      +
    1. Let c be this.
    2. +
    3. Return false.
    4. +
    +
  4. +
+
+
diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-parsing.xml.expectation b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-parsing.xml.expectation index cba8728620..f85856a9cd 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-parsing.xml.expectation +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-parsing.xml.expectation @@ -27,3 +27,22 @@ TreeList Var d Var e +WellKnownConstants(a): +TreeList + IfElseIfChain + IsOneOf + Var a + WellKnownNode Undefined + TreeList + BinaryOperation Assignment + Var b + WellKnownNode Null + ReturnNode + WellKnownNode True + TreeList + BinaryOperation Assignment + Var c + WellKnownNode This + ReturnNode + WellKnownNode False +