Step 152: extend cross-language projection
This commit is contained in:
@@ -499,3 +499,4 @@ Sprint 5 in progress. Step 141 (Emacs daemon with user config) done. Next: Step
|
||||
| 2026-02-10 | Codex | Step 149: Java CST-to-AST parsing + generator with class/method/constructor handling, import support, and GC-aware annotations. 8/8 tests pass. |
|
||||
| 2026-02-10 | Codex | Step 150: Rust CST-to-AST parsing + generator with impl methods, imports, and RAII annotations. 7/7 tests pass. |
|
||||
| 2026-02-10 | Codex | Step 151: Go CST-to-AST parsing + generator with receivers, imports, and Go-style control flow. 8/8 tests pass. |
|
||||
| 2026-02-10 | Codex | Step 152: Cross-language projection extended for new languages with annotation adaptation and richer node cloning. 6/6 tests pass. |
|
||||
|
||||
@@ -856,6 +856,9 @@ target_link_libraries(step151_test PRIVATE
|
||||
unofficial::tree-sitter::tree-sitter
|
||||
tree_sitter_go)
|
||||
|
||||
add_executable(step152_test tests/step152_test.cpp)
|
||||
target_include_directories(step152_test PRIVATE src)
|
||||
|
||||
find_package(SDL2 CONFIG REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(glad CONFIG REQUIRED)
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
#include "ast/Function.h"
|
||||
#include "ast/Variable.h"
|
||||
#include "ast/Parameter.h"
|
||||
#include "ast/Statement.h"
|
||||
#include "ast/Expression.h"
|
||||
#include "ast/Type.h"
|
||||
#include "ast/Import.h"
|
||||
#include "ast/Annotation.h"
|
||||
|
||||
class CrossLanguageProjector {
|
||||
@@ -28,11 +31,21 @@ public:
|
||||
auto mod = std::make_unique<Module>(
|
||||
source->id + "_proj", source->name, targetLanguage);
|
||||
|
||||
// Copy imports
|
||||
for (auto* child : source->getChildren("imports")) {
|
||||
if (child->conceptType == "Import") {
|
||||
auto* srcImp = static_cast<const Import*>(child);
|
||||
auto* imp = new Import(srcImp->id + "_proj", srcImp->moduleName,
|
||||
srcImp->importKind, srcImp->alias);
|
||||
mod->addChild("imports", imp);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy functions with annotations and body
|
||||
for (auto* child : source->getChildren("functions")) {
|
||||
if (child->conceptType == "Function") {
|
||||
auto* srcFn = static_cast<const Function*>(child);
|
||||
Function* newFn = cloneFunction(srcFn);
|
||||
Function* newFn = cloneFunction(srcFn, targetLanguage);
|
||||
mod->addChild("functions", newFn);
|
||||
}
|
||||
}
|
||||
@@ -42,13 +55,23 @@ public:
|
||||
if (child->conceptType == "Variable") {
|
||||
auto* srcVar = static_cast<const Variable*>(child);
|
||||
Variable* newVar = new Variable(srcVar->id + "_proj", srcVar->name);
|
||||
auto* typeChild = srcVar->getChild("type");
|
||||
if (typeChild) {
|
||||
ASTNode* t = cloneNode(typeChild, targetLanguage);
|
||||
if (t) newVar->setChild("type", t);
|
||||
}
|
||||
auto* init = srcVar->getChild("initializer");
|
||||
if (init) {
|
||||
ASTNode* i = cloneNode(init, targetLanguage);
|
||||
if (i) newVar->setChild("initializer", i);
|
||||
}
|
||||
mod->addChild("variables", newVar);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy module-level annotations
|
||||
for (auto* anno : source->getChildren("annotations")) {
|
||||
ASTNode* newAnno = cloneAnnotation(anno);
|
||||
ASTNode* newAnno = cloneAnnotation(anno, targetLanguage);
|
||||
if (newAnno) mod->addChild("annotations", newAnno);
|
||||
}
|
||||
|
||||
@@ -72,45 +95,49 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Function* cloneFunction(const Function* src) const {
|
||||
Function* cloneFunction(const Function* src,
|
||||
const std::string& targetLanguage) const {
|
||||
Function* fn = new Function(src->id + "_proj", src->name);
|
||||
|
||||
// Copy annotations (preserve all, even non-native to target)
|
||||
for (auto* anno : src->getChildren("annotations")) {
|
||||
ASTNode* newAnno = cloneAnnotation(anno);
|
||||
ASTNode* newAnno = cloneAnnotation(anno, targetLanguage);
|
||||
if (newAnno) fn->addChild("annotations", newAnno);
|
||||
}
|
||||
|
||||
// Copy body nodes
|
||||
for (auto* child : src->getChildren("body")) {
|
||||
ASTNode* newChild = cloneNode(child);
|
||||
ASTNode* newChild = cloneNode(child, targetLanguage);
|
||||
if (newChild) fn->addChild("body", newChild);
|
||||
}
|
||||
|
||||
// Copy parameters
|
||||
for (auto* child : src->getChildren("parameters")) {
|
||||
ASTNode* newChild = cloneNode(child);
|
||||
ASTNode* newChild = cloneNode(child, targetLanguage);
|
||||
if (newChild) fn->addChild("parameters", newChild);
|
||||
}
|
||||
|
||||
// Copy return type
|
||||
auto* retType = src->getChild("returnType");
|
||||
if (retType) {
|
||||
ASTNode* newRet = cloneNode(retType);
|
||||
ASTNode* newRet = cloneNode(retType, targetLanguage);
|
||||
if (newRet) fn->setChild("returnType", newRet);
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
ASTNode* cloneAnnotation(const ASTNode* anno) const {
|
||||
ASTNode* cloneAnnotation(const ASTNode* anno,
|
||||
const std::string& targetLanguage) const {
|
||||
if (!anno) return nullptr;
|
||||
|
||||
const auto& ct = anno->conceptType;
|
||||
|
||||
if (ct == "ReclaimAnnotation") {
|
||||
auto* src = static_cast<const ReclaimAnnotation*>(anno);
|
||||
std::string strategy = adaptReclaimStrategy(src->strategy, targetLanguage);
|
||||
auto* a = new ReclaimAnnotation(src->id + "_proj", src->strategy);
|
||||
a->strategy = strategy;
|
||||
a->reclaimPattern = src->reclaimPattern;
|
||||
return a;
|
||||
}
|
||||
@@ -168,7 +195,8 @@ private:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ASTNode* cloneNode(const ASTNode* node) const {
|
||||
ASTNode* cloneNode(const ASTNode* node,
|
||||
const std::string& targetLanguage) const {
|
||||
if (!node) return nullptr;
|
||||
|
||||
const auto& ct = node->conceptType;
|
||||
@@ -178,19 +206,19 @@ private:
|
||||
auto* v = new Variable(src->id + "_proj", src->name);
|
||||
// Clone variable annotations
|
||||
for (auto* anno : src->getChildren("annotations")) {
|
||||
ASTNode* a = cloneAnnotation(anno);
|
||||
ASTNode* a = cloneAnnotation(anno, targetLanguage);
|
||||
if (a) v->addChild("annotations", a);
|
||||
}
|
||||
// Clone type child
|
||||
auto* typeChild = src->getChild("type");
|
||||
if (typeChild) {
|
||||
ASTNode* t = cloneNode(typeChild);
|
||||
ASTNode* t = cloneNode(typeChild, targetLanguage);
|
||||
if (t) v->setChild("type", t);
|
||||
}
|
||||
// Clone initializer
|
||||
auto* init = src->getChild("initializer");
|
||||
if (init) {
|
||||
ASTNode* i = cloneNode(init);
|
||||
ASTNode* i = cloneNode(init, targetLanguage);
|
||||
if (i) v->setChild("initializer", i);
|
||||
}
|
||||
return v;
|
||||
@@ -200,26 +228,319 @@ private:
|
||||
auto* p = new Parameter(src->id + "_proj", src->name);
|
||||
auto* typeChild = src->getChild("type");
|
||||
if (typeChild) {
|
||||
ASTNode* t = cloneNode(typeChild);
|
||||
ASTNode* t = cloneNode(typeChild, targetLanguage);
|
||||
if (t) p->setChild("type", t);
|
||||
}
|
||||
auto* defaultValue = src->getChild("defaultValue");
|
||||
if (defaultValue) {
|
||||
ASTNode* d = cloneNode(defaultValue, targetLanguage);
|
||||
if (d) p->setChild("defaultValue", d);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
if (ct == "PrimitiveType") {
|
||||
auto* src = static_cast<const PrimitiveType*>(node);
|
||||
return new PrimitiveType(src->id + "_proj", src->kind);
|
||||
}
|
||||
if (ct == "ListType") {
|
||||
auto* t = new ListType();
|
||||
t->id = node->id + "_proj";
|
||||
auto* elem = node->getChild("elementType");
|
||||
if (elem) {
|
||||
ASTNode* e = cloneNode(elem, targetLanguage);
|
||||
if (e) t->setChild("elementType", e);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
if (ct == "SetType") {
|
||||
auto* t = new SetType();
|
||||
t->id = node->id + "_proj";
|
||||
auto* elem = node->getChild("elementType");
|
||||
if (elem) {
|
||||
ASTNode* e = cloneNode(elem, targetLanguage);
|
||||
if (e) t->setChild("elementType", e);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
if (ct == "MapType") {
|
||||
auto* t = new MapType();
|
||||
t->id = node->id + "_proj";
|
||||
auto* key = node->getChild("keyType");
|
||||
auto* val = node->getChild("valueType");
|
||||
if (key) {
|
||||
ASTNode* k = cloneNode(key, targetLanguage);
|
||||
if (k) t->setChild("keyType", k);
|
||||
}
|
||||
if (val) {
|
||||
ASTNode* v = cloneNode(val, targetLanguage);
|
||||
if (v) t->setChild("valueType", v);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
if (ct == "TupleType") {
|
||||
auto* t = new TupleType();
|
||||
t->id = node->id + "_proj";
|
||||
for (auto* child : node->getChildren("elementTypes")) {
|
||||
ASTNode* c = cloneNode(child, targetLanguage);
|
||||
if (c) t->addChild("elementTypes", c);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
if (ct == "ArrayType") {
|
||||
auto* t = new ArrayType();
|
||||
t->id = node->id + "_proj";
|
||||
auto* elem = node->getChild("elementType");
|
||||
if (elem) {
|
||||
ASTNode* e = cloneNode(elem, targetLanguage);
|
||||
if (e) t->setChild("elementType", e);
|
||||
}
|
||||
auto* size = node->getChild("size");
|
||||
if (size) {
|
||||
ASTNode* s = cloneNode(size, targetLanguage);
|
||||
if (s) t->setChild("size", s);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
if (ct == "OptionalType") {
|
||||
auto* t = new OptionalType();
|
||||
t->id = node->id + "_proj";
|
||||
auto* inner = node->getChild("innerType");
|
||||
if (inner) {
|
||||
ASTNode* i = cloneNode(inner, targetLanguage);
|
||||
if (i) t->setChild("innerType", i);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
if (ct == "CustomType") {
|
||||
auto* src = static_cast<const CustomType*>(node);
|
||||
return new CustomType(src->id + "_proj", src->typeName);
|
||||
}
|
||||
if (ct == "Assignment") {
|
||||
auto* src = static_cast<const Assignment*>(node);
|
||||
auto* a = new Assignment();
|
||||
a->id = src->id + "_proj";
|
||||
auto* target = src->getChild("target");
|
||||
auto* value = src->getChild("value");
|
||||
if (target) {
|
||||
ASTNode* t = cloneNode(target, targetLanguage);
|
||||
if (t) a->setChild("target", t);
|
||||
}
|
||||
if (value) {
|
||||
ASTNode* v = cloneNode(value, targetLanguage);
|
||||
if (v) a->setChild("value", v);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
if (ct == "Return") {
|
||||
auto* src = static_cast<const Return*>(node);
|
||||
auto* r = new Return();
|
||||
r->id = src->id + "_proj";
|
||||
auto* val = src->getChild("value");
|
||||
if (val) {
|
||||
ASTNode* v = cloneNode(val, targetLanguage);
|
||||
if (v) r->setChild("value", v);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
if (ct == "BinaryOperation") {
|
||||
auto* src = static_cast<const BinaryOperation*>(node);
|
||||
auto* b = new BinaryOperation();
|
||||
b->id = src->id + "_proj";
|
||||
b->op = src->op;
|
||||
auto* left = src->getChild("left");
|
||||
auto* right = src->getChild("right");
|
||||
if (left) {
|
||||
ASTNode* l = cloneNode(left, targetLanguage);
|
||||
if (l) b->setChild("left", l);
|
||||
}
|
||||
if (right) {
|
||||
ASTNode* r = cloneNode(right, targetLanguage);
|
||||
if (r) b->setChild("right", r);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
if (ct == "UnaryOperation") {
|
||||
auto* src = static_cast<const UnaryOperation*>(node);
|
||||
auto* u = new UnaryOperation();
|
||||
u->id = src->id + "_proj";
|
||||
u->op = src->op;
|
||||
auto* operand = src->getChild("operand");
|
||||
if (operand) {
|
||||
ASTNode* o = cloneNode(operand, targetLanguage);
|
||||
if (o) u->setChild("operand", o);
|
||||
}
|
||||
return u;
|
||||
}
|
||||
if (ct == "VariableReference") {
|
||||
auto* src = static_cast<const VariableReference*>(node);
|
||||
return new VariableReference(src->id + "_proj", src->variableName);
|
||||
}
|
||||
if (ct == "IntegerLiteral") {
|
||||
auto* src = static_cast<const IntegerLiteral*>(node);
|
||||
return new IntegerLiteral(src->id + "_proj", src->value);
|
||||
}
|
||||
if (ct == "FloatLiteral") {
|
||||
auto* src = static_cast<const FloatLiteral*>(node);
|
||||
return new FloatLiteral(src->id + "_proj", src->value);
|
||||
}
|
||||
if (ct == "StringLiteral") {
|
||||
auto* src = static_cast<const StringLiteral*>(node);
|
||||
return new StringLiteral(src->id + "_proj", src->value);
|
||||
}
|
||||
if (ct == "BooleanLiteral") {
|
||||
auto* src = static_cast<const BooleanLiteral*>(node);
|
||||
return new BooleanLiteral(src->id + "_proj", src->value);
|
||||
}
|
||||
if (ct == "NullLiteral") {
|
||||
auto* n = new NullLiteral();
|
||||
n->id = node->id + "_proj";
|
||||
return n;
|
||||
}
|
||||
if (ct == "IfStatement") {
|
||||
auto* src = static_cast<const IfStatement*>(node);
|
||||
auto* s = new IfStatement();
|
||||
s->id = src->id + "_proj";
|
||||
auto* cond = src->getChild("condition");
|
||||
if (cond) {
|
||||
ASTNode* c = cloneNode(cond, targetLanguage);
|
||||
if (c) s->setChild("condition", c);
|
||||
}
|
||||
for (auto* child : src->getChildren("thenBranch")) {
|
||||
ASTNode* c = cloneNode(child, targetLanguage);
|
||||
if (c) s->addChild("thenBranch", c);
|
||||
}
|
||||
for (auto* child : src->getChildren("elseBranch")) {
|
||||
ASTNode* c = cloneNode(child, targetLanguage);
|
||||
if (c) s->addChild("elseBranch", c);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
if (ct == "WhileLoop") {
|
||||
auto* src = static_cast<const WhileLoop*>(node);
|
||||
auto* s = new WhileLoop();
|
||||
s->id = src->id + "_proj";
|
||||
auto* cond = src->getChild("condition");
|
||||
if (cond) {
|
||||
ASTNode* c = cloneNode(cond, targetLanguage);
|
||||
if (c) s->setChild("condition", c);
|
||||
}
|
||||
for (auto* child : src->getChildren("body")) {
|
||||
ASTNode* c = cloneNode(child, targetLanguage);
|
||||
if (c) s->addChild("body", c);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
if (ct == "ForLoop") {
|
||||
auto* src = static_cast<const ForLoop*>(node);
|
||||
auto* s = new ForLoop();
|
||||
s->id = src->id + "_proj";
|
||||
s->iteratorName = src->iteratorName;
|
||||
auto* iter = src->getChild("iterable");
|
||||
if (iter) {
|
||||
ASTNode* i = cloneNode(iter, targetLanguage);
|
||||
if (i) s->setChild("iterable", i);
|
||||
}
|
||||
for (auto* child : src->getChildren("body")) {
|
||||
ASTNode* c = cloneNode(child, targetLanguage);
|
||||
if (c) s->addChild("body", c);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
if (ct == "ExpressionStatement") {
|
||||
auto* src = static_cast<const ExpressionStatement*>(node);
|
||||
auto* s = new ExpressionStatement();
|
||||
s->id = src->id + "_proj";
|
||||
auto* expr = src->getChild("expression");
|
||||
if (expr) {
|
||||
ASTNode* e = cloneNode(expr, targetLanguage);
|
||||
if (e) s->setChild("expression", e);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
if (ct == "FunctionCall") {
|
||||
auto* src = static_cast<const FunctionCall*>(node);
|
||||
auto* c = new FunctionCall();
|
||||
c->id = src->id + "_proj";
|
||||
c->functionName = src->functionName;
|
||||
for (auto* child : src->getChildren("arguments")) {
|
||||
ASTNode* a = cloneNode(child, targetLanguage);
|
||||
if (a) c->addChild("arguments", a);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
if (ct == "Block") {
|
||||
auto* src = static_cast<const Block*>(node);
|
||||
auto* b = new Block();
|
||||
b->id = src->id + "_proj";
|
||||
for (auto* child : src->getChildren("statements")) {
|
||||
ASTNode* c = cloneNode(child, targetLanguage);
|
||||
if (c) b->addChild("statements", c);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
if (ct == "ListLiteral") {
|
||||
auto* src = static_cast<const ListLiteral*>(node);
|
||||
auto* l = new ListLiteral();
|
||||
l->id = src->id + "_proj";
|
||||
for (auto* child : src->getChildren("elements")) {
|
||||
ASTNode* c = cloneNode(child, targetLanguage);
|
||||
if (c) l->addChild("elements", c);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
if (ct == "IndexAccess") {
|
||||
auto* src = static_cast<const IndexAccess*>(node);
|
||||
auto* a = new IndexAccess();
|
||||
a->id = src->id + "_proj";
|
||||
auto* target = src->getChild("target");
|
||||
auto* index = src->getChild("index");
|
||||
if (target) {
|
||||
ASTNode* t = cloneNode(target, targetLanguage);
|
||||
if (t) a->setChild("target", t);
|
||||
}
|
||||
if (index) {
|
||||
ASTNode* i = cloneNode(index, targetLanguage);
|
||||
if (i) a->setChild("index", i);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
if (ct == "MemberAccess") {
|
||||
auto* src = static_cast<const MemberAccess*>(node);
|
||||
auto* m = new MemberAccess();
|
||||
m->id = src->id + "_proj";
|
||||
m->memberName = src->memberName;
|
||||
auto* target = src->getChild("target");
|
||||
if (target) {
|
||||
ASTNode* t = cloneNode(target, targetLanguage);
|
||||
if (t) m->setChild("target", t);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
// Fallback: annotations
|
||||
if (ct.find("Annotation") != std::string::npos ||
|
||||
ct == "DerefStrategy" || ct == "OptimizationLock" ||
|
||||
ct == "LangSpecific") {
|
||||
return cloneAnnotation(node);
|
||||
return cloneAnnotation(node, targetLanguage);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static std::string adaptReclaimStrategy(const std::string& strategy,
|
||||
const std::string& targetLanguage) {
|
||||
if (targetLanguage == "go") {
|
||||
return "Escape";
|
||||
}
|
||||
if (targetLanguage == "rust" || targetLanguage == "cpp" ||
|
||||
targetLanguage == "java" || targetLanguage == "javascript" ||
|
||||
targetLanguage == "typescript" || targetLanguage == "python" ||
|
||||
targetLanguage == "elisp") {
|
||||
return "Tracing";
|
||||
}
|
||||
return strategy;
|
||||
}
|
||||
|
||||
// Recursively collect all annotation conceptTypes from a tree
|
||||
std::vector<std::string> collectAnnotationTypes(const ASTNode* node) const {
|
||||
std::vector<std::string> types;
|
||||
|
||||
73
editor/tests/step152_test.cpp
Normal file
73
editor/tests/step152_test.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
// Step 152 TDD Test: Cross-language projection for new languages
|
||||
#include "CrossLanguageProjector.h"
|
||||
#include "ast/Annotation.h"
|
||||
#include "ast/Module.h"
|
||||
#include "ast/Function.h"
|
||||
#include "ast/Statement.h"
|
||||
#include "ast/Expression.h"
|
||||
#include <iostream>
|
||||
|
||||
static void expect(bool cond, const std::string& name, int& passed, int& failed) {
|
||||
if (cond) {
|
||||
std::cout << "Test " << (passed + failed + 1) << " PASS: " << name << "\n";
|
||||
++passed;
|
||||
} else {
|
||||
std::cout << "Test " << (passed + failed + 1) << " FAIL: " << name << "\n";
|
||||
++failed;
|
||||
}
|
||||
}
|
||||
|
||||
static bool hasReclaimAnnotation(const ASTNode* node, std::string* strategyOut = nullptr) {
|
||||
if (!node) return false;
|
||||
for (auto* anno : node->getChildren("annotations")) {
|
||||
if (anno->conceptType == "ReclaimAnnotation") {
|
||||
if (strategyOut) {
|
||||
auto* ra = static_cast<const ReclaimAnnotation*>(anno);
|
||||
*strategyOut = ra->strategy;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int passed = 0;
|
||||
int failed = 0;
|
||||
|
||||
Module src("mod_src", "Demo", "python");
|
||||
auto* fn = new Function("fn_add", "add");
|
||||
auto* reclaim = new ReclaimAnnotation("anno_gc", "Tracing");
|
||||
fn->addChild("annotations", reclaim);
|
||||
|
||||
auto* ret = new Return();
|
||||
ret->id = "ret";
|
||||
ret->setChild("value", new IntegerLiteral("int_one", 1));
|
||||
fn->addChild("body", ret);
|
||||
src.addChild("functions", fn);
|
||||
|
||||
CrossLanguageProjector projector;
|
||||
|
||||
auto rust = projector.project(&src, "rust");
|
||||
expect(rust != nullptr, "rust projection created", passed, failed);
|
||||
expect(rust && rust->targetLanguage == "rust", "rust target language set", passed, failed);
|
||||
|
||||
auto go = projector.project(&src, "go");
|
||||
expect(go != nullptr, "go projection created", passed, failed);
|
||||
expect(go && go->targetLanguage == "go", "go target language set", passed, failed);
|
||||
|
||||
bool reclaimFound = false;
|
||||
std::string strategy;
|
||||
if (go) {
|
||||
auto fns = go->getChildren("functions");
|
||||
if (!fns.empty() && fns[0]->conceptType == "Function") {
|
||||
reclaimFound = hasReclaimAnnotation(fns[0], &strategy);
|
||||
}
|
||||
}
|
||||
expect(reclaimFound, "reclaim annotation preserved", passed, failed);
|
||||
expect(strategy == "Escape", "reclaim adapted for go", passed, failed);
|
||||
|
||||
std::cout << "\n=== Step 152 Results: " << passed << " passed, "
|
||||
<< failed << " failed ===\n";
|
||||
return failed == 0 ? 0 : 1;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ adds full semantic support.
|
||||
Close()/Release() patterns, @Owner(Single) → ownership convention comments.
|
||||
*Modifies:* `Parser.h`, `Generator.h`
|
||||
|
||||
- [ ] **Step 152: Cross-language projection for new languages**
|
||||
- [x] **Step 152: Cross-language projection for new languages**
|
||||
Extend `CrossLanguageProjector` to handle projection between all pairs of
|
||||
supported languages (Python, C++, Elisp, JS/TS, Java, Rust, Go).
|
||||
Annotation adaptation rules for each target. Library compatibility
|
||||
|
||||
Reference in New Issue
Block a user