From 1640dd0e27f15bf4631a4e54cab39b9905228280 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Fri, 11 Oct 2024 00:36:06 +0800 Subject: [PATCH] :art: do generic symbol copy & clone --- bootstrap/src/sema/func.h | 11 ++++++++ bootstrap/src/sema/regist_pass.cpp | 41 ++++++++++++++++++++++++++++-- bootstrap/src/sema/regist_pass.h | 2 ++ bootstrap/src/sema/semantic.cpp | 18 +++++++++++-- bootstrap/src/sema/struct.h | 11 ++++++++ 5 files changed, 79 insertions(+), 4 deletions(-) diff --git a/bootstrap/src/sema/func.h b/bootstrap/src/sema/func.h index c722b28..3e952bd 100644 --- a/bootstrap/src/sema/func.h +++ b/bootstrap/src/sema/func.h @@ -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&); diff --git a/bootstrap/src/sema/regist_pass.cpp b/bootstrap/src/sema/regist_pass.cpp index 276ab65..5bfe173 100644 --- a/bootstrap/src/sema/regist_pass.cpp +++ b/bootstrap/src/sema/regist_pass.cpp @@ -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(); } } \ No newline at end of file diff --git a/bootstrap/src/sema/regist_pass.h b/bootstrap/src/sema/regist_pass.h index adf4653..4831481 100644 --- a/bootstrap/src/sema/regist_pass.h +++ b/bootstrap/src/sema/regist_pass.h @@ -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 types; }; @@ -41,6 +42,7 @@ public: n->accept(this); } void dump() const; + void insert_into_symbol_table(); }; class regist_pass { diff --git a/bootstrap/src/sema/semantic.cpp b/bootstrap/src/sema/semantic.cpp index a4f0562..dee20da 100644 --- a/bootstrap/src/sema/semantic.cpp +++ b/bootstrap/src/sema/semantic.cpp @@ -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; } diff --git a/bootstrap/src/sema/struct.h b/bootstrap/src/sema/struct.h index 16f4ca0..86f52a2 100644 --- a/bootstrap/src/sema/struct.h +++ b/bootstrap/src/sema/struct.h @@ -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; };