1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 15:34:59 +00:00
serenity/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/SpecificationParsing.h

180 lines
4.5 KiB
C++

/*
* Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/OwnPtr.h>
#include <AK/TemporaryChange.h>
#include "AST/AST.h"
#include "CompilationPipeline.h"
#include "Forward.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)
{
}
TranslationUnitRef translation_unit();
DiagnosticEngine& diag();
template<typename Func>
auto with_new_logical_scope(Func&& func)
{
TemporaryChange<RefPtr<LogicalLocation>> change(m_current_logical_scope, make_ref_counted<LogicalLocation>());
return func();
}
LogicalLocation& current_logical_scope();
template<typename Func>
auto with_new_step_list_nesting_level(Func&& func)
{
TemporaryChange change(m_step_list_nesting_level, m_step_list_nesting_level + 1);
return func();
}
int step_list_nesting_level() const;
Location file_scope() const;
Location location_from_xml_offset(LineTrackingLexer::Position position) const;
private:
TranslationUnitRef m_translation_unit;
RefPtr<LogicalLocation> m_current_logical_scope;
int m_step_list_nesting_level = 0;
};
class AlgorithmStepList {
public:
static Optional<AlgorithmStepList> create(SpecificationParsingContext& ctx, XML::Node const* element);
Tree tree() const { return m_expression; }
private:
static void update_logical_scope_for_step(SpecificationParsingContext& ctx, LogicalLocation const& parent_scope, int step_number);
Tree m_expression = error_tree;
};
class AlgorithmStep {
public:
static Optional<AlgorithmStep> create(SpecificationParsingContext& ctx, XML::Node const* node);
NullableTree tree() const { return m_expression; }
private:
AlgorithmStep(SpecificationParsingContext& ctx)
: m_ctx(ctx)
{
}
bool parse();
SpecificationParsingContext& m_ctx;
Vector<Token> m_tokens;
XML::Node const* m_node;
NullableTree m_expression = error_tree;
NullableTree m_substeps;
};
class Algorithm {
public:
static Optional<Algorithm> create(SpecificationParsingContext& ctx, XML::Node const* element);
Tree tree() const { return m_tree; }
private:
Tree m_tree = error_tree;
};
class SpecificationClause {
AK_MAKE_DEFAULT_MOVABLE(SpecificationClause);
public:
static NonnullOwnPtr<SpecificationClause> create(SpecificationParsingContext& ctx, XML::Node const* element);
virtual ~SpecificationClause() = default;
void collect_into(TranslationUnitRef translation_unit);
protected:
virtual bool post_initialize(XML::Node const* /*element*/) { return true; }
virtual void do_collect(TranslationUnitRef /*translation_unit*/) { }
SpecificationParsingContext& context() { return *m_ctx_pointer; }
ClauseHeader m_header;
private:
SpecificationClause(SpecificationParsingContext& ctx)
: m_ctx_pointer(&ctx)
{
}
Optional<FailedTextParseDiagnostic> parse_header(XML::Node const* element);
void parse(XML::Node const* element);
TextParser::ClauseHasAoidAttribute m_clause_has_aoid_attribute;
SpecificationParsingContext* m_ctx_pointer;
Vector<NonnullOwnPtr<SpecificationClause>> m_subclauses;
};
class SpecificationFunction : public SpecificationClause {
public:
SpecificationFunction(SpecificationClause&& clause)
: SpecificationClause(move(clause))
{
}
protected:
bool post_initialize(XML::Node const* element) override;
void do_collect(TranslationUnitRef translation_unit) override;
private:
StringView m_id;
String m_name;
Vector<FunctionArgument> m_arguments;
Algorithm m_algorithm;
};
class Specification {
public:
static NonnullOwnPtr<Specification> create(SpecificationParsingContext& ctx, XML::Node const* element);
void collect_into(TranslationUnitRef translation_unit);
private:
void parse(SpecificationParsingContext& ctx, XML::Node const* element);
Vector<NonnullOwnPtr<SpecificationClause>> m_clauses;
};
class SpecificationParsingStep : public CompilationStep {
public:
SpecificationParsingStep();
~SpecificationParsingStep();
void run(TranslationUnitRef translation_unit) override;
private:
OwnPtr<XML::Document> m_document;
OwnPtr<Specification> m_specification;
ByteBuffer m_input;
};
}