From c7c1f5727f8a9fb9c27a4b35d1240a551da66d34 Mon Sep 17 00:00:00 2001 From: Bill Date: Mon, 16 Feb 2026 09:58:31 -0700 Subject: [PATCH] Step 368: Add WAT cross-language projection tests --- editor/CMakeLists.txt | 9 ++ editor/tests/step368_test.cpp | 162 ++++++++++++++++++++++++++++++++++ progress.md | 34 +++++++ 3 files changed, 205 insertions(+) create mode 100644 editor/tests/step368_test.cpp diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 7bc63d3..b595b78 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -2191,4 +2191,13 @@ target_link_libraries(step367_test PRIVATE tree_sitter_javascript tree_sitter_typescript tree_sitter_java tree_sitter_rust tree_sitter_go) +add_executable(step368_test tests/step368_test.cpp) +target_include_directories(step368_test PRIVATE src) +target_link_libraries(step368_test PRIVATE + nlohmann_json::nlohmann_json + unofficial::tree-sitter::tree-sitter + tree_sitter_python tree_sitter_cpp tree_sitter_elisp + tree_sitter_javascript tree_sitter_typescript + tree_sitter_java tree_sitter_rust tree_sitter_go) + # Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies) diff --git a/editor/tests/step368_test.cpp b/editor/tests/step368_test.cpp new file mode 100644 index 0000000..6bb34f4 --- /dev/null +++ b/editor/tests/step368_test.cpp @@ -0,0 +1,162 @@ +// Step 368: WAT Cross-Language Projection (12 tests) + +#include +#include +#include +#include +#include "Pipeline.h" +#include "CrossLanguageProjector.h" +#include "SemannoFormat.h" +#include "ast/WatParser.h" + +static bool contains(const std::string& text, const std::string& token) { + return text.find(token) != std::string::npos; +} + +int main() { + int passed = 0; + + // Test 1: Python function -> WAT + { + Pipeline p; + std::string py = "def add(x, y):\n return x + y\n"; + auto res = p.run(py, "python", "wat"); + assert(res.success); + assert(contains(res.generatedCode, "(module")); + assert(contains(res.generatedCode, "(func")); + std::cout << "Test 1 PASSED: Python -> WAT\n"; + passed++; + } + + // Test 2: C function -> WAT + { + Pipeline p; + std::string csrc = "int add(int a, int b) { return a + b; }\n"; + auto res = p.run(csrc, "c", "wat"); + assert(res.success); + assert(contains(res.generatedCode, "(module")); + std::cout << "Test 2 PASSED: C -> WAT\n"; + passed++; + } + + // Test 3: WAT -> Python + { + Pipeline p; + std::string wat = "(module (func $add (param $x i32) (param $y i32) (result i32)))"; + auto res = p.run(wat, "wat", "python"); + assert(res.success); + assert(contains(res.generatedCode, "def")); + std::cout << "Test 3 PASSED: WAT -> Python\n"; + passed++; + } + + // Test 4: WAT -> C + { + Pipeline p; + std::string wat = "(module (func $f (result i32)))"; + auto res = p.run(wat, "wat", "c"); + assert(res.success); + assert(!res.generatedCode.empty()); + std::cout << "Test 4 PASSED: WAT -> C\n"; + passed++; + } + + // Test 5: WAT -> Rust + { + Pipeline p; + std::string wat = "(module (func $f (result i32)))"; + auto res = p.run(wat, "wat", "rust"); + assert(res.success); + assert(contains(res.generatedCode, "fn")); + std::cout << "Test 5 PASSED: WAT -> Rust\n"; + passed++; + } + + // Test 6: Java -> WAT + { + Pipeline p; + std::string java = "class A { int add(int x, int y) { return x + y; } }\n"; + auto res = p.run(java, "java", "wat"); + assert(res.success); + assert(contains(res.generatedCode, "(module")); + std::cout << "Test 6 PASSED: Java -> WAT\n"; + passed++; + } + + // Test 7: Python -> WAT -> Python keeps function identity + { + Pipeline p; + std::string py = "def add(x, y):\n return x + y\n"; + auto toWat = p.run(py, "python", "wat"); + assert(toWat.success); + auto back = p.run(toWat.generatedCode, "wat", "python"); + assert(back.success); + assert(contains(back.generatedCode, "add")); + std::cout << "Test 7 PASSED: Python -> WAT -> Python identity\n"; + passed++; + } + + // Test 8: memory annotation preserved across WAT <-> C + { + Module watMod("m1", "watmod", "wat"); + auto* fn = new Function("f1", "grow"); + fn->addChild("annotations", new OwnerAnnotation("a1", "Manual")); + watMod.addChild("functions", fn); + + CrossLanguageProjector projector; + auto cMod = projector.project(&watMod, "c"); + auto back = projector.project(cMod.get(), "wat"); + assert(projector.annotationsPreserved(&watMod, back.get())); + std::cout << "Test 8 PASSED: WAT<->C annotation preservation\n"; + passed++; + } + + // Test 9: WAT imports survive projection metadata to C + { + auto wat = WatParser::parseWat("(module (import \"env\" \"print\" (func $print)))"); + CrossLanguageProjector projector; + auto cMod = projector.project(wat.get(), "c"); + assert(!cMod->getChildren("imports").empty()); + std::cout << "Test 9 PASSED: imports survive projection metadata\n"; + passed++; + } + + // Test 10: multi-function WAT module -> C output non-empty + { + Pipeline p; + std::string wat = "(module (func $a (result i32)) (func $b (result i32)))"; + auto res = p.run(wat, "wat", "c"); + assert(res.success); + assert(!res.generatedCode.empty()); + std::cout << "Test 10 PASSED: multi-function WAT -> C output\n"; + passed++; + } + + // Test 11: Semanno roundtrip on WAT-style annotation + { + ExecAnnotation exec; + exec.id = "e1"; + exec.mode = "stack"; + std::string line = SemannoEmitter::emit(&exec); + auto parsed = SemannoParser::parse(line); + assert(parsed.type == "exec"); + assert(parsed.properties["mode"] == "stack"); + std::cout << "Test 11 PASSED: semanno roundtrip\n"; + passed++; + } + + // Test 12: pipeline run with WAT source succeeds + { + Pipeline p; + std::string wat = "(module (func $f (result i32)))"; + auto res = p.run(wat, "wat", "wat"); + assert(res.success); + assert(contains(res.generatedCode, "(module")); + std::cout << "Test 12 PASSED: pipeline WAT source run\n"; + passed++; + } + + std::cout << "\nResults: " << passed << "/12\n"; + assert(passed == 12); + return 0; +} diff --git a/progress.md b/progress.md index 03e62c0..45923a1 100644 --- a/progress.md +++ b/progress.md @@ -2328,6 +2328,40 @@ memory-layout signals, plus WAT memory-strategy defaults. - `editor/src/AnnotationInference.h` remains within header size limit (`589` lines <= `600`) +### Step 368: WAT Cross-Language Projection +**Status:** PASS (12/12 tests) + +Added cross-language WAT projection coverage across pipeline and direct +projection paths (Python/C/Rust/Java), including annotation and metadata +preservation checks. + +**Files created:** +- `editor/tests/step368_test.cpp` — 12 tests covering: + 1. Python -> WAT + 2. C -> WAT + 3. WAT -> Python + 4. WAT -> C + 5. WAT -> Rust + 6. Java -> WAT + 7. Python -> WAT -> Python identity check + 8. WAT <-> C annotation preservation + 9. import metadata preservation through projection + 10. multi-function WAT -> C output generation + 11. Semanno roundtrip on projected annotation data + 12. WAT-source pipeline run success + +**Files modified:** +- `editor/CMakeLists.txt` — `step368_test` target + +**Verification run:** +- `step368_test` — PASS (12/12) new step coverage +- `step367_test` — PASS (12/12) regression coverage +- `step366_test` — PASS (12/12) regression coverage + +**Architecture gate check:** +- `editor/tests/step368_test.cpp` remains within project file-size guidance + for test artifacts (`162` lines) + # Roadmap Planning — Sprints 12-25+ ## Status: Planning Complete (Sprints 12-19 detailed, 20-25 in roadmap.md)