mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:27:42 +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:
parent
55c845713a
commit
7c48c3c8e1
4 changed files with 26 additions and 7 deletions
|
@ -91,8 +91,11 @@ Value IfStatement::execute(Interpreter& interpreter) const
|
||||||
|
|
||||||
if (predicate_result.to_boolean())
|
if (predicate_result.to_boolean())
|
||||||
return interpreter.run(*m_consequent);
|
return interpreter.run(*m_consequent);
|
||||||
else
|
|
||||||
|
if (m_alternate)
|
||||||
return interpreter.run(*m_alternate);
|
return interpreter.run(*m_alternate);
|
||||||
|
|
||||||
|
return js_undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
Value WhileStatement::execute(Interpreter& interpreter) const
|
Value WhileStatement::execute(Interpreter& interpreter) const
|
||||||
|
@ -427,9 +430,11 @@ void IfStatement::dump(int indent) const
|
||||||
printf("If\n");
|
printf("If\n");
|
||||||
predicate().dump(indent + 1);
|
predicate().dump(indent + 1);
|
||||||
consequent().dump(indent + 1);
|
consequent().dump(indent + 1);
|
||||||
print_indent(indent);
|
if (alternate()) {
|
||||||
printf("Else\n");
|
print_indent(indent);
|
||||||
alternate().dump(indent + 1);
|
printf("Else\n");
|
||||||
|
alternate()->dump(indent + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WhileStatement::dump(int indent) const
|
void WhileStatement::dump(int indent) const
|
||||||
|
|
|
@ -211,7 +211,7 @@ private:
|
||||||
|
|
||||||
class IfStatement : public Statement {
|
class IfStatement : public Statement {
|
||||||
public:
|
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_predicate(move(predicate))
|
||||||
, m_consequent(move(consequent))
|
, m_consequent(move(consequent))
|
||||||
, m_alternate(move(alternate))
|
, m_alternate(move(alternate))
|
||||||
|
@ -220,7 +220,7 @@ public:
|
||||||
|
|
||||||
const Expression& predicate() const { return *m_predicate; }
|
const Expression& predicate() const { return *m_predicate; }
|
||||||
const ScopeNode& consequent() const { return *m_consequent; }
|
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 Value execute(Interpreter&) const override;
|
||||||
virtual void dump(int indent) const override;
|
virtual void dump(int indent) const override;
|
||||||
|
@ -230,7 +230,7 @@ private:
|
||||||
|
|
||||||
NonnullRefPtr<Expression> m_predicate;
|
NonnullRefPtr<Expression> m_predicate;
|
||||||
NonnullRefPtr<ScopeNode> m_consequent;
|
NonnullRefPtr<ScopeNode> m_consequent;
|
||||||
NonnullRefPtr<ScopeNode> m_alternate;
|
RefPtr<ScopeNode> m_alternate;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WhileStatement : public Statement {
|
class WhileStatement : public Statement {
|
||||||
|
|
|
@ -194,6 +194,8 @@ NonnullRefPtr<Statement> Parser::parse_statement()
|
||||||
return parse_variable_declaration();
|
return parse_variable_declaration();
|
||||||
case TokenType::For:
|
case TokenType::For:
|
||||||
return parse_for_statement();
|
return parse_for_statement();
|
||||||
|
case TokenType::If:
|
||||||
|
return parse_if_statement();
|
||||||
default:
|
default:
|
||||||
if (match_expression())
|
if (match_expression())
|
||||||
return adopt(*new ExpressionStatement(parse_expression(0)));
|
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);
|
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()
|
NonnullRefPtr<ForStatement> Parser::parse_for_statement()
|
||||||
{
|
{
|
||||||
consume(TokenType::For);
|
consume(TokenType::For);
|
||||||
|
|
|
@ -51,6 +51,7 @@ public:
|
||||||
NonnullRefPtr<ReturnStatement> parse_return_statement();
|
NonnullRefPtr<ReturnStatement> parse_return_statement();
|
||||||
NonnullRefPtr<VariableDeclaration> parse_variable_declaration();
|
NonnullRefPtr<VariableDeclaration> parse_variable_declaration();
|
||||||
NonnullRefPtr<ForStatement> parse_for_statement();
|
NonnullRefPtr<ForStatement> parse_for_statement();
|
||||||
|
NonnullRefPtr<IfStatement> parse_if_statement();
|
||||||
|
|
||||||
NonnullRefPtr<Expression> parse_expression(int min_precedence, Associativity associate = Associativity::Right);
|
NonnullRefPtr<Expression> parse_expression(int min_precedence, Associativity associate = Associativity::Right);
|
||||||
NonnullRefPtr<Expression> parse_primary_expression();
|
NonnullRefPtr<Expression> parse_primary_expression();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue