🎨 do generic symbol copy & clone

This commit is contained in:
ValKmjolnir 2024-10-11 00:36:06 +08:00
parent 8e9439158e
commit 1640dd0e27
5 changed files with 79 additions and 4 deletions

View File

@ -30,6 +30,17 @@ public:
bool is_extern = false;
public:
colgm_func() = default;
colgm_func(const colgm_func& f):
name(f.name), location(f.location),
return_type(f.return_type), parameters(f.parameters),
unordered_params(f.unordered_params), generic_template(f.generic_template),
generic_func_decl(nullptr),
is_public(f.is_public), is_extern(f.is_extern) {
if (f.generic_func_decl) {
generic_func_decl = f.generic_func_decl->clone();
}
}
~colgm_func();
bool find_parameter(const std::string&);
void add_parameter(const std::string&, const type&);

View File

@ -57,8 +57,9 @@ bool generic_visitor::visit_call_id(ast::call_id* node) {
const auto& generic_template = sym.kind == sym_kind::struct_kind
? dm.generic_structs.at(type_name).generic_template
: dm.generic_functions.at(type_name).generic_template;
const auto& type_list = node->get_generic_types()->get_types();
if (node->get_generic_types()->get_types().size() != generic_template.size()) {
if (type_list.size() != generic_template.size()) {
rp.report(node, "generic type count does not match.");
return true;
}
@ -66,7 +67,7 @@ bool generic_visitor::visit_call_id(ast::call_id* node) {
// generate real name
std::stringstream ss;
ss << type_name << "<";
for (auto i : node->get_generic_types()->get_types()) {
for (auto i : type_list) {
const auto& name = i->get_name()->get_name();
const auto type = tr.resolve(i);
ss << type.full_path_name();
@ -86,6 +87,7 @@ bool generic_visitor::visit_call_id(ast::call_id* node) {
generic_data_map.insert({ss.str(), {}});
auto& data = generic_data_map.at(ss.str());
data.name = type_name;
data.generated_name = ss.str();
data.loc_file = sym.loc_file;
for(i64 i = 0; i < generic_template.size(); ++i) {
@ -111,6 +113,40 @@ void generic_visitor::dump() const {
}
}
void generic_visitor::insert_into_symbol_table() {
for(const auto& i : generic_data_map) {
const auto& data = i.second;
// insert type
const auto t = type {
.name = data.generated_name,
.loc_file = data.loc_file
};
if (!ctx.global.domain.count(data.loc_file)) {
continue;
}
auto& dm = ctx.global.domain.at(data.loc_file);
if (dm.generic_structs.count(data.name)) {
const auto& generic = dm.generic_structs.at(data.name);
dm.structs.insert({
data.generated_name,
generic
});
// FIXME: do type replace
}
if (dm.generic_functions.count(data.name)) {
const auto& generic = dm.generic_functions.at(data.name);
dm.functions.insert({
data.generated_name,
generic
});
// FIXME: do type replace
}
}
}
bool regist_pass::check_is_public_struct(ast::identifier* node,
const colgm_module& domain) {
const auto& name = node->get_name();
@ -890,6 +926,7 @@ void regist_pass::run(ast::root* ast_root) {
}
gnv.visit(ast_root);
gnv.insert_into_symbol_table();
}
}

View File

@ -18,6 +18,7 @@ class generic_visitor: public ast::visitor {
private:
struct generic_data {
std::string name;
std::string generated_name;
std::string loc_file;
std::unordered_map<std::string, type> types;
};
@ -41,6 +42,7 @@ public:
n->accept(this);
}
void dump() const;
void insert_into_symbol_table();
};
class regist_pass {

View File

@ -591,8 +591,22 @@ type semantic::resolve_call_id(call_id* node) {
name.pop_back();
}
name += ">";
const auto t = type {.name = name, .loc_file = infer.loc_file};
rp.warn(node, "call id: " + t.full_path_name());
const auto t = type {
.name = name,
.loc_file = infer.loc_file
};
const auto generated_name = t.full_path_name();
if (!ctx.global.domain.count(infer.loc_file)) {
rp.report(node, "namespace in \"" + infer.loc_file + "\" not found.");
return infer;
}
const auto& dm = ctx.global.domain.at(infer.loc_file);
if (dm.structs.count(generated_name) ||
dm.functions.count(generated_name)) {
infer.name = generated_name;
}
}
return infer;
}

View File

@ -31,6 +31,17 @@ public:
bool is_extern = false;
public:
colgm_struct() = default;
colgm_struct(const colgm_struct& s):
name(s.name), location(s.location),
field(s.field), ordered_field(s.ordered_field),
static_method(s.static_method), method(s.method), generic_template(s.generic_template),
generic_struct_impl({}), is_public(s.is_public),
is_extern(s.is_extern) {
for(auto i : s.generic_struct_impl) {
generic_struct_impl.push_back(i->clone());
}
}
~colgm_struct();
usize field_index(const std::string&) const;
};