mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:07:34 +00:00
LibJS: Implement update expressions
Note that currently only the non-prefixed variant is supported (i.e i++ not ++i), this variant returns the value of the argument before the update.
This commit is contained in:
parent
dc9a702aa8
commit
8557bc56f7
3 changed files with 69 additions and 1 deletions
|
@ -442,6 +442,25 @@ Value AssignmentExpression::execute(Interpreter& interpreter) const
|
||||||
return rhs_result;
|
return rhs_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value UpdateExpression::execute(Interpreter& interpreter) const
|
||||||
|
{
|
||||||
|
ASSERT(m_argument->is_identifier());
|
||||||
|
auto name = static_cast<const Identifier&>(*m_argument).string();
|
||||||
|
|
||||||
|
auto previous_value = interpreter.get_variable(name);
|
||||||
|
ASSERT(previous_value.is_number());
|
||||||
|
|
||||||
|
switch (m_op) {
|
||||||
|
case UpdateOp::Increment:
|
||||||
|
interpreter.set_variable(name, Value(previous_value.as_double() + 1));
|
||||||
|
break;
|
||||||
|
case UpdateOp::Decrement:
|
||||||
|
interpreter.set_variable(name, Value(previous_value.as_double() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return previous_value;
|
||||||
|
}
|
||||||
|
|
||||||
void AssignmentExpression::dump(int indent) const
|
void AssignmentExpression::dump(int indent) const
|
||||||
{
|
{
|
||||||
const char* op_string = nullptr;
|
const char* op_string = nullptr;
|
||||||
|
@ -470,6 +489,24 @@ void AssignmentExpression::dump(int indent) const
|
||||||
m_rhs->dump(indent + 1);
|
m_rhs->dump(indent + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateExpression::dump(int indent) const
|
||||||
|
{
|
||||||
|
const char* op_string = nullptr;
|
||||||
|
switch (m_op) {
|
||||||
|
case UpdateOp::Increment:
|
||||||
|
op_string = "++";
|
||||||
|
break;
|
||||||
|
case UpdateOp::Decrement:
|
||||||
|
op_string = "--";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode::dump(indent);
|
||||||
|
print_indent(indent + 1);
|
||||||
|
printf("%s\n", op_string);
|
||||||
|
m_argument->dump(indent + 1);
|
||||||
|
}
|
||||||
|
|
||||||
Value VariableDeclaration::execute(Interpreter& interpreter) const
|
Value VariableDeclaration::execute(Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
interpreter.declare_variable(name().string(), m_declaration_type);
|
interpreter.declare_variable(name().string(), m_declaration_type);
|
||||||
|
|
|
@ -444,6 +444,29 @@ private:
|
||||||
NonnullOwnPtr<Expression> m_rhs;
|
NonnullOwnPtr<Expression> m_rhs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class UpdateOp {
|
||||||
|
Increment,
|
||||||
|
Decrement,
|
||||||
|
};
|
||||||
|
|
||||||
|
class UpdateExpression : public Expression {
|
||||||
|
public:
|
||||||
|
UpdateExpression(UpdateOp op, NonnullOwnPtr<Expression> argument)
|
||||||
|
: m_op(op)
|
||||||
|
, m_argument(move(argument))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Value execute(Interpreter&) const override;
|
||||||
|
virtual void dump(int indent) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual const char* class_name() const override { return "UpdateExpression"; }
|
||||||
|
|
||||||
|
UpdateOp m_op;
|
||||||
|
NonnullOwnPtr<Identifier> m_argument;
|
||||||
|
};
|
||||||
|
|
||||||
enum class DeclarationType {
|
enum class DeclarationType {
|
||||||
Var,
|
Var,
|
||||||
Let,
|
Let,
|
||||||
|
|
|
@ -174,6 +174,12 @@ NonnullOwnPtr<Expression> Parser::parse_secondary_expression(NonnullOwnPtr<Expre
|
||||||
case TokenType::Period:
|
case TokenType::Period:
|
||||||
consume();
|
consume();
|
||||||
return make<MemberExpression>(move(lhs), parse_expression());
|
return make<MemberExpression>(move(lhs), parse_expression());
|
||||||
|
case TokenType::PlusPlus:
|
||||||
|
consume();
|
||||||
|
return make<UpdateExpression>(UpdateOp::Increment, move(lhs));
|
||||||
|
case TokenType::MinusMinus:
|
||||||
|
consume();
|
||||||
|
return make<UpdateExpression>(UpdateOp::Decrement, move(lhs));
|
||||||
default:
|
default:
|
||||||
m_has_errors = true;
|
m_has_errors = true;
|
||||||
expected("secondary expression (missing switch case)");
|
expected("secondary expression (missing switch case)");
|
||||||
|
@ -352,7 +358,9 @@ bool Parser::match_secondary_expression() const
|
||||||
|| type == TokenType::LessThan
|
|| type == TokenType::LessThan
|
||||||
|| type == TokenType::LessThanEquals
|
|| type == TokenType::LessThanEquals
|
||||||
|| type == TokenType::ParenOpen
|
|| type == TokenType::ParenOpen
|
||||||
|| type == TokenType::Period;
|
|| type == TokenType::Period
|
||||||
|
|| type == TokenType::PlusPlus
|
||||||
|
|| type == TokenType::MinusMinus;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::match_statement() const
|
bool Parser::match_statement() const
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue