From f094c14ea7062a4c1176fd3cd0c2140eff8ee6a2 Mon Sep 17 00:00:00 2001 From: Bill Date: Fri, 6 Feb 2026 19:56:57 -0700 Subject: [PATCH] Sprint 2 Step 11: Python generator - Annotation output --- editor/CMakeLists.txt | 3 ++ editor/src/ast/Generator.h | 6 +++ editor/tests/step11_test.cpp | 95 ++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 editor/tests/step11_test.cpp diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index aa11bf0..5c9966c 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -45,3 +45,6 @@ target_include_directories(step9_test PRIVATE src) add_executable(step10_test tests/step10_test.cpp) target_include_directories(step10_test PRIVATE src) + +add_executable(step11_test tests/step11_test.cpp) +target_include_directories(step11_test PRIVATE src) diff --git a/editor/src/ast/Generator.h b/editor/src/ast/Generator.h index df9bbcf..7610a54 100644 --- a/editor/src/ast/Generator.h +++ b/editor/src/ast/Generator.h @@ -161,6 +161,12 @@ public: std::string visitFunction(const Function* function) override { std::ostringstream oss; + // Process annotations first (these are in the "annotations" role) + auto annotations = function->getChildren("annotations"); + for (const auto* annotation : annotations) { + oss << generate(annotation) << "\n"; + } + // Generate function signature oss << "def " << function->name << "("; diff --git a/editor/tests/step11_test.cpp b/editor/tests/step11_test.cpp new file mode 100644 index 0000000..e735f41 --- /dev/null +++ b/editor/tests/step11_test.cpp @@ -0,0 +1,95 @@ +// Step 11: Python generator - Annotation output. +// +// DerefStrategy → `# @deref(strategy)` comment in Python +// OptimizationLock → `# @lock(...)` comment +// Test: SimpleFunctionExample with @deref(batched) → comment appears in output. + +#include "../src/ast/Module.h" +#include "../src/ast/Function.h" +#include "../src/ast/Variable.h" +#include "../src/ast/Parameter.h" +#include "../src/ast/Statement.h" +#include "../src/ast/Expression.h" +#include "../src/ast/Type.h" +#include "../src/ast/Annotation.h" +#include "../src/ast/Generator.h" +#include +#include +#include + +int main() { + // Build a SimpleFunctionExample module with deref annotation + Module simple("SFE_M001", "SimpleFunctionExample", "python"); + + // Add a function: def calculate_sum(a, b) with deref annotation + Function calcSum("SFE_F001", "calculate_sum"); + + // Add parameters a and b + Parameter pa("SFE_P001", "a"); + PrimitiveType paType("SFE_PT001", "int"); + pa.setChild("type", &paType); + calcSum.addChild("parameters", &pa); + + Parameter pb("SFE_P002", "b"); + PrimitiveType pbType("SFE_PT002", "int"); + pb.setChild("type", &pbType); + calcSum.addChild("parameters", &pb); + + // Add return type + PrimitiveType retType("SFE_RT001", "int"); + calcSum.setChild("returnType", &retType); + + // Add deref strategy annotation: @deref(batched) + DerefStrategy derefStrategy; + derefStrategy.id = "SFE_DR001"; + derefStrategy.strategy = "batched"; + calcSum.addChild("annotations", &derefStrategy); + + // Add a simple assignment: result = a + b + Assignment assign; + assign.id = "SFE_A001"; + + // Assignment target: result + VariableReference assignTarget("SFE_VR001", "result"); + assign.setChild("target", &assignTarget); + + // Assignment value: a + b (BinaryOperation) + BinaryOperation addOp("SFE_BO001", "+"); + + // Left operand: a + VariableReference varA("SFE_VR_a", "a"); + addOp.setChild("left", &varA); + + // Right operand: b + VariableReference varB("SFE_VR_b", "b"); + addOp.setChild("right", &varB); + + assign.setChild("value", &addOp); + calcSum.addChild("body", &assign); + + // Add return statement: return result + Return retStmt; + retStmt.id = "SFE_R001"; + VariableReference retVal("SFE_VR_return", "result"); + retStmt.setChild("value", &retVal); + calcSum.addChild("body", &retStmt); + + // Add function to module + simple.addChild("functions", &calcSum); + + // Create Python generator and generate code + PythonGenerator gen; + std::string output = gen.visitModule(&simple); + + std::cout << "Generated Python code:\n" << output << std::endl; + + // Verify the output contains the expected Python code with annotation comment + assert(output.find("def calculate_sum(a: int, b: int):") != std::string::npos); + assert(output.find("result = a + b") != std::string::npos); + assert(output.find("return result") != std::string::npos); + // Check that the deref annotation appears as a comment + assert(output.find("# @deref(batched)") != std::string::npos); + + std::cout << "\nStep 11: PASS — Python generator handles annotation output" << std::endl; + return 0; +} \ No newline at end of file