Skip to content

Commit

Permalink
Initial conversion commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Spartan322 committed Nov 28, 2023
1 parent 853b186 commit 6d7df1c
Show file tree
Hide file tree
Showing 32 changed files with 1,154 additions and 80 deletions.
105 changes: 105 additions & 0 deletions include/openvic-dataloader/AbstractSyntaxTree.hpp
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;
};
}
144 changes: 144 additions & 0 deletions include/openvic-dataloader/DiagnosticLogger.hpp
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;
};
}
71 changes: 71 additions & 0 deletions include/openvic-dataloader/File.hpp
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;
};
}
33 changes: 33 additions & 0 deletions include/openvic-dataloader/NodeLocation.hpp
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; }
};
}
Loading

0 comments on commit 6d7df1c

Please sign in to comment.