mirror of https://github.com/exaloop/codon.git
Fix NTuple handling
parent
2cff95109d
commit
04913cd405
|
@ -91,10 +91,29 @@ int ClassType::unify(Type *typ, Unification *us) {
|
|||
} else if (name == "__NTuple__" && tc->name == TYPE_TUPLE) {
|
||||
auto n1 = generics[0].getType()->getIntStatic();
|
||||
if (!n1) {
|
||||
auto t1 = std::make_shared<IntStaticType>(cache, 1);
|
||||
if (generics[0].type->unify(t1.get(), us) == -1)
|
||||
auto n = tc->generics.size();
|
||||
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 generics[1].type->unify(tc, us);
|
||||
} else {
|
||||
auto t1 = generics[1].getType()->getClass();
|
||||
seqassert(t1, "bad ntuples");
|
||||
|
@ -106,8 +125,8 @@ int ClassType::unify(Type *typ, Unification *us) {
|
|||
return -1;
|
||||
s1 += s;
|
||||
}
|
||||
return s1;
|
||||
}
|
||||
return s1;
|
||||
}
|
||||
|
||||
// Check names.
|
||||
|
|
|
@ -82,6 +82,9 @@ void TypecheckVisitor::visit(StringExpr *expr) {
|
|||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -690,12 +690,12 @@ bool TypecheckVisitor::typecheckCallArgs(FuncType *calleeFn,
|
|||
|
||||
// Handle default generics
|
||||
for (size_t i = 0, j = 0; wrappingDone && i < calleeFn->ast->size(); i++)
|
||||
if ((*calleeFn->ast)[i].status == Param::Generic) {
|
||||
if ((*calleeFn->ast)[i].defaultValue &&
|
||||
if ((*calleeFn->ast)[i].isGeneric()) {
|
||||
if ((*calleeFn->ast)[i].getDefault() &&
|
||||
isUnbound(extractFuncGeneric(calleeFn, j))) {
|
||||
auto def = extractType(withClassGenerics(
|
||||
calleeFn,
|
||||
[&]() { return transform(clone((*calleeFn->ast)[i].getDefault())); },
|
||||
[&]() { return transform(clean_clone((*calleeFn->ast)[i].getDefault())); },
|
||||
true));
|
||||
unify(extractFuncGeneric(calleeFn, j), def);
|
||||
}
|
||||
|
|
|
@ -491,8 +491,11 @@ ir::types::Type *TypecheckVisitor::makeIRType(types::ClassType *t) {
|
|||
// Realize if not, and return cached value if it exists
|
||||
auto realizedName = t->ClassType::realizedName();
|
||||
auto cls = ctx->cache->getClass(t);
|
||||
if (!in(cls->realizations, realizedName))
|
||||
realize(t->getClass());
|
||||
if (!in(cls->realizations, realizedName)) {
|
||||
t = realize(t->getClass())->getClass();
|
||||
realizedName = t->ClassType::realizedName();
|
||||
cls = ctx->cache->getClass(t);
|
||||
}
|
||||
if (auto l = cls->realizations[realizedName]->ir) {
|
||||
if (cls->rtti)
|
||||
cast<ir::types::RefType>(l)->setPolymorphic();
|
||||
|
|
|
@ -850,6 +850,13 @@ print(Tuple[-5, int].__class__.__name__)
|
|||
print(Tuple[5, int, str].__class__.__name__)
|
||||
#: 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
|
||||
class A:
|
||||
|
|
Loading…
Reference in New Issue