mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:32:44 +00:00 
			
		
		
		
	JSSpecCompiler: Allow storing NullableTrees in nodes
				
					
				
			And use this in ElseIfBranch node.
This commit is contained in:
		
							parent
							
								
									4eede5282c
								
							
						
					
					
						commit
						092ed1cc8a
					
				
					 7 changed files with 56 additions and 18 deletions
				
			
		|  | @ -8,6 +8,29 @@ | ||||||
| 
 | 
 | ||||||
| namespace JSSpecCompiler { | 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() | Vector<NodeSubtreePointer> BinaryOperation::subtrees() | ||||||
| { | { | ||||||
|     return { { &m_left }, { &m_right } }; |     return { { &m_left }, { &m_right } }; | ||||||
|  | @ -43,8 +66,8 @@ Vector<NodeSubtreePointer> IfBranch::subtrees() | ||||||
| 
 | 
 | ||||||
| Vector<NodeSubtreePointer> ElseIfBranch::subtrees() | Vector<NodeSubtreePointer> ElseIfBranch::subtrees() | ||||||
| { | { | ||||||
|     if (m_condition.has_value()) |     if (m_condition) | ||||||
|         return { { &m_condition.value() }, { &m_branch } }; |         return { { &m_condition }, { &m_branch } }; | ||||||
|     return { { &m_branch } }; |     return { { &m_branch } }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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: | private: | ||||||
|     Tree* m_tree_ptr; |     Variant<Tree*, NullableTree*> m_tree_ptr; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // ===== Generic nodes =====
 | // ===== Generic nodes =====
 | ||||||
|  | @ -258,7 +262,7 @@ protected: | ||||||
| 
 | 
 | ||||||
| class ElseIfBranch : public Node { | class ElseIfBranch : public Node { | ||||||
| public: | public: | ||||||
|     ElseIfBranch(Optional<Tree> condition, Tree branch) |     ElseIfBranch(NullableTree condition, Tree branch) | ||||||
|         : m_condition(condition) |         : m_condition(condition) | ||||||
|         , m_branch(branch) |         , m_branch(branch) | ||||||
|     { |     { | ||||||
|  | @ -266,7 +270,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     Vector<NodeSubtreePointer> subtrees() override; |     Vector<NodeSubtreePointer> subtrees() override; | ||||||
| 
 | 
 | ||||||
|     Optional<Tree> m_condition; |     NullableTree m_condition; | ||||||
|     Tree m_branch; |     Tree m_branch; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -91,9 +91,9 @@ void IfBranch::dump_tree(StringBuilder& builder) | ||||||
| 
 | 
 | ||||||
| void ElseIfBranch::dump_tree(StringBuilder& builder) | void ElseIfBranch::dump_tree(StringBuilder& builder) | ||||||
| { | { | ||||||
|     dump_node(builder, "ElseIfBranch {}", m_condition.has_value() ? "ElseIf" : "Else"); |     dump_node(builder, "ElseIfBranch {}", m_condition ? "ElseIf" : "Else"); | ||||||
|     if (m_condition.has_value()) |     if (m_condition) | ||||||
|         (*m_condition)->format_tree(builder); |         m_condition->format_tree(builder); | ||||||
|     m_branch->format_tree(builder); |     m_branch->format_tree(builder); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,13 +10,24 @@ | ||||||
| 
 | 
 | ||||||
| namespace JSSpecCompiler { | 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) | void RecursiveASTVisitor::run_in_subtree(Tree& tree) | ||||||
| { | { | ||||||
|     NodeSubtreePointer pointer { &tree }; |     NodeSubtreePointer pointer { &tree }; | ||||||
|     recurse(tree, pointer); |     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)); |     m_current_subtree_pointer->replace_subtree({}, move(tree)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,13 +17,14 @@ class RecursiveASTVisitor { | ||||||
| public: | public: | ||||||
|     virtual ~RecursiveASTVisitor() = default; |     virtual ~RecursiveASTVisitor() = default; | ||||||
| 
 | 
 | ||||||
|  |     void run_in_const_subtree(NullableTree tree); | ||||||
|     void run_in_subtree(Tree& tree); |     void run_in_subtree(Tree& tree); | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|     virtual RecursionDecision on_entry(Tree) { return RecursionDecision::Recurse; } |     virtual RecursionDecision on_entry(Tree) { return RecursionDecision::Recurse; } | ||||||
|     virtual void on_leave(Tree) { } |     virtual void on_leave(Tree) { } | ||||||
| 
 | 
 | ||||||
|     void replace_current_node_with(Tree tree); |     void replace_current_node_with(NullableTree tree); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     RecursionDecision recurse(Tree root, NodeSubtreePointer& pointer); |     RecursionDecision recurse(Tree root, NodeSubtreePointer& pointer); | ||||||
|  |  | ||||||
|  | @ -382,7 +382,7 @@ ParseErrorOr<TextParser::IfConditionParseResult> TextParser::parse_if_beginning( | ||||||
|     auto rollback = rollback_point(); |     auto rollback = rollback_point(); | ||||||
| 
 | 
 | ||||||
|     bool is_if_branch = !consume_word("if"sv).is_error(); |     bool is_if_branch = !consume_word("if"sv).is_error(); | ||||||
|     Optional<Tree> condition; |     NullableTree condition = nullptr; | ||||||
|     if (is_if_branch) { |     if (is_if_branch) { | ||||||
|         condition = TRY(parse_condition()); |         condition = TRY(parse_condition()); | ||||||
|     } else { |     } else { | ||||||
|  | @ -406,9 +406,8 @@ ParseErrorOr<Tree> TextParser::parse_inline_if_else() | ||||||
| 
 | 
 | ||||||
|     rollback.disarm(); |     rollback.disarm(); | ||||||
|     if (is_if_branch) |     if (is_if_branch) | ||||||
|         return make_ref_counted<IfBranch>(*condition, then_branch); |         return make_ref_counted<IfBranch>(condition.release_nonnull(), then_branch); | ||||||
|     else |     return make_ref_counted<ElseIfBranch>(condition, then_branch); | ||||||
|         return make_ref_counted<ElseIfBranch>(condition, then_branch); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // <if> :== <if_condition> then$ <substeps>
 | // <if> :== <if_condition> then$ <substeps>
 | ||||||
|  | @ -437,7 +436,7 @@ ParseErrorOr<Tree> TextParser::parse_else(Tree else_branch) | ||||||
|     TRY(expect_eof()); |     TRY(expect_eof()); | ||||||
| 
 | 
 | ||||||
|     rollback.disarm(); |     rollback.disarm(); | ||||||
|     return make_ref_counted<ElseIfBranch>(Optional<Tree> {}, else_branch); |     return make_ref_counted<ElseIfBranch>(nullptr, else_branch); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // <simple_step> | <inline_if>
 | // <simple_step> | <inline_if>
 | ||||||
|  |  | ||||||
|  | @ -33,7 +33,7 @@ public: | ||||||
| private: | private: | ||||||
|     struct IfConditionParseResult { |     struct IfConditionParseResult { | ||||||
|         bool is_if_branch; |         bool is_if_branch; | ||||||
|         Optional<Tree> condition; |         NullableTree condition; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     void retreat(); |     void retreat(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Klishch
						Dan Klishch