Step 340: C++ Generator — Preprocessor, Enum, Namespace (12/12 tests)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Bill
2026-02-16 08:17:50 -07:00
parent 93d84fd29b
commit e958c778f3
12 changed files with 776 additions and 0 deletions

View File

@@ -354,4 +354,59 @@ public:
std::string visitInlineAnnotation(const InlineAnnotation* a) override { return semanno(a); }
std::string visitPureAnnotation(const PureAnnotation* a) override { return semanno(a); }
std::string visitConstExprAnnotation(const ConstExprAnnotation* a) override { return semanno(a); }
// --- Preprocessor/Enum/Namespace visitors (Step 340) ---
std::string visitIncludeDirective(const ASTNode* node) override {
auto* inc = static_cast<const IncludeDirective*>(node);
std::string mod = inc->path;
auto dot = mod.rfind('.');
if (dot != std::string::npos) mod = mod.substr(0, dot);
for (auto& c : mod) { if (c == '/' || c == '\\') c = '.'; }
return "using " + mod + ";";
}
std::string visitPragmaDirective(const ASTNode* node) override {
auto* prag = static_cast<const PragmaDirective*>(node);
return "#pragma " + prag->directive;
}
std::string visitMacroDefinition(const ASTNode* node) override {
auto* mac = static_cast<const MacroDefinition*>(node);
return "public const var " + mac->name + " = " + (mac->body.empty() ? "null" : mac->body) + ";";
}
std::string visitEnumDeclaration(const ASTNode* node) override {
auto* e = static_cast<const EnumDeclaration*>(node);
std::ostringstream oss;
oss << "enum " << e->name;
if (!e->underlyingType.empty()) oss << " : " << e->underlyingType;
oss << "\n{\n";
auto members = e->getChildren("members");
for (size_t i = 0; i < members.size(); ++i) {
auto* m = static_cast<const EnumMember*>(members[i]);
oss << " " << m->name;
if (!m->value.empty()) oss << " = " << m->value;
if (i + 1 < members.size()) oss << ",";
oss << "\n";
}
oss << "}";
return oss.str();
}
std::string visitNamespaceDeclaration(const ASTNode* node) override {
auto* ns = static_cast<const NamespaceDeclaration*>(node);
std::ostringstream oss;
oss << "namespace " << ns->name << "\n{\n";
auto body = ns->getChildren("body");
for (const auto* child : body)
oss << " " << generate(child) << "\n";
oss << "}";
return oss.str();
}
std::string visitTypeAlias(const ASTNode* node) override {
auto* ta = static_cast<const TypeAlias*>(node);
return "using " + ta->aliasName + " = " + ta->targetType + ";";
}
};

View File

@@ -320,6 +320,79 @@
return "constexpr";
}
// --- Preprocessor/Enum/Namespace visitors (Step 340) ---
std::string visitIncludeDirective(const ASTNode* node) override {
auto* inc = static_cast<const IncludeDirective*>(node);
if (inc->isSystem)
return "#include <" + inc->path + ">";
return "#include \"" + inc->path + "\"";
}
std::string visitPragmaDirective(const ASTNode* node) override {
auto* prag = static_cast<const PragmaDirective*>(node);
return "#pragma " + prag->directive;
}
std::string visitMacroDefinition(const ASTNode* node) override {
auto* mac = static_cast<const MacroDefinition*>(node);
std::ostringstream oss;
oss << "#define " << mac->name;
if (mac->isFunctionLike) {
oss << "(";
for (size_t i = 0; i < mac->parameters.size(); ++i) {
if (i > 0) oss << ", ";
oss << mac->parameters[i];
}
oss << ")";
}
if (!mac->body.empty()) oss << " " << mac->body;
return oss.str();
}
std::string visitEnumDeclaration(const ASTNode* node) override {
auto* e = static_cast<const EnumDeclaration*>(node);
std::ostringstream oss;
if (e->isScoped)
oss << "enum class " << e->name;
else
oss << "enum " << e->name;
if (!e->underlyingType.empty())
oss << " : " << e->underlyingType;
oss << " {\n";
auto members = e->getChildren("members");
for (size_t i = 0; i < members.size(); ++i) {
auto* m = static_cast<const EnumMember*>(members[i]);
oss << " " << m->name;
if (!m->value.empty()) oss << " = " << m->value;
if (i + 1 < members.size()) oss << ",";
oss << "\n";
}
oss << "};\n";
return oss.str();
}
std::string visitNamespaceDeclaration(const ASTNode* node) override {
auto* ns = static_cast<const NamespaceDeclaration*>(node);
std::ostringstream oss;
if (ns->name.empty())
oss << "namespace {\n";
else
oss << "namespace " << ns->name << " {\n";
auto body = ns->getChildren("body");
for (const auto* child : body)
oss << " " << generate(child) << "\n";
oss << "}\n";
return oss.str();
}
std::string visitTypeAlias(const ASTNode* node) override {
auto* ta = static_cast<const TypeAlias*>(node);
if (ta->isUsing)
return "using " + ta->aliasName + " = " + ta->targetType + ";";
return "typedef " + ta->targetType + " " + ta->aliasName + ";";
}
private:
// Check enclosing function's memory annotations to determine smart-pointer wrapper
std::string getMemoryTypeWrapper(const Variable* variable) const {

View File

@@ -665,4 +665,62 @@ public:
std::string visitConstExprAnnotation(const ConstExprAnnotation*) override {
return "; @constexpr - Compile-time evaluable";
}
// --- Preprocessor/Enum/Namespace visitors (Step 340) ---
std::string visitIncludeDirective(const ASTNode* node) override {
auto* inc = static_cast<const IncludeDirective*>(node);
std::string mod = inc->path;
auto dot = mod.rfind('.');
if (dot != std::string::npos) mod = mod.substr(0, dot);
return "(require '" + mod + ")";
}
std::string visitPragmaDirective(const ASTNode* node) override {
auto* prag = static_cast<const PragmaDirective*>(node);
return ";; pragma " + prag->directive;
}
std::string visitMacroDefinition(const ASTNode* node) override {
auto* mac = static_cast<const MacroDefinition*>(node);
if (mac->isFunctionLike) {
std::ostringstream oss;
oss << "(defmacro " << mac->name << " (";
for (size_t i = 0; i < mac->parameters.size(); ++i) {
if (i > 0) oss << " ";
oss << mac->parameters[i];
}
oss << ")\n " << (mac->body.empty() ? "nil" : mac->body) << ")";
return oss.str();
}
return "(defconst " + mac->name + " " + (mac->body.empty() ? "nil" : mac->body) + ")";
}
std::string visitEnumDeclaration(const ASTNode* node) override {
auto* e = static_cast<const EnumDeclaration*>(node);
std::ostringstream oss;
auto members = e->getChildren("members");
for (size_t i = 0; i < members.size(); ++i) {
auto* m = static_cast<const EnumMember*>(members[i]);
oss << "(defconst " << e->name << "-" << m->name << " "
<< (m->value.empty() ? std::to_string(i) : m->value) << ")";
if (i + 1 < members.size()) oss << "\n";
}
return oss.str();
}
std::string visitNamespaceDeclaration(const ASTNode* node) override {
auto* ns = static_cast<const NamespaceDeclaration*>(node);
std::ostringstream oss;
oss << ";; namespace " << ns->name << "\n";
auto body = ns->getChildren("body");
for (const auto* child : body)
oss << generate(child) << "\n";
return oss.str();
}
std::string visitTypeAlias(const ASTNode* node) override {
auto* ta = static_cast<const TypeAlias*>(node);
return "(defalias '" + ta->aliasName + " '" + ta->targetType + ")";
}
};

View File

@@ -573,6 +573,53 @@ public:
return "// @constexpr";
}
// --- Preprocessor/Enum/Namespace visitors (Step 340) ---
std::string visitIncludeDirective(const ASTNode* node) override {
auto* inc = static_cast<const IncludeDirective*>(node);
return "import \"" + inc->path + "\"";
}
std::string visitPragmaDirective(const ASTNode* node) override {
auto* prag = static_cast<const PragmaDirective*>(node);
return "// pragma " + prag->directive;
}
std::string visitMacroDefinition(const ASTNode* node) override {
auto* mac = static_cast<const MacroDefinition*>(node);
return "const " + mac->name + " = " + (mac->body.empty() ? "0" : mac->body);
}
std::string visitEnumDeclaration(const ASTNode* node) override {
auto* e = static_cast<const EnumDeclaration*>(node);
std::ostringstream oss;
oss << "type " << e->name << " int\n\nconst (\n";
auto members = e->getChildren("members");
for (size_t i = 0; i < members.size(); ++i) {
auto* m = static_cast<const EnumMember*>(members[i]);
oss << " " << m->name;
if (i == 0) oss << " " << e->name << " = iota";
oss << "\n";
}
oss << ")";
return oss.str();
}
std::string visitNamespaceDeclaration(const ASTNode* node) override {
auto* ns = static_cast<const NamespaceDeclaration*>(node);
std::ostringstream oss;
oss << "package " << ns->name << "\n";
auto body = ns->getChildren("body");
for (const auto* child : body)
oss << generate(child) << "\n";
return oss.str();
}
std::string visitTypeAlias(const ASTNode* node) override {
auto* ta = static_cast<const TypeAlias*>(node);
return "type " + ta->aliasName + " = " + ta->targetType;
}
private:
static std::string emitImport(const Import* imp) {
std::string moduleName = imp->moduleName.empty() ? "" : imp->moduleName;

View File

@@ -652,6 +652,57 @@ public:
return "// @constexpr";
}
// --- Preprocessor/Enum/Namespace visitors (Step 340) ---
std::string visitIncludeDirective(const ASTNode* node) override {
auto* inc = static_cast<const IncludeDirective*>(node);
std::string mod = inc->path;
auto dot = mod.rfind('.');
if (dot != std::string::npos) mod = mod.substr(0, dot);
for (auto& c : mod) { if (c == '/' || c == '\\') c = '.'; }
return "import " + mod + ";";
}
std::string visitPragmaDirective(const ASTNode* node) override {
auto* prag = static_cast<const PragmaDirective*>(node);
return "// pragma " + prag->directive;
}
std::string visitMacroDefinition(const ASTNode* node) override {
auto* mac = static_cast<const MacroDefinition*>(node);
return "public static final var " + mac->name + " = " + (mac->body.empty() ? "null" : mac->body) + ";";
}
std::string visitEnumDeclaration(const ASTNode* node) override {
auto* e = static_cast<const EnumDeclaration*>(node);
std::ostringstream oss;
oss << "enum " << e->name << " {\n";
auto members = e->getChildren("members");
for (size_t i = 0; i < members.size(); ++i) {
auto* m = static_cast<const EnumMember*>(members[i]);
oss << " " << m->name;
if (i + 1 < members.size()) oss << ",";
oss << "\n";
}
oss << "}\n";
return oss.str();
}
std::string visitNamespaceDeclaration(const ASTNode* node) override {
auto* ns = static_cast<const NamespaceDeclaration*>(node);
std::ostringstream oss;
oss << "package " << ns->name << ";\n";
auto body = ns->getChildren("body");
for (const auto* child : body)
oss << generate(child) << "\n";
return oss.str();
}
std::string visitTypeAlias(const ASTNode* node) override {
auto* ta = static_cast<const TypeAlias*>(node);
return "// type alias: " + ta->aliasName + " = " + ta->targetType;
}
private:
static std::string emitImport(const Import* imp) {
std::string moduleName = imp->moduleName.empty() ? "module" : imp->moduleName;

View File

@@ -624,6 +624,56 @@ public:
return "// @constexpr";
}
// --- Preprocessor/Enum/Namespace visitors (Step 340) ---
std::string visitIncludeDirective(const ASTNode* node) override {
auto* inc = static_cast<const IncludeDirective*>(node);
std::string mod = inc->path;
auto dot = mod.rfind('.');
if (dot != std::string::npos) mod = mod.substr(0, dot);
return "import '" + mod + "';";
}
std::string visitPragmaDirective(const ASTNode* node) override {
auto* prag = static_cast<const PragmaDirective*>(node);
return "// pragma " + prag->directive;
}
std::string visitMacroDefinition(const ASTNode* node) override {
auto* mac = static_cast<const MacroDefinition*>(node);
return "const " + mac->name + " = " + (mac->body.empty() ? "undefined" : mac->body) + ";";
}
std::string visitEnumDeclaration(const ASTNode* node) override {
auto* e = static_cast<const EnumDeclaration*>(node);
std::ostringstream oss;
oss << "const " << e->name << " = Object.freeze({\n";
auto members = e->getChildren("members");
for (size_t i = 0; i < members.size(); ++i) {
auto* m = static_cast<const EnumMember*>(members[i]);
oss << " " << m->name << ": " << (m->value.empty() ? std::to_string(i) : m->value);
if (i + 1 < members.size()) oss << ",";
oss << "\n";
}
oss << "});";
return oss.str();
}
std::string visitNamespaceDeclaration(const ASTNode* node) override {
auto* ns = static_cast<const NamespaceDeclaration*>(node);
std::ostringstream oss;
oss << "// namespace " << ns->name << "\n";
auto body = ns->getChildren("body");
for (const auto* child : body)
oss << generate(child) << "\n";
return oss.str();
}
std::string visitTypeAlias(const ASTNode* node) override {
auto* ta = static_cast<const TypeAlias*>(node);
return "/** @typedef {" + ta->targetType + "} " + ta->aliasName + " */";
}
protected:
bool includeTypes_ = false;

View File

@@ -374,4 +374,55 @@ public:
std::string visitInlineAnnotation(const InlineAnnotation* a) override { return semanno(a); }
std::string visitPureAnnotation(const PureAnnotation* a) override { return semanno(a); }
std::string visitConstExprAnnotation(const ConstExprAnnotation* a) override { return semanno(a); }
// --- Preprocessor/Enum/Namespace visitors (Step 340) ---
std::string visitIncludeDirective(const ASTNode* node) override {
auto* inc = static_cast<const IncludeDirective*>(node);
std::string mod = inc->path;
auto dot = mod.rfind('.');
if (dot != std::string::npos) mod = mod.substr(0, dot);
for (auto& c : mod) { if (c == '/' || c == '\\') c = '.'; }
return "import " + mod;
}
std::string visitPragmaDirective(const ASTNode* node) override {
auto* prag = static_cast<const PragmaDirective*>(node);
return "// pragma " + prag->directive;
}
std::string visitMacroDefinition(const ASTNode* node) override {
auto* mac = static_cast<const MacroDefinition*>(node);
return "const val " + mac->name + " = " + (mac->body.empty() ? "null" : mac->body);
}
std::string visitEnumDeclaration(const ASTNode* node) override {
auto* e = static_cast<const EnumDeclaration*>(node);
std::ostringstream oss;
oss << "enum class " << e->name << " {\n";
auto members = e->getChildren("members");
for (size_t i = 0; i < members.size(); ++i) {
auto* m = static_cast<const EnumMember*>(members[i]);
oss << " " << m->name;
if (i + 1 < members.size()) oss << ",";
oss << "\n";
}
oss << "}";
return oss.str();
}
std::string visitNamespaceDeclaration(const ASTNode* node) override {
auto* ns = static_cast<const NamespaceDeclaration*>(node);
std::ostringstream oss;
oss << "package " << ns->name << "\n";
auto body = ns->getChildren("body");
for (const auto* child : body)
oss << generate(child) << "\n";
return oss.str();
}
std::string visitTypeAlias(const ASTNode* node) override {
auto* ta = static_cast<const TypeAlias*>(node);
return "typealias " + ta->aliasName + " = " + ta->targetType;
}
};

View File

@@ -14,6 +14,8 @@
#include "Annotation.h"
#include "AnnotationVisitors.h"
#include "HostBoundary.h"
#include "PreprocessorNodes.h"
#include "EnumNamespaceNodes.h"
class ProjectionGenerator : public virtual AnnotationVisitorExtended {
public:
@@ -75,6 +77,14 @@ public:
virtual std::string visitLambdaExpression(const ASTNode* node) { return ""; }
virtual std::string visitDecoratorAnnotation(const ASTNode* node) { return ""; }
// Preprocessor/Enum/Namespace visitors (Step 340)
virtual std::string visitIncludeDirective(const ASTNode* node) { return ""; }
virtual std::string visitPragmaDirective(const ASTNode* node) { return ""; }
virtual std::string visitMacroDefinition(const ASTNode* node) { return ""; }
virtual std::string visitEnumDeclaration(const ASTNode* node) { return ""; }
virtual std::string visitNamespaceDeclaration(const ASTNode* node) { return ""; }
virtual std::string visitTypeAlias(const ASTNode* node) { return ""; }
// Host boundary visitors
virtual std::string visitHostCall(const HostCall* node) { return ""; }
virtual std::string visitScheduleTask(const ScheduleTask* node) { return ""; }
@@ -350,6 +360,20 @@ std::string dispatchGenerate(Gen* gen, const ASTNode* node, const std::string& u
} else if (node->conceptType == "DecoratorAnnotation") {
return gen->visitDecoratorAnnotation(node);
}
// Preprocessor/Enum/Namespace dispatch (Step 340)
else if (node->conceptType == "IncludeDirective") {
return gen->visitIncludeDirective(node);
} else if (node->conceptType == "PragmaDirective") {
return gen->visitPragmaDirective(node);
} else if (node->conceptType == "MacroDefinition") {
return gen->visitMacroDefinition(node);
} else if (node->conceptType == "EnumDeclaration") {
return gen->visitEnumDeclaration(node);
} else if (node->conceptType == "NamespaceDeclaration") {
return gen->visitNamespaceDeclaration(node);
} else if (node->conceptType == "TypeAlias") {
return gen->visitTypeAlias(node);
}
return unknownPrefix + node->conceptType;
}

View File

@@ -727,4 +727,62 @@ public:
std::string visitConstExprAnnotation(const ConstExprAnnotation*) override {
return "# @constexpr - Compile-time evaluable";
}
// --- Preprocessor/Enum/Namespace visitors (Step 340) ---
std::string visitIncludeDirective(const ASTNode* node) override {
auto* inc = static_cast<const IncludeDirective*>(node);
std::string mod = inc->path;
auto dot = mod.rfind('.');
if (dot != std::string::npos) mod = mod.substr(0, dot);
for (auto& c : mod) { if (c == '/' || c == '\\') c = '.'; }
return "import " + mod;
}
std::string visitPragmaDirective(const ASTNode*) override {
return "# pragma (no Python equivalent)";
}
std::string visitMacroDefinition(const ASTNode* node) override {
auto* mac = static_cast<const MacroDefinition*>(node);
if (mac->isFunctionLike) {
std::ostringstream oss;
oss << "def " << mac->name << "(";
for (size_t i = 0; i < mac->parameters.size(); ++i) {
if (i > 0) oss << ", ";
oss << mac->parameters[i];
}
oss << "):\n return " << (mac->body.empty() ? "None" : mac->body);
return oss.str();
}
return mac->name + " = " + (mac->body.empty() ? "None" : mac->body);
}
std::string visitEnumDeclaration(const ASTNode* node) override {
auto* e = static_cast<const EnumDeclaration*>(node);
std::ostringstream oss;
oss << "class " << e->name << "(Enum):\n";
auto members = e->getChildren("members");
for (size_t i = 0; i < members.size(); ++i) {
auto* m = static_cast<const EnumMember*>(members[i]);
oss << " " << m->name << " = " << (m->value.empty() ? std::to_string(i) : m->value) << "\n";
}
if (members.empty()) oss << " pass\n";
return oss.str();
}
std::string visitNamespaceDeclaration(const ASTNode* node) override {
auto* ns = static_cast<const NamespaceDeclaration*>(node);
std::ostringstream oss;
oss << "# namespace " << ns->name << "\n";
auto body = ns->getChildren("body");
for (const auto* child : body)
oss << generate(child) << "\n";
return oss.str();
}
std::string visitTypeAlias(const ASTNode* node) override {
auto* ta = static_cast<const TypeAlias*>(node);
return ta->aliasName + " = " + ta->targetType;
}
};

View File

@@ -607,6 +607,62 @@ public:
return "// @constexpr";
}
// --- Preprocessor/Enum/Namespace visitors (Step 340) ---
std::string visitIncludeDirective(const ASTNode* node) override {
auto* inc = static_cast<const IncludeDirective*>(node);
std::string mod = inc->path;
auto dot = mod.rfind('.');
if (dot != std::string::npos) mod = mod.substr(0, dot);
for (auto& c : mod) { if (c == '/' || c == '\\') c = ':'; }
return "use " + mod + ";";
}
std::string visitPragmaDirective(const ASTNode* node) override {
auto* prag = static_cast<const PragmaDirective*>(node);
return "#![" + prag->directive + "]";
}
std::string visitMacroDefinition(const ASTNode* node) override {
auto* mac = static_cast<const MacroDefinition*>(node);
std::ostringstream oss;
oss << "macro_rules! " << mac->name << " {\n";
oss << " () => { " << (mac->body.empty() ? "" : mac->body) << " };\n";
oss << "}";
return oss.str();
}
std::string visitEnumDeclaration(const ASTNode* node) override {
auto* e = static_cast<const EnumDeclaration*>(node);
std::ostringstream oss;
oss << "enum " << e->name << " {\n";
auto members = e->getChildren("members");
for (size_t i = 0; i < members.size(); ++i) {
auto* m = static_cast<const EnumMember*>(members[i]);
oss << " " << m->name;
if (!m->value.empty()) oss << " = " << m->value;
oss << ",\n";
}
oss << "}";
return oss.str();
}
std::string visitNamespaceDeclaration(const ASTNode* node) override {
auto* ns = static_cast<const NamespaceDeclaration*>(node);
std::ostringstream oss;
oss << "mod " << ns->name << " {\n";
auto body = ns->getChildren("body");
for (const auto* child : body)
oss << " " << generate(child) << "\n";
oss << "}";
return oss.str();
}
std::string visitTypeAlias(const ASTNode* node) override {
auto* ta = static_cast<const TypeAlias*>(node);
return "type " + ta->aliasName + " = " + ta->targetType + ";";
}
private:
static std::string emitImport(const Import* imp) {
std::string moduleName = imp->moduleName.empty() ? "crate" : imp->moduleName;