Files
whetstone_DSL/editor/tests/step366_test.cpp

179 lines
5.7 KiB
C++

// Step 366: WAT Generator (12 tests)
#include <cassert>
#include <iostream>
#include <string>
#include "Pipeline.h"
#include "ast/WatGenerator.h"
#include "ast/WatParser.h"
static int parenBalance(const std::string& s) {
int d = 0;
for (char c : s) {
if (c == '(') ++d;
if (c == ')') --d;
}
return d;
}
int main() {
int passed = 0;
// Test 1: function generation
{
WatGenerator gen;
Function fn("f1", "add");
auto* p1 = new Parameter("p1", "x");
p1->setChild("type", new PrimitiveType("t1", "int"));
fn.addChild("parameters", p1);
fn.setChild("returnType", new PrimitiveType("rt1", "int"));
auto out = gen.generate(&fn);
assert(out.find("(func $add") != std::string::npos);
assert(out.find("(param $x i32)") != std::string::npos);
assert(out.find("(result i32)") != std::string::npos);
std::cout << "Test 1 PASSED: function generation\n";
passed++;
}
// Test 2: S-expression formatting for module
{
WatGenerator gen;
Module mod("m1", "wat_mod", "wat");
auto out = gen.generate(&mod);
assert(out.find("(module") == 0);
assert(out.back() == ')');
std::cout << "Test 2 PASSED: module s-expression formatting\n";
passed++;
}
// Test 3: type mapping
{
WatGenerator gen;
Function fn("f1", "types");
auto* p = new Parameter("p1", "a");
p->setChild("type", new PrimitiveType("t1", "double"));
fn.addChild("parameters", p);
fn.setChild("returnType", new PrimitiveType("rt", "long"));
auto out = gen.generate(&fn);
assert(out.find("f64") != std::string::npos);
assert(out.find("i64") != std::string::npos);
std::cout << "Test 3 PASSED: type mapping\n";
passed++;
}
// Test 4: arithmetic to stack instruction
{
WatGenerator gen;
BinaryOperation add;
add.id = "b1";
add.op = "+";
add.setChild("left", new VariableReference("vr1", "x"));
add.setChild("right", new VariableReference("vr2", "y"));
auto out = gen.generate(&add);
assert(out.find("i32.add") != std::string::npos);
assert(out.find("local.get $x") != std::string::npos);
std::cout << "Test 4 PASSED: arithmetic stack lowering\n";
passed++;
}
// Test 5: if/else to WAT if
{
WatGenerator gen;
IfStatement stmt;
stmt.id = "if1";
stmt.setChild("condition", new BooleanLiteral("b1", true));
stmt.addChild("thenBranch", new IntegerLiteral("i1", 1));
stmt.addChild("elseBranch", new IntegerLiteral("i2", 0));
auto out = gen.generate(&stmt);
assert(out.find("(if") != std::string::npos);
assert(out.find("(then") != std::string::npos);
assert(out.find("(else") != std::string::npos);
std::cout << "Test 5 PASSED: if/else generation\n";
passed++;
}
// Test 6: function call to call instruction
{
WatGenerator gen;
FunctionCall call;
call.id = "c1";
call.functionName = "helper";
auto out = gen.generate(&call);
assert(out.find("call $helper") != std::string::npos);
std::cout << "Test 6 PASSED: function call generation\n";
passed++;
}
// Test 7: export declaration
{
WatGenerator gen;
PragmaDirective exp("p1", "export");
auto out = gen.generate(&exp);
assert(out.find("(export") != std::string::npos);
std::cout << "Test 7 PASSED: export generation\n";
passed++;
}
// Test 8: import declaration
{
WatGenerator gen;
Module mod("m1", "imports", "wat");
mod.addChild("imports", new Import("i1", "env.print", "runtime", ""));
auto out = gen.generate(&mod);
assert(out.find("(import") != std::string::npos);
assert(out.find("\"env\"") != std::string::npos);
std::cout << "Test 8 PASSED: import generation\n";
passed++;
}
// Test 9: Semanno comments with ;; prefix
{
WatGenerator gen;
Function fn("f1", "owned");
fn.addChild("annotations", new OwnerAnnotation("a1", "Manual"));
auto out = gen.generate(&fn);
assert(out.find(";; @owner(Manual)") != std::string::npos);
std::cout << "Test 9 PASSED: semanno-style comment prefix\n";
passed++;
}
// Test 10: cross-language pipeline Python -> WAT
{
Pipeline p;
std::string py = "def add(x, y):\n return x + y\n";
auto result = p.run(py, "python", "wat");
assert(result.success);
assert(result.generatedCode.find("(module") != std::string::npos);
std::cout << "Test 10 PASSED: Python->WAT pipeline route\n";
passed++;
}
// Test 11: round-trip parse -> generate -> parse
{
std::string wat = "(module (func $add (param $x i32) (param $y i32) (result i32) i32.add))";
auto parsed = WatParser::parseWat(wat);
WatGenerator gen;
std::string out = gen.generate(parsed.get());
auto reparsed = WatParser::parseWat(out);
assert(!reparsed->getChildren("functions").empty());
std::cout << "Test 11 PASSED: parse/generate/parse roundtrip\n";
passed++;
}
// Test 12: parentheses balanced in generated module
{
WatGenerator gen;
Module mod("m1", "bal", "wat");
Function* fn = new Function("f1", "noop");
mod.addChild("functions", fn);
auto out = gen.generate(&mod);
assert(parenBalance(out) == 0);
std::cout << "Test 12 PASSED: balanced parentheses\n";
passed++;
}
std::cout << "\nResults: " << passed << "/12\n";
assert(passed == 12);
return 0;
}