mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 06:02:44 +00:00 
			
		
		
		
	JSSpecCompiler: Parse enumerators in xspec mode
This commit is contained in:
		
							parent
							
								
									3d365326af
								
							
						
					
					
						commit
						990e30f458
					
				
					 13 changed files with 69 additions and 0 deletions
				
			
		|  | @ -523,6 +523,20 @@ protected: | |||
|     void dump_tree(StringBuilder& builder) override; | ||||
| }; | ||||
| 
 | ||||
| class Enumerator : public Expression { | ||||
| public: | ||||
|     Enumerator(Badge<TranslationUnit>, StringView value) | ||||
|         : m_value(value) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
| protected: | ||||
|     void dump_tree(StringBuilder& builder) override; | ||||
| 
 | ||||
| private: | ||||
|     StringView m_value; | ||||
| }; | ||||
| 
 | ||||
| class FunctionPointer : public Expression { | ||||
| public: | ||||
|     FunctionPointer(FunctionDeclarationRef declaration) | ||||
|  |  | |||
|  | @ -178,6 +178,11 @@ void Variable::dump_tree(StringBuilder& builder) | |||
|     dump_node(builder, "Var {}", name()); | ||||
| } | ||||
| 
 | ||||
| void Enumerator::dump_tree(StringBuilder& builder) | ||||
| { | ||||
|     dump_node(builder, "Enumerator {}", m_value); | ||||
| } | ||||
| 
 | ||||
| void FunctionPointer::dump_tree(StringBuilder& builder) | ||||
| { | ||||
|     dump_node(builder, "Func \"{}\"", m_declaration->m_name); | ||||
|  |  | |||
|  | @ -45,6 +45,8 @@ class TreeList; | |||
| class RecordDirectListInitialization; | ||||
| class FunctionCall; | ||||
| class SlotName; | ||||
| class Enumerator; | ||||
| using EnumeratorRef = NonnullRefPtr<Enumerator>; | ||||
| class Variable; | ||||
| using VariableRef = NonnullRefPtr<Variable>; | ||||
| class FunctionPointer; | ||||
|  |  | |||
|  | @ -40,6 +40,16 @@ FunctionDeclarationRef TranslationUnit::find_declaration_by_name(StringView name | |||
|     return it->value; | ||||
| } | ||||
| 
 | ||||
| EnumeratorRef TranslationUnit::get_node_for_enumerator_value(StringView value) | ||||
| { | ||||
|     if (auto it = m_enumerator_nodes.find(value); it != m_enumerator_nodes.end()) | ||||
|         return it->value; | ||||
| 
 | ||||
|     auto enumerator = NonnullRefPtr(NonnullRefPtr<Enumerator>::Adopt, *new Enumerator { {}, value }); | ||||
|     m_enumerator_nodes.set(value, enumerator); | ||||
|     return enumerator; | ||||
| } | ||||
| 
 | ||||
| FunctionDeclaration::FunctionDeclaration(StringView name, Vector<FunctionArgument>&& arguments) | ||||
|     : m_name(name) | ||||
|     , m_arguments(arguments) | ||||
|  |  | |||
|  | @ -30,12 +30,15 @@ public: | |||
|     DiagnosticEngine& diag() { return m_diagnostic_engine; } | ||||
|     Vector<FunctionDefinitionRef> functions_to_compile() const { return m_functions_to_compile; } | ||||
| 
 | ||||
|     EnumeratorRef get_node_for_enumerator_value(StringView value); | ||||
| 
 | ||||
| private: | ||||
|     StringView m_filename; | ||||
|     DiagnosticEngine m_diagnostic_engine; | ||||
|     Vector<FunctionDefinitionRef> m_functions_to_compile; | ||||
|     Vector<NonnullRefPtr<FunctionDeclaration>> m_declarations_owner; | ||||
|     HashMap<StringView, FunctionDeclarationRef> m_function_index; | ||||
|     HashMap<StringView, EnumeratorRef> m_enumerator_nodes; | ||||
| }; | ||||
| 
 | ||||
| struct FunctionArgument { | ||||
|  |  | |||
|  | @ -185,6 +185,15 @@ void tokenize_tree(SpecificationParsingContext& ctx, TokenizerState& state, XML: | |||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 if (element.name == tag_emu_const) { | ||||
|                     auto maybe_contents = get_text_contents(child); | ||||
|                     if (!maybe_contents.has_value()) | ||||
|                         report_error("malformed <emu-const> subtree, expected single text child node"); | ||||
| 
 | ||||
|                     tokens.append({ TokenType::Enumerator, maybe_contents.value_or(""sv), move(child_location) }); | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 if (tree_type == TreeType::Header && element.name == tag_span) { | ||||
|                     auto element_class = get_attribute_by_name(child, attribute_class); | ||||
|                     if (element_class != class_secnum) | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ namespace JSSpecCompiler { | |||
| 
 | ||||
| inline constexpr StringView tag_emu_alg = "emu-alg"sv; | ||||
| inline constexpr StringView tag_emu_clause = "emu-clause"sv; | ||||
| inline constexpr StringView tag_emu_const = "emu-const"sv; | ||||
| inline constexpr StringView tag_emu_import = "emu-import"sv; | ||||
| inline constexpr StringView tag_emu_intro = "emu-intro"sv; | ||||
| inline constexpr StringView tag_emu_val = "emu-val"sv; | ||||
|  |  | |||
|  | @ -16,6 +16,11 @@ | |||
| 
 | ||||
| namespace JSSpecCompiler { | ||||
| 
 | ||||
| TranslationUnitRef SpecificationParsingContext::translation_unit() | ||||
| { | ||||
|     return m_translation_unit; | ||||
| } | ||||
| 
 | ||||
| DiagnosticEngine& SpecificationParsingContext::diag() | ||||
| { | ||||
|     return m_translation_unit->diag(); | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ public: | |||
|     { | ||||
|     } | ||||
| 
 | ||||
|     TranslationUnitRef translation_unit(); | ||||
|     DiagnosticEngine& diag(); | ||||
| 
 | ||||
|     template<typename Func> | ||||
|  |  | |||
|  | @ -316,6 +316,8 @@ TextParseErrorOr<Tree> TextParser::parse_expression() | |||
|                     } | ||||
|                 } | ||||
|                 VERIFY(expression); | ||||
|             } else if (token.type == TokenType::Enumerator) { | ||||
|                 expression = m_ctx.translation_unit()->get_node_for_enumerator_value(token.data); | ||||
|             } else if (token.type == TokenType::Number) { | ||||
|                 expression = make_ref_counted<MathematicalConstant>(MUST(Crypto::BigFraction::from_string(token.data))); | ||||
|             } else if (token.type == TokenType::String) { | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ constexpr i32 closing_bracket_precedence = 18; | |||
|     F(Comma, 17, Invalid, Comma, Invalid, "','")                                     \ | ||||
|     F(Division, 5, Invalid, Division, Invalid, "division")                           \ | ||||
|     F(Dot, -1, Invalid, Invalid, Invalid, "punctuation mark '.'")                    \ | ||||
|     F(Enumerator, -1, Invalid, Invalid, Invalid, "enumerator")                       \ | ||||
|     F(Equals, 10, Invalid, CompareEqual, Invalid, "equals")                          \ | ||||
|     F(ExclamationMark, 3, AssertCompletion, Invalid, Invalid, "exclamation mark")    \ | ||||
|     F(FunctionCall, 2, Invalid, FunctionCall, Invalid, "function call token")        \ | ||||
|  |  | |||
|  | @ -41,4 +41,12 @@ | |||
|          </ol> | ||||
|       </emu-alg> | ||||
|    </emu-clause> | ||||
|    <emu-clause id="4" aoid="Enumerators"> | ||||
|       <h1><span class="secnum">4</span> Enumerators ( )</h1> | ||||
|       <emu-alg> | ||||
|          <ol> | ||||
|             <li>Return ? <emu-xref><a>WellKnownConstants</a></emu-xref>(<emu-const>enumerator</emu-const>).</li> | ||||
|          </ol> | ||||
|       </emu-alg> | ||||
|    </emu-clause> | ||||
| </specification> | ||||
|  |  | |||
|  | @ -54,3 +54,11 @@ TreeList | |||
|         Func "WellKnownConstants" | ||||
|         Var a | ||||
| 
 | ||||
| Enumerators(): | ||||
| TreeList | ||||
|   ReturnNode | ||||
|     UnaryOperation ReturnIfAbrubt | ||||
|       FunctionCall | ||||
|         Func "WellKnownConstants" | ||||
|         Enumerator enumerator | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Klishch
						Dan Klishch