1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-20 13:25:08 +00:00

LibJS: Add FunctionExpression AST node

Most of the code is shared with FunctionDeclaration, so the shared bits
are moved up into a common base called FunctionNode.
This commit is contained in:
Andreas Kling 2020-03-19 11:12:08 +01:00
parent f0b49ae04b
commit b1b4c9844e
2 changed files with 59 additions and 15 deletions

View file

@ -43,10 +43,15 @@ Value ScopeNode::execute(Interpreter& interpreter) const
Value FunctionDeclaration::execute(Interpreter& interpreter) const Value FunctionDeclaration::execute(Interpreter& interpreter) const
{ {
auto* function = interpreter.heap().allocate<ScriptFunction>(body(), parameters()); auto* function = interpreter.heap().allocate<ScriptFunction>(body(), parameters());
interpreter.set_variable(m_name, function); interpreter.set_variable(name(), function);
return function; return function;
} }
Value FunctionExpression::execute(Interpreter& interpreter) const
{
return interpreter.heap().allocate<ScriptFunction>(body(), parameters());
}
Value ExpressionStatement::execute(Interpreter& interpreter) const Value ExpressionStatement::execute(Interpreter& interpreter) const
{ {
return m_expression->execute(interpreter); return m_expression->execute(interpreter);
@ -385,11 +390,11 @@ void NullLiteral::dump(int indent) const
printf("null\n"); printf("null\n");
} }
void FunctionDeclaration::dump(int indent) const void FunctionNode::dump(int indent, const char* class_name) const
{ {
bool first_time = true; bool first_time = true;
StringBuilder parameters_builder; StringBuilder parameters_builder;
for (const auto& parameter : m_parameters) { for (const auto& parameter : parameters()) {
if (first_time) if (first_time)
first_time = false; first_time = false;
else else
@ -399,10 +404,20 @@ void FunctionDeclaration::dump(int indent) const
} }
print_indent(indent); print_indent(indent);
printf("%s '%s(%s)'\n", class_name(), name().characters(), parameters_builder.build().characters()); printf("%s '%s(%s)'\n", class_name, name().characters(), parameters_builder.build().characters());
body().dump(indent + 1); body().dump(indent + 1);
} }
void FunctionDeclaration::dump(int indent) const
{
FunctionNode::dump(indent, class_name());
}
void FunctionExpression::dump(int indent) const
{
FunctionNode::dump(indent, class_name());
}
void ReturnStatement::dump(int indent) const void ReturnStatement::dump(int indent) const
{ {
ASTNode::dump(indent); ASTNode::dump(indent);

View file

@ -123,33 +123,62 @@ private:
virtual const char* class_name() const override { return "BlockStatement"; } virtual const char* class_name() const override { return "BlockStatement"; }
}; };
class FunctionDeclaration : public Statement { class Expression : public ASTNode {
public: public:
FunctionDeclaration(String name, NonnullRefPtr<ScopeNode> body, Vector<String> parameters = {}) virtual bool is_member_expression() const { return false; }
};
class FunctionNode {
public:
String name() const { return m_name; }
const ScopeNode& body() const { return *m_body; }
const Vector<String>& parameters() const { return m_parameters; };
protected:
FunctionNode(String name, NonnullRefPtr<ScopeNode> body, Vector<String> parameters = {})
: m_name(move(name)) : m_name(move(name))
, m_body(move(body)) , m_body(move(body))
, m_parameters(move(parameters)) , m_parameters(move(parameters))
{ {
} }
String name() const { return m_name; } void dump(int indent, const char* class_name) const;
const ScopeNode& body() const { return *m_body; }
const Vector<String>& parameters() const { return m_parameters; }; private:
String m_name;
NonnullRefPtr<ScopeNode> m_body;
const Vector<String> m_parameters;
};
class FunctionDeclaration final
: public Statement
, public FunctionNode {
public:
FunctionDeclaration(String name, NonnullRefPtr<ScopeNode> body, Vector<String> parameters = {})
: FunctionNode(move(name), move(body), move(parameters))
{
}
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 "FunctionDeclaration"; } virtual const char* class_name() const override { return "FunctionDeclaration"; }
String m_name;
NonnullRefPtr<ScopeNode> m_body;
const Vector<String> m_parameters;
}; };
class Expression : public ASTNode { class FunctionExpression final : public Expression
, public FunctionNode {
public: public:
virtual bool is_member_expression() const { return false; } FunctionExpression(String name, NonnullRefPtr<ScopeNode> body, Vector<String> parameters = {})
: FunctionNode(move(name), move(body), move(parameters))
{
}
virtual Value execute(Interpreter&) const override;
virtual void dump(int indent) const override;
private:
virtual const char* class_name() const override { return "FunctionExpression"; }
}; };
class ErrorExpression final : public Expression { class ErrorExpression final : public Expression {