1
0
mirror of https://github.com/exaloop/codon.git synced 2025-06-03 15:03:52 +08:00

Fix NTuple handling

This commit is contained in:
Ibrahim Numanagić 2024-12-12 19:13:54 -08:00
parent 2cff95109d
commit 04913cd405
5 changed files with 42 additions and 10 deletions

View File

@ -91,10 +91,29 @@ int ClassType::unify(Type *typ, Unification *us) {
} else if (name == "__NTuple__" && tc->name == TYPE_TUPLE) { } else if (name == "__NTuple__" && tc->name == TYPE_TUPLE) {
auto n1 = generics[0].getType()->getIntStatic(); auto n1 = generics[0].getType()->getIntStatic();
if (!n1) { if (!n1) {
auto t1 = std::make_shared<IntStaticType>(cache, 1); auto n = tc->generics.size();
if (generics[0].type->unify(t1.get(), us) == -1) auto tn = std::make_shared<IntStaticType>(cache, n);
// If we are unifying NT[N, T] and T[X, X, ...], we assume that N is number of
// X's
if (generics[0].type->unify(tn.get(), us) == -1)
return -1;
auto tv = TypecheckVisitor(cache->typeCtx);
TypePtr tt;
if (n) {
tt = tv.instantiateType(tv.generateTuple(1), {tc->generics[0].getType()});
for (size_t i = 1; i < tc->generics.size(); i++) {
if ((s = tt->getClass()->generics[0].getType()->unify(
tc->generics[i].getType(), us)) == -1)
return -1;
s1 += s;
}
} else {
tt = tv.instantiateType(tv.generateTuple(1));
// tt = tv.instantiateType(tv.generateTuple(0));
}
if (generics[1].type->unify(tt.get(), us) == -1)
return -1; return -1;
return generics[1].type->unify(tc, us);
} else { } else {
auto t1 = generics[1].getType()->getClass(); auto t1 = generics[1].getType()->getClass();
seqassert(t1, "bad ntuples"); seqassert(t1, "bad ntuples");
@ -106,8 +125,8 @@ int ClassType::unify(Type *typ, Unification *us) {
return -1; return -1;
s1 += s; s1 += s;
} }
return s1;
} }
return s1;
} }
// Check names. // Check names.

View File

@ -82,6 +82,9 @@ void TypecheckVisitor::visit(StringExpr *expr) {
items.emplace_back(N<StringExpr>(p.value)); items.emplace_back(N<StringExpr>(p.value));
} }
} }
if (items.size() == 1)
resultExpr = transform(items.front());
else
resultExpr = transform(N<CallExpr>(N<DotExpr>(N<IdExpr>("str"), "cat"), items)); resultExpr = transform(N<CallExpr>(N<DotExpr>(N<IdExpr>("str"), "cat"), items));
} }
} }

View File

@ -690,12 +690,12 @@ bool TypecheckVisitor::typecheckCallArgs(FuncType *calleeFn,
// Handle default generics // Handle default generics
for (size_t i = 0, j = 0; wrappingDone && i < calleeFn->ast->size(); i++) for (size_t i = 0, j = 0; wrappingDone && i < calleeFn->ast->size(); i++)
if ((*calleeFn->ast)[i].status == Param::Generic) { if ((*calleeFn->ast)[i].isGeneric()) {
if ((*calleeFn->ast)[i].defaultValue && if ((*calleeFn->ast)[i].getDefault() &&
isUnbound(extractFuncGeneric(calleeFn, j))) { isUnbound(extractFuncGeneric(calleeFn, j))) {
auto def = extractType(withClassGenerics( auto def = extractType(withClassGenerics(
calleeFn, calleeFn,
[&]() { return transform(clone((*calleeFn->ast)[i].getDefault())); }, [&]() { return transform(clean_clone((*calleeFn->ast)[i].getDefault())); },
true)); true));
unify(extractFuncGeneric(calleeFn, j), def); unify(extractFuncGeneric(calleeFn, j), def);
} }

View File

@ -491,8 +491,11 @@ ir::types::Type *TypecheckVisitor::makeIRType(types::ClassType *t) {
// Realize if not, and return cached value if it exists // Realize if not, and return cached value if it exists
auto realizedName = t->ClassType::realizedName(); auto realizedName = t->ClassType::realizedName();
auto cls = ctx->cache->getClass(t); auto cls = ctx->cache->getClass(t);
if (!in(cls->realizations, realizedName)) if (!in(cls->realizations, realizedName)) {
realize(t->getClass()); t = realize(t->getClass())->getClass();
realizedName = t->ClassType::realizedName();
cls = ctx->cache->getClass(t);
}
if (auto l = cls->realizations[realizedName]->ir) { if (auto l = cls->realizations[realizedName]->ir) {
if (cls->rtti) if (cls->rtti)
cast<ir::types::RefType>(l)->setPolymorphic(); cast<ir::types::RefType>(l)->setPolymorphic();

View File

@ -850,6 +850,13 @@ print(Tuple[-5, int].__class__.__name__)
print(Tuple[5, int, str].__class__.__name__) print(Tuple[5, int, str].__class__.__name__)
#: Tuple[int,str,int,str,int,str,int,str,int,str] #: Tuple[int,str,int,str,int,str,int,str,int,str]
def foo(t: Tuple[N, int], N: Static[int]):
print("foo", N, t)
foo((1, 2, 3))
#: foo 3 (1, 2, 3)
foo((1, 2, 3, 4, 5))
#: foo 5 (1, 2, 3, 4, 5)
#%% union_hasattr,barebones #%% union_hasattr,barebones
class A: class A: