Przeglądaj źródła

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.
Andreas Kling 5 lat temu
rodzic
commit
b1b4c9844e
2 zmienionych plików z 59 dodań i 15 usunięć
  1. 19 4
      Libraries/LibJS/AST.cpp
  2. 40 11
      Libraries/LibJS/AST.h

+ 19 - 4
Libraries/LibJS/AST.cpp

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

+ 40 - 11
Libraries/LibJS/AST.h

@@ -123,33 +123,62 @@ private:
     virtual const char* class_name() const override { return "BlockStatement"; }
 };
 
-class FunctionDeclaration : public Statement {
+class Expression : public ASTNode {
 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_body(move(body))
         , m_parameters(move(parameters))
     {
     }
 
-    String name() const { return m_name; }
-    const ScopeNode& body() const { return *m_body; }
-    const Vector<String>& parameters() const { return m_parameters; };
+    void dump(int indent, const char* class_name) const;
+
+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 void dump(int indent) const override;
 
 private:
     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:
-    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 {