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

Add tuple support for super()

This commit is contained in:
Ibrahim Numanagić 2022-01-11 11:04:03 -08:00
parent 65bc56eb21
commit 9dde5be88f
4 changed files with 34 additions and 18 deletions

View File

@ -133,7 +133,8 @@ struct Cache : public std::enable_shared_from_this<Cache> {
/// Realization lookup table that maps a realized class name to the corresponding
/// ClassRealization instance.
std::unordered_map<std::string, std::shared_ptr<ClassRealization>> realizations;
/// List of inherited class. We also keep the number of fields each of inherited
/// class.
std::vector<std::pair<std::string, int>> parentClasses;
Class() : ast(nullptr), originalAst(nullptr) {}

View File

@ -88,7 +88,7 @@ SimplifyVisitor::apply(Cache *cache, const StmtPtr &node, const std::string &fil
}
// Reserve the following static identifiers.
for (auto name : {"staticlen", "compile_error", "isinstance", "hasattr", "type",
"TypeVar", "Callable", "argv", "super", "superf", "fn"})
"TypeVar", "Callable", "argv", "super", "superf"})
stdlib->generateCanonicalName(name);
stdlib->add(SimplifyItem::Var, "super", "super", true);
stdlib->add(SimplifyItem::Var, "superf", "superf", true);

View File

@ -1958,12 +1958,14 @@ ExprPtr TypecheckVisitor::transformSuper(const CallExpr *expr) {
auto fptyp = ctx->bases.back().type->getFunc();
if (!fptyp || fptyp->ast->hasAttr(Attr::Method))
error("no parent classes available");
if (fptyp->args.size() < 2)
error("no parent classes available");
ClassTypePtr typ = fptyp->args[1]->getClass();
auto &cands = ctx->cache->classes[typ->name].parentClasses;
if (cands.empty())
error("no parent classes available");
if (typ->getRecord())
error("cannot use super on tuple types");
// if (typ->getRecord())
// error("cannot use super on tuple types");
// find parent typ
// unify top N args with parent typ args
@ -1976,22 +1978,34 @@ ExprPtr TypecheckVisitor::transformSuper(const CallExpr *expr) {
seqassert(val, "cannot find '{}'", name);
auto ftyp = ctx->instantiate(expr, val->type)->getClass();
for (int i = 0; i < fields; i++) {
auto t = ctx->cache->classes[typ->name].fields[i].type;
t = ctx->instantiate(expr, t, typ.get());
if (typ->getRecord()) {
std::vector<ExprPtr> members;
for (int i = 0; i < fields; i++)
members.push_back(N<DotExpr>(N<IdExpr>(fptyp->ast->args[0].name),
ctx->cache->classes[typ->name].fields[i].name));
ExprPtr e = transform(
N<CallExpr>(N<IdExpr>(format(TYPE_TUPLE "{}", members.size())), members));
unify(e->type, ftyp);
e->type = ftyp;
return e;
} else {
for (int i = 0; i < fields; i++) {
auto t = ctx->cache->classes[typ->name].fields[i].type;
t = ctx->instantiate(expr, t, typ.get());
auto ft = ctx->cache->classes[name].fields[i].type;
ft = ctx->instantiate(expr, ft, ftyp.get());
unify(t, ft);
auto ft = ctx->cache->classes[name].fields[i].type;
ft = ctx->instantiate(expr, ft, ftyp.get());
unify(t, ft);
}
ExprPtr typExpr = N<IdExpr>(name);
typExpr->setType(ftyp);
auto self = fptyp->ast->args[0].name;
ExprPtr e = transform(
N<CallExpr>(N<DotExpr>(N<IdExpr>("__internal__"), "to_class_ptr"),
N<CallExpr>(N<DotExpr>(N<IdExpr>(self), "__raw__")), typExpr));
return e;
}
ExprPtr typExpr = N<IdExpr>(name);
typExpr->setType(ftyp);
auto self = fptyp->ast->args[0].name;
ExprPtr e = transform(
N<CallExpr>(N<DotExpr>(N<IdExpr>("__internal__"), "to_class_ptr"),
N<CallExpr>(N<DotExpr>(N<IdExpr>(self), "__raw__")), typExpr));
return e;
}
} // namespace ast

View File

@ -131,6 +131,7 @@ class __internal__:
%0 = bitcast i8* %ptr to {=T}
ret {=T} %0
@pure
def _tuple_offsetof(x, field: Static[int]):
@llvm
def _llvm_offsetof(T: type, idx: Static[int], TE: type) -> int: