mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:52:43 +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; |     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 { | class FunctionPointer : public Expression { | ||||||
| public: | public: | ||||||
|     FunctionPointer(FunctionDeclarationRef declaration) |     FunctionPointer(FunctionDeclarationRef declaration) | ||||||
|  |  | ||||||
|  | @ -178,6 +178,11 @@ void Variable::dump_tree(StringBuilder& builder) | ||||||
|     dump_node(builder, "Var {}", name()); |     dump_node(builder, "Var {}", name()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Enumerator::dump_tree(StringBuilder& builder) | ||||||
|  | { | ||||||
|  |     dump_node(builder, "Enumerator {}", m_value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void FunctionPointer::dump_tree(StringBuilder& builder) | void FunctionPointer::dump_tree(StringBuilder& builder) | ||||||
| { | { | ||||||
|     dump_node(builder, "Func \"{}\"", m_declaration->m_name); |     dump_node(builder, "Func \"{}\"", m_declaration->m_name); | ||||||
|  |  | ||||||
|  | @ -45,6 +45,8 @@ class TreeList; | ||||||
| class RecordDirectListInitialization; | class RecordDirectListInitialization; | ||||||
| class FunctionCall; | class FunctionCall; | ||||||
| class SlotName; | class SlotName; | ||||||
|  | class Enumerator; | ||||||
|  | using EnumeratorRef = NonnullRefPtr<Enumerator>; | ||||||
| class Variable; | class Variable; | ||||||
| using VariableRef = NonnullRefPtr<Variable>; | using VariableRef = NonnullRefPtr<Variable>; | ||||||
| class FunctionPointer; | class FunctionPointer; | ||||||
|  |  | ||||||
|  | @ -40,6 +40,16 @@ FunctionDeclarationRef TranslationUnit::find_declaration_by_name(StringView name | ||||||
|     return it->value; |     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) | FunctionDeclaration::FunctionDeclaration(StringView name, Vector<FunctionArgument>&& arguments) | ||||||
|     : m_name(name) |     : m_name(name) | ||||||
|     , m_arguments(arguments) |     , m_arguments(arguments) | ||||||
|  |  | ||||||
|  | @ -30,12 +30,15 @@ public: | ||||||
|     DiagnosticEngine& diag() { return m_diagnostic_engine; } |     DiagnosticEngine& diag() { return m_diagnostic_engine; } | ||||||
|     Vector<FunctionDefinitionRef> functions_to_compile() const { return m_functions_to_compile; } |     Vector<FunctionDefinitionRef> functions_to_compile() const { return m_functions_to_compile; } | ||||||
| 
 | 
 | ||||||
|  |     EnumeratorRef get_node_for_enumerator_value(StringView value); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     StringView m_filename; |     StringView m_filename; | ||||||
|     DiagnosticEngine m_diagnostic_engine; |     DiagnosticEngine m_diagnostic_engine; | ||||||
|     Vector<FunctionDefinitionRef> m_functions_to_compile; |     Vector<FunctionDefinitionRef> m_functions_to_compile; | ||||||
|     Vector<NonnullRefPtr<FunctionDeclaration>> m_declarations_owner; |     Vector<NonnullRefPtr<FunctionDeclaration>> m_declarations_owner; | ||||||
|     HashMap<StringView, FunctionDeclarationRef> m_function_index; |     HashMap<StringView, FunctionDeclarationRef> m_function_index; | ||||||
|  |     HashMap<StringView, EnumeratorRef> m_enumerator_nodes; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct FunctionArgument { | struct FunctionArgument { | ||||||
|  |  | ||||||
|  | @ -185,6 +185,15 @@ void tokenize_tree(SpecificationParsingContext& ctx, TokenizerState& state, XML: | ||||||
|                     return; |                     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) { |                 if (tree_type == TreeType::Header && element.name == tag_span) { | ||||||
|                     auto element_class = get_attribute_by_name(child, attribute_class); |                     auto element_class = get_attribute_by_name(child, attribute_class); | ||||||
|                     if (element_class != class_secnum) |                     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_alg = "emu-alg"sv; | ||||||
| inline constexpr StringView tag_emu_clause = "emu-clause"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_import = "emu-import"sv; | ||||||
| inline constexpr StringView tag_emu_intro = "emu-intro"sv; | inline constexpr StringView tag_emu_intro = "emu-intro"sv; | ||||||
| inline constexpr StringView tag_emu_val = "emu-val"sv; | inline constexpr StringView tag_emu_val = "emu-val"sv; | ||||||
|  |  | ||||||
|  | @ -16,6 +16,11 @@ | ||||||
| 
 | 
 | ||||||
| namespace JSSpecCompiler { | namespace JSSpecCompiler { | ||||||
| 
 | 
 | ||||||
|  | TranslationUnitRef SpecificationParsingContext::translation_unit() | ||||||
|  | { | ||||||
|  |     return m_translation_unit; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| DiagnosticEngine& SpecificationParsingContext::diag() | DiagnosticEngine& SpecificationParsingContext::diag() | ||||||
| { | { | ||||||
|     return m_translation_unit->diag(); |     return m_translation_unit->diag(); | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     TranslationUnitRef translation_unit(); | ||||||
|     DiagnosticEngine& diag(); |     DiagnosticEngine& diag(); | ||||||
| 
 | 
 | ||||||
|     template<typename Func> |     template<typename Func> | ||||||
|  |  | ||||||
|  | @ -316,6 +316,8 @@ TextParseErrorOr<Tree> TextParser::parse_expression() | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 VERIFY(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) { |             } else if (token.type == TokenType::Number) { | ||||||
|                 expression = make_ref_counted<MathematicalConstant>(MUST(Crypto::BigFraction::from_string(token.data))); |                 expression = make_ref_counted<MathematicalConstant>(MUST(Crypto::BigFraction::from_string(token.data))); | ||||||
|             } else if (token.type == TokenType::String) { |             } else if (token.type == TokenType::String) { | ||||||
|  |  | ||||||
|  | @ -30,6 +30,7 @@ constexpr i32 closing_bracket_precedence = 18; | ||||||
|     F(Comma, 17, Invalid, Comma, Invalid, "','")                                     \ |     F(Comma, 17, Invalid, Comma, Invalid, "','")                                     \ | ||||||
|     F(Division, 5, Invalid, Division, Invalid, "division")                           \ |     F(Division, 5, Invalid, Division, Invalid, "division")                           \ | ||||||
|     F(Dot, -1, Invalid, Invalid, Invalid, "punctuation mark '.'")                    \ |     F(Dot, -1, Invalid, Invalid, Invalid, "punctuation mark '.'")                    \ | ||||||
|  |     F(Enumerator, -1, Invalid, Invalid, Invalid, "enumerator")                       \ | ||||||
|     F(Equals, 10, Invalid, CompareEqual, Invalid, "equals")                          \ |     F(Equals, 10, Invalid, CompareEqual, Invalid, "equals")                          \ | ||||||
|     F(ExclamationMark, 3, AssertCompletion, Invalid, Invalid, "exclamation mark")    \ |     F(ExclamationMark, 3, AssertCompletion, Invalid, Invalid, "exclamation mark")    \ | ||||||
|     F(FunctionCall, 2, Invalid, FunctionCall, Invalid, "function call token")        \ |     F(FunctionCall, 2, Invalid, FunctionCall, Invalid, "function call token")        \ | ||||||
|  |  | ||||||
|  | @ -41,4 +41,12 @@ | ||||||
|          </ol> |          </ol> | ||||||
|       </emu-alg> |       </emu-alg> | ||||||
|    </emu-clause> |    </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> | </specification> | ||||||
|  |  | ||||||
|  | @ -54,3 +54,11 @@ TreeList | ||||||
|         Func "WellKnownConstants" |         Func "WellKnownConstants" | ||||||
|         Var a |         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