/* * Copyright (C) 2023 Riyyi * * SPDX-License-Identifier: MIT */ #pragma once #include // int64_t #include // std::function #include // std::shared_ptr #include #include #include #include // typeid #include #include #include "ruc/format/formatter.h" namespace blaze { class ASTNode; typedef std::shared_ptr ASTNodePtr; class ASTNode { public: virtual ~ASTNode() = default; std::string className() const { return typeid(*this).name(); } template bool fastIs() const = delete; virtual bool isCollection() const { return false; } virtual bool isVector() const { return false; } virtual bool isHashMap() const { return false; } virtual bool isList() const { return false; } virtual bool isString() const { return false; } virtual bool isKeyword() const { return false; } virtual bool isNumber() const { return false; } virtual bool isValue() const { return false; } virtual bool isSymbol() const { return false; } virtual bool isFunction() const { return false; } protected: ASTNode() {} }; // ----------------------------------------- class Collection : public ASTNode { public: virtual ~Collection() = default; virtual bool isCollection() const override { return true; } void addNode(ASTNodePtr node); const std::vector& nodes() const { return m_nodes; } size_t size() const { return m_nodes.size(); } bool empty() const { return m_nodes.size() == 0; } protected: Collection() {} private: std::vector m_nodes; }; // ----------------------------------------- // () class List final : public Collection { public: List() = default; virtual ~List() = default; virtual bool isCollection() const override { return false; } virtual bool isList() const override { return true; } }; // ----------------------------------------- // [] class Vector final : public Collection { public: Vector() = default; virtual ~Vector() = default; virtual bool isCollection() const override { return false; } virtual bool isVector() const override { return true; } }; // ----------------------------------------- // {} class HashMap final : public ASTNode { public: HashMap() = default; virtual ~HashMap() = default; virtual bool isHashMap() const override { return true; } void addElement(const std::string& key, ASTNodePtr value); const std::unordered_map& elements() const { return m_elements; } size_t size() const { return m_elements.size(); } bool empty() const { return m_elements.size() == 0; } private: std::unordered_map m_elements; }; // ----------------------------------------- // "string" class String final : public ASTNode { public: explicit String(const std::string& data); virtual ~String() = default; virtual bool isString() const override { return true; } const std::string& data() const { return m_data; } private: std::string m_data; }; // ----------------------------------------- // :keyword class Keyword final : public ASTNode { public: explicit Keyword(const std::string& data); virtual ~Keyword() = default; virtual bool isKeyword() const override { return true; } const std::string& keyword() const { return m_data; } private: std::string m_data; }; // ----------------------------------------- // 123 class Number final : public ASTNode { public: explicit Number(int64_t number); virtual ~Number() = default; virtual bool isNumber() const override { return true; } int64_t number() const { return m_number; } private: int64_t m_number { 0 }; }; // ----------------------------------------- // Symbols class Symbol final : public ASTNode { public: explicit Symbol(const std::string& symbol); virtual ~Symbol() = default; virtual bool isSymbol() const override { return true; } const std::string& symbol() const { return m_symbol; } private: std::string m_symbol; }; // ----------------------------------------- // true, false, nil class Value final : public ASTNode { public: explicit Value(const std::string& value); virtual ~Value() = default; virtual bool isValue() const override { return true; } const std::string& value() const { return m_value; } private: std::string m_value; }; // ----------------------------------------- using Lambda = std::function)>; class Function final : public ASTNode { public: explicit Function(Lambda lambda); virtual ~Function() = default; virtual bool isFunction() const override { return true; } Lambda lambda() const { return m_lambda; } private: Lambda m_lambda; }; // ----------------------------------------- template std::shared_ptr makePtr(Args&&... args) { return std::make_shared(std::forward(args)...); } // ----------------------------------------- // clang-format off template<> inline bool ASTNode::fastIs() const { return isCollection(); } template<> inline bool ASTNode::fastIs() const { return isList(); } template<> inline bool ASTNode::fastIs() const { return isVector(); } template<> inline bool ASTNode::fastIs() const { return isHashMap(); } template<> inline bool ASTNode::fastIs() const { return isString(); } template<> inline bool ASTNode::fastIs() const { return isKeyword(); } template<> inline bool ASTNode::fastIs() const { return isNumber(); } template<> inline bool ASTNode::fastIs() const { return isSymbol(); } template<> inline bool ASTNode::fastIs() const { return isValue(); } template<> inline bool ASTNode::fastIs() const { return isFunction(); } // clang-format on } // namespace blaze // ----------------------------------------- template<> struct ruc::format::Formatter : public Formatter { void format(Builder& builder, blaze::ASTNodePtr value) const; };