Selaa lähdekoodia

JSSpecCompiler: Allow storing `NullableTree`s in nodes

And use this in ElseIfBranch node.
Dan Klishch 1 vuosi sitten
vanhempi
commit
092ed1cc8a

+ 25 - 2
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.cpp

@@ -8,6 +8,29 @@
 
 namespace JSSpecCompiler {
 
+Tree NodeSubtreePointer::get(Badge<RecursiveASTVisitor>)
+{
+    return m_tree_ptr.visit(
+        [&](NullableTree* nullable_tree) -> Tree {
+            NullableTree copy = *nullable_tree;
+            return copy.release_nonnull();
+        },
+        [&](Tree* tree) -> Tree {
+            return *tree;
+        });
+}
+
+void NodeSubtreePointer::replace_subtree(Badge<RecursiveASTVisitor>, NullableTree replacement)
+{
+    m_tree_ptr.visit(
+        [&](NullableTree* nullable_tree) {
+            *nullable_tree = replacement;
+        },
+        [&](Tree* tree) {
+            *tree = replacement.release_nonnull();
+        });
+}
+
 Vector<NodeSubtreePointer> BinaryOperation::subtrees()
 {
     return { { &m_left }, { &m_right } };
@@ -43,8 +66,8 @@ Vector<NodeSubtreePointer> IfBranch::subtrees()
 
 Vector<NodeSubtreePointer> ElseIfBranch::subtrees()
 {
-    if (m_condition.has_value())
-        return { { &m_condition.value() }, { &m_branch } };
+    if (m_condition)
+        return { { &m_condition }, { &m_branch } };
     return { { &m_branch } };
 }
 

+ 9 - 5
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h

@@ -28,12 +28,16 @@ public:
     {
     }
 
-    Tree& get(Badge<RecursiveASTVisitor>) { return *m_tree_ptr; }
+    NodeSubtreePointer(NullableTree* tree_ptr)
+        : m_tree_ptr(tree_ptr)
+    {
+    }
 
-    void replace_subtree(Badge<RecursiveASTVisitor>, Tree tree) { *m_tree_ptr = move(tree); }
+    Tree get(Badge<RecursiveASTVisitor>);
+    void replace_subtree(Badge<RecursiveASTVisitor>, NullableTree replacement);
 
 private:
-    Tree* m_tree_ptr;
+    Variant<Tree*, NullableTree*> m_tree_ptr;
 };
 
 // ===== Generic nodes =====
@@ -258,7 +262,7 @@ protected:
 
 class ElseIfBranch : public Node {
 public:
-    ElseIfBranch(Optional<Tree> condition, Tree branch)
+    ElseIfBranch(NullableTree condition, Tree branch)
         : m_condition(condition)
         , m_branch(branch)
     {
@@ -266,7 +270,7 @@ public:
 
     Vector<NodeSubtreePointer> subtrees() override;
 
-    Optional<Tree> m_condition;
+    NullableTree m_condition;
     Tree m_branch;
 
 protected:

+ 3 - 3
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp

@@ -91,9 +91,9 @@ void IfBranch::dump_tree(StringBuilder& builder)
 
 void ElseIfBranch::dump_tree(StringBuilder& builder)
 {
-    dump_node(builder, "ElseIfBranch {}", m_condition.has_value() ? "ElseIf" : "Else");
-    if (m_condition.has_value())
-        (*m_condition)->format_tree(builder);
+    dump_node(builder, "ElseIfBranch {}", m_condition ? "ElseIf" : "Else");
+    if (m_condition)
+        m_condition->format_tree(builder);
     m_branch->format_tree(builder);
 }
 

+ 12 - 1
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/GenericASTPass.cpp

@@ -10,13 +10,24 @@
 
 namespace JSSpecCompiler {
 
+void RecursiveASTVisitor::run_in_const_subtree(NullableTree nullable_tree)
+{
+    if (nullable_tree) {
+        auto tree = nullable_tree.release_nonnull();
+        auto tree_copy = tree;
+        NodeSubtreePointer pointer { &tree };
+        recurse(tree, pointer);
+        VERIFY(tree == tree_copy);
+    }
+}
+
 void RecursiveASTVisitor::run_in_subtree(Tree& tree)
 {
     NodeSubtreePointer pointer { &tree };
     recurse(tree, pointer);
 }
 
-void RecursiveASTVisitor::replace_current_node_with(Tree tree)
+void RecursiveASTVisitor::replace_current_node_with(NullableTree tree)
 {
     m_current_subtree_pointer->replace_subtree({}, move(tree));
 }

+ 2 - 1
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/GenericASTPass.h

@@ -17,13 +17,14 @@ class RecursiveASTVisitor {
 public:
     virtual ~RecursiveASTVisitor() = default;
 
+    void run_in_const_subtree(NullableTree tree);
     void run_in_subtree(Tree& tree);
 
 protected:
     virtual RecursionDecision on_entry(Tree) { return RecursionDecision::Recurse; }
     virtual void on_leave(Tree) { }
 
-    void replace_current_node_with(Tree tree);
+    void replace_current_node_with(NullableTree tree);
 
 private:
     RecursionDecision recurse(Tree root, NodeSubtreePointer& pointer);

+ 4 - 5
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp

@@ -382,7 +382,7 @@ ParseErrorOr<TextParser::IfConditionParseResult> TextParser::parse_if_beginning(
     auto rollback = rollback_point();
 
     bool is_if_branch = !consume_word("if"sv).is_error();
-    Optional<Tree> condition;
+    NullableTree condition = nullptr;
     if (is_if_branch) {
         condition = TRY(parse_condition());
     } else {
@@ -406,9 +406,8 @@ ParseErrorOr<Tree> TextParser::parse_inline_if_else()
 
     rollback.disarm();
     if (is_if_branch)
-        return make_ref_counted<IfBranch>(*condition, then_branch);
-    else
-        return make_ref_counted<ElseIfBranch>(condition, then_branch);
+        return make_ref_counted<IfBranch>(condition.release_nonnull(), then_branch);
+    return make_ref_counted<ElseIfBranch>(condition, then_branch);
 }
 
 // <if> :== <if_condition> then$ <substeps>
@@ -437,7 +436,7 @@ ParseErrorOr<Tree> TextParser::parse_else(Tree else_branch)
     TRY(expect_eof());
 
     rollback.disarm();
-    return make_ref_counted<ElseIfBranch>(Optional<Tree> {}, else_branch);
+    return make_ref_counted<ElseIfBranch>(nullptr, else_branch);
 }
 
 // <simple_step> | <inline_if>

+ 1 - 1
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.h

@@ -33,7 +33,7 @@ public:
 private:
     struct IfConditionParseResult {
         bool is_if_branch;
-        Optional<Tree> condition;
+        NullableTree condition;
     };
 
     void retreat();