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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#pragma once
#include <concepts>
#include <utility>
#include <openvic-dataloader/NodeLocation.hpp>
#include <openvic-dataloader/detail/Encoding.hpp>
#include <openvic-dataloader/detail/SymbolIntern.hpp>
#include <lexy/encoding.hpp>
#include <lexy/input/buffer.hpp>
#include <fmt/core.h>
#include <lexy_ext/report_error.hpp>
namespace ovdl::detail {
template<typename T>
concept IsFile =
requires(T t, const typename T::node_type* node, NodeLocation location) {
typename T::node_type;
{ t.set_location(node, location) } -> std::same_as<void>;
{ t.location_of(node) } -> std::same_as<NodeLocation>;
};
template<typename T>
concept IsAst =
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<typename T>
concept IsDiagnosticLogger = requires(
T t,
const T ct,
const char* str,
std::size_t length,
std::string_view sv,
lexy_ext::diagnostic_kind diag_kind //
) {
typename T::error_range;
typename T::Writer;
{ static_cast<bool>(ct) } -> std::same_as<bool>;
{ ct.errored() } -> std::same_as<bool>;
{ ct.warned() } -> std::same_as<bool>;
{ ct.get_errors() } -> std::same_as<typename T::error_range>;
{ t.intern(str, length) } -> std::same_as<ovdl::SymbolIntern::symbol_type>;
{ t.intern(sv) } -> std::same_as<ovdl::SymbolIntern::symbol_type>;
{ t.intern_cstr(str, length) } -> std::same_as<const char*>;
{ t.intern_cstr(sv) } -> std::same_as<const char*>;
{ t.symbol_interner() } -> std::same_as<SymbolIntern::symbol_interner_type&>;
{ ct.symbol_interner() } -> std::same_as<const SymbolIntern::symbol_interner_type&>;
{ t.error(std::declval<typename T::template format_str<>>()) } -> std::same_as<typename T::Writer>;
{ t.warning(std::declval<typename T::template format_str<>>()) } -> std::same_as<typename T::Writer>;
{ t.note(std::declval<typename T::template format_str<>>()) } -> std::same_as<typename T::Writer>;
{ t.info(std::declval<typename T::template format_str<>>()) } -> std::same_as<typename T::Writer>;
{ t.debug(std::declval<typename T::template format_str<>>()) } -> std::same_as<typename T::Writer>;
{ t.fixit(std::declval<typename T::template format_str<>>()) } -> std::same_as<typename T::Writer>;
{ t.help(std::declval<typename T::template format_str<>>()) } -> std::same_as<typename T::Writer>;
{ t.error(sv) } -> std::same_as<typename T::Writer>;
{ t.warning(sv) } -> std::same_as<typename T::Writer>;
{ t.note(sv) } -> std::same_as<typename T::Writer>;
{ t.info(sv) } -> std::same_as<typename T::Writer>;
{ t.debug(sv) } -> std::same_as<typename T::Writer>;
{ t.fixit(sv) } -> std::same_as<typename T::Writer>;
{ t.help(sv) } -> std::same_as<typename T::Writer>;
{ std::move(t.error_callback().sink()).finish() } -> std::same_as<std::size_t>;
{ t.log(diag_kind, std::declval<typename T::template format_str<>>()) } -> std::same_as<typename T::Writer>;
};
template<typename T>
concept IsParseState = requires(
T t,
const T ct,
typename T::ast_type::file_type&& file,
lexy::buffer<lexy::default_encoding>&& buffer,
ovdl::detail::Encoding encoding,
const char* path //
) {
requires IsAst<typename T::ast_type>;
requires IsDiagnosticLogger<typename T::diagnostic_logger_type>;
{ T { std::move(file), encoding } } -> std::same_as<T>;
{ T { std::move(buffer), encoding } } -> std::same_as<T>;
{ T { path, std::move(buffer), encoding } } -> std::same_as<T>;
{ t.ast() } -> std::same_as<typename T::ast_type&>;
{ ct.ast() } -> std::same_as<const typename T::ast_type&>;
{ t.logger() } -> std::same_as<typename T::diagnostic_logger_type&>;
{ ct.logger() } -> std::same_as<const typename T::diagnostic_logger_type&>;
};
template<typename T>
concept IsFileParseState = requires(
T t,
const T ct,
typename T::file_type&& file,
lexy::buffer<lexy::default_encoding>&& buffer,
ovdl::detail::Encoding encoding,
const char* path //
) {
requires IsFile<typename T::file_type>;
requires IsDiagnosticLogger<typename T::diagnostic_logger_type>;
{ T { std::move(file), encoding } } -> std::same_as<T>;
{ T { std::move(buffer), encoding } } -> std::same_as<T>;
{ T { path, std::move(buffer), encoding } } -> std::same_as<T>;
{ t.file() } -> std::same_as<typename T::file_type&>;
{ ct.file() } -> std::same_as<const typename T::file_type&>;
{ t.logger() } -> std::same_as<typename T::diagnostic_logger_type&>;
{ ct.logger() } -> std::same_as<const typename T::diagnostic_logger_type&>;
};
template<typename T>
concept IsStateType = IsParseState<T> || IsFileParseState<T>;
}
|