Parser tests

Signed-off-by: CHatingPython <chatingpython@gmail.com>
This commit is contained in:
CHatingPython
2026-05-25 12:18:31 +02:00
committed by CHatingPython
parent 535b088f81
commit 2cf4ff90a5
5 changed files with 70 additions and 18 deletions
+26 -11
View File
@@ -12,13 +12,15 @@ namespace furc {
namespace ast {
enum class declaration_node_t {
Function,
FunctionDeclaration,
FunctionDefinition,
Variable,
};
static inline std::ostream& operator<<(std::ostream& os, declaration_node_t type) {
switch (type) {
case declaration_node_t::Function: return os << "function";
case declaration_node_t::FunctionDeclaration: return os << "function declaration";
case declaration_node_t::FunctionDefinition: return os << "function definition";
case declaration_node_t::Variable: return os << "variable";
}
}
@@ -30,7 +32,7 @@ public:
virtual std::ostream& print(std::ostream& os) const = 0;
friend std::ostream& operator<<(std::ostream& os, const declaration_node& node) {
os << node.type() << " declaration";
os << node.type();
return node.print(os);
}
};
@@ -46,15 +48,28 @@ class function_declarartion_node : public declaration_node {
public:
function_declarartion_node(front::token name)
: m_name(name) {}
function_declarartion_node(front::token name, function_body&& body)
: m_name(name), m_body(std::move(body)) {}
public:
declaration_node_t type() const override { return declaration_node_t::Function; }
declaration_node_t type() const override { return declaration_node_t::FunctionDeclaration; }
front::token name() const { return m_name; }
public:
std::ostream& print(std::ostream& os) const override { return os << ": " << m_name; }
protected:
front::token m_name;
};
class function_definition_node : public function_declarartion_node {
public:
function_definition_node(front::token name, function_body_handle&& body)
: function_declarartion_node(name), m_body(std::move(body)) {}
public:
declaration_node_t type() const override { return declaration_node_t::FunctionDefinition; }
const function_body_handle& body() const { return m_body; }
public:
std::ostream& print(std::ostream& os) const override {
os << ": " << m_name;
if (m_body.has_value()) {
os << ": " << m_name.value;
if (m_body.present()) {
os << '\n' << m_body->begin << ": begin:";
for (const auto& entry : m_body->statements) {
os << '\n' << entry;
@@ -64,8 +79,8 @@ public:
return os;
}
private:
front::token m_name;
std::optional<function_body> m_body;
front::token m_name;
function_body_handle m_body;
};
} // namespace ast
+8 -3
View File
@@ -115,6 +115,10 @@ public:
handle(location location, std::shared_ptr<U> value)
: m_location(location), m_value(value) {}
template <typename U, typename = std::enable_if_t<std::is_base_of_v<U, value_type>>>
handle(const handle<U*, Error>& other)
: m_location(other.m_location), m_value(std::dynamic_pointer_cast<value_type>(other.m_value)) {}
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<value_type, Args...>>>
handle(location location, Args&&... args)
: m_location(location), m_value(std::make_shared<value_type>(std::forward<Args>(args)...)) {}
@@ -133,7 +137,8 @@ public:
other.m_value = nullptr;
}
template <typename U = value_type, typename = std::enable_if_t<std::is_base_of_v<value_type, U>>>
template <typename U = value_type,
typename = std::enable_if_t<std::is_base_of_v<value_type, U> || std::is_base_of_v<U, value_type>>>
handle(handle<U*, Error>&& other) noexcept // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
: m_location(other.m_location), m_value(std::move(other.m_value)), m_error(std::move(other.m_error)) {
other.m_value = nullptr;
@@ -172,8 +177,8 @@ public:
reference operator*() { return *m_value; }
const_reference operator*() const { return *m_value; }
pointer operator->() { return m_value; }
const_pointer operator->() const { return m_value; }
pointer operator->() { return m_value.get(); }
const_pointer operator->() const { return m_value.get(); }
public:
friend std::ostream& operator<<(std::ostream& os, const handle& result) {
os << result.m_location << ": ";