Files
whetstone_DSL/editor/tests/step1950_test.cpp
Bill 0f6d10e39a Sprint 284: poly-compiler (steps 1948–1952)
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>
2026-03-01 22:32:40 -07:00

90 lines
3.2 KiB
C++

// Step 1950: CompilerPhaseRouter
//
// t1: registerRoute and routeCount
// t2: routePhase returns correct phaseId
// t3: routePhase throws on unregistered kind with no fallback
// t4: fallback phaseId used when no route matches
// t5: hasRoute and registeredKinds
#include "CompilerPhaseRouter.h"
#include <iostream>
namespace ws = whetstone;
static int p=0,f=0;
#define T(n) { std::cout<<" "<<#n<<"... "; }
#define P() { std::cout<<"PASS\n"; ++p; }
#define F(m) { std::cout<<"FAIL: "<<m<<"\n"; ++f; }
#define C(c,m) if(!(c)){F(m);return;}
void t1(){
T(registerRoute_and_routeCount);
ws::CompilerPhaseRouter r;
C(r.routeCount() == 0, "empty initially");
r.registerRoute(ws::IRNodeKind::Source, "lex");
r.registerRoute(ws::IRNodeKind::Token, "parse");
C(r.routeCount() == 2, "two routes");
P();
}
void t2(){
T(routePhase_returns_correct_phaseId);
ws::CompilerPhaseRouter r;
r.registerRoute(ws::IRNodeKind::Source, "lex");
r.registerRoute(ws::IRNodeKind::Token, "parse");
r.registerRoute(ws::IRNodeKind::AST, "typecheck");
r.registerRoute(ws::IRNodeKind::TypedAST, "optimize");
r.registerRoute(ws::IRNodeKind::OptimizedAST, "emit");
C(r.routePhase(ws::IRNodeKind::Source) == "lex", "Source→lex");
C(r.routePhase(ws::IRNodeKind::Token) == "parse", "Token→parse");
C(r.routePhase(ws::IRNodeKind::AST) == "typecheck", "AST→typecheck");
C(r.routePhase(ws::IRNodeKind::TypedAST) == "optimize", "TypedAST→optimize");
C(r.routePhase(ws::IRNodeKind::OptimizedAST) == "emit", "OptimizedAST→emit");
P();
}
void t3(){
T(routePhase_throws_on_unregistered_no_fallback);
ws::CompilerPhaseRouter r;
r.registerRoute(ws::IRNodeKind::Source, "lex");
bool threw = false;
try { r.routePhase(ws::IRNodeKind::Bytecode); }
catch (const std::out_of_range&) { threw = true; }
C(threw, "throws on unregistered kind");
P();
}
void t4(){
T(fallback_phaseId_used_when_no_route_matches);
ws::CompilerPhaseRouter r;
r.registerRoute(ws::IRNodeKind::Source, "lex");
r.setFallback("unknown-phase");
C(r.routePhase(ws::IRNodeKind::Source) == "lex", "explicit route wins");
C(r.routePhase(ws::IRNodeKind::Bytecode)== "unknown-phase", "fallback used");
r.clearFallback();
bool threw = false;
try { r.routePhase(ws::IRNodeKind::Bytecode); }
catch (const std::out_of_range&) { threw = true; }
C(threw, "throws after clearFallback");
P();
}
void t5(){
T(hasRoute_and_registeredKinds);
ws::CompilerPhaseRouter r;
r.registerRoute(ws::IRNodeKind::Source, "lex");
r.registerRoute(ws::IRNodeKind::Token, "parse");
C( r.hasRoute(ws::IRNodeKind::Source), "Source registered");
C( r.hasRoute(ws::IRNodeKind::Token), "Token registered");
C(!r.hasRoute(ws::IRNodeKind::AST), "AST not registered");
auto kinds = r.registeredKinds();
C(kinds.size() == 2, "two registered kinds");
P();
}
int main(){
std::cout << "Step 1950: CompilerPhaseRouter\n";
t1(); t2(); t3(); t4(); t5();
std::cout << "\n" << p << "/" << (p+f) << " passed\n";
return f > 0 ? 1 : 0;
}