Step 121: add import/external module AST concepts

This commit is contained in:
Bill
2026-02-09 15:00:26 -07:00
parent 664645852d
commit 1fd567fb20
8 changed files with 198 additions and 2 deletions

View File

@@ -0,0 +1,19 @@
#pragma once
#include "ASTNode.h"
class ExternalModule : public ASTNode {
public:
std::string name;
std::string version;
std::string language;
ExternalModule() { conceptType = "ExternalModule"; }
ExternalModule(const std::string& id, const std::string& name,
const std::string& language,
const std::string& version = "")
: name(name), version(version), language(language) {
this->id = id;
this->conceptType = "ExternalModule";
}
// children: signatures (0..n) via addChild("signatures", TypeSignature*)
};

18
editor/src/ast/Import.h Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
#include "ASTNode.h"
class Import : public ASTNode {
public:
std::string moduleName;
std::string alias;
std::string importKind; // "module", "include", "require"
Import() { conceptType = "Import"; }
Import(const std::string& id, const std::string& module,
const std::string& kind = "module",
const std::string& alias = "")
: moduleName(module), alias(alias), importKind(kind) {
this->id = id;
this->conceptType = "Import";
}
};

View File

@@ -80,6 +80,8 @@ private:
addRule("Module", "variables", {"Variable"}, false); // multi-valued
addRule("Module", "targetLanguage", {}, true); // property, not used for AST nodes
addRule("Module", "annotations", {"DerefStrategy", "OptimizationLock", "LangSpecific"}, false); // multi-valued
addRule("Module", "imports", {"Import"}, false); // multi-valued
addRule("Module", "externalModules", {"ExternalModule"}, false); // multi-valued
// Function concept rules
addRule("Function", "parameters", {"Parameter"}, false); // multi-valued
@@ -151,6 +153,17 @@ private:
// Type concepts - no child rules needed as they're leaf nodes for types
// Annotation concepts - no child rules needed as they're leaf nodes for annotations
// External module concepts
addRule("ExternalModule", "signatures", {"TypeSignature"}, false); // multi-valued
addRule("TypeSignature", "returnType",
{"PrimitiveType", "ListType", "SetType", "MapType", "TupleType",
"ArrayType", "OptionalType", "CustomType"},
true);
addRule("TypeSignature", "paramTypes",
{"PrimitiveType", "ListType", "SetType", "MapType", "TupleType",
"ArrayType", "OptionalType", "CustomType"},
false);
}
void addRule(const std::string& parentConcept, const std::string& role, const std::vector<std::string>& allowedConcepts, bool isSingleValued) {
@@ -159,4 +172,4 @@ private:
rule.isSingleValued = isSingleValued;
schema_[parentConcept][role] = rule;
}
};
};

View File

@@ -9,6 +9,9 @@
#include "Expression.h"
#include "Type.h"
#include "Annotation.h"
#include "Import.h"
#include "ExternalModule.h"
#include "TypeSignature.h"
using json = nlohmann::json;
@@ -88,6 +91,24 @@ inline json propertiesToJson(const ASTNode* node) {
auto* n = static_cast<const CustomType*>(node);
props["typeName"] = n->typeName;
}
// Imports / External modules
else if (ct == "Import") {
auto* n = static_cast<const Import*>(node);
props["moduleName"] = n->moduleName;
if (!n->alias.empty()) props["alias"] = n->alias;
if (!n->importKind.empty()) props["importKind"] = n->importKind;
}
else if (ct == "ExternalModule") {
auto* n = static_cast<const ExternalModule*>(node);
props["name"] = n->name;
if (!n->version.empty()) props["version"] = n->version;
if (!n->language.empty()) props["language"] = n->language;
}
else if (ct == "TypeSignature") {
auto* n = static_cast<const TypeSignature*>(node);
props["name"] = n->name;
props["variadic"] = n->variadic;
}
// Annotations
else if (ct == "DerefStrategy") {
auto* n = static_cast<const DerefStrategy*>(node);
@@ -177,6 +198,9 @@ inline ASTNode* createNode(const std::string& conceptName) {
if (conceptName == "ArrayType") return new ArrayType();
if (conceptName == "OptionalType") return new OptionalType();
if (conceptName == "CustomType") return new CustomType();
if (conceptName == "Import") return new Import();
if (conceptName == "ExternalModule") return new ExternalModule();
if (conceptName == "TypeSignature") return new TypeSignature();
if (conceptName == "DerefStrategy") return new DerefStrategy();
if (conceptName == "OptimizationLock") return new OptimizationLock();
if (conceptName == "LangSpecific") return new LangSpecific();
@@ -251,6 +275,23 @@ inline void setPropertiesFromJson(ASTNode* node, const json& props) {
auto* n = static_cast<CustomType*>(node);
if (props.contains("typeName")) n->typeName = props["typeName"].get<std::string>();
}
else if (ct == "Import") {
auto* n = static_cast<Import*>(node);
if (props.contains("moduleName")) n->moduleName = props["moduleName"].get<std::string>();
if (props.contains("alias")) n->alias = props["alias"].get<std::string>();
if (props.contains("importKind")) n->importKind = props["importKind"].get<std::string>();
}
else if (ct == "ExternalModule") {
auto* n = static_cast<ExternalModule*>(node);
if (props.contains("name")) n->name = props["name"].get<std::string>();
if (props.contains("version")) n->version = props["version"].get<std::string>();
if (props.contains("language")) n->language = props["language"].get<std::string>();
}
else if (ct == "TypeSignature") {
auto* n = static_cast<TypeSignature*>(node);
if (props.contains("name")) n->name = props["name"].get<std::string>();
if (props.contains("variadic")) n->variadic = props["variadic"].get<bool>();
}
else if (ct == "DerefStrategy") {
auto* n = static_cast<DerefStrategy*>(node);
if (props.contains("strategy")) n->strategy = props["strategy"].get<std::string>();

View File

@@ -0,0 +1,17 @@
#pragma once
#include "ASTNode.h"
class TypeSignature : public ASTNode {
public:
std::string name;
bool variadic = false;
TypeSignature() { conceptType = "TypeSignature"; }
TypeSignature(const std::string& id, const std::string& name, bool variadic = false)
: name(name), variadic(variadic) {
this->id = id;
this->conceptType = "TypeSignature";
}
// children: returnType (1) via setChild("returnType", Type*)
// children: paramTypes (0..n) via addChild("paramTypes", Type*)
};