LibJS: Parse "this" as ThisExpression

This commit is contained in:
Stephan Unverwerth 2020-04-13 00:42:14 +02:00 committed by Andreas Kling
parent 110ca6b0b6
commit f8f65053bd
Notes: sideshowbarker 2024-07-19 07:39:59 +09:00
6 changed files with 37 additions and 17 deletions

View file

@ -662,6 +662,16 @@ void Identifier::dump(int indent) const
printf("Identifier \"%s\"\n", m_string.characters());
}
Value ThisExpression::execute(Interpreter& interpreter) const
{
return interpreter.this_value();
}
void ThisExpression::dump(int indent) const
{
ASTNode::dump(indent);
}
Value AssignmentExpression::execute(Interpreter& interpreter) const
{
auto rhs_result = m_rhs->execute(interpreter);

View file

@ -502,6 +502,15 @@ private:
FlyString m_string;
};
class ThisExpression final : public Expression {
public:
virtual Value execute(Interpreter&) const override;
virtual void dump(int indent) const override;
private:
virtual const char* class_name() const override { return "ThisExpression"; }
};
class CallExpression : public Expression {
public:
CallExpression(NonnullRefPtr<Expression> callee, NonnullRefPtrVector<Expression> arguments = {})

View file

@ -158,10 +158,6 @@ void Interpreter::set_variable(const FlyString& name, Value value, bool first_as
Optional<Value> Interpreter::get_variable(const FlyString& name)
{
static FlyString this_name = "this";
if (name == this_name)
return this_value();
for (ssize_t i = m_scope_stack.size() - 1; i >= 0; --i) {
auto& scope = m_scope_stack.at(i);
auto value = scope.variables.get(name);

View file

@ -66,6 +66,7 @@ Lexer::Lexer(StringView source)
s_keywords.set("null", TokenType::NullLiteral);
s_keywords.set("return", TokenType::Return);
s_keywords.set("switch", TokenType::Switch);
s_keywords.set("this", TokenType::This);
s_keywords.set("throw", TokenType::Throw);
s_keywords.set("true", TokenType::BoolLiteral);
s_keywords.set("try", TokenType::Try);

View file

@ -317,6 +317,9 @@ NonnullRefPtr<Expression> Parser::parse_primary_expression()
consume(TokenType::ParenClose);
return expression;
}
case TokenType::This:
consume();
return create_ast_node<ThisExpression>();
case TokenType::Identifier: {
auto arrow_function_result = try_parse_arrow_function_expression(false);
if (!arrow_function_result.is_null()) {
@ -400,14 +403,13 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
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());
current_token.name(),
current_token.line_number(),
current_token.line_column());
consume();
continue;
}
if (match(TokenType::Colon)) {
consume(TokenType::Colon);
properties.set(property_name, parse_expression(0));
@ -487,7 +489,7 @@ NonnullRefPtr<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expre
case TokenType::Percent:
consume();
return create_ast_node<BinaryExpression>(BinaryOp::Modulo, move(lhs), parse_expression(min_precedence, associativity));
case TokenType::DoubleAsterisk:
case TokenType::DoubleAsterisk:
consume();
return create_ast_node<BinaryExpression>(BinaryOp::Exponentiation, move(lhs), parse_expression(min_precedence, associativity));
case TokenType::GreaterThan:
@ -905,6 +907,7 @@ bool Parser::match_expression() const
|| type == TokenType::BracketOpen
|| type == TokenType::ParenOpen
|| type == TokenType::Function
|| type == TokenType::This
|| match_unary_prefixed_expression();
}
@ -997,10 +1000,10 @@ Token Parser::consume(TokenType type)
m_parser_state.m_has_errors = true;
auto& current_token = m_parser_state.m_current_token;
fprintf(stderr, "Error: Unexpected token %s. Expected %s (line: %zu, column: %zu))\n",
current_token.name(),
Token::name(type),
current_token.line_number(),
current_token.line_column());
current_token.name(),
Token::name(type),
current_token.line_number(),
current_token.line_column());
}
return consume();
}
@ -1010,10 +1013,10 @@ void Parser::expected(const char* what)
m_parser_state.m_has_errors = true;
auto& current_token = m_parser_state.m_current_token;
fprintf(stderr, "Error: Unexpected token %s. Expected %s (line: %zu, column: %zu)\n",
current_token.name(),
what,
current_token.line_number(),
current_token.line_column());
current_token.name(),
what,
current_token.line_number(),
current_token.line_column());
}
void Parser::save_state()

View file

@ -111,6 +111,7 @@ namespace JS {
__ENUMERATE_JS_TOKEN(SlashEquals) \
__ENUMERATE_JS_TOKEN(StringLiteral) \
__ENUMERATE_JS_TOKEN(Switch) \
__ENUMERATE_JS_TOKEN(This) \
__ENUMERATE_JS_TOKEN(Throw) \
__ENUMERATE_JS_TOKEN(Tilde) \
__ENUMERATE_JS_TOKEN(Try) \