mirror of https://github.com/colgm/colgm.git
🎨 fix complext generic type generation
This commit is contained in:
parent
55211ee666
commit
0b85f5ca51
|
@ -6,8 +6,6 @@
|
|||
#include "sema/semantic.h"
|
||||
#include "mir/ast2mir.h"
|
||||
|
||||
#include "ast/dumper.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
@ -16,13 +14,40 @@
|
|||
|
||||
namespace colgm {
|
||||
|
||||
ast::type_def* type_replace_pass::generate_generic_type(const type& t,
|
||||
const span& loc) {
|
||||
auto new_def = new type_def(loc);
|
||||
new_def->set_name(new identifier(loc, t.name));
|
||||
new_def->get_name()->set_redirect_location(ctx.this_file);
|
||||
new_def->set_redirect_location(ctx.this_file);
|
||||
if (t.is_immutable) {
|
||||
new_def->set_constant();
|
||||
}
|
||||
for(i64 i = 0; i < t.pointer_depth; ++i) {
|
||||
new_def->add_pointer_level();
|
||||
}
|
||||
if (!t.generics.empty()) {
|
||||
new_def->set_generic_types(new generic_type_list(loc));
|
||||
for(const auto& i : t.generics) {
|
||||
new_def->get_generic_types()->add_type(
|
||||
generate_generic_type(i, loc)
|
||||
);
|
||||
}
|
||||
}
|
||||
return new_def;
|
||||
}
|
||||
|
||||
bool type_replace_pass::visit_type_def(type_def* node) {
|
||||
const auto name = node->get_name()->get_name();
|
||||
if (g_data.types.count(name)) {
|
||||
// FIXME: if embedded generics like A<T<K>>, this will be wrong
|
||||
node->get_name()->reset_name(g_data.types.at(name).name);
|
||||
node->get_name()->set_redirect_location(ctx.this_file);
|
||||
node->set_redirect_location(ctx.this_file);
|
||||
|
||||
for (i64 i = 0; i < g_data.types.at(name).pointer_depth; ++i) {
|
||||
node->add_pointer_level();
|
||||
}
|
||||
|
||||
if (!g_data.types.at(name).generics.empty() &&
|
||||
node->get_generic_types()) {
|
||||
err.err(node->get_location(),
|
||||
|
@ -31,6 +56,15 @@ bool type_replace_pass::visit_type_def(type_def* node) {
|
|||
"but more generic types are specified in this node."
|
||||
);
|
||||
}
|
||||
if (!g_data.types.at(name).generics.empty() &&
|
||||
!node->get_generic_types()) {
|
||||
node->set_generic_types(new generic_type_list(node->get_location()));
|
||||
for(const auto& i : g_data.types.at(name).generics) {
|
||||
node->get_generic_types()->add_type(
|
||||
generate_generic_type(i, node->get_location())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node->get_generic_types()) {
|
||||
node->get_generic_types()->accept(this);
|
||||
|
@ -41,10 +75,17 @@ bool type_replace_pass::visit_type_def(type_def* node) {
|
|||
bool type_replace_pass::visit_call_id(ast::call_id* node) {
|
||||
const auto name = node->get_id()->get_name();
|
||||
if (g_data.types.count(name)) {
|
||||
// FIXME: if embedded generics like A<T<K>>, this will be wrong
|
||||
node->get_id()->set_name(g_data.types.at(name).name);
|
||||
node->get_id()->set_redirect_location(ctx.this_file);
|
||||
node->set_redirect_location(ctx.this_file);
|
||||
|
||||
if (g_data.types.at(name).pointer_depth) {
|
||||
err.err(node->get_location(),
|
||||
"replace type \"" + g_data.types.at(name).full_path_name() +
|
||||
"\" is a pointer type, which is not allowed here."
|
||||
);
|
||||
}
|
||||
|
||||
if (!g_data.types.at(name).generics.empty() &&
|
||||
node->get_generic_types()) {
|
||||
err.err(node->get_location(),
|
||||
|
@ -53,6 +94,15 @@ bool type_replace_pass::visit_call_id(ast::call_id* node) {
|
|||
"but more generic types are specified in this node."
|
||||
);
|
||||
}
|
||||
if (!g_data.types.at(name).generics.empty() &&
|
||||
!node->get_generic_types()) {
|
||||
node->set_generic_types(new generic_type_list(node->get_location()));
|
||||
for(const auto& i : g_data.types.at(name).generics) {
|
||||
node->get_generic_types()->add_type(
|
||||
generate_generic_type(i, node->get_location())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node->get_generic_types()) {
|
||||
node->get_generic_types()->accept(this);
|
||||
|
@ -62,7 +112,9 @@ bool type_replace_pass::visit_call_id(ast::call_id* node) {
|
|||
|
||||
void generic_visitor::scan_generic_type(type_def* type_node) {
|
||||
const auto& type_name = type_node->get_name()->get_name();
|
||||
const auto& dm = ctx.global.domain.at(type_node->get_file());
|
||||
const auto& dm = type_node->is_redirected()
|
||||
? ctx.global.domain.at(type_node->get_redirect_location())
|
||||
: ctx.global.domain.at(type_node->get_file());
|
||||
|
||||
if (!dm.global_symbol.count(type_name)) {
|
||||
rp.report(type_node, "unknown type \"" + type_name + "\".");
|
||||
|
@ -180,7 +232,9 @@ bool generic_visitor::visit_call_id(ast::call_id* node) {
|
|||
}
|
||||
|
||||
const auto& type_name = node->get_id()->get_name();
|
||||
const auto& dm = ctx.global.domain.at(node->get_file());
|
||||
const auto& dm = node->is_redirected()
|
||||
? ctx.global.domain.at(node->get_redirect_location())
|
||||
: ctx.global.domain.at(node->get_file());
|
||||
if (!dm.global_symbol.count(type_name)) {
|
||||
rp.report(node, "unknown type \"" + type_name + "\".");
|
||||
return true;
|
||||
|
|
|
@ -25,6 +25,9 @@ private:
|
|||
sema_context& ctx;
|
||||
generic_data g_data;
|
||||
|
||||
private:
|
||||
ast::type_def* generate_generic_type(const type&, const span&);
|
||||
|
||||
private:
|
||||
bool visit_type_def(ast::type_def*) override;
|
||||
bool visit_call_id(ast::call_id*) override;
|
||||
|
|
|
@ -390,7 +390,9 @@ type semantic::resolve_identifier(identifier* node) {
|
|||
return ctx.get_local(name);
|
||||
}
|
||||
|
||||
const auto& dm = ctx.get_domain(node->get_file());
|
||||
const auto& dm = node->is_redirected()
|
||||
? ctx.get_domain(node->get_redirect_location())
|
||||
: ctx.get_domain(node->get_file());
|
||||
if (dm.global_symbol.count(name)) {
|
||||
const auto& sym = dm.global_symbol.at(name);
|
||||
if (!sym.is_public) {
|
||||
|
|
2
makefile
2
makefile
|
@ -12,7 +12,7 @@ test: $(COLGMCC) test/*
|
|||
@ $(COLGMCC) test/bitwise.colgm $(TEST_LIB) && lli out.ll
|
||||
@ $(COLGMCC) test/branch.colgm $(TEST_LIB) && lli out.ll
|
||||
@ $(COLGMCC) test/cmpnot.colgm $(TEST_LIB) && lli out.ll
|
||||
-@ $(COLGMCC) test/complex_generics.colgm $(TEST_LIB) && lli out.ll
|
||||
@ $(COLGMCC) test/complex_generics.colgm $(TEST_LIB) && lli out.ll
|
||||
@ $(COLGMCC) test/continue_break.colgm $(TEST_LIB) && lli out.ll
|
||||
@ $(COLGMCC) test/enum_test.colgm $(TEST_LIB) && lli out.ll
|
||||
@ $(COLGMCC) test/for_test.colgm $(TEST_LIB) && lli out.ll
|
||||
|
|
|
@ -35,7 +35,9 @@ pub func version() -> i8* {
|
|||
}
|
||||
|
||||
pub func print_version() {
|
||||
io::stdout().out("colgm compiler version ").out(version()).out("\n");
|
||||
io::stdout().out("colgm compiler version ").out(version());
|
||||
io::stdout().out(" ").out(get_platform()).out(" ").out(get_arch());
|
||||
io::stdout().out("\n");
|
||||
}
|
||||
|
||||
pub func help() {
|
||||
|
|
|
@ -6,7 +6,7 @@ struct B<T> {
|
|||
b: T
|
||||
}
|
||||
|
||||
func main() -> u64 {
|
||||
func main() -> i64 {
|
||||
var aptr = Aptr<i32*> {
|
||||
a: nil => i32*
|
||||
};
|
||||
|
@ -15,5 +15,5 @@ func main() -> u64 {
|
|||
a: nil => B<i32*>*
|
||||
};
|
||||
|
||||
return i32::__size__();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue