// Step 1926: LanguageSeamFrameDetector // Finds language boundary frames in a decoded polyglot stack. // // t1: detectSeams returns indices of boundary frames // t2: primarySeam returns first seam index, -1 if none // t3: seamCount counts boundary frames // t4: frameLanguages returns unique langs in order of appearance // t5: crossesBoundary detects specific language transitions #include "LanguageSeamFrameDetector.h" #include "PolyglotStackTraceDecoder.h" #include 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: "< makePolySortStack() { ws::PolyglotStackTraceDecoder dec; return dec.decode({ {1, "run", "main.py", 10}, {2, "generate", "datagen.py", 20}, {3, "sort_array", "sort.rs", 5}, {4, "partition", "sort.rs", 30}, }); } void t1(){ T(detectSeams_returns_boundary_indices); ws::LanguageSeamFrameDetector det; auto frames = makePolySortStack(); auto seams = det.detectSeams(frames); // generate(1) and sort_array(2) are at the boundary C(seams.size() == 2, "two seam frames"); C(seams[0] == 1, "index 1 (generate)"); C(seams[1] == 2, "index 2 (sort_array)"); P(); } void t2(){ T(primarySeam_first_index_or_minus1); ws::LanguageSeamFrameDetector det; auto frames = makePolySortStack(); C(det.primarySeam(frames) == 1, "primary seam at index 1"); // all-same-language: no seam ws::PolyglotStackTraceDecoder dec; auto mono = dec.decode({{1,"a","a.py",1},{2,"b","b.py",2}}); C(det.primarySeam(mono) == -1, "no seam returns -1"); P(); } void t3(){ T(seamCount); ws::LanguageSeamFrameDetector det; auto frames = makePolySortStack(); C(det.seamCount(frames) == 2, "two seam frames"); ws::PolyglotStackTraceDecoder dec; auto mono = dec.decode({{1,"a","a.rs",1},{2,"b","b.rs",2}}); C(det.seamCount(mono) == 0, "zero seams in mono stack"); P(); } void t4(){ T(frameLanguages_unique_ordered); ws::LanguageSeamFrameDetector det; auto frames = makePolySortStack(); auto langs = det.frameLanguages(frames); C(langs.size() == 2, "two languages"); C(langs[0] == "Python", "Python first"); C(langs[1] == "Rust", "Rust second"); // three-language stack ws::PolyglotStackTraceDecoder dec; auto tri = dec.decode({ {1,"a","a.py",1}, {2,"b","b.rs",1}, {3,"c","c.go",1} }); auto tl = det.frameLanguages(tri); C(tl.size() == 3, "three languages"); C(tl[0] == "Python", "Python"); C(tl[1] == "Rust", "Rust"); C(tl[2] == "Go", "Go"); P(); } void t5(){ T(crossesBoundary_specific_transitions); ws::LanguageSeamFrameDetector det; auto frames = makePolySortStack(); C( det.crossesBoundary(frames,"Python","Rust"), "Python→Rust present"); C(!det.crossesBoundary(frames,"Rust","Python"), "Rust→Python not present"); C(!det.crossesBoundary(frames,"Python","Go"), "Python→Go not present"); // reversed stack would have Rust→Python ws::PolyglotStackTraceDecoder dec; auto rev = dec.decode({ {1,"partition","sort.rs",1}, {2,"sort_array","sort.rs",1}, {3,"generate","datagen.py",1}, {4,"run","main.py",1}, }); C( det.crossesBoundary(rev,"Rust","Python"), "Rust→Python in reversed stack"); P(); } int main(){ std::cout << "Step 1926: LanguageSeamFrameDetector\n"; t1(); t2(); t3(); t4(); t5(); std::cout << "\n" << p << "/" << (p+f) << " passed\n"; return f > 0 ? 1 : 0; }