[Fix] 修复Implement没有向上级查找的BUG ! 非常抱歉

This commit is contained in:
2025-12-30 18:14:48 +08:00
parent b76d1e6edf
commit 95f74356a8

View File

@@ -33,37 +33,33 @@ namespace Fig
std::unordered_map<std::size_t, FString> functionNames; std::unordered_map<std::size_t, FString> functionNames;
// implRegistry <Struct, ordered list of ImplRecord> // implRegistry <Struct, ordered list of ImplRecord>
std::unordered_map<TypeInfo, std::vector<ImplRecord>, TypeInfoHash> implRegistry; std::unordered_map<TypeInfo, std::vector<ImplRecord>, TypeInfoHash>
implRegistry;
public: public:
ContextPtr parent; ContextPtr parent;
Context(const Context &) = default; Context(const Context &) = default;
Context(const FString &name, ContextPtr p = nullptr) : Context(const FString &name, ContextPtr p = nullptr) :
scopeName(name), parent(p) {} scopeName(name), parent(p)
void setParent(ContextPtr _parent)
{ {
parent = _parent;
} }
void setScopeName(FString _name) void setParent(ContextPtr _parent) { parent = _parent; }
{
scopeName = std::move(_name);
}
FString getScopeName() const void setScopeName(FString _name) { scopeName = std::move(_name); }
{
return scopeName; FString getScopeName() const { return scopeName; }
}
void merge(const Context &c) void merge(const Context &c)
{ {
variables.insert(c.variables.begin(), c.variables.end()); variables.insert(c.variables.begin(), c.variables.end());
functions.insert(c.functions.begin(), c.functions.end()); functions.insert(c.functions.begin(), c.functions.end());
functionNames.insert(c.functionNames.begin(), c.functionNames.end()); functionNames.insert(c.functionNames.begin(),
c.functionNames.end());
implRegistry.insert(c.implRegistry.begin(), c.implRegistry.end()); implRegistry.insert(c.implRegistry.begin(), c.implRegistry.end());
// structTypeNames.insert(c.structTypeNames.begin(), c.structTypeNames.end()); // structTypeNames.insert(c.structTypeNames.begin(),
// c.structTypeNames.end());
} }
std::unordered_map<size_t, Function> getFunctions() const std::unordered_map<size_t, Function> getFunctions() const
@@ -74,25 +70,22 @@ namespace Fig
std::shared_ptr<VariableSlot> get(const FString &name) std::shared_ptr<VariableSlot> get(const FString &name)
{ {
auto it = variables.find(name); auto it = variables.find(name);
if (it != variables.end()) if (it != variables.end()) return it->second;
return it->second; if (parent) return parent->get(name);
if (parent) throw RuntimeError(FString(std::format("Variable '{}' not defined",
return parent->get(name); name.toBasicString())));
throw RuntimeError(FString(std::format("Variable '{}' not defined", name.toBasicString())));
} }
AccessModifier getAccessModifier(const FString &name) AccessModifier getAccessModifier(const FString &name)
{ {
if (variables.contains(name)) if (variables.contains(name)) { return variables[name]->am; }
{
return variables[name]->am;
}
else if (parent != nullptr) else if (parent != nullptr)
{ {
return parent->getAccessModifier(name); return parent->getAccessModifier(name);
} }
else else
{ {
throw RuntimeError(FString(std::format("Variable '{}' not defined", name.toBasicString()))); throw RuntimeError(FString(std::format(
"Variable '{}' not defined", name.toBasicString())));
} }
} }
bool isVariableMutable(const FString &name) bool isVariableMutable(const FString &name)
@@ -111,46 +104,43 @@ namespace Fig
{ {
if (!isVariableMutable(name)) if (!isVariableMutable(name))
{ {
throw RuntimeError(FString(std::format("Variable '{}' is immutable", name.toBasicString()))); throw RuntimeError(FString(std::format(
"Variable '{}' is immutable", name.toBasicString())));
} }
variables[name]->value = value; variables[name]->value = value;
} }
else if (parent != nullptr) else if (parent != nullptr) { parent->set(name, value); }
{
parent->set(name, value);
}
else else
{ {
throw RuntimeError(FString(std::format("Variable '{}' not defined", name.toBasicString()))); throw RuntimeError(FString(std::format(
"Variable '{}' not defined", name.toBasicString())));
} }
} }
void _update(const FString &name, ObjectPtr value) void _update(const FString &name, ObjectPtr value)
{ {
if (variables.contains(name)) if (variables.contains(name)) { variables[name]->value = value; }
{ else if (parent != nullptr) { parent->_update(name, value); }
variables[name]->value = value;
}
else if (parent != nullptr)
{
parent->_update(name, value);
}
else else
{ {
throw RuntimeError(FString(std::format("Variable '{}' not defined", name.toBasicString()))); throw RuntimeError(FString(std::format(
"Variable '{}' not defined", name.toBasicString())));
} }
} }
void def(const FString &name, const TypeInfo &ti, AccessModifier am, const ObjectPtr &value = Object::getNullInstance()) void def(const FString &name,
const TypeInfo &ti,
AccessModifier am,
const ObjectPtr &value = Object::getNullInstance())
{ {
if (containsInThisScope(name)) if (containsInThisScope(name))
{ {
throw RuntimeError(FString(std::format("Variable '{}' already defined in this scope", name.toBasicString()))); throw RuntimeError(FString(
std::format("Variable '{}' already defined in this scope",
name.toBasicString())));
} }
variables[name] = std::make_shared<VariableSlot>( variables[name] =
name, std::make_shared<VariableSlot>(name, value, ti, am);
value, if (ti == ValueType::Function
ti, and value->getTypeInfo() == ValueType::Function)
am);
if (ti == ValueType::Function and value->getTypeInfo() == ValueType::Function)
{ {
auto &fn = value->as<Function>(); auto &fn = value->as<Function>();
functions[fn.id] = fn; functions[fn.id] = fn;
@@ -165,34 +155,16 @@ namespace Fig
std::optional<Function> getFunction(std::size_t id) std::optional<Function> getFunction(std::size_t id)
{ {
auto it = functions.find(id); auto it = functions.find(id);
if (it != functions.end()) if (it != functions.end()) { return it->second; }
{ else if (parent) { return parent->getFunction(id); }
return it->second; else { return std::nullopt; }
}
else if (parent)
{
return parent->getFunction(id);
}
else
{
return std::nullopt;
}
} }
std::optional<FString> getFunctionName(std::size_t id) std::optional<FString> getFunctionName(std::size_t id)
{ {
auto it = functionNames.find(id); auto it = functionNames.find(id);
if (it != functionNames.end()) if (it != functionNames.end()) { return it->second; }
{ else if (parent) { return parent->getFunctionName(id); }
return it->second; else { return std::nullopt; }
}
else if (parent)
{
return parent->getFunctionName(id);
}
else
{
return std::nullopt;
}
} }
// std::optional<FString> getStructName(std::size_t id) // std::optional<FString> getStructName(std::size_t id)
// { // {
@@ -212,14 +184,8 @@ namespace Fig
// } // }
bool contains(const FString &name) bool contains(const FString &name)
{ {
if (variables.contains(name)) if (variables.contains(name)) { return true; }
{ else if (parent != nullptr) { return parent->contains(name); }
return true;
}
else if (parent != nullptr)
{
return parent->contains(name);
}
return false; return false;
} }
bool containsInThisScope(const FString &name) const bool containsInThisScope(const FString &name) const
@@ -249,7 +215,8 @@ namespace Fig
ContextPtr ctx = shared_from_this(); ContextPtr ctx = shared_from_this();
while (ctx) while (ctx)
{ {
if (ctx->getScopeName().find(u8"<While ") == 0 or ctx->getScopeName().find(u8"<For ") == 0) if (ctx->getScopeName().find(u8"<While ") == 0
or ctx->getScopeName().find(u8"<For ") == 0)
{ {
return true; return true;
} }
@@ -258,71 +225,73 @@ namespace Fig
return false; return false;
} }
bool hasImplRegisted(const TypeInfo &structType, const TypeInfo &interfaceType) const bool hasImplRegisted(const TypeInfo &structType,
const TypeInfo &interfaceType) const
{ {
auto it = implRegistry.find(structType); auto it = implRegistry.find(structType);
if (it != implRegistry.end()) if (it != implRegistry.end())
{ {
for (auto &r : it->second) for (auto &r : it->second)
{ {
if (r.interfaceType == interfaceType) if (r.interfaceType == interfaceType) return true;
return true;
} }
} }
return parent && parent->hasImplRegisted(structType, interfaceType); return parent && parent->hasImplRegisted(structType, interfaceType);
} }
std::optional<ImplRecord> getImplRecord(const TypeInfo &structType, const TypeInfo &interfaceType) const std::optional<ImplRecord>
getImplRecord(const TypeInfo &structType,
const TypeInfo &interfaceType) const
{ {
auto it = implRegistry.find(structType); auto it = implRegistry.find(structType);
if (it != implRegistry.end()) if (it != implRegistry.end())
{ {
for (auto &r : it->second) for (auto &r : it->second)
{ {
if (r.interfaceType == interfaceType) if (r.interfaceType == interfaceType) return r;
return r;
} }
} }
if (parent) if (parent) return parent->getImplRecord(structType, interfaceType);
return parent->getImplRecord(structType, interfaceType);
return std::nullopt; return std::nullopt;
} }
void setImplRecord(const TypeInfo &structType, const TypeInfo &interfaceType, const ImplRecord &record) void setImplRecord(const TypeInfo &structType,
const TypeInfo &interfaceType,
const ImplRecord &record)
{ {
auto &list = implRegistry[structType]; auto &list = implRegistry[structType];
for (auto &r : list) for (auto &r : list)
{ {
if (r.interfaceType == interfaceType) if (r.interfaceType == interfaceType) return;
return;
} }
list.push_back(record); // order is the level list.push_back(record); // order is the level
} }
bool hasMethodImplemented(const TypeInfo &structType, const FString &functionName) const bool hasMethodImplemented(const TypeInfo &structType,
const FString &functionName) const
{ {
auto it = implRegistry.find(structType); auto it = implRegistry.find(structType);
if (it == implRegistry.end()) if (it != implRegistry.end())
return false;
for (auto &record : it->second)
{ {
if (record.implMethods.contains(functionName)) for (auto &record : it->second)
return true; {
if (record.implMethods.contains(functionName)) return true;
}
} }
return false; return parent
&& parent->hasMethodImplemented(structType, functionName);
} }
bool hasDefaultImplementedMethod(const TypeInfo &structType, const FString &functionName) const bool hasDefaultImplementedMethod(const TypeInfo &structType,
const FString &functionName) const
{ {
auto it = implRegistry.find(structType); auto it = implRegistry.find(structType);
if (it == implRegistry.end()) if (it == implRegistry.end()) return false;
return false;
std::vector<TypeInfo> implementedInterfaces; std::vector<TypeInfo> implementedInterfaces;
for (auto &record : it->second) for (auto &record : it->second)
@@ -330,19 +299,16 @@ namespace Fig
for (auto &[_, slot] : variables) for (auto &[_, slot] : variables)
{ {
if (!slot->value->is<InterfaceType>()) if (!slot->value->is<InterfaceType>()) continue;
continue;
InterfaceType &interface = slot->value->as<InterfaceType>(); InterfaceType &interface = slot->value->as<InterfaceType>();
bool implemented = bool implemented = std::any_of(
std::any_of( implementedInterfaces.begin(),
implementedInterfaces.begin(), implementedInterfaces.end(),
implementedInterfaces.end(), [&](const TypeInfo &ti) { return ti == interface.type; });
[&](const TypeInfo &ti) { return ti == interface.type; });
if (!implemented) if (!implemented) continue;
continue;
for (auto &method : interface.methods) for (auto &method : interface.methods)
{ {
@@ -354,7 +320,8 @@ namespace Fig
return false; return false;
} }
Function getDefaultImplementedMethod(const TypeInfo &structType, const FString &functionName) Function getDefaultImplementedMethod(const TypeInfo &structType,
const FString &functionName)
{ {
// O(N²) // O(N²)
// SLOW // SLOW
@@ -365,8 +332,7 @@ namespace Fig
// i dont give a fuck // i dont give a fuck
auto it = implRegistry.find(structType); auto it = implRegistry.find(structType);
if (it == implRegistry.end()) if (it == implRegistry.end()) assert(false);
assert(false);
std::vector<TypeInfo> implementedInterfaces; std::vector<TypeInfo> implementedInterfaces;
for (auto &record : it->second) for (auto &record : it->second)
@@ -374,32 +340,27 @@ namespace Fig
for (auto &[_, slot] : variables) for (auto &[_, slot] : variables)
{ {
if (!slot->value->is<InterfaceType>()) if (!slot->value->is<InterfaceType>()) continue;
continue;
InterfaceType &interface = slot->value->as<InterfaceType>(); InterfaceType &interface = slot->value->as<InterfaceType>();
bool implemented = bool implemented = std::any_of(
std::any_of( implementedInterfaces.begin(),
implementedInterfaces.begin(), implementedInterfaces.end(),
implementedInterfaces.end(), [&](const TypeInfo &ti) { return ti == interface.type; });
[&](const TypeInfo &ti) { return ti == interface.type; });
if (!implemented) if (!implemented) continue;
continue;
for (auto &method : interface.methods) for (auto &method : interface.methods)
{ {
if (method.name == functionName) if (method.name == functionName)
{ {
if (!method.hasDefaultBody()) if (!method.hasDefaultBody()) assert(false);
assert(false);
return Function( return Function(method.paras,
method.paras, TypeInfo(method.returnType),
TypeInfo(method.returnType), method.defaultBody,
method.defaultBody, shared_from_this());
shared_from_this());
} }
} }
} }
@@ -407,17 +368,23 @@ namespace Fig
assert(false); assert(false);
} }
const Function &getImplementedMethod(const TypeInfo &structType, const FString &functionName) const const Function &getImplementedMethod(const TypeInfo &structType,
const FString &functionName) const
{ {
const auto &list = implRegistry.at(structType); auto it = implRegistry.find(structType);
for (auto &record : list) if (it != implRegistry.end())
{ {
auto it = record.implMethods.find(functionName); for (auto &record : it->second)
if (it != record.implMethods.end()) {
return it->second; auto fit = record.implMethods.find(functionName);
if (fit != record.implMethods.end()) return fit->second;
}
} }
assert(false); if (parent)
return parent->getImplementedMethod(structType, functionName);
assert(false); // not found
} }
void printStackTrace(std::ostream &os = std::cerr, int indent = 0) const void printStackTrace(std::ostream &os = std::cerr, int indent = 0) const
@@ -434,9 +401,8 @@ namespace Fig
os << "[STACK TRACE]\n"; os << "[STACK TRACE]\n";
for (int i = static_cast<int>(chain.size()) - 1; i >= 0; --i) for (int i = static_cast<int>(chain.size()) - 1; i >= 0; --i)
{ {
os << " #" << (chain.size() - 1 - i) os << " #" << (chain.size() - 1 - i) << " "
<< " " << chain[i]->scopeName.toBasicString() << chain[i]->scopeName.toBasicString() << "\n";
<< "\n";
} }
} }
}; };