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>
This commit is contained in:
89
editor/tests/step1950_test.cpp
Normal file
89
editor/tests/step1950_test.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
// 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;
|
||||
}
|
||||
Reference in New Issue
Block a user