refactor(AST): improve literals

Changed literal node to templated class and literals to aliases.
This commit is contained in:
2026-06-03 14:13:28 +02:00
parent 52537e0955
commit d50bfc868f
6 changed files with 79 additions and 154 deletions
+20 -10
View File
@@ -4,6 +4,7 @@
#include "furc/diag.hpp"
#include "furlang/result.hpp"
#include <cstdint>
#include <memory>
#include <vector>
@@ -56,14 +57,6 @@ class node;
template <typename T>
using node_r = furlang::result<std::shared_ptr<T>, error>;
class literal_node;
/**
* @brief Alias for handle to literal_node.
* @see literal_node
*/
using literal_node_r = node_r<literal_node>;
class expression_node;
/**
@@ -96,7 +89,21 @@ class program_node;
*/
using program_node_r = node_r<program_node>;
class string_literal_node;
/**
* @brief Literal node type.
*/
enum class literal_node_t {
String, /**< String literal. */
Integer, /**< Integer literal. */
};
template <typename, literal_node_t>
class literal_node;
/**
* @brief String literal AST node.
*/
using string_literal_node = literal_node<std::string, literal_node_t::String>;
/**
* @brief Alias for handle to string_literal_node.
@@ -104,7 +111,10 @@ class string_literal_node;
*/
using string_literal_node_r = node_r<string_literal_node>;
class integer_literal_node;
/**
* @brief Integer literal AST node.
*/
using integer_literal_node = literal_node<std::uint64_t, literal_node_t::Integer>;
/**
* @brief Alias for handle to integer_literal_node.
+46 -89
View File
@@ -1,33 +1,58 @@
// NOLINTBEGIN(portability-template-virtual-member-function)
#ifndef FURC_AST_LITERAL_HPP
#define FURC_AST_LITERAL_HPP
#include "furc/ast/expression.hpp"
#include "furc/ast/node.hpp"
#include "furc/front/token.hpp"
namespace furc {
namespace ast {
/**
* @brief Literal node type.
*/
enum class literal_node_t {
String, /**< String literal. */
Integer, /**< Integer literal. */
};
/**
* @brief Literal AST node.
*/
template <typename ValueType, literal_node_t LiteralType>
class literal_node : public expression_node {
public:
using value_type = std::remove_reference_t<ValueType>; /**< Value type. */
public:
/**
* @brief Construct a new literal AST node.
*
* @param location Node location.
*/
template <typename = std::enable_if_t<std::is_default_constructible_v<ValueType>>>
literal_node(struct location location)
: expression_node(location) {}
/**
* @brief Construct a new literal AST node.
*
* @param location Node location.
* @param value Node value to copy.
*/
literal_node(struct location location, const value_type& value)
: expression_node(location), p_value(value) {}
/**
* @brief Construct a new literal AST node.
*
* @param location Node location.
* @param value Node value to move.
*/
literal_node(struct location location, value_type&& value)
: expression_node(location), p_value(std::move(value)) {}
/**
* @brief Construct a new literal AST node.
*
* @param location Node location.
* @param args Arguments to call value constructor with.
*/
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<ValueType, Args...>>>
literal_node(struct location location, Args&&... args)
: expression_node(location), p_value(std::forward<Args>(args)...) {}
public:
/**
* @brief Returns this node's category.
@@ -48,98 +73,30 @@ public:
*
* @return The literal type.
*/
virtual literal_node_t literal_type() const = 0;
protected:
bool equal(const node& rhs) const override;
};
/**
* @brief String literal AST node.
*/
class string_literal_node final : public literal_node {
public:
using value_type = furlang::result<std::string_view, error>; /**< Value type. */
public:
/**
* @brief Construct a new string literal node object from a handle.
*
* @param location Node location.
* @param value A string view result.
*/
string_literal_node(struct location location, value_type&& value)
: literal_node(location), m_value(std::move(value)) {}
public:
/**
* @brief Returns this node's literal type.
*
* @return literal_node_t::String.
*/
literal_node_t literal_type() const override { return literal_node_t::String; }
literal_node_t literal_type() const { return LiteralType; }
/**
* @brief Returns this node's value.
*
* @return A string view result.
*/
const value_type& value() const { return m_value; }
const value_type& value() const { return p_value; }
public:
void accept(visitor& visitor) const override;
void accept(visitor& visitor) const override { visitor.visit(*this); }
std::ostream& print(std::ostream& os) const override;
std::ostream& print(std::ostream& os) const override { return os << p_value; }
protected:
bool equal(const node& rhs) const override;
private:
value_type m_value;
};
/**
* @brief Integer literal AST node.
*/
class integer_literal_node final : public literal_node {
public:
using value_type = furlang::result<front::integer_token, error>; /**< Value type. */
public:
/**
* @brief Construct a new integer literal node object from a handle.
*
* @param location Node location.
* @param value An integer result.
*/
integer_literal_node(struct location location, value_type&& value)
: literal_node(location), m_value(std::move(value)) {}
public:
/**
* @brief Returns this node's literal type.
*
* @return literal_node_t::Integer.
*/
literal_node_t literal_type() const override { return literal_node_t::Integer; }
/**
* @brief Returns this node's value.
*
* @return An integer result.
*/
const value_type& value() const { return m_value; }
/**
* @brief Compares this node with an integer token for equality.
*
* @param integer Integer token to compare against.
* @return true if the integer token is equal to this node.
*/
bool operator==(front::integer_token integer) const { return m_value == integer; }
public:
void accept(visitor& visitor) const override;
std::ostream& print(std::ostream& os) const override;
bool equal(const node& rhsNode) const override {
const auto& rhs = dynamic_cast<const literal_node&>(rhsNode);
return literal_type() == rhs.literal_type() && p_value == rhs.p_value;
}
protected:
bool equal(const node& rhs) const override;
private:
value_type m_value;
value_type p_value; /**< Node value. */
};
} // namespace ast
} // namespace furc
#endif // FURC_AST_LITERAL_HPP
#endif // FURC_AST_LITERAL_HPP
// NOLINTEND(portability-template-virtual-member-function)
-1
View File
@@ -59,7 +59,6 @@ private:
ast::declaration_node_r parse_declaration();
ast::statement_node_r parse_statement();
ast::expression_node_r parse_expression(std::uint32_t precedence = 16);
ast::literal_node_r parse_literal();
ast::expression_node_r parse_expression_primary();
ast::expression_node_r parse_expression_unary(std::uint32_t precedence);