5-phase compiler pipeline: C++(lex)→Haskell(parse)→Rust(typecheck)→Lisp(optimize)→Go(emit) Components: - CompilerPhaseSpec + CompilerPhaseRegistry: phase descriptors sorted by order field - CompilerIRNode + IRNodePipeline: IR node kinds (Source→Token→AST→TypedAST→OptimizedAST→Bytecode) + queue - CompilerPhaseRouter: IRNodeKind→phaseId routing with optional fallback - CompilerPipelineRunner: chains PhaseTransform functions in order, supports runUpTo 26/26 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
80 lines
2.1 KiB
C++
80 lines
2.1 KiB
C++
#pragma once
|
|
// Step 1949: CompilerIRNode + IRNodePipeline
|
|
//
|
|
// CompilerIRNode — IR node with kind enum and payload
|
|
// IRNodePipeline — queue with push/pop/peek/drain
|
|
|
|
#include <deque>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
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<CompilerIRNode> drain() {
|
|
std::vector<CompilerIRNode> result(queue_.begin(), queue_.end());
|
|
queue_.clear();
|
|
return result;
|
|
}
|
|
|
|
bool empty() const { return queue_.empty(); }
|
|
int size() const { return static_cast<int>(queue_.size()); }
|
|
void clear() { queue_.clear(); }
|
|
|
|
private:
|
|
std::deque<CompilerIRNode> queue_;
|
|
};
|
|
|
|
} // namespace whetstone
|