Step 308: All 8 generators produce language-appropriate output for 9 new AST node types (8/8 tests)
Phase 11c complete (80/80 tests). Added visitor implementations for ClassDeclaration, InterfaceDeclaration, MethodDeclaration, GenericType, TypeParameter, AsyncFunction, AwaitExpression, LambdaExpression, and DecoratorAnnotation to Rust, Go, Java, JavaScript/TypeScript, and Elisp generators. Each generator emits idiomatic syntax: Rust struct+impl/trait/async fn/.await/|closure|, Go type struct/interface/func receiver/<-channel/func(), Java class extends/interface/CompletableFuture/(x)->/@annotation, JS class extends/async function/await/(x)=>/class, Elisp cl-defstruct/cl-defgeneric/cl-defmethod/(lambda). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#include "ProjectionGenerator.h"
|
||||
#include "ClassDeclaration.h"
|
||||
#include "GenericType.h"
|
||||
#include "AsyncNodes.h"
|
||||
#include "../SemannoAnnotationImpl.h"
|
||||
|
||||
class ElispGenerator : public ProjectionGenerator, public SemannoAnnotationImpl<ElispGenerator> {
|
||||
@@ -489,6 +492,123 @@ public:
|
||||
return type->typeName;
|
||||
}
|
||||
|
||||
// --- New AST node visitors (Step 308) ---
|
||||
|
||||
std::string visitClassDeclaration(const ASTNode* node) override {
|
||||
auto* cls = static_cast<const ClassDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = cls->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "(cl-defstruct " << cls->name;
|
||||
if (!cls->superClass.empty()) oss << "\n (:include " << cls->superClass << ")";
|
||||
auto fields = cls->getChildren("fields");
|
||||
for (const auto* f : fields) {
|
||||
auto* var = static_cast<const Variable*>(f);
|
||||
oss << "\n (" << var->name << " nil)";
|
||||
}
|
||||
oss << ")\n";
|
||||
auto methods = cls->getChildren("methods");
|
||||
for (const auto* m : methods) oss << "\n" << generate(m);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitInterfaceDeclaration(const ASTNode* node) override {
|
||||
auto* iface = static_cast<const InterfaceDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "; Interface: " << iface->name << "\n";
|
||||
auto methods = iface->getChildren("methods");
|
||||
for (const auto* m : methods) {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(m);
|
||||
oss << "(cl-defgeneric " << meth->name << " (self))\n";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitMethodDeclaration(const ASTNode* node) override {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = meth->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "(cl-defmethod " << meth->name << " ((self";
|
||||
if (!meth->className.empty()) oss << " " << meth->className;
|
||||
oss << ")";
|
||||
auto params = meth->getChildren("parameters");
|
||||
for (const auto* p : params) oss << " " << visitParameter(static_cast<const Parameter*>(p));
|
||||
oss << ")\n";
|
||||
auto body = meth->getChildren("body");
|
||||
if (body.empty()) {
|
||||
oss << " nil)\n";
|
||||
} else {
|
||||
for (const auto* s : body) oss << " " << generate(s) << "\n";
|
||||
oss << ")\n";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitGenericType(const ASTNode* node) override {
|
||||
auto* gen = static_cast<const GenericType*>(node);
|
||||
return gen->baseName;
|
||||
}
|
||||
|
||||
std::string visitTypeParameter(const ASTNode* node) override {
|
||||
auto* tp = static_cast<const TypeParameter*>(node);
|
||||
return tp->name;
|
||||
}
|
||||
|
||||
std::string visitAsyncFunction(const ASTNode* node) override {
|
||||
auto* af = static_cast<const AsyncFunction*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = af->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "(defun " << af->name << " (";
|
||||
auto params = af->getChildren("parameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << " ";
|
||||
oss << visitParameter(static_cast<const Parameter*>(params[i]));
|
||||
}
|
||||
oss << ")\n";
|
||||
oss << " ;; async\n";
|
||||
auto body = af->getChildren("body");
|
||||
if (body.empty()) {
|
||||
oss << " nil)\n";
|
||||
} else {
|
||||
for (const auto* s : body) oss << " " << generate(s) << "\n";
|
||||
oss << ")\n";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitAwaitExpression(const ASTNode* node) override {
|
||||
auto* aw = static_cast<const AwaitExpression*>(node);
|
||||
auto* expr = aw->getChild("expression");
|
||||
return "(async-get " + (expr ? generate(expr) : "nil") + ")";
|
||||
}
|
||||
|
||||
std::string visitLambdaExpression(const ASTNode* node) override {
|
||||
auto* lam = static_cast<const LambdaExpression*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "(lambda (";
|
||||
auto params = lam->getChildren("parameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << " ";
|
||||
oss << static_cast<const Parameter*>(params[i])->name;
|
||||
}
|
||||
oss << ")";
|
||||
auto body = lam->getChildren("body");
|
||||
if (body.empty()) {
|
||||
oss << " nil";
|
||||
} else {
|
||||
for (const auto* s : body) oss << "\n " << generate(s);
|
||||
}
|
||||
oss << ")";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitDecoratorAnnotation(const ASTNode* node) override {
|
||||
auto* dec = static_cast<const DecoratorAnnotation*>(node);
|
||||
return "; @" + dec->name;
|
||||
}
|
||||
|
||||
std::string visitDerefStrategy(const DerefStrategy* annotation) override {
|
||||
// Convert deref strategy to Elisp annotation/comment
|
||||
if (annotation->strategy == "batched") {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
#include "ProjectionGenerator.h"
|
||||
#include "Import.h"
|
||||
#include "ClassDeclaration.h"
|
||||
#include "GenericType.h"
|
||||
#include "AsyncNodes.h"
|
||||
#include "../SemannoAnnotationImpl.h"
|
||||
|
||||
class GoGenerator : public ProjectionGenerator, public SemannoAnnotationImpl<GoGenerator> {
|
||||
@@ -404,6 +407,118 @@ public:
|
||||
return type->typeName;
|
||||
}
|
||||
|
||||
// --- New AST node visitors (Step 308) ---
|
||||
|
||||
std::string visitClassDeclaration(const ASTNode* node) override {
|
||||
auto* cls = static_cast<const ClassDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = cls->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "type " << cls->name << " struct {\n";
|
||||
auto fields = cls->getChildren("fields");
|
||||
for (const auto* f : fields)
|
||||
oss << " " << generate(f) << "\n";
|
||||
oss << "}\n";
|
||||
auto methods = cls->getChildren("methods");
|
||||
for (const auto* m : methods) oss << "\n" << generate(m);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitInterfaceDeclaration(const ASTNode* node) override {
|
||||
auto* iface = static_cast<const InterfaceDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "type " << iface->name << " interface {\n";
|
||||
auto methods = iface->getChildren("methods");
|
||||
for (const auto* m : methods) {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(m);
|
||||
oss << " " << meth->name << "()\n";
|
||||
}
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitMethodDeclaration(const ASTNode* node) override {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = meth->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "func ";
|
||||
if (!meth->isStatic && !meth->className.empty()) {
|
||||
oss << "(" << receiverVar(meth->className) << " *" << meth->className << ") ";
|
||||
}
|
||||
oss << meth->name << "(";
|
||||
emitParameters(oss, meth->getChildren("parameters"));
|
||||
oss << ")";
|
||||
auto retType = meth->getChild("returnType");
|
||||
if (retType) oss << " " << generate(retType);
|
||||
oss << " {\n";
|
||||
emitBody(oss, meth->getChildren("body"), " ");
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitGenericType(const ASTNode* node) override {
|
||||
auto* gen = static_cast<const GenericType*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << gen->baseName << "[";
|
||||
auto params = gen->getChildren("typeParameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << generate(params[i]);
|
||||
}
|
||||
oss << "]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitTypeParameter(const ASTNode* node) override {
|
||||
auto* tp = static_cast<const TypeParameter*>(node);
|
||||
if (!tp->constraint.empty()) return tp->name + " " + tp->constraint;
|
||||
return tp->name;
|
||||
}
|
||||
|
||||
std::string visitAsyncFunction(const ASTNode* node) override {
|
||||
auto* af = static_cast<const AsyncFunction*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = af->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "func " << af->name << "(";
|
||||
emitParameters(oss, af->getChildren("parameters"));
|
||||
oss << ")";
|
||||
auto retType = af->getChild("returnType");
|
||||
if (retType) oss << " " << generate(retType);
|
||||
oss << " {\n";
|
||||
oss << " // async: use goroutine\n";
|
||||
emitBody(oss, af->getChildren("body"), " ");
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitAwaitExpression(const ASTNode* node) override {
|
||||
auto* aw = static_cast<const AwaitExpression*>(node);
|
||||
auto* expr = aw->getChild("expression");
|
||||
return "<-" + (expr ? generate(expr) : "/* missing */");
|
||||
}
|
||||
|
||||
std::string visitLambdaExpression(const ASTNode* node) override {
|
||||
auto* lam = static_cast<const LambdaExpression*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "func(";
|
||||
auto params = lam->getChildren("parameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << visitParameter(static_cast<const Parameter*>(params[i]));
|
||||
}
|
||||
oss << ") {\n";
|
||||
emitBody(oss, lam->getChildren("body"), " ");
|
||||
oss << "}";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitDecoratorAnnotation(const ASTNode* node) override {
|
||||
auto* dec = static_cast<const DecoratorAnnotation*>(node);
|
||||
return "// @" + dec->name;
|
||||
}
|
||||
|
||||
std::string visitDerefStrategy(const DerefStrategy* annotation) override {
|
||||
return "// @deref(" + annotation->strategy + ")";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
#include "ProjectionGenerator.h"
|
||||
#include "Import.h"
|
||||
#include "ClassDeclaration.h"
|
||||
#include "GenericType.h"
|
||||
#include "AsyncNodes.h"
|
||||
#include "../SemannoAnnotationImpl.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
@@ -439,6 +442,151 @@ public:
|
||||
return type->typeName;
|
||||
}
|
||||
|
||||
// --- New AST node visitors (Step 308) ---
|
||||
|
||||
std::string visitClassDeclaration(const ASTNode* node) override {
|
||||
auto* cls = static_cast<const ClassDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = cls->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
if (cls->isAbstract) oss << "abstract ";
|
||||
oss << "class " << cls->name;
|
||||
if (!cls->superClass.empty()) oss << " extends " << cls->superClass;
|
||||
auto interfaces = cls->getChildren("interfaces");
|
||||
if (!interfaces.empty()) {
|
||||
oss << " implements ";
|
||||
for (size_t i = 0; i < interfaces.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << generate(interfaces[i]);
|
||||
}
|
||||
}
|
||||
oss << " {\n";
|
||||
auto fields = cls->getChildren("fields");
|
||||
for (const auto* f : fields)
|
||||
oss << " " << generate(f) << "\n";
|
||||
if (!fields.empty() && !cls->getChildren("methods").empty()) oss << "\n";
|
||||
auto methods = cls->getChildren("methods");
|
||||
for (const auto* m : methods) oss << generate(m) << "\n";
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitInterfaceDeclaration(const ASTNode* node) override {
|
||||
auto* iface = static_cast<const InterfaceDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "interface " << iface->name << " {\n";
|
||||
auto methods = iface->getChildren("methods");
|
||||
for (const auto* m : methods) {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(m);
|
||||
oss << " void " << meth->name << "();\n";
|
||||
}
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitMethodDeclaration(const ASTNode* node) override {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = meth->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << " " << generate(a) << "\n";
|
||||
oss << " ";
|
||||
if (!meth->visibility.empty()) oss << meth->visibility << " ";
|
||||
if (meth->isStatic) oss << "static ";
|
||||
std::string returnType = "void";
|
||||
auto retType = meth->getChild("returnType");
|
||||
if (retType) returnType = generate(retType);
|
||||
oss << returnType << " " << meth->name << "(";
|
||||
emitParameters(oss, meth->getChildren("parameters"));
|
||||
oss << ")";
|
||||
if (meth->isOverride) oss << " /* @Override */";
|
||||
auto body = meth->getChildren("body");
|
||||
if (body.empty()) {
|
||||
oss << " {}\n";
|
||||
} else {
|
||||
oss << " {\n";
|
||||
emitBody(oss, body, " ");
|
||||
oss << " }\n";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitGenericType(const ASTNode* node) override {
|
||||
auto* gen = static_cast<const GenericType*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << gen->baseName << "<";
|
||||
auto params = gen->getChildren("typeParameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << generate(params[i]);
|
||||
}
|
||||
oss << ">";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitTypeParameter(const ASTNode* node) override {
|
||||
auto* tp = static_cast<const TypeParameter*>(node);
|
||||
if (!tp->constraint.empty()) return tp->name + " extends " + tp->constraint;
|
||||
return tp->name;
|
||||
}
|
||||
|
||||
std::string visitAsyncFunction(const ASTNode* node) override {
|
||||
auto* af = static_cast<const AsyncFunction*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = af->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "CompletableFuture<Void> " << af->name << "(";
|
||||
emitParameters(oss, af->getChildren("parameters"));
|
||||
oss << ") {\n";
|
||||
emitBody(oss, af->getChildren("body"), " ");
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitAwaitExpression(const ASTNode* node) override {
|
||||
auto* aw = static_cast<const AwaitExpression*>(node);
|
||||
auto* expr = aw->getChild("expression");
|
||||
return (expr ? generate(expr) : "/* missing */") + ".get()";
|
||||
}
|
||||
|
||||
std::string visitLambdaExpression(const ASTNode* node) override {
|
||||
auto* lam = static_cast<const LambdaExpression*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "(";
|
||||
auto params = lam->getChildren("parameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << static_cast<const Parameter*>(params[i])->name;
|
||||
}
|
||||
oss << ") -> ";
|
||||
auto body = lam->getChildren("body");
|
||||
if (body.size() == 1) {
|
||||
oss << generate(body[0]);
|
||||
} else if (body.empty()) {
|
||||
oss << "{}";
|
||||
} else {
|
||||
oss << "{ ";
|
||||
for (const auto* s : body) oss << generate(s) << "; ";
|
||||
oss << "}";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitDecoratorAnnotation(const ASTNode* node) override {
|
||||
auto* dec = static_cast<const DecoratorAnnotation*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "@" << dec->name;
|
||||
auto args = dec->getChildren("arguments");
|
||||
if (!args.empty()) {
|
||||
oss << "(";
|
||||
for (size_t i = 0; i < args.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << generate(args[i]);
|
||||
}
|
||||
oss << ")";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitDerefStrategy(const DerefStrategy* annotation) override {
|
||||
return "// @deref(" + annotation->strategy + ")";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
#include "ProjectionGenerator.h"
|
||||
#include "Import.h"
|
||||
#include "ClassDeclaration.h"
|
||||
#include "GenericType.h"
|
||||
#include "AsyncNodes.h"
|
||||
#include "../SemannoAnnotationImpl.h"
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
@@ -446,6 +449,133 @@ public:
|
||||
return type->typeName;
|
||||
}
|
||||
|
||||
// --- New AST node visitors (Step 308) ---
|
||||
|
||||
std::string visitClassDeclaration(const ASTNode* node) override {
|
||||
auto* cls = static_cast<const ClassDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = cls->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "class " << cls->name;
|
||||
if (!cls->superClass.empty()) oss << " extends " << cls->superClass;
|
||||
oss << " {\n";
|
||||
auto fields = cls->getChildren("fields");
|
||||
for (const auto* f : fields)
|
||||
oss << " " << generate(f) << "\n";
|
||||
auto methods = cls->getChildren("methods");
|
||||
for (const auto* m : methods) oss << generate(m);
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitInterfaceDeclaration(const ASTNode* node) override {
|
||||
auto* iface = static_cast<const InterfaceDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "class " << iface->name << " {\n";
|
||||
auto methods = iface->getChildren("methods");
|
||||
for (const auto* m : methods) {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(m);
|
||||
oss << " " << meth->name << "() { throw new Error('not implemented'); }\n";
|
||||
}
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitMethodDeclaration(const ASTNode* node) override {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = meth->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << " " << generate(a) << "\n";
|
||||
oss << " ";
|
||||
if (meth->isStatic) oss << "static ";
|
||||
oss << meth->name << "(";
|
||||
emitParameters(oss, meth->getChildren("parameters"));
|
||||
oss << ")";
|
||||
if (includeTypes_) {
|
||||
auto retType = meth->getChild("returnType");
|
||||
if (retType) oss << ": " << generate(retType);
|
||||
}
|
||||
auto body = meth->getChildren("body");
|
||||
if (body.empty()) {
|
||||
oss << " {}\n";
|
||||
} else {
|
||||
oss << " {\n";
|
||||
emitBody(oss, body, " ");
|
||||
oss << " }\n";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitGenericType(const ASTNode* node) override {
|
||||
auto* gen = static_cast<const GenericType*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << gen->baseName << "<";
|
||||
auto params = gen->getChildren("typeParameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << generate(params[i]);
|
||||
}
|
||||
oss << ">";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitTypeParameter(const ASTNode* node) override {
|
||||
auto* tp = static_cast<const TypeParameter*>(node);
|
||||
return tp->name;
|
||||
}
|
||||
|
||||
std::string visitAsyncFunction(const ASTNode* node) override {
|
||||
auto* af = static_cast<const AsyncFunction*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = af->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "async function " << af->name << "(";
|
||||
emitParameters(oss, af->getChildren("parameters"));
|
||||
oss << ")";
|
||||
if (includeTypes_) {
|
||||
auto retType = af->getChild("returnType");
|
||||
if (retType) oss << ": Promise<" << generate(retType) << ">";
|
||||
}
|
||||
oss << " {\n";
|
||||
emitBody(oss, af->getChildren("body"), " ");
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitAwaitExpression(const ASTNode* node) override {
|
||||
auto* aw = static_cast<const AwaitExpression*>(node);
|
||||
auto* expr = aw->getChild("expression");
|
||||
return "await " + (expr ? generate(expr) : "undefined");
|
||||
}
|
||||
|
||||
std::string visitLambdaExpression(const ASTNode* node) override {
|
||||
auto* lam = static_cast<const LambdaExpression*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "(";
|
||||
auto params = lam->getChildren("parameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << static_cast<const Parameter*>(params[i])->name;
|
||||
}
|
||||
oss << ") => ";
|
||||
auto body = lam->getChildren("body");
|
||||
if (body.size() == 1) {
|
||||
oss << generate(body[0]);
|
||||
} else if (body.empty()) {
|
||||
oss << "{}";
|
||||
} else {
|
||||
oss << "{ ";
|
||||
for (const auto* s : body) oss << generate(s) << "; ";
|
||||
oss << "}";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitDecoratorAnnotation(const ASTNode* node) override {
|
||||
auto* dec = static_cast<const DecoratorAnnotation*>(node);
|
||||
return "// @" + dec->name;
|
||||
}
|
||||
|
||||
std::string visitDerefStrategy(const DerefStrategy* annotation) override {
|
||||
return "// @deref(" + annotation->strategy + ")";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
#include "ProjectionGenerator.h"
|
||||
#include "Import.h"
|
||||
#include "ClassDeclaration.h"
|
||||
#include "GenericType.h"
|
||||
#include "AsyncNodes.h"
|
||||
#include "../SemannoAnnotationImpl.h"
|
||||
|
||||
class RustGenerator : public ProjectionGenerator, public SemannoAnnotationImpl<RustGenerator> {
|
||||
@@ -419,6 +422,134 @@ public:
|
||||
return type->typeName;
|
||||
}
|
||||
|
||||
// --- New AST node visitors (Step 308) ---
|
||||
|
||||
std::string visitClassDeclaration(const ASTNode* node) override {
|
||||
auto* cls = static_cast<const ClassDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = cls->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "struct " << cls->name << " {\n";
|
||||
auto fields = cls->getChildren("fields");
|
||||
for (const auto* f : fields)
|
||||
oss << " " << generate(f) << "\n";
|
||||
oss << "}\n";
|
||||
auto methods = cls->getChildren("methods");
|
||||
if (!methods.empty()) {
|
||||
oss << "\nimpl " << cls->name << " {\n";
|
||||
for (const auto* m : methods) oss << generate(m);
|
||||
oss << "}\n";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitInterfaceDeclaration(const ASTNode* node) override {
|
||||
auto* iface = static_cast<const InterfaceDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "trait " << iface->name << " {\n";
|
||||
auto methods = iface->getChildren("methods");
|
||||
for (const auto* m : methods) {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(m);
|
||||
oss << " fn " << meth->name << "(&self);\n";
|
||||
}
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitMethodDeclaration(const ASTNode* node) override {
|
||||
auto* meth = static_cast<const MethodDeclaration*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = meth->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << " " << generate(a) << "\n";
|
||||
oss << " fn " << meth->name << "(";
|
||||
if (!meth->isStatic) oss << "&self";
|
||||
auto params = meth->getChildren("parameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (!meth->isStatic || i > 0) oss << ", ";
|
||||
oss << visitParameter(static_cast<const Parameter*>(params[i]));
|
||||
}
|
||||
oss << ")";
|
||||
auto retType = meth->getChild("returnType");
|
||||
if (retType) oss << " -> " << generate(retType);
|
||||
auto body = meth->getChildren("body");
|
||||
if (body.empty()) {
|
||||
oss << " {}\n";
|
||||
} else {
|
||||
oss << " {\n";
|
||||
emitBody(oss, body, " ");
|
||||
oss << " }\n";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitGenericType(const ASTNode* node) override {
|
||||
auto* gen = static_cast<const GenericType*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << gen->baseName << "<";
|
||||
auto params = gen->getChildren("typeParameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << generate(params[i]);
|
||||
}
|
||||
oss << ">";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitTypeParameter(const ASTNode* node) override {
|
||||
auto* tp = static_cast<const TypeParameter*>(node);
|
||||
return tp->name;
|
||||
}
|
||||
|
||||
std::string visitAsyncFunction(const ASTNode* node) override {
|
||||
auto* af = static_cast<const AsyncFunction*>(node);
|
||||
std::ostringstream oss;
|
||||
auto annotations = af->getChildren("annotations");
|
||||
for (const auto* a : annotations) oss << generate(a) << "\n";
|
||||
oss << "async fn " << af->name << "(";
|
||||
emitParameters(oss, af->getChildren("parameters"));
|
||||
oss << ")";
|
||||
auto retType = af->getChild("returnType");
|
||||
if (retType) oss << " -> " << generate(retType);
|
||||
oss << " {\n";
|
||||
emitBody(oss, af->getChildren("body"), " ");
|
||||
oss << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitAwaitExpression(const ASTNode* node) override {
|
||||
auto* aw = static_cast<const AwaitExpression*>(node);
|
||||
auto* expr = aw->getChild("expression");
|
||||
return (expr ? generate(expr) : "/* missing */") + ".await";
|
||||
}
|
||||
|
||||
std::string visitLambdaExpression(const ASTNode* node) override {
|
||||
auto* lam = static_cast<const LambdaExpression*>(node);
|
||||
std::ostringstream oss;
|
||||
oss << "|";
|
||||
auto params = lam->getChildren("parameters");
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) oss << ", ";
|
||||
oss << static_cast<const Parameter*>(params[i])->name;
|
||||
}
|
||||
oss << "| ";
|
||||
auto body = lam->getChildren("body");
|
||||
if (body.size() == 1) {
|
||||
oss << generate(body[0]);
|
||||
} else if (body.empty()) {
|
||||
oss << "()";
|
||||
} else {
|
||||
oss << "{ ";
|
||||
for (const auto* s : body) oss << generate(s) << " ";
|
||||
oss << "}";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitDecoratorAnnotation(const ASTNode* node) override {
|
||||
auto* dec = static_cast<const DecoratorAnnotation*>(node);
|
||||
return "// @" + dec->name;
|
||||
}
|
||||
|
||||
std::string visitDerefStrategy(const DerefStrategy* annotation) override {
|
||||
return "// @deref(" + annotation->strategy + ")";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user