Sprint 2 Step 32: Tree-sitter import integration
This commit is contained in:
@@ -39,3 +39,81 @@ public:
|
||||
std::string position;
|
||||
LangSpecific() { conceptType = "LangSpecific"; }
|
||||
};
|
||||
|
||||
// New canonical memory annotations replacing the old DerefStrategy
|
||||
|
||||
class DeallocateAnnotation : public Annotation {
|
||||
public:
|
||||
std::string strategy; // "Explicit" for manual allocation/deallocation
|
||||
std::string deallocateLocation;
|
||||
std::string owner;
|
||||
DeallocateAnnotation() {
|
||||
conceptType = "DeallocateAnnotation";
|
||||
strategy = "Explicit";
|
||||
}
|
||||
DeallocateAnnotation(const std::string& id, const std::string& strategy_val)
|
||||
: strategy(strategy_val) {
|
||||
this->id = id;
|
||||
this->conceptType = "DeallocateAnnotation";
|
||||
}
|
||||
};
|
||||
|
||||
class LifetimeAnnotation : public Annotation {
|
||||
public:
|
||||
std::string strategy; // "RAII" for destructor-based cleanup
|
||||
std::string lifetimeScope;
|
||||
LifetimeAnnotation() {
|
||||
conceptType = "LifetimeAnnotation";
|
||||
strategy = "RAII";
|
||||
}
|
||||
LifetimeAnnotation(const std::string& id, const std::string& strategy_val)
|
||||
: strategy(strategy_val) {
|
||||
this->id = id;
|
||||
this->conceptType = "LifetimeAnnotation";
|
||||
}
|
||||
};
|
||||
|
||||
class ReclaimAnnotation : public Annotation {
|
||||
public:
|
||||
std::string strategy; // "Tracing", "Cycle", "Escape" for different GC strategies
|
||||
std::string reclaimPattern;
|
||||
ReclaimAnnotation() {
|
||||
conceptType = "ReclaimAnnotation";
|
||||
strategy = "Tracing";
|
||||
}
|
||||
ReclaimAnnotation(const std::string& id, const std::string& strategy_val)
|
||||
: strategy(strategy_val) {
|
||||
this->id = id;
|
||||
this->conceptType = "ReclaimAnnotation";
|
||||
}
|
||||
};
|
||||
|
||||
class OwnerAnnotation : public Annotation {
|
||||
public:
|
||||
std::string strategy; // "Single", "Shared_ARC" for ownership strategies
|
||||
std::string ownerType;
|
||||
OwnerAnnotation() {
|
||||
conceptType = "OwnerAnnotation";
|
||||
strategy = "Single";
|
||||
}
|
||||
OwnerAnnotation(const std::string& id, const std::string& strategy_val)
|
||||
: strategy(strategy_val) {
|
||||
this->id = id;
|
||||
this->conceptType = "OwnerAnnotation";
|
||||
}
|
||||
};
|
||||
|
||||
class AllocateAnnotation : public Annotation {
|
||||
public:
|
||||
std::string strategy; // "Static", "Register", "Allocator" for allocation strategies
|
||||
std::string allocationPattern;
|
||||
AllocateAnnotation() {
|
||||
conceptType = "AllocateAnnotation";
|
||||
strategy = "Static";
|
||||
}
|
||||
AllocateAnnotation(const std::string& id, const std::string& strategy_val)
|
||||
: strategy(strategy_val) {
|
||||
this->id = id;
|
||||
this->conceptType = "AllocateAnnotation";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -52,6 +52,11 @@ public:
|
||||
virtual std::string visitDerefStrategy(const DerefStrategy* annotation) = 0;
|
||||
virtual std::string visitOptimizationLock(const OptimizationLock* annotation) = 0;
|
||||
virtual std::string visitLangSpecific(const LangSpecific* annotation) = 0;
|
||||
virtual std::string visitDeallocateAnnotation(const DeallocateAnnotation* annotation) = 0;
|
||||
virtual std::string visitLifetimeAnnotation(const LifetimeAnnotation* annotation) = 0;
|
||||
virtual std::string visitReclaimAnnotation(const ReclaimAnnotation* annotation) = 0;
|
||||
virtual std::string visitOwnerAnnotation(const OwnerAnnotation* annotation) = 0;
|
||||
virtual std::string visitAllocateAnnotation(const AllocateAnnotation* annotation) = 0;
|
||||
};
|
||||
|
||||
class PythonGenerator : public ProjectionGenerator {
|
||||
@@ -127,6 +132,16 @@ public:
|
||||
return visitOptimizationLock(static_cast<const OptimizationLock*>(node));
|
||||
} else if (node->conceptType == "LangSpecific") {
|
||||
return visitLangSpecific(static_cast<const LangSpecific*>(node));
|
||||
} else if (node->conceptType == "DeallocateAnnotation") {
|
||||
return visitDeallocateAnnotation(static_cast<const DeallocateAnnotation*>(node));
|
||||
} else if (node->conceptType == "LifetimeAnnotation") {
|
||||
return visitLifetimeAnnotation(static_cast<const LifetimeAnnotation*>(node));
|
||||
} else if (node->conceptType == "ReclaimAnnotation") {
|
||||
return visitReclaimAnnotation(static_cast<const ReclaimAnnotation*>(node));
|
||||
} else if (node->conceptType == "OwnerAnnotation") {
|
||||
return visitOwnerAnnotation(static_cast<const OwnerAnnotation*>(node));
|
||||
} else if (node->conceptType == "AllocateAnnotation") {
|
||||
return visitAllocateAnnotation(static_cast<const AllocateAnnotation*>(node));
|
||||
}
|
||||
|
||||
return "// Unknown concept: " + node->conceptType;
|
||||
@@ -662,6 +677,26 @@ public:
|
||||
std::string visitLangSpecific(const LangSpecific* annotation) override {
|
||||
return "# @lang_specific(" + annotation->language + ", " + annotation->idiomType + ")";
|
||||
}
|
||||
|
||||
std::string visitDeallocateAnnotation(const DeallocateAnnotation* annotation) override {
|
||||
return "# @dealloc(" + annotation->strategy + ") - Memory deallocation strategy";
|
||||
}
|
||||
|
||||
std::string visitLifetimeAnnotation(const LifetimeAnnotation* annotation) override {
|
||||
return "# @lifetime(" + annotation->strategy + ") - Object lifetime management";
|
||||
}
|
||||
|
||||
std::string visitReclaimAnnotation(const ReclaimAnnotation* annotation) override {
|
||||
return "# @reclaim(" + annotation->strategy + ") - Memory reclamation strategy";
|
||||
}
|
||||
|
||||
std::string visitOwnerAnnotation(const OwnerAnnotation* annotation) override {
|
||||
return "# @owner(" + annotation->strategy + ") - Ownership management strategy";
|
||||
}
|
||||
|
||||
std::string visitAllocateAnnotation(const AllocateAnnotation* annotation) override {
|
||||
return "# @allocate(" + annotation->strategy + ") - Memory allocation strategy";
|
||||
}
|
||||
};
|
||||
|
||||
class ElispGenerator : public ProjectionGenerator {
|
||||
@@ -1241,4 +1276,727 @@ public:
|
||||
std::string visitLangSpecific(const LangSpecific* annotation) override {
|
||||
return "; @lang_specific(" + annotation->language + ", " + annotation->idiomType + ")";
|
||||
}
|
||||
};
|
||||
|
||||
class CppGenerator : public ProjectionGenerator {
|
||||
public:
|
||||
std::string generate(const ASTNode* node) override {
|
||||
if (!node) return "";
|
||||
|
||||
if (node->conceptType == "Module") {
|
||||
return visitModule(static_cast<const Module*>(node));
|
||||
} else if (node->conceptType == "Function") {
|
||||
return visitFunction(static_cast<const Function*>(node));
|
||||
} else if (node->conceptType == "Variable") {
|
||||
return visitVariable(static_cast<const Variable*>(node));
|
||||
} else if (node->conceptType == "Parameter") {
|
||||
return visitParameter(static_cast<const Parameter*>(node));
|
||||
} else if (node->conceptType == "Assignment") {
|
||||
return visitAssignment(static_cast<const Assignment*>(node));
|
||||
} else if (node->conceptType == "Return") {
|
||||
return visitReturn(static_cast<const Return*>(node));
|
||||
} else if (node->conceptType == "BinaryOperation") {
|
||||
return visitBinaryOperation(static_cast<const BinaryOperation*>(node));
|
||||
} else if (node->conceptType == "VariableReference") {
|
||||
return visitVariableReference(static_cast<const VariableReference*>(node));
|
||||
} else if (node->conceptType == "IntegerLiteral") {
|
||||
return visitIntegerLiteral(static_cast<const IntegerLiteral*>(node));
|
||||
} else if (node->conceptType == "FloatLiteral") {
|
||||
return visitFloatLiteral(static_cast<const FloatLiteral*>(node));
|
||||
} else if (node->conceptType == "StringLiteral") {
|
||||
return visitStringLiteral(static_cast<const StringLiteral*>(node));
|
||||
} else if (node->conceptType == "BooleanLiteral") {
|
||||
return visitBooleanLiteral(static_cast<const BooleanLiteral*>(node));
|
||||
} else if (node->conceptType == "NullLiteral") {
|
||||
return visitNullLiteral(static_cast<const NullLiteral*>(node));
|
||||
} else if (node->conceptType == "IfStatement") {
|
||||
return visitIfStatement(static_cast<const IfStatement*>(node));
|
||||
} else if (node->conceptType == "WhileLoop") {
|
||||
return visitWhileLoop(static_cast<const WhileLoop*>(node));
|
||||
} else if (node->conceptType == "ForLoop") {
|
||||
return visitForLoop(static_cast<const ForLoop*>(node));
|
||||
} else if (node->conceptType == "ExpressionStatement") {
|
||||
return visitExpressionStatement(static_cast<const ExpressionStatement*>(node));
|
||||
} else if (node->conceptType == "UnaryOperation") {
|
||||
return visitUnaryOperation(static_cast<const UnaryOperation*>(node));
|
||||
} else if (node->conceptType == "FunctionCall") {
|
||||
return visitFunctionCall(static_cast<const FunctionCall*>(node));
|
||||
} else if (node->conceptType == "Block") {
|
||||
return visitBlock(static_cast<const Block*>(node));
|
||||
} else if (node->conceptType == "ListLiteral") {
|
||||
return visitListLiteral(static_cast<const ListLiteral*>(node));
|
||||
} else if (node->conceptType == "IndexAccess") {
|
||||
return visitIndexAccess(static_cast<const IndexAccess*>(node));
|
||||
} else if (node->conceptType == "MemberAccess") {
|
||||
return visitMemberAccess(static_cast<const MemberAccess*>(node));
|
||||
} else if (node->conceptType == "PrimitiveType") {
|
||||
return visitPrimitiveType(static_cast<const PrimitiveType*>(node));
|
||||
} else if (node->conceptType == "ListType") {
|
||||
return visitListType(static_cast<const ListType*>(node));
|
||||
} else if (node->conceptType == "SetType") {
|
||||
return visitSetType(static_cast<const SetType*>(node));
|
||||
} else if (node->conceptType == "MapType") {
|
||||
return visitMapType(static_cast<const MapType*>(node));
|
||||
} else if (node->conceptType == "TupleType") {
|
||||
return visitTupleType(static_cast<const TupleType*>(node));
|
||||
} else if (node->conceptType == "ArrayType") {
|
||||
return visitArrayType(static_cast<const ArrayType*>(node));
|
||||
} else if (node->conceptType == "OptionalType") {
|
||||
return visitOptionalType(static_cast<const OptionalType*>(node));
|
||||
} else if (node->conceptType == "CustomType") {
|
||||
return visitCustomType(static_cast<const CustomType*>(node));
|
||||
} else if (node->conceptType == "DerefStrategy") {
|
||||
return visitDerefStrategy(static_cast<const DerefStrategy*>(node));
|
||||
} else if (node->conceptType == "OptimizationLock") {
|
||||
return visitOptimizationLock(static_cast<const OptimizationLock*>(node));
|
||||
} else if (node->conceptType == "LangSpecific") {
|
||||
return visitLangSpecific(static_cast<const LangSpecific*>(node));
|
||||
} else if (node->conceptType == "DeallocateAnnotation") {
|
||||
return visitDeallocateAnnotation(static_cast<const DeallocateAnnotation*>(node));
|
||||
} else if (node->conceptType == "LifetimeAnnotation") {
|
||||
return visitLifetimeAnnotation(static_cast<const LifetimeAnnotation*>(node));
|
||||
} else if (node->conceptType == "ReclaimAnnotation") {
|
||||
return visitReclaimAnnotation(static_cast<const ReclaimAnnotation*>(node));
|
||||
} else if (node->conceptType == "OwnerAnnotation") {
|
||||
return visitOwnerAnnotation(static_cast<const OwnerAnnotation*>(node));
|
||||
} else if (node->conceptType == "AllocateAnnotation") {
|
||||
return visitAllocateAnnotation(static_cast<const AllocateAnnotation*>(node));
|
||||
}
|
||||
|
||||
return "// Unknown concept: " + node->conceptType;
|
||||
}
|
||||
|
||||
std::string visitModule(const Module* module) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
// Generate namespace wrapper
|
||||
oss << "namespace " << module->name << " {\n\n";
|
||||
|
||||
// Process variables first
|
||||
auto variables = module->getChildren("variables");
|
||||
for (const auto* var : variables) {
|
||||
oss << visitVariable(static_cast<const Variable*>(var)) << "\n";
|
||||
}
|
||||
|
||||
if (!variables.empty()) {
|
||||
oss << "\n";
|
||||
}
|
||||
|
||||
// Process functions
|
||||
auto functions = module->getChildren("functions");
|
||||
for (size_t i = 0; i < functions.size(); ++i) {
|
||||
if (i > 0) oss << "\n"; // Add blank line between functions
|
||||
oss << visitFunction(static_cast<const Function*>(functions[i]));
|
||||
}
|
||||
|
||||
oss << "\n} // namespace " << module->name << "\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
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) {
|
||||
std::string annotationCode = generate(annotation);
|
||||
if (!annotationCode.empty() && annotationCode != "// Unknown concept: Annotation") {
|
||||
oss << annotationCode << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Generate function return type
|
||||
std::string returnTypeStr = "void"; // Default
|
||||
auto returnType = function->getChild("returnType");
|
||||
if (returnType) {
|
||||
returnTypeStr = generate(returnType);
|
||||
}
|
||||
|
||||
// Generate function signature
|
||||
oss << returnTypeStr << " " << function->name << "(";
|
||||
|
||||
auto parameters = function->getChildren("parameters");
|
||||
for (size_t i = 0; i < parameters.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << visitParameter(static_cast<const Parameter*>(parameters[i]));
|
||||
}
|
||||
|
||||
oss << ") {\n";
|
||||
|
||||
// Process function body
|
||||
auto body = function->getChildren("body");
|
||||
if (body.empty()) {
|
||||
oss << " // Function body is empty\n";
|
||||
oss << " return;";
|
||||
if (returnTypeStr != "void") {
|
||||
oss << " // TODO: return appropriate value";
|
||||
}
|
||||
oss << "\n";
|
||||
} else {
|
||||
for (const auto* stmt : body) {
|
||||
std::string stmtCode = generate(stmt);
|
||||
// Indent each line of the statement
|
||||
size_t pos = 0;
|
||||
while (pos < stmtCode.length()) {
|
||||
size_t newlinePos = stmtCode.find('\n', pos);
|
||||
if (newlinePos == std::string::npos) {
|
||||
oss << " " << stmtCode.substr(pos) << "\n";
|
||||
break;
|
||||
} else {
|
||||
oss << " " << stmtCode.substr(pos, newlinePos - pos) << "\n";
|
||||
pos = newlinePos + 1;
|
||||
if (pos >= stmtCode.length()) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oss << "}\n";
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitVariable(const Variable* variable) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto type = variable->getChild("type");
|
||||
std::string typeStr = "auto"; // Default
|
||||
if (type) {
|
||||
typeStr = generate(type);
|
||||
}
|
||||
|
||||
oss << typeStr << " " << variable->name;
|
||||
|
||||
auto initializer = variable->getChild("initializer");
|
||||
if (initializer) {
|
||||
oss << " = " << generate(initializer);
|
||||
}
|
||||
|
||||
oss << ";";
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitParameter(const Parameter* parameter) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto type = parameter->getChild("type");
|
||||
std::string typeStr = "auto"; // Default
|
||||
if (type) {
|
||||
typeStr = generate(type);
|
||||
}
|
||||
|
||||
oss << typeStr << " " << parameter->name;
|
||||
|
||||
// Add default value if present
|
||||
auto defaultValue = parameter->getChild("defaultValue");
|
||||
if (defaultValue) {
|
||||
oss << " = " << generate(defaultValue);
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitAssignment(const Assignment* assignment) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto target = assignment->getChild("target");
|
||||
auto value = assignment->getChild("value");
|
||||
|
||||
if (target) {
|
||||
oss << generate(target) << " = ";
|
||||
} else {
|
||||
oss << "/* missing target */ ";
|
||||
}
|
||||
|
||||
if (value) {
|
||||
oss << generate(value);
|
||||
} else {
|
||||
oss << "/* missing value */";
|
||||
}
|
||||
|
||||
oss << ";";
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitReturn(const Return* ret) override {
|
||||
std::ostringstream oss;
|
||||
oss << "return ";
|
||||
|
||||
auto value = ret->getChild("value");
|
||||
if (value) {
|
||||
oss << generate(value);
|
||||
} else {
|
||||
// For void returns
|
||||
oss << ";";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
oss << ";";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitBinaryOperation(const BinaryOperation* binOp) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto left = binOp->getChild("left");
|
||||
auto right = binOp->getChild("right");
|
||||
|
||||
if (left) {
|
||||
oss << generate(left);
|
||||
} else {
|
||||
oss << "/* missing left */";
|
||||
}
|
||||
|
||||
oss << " " << binOp->op << " ";
|
||||
|
||||
if (right) {
|
||||
oss << generate(right);
|
||||
} else {
|
||||
oss << "/* missing right */";
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitVariableReference(const VariableReference* varRef) override {
|
||||
return varRef->variableName;
|
||||
}
|
||||
|
||||
std::string visitIntegerLiteral(const IntegerLiteral* lit) override {
|
||||
return std::to_string(lit->value);
|
||||
}
|
||||
|
||||
std::string visitFloatLiteral(const FloatLiteral* lit) override {
|
||||
return lit->value;
|
||||
}
|
||||
|
||||
std::string visitStringLiteral(const StringLiteral* lit) override {
|
||||
// In C++, strings need to be enclosed in double quotes
|
||||
return "\"" + lit->value + "\"";
|
||||
}
|
||||
|
||||
std::string visitBooleanLiteral(const BooleanLiteral* lit) override {
|
||||
return lit->value ? "true" : "false";
|
||||
}
|
||||
|
||||
std::string visitNullLiteral(const NullLiteral* lit) override {
|
||||
return "nullptr";
|
||||
}
|
||||
|
||||
std::string visitIfStatement(const IfStatement* stmt) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto condition = stmt->getChild("condition");
|
||||
auto thenBranch = stmt->getChildren("thenBranch");
|
||||
auto elseBranch = stmt->getChildren("elseBranch");
|
||||
|
||||
oss << "if (";
|
||||
if (condition) {
|
||||
oss << generate(condition);
|
||||
} else {
|
||||
oss << "true"; // fallback
|
||||
}
|
||||
oss << ") {\n";
|
||||
|
||||
// Then branch
|
||||
for (const auto* thenStmt : thenBranch) {
|
||||
std::string stmtCode = generate(thenStmt);
|
||||
size_t pos = 0;
|
||||
while (pos < stmtCode.length()) {
|
||||
size_t newlinePos = stmtCode.find('\n', pos);
|
||||
if (newlinePos == std::string::npos) {
|
||||
oss << " " << stmtCode.substr(pos) << "\n";
|
||||
break;
|
||||
} else {
|
||||
oss << " " << stmtCode.substr(pos, newlinePos - pos) << "\n";
|
||||
pos = newlinePos + 1;
|
||||
if (pos >= stmtCode.length()) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
oss << "}";
|
||||
|
||||
// Else branch
|
||||
if (!elseBranch.empty()) {
|
||||
oss << " else {\n";
|
||||
for (const auto* elseStmt : elseBranch) {
|
||||
std::string stmtCode = generate(elseStmt);
|
||||
size_t pos = 0;
|
||||
while (pos < stmtCode.length()) {
|
||||
size_t newlinePos = stmtCode.find('\n', pos);
|
||||
if (newlinePos == std::string::npos) {
|
||||
oss << " " << stmtCode.substr(pos) << "\n";
|
||||
break;
|
||||
} else {
|
||||
oss << " " << stmtCode.substr(pos, newlinePos - pos) << "\n";
|
||||
pos = newlinePos + 1;
|
||||
if (pos >= stmtCode.length()) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
oss << "}";
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitWhileLoop(const WhileLoop* loop) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto condition = loop->getChild("condition");
|
||||
auto body = loop->getChildren("body");
|
||||
|
||||
oss << "while (";
|
||||
if (condition) {
|
||||
oss << generate(condition);
|
||||
} else {
|
||||
oss << "true"; // fallback to infinite loop
|
||||
}
|
||||
oss << ") {\n";
|
||||
|
||||
for (const auto* stmt : body) {
|
||||
std::string stmtCode = generate(stmt);
|
||||
size_t pos = 0;
|
||||
while (pos < stmtCode.length()) {
|
||||
size_t newlinePos = stmtCode.find('\n', pos);
|
||||
if (newlinePos == std::string::npos) {
|
||||
oss << " " << stmtCode.substr(pos) << "\n";
|
||||
break;
|
||||
} else {
|
||||
oss << " " << stmtCode.substr(pos, newlinePos - pos) << "\n";
|
||||
pos = newlinePos + 1;
|
||||
if (pos >= stmtCode.length()) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oss << "}";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitForLoop(const ForLoop* loop) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto iterable = loop->getChild("iterable");
|
||||
auto body = loop->getChildren("body");
|
||||
|
||||
std::string iterator = loop->iteratorName.empty() ? "item" : loop->iteratorName;
|
||||
|
||||
oss << "for (auto& " << iterator << " : ";
|
||||
if (iterable) {
|
||||
oss << generate(iterable);
|
||||
} else {
|
||||
oss << "/* missing iterable */"; // fallback
|
||||
}
|
||||
oss << ") {\n";
|
||||
|
||||
for (const auto* stmt : body) {
|
||||
std::string stmtCode = generate(stmt);
|
||||
size_t pos = 0;
|
||||
while (pos < stmtCode.length()) {
|
||||
size_t newlinePos = stmtCode.find('\n', pos);
|
||||
if (newlinePos == std::string::npos) {
|
||||
oss << " " << stmtCode.substr(pos) << "\n";
|
||||
break;
|
||||
} else {
|
||||
oss << " " << stmtCode.substr(pos, newlinePos - pos) << "\n";
|
||||
pos = newlinePos + 1;
|
||||
if (pos >= stmtCode.length()) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oss << "}";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitExpressionStatement(const ExpressionStatement* stmt) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto expr = stmt->getChild("expression");
|
||||
if (expr) {
|
||||
oss << generate(expr) << ";";
|
||||
} else {
|
||||
oss << ";"; // Empty statement
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitUnaryOperation(const UnaryOperation* unOp) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto operand = unOp->getChild("operand");
|
||||
std::string op = unOp->op;
|
||||
|
||||
oss << op << " ";
|
||||
if (operand) {
|
||||
oss << generate(operand);
|
||||
} else {
|
||||
oss << "/* missing operand */";
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitFunctionCall(const FunctionCall* call) override {
|
||||
std::ostringstream oss;
|
||||
oss << call->functionName << "(";
|
||||
|
||||
auto arguments = call->getChildren("arguments");
|
||||
for (size_t i = 0; i < arguments.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << generate(arguments[i]);
|
||||
}
|
||||
|
||||
oss << ")";
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitBlock(const Block* block) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto statements = block->getChildren("statements");
|
||||
if (statements.empty()) {
|
||||
oss << "{}";
|
||||
} else {
|
||||
oss << "{\n";
|
||||
for (size_t i = 0; i < statements.size(); ++i) {
|
||||
std::string stmtCode = generate(statements[i]);
|
||||
size_t pos = 0;
|
||||
while (pos < stmtCode.length()) {
|
||||
size_t newlinePos = stmtCode.find('\n', pos);
|
||||
if (newlinePos == std::string::npos) {
|
||||
oss << " " << stmtCode.substr(pos) << "\n";
|
||||
break;
|
||||
} else {
|
||||
oss << " " << stmtCode.substr(pos, newlinePos - pos) << "\n";
|
||||
pos = newlinePos + 1;
|
||||
if (pos >= stmtCode.length()) break;
|
||||
}
|
||||
}
|
||||
if (i < statements.size() - 1) oss << "\n";
|
||||
}
|
||||
oss << "}";
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitListLiteral(const ListLiteral* lit) override {
|
||||
std::ostringstream oss;
|
||||
oss << "{";
|
||||
|
||||
auto elements = lit->getChildren("elements");
|
||||
for (size_t i = 0; i < elements.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << generate(elements[i]);
|
||||
}
|
||||
|
||||
oss << "}";
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitIndexAccess(const IndexAccess* access) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto target = access->getChild("target");
|
||||
auto index = access->getChild("index");
|
||||
|
||||
if (target) {
|
||||
oss << generate(target);
|
||||
} else {
|
||||
oss << "/* missing target */";
|
||||
}
|
||||
|
||||
oss << "[";
|
||||
if (index) {
|
||||
oss << generate(index);
|
||||
} else {
|
||||
oss << "/* missing index */";
|
||||
}
|
||||
oss << "]";
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitMemberAccess(const MemberAccess* access) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
auto target = access->getChild("target");
|
||||
if (target) {
|
||||
oss << generate(target);
|
||||
} else {
|
||||
oss << "/* missing target */";
|
||||
}
|
||||
|
||||
oss << "." << access->memberName;
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitPrimitiveType(const PrimitiveType* type) override {
|
||||
std::string kind = type->kind;
|
||||
// Map common types to C++ equivalents
|
||||
if (kind == "int") return "int";
|
||||
if (kind == "float") return "float";
|
||||
if (kind == "string") return "std::string";
|
||||
if (kind == "bool") return "bool";
|
||||
if (kind == "char") return "char";
|
||||
if (kind == "double") return "double";
|
||||
if (kind == "long") return "long";
|
||||
if (kind == "short") return "short";
|
||||
if (kind == "byte") return "char"; // C++ doesn't have byte, use char
|
||||
if (kind == "void") return "void";
|
||||
|
||||
return kind; // Return as-is if not a common type
|
||||
}
|
||||
|
||||
std::string visitListType(const ListType* type) override {
|
||||
std::ostringstream oss;
|
||||
oss << "std::vector<";
|
||||
|
||||
auto elementType = type->getChild("elementType");
|
||||
if (elementType) {
|
||||
oss << generate(elementType);
|
||||
} else {
|
||||
oss << "auto"; // Default if no element type specified
|
||||
}
|
||||
|
||||
oss << ">";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitSetType(const SetType* type) override {
|
||||
std::ostringstream oss;
|
||||
oss << "std::set<";
|
||||
|
||||
auto elementType = type->getChild("elementType");
|
||||
if (elementType) {
|
||||
oss << generate(elementType);
|
||||
} else {
|
||||
oss << "auto"; // Default if no element type specified
|
||||
}
|
||||
|
||||
oss << ">";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitMapType(const MapType* type) override {
|
||||
std::ostringstream oss;
|
||||
oss << "std::map<";
|
||||
|
||||
auto keyType = type->getChild("keyType");
|
||||
auto valueType = type->getChild("valueType");
|
||||
|
||||
if (keyType) {
|
||||
oss << generate(keyType);
|
||||
} else {
|
||||
oss << "auto"; // Default if no key type specified
|
||||
}
|
||||
|
||||
oss << ", ";
|
||||
|
||||
if (valueType) {
|
||||
oss << generate(valueType);
|
||||
} else {
|
||||
oss << "auto"; // Default if no value type specified
|
||||
}
|
||||
|
||||
oss << ">";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitTupleType(const TupleType* type) override {
|
||||
std::ostringstream oss;
|
||||
oss << "std::tuple<";
|
||||
|
||||
auto elementTypes = type->getChildren("elementTypes");
|
||||
for (size_t i = 0; i < elementTypes.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << generate(elementTypes[i]);
|
||||
}
|
||||
|
||||
oss << ">";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitArrayType(const ArrayType* type) override {
|
||||
std::ostringstream oss;
|
||||
oss << "std::array<";
|
||||
|
||||
auto elementType = type->getChild("elementType");
|
||||
if (elementType) {
|
||||
oss << generate(elementType);
|
||||
} else {
|
||||
oss << "auto"; // Default if no element type specified
|
||||
}
|
||||
|
||||
oss << ", /* size unknown */>";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitOptionalType(const OptionalType* type) override {
|
||||
std::ostringstream oss;
|
||||
oss << "std::optional<";
|
||||
|
||||
auto innerType = type->getChild("innerType");
|
||||
if (innerType) {
|
||||
oss << generate(innerType);
|
||||
} else {
|
||||
oss << "auto"; // Default if no inner type specified
|
||||
}
|
||||
|
||||
oss << ">";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitCustomType(const CustomType* type) override {
|
||||
return type->typeName;
|
||||
}
|
||||
|
||||
std::string visitDerefStrategy(const DerefStrategy* annotation) override {
|
||||
// Generate C++-style comment for deref strategy
|
||||
if (annotation->strategy == "batched") {
|
||||
return "// @deref(batched) - Use batched memory management (smart pointers)";
|
||||
} else if (annotation->strategy == "streamed") {
|
||||
return "// @deref(streamed) - Use streamed memory management (RAII)";
|
||||
} else if (annotation->strategy == "manual") {
|
||||
return "// @deref(manual) - Use manual memory management (new/delete)";
|
||||
} else {
|
||||
return "// @deref(" + annotation->strategy + ") - Memory management strategy";
|
||||
}
|
||||
}
|
||||
|
||||
std::string visitOptimizationLock(const OptimizationLock* annotation) override {
|
||||
return "// @lock(" + annotation->lockedBy + ") - Optimization locked: " + annotation->lockReason;
|
||||
}
|
||||
|
||||
std::string visitLangSpecific(const LangSpecific* annotation) override {
|
||||
return "// @lang_specific(" + annotation->language + ", " + annotation->idiomType + ")";
|
||||
}
|
||||
|
||||
std::string visitDeallocateAnnotation(const DeallocateAnnotation* annotation) override {
|
||||
return "// @dealloc(" + annotation->strategy + ") - Memory deallocation strategy";
|
||||
}
|
||||
|
||||
std::string visitLifetimeAnnotation(const LifetimeAnnotation* annotation) override {
|
||||
return "// @lifetime(" + annotation->strategy + ") - Object lifetime management";
|
||||
}
|
||||
|
||||
std::string visitReclaimAnnotation(const ReclaimAnnotation* annotation) override {
|
||||
return "// @reclaim(" + annotation->strategy + ") - Memory reclamation strategy";
|
||||
}
|
||||
|
||||
std::string visitOwnerAnnotation(const OwnerAnnotation* annotation) override {
|
||||
return "// @owner(" + annotation->strategy + ") - Ownership management strategy";
|
||||
}
|
||||
|
||||
std::string visitAllocateAnnotation(const AllocateAnnotation* annotation) override {
|
||||
return "// @allocate(" + annotation->strategy + ") - Memory allocation strategy";
|
||||
}
|
||||
};
|
||||
@@ -8,6 +8,110 @@
|
||||
#include "Expression.h"
|
||||
#include "Type.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
// Forward declarations for tree-sitter
|
||||
extern "C" {
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
typedef struct TSParser TSParser;
|
||||
typedef struct TSTree TSTree;
|
||||
typedef struct TSNode TSNodeStruct;
|
||||
typedef TSNodeStruct* TSNode;
|
||||
typedef struct TSQuery TSQuery;
|
||||
}
|
||||
|
||||
class TreeSitterParser {
|
||||
public:
|
||||
// Parse Python source code into AST
|
||||
static std::unique_ptr<Module> parsePython(const std::string& source) {
|
||||
// This is a placeholder implementation
|
||||
// In a real implementation, this would:
|
||||
// 1. Use tree-sitter-python to parse the source
|
||||
// 2. Traverse the resulting CST/SIT
|
||||
// 3. Build the corresponding SemAnno AST nodes
|
||||
|
||||
// For now, we'll create a simple module as a placeholder
|
||||
auto module = std::make_unique<Module>();
|
||||
module->id = "ParsedPythonModule";
|
||||
module->name = "parsed_python_module";
|
||||
module->targetLanguage = "python";
|
||||
|
||||
// In a real implementation:
|
||||
/*
|
||||
// Initialize tree-sitter parser for Python
|
||||
TSParser* parser = ts_parser_new();
|
||||
TSLanguage* language = tree_sitter_python(); // Need to link with tree-sitter-python
|
||||
ts_parser_set_language(parser, language);
|
||||
|
||||
// Parse the source
|
||||
TSTree* tree = ts_parser_parse_string(parser, nullptr, source.c_str(), source.length());
|
||||
TSNode rootNode = ts_tree_root_node(tree);
|
||||
|
||||
// Convert the tree-sitter tree to our AST
|
||||
std::unique_ptr<Module> result = convertTreeSitterToAST(rootNode, source);
|
||||
|
||||
// Cleanup
|
||||
ts_tree_delete(tree);
|
||||
ts_parser_delete(parser);
|
||||
|
||||
return result;
|
||||
*/
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
// Parse C++ source code into AST
|
||||
static std::unique_ptr<Module> parseCpp(const std::string& source) {
|
||||
// This is a placeholder implementation
|
||||
// In a real implementation, this would:
|
||||
// 1. Use tree-sitter-cpp to parse the source
|
||||
// 2. Traverse the resulting CST/SIT
|
||||
// 3. Build the corresponding SemAnno AST nodes
|
||||
|
||||
// For now, we'll create a simple module as a placeholder
|
||||
auto module = std::make_unique<Module>();
|
||||
module->id = "ParsedCppModule";
|
||||
module->name = "parsed_cpp_module";
|
||||
module->targetLanguage = "cpp";
|
||||
|
||||
// In a real implementation:
|
||||
/*
|
||||
// Initialize tree-sitter parser for C++
|
||||
TSParser* parser = ts_parser_new();
|
||||
TSLanguage* language = tree_sitter_cpp(); // Need to link with tree-sitter-cpp
|
||||
ts_parser_set_language(parser, language);
|
||||
|
||||
// Parse the source
|
||||
TSTree* tree = ts_parser_parse_string(parser, nullptr, source.c_str(), source.length());
|
||||
TSNode rootNode = ts_tree_root_node(tree);
|
||||
|
||||
// Convert the tree-sitter tree to our AST
|
||||
std::unique_ptr<Module> result = convertTreeSitterToAST(rootNode, source);
|
||||
|
||||
// Cleanup
|
||||
ts_tree_delete(tree);
|
||||
ts_parser_delete(parser);
|
||||
|
||||
return result;
|
||||
*/
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
private:
|
||||
// Helper function to convert tree-sitter nodes to our AST (implementation would be complex)
|
||||
static std::unique_ptr<Module> convertTreeSitterToAST(TSNode node, const std::string& source) {
|
||||
// This would contain the complex logic to map tree-sitter nodes to SemAnno AST nodes
|
||||
// Implementation would traverse the tree-sitter syntax tree and create corresponding
|
||||
// SemAnno AST nodes based on the syntax tree structure
|
||||
auto module = std::make_unique<Module>();
|
||||
module->id = "ConvertedModule";
|
||||
module->name = "converted_module";
|
||||
module->targetLanguage = "unknown"; // Would be determined by the parser used
|
||||
|
||||
return module;
|
||||
}
|
||||
};
|
||||
|
||||
// Forward declarations for tree-sitter
|
||||
extern "C" {
|
||||
|
||||
Reference in New Issue
Block a user