#pragma once // Step 66: Cross-language memory projection // // CrossLanguageProjector: deep-copies an AST Module, changing its // targetLanguage while preserving (and optionally adapting) memory // annotations so that code generators can emit language-appropriate // constructs (e.g. shared_ptr for @Reclaim(Tracing) in C++). #include #include #include #include "ProjectionAdaptation.h" #include "ast/ASTNode.h" #include "ast/Module.h" #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" #include "ast/Serialization.h" class CrossLanguageProjector { public: // Project an AST from source language to target language. // Returns a new Module with annotations adapted for the target. std::unique_ptr project(const Module* source, const std::string& targetLanguage) const { if (!source) return nullptr; auto mod = std::make_unique( source->id + "_proj", source->name, targetLanguage); // Copy imports for (auto* child : source->getChildren("imports")) { if (child->conceptType == "Import") { auto* srcImp = static_cast(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(child); Function* newFn = cloneFunction(srcFn, targetLanguage); mod->addChild("functions", newFn); } } // Copy classes and statements for cross-language structural projection. for (auto* child : source->getChildren("classes")) { if (ASTNode* n = cloneNode(child, targetLanguage)) mod->addChild("classes", n); } for (auto* child : source->getChildren("statements")) { if (ASTNode* n = cloneNode(child, targetLanguage)) mod->addChild("statements", n); } // Copy module-level variables for (auto* child : source->getChildren("variables")) { if (child->conceptType == "Variable") { auto* srcVar = static_cast(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, targetLanguage); if (newAnno) mod->addChild("annotations", newAnno); } return mod; } // Check if all annotation types from the original survive in the projected AST. bool annotationsPreserved(const Module* original, const Module* projected) const { auto origTypes = collectAnnotationTypes(original); auto projTypes = collectAnnotationTypes(projected); for (const auto& type : origTypes) { bool found = false; for (const auto& pt : projTypes) { if (pt == type) { found = true; break; } } if (!found) return false; } return true; } private: 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, targetLanguage); if (newAnno) fn->addChild("annotations", newAnno); } // Copy body nodes for (auto* child : src->getChildren("body")) { ASTNode* newChild = cloneNode(child, targetLanguage); if (newChild) fn->addChild("body", newChild); } // Copy parameters for (auto* child : src->getChildren("parameters")) { 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, targetLanguage); if (newRet) fn->setChild("returnType", newRet); } return fn; } 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(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; } if (ct == "DeallocateAnnotation") { auto* src = static_cast(anno); auto* a = new DeallocateAnnotation(src->id + "_proj", src->strategy); a->deallocateLocation = src->deallocateLocation; a->owner = src->owner; return a; } if (ct == "LifetimeAnnotation") { auto* src = static_cast(anno); auto* a = new LifetimeAnnotation(src->id + "_proj", src->strategy); a->lifetimeScope = src->lifetimeScope; return a; } if (ct == "OwnerAnnotation") { auto* src = static_cast(anno); auto* a = new OwnerAnnotation( src->id + "_proj", ProjectionAdaptation::adaptOwnerStrategy(src->strategy, targetLanguage)); a->ownerType = src->ownerType; return a; } if (ct == "AllocateAnnotation") { auto* src = static_cast(anno); auto* a = new AllocateAnnotation(src->id + "_proj", src->strategy); a->allocationPattern = src->allocationPattern; return a; } if (ct == "DerefStrategy") { auto* src = static_cast(anno); auto* a = new DerefStrategy(src->id + "_proj", src->strategy); a->derefLocation = src->derefLocation; a->owner = src->owner; return a; } if (ct == "OptimizationLock") { auto* a = new OptimizationLock(); auto* src = static_cast(anno); a->id = src->id + "_proj"; a->lockedBy = src->lockedBy; a->lockReason = src->lockReason; a->lockLevel = src->lockLevel; return a; } if (ct == "LangSpecific") { auto* a = new LangSpecific(); auto* src = static_cast(anno); a->id = src->id + "_proj"; a->language = src->language; a->idiomType = src->idiomType; a->rawSyntax = src->rawSyntax; return a; } // Generic clone: use Serialization roundtrip for all other annotation types if (ct.find("Annotation") != std::string::npos || ct == "CapabilityRequirement" || ct == "HostCall" || ct == "ScheduleTask" || ct == "ModuleLoad") { json nodeJson = toJson(anno); nodeJson["id"] = anno->id + "_proj"; ASTNode* cloned = fromJson(nodeJson); return cloned; } return nullptr; } ASTNode* cloneNode(const ASTNode* node, const std::string& targetLanguage) const { if (!node) return nullptr; const auto& ct = node->conceptType; if (ct == "Variable") { auto* src = static_cast(node); auto* v = new Variable(src->id + "_proj", src->name); // Clone variable annotations for (auto* anno : src->getChildren("annotations")) { 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, targetLanguage); if (t) v->setChild("type", t); } // Clone initializer auto* init = src->getChild("initializer"); if (init) { ASTNode* i = cloneNode(init, targetLanguage); if (i) v->setChild("initializer", i); } return v; } if (ct == "Parameter") { auto* src = static_cast(node); auto* p = new Parameter(src->id + "_proj", src->name); auto* typeChild = src->getChild("type"); if (typeChild) { ASTNode* t = cloneNode(typeChild, targetLanguage); t = ProjectionAdaptation::adaptTypeForTarget(t, 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(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(node); return new CustomType(src->id + "_proj", src->typeName); } if (ct == "Assignment") { auto* src = static_cast(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(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(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(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(node); return new VariableReference(src->id + "_proj", src->variableName); } if (ct == "IntegerLiteral") { auto* src = static_cast(node); return new IntegerLiteral(src->id + "_proj", src->value); } if (ct == "FloatLiteral") { auto* src = static_cast(node); return new FloatLiteral(src->id + "_proj", src->value); } if (ct == "StringLiteral") { auto* src = static_cast(node); return new StringLiteral(src->id + "_proj", src->value); } if (ct == "BooleanLiteral") { auto* src = static_cast(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(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(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(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(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(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(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(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(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(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, targetLanguage); } // Generic clone fallback for declaration nodes not yet specialized. json nodeJson = toJson(node); nodeJson["id"] = node->id + "_proj"; return fromJson(nodeJson); } 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" || targetLanguage == "kotlin" || targetLanguage == "csharp") { return "Tracing"; } return strategy; } // Recursively collect all annotation conceptTypes from a tree std::vector collectAnnotationTypes(const ASTNode* node) const { std::vector types; if (!node) return types; collectAnnotationTypesImpl(node, types); return types; } void collectAnnotationTypesImpl(const ASTNode* node, std::vector& types) const { if (!node) return; // If this is an annotation node, record its type const auto& ct = node->conceptType; if (ct.find("Annotation") != std::string::npos || ct == "DerefStrategy" || ct == "OptimizationLock" || ct == "LangSpecific" || ct == "CapabilityRequirement") { types.push_back(ct); } // Recurse into all children for (auto* child : node->allChildren()) { collectAnnotationTypesImpl(child, types); } } };