mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 14:35:07 +00:00
LibJS: Parse object expressions
This commit is contained in:
parent
c64b5e73f5
commit
bc002f807a
7 changed files with 48 additions and 4 deletions
7
Base/home/anon/js/object-expression.js
Normal file
7
Base/home/anon/js/object-expression.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
const a = 1;
|
||||||
|
const object = {a, b: 2};
|
||||||
|
const emptyObject = {};
|
||||||
|
|
||||||
|
console.log(object.a);
|
||||||
|
console.log(object.b);
|
||||||
|
console.log(emptyObject.foo);
|
|
@ -623,6 +623,11 @@ void VariableDeclaration::dump(int indent) const
|
||||||
void ObjectExpression::dump(int indent) const
|
void ObjectExpression::dump(int indent) const
|
||||||
{
|
{
|
||||||
ASTNode::dump(indent);
|
ASTNode::dump(indent);
|
||||||
|
for (String property_key : m_properties.keys()) {
|
||||||
|
print_indent(indent + 1);
|
||||||
|
printf("%s: ", property_key.characters());
|
||||||
|
m_properties.get(property_key).value()->dump(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionStatement::dump(int indent) const
|
void ExpressionStatement::dump(int indent) const
|
||||||
|
@ -633,7 +638,12 @@ void ExpressionStatement::dump(int indent) const
|
||||||
|
|
||||||
Value ObjectExpression::execute(Interpreter& interpreter) const
|
Value ObjectExpression::execute(Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
return interpreter.heap().allocate<Object>();
|
auto object = interpreter.heap().allocate<Object>();
|
||||||
|
for (String property_key : m_properties.keys()) {
|
||||||
|
object->put(property_key, m_properties.get(property_key).value()->execute(interpreter));
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemberExpression::dump(int indent) const
|
void MemberExpression::dump(int indent) const
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/HashMap.h>
|
||||||
#include <AK/NonnullRefPtrVector.h>
|
#include <AK/NonnullRefPtrVector.h>
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
@ -572,13 +573,18 @@ private:
|
||||||
|
|
||||||
class ObjectExpression : public Expression {
|
class ObjectExpression : public Expression {
|
||||||
public:
|
public:
|
||||||
ObjectExpression() {}
|
ObjectExpression(HashMap<String, NonnullRefPtr<Expression>> properties = {})
|
||||||
|
: m_properties(properties)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value execute(Interpreter&) const override;
|
virtual Value execute(Interpreter&) const override;
|
||||||
virtual void dump(int indent) const override;
|
virtual void dump(int indent) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual const char* class_name() const override { return "ObjectExpression"; }
|
virtual const char* class_name() const override { return "ObjectExpression"; }
|
||||||
|
|
||||||
|
HashMap<String, NonnullRefPtr<Expression>> m_properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArrayExpression : public Expression {
|
class ArrayExpression : public Expression {
|
||||||
|
|
|
@ -107,6 +107,7 @@ Lexer::Lexer(StringView source)
|
||||||
s_single_char_tokens.set('[', TokenType::BracketOpen);
|
s_single_char_tokens.set('[', TokenType::BracketOpen);
|
||||||
s_single_char_tokens.set(']', TokenType::BracketClose);
|
s_single_char_tokens.set(']', TokenType::BracketClose);
|
||||||
s_single_char_tokens.set('^', TokenType::Caret);
|
s_single_char_tokens.set('^', TokenType::Caret);
|
||||||
|
s_single_char_tokens.set(':', TokenType::Colon);
|
||||||
s_single_char_tokens.set(',', TokenType::Comma);
|
s_single_char_tokens.set(',', TokenType::Comma);
|
||||||
s_single_char_tokens.set('{', TokenType::CurlyOpen);
|
s_single_char_tokens.set('{', TokenType::CurlyOpen);
|
||||||
s_single_char_tokens.set('}', TokenType::CurlyClose);
|
s_single_char_tokens.set('}', TokenType::CurlyClose);
|
||||||
|
|
|
@ -269,10 +269,27 @@ NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
|
||||||
|
|
||||||
NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||||
{
|
{
|
||||||
// FIXME: Parse actual object expression
|
HashMap<String, NonnullRefPtr<Expression>> properties;
|
||||||
consume(TokenType::CurlyOpen);
|
consume(TokenType::CurlyOpen);
|
||||||
|
|
||||||
|
while (!match(TokenType::CurlyClose)) {
|
||||||
|
auto identifier = create_ast_node<Identifier>(consume(TokenType::Identifier).value());
|
||||||
|
|
||||||
|
if (match(TokenType::Colon)) {
|
||||||
|
consume(TokenType::Colon);
|
||||||
|
properties.set(identifier->string(), parse_expression(0));
|
||||||
|
} else {
|
||||||
|
properties.set(identifier->string(), identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match(TokenType::Comma))
|
||||||
|
break;
|
||||||
|
|
||||||
|
consume(TokenType::Comma);
|
||||||
|
}
|
||||||
|
|
||||||
consume(TokenType::CurlyClose);
|
consume(TokenType::CurlyClose);
|
||||||
return create_ast_node<ObjectExpression>();
|
return create_ast_node<ObjectExpression>(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<ArrayExpression> Parser::parse_array_expression()
|
NonnullRefPtr<ArrayExpression> Parser::parse_array_expression()
|
||||||
|
|
|
@ -57,6 +57,8 @@ const char* Token::name(TokenType type)
|
||||||
return "Catch";
|
return "Catch";
|
||||||
case TokenType::Class:
|
case TokenType::Class:
|
||||||
return "Class";
|
return "Class";
|
||||||
|
case TokenType::Colon:
|
||||||
|
return "Colon";
|
||||||
case TokenType::Comma:
|
case TokenType::Comma:
|
||||||
return "Comma";
|
return "Comma";
|
||||||
case TokenType::Const:
|
case TokenType::Const:
|
||||||
|
|
|
@ -44,6 +44,7 @@ enum class TokenType {
|
||||||
Caret,
|
Caret,
|
||||||
Catch,
|
Catch,
|
||||||
Class,
|
Class,
|
||||||
|
Colon,
|
||||||
Comma,
|
Comma,
|
||||||
Const,
|
Const,
|
||||||
CurlyClose,
|
CurlyClose,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue