Explorar o código

LibJS: Allow parsing numeric and string literals in object expressions

Also updated the object-basic.js test to include this change
DexesTTP %!s(int64=5) %!d(string=hai) anos
pai
achega
e586dc285a
Modificáronse 2 ficheiros con 32 adicións e 5 borrados
  1. 20 3
      Libraries/LibJS/Parser.cpp
  2. 12 2
      Libraries/LibJS/Tests/object-basic.js

+ 20 - 3
Libraries/LibJS/Parser.cpp

@@ -389,13 +389,30 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
     consume(TokenType::CurlyOpen);
 
     while (!match(TokenType::CurlyClose)) {
-        auto identifier = create_ast_node<Identifier>(consume(TokenType::Identifier).value());
+        FlyString property_name;
+        if (match(TokenType::Identifier)) {
+            property_name = consume(TokenType::Identifier).value();
+        } else if (match(TokenType::StringLiteral)) {
+            property_name = consume(TokenType::StringLiteral).string_value();
+        } else if (match(TokenType::NumericLiteral)) {
+            property_name = consume(TokenType::NumericLiteral).value();
+        } else {
+            m_parser_state.m_has_errors = true;
+            auto& current_token = m_parser_state.m_current_token;
+            fprintf(stderr, "Error: Unexpected token %s as member in object initialization. Expected a numeric literal, string literal or identifier (line: %zu, column: %zu))\n",
+                    current_token.name(),
+                    current_token.line_number(),
+                    current_token.line_column());
+            consume();
+            continue;
+        }
+
 
         if (match(TokenType::Colon)) {
             consume(TokenType::Colon);
-            properties.set(identifier->string(), parse_expression(0));
+            properties.set(property_name, parse_expression(0));
         } else {
-            properties.set(identifier->string(), identifier);
+            properties.set(property_name, create_ast_node<Identifier>(property_name));
         }
 
         if (!match(TokenType::Comma))

+ 12 - 2
Libraries/LibJS/Tests/object-basic.js

@@ -1,7 +1,11 @@
 try {
-    var o = { foo: "bar" };
+    var o = { 1: 23, foo: "bar", "hello": "friends" };
+    assert(o[1] === 23);
+    assert(o["1"] === 23);
     assert(o.foo === "bar");
     assert(o["foo"] === "bar");
+    assert(o.hello === "friends");
+    assert(o["hello"] === "friends");
     o.baz = "test";
     assert(o.baz === "test");
     assert(o["baz"] === "test");
@@ -11,7 +15,13 @@ try {
     o[-1] = "hello friends";
     assert(o[-1] === "hello friends");
     assert(o["-1"] === "hello friends");
+
+    var math = { 3.14: "pi" };
+    assert(math["3.14"] === "pi");
+    // Note : this test doesn't pass yet due to floating-point literals being coerced to i32 on access
+    // assert(math[3.14] === "pi");
+
     console.log("PASS");
 } catch (e) {
     console.log("FAIL: " + e);
-}
+}