#pragma once // Step 1949: CompilerIRNode + IRNodePipeline // // CompilerIRNode — IR node with kind enum and payload // IRNodePipeline — queue with push/pop/peek/drain #include #include #include #include namespace whetstone { enum class IRNodeKind { Source, Token, AST, TypedAST, OptimizedAST, Bytecode }; inline std::string irKindName(IRNodeKind k) { switch (k) { case IRNodeKind::Source: return "Source"; case IRNodeKind::Token: return "Token"; case IRNodeKind::AST: return "AST"; case IRNodeKind::TypedAST: return "TypedAST"; case IRNodeKind::OptimizedAST: return "OptimizedAST"; case IRNodeKind::Bytecode: return "Bytecode"; default: return "Unknown"; } } struct CompilerIRNode { IRNodeKind kind; std::string payload; // serialized content at this stage std::string sourceId; // identifier of originating source unit CompilerIRNode() : kind(IRNodeKind::Source) {} CompilerIRNode(IRNodeKind k, std::string p, std::string s = "") : kind(k), payload(std::move(p)), sourceId(std::move(s)) {} }; class IRNodePipeline { public: void push(const CompilerIRNode& node) { queue_.push_back(node); } CompilerIRNode pop() { if (queue_.empty()) throw std::underflow_error("IRNodePipeline is empty"); CompilerIRNode node = queue_.front(); queue_.pop_front(); return node; } const CompilerIRNode& peek() const { if (queue_.empty()) throw std::underflow_error("IRNodePipeline is empty"); return queue_.front(); } std::vector drain() { std::vector result(queue_.begin(), queue_.end()); queue_.clear(); return result; } bool empty() const { return queue_.empty(); } int size() const { return static_cast(queue_.size()); } void clear() { queue_.clear(); } private: std::deque queue_; }; } // namespace whetstone