/* * Copyright (c) 2023, Dan Klishch * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include "AST/AST.h" #include "CompilationPipeline.h" #include "Forward.h" #include "Parser/ParseError.h" #include "Parser/TextParser.h" #include "Parser/Token.h" namespace JSSpecCompiler { class SpecificationParsingContext { AK_MAKE_NONCOPYABLE(SpecificationParsingContext); AK_MAKE_NONMOVABLE(SpecificationParsingContext); public: SpecificationParsingContext(TranslationUnitRef translation_unit) : m_translation_unit(translation_unit) { } DiagnosticEngine& diag(); template auto with_new_logical_scope(Func&& func); LogicalLocation& current_logical_scope(); Location file_scope() const; Location location_from_xml_offset(XML::Offset offset) const; private: TranslationUnitRef m_translation_unit; RefPtr m_current_logical_scope; }; class AlgorithmStepList { public: static ParseErrorOr create(XML::Node::Element const& element); Vector m_steps; Tree m_expression = error_tree; }; class AlgorithmStep { public: static ParseErrorOr create(XML::Node const* node); ParseErrorOr parse(); Tree m_expression = error_tree; Vector m_tokens; NullableTree m_substeps; XML::Node const* m_node; }; class Algorithm { public: static ParseErrorOr create(XML::Node const* node); AlgorithmStepList m_steps; Tree m_tree = error_tree; }; class SpecificationClause { AK_MAKE_DEFAULT_MOVABLE(SpecificationClause); public: static NonnullOwnPtr create(SpecificationParsingContext& ctx, XML::Node const* element); virtual ~SpecificationClause() = default; void collect_into(TranslationUnitRef translation_unit); protected: virtual bool post_initialize(SpecificationParsingContext& /*ctx*/, XML::Node const* /*element*/) { return true; } virtual void do_collect(TranslationUnitRef /*translation_unit*/) { } ClauseHeader m_header; private: SpecificationClause() = default; ParseErrorOr parse_header(XML::Node const* element); void parse(SpecificationParsingContext& ctx, XML::Node const* element); Vector> m_subclauses; }; class SpecFunction : public SpecificationClause { public: SpecFunction(SpecificationClause&& clause) : SpecificationClause(move(clause)) { } protected: bool post_initialize(SpecificationParsingContext& ctx, XML::Node const* element) override; void do_collect(TranslationUnitRef translation_unit) override; private: ParseErrorOr do_post_initialize(SpecificationParsingContext& ctx, XML::Node const* element); StringView m_section_number; StringView m_id; StringView m_name; Vector m_arguments; Algorithm m_algorithm; }; class Specification { public: static Specification create(SpecificationParsingContext& ctx, XML::Node const* element); void collect_into(TranslationUnitRef translation_unit); private: void parse(SpecificationParsingContext& ctx, XML::Node const* element); Vector> m_clauses; }; class SpecParsingStep : public CompilationStep { public: SpecParsingStep(); ~SpecParsingStep(); void run(TranslationUnitRef translation_unit) override; private: OwnPtr m_document; ByteBuffer m_input; }; }