1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#pragma once
#include <concepts>
#include <cstdio>
#include <string_view>
#include <utility>
#include <openvic-dataloader/File.hpp>
#include <openvic-dataloader/NodeLocation.hpp>
#include <openvic-dataloader/detail/utility/Utility.hpp>
#include <dryad/node.hpp>
#include <dryad/node_map.hpp>
#include <dryad/symbol.hpp>
#include <dryad/tree.hpp>
#include <fmt/core.h>
namespace ovdl {
struct AbstractSyntaxTree {
struct SymbolId;
using index_type = std::uint32_t;
using symbol_type = dryad::symbol<SymbolId, index_type>;
using symbol_interner_type = dryad::symbol_interner<SymbolId, char, index_type>;
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<typename T>
concept IsAst =
std::derived_from<T, AbstractSyntaxTree> &&
requires(
T t,
const T ct,
const typename T::node_type* node,
NodeLocation loc //
) {
requires IsFile<typename T::file_type>;
typename T::root_node_type;
typename T::node_type;
requires std::derived_from<typename T::root_node_type, typename T::node_type>;
{ t.set_location(node, loc) } -> std::same_as<void>;
{ t.location_of(node) } -> std::same_as<NodeLocation>;
{ t.root() } -> std::same_as<typename T::root_node_type*>;
{ ct.root() } -> std::same_as<const typename T::root_node_type*>;
{ t.file() } -> std::same_as<typename T::file_type&>;
{ ct.file() } -> std::same_as<const typename T::file_type&>;
};
template<IsFile FileT, std::derived_from<typename FileT::node_type> 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<typename file_type::encoding_type, void>&& 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<typename T, typename... Args>
T* create(NodeLocation loc, Args&&... args) {
auto node = _tree.template create<T>(DRYAD_FWD(args)...);
set_location(node, loc);
return node;
}
template<typename T, typename... Args>
T* create(const char* begin, const char* end, Args&&... args) {
return create<T>(NodeLocation::make_from(begin, end), DRYAD_FWD(args)...);
}
void set_root(root_node_type* node) {
_tree.set_root(node);
}
protected:
dryad::tree<root_node_type> _tree;
file_type _file;
};
}
|