-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
853b186
commit 6d7df1c
Showing
32 changed files
with
1,154 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#pragma once | ||
|
||
#include <concepts> | ||
#include <cstdio> | ||
#include <string_view> | ||
#include <type_traits> | ||
#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::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*>; | ||
{ const_cast<const T&>(t).root() } -> std::same_as<const typename T::root_node_type*>; | ||
{ t.file() } -> std::same_as<typename T::file_type&>; | ||
{ const_cast<const T&>(t).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 = file_type::node_type; | ||
|
||
explicit BasicAbstractSyntaxTree(file_type&& file) : _file(std::move(file)) {} | ||
explicit BasicAbstractSyntaxTree(lexy::buffer<typename file_type::encoding_type>&& 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; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#pragma once | ||
|
||
#include <cstdarg> | ||
#include <cstdio> | ||
#include <initializer_list> | ||
|
||
#include <openvic-dataloader/AbstractSyntaxTree.hpp> | ||
#include <openvic-dataloader/File.hpp> | ||
#include <openvic-dataloader/NodeLocation.hpp> | ||
#include <openvic-dataloader/detail/LexyReportError.hpp> | ||
#include <openvic-dataloader/detail/OStreamOutputIterator.hpp> | ||
|
||
#include <lexy/input/buffer.hpp> | ||
#include <lexy/visualize.hpp> | ||
|
||
#include <fmt/core.h> | ||
|
||
#include <lexy_ext/report_error.hpp> | ||
|
||
namespace ovdl { | ||
struct DiagnosticLogger { | ||
using AnnotationKind = lexy_ext::annotation_kind; | ||
using DiagnosticKind = lexy_ext::diagnostic_kind; | ||
|
||
explicit operator bool() const; | ||
bool errored() const; | ||
bool warned() const; | ||
|
||
protected: | ||
bool _errored = false; | ||
bool _warned = false; | ||
}; | ||
|
||
template<IsFile FileT> | ||
struct BasicDiagnosticLogger : DiagnosticLogger { | ||
using file_type = FileT; | ||
|
||
explicit BasicDiagnosticLogger(const file_type& file, std::ostream& error_stream) | ||
: _file(&file), | ||
_stream_iterator(detail::OStreamOutputIterator { error_stream }) {} | ||
|
||
class Writer { | ||
public: | ||
template<typename CharT, typename... Args> | ||
[[nodiscard]] Writer& annotation(AnnotationKind kind, | ||
NodeLocation loc, | ||
const CharT* fmt, Args&&... args) { | ||
|
||
auto begin_loc = lexy::get_input_location(_file->buffer(), loc.begin()); | ||
|
||
_impl.write_empty_annotation(_stream_iterator); | ||
_impl.write_annotation(_stream_iterator, kind, begin_loc, loc.end(), | ||
[&](auto out, lexy::visualization_options) { | ||
return lexy::_detail::write_str(out, fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...).c_str()); | ||
}); | ||
return *this; | ||
} | ||
|
||
template<typename CharT, typename... Args> | ||
[[nodiscard]] Writer& primary(NodeLocation loc, const CharT* fmt, Args&&... args) { | ||
return annotation(AnnotationKind::primary, loc, fmt, std::forward<Args>(args)...); | ||
} | ||
|
||
template<typename CharT, typename... Args> | ||
[[nodiscard]] Writer& secondary(NodeLocation loc, const CharT* fmt, Args&&... args) { | ||
return annotation(AnnotationKind::secondary, loc, fmt, std::forward<Args>(args)...); | ||
} | ||
|
||
void finish() {} | ||
|
||
private: | ||
Writer(const file_type* file, detail::OStreamOutputIterator& stream_iterator) | ||
: _file(file), | ||
_impl(file->buffer(), { lexy::visualize_fancy }), | ||
_stream_iterator(stream_iterator) {} | ||
|
||
const file_type* _file; | ||
lexy_ext::diagnostic_writer<lexy::buffer<typename file_type::encoding_type>> _impl; | ||
detail::OStreamOutputIterator& _stream_iterator; | ||
|
||
friend BasicDiagnosticLogger; | ||
}; | ||
|
||
template<typename CharT, typename... Args> | ||
Writer log(DiagnosticKind kind, const CharT* fmt, Args&&... args) { | ||
Writer result(_file, _stream_iterator); | ||
|
||
result._impl.write_message(_stream_iterator, kind, | ||
[&](auto out, lexy::visualization_options) { | ||
return lexy::_detail::write_str(out, fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...).c_str()); | ||
}); | ||
result._impl.write_path(_stream_iterator, _file->path()); | ||
|
||
if (kind == DiagnosticKind::error) | ||
_errored = true; | ||
if (kind == DiagnosticKind::warning) | ||
_warned = true; | ||
return result; | ||
} | ||
|
||
template<typename CharT, typename... Args> | ||
Writer error(const CharT* fmt, Args&&... args) { | ||
return log(DiagnosticKind::error, fmt, std::forward<Args>(args)...); | ||
} | ||
|
||
template<typename CharT, typename... Args> | ||
Writer warning(const CharT* fmt, Args&&... args) { | ||
return log(DiagnosticKind::warning, fmt, std::forward<Args>(args)...); | ||
} | ||
|
||
template<typename CharT, typename... Args> | ||
Writer note(const CharT* fmt, Args&&... args) { | ||
return log(DiagnosticKind::note, fmt, std::forward<Args>(args)...); | ||
} | ||
|
||
template<typename CharT, typename... Args> | ||
Writer info(const CharT* fmt, Args&&... args) { | ||
return log(DiagnosticKind::info, fmt, std::forward<Args>(args)...); | ||
} | ||
|
||
template<typename CharT, typename... Args> | ||
Writer debug(const CharT* fmt, Args&&... args) { | ||
return log(DiagnosticKind::debug, fmt, std::forward<Args>(args)...); | ||
} | ||
|
||
template<typename CharT, typename... Args> | ||
Writer fixit(const CharT* fmt, Args&&... args) { | ||
return log(DiagnosticKind::fixit, fmt, std::forward<Args>(args)...); | ||
} | ||
|
||
template<typename CharT, typename... Args> | ||
Writer help(const CharT* fmt, Args&&... args) { | ||
return log(DiagnosticKind::help, fmt, std::forward<Args>(args)...); | ||
} | ||
|
||
auto error_callback() const { | ||
return ovdl::detail::ReporError.path(_file->path()).to(_stream_iterator); | ||
} | ||
|
||
private: | ||
const file_type* _file; | ||
detail::OStreamOutputIterator _stream_iterator; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#pragma once | ||
|
||
#include <concepts> | ||
#include <utility> | ||
|
||
#include <openvic-dataloader/NodeLocation.hpp> | ||
|
||
#include <lexy/input/buffer.hpp> | ||
|
||
#include <dryad/node_map.hpp> | ||
|
||
namespace ovdl { | ||
template<typename T> | ||
concept IsEncoding = requires(T t) { | ||
typename T::char_type; | ||
typename T::int_type; | ||
{ T::template is_secondary_char_type<typename T::char_type>() } -> std::same_as<bool>; | ||
{ T::eof() } -> std::same_as<typename T::int_type>; | ||
{ T::to_int_type(typename T::char_type {}) } -> std::same_as<typename T::int_type>; | ||
}; | ||
|
||
struct File { | ||
explicit File(const char* path); | ||
|
||
const char* path() const noexcept; | ||
|
||
protected: | ||
const char* _path; | ||
}; | ||
|
||
template<typename T> | ||
concept IsFile = | ||
std::derived_from<T, File> && IsEncoding<typename T::encoding_type> && | ||
requires(T t, const T::node_type* node, NodeLocation location) { | ||
{ t.buffer() } -> std::same_as<const lexy::buffer<typename T::encoding_type>&>; | ||
{ t.set_location(node, location) } -> std::same_as<void>; | ||
{ t.location_of(node) } -> std::same_as<NodeLocation>; | ||
}; | ||
|
||
template<typename EncodingT, typename NodeT> | ||
struct BasicFile : File { | ||
using encoding_type = EncodingT; | ||
using node_type = NodeT; | ||
|
||
explicit BasicFile(const char* path, lexy::buffer<encoding_type>&& buffer) | ||
: File(path), | ||
_buffer(LEXY_MOV(buffer)) {} | ||
|
||
explicit BasicFile(lexy::buffer<encoding_type>&& buffer) | ||
: File(""), | ||
_buffer(LEXY_MOV(buffer)) {} | ||
|
||
const lexy::buffer<encoding_type>& buffer() const { | ||
return _buffer; | ||
} | ||
|
||
void set_location(const node_type* n, NodeLocation loc) { | ||
_map.insert(n, loc); | ||
} | ||
|
||
NodeLocation location_of(const node_type* n) const { | ||
auto result = _map.lookup(n); | ||
DRYAD_ASSERT(result != nullptr, "every Node should have a NodeLocation"); | ||
return *result; | ||
} | ||
|
||
protected: | ||
lexy::buffer<encoding_type> _buffer; | ||
dryad::node_map<const node_type, NodeLocation> _map; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#pragma once | ||
|
||
#include <cstdint> | ||
|
||
namespace ovdl { | ||
struct NodeLocation { | ||
const char* _begin = nullptr; | ||
const char* _end = nullptr; | ||
|
||
NodeLocation(); | ||
NodeLocation(const char* pos); | ||
NodeLocation(const char* begin, const char* end); | ||
|
||
NodeLocation(const NodeLocation&) noexcept; | ||
NodeLocation& operator=(const NodeLocation&); | ||
|
||
NodeLocation(NodeLocation&&); | ||
NodeLocation& operator=(NodeLocation&&); | ||
|
||
const char* begin() const; | ||
const char* end() const; | ||
|
||
bool is_synthesized() const; | ||
|
||
static NodeLocation make_from(const char* begin, const char* end); | ||
}; | ||
|
||
struct FilePosition { | ||
std::uint32_t start_line = -1, end_line = -1, start_column = -1, end_column = -1; | ||
|
||
inline constexpr bool is_empty() { return start_line == -1 && end_line == -1 && start_column == -1 && end_column == -1; } | ||
}; | ||
} |
Oops, something went wrong.