mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2026-03-12 04:37:09 +00:00
utils functions, expect, ensure, error handling refactoring (string -> string_view), std::source_location
This commit is contained in:
parent
5afbaf06ae
commit
d6a3ce1946
7 changed files with 149 additions and 29 deletions
|
|
@ -1,10 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <ranges>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace nodes {
|
||||
|
||||
|
|
@ -222,6 +225,8 @@ private:
|
|||
|
||||
class Identifier : public Node {
|
||||
public:
|
||||
static constexpr char NAME_DELIMITER = '.';
|
||||
|
||||
enum IdentifierType {
|
||||
SIMPLE_NAME,
|
||||
SIMPLE_TYPE,
|
||||
|
|
@ -251,18 +256,51 @@ public:
|
|||
|
||||
//
|
||||
|
||||
void append_before(const std::string &name) { value_ = name + "." + value_; }
|
||||
void append_before(const std::string &name) {
|
||||
value_ = name + NAME_DELIMITER + value_;
|
||||
}
|
||||
|
||||
void append_before(
|
||||
const Identifier &identifier,
|
||||
std::source_location location = std::source_location::current()) {
|
||||
error_handling::expect(identifier.type_ == type_,
|
||||
"different Identifier types on append_before",
|
||||
location);
|
||||
value_ = *identifier.get() + NAME_DELIMITER + value_;
|
||||
}
|
||||
|
||||
void append_after(const std::string &name) {
|
||||
value_ += "." + name;
|
||||
value_ += NAME_DELIMITER + name;
|
||||
}
|
||||
|
||||
void append_after(
|
||||
const Identifier &identifier,
|
||||
std::source_location location = std::source_location::current()) {
|
||||
error_handling::expect(identifier.type_ == type_,
|
||||
"different Identifier types on append_after",
|
||||
location);
|
||||
value_ += NAME_DELIMITER + *identifier.get();
|
||||
}
|
||||
|
||||
std::vector<Identifier> git_fragments() const {
|
||||
std::vector<Identifier> fragments;
|
||||
for (auto &&fragment_name :
|
||||
std::ranges::views::split(value_, NAME_DELIMITER)) {
|
||||
fragments.emplace_back(
|
||||
*this, type_,
|
||||
std::string(fragment_name.begin(), fragment_name.end()));
|
||||
}
|
||||
return fragments;
|
||||
}
|
||||
|
||||
std::pair<Identifier, Identifier> split_first() {
|
||||
const auto pos = value_.find('.');
|
||||
const auto pos = value_.find(NAME_DELIMITER);
|
||||
if (pos == std::string::npos) {
|
||||
return {Identifier(*this, type_, ""), *this};
|
||||
}
|
||||
return {Identifier(*this, type_, value_.substr(0, pos)), Identifier(*this, type_, value_.substr(pos + 1))}; // '.' is leaved out
|
||||
return {
|
||||
Identifier(*this, type_, value_.substr(0, pos)),
|
||||
Identifier(*this, type_, value_.substr(pos + 1))}; // '.' is leaved out
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "builtin_types.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
|
@ -28,7 +29,7 @@ public:
|
|||
|
||||
bool operator==(const TypeProxy &other) const;
|
||||
|
||||
bool operator!=(const TypeProxy&) const = default;
|
||||
bool operator!=(const TypeProxy &) const = default;
|
||||
|
||||
private:
|
||||
TypeProxy(TypeStorage &type_storage, size_t id)
|
||||
|
|
@ -75,13 +76,40 @@ public:
|
|||
|
||||
size_t parameters_size() const { return parameters_.size(); }
|
||||
|
||||
Type *get_parameter(size_t id) { return parameters_.at(id).get(); }
|
||||
TypeProxy get_parameter_proxy(size_t id) const { return parameters_.at(id); }
|
||||
|
||||
Type *get_parameter(size_t id) { return get_parameter_proxy(id).get(); }
|
||||
|
||||
const Type *get_parameter(size_t id) const {
|
||||
return parameters_.at(id).get();
|
||||
return get_parameter_proxy(id).get();
|
||||
}
|
||||
|
||||
TypeProxy get_parameter_proxy(size_t id) const { return parameters_.at(id); }
|
||||
// TODO: cache with map ??
|
||||
std::optional<TypeProxy>
|
||||
get_parameter_proxy_by_name(const std::string &name) const {
|
||||
const auto it = std::find_if(
|
||||
parameters_.begin(), parameters_.end(), [&name](const auto ¶meter) {
|
||||
return parameter.get()->has_annotation() &&
|
||||
*parameter.get()->get_annotation().value() == name;
|
||||
});
|
||||
|
||||
if (it != parameters_.end()) {
|
||||
return *it;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<const Type *>
|
||||
get_parameter_by_name(const std::string &name) const {
|
||||
const auto proxy = get_parameter_proxy_by_name(name);
|
||||
return proxy.has_value() ? proxy.value().get()
|
||||
: std::optional<const Type *>{};
|
||||
}
|
||||
|
||||
std::optional<Type *> get_parameter_by_name(const std::string &name) {
|
||||
auto proxy = get_parameter_proxy_by_name(name);
|
||||
return proxy.has_value() ? proxy.value().get() : std::optional<Type *>{};
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
|
|
@ -93,6 +121,8 @@ public:
|
|||
|
||||
//
|
||||
|
||||
bool has_annotation() const { return annotation_.has_value(); }
|
||||
|
||||
std::optional<std::string *> get_annotation() {
|
||||
if (annotation_.has_value()) {
|
||||
return &annotation_.value();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue