#pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace ovdl { struct AbstractSyntaxTree { struct SymbolId; using index_type = std::uint32_t; using symbol_type = dryad::symbol; using symbol_interner_type = dryad::symbol_interner; symbol_type intern(const char* str, std::size_t length); symbol_type intern(std::string_view str); const char* intern_cstr(const char* str, std::size_t length); const char* intern_cstr(std::string_view str); symbol_interner_type& symbol_interner(); const symbol_interner_type& symbol_interner() const; protected: symbol_interner_type _symbol_interner; }; template concept IsAst = std::derived_from && requires( T t, const T ct, const typename T::node_type* node, NodeLocation loc // ) { requires IsFile; typename T::root_node_type; typename T::node_type; requires std::derived_from; { t.set_location(node, loc) } -> std::same_as; { t.location_of(node) } -> std::same_as; { t.root() } -> std::same_as; { ct.root() } -> std::same_as; { t.file() } -> std::same_as; { ct.file() } -> std::same_as; }; template RootNodeT> struct BasicAbstractSyntaxTree : AbstractSyntaxTree { using file_type = FileT; using root_node_type = RootNodeT; using node_type = typename file_type::node_type; explicit BasicAbstractSyntaxTree(file_type&& file) : _file(std::move(file)) {} explicit BasicAbstractSyntaxTree(lexy::buffer&& buffer) : _file(std::move(buffer)) {} void set_location(const node_type* n, NodeLocation loc) { _file.set_location(n, loc); } NodeLocation location_of(const node_type* n) const { return _file.location_of(n); } root_node_type* root() { return _tree.root(); } const root_node_type* root() const { return _tree.root(); } file_type& file() { return _file; } const file_type& file() const { return _file; } template T* create(NodeLocation loc, Args&&... args) { auto node = _tree.template create(DRYAD_FWD(args)...); set_location(node, loc); return node; } template T* create(const char* begin, const char* end, Args&&... args) { return create(NodeLocation::make_from(begin, end), DRYAD_FWD(args)...); } void set_root(root_node_type* node) { _tree.set_root(node); } protected: dryad::tree _tree; file_type _file; }; }