1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 23:17:44 +00:00

LibJS: Parse "if" statements

This patch implements basic parsing of "if" statements. We don't yet
support parsing "else", so I added a FIXME about that.
This commit is contained in:
Andreas Kling 2020-03-21 18:40:17 +01:00
parent 55c845713a
commit 7c48c3c8e1
4 changed files with 26 additions and 7 deletions

View file

@ -91,8 +91,11 @@ Value IfStatement::execute(Interpreter& interpreter) const
if (predicate_result.to_boolean())
return interpreter.run(*m_consequent);
else
if (m_alternate)
return interpreter.run(*m_alternate);
return js_undefined();
}
Value WhileStatement::execute(Interpreter& interpreter) const
@ -427,9 +430,11 @@ void IfStatement::dump(int indent) const
printf("If\n");
predicate().dump(indent + 1);
consequent().dump(indent + 1);
if (alternate()) {
print_indent(indent);
printf("Else\n");
alternate().dump(indent + 1);
alternate()->dump(indent + 1);
}
}
void WhileStatement::dump(int indent) const

View file

@ -211,7 +211,7 @@ private:
class IfStatement : public Statement {
public:
IfStatement(NonnullRefPtr<Expression> predicate, NonnullRefPtr<ScopeNode> consequent, NonnullRefPtr<ScopeNode> alternate)
IfStatement(NonnullRefPtr<Expression> predicate, NonnullRefPtr<ScopeNode> consequent, RefPtr<ScopeNode> alternate)
: m_predicate(move(predicate))
, m_consequent(move(consequent))
, m_alternate(move(alternate))
@ -220,7 +220,7 @@ public:
const Expression& predicate() const { return *m_predicate; }
const ScopeNode& consequent() const { return *m_consequent; }
const ScopeNode& alternate() const { return *m_alternate; }
const ScopeNode* alternate() const { return m_alternate; }
virtual Value execute(Interpreter&) const override;
virtual void dump(int indent) const override;
@ -230,7 +230,7 @@ private:
NonnullRefPtr<Expression> m_predicate;
NonnullRefPtr<ScopeNode> m_consequent;
NonnullRefPtr<ScopeNode> m_alternate;
RefPtr<ScopeNode> m_alternate;
};
class WhileStatement : public Statement {

View file

@ -194,6 +194,8 @@ NonnullRefPtr<Statement> Parser::parse_statement()
return parse_variable_declaration();
case TokenType::For:
return parse_for_statement();
case TokenType::If:
return parse_if_statement();
default:
if (match_expression())
return adopt(*new ExpressionStatement(parse_expression(0)));
@ -512,6 +514,17 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration()
return create_ast_node<VariableDeclaration>(create_ast_node<Identifier>(name), move(initializer), declaration_type);
}
NonnullRefPtr<IfStatement> Parser::parse_if_statement()
{
consume(TokenType::If);
consume(TokenType::ParenOpen);
auto predicate = parse_expression(0);
consume(TokenType::ParenClose);
auto consequent = parse_block_statement();
// FIXME: Parse "else"
return create_ast_node<IfStatement>(move(predicate), move(consequent), nullptr);
}
NonnullRefPtr<ForStatement> Parser::parse_for_statement()
{
consume(TokenType::For);

View file

@ -51,6 +51,7 @@ public:
NonnullRefPtr<ReturnStatement> parse_return_statement();
NonnullRefPtr<VariableDeclaration> parse_variable_declaration();
NonnullRefPtr<ForStatement> parse_for_statement();
NonnullRefPtr<IfStatement> parse_if_statement();
NonnullRefPtr<Expression> parse_expression(int min_precedence, Associativity associate = Associativity::Right);
NonnullRefPtr<Expression> parse_primary_expression();