mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:12:43 +00:00 
			
		
		
		
	JSSpecCompiler: Move passes to Passes subdirectory of Compiler/
This commit is contained in:
		
							parent
							
								
									61fa00d46c
								
							
						
					
					
						commit
						867ce0df52
					
				
					 8 changed files with 9 additions and 9 deletions
				
			
		|  | @ -0,0 +1,97 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #include <AK/TypeCasts.h> | ||||
| 
 | ||||
| #include "AST/AST.h" | ||||
| #include "Compiler/Passes/IfBranchMergingPass.h" | ||||
| 
 | ||||
| namespace JSSpecCompiler { | ||||
| 
 | ||||
| RecursionDecision IfBranchMergingPass::on_entry(Tree tree) | ||||
| { | ||||
|     if (auto list = as<TreeList>(tree); list) { | ||||
|         Vector<Tree> result; | ||||
|         Vector<Tree> unmerged_branches; | ||||
| 
 | ||||
|         auto merge_if_needed = [&] { | ||||
|             if (!unmerged_branches.is_empty()) { | ||||
|                 result.append(merge_branches(unmerged_branches)); | ||||
|                 unmerged_branches.clear(); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         for (auto const& node : list->m_trees) { | ||||
|             if (is<IfBranch>(node.ptr())) { | ||||
|                 merge_if_needed(); | ||||
|                 unmerged_branches.append(node); | ||||
|             } else if (is<ElseIfBranch>(node.ptr())) { | ||||
|                 unmerged_branches.append(node); | ||||
|             } else { | ||||
|                 merge_if_needed(); | ||||
|                 result.append(node); | ||||
|             } | ||||
|         } | ||||
|         merge_if_needed(); | ||||
| 
 | ||||
|         list->m_trees = move(result); | ||||
|     } | ||||
|     return RecursionDecision::Recurse; | ||||
| } | ||||
| 
 | ||||
| Tree IfBranchMergingPass::merge_branches(Vector<Tree> const& unmerged_branches) | ||||
| { | ||||
|     static const Tree error = make_ref_counted<ErrorNode>("Cannot make sense of if-elseif-else chain"sv); | ||||
| 
 | ||||
|     VERIFY(unmerged_branches.size() >= 1); | ||||
| 
 | ||||
|     Vector<Tree> conditions; | ||||
|     Vector<Tree> branches; | ||||
|     NullableTree else_branch; | ||||
| 
 | ||||
|     if (auto if_branch = as<IfBranch>(unmerged_branches[0]); if_branch) { | ||||
|         conditions.append(if_branch->m_condition); | ||||
|         branches.append(if_branch->m_branch); | ||||
|     } else { | ||||
|         return error; | ||||
|     } | ||||
| 
 | ||||
|     for (size_t i = 1; i < unmerged_branches.size(); ++i) { | ||||
|         auto branch = as<ElseIfBranch>(unmerged_branches[i]); | ||||
| 
 | ||||
|         if (!branch) | ||||
|             return error; | ||||
| 
 | ||||
|         if (!branch->m_condition) { | ||||
|             // There might be situation like:
 | ||||
|             //   1. If <condition>, then
 | ||||
|             //      ...
 | ||||
|             //   2. Else,
 | ||||
|             //      a. If <condition>, then
 | ||||
|             //         ...
 | ||||
|             //   3. Else,
 | ||||
|             //      ...
 | ||||
|             auto substep_list = as<TreeList>(branch->m_branch); | ||||
|             if (substep_list && substep_list->m_trees.size() == 1) { | ||||
|                 if (auto nested_if = as<IfBranch>(substep_list->m_trees[0]); nested_if) | ||||
|                     branch = make_ref_counted<ElseIfBranch>(nested_if->m_condition, nested_if->m_branch); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (branch->m_condition) { | ||||
|             conditions.append(branch->m_condition.release_nonnull()); | ||||
|             branches.append(branch->m_branch); | ||||
|         } else { | ||||
|             if (i + 1 != unmerged_branches.size()) | ||||
|                 return error; | ||||
|             else_branch = branch->m_branch; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return make_ref_counted<IfElseIfChain>(move(conditions), move(branches), else_branch); | ||||
| } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Klishch
						Dan Klishch