Step 67 TDD test: Optimization annotations
Tests HotColdAnnotation, InlineAnnotation, PureAnnotation, ConstExprAnnotation classes exist. Tests C++ generation: @Hot->__attribute__((hot)), @Cold->__attribute__((cold)), @Inline(Always)->always_inline, @Pure->[[nodiscard]], @ConstExpr->constexpr. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -190,6 +190,9 @@ target_include_directories(step65_test PRIVATE src)
|
|||||||
add_executable(step66_test tests/step66_test.cpp)
|
add_executable(step66_test tests/step66_test.cpp)
|
||||||
target_include_directories(step66_test PRIVATE src)
|
target_include_directories(step66_test PRIVATE src)
|
||||||
|
|
||||||
|
add_executable(step67_test tests/step67_test.cpp)
|
||||||
|
target_include_directories(step67_test PRIVATE src)
|
||||||
|
|
||||||
add_executable(whetstone_editor src/main.cpp)
|
add_executable(whetstone_editor src/main.cpp)
|
||||||
target_include_directories(whetstone_editor PRIVATE src)
|
target_include_directories(whetstone_editor PRIVATE src)
|
||||||
# find_package(SDL2 REQUIRED) # Commented out for now to avoid build issues
|
# find_package(SDL2 REQUIRED) # Commented out for now to avoid build issues
|
||||||
|
|||||||
203
editor/tests/step67_test.cpp
Normal file
203
editor/tests/step67_test.cpp
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
// Step 67 TDD Test: Optimization annotations
|
||||||
|
//
|
||||||
|
// Tests optimization annotation classes and their C++ code generation:
|
||||||
|
// 1. @Hot → C++ __attribute__((hot))
|
||||||
|
// 2. @Cold → C++ __attribute__((cold))
|
||||||
|
// 3. @Inline(Always) → C++ [[gnu::always_inline]]
|
||||||
|
// 4. @Pure → C++ [[nodiscard]]
|
||||||
|
// 5. @ConstExpr → C++ constexpr
|
||||||
|
// 6. All optimization annotation classes exist and inherit from Annotation
|
||||||
|
//
|
||||||
|
// Will fail until optimization annotation classes are created and
|
||||||
|
// CppGenerator handles them.
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <cassert>
|
||||||
|
#include "ast/Generator.h"
|
||||||
|
|
||||||
|
static bool contains(const std::string& haystack, const std::string& needle) {
|
||||||
|
return haystack.find(needle) != std::string::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int passed = 0;
|
||||||
|
int failed = 0;
|
||||||
|
|
||||||
|
// --- Test 1: HotColdAnnotation exists ---
|
||||||
|
{
|
||||||
|
HotColdAnnotation anno;
|
||||||
|
anno.hint = "Hot";
|
||||||
|
Annotation* base = &anno;
|
||||||
|
(void)base;
|
||||||
|
assert(anno.hint == "Hot" && "Should store hint");
|
||||||
|
|
||||||
|
std::cout << "Test 1 PASS: HotColdAnnotation exists" << std::endl;
|
||||||
|
++passed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Test 2: InlineAnnotation exists ---
|
||||||
|
{
|
||||||
|
InlineAnnotation anno;
|
||||||
|
anno.mode = "Always";
|
||||||
|
Annotation* base = &anno;
|
||||||
|
(void)base;
|
||||||
|
assert(anno.mode == "Always" && "Should store mode");
|
||||||
|
|
||||||
|
std::cout << "Test 2 PASS: InlineAnnotation exists" << std::endl;
|
||||||
|
++passed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Test 3: PureAnnotation exists ---
|
||||||
|
{
|
||||||
|
PureAnnotation anno;
|
||||||
|
Annotation* base = &anno;
|
||||||
|
(void)base;
|
||||||
|
|
||||||
|
std::cout << "Test 3 PASS: PureAnnotation exists" << std::endl;
|
||||||
|
++passed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Test 4: ConstExprAnnotation exists ---
|
||||||
|
{
|
||||||
|
ConstExprAnnotation anno;
|
||||||
|
Annotation* base = &anno;
|
||||||
|
(void)base;
|
||||||
|
|
||||||
|
std::cout << "Test 4 PASS: ConstExprAnnotation exists" << std::endl;
|
||||||
|
++passed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Test 5: @Hot function → C++ __attribute__((hot)) ---
|
||||||
|
{
|
||||||
|
Module mod("m1", "Perf", "cpp");
|
||||||
|
Function* fn = new Function("f1", "hotPath");
|
||||||
|
PrimitiveType* retType = new PrimitiveType("t1", "void");
|
||||||
|
fn->setChild("returnType", retType);
|
||||||
|
|
||||||
|
HotColdAnnotation* anno = new HotColdAnnotation();
|
||||||
|
anno->hint = "Hot";
|
||||||
|
fn->addChild("annotations", anno);
|
||||||
|
mod.addChild("functions", fn);
|
||||||
|
|
||||||
|
CppGenerator gen;
|
||||||
|
std::string output = gen.generate(&mod);
|
||||||
|
|
||||||
|
assert((contains(output, "__attribute__((hot))") || contains(output, "[[likely]]")) &&
|
||||||
|
"@Hot should produce __attribute__((hot)) or [[likely]]");
|
||||||
|
|
||||||
|
std::cout << "Test 5 PASS: @Hot → C++ hot attribute" << std::endl;
|
||||||
|
++passed;
|
||||||
|
|
||||||
|
delete anno;
|
||||||
|
delete retType;
|
||||||
|
delete fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Test 6: @Cold function → C++ __attribute__((cold)) ---
|
||||||
|
{
|
||||||
|
Module mod("m1", "Perf", "cpp");
|
||||||
|
Function* fn = new Function("f1", "errorHandler");
|
||||||
|
PrimitiveType* retType = new PrimitiveType("t1", "void");
|
||||||
|
fn->setChild("returnType", retType);
|
||||||
|
|
||||||
|
HotColdAnnotation* anno = new HotColdAnnotation();
|
||||||
|
anno->hint = "Cold";
|
||||||
|
fn->addChild("annotations", anno);
|
||||||
|
mod.addChild("functions", fn);
|
||||||
|
|
||||||
|
CppGenerator gen;
|
||||||
|
std::string output = gen.generate(&mod);
|
||||||
|
|
||||||
|
assert((contains(output, "__attribute__((cold))") || contains(output, "[[unlikely]]")) &&
|
||||||
|
"@Cold should produce __attribute__((cold)) or [[unlikely]]");
|
||||||
|
|
||||||
|
std::cout << "Test 6 PASS: @Cold → C++ cold attribute" << std::endl;
|
||||||
|
++passed;
|
||||||
|
|
||||||
|
delete anno;
|
||||||
|
delete retType;
|
||||||
|
delete fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Test 7: @Inline(Always) → C++ always_inline ---
|
||||||
|
{
|
||||||
|
Module mod("m1", "Perf", "cpp");
|
||||||
|
Function* fn = new Function("f1", "fastMath");
|
||||||
|
PrimitiveType* retType = new PrimitiveType("t1", "int");
|
||||||
|
fn->setChild("returnType", retType);
|
||||||
|
|
||||||
|
InlineAnnotation* anno = new InlineAnnotation();
|
||||||
|
anno->mode = "Always";
|
||||||
|
fn->addChild("annotations", anno);
|
||||||
|
mod.addChild("functions", fn);
|
||||||
|
|
||||||
|
CppGenerator gen;
|
||||||
|
std::string output = gen.generate(&mod);
|
||||||
|
|
||||||
|
assert((contains(output, "always_inline") || contains(output, "inline")) &&
|
||||||
|
"@Inline(Always) should produce inline attribute");
|
||||||
|
|
||||||
|
std::cout << "Test 7 PASS: @Inline(Always) → C++ always_inline" << std::endl;
|
||||||
|
++passed;
|
||||||
|
|
||||||
|
delete anno;
|
||||||
|
delete retType;
|
||||||
|
delete fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Test 8: @Pure → C++ [[nodiscard]] ---
|
||||||
|
{
|
||||||
|
Module mod("m1", "Perf", "cpp");
|
||||||
|
Function* fn = new Function("f1", "pureCalc");
|
||||||
|
PrimitiveType* retType = new PrimitiveType("t1", "int");
|
||||||
|
fn->setChild("returnType", retType);
|
||||||
|
|
||||||
|
PureAnnotation* anno = new PureAnnotation();
|
||||||
|
fn->addChild("annotations", anno);
|
||||||
|
mod.addChild("functions", fn);
|
||||||
|
|
||||||
|
CppGenerator gen;
|
||||||
|
std::string output = gen.generate(&mod);
|
||||||
|
|
||||||
|
assert((contains(output, "[[nodiscard]]") || contains(output, "pure") ||
|
||||||
|
contains(output, "[[gnu::pure]]")) &&
|
||||||
|
"@Pure should produce [[nodiscard]] or [[gnu::pure]]");
|
||||||
|
|
||||||
|
std::cout << "Test 8 PASS: @Pure → C++ pure/nodiscard attribute" << std::endl;
|
||||||
|
++passed;
|
||||||
|
|
||||||
|
delete anno;
|
||||||
|
delete retType;
|
||||||
|
delete fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Test 9: @ConstExpr → C++ constexpr ---
|
||||||
|
{
|
||||||
|
Module mod("m1", "Perf", "cpp");
|
||||||
|
Function* fn = new Function("f1", "constCalc");
|
||||||
|
PrimitiveType* retType = new PrimitiveType("t1", "int");
|
||||||
|
fn->setChild("returnType", retType);
|
||||||
|
|
||||||
|
ConstExprAnnotation* anno = new ConstExprAnnotation();
|
||||||
|
fn->addChild("annotations", anno);
|
||||||
|
mod.addChild("functions", fn);
|
||||||
|
|
||||||
|
CppGenerator gen;
|
||||||
|
std::string output = gen.generate(&mod);
|
||||||
|
|
||||||
|
assert(contains(output, "constexpr") &&
|
||||||
|
"@ConstExpr should produce 'constexpr' keyword");
|
||||||
|
|
||||||
|
std::cout << "Test 9 PASS: @ConstExpr → C++ constexpr" << std::endl;
|
||||||
|
++passed;
|
||||||
|
|
||||||
|
delete anno;
|
||||||
|
delete retType;
|
||||||
|
delete fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Summary ---
|
||||||
|
std::cout << "\n=== Step 67 Results: " << passed << " passed, " << failed << " failed ===" << std::endl;
|
||||||
|
return failed > 0 ? 1 : 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user