mirror of https://github.com/colgm/colgm.git
🎨 do generic symbol copy & clone
This commit is contained in:
parent
8e9439158e
commit
1640dd0e27
|
@ -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&);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue