Use @overload for top-level function overloads; Partial function bugfixes

pull/12/head
Ibrahim Numanagić 2022-02-18 17:27:24 -08:00
parent 6f402ff810
commit 2506cb849e
10 changed files with 46 additions and 18 deletions

View File

@ -69,6 +69,9 @@ CPMAddPackage(
GITHUB_REPOSITORY "llvm-mirror/openmp"
VERSION 9.0
GIT_TAG release_90
# GITHUB_REPOSITORY "exaloop/openmp"
# VERSION 12.0.1
# GIT_TAG v12.0.1
OPTIONS "OPENMP_ENABLE_LIBOMPTARGET OFF"
"OPENMP_STANDALONE_BUILD ON")
@ -125,8 +128,8 @@ if(CODON_JUPYTER)
NAME libzmq
VERSION 4.3.4
URL https://github.com/zeromq/libzmq/releases/download/v4.3.4/zeromq-4.3.4.tar.gz
OPTIONS "WITH_PERF_TOOL OFF"
"ZMQ_BUILD_TESTS OFF"
OPTIONS "WITH_PERF_TOOL OFF"
"ZMQ_BUILD_TESTS OFF"
"ENABLE_CPACK OFF"
"BUILD_SHARED ON"
"WITH_LIBSODIUM OFF")

View File

@ -294,6 +294,7 @@ const std::string Attr::Capture = ".__capture__";
const std::string Attr::Extend = "extend";
const std::string Attr::Tuple = "tuple";
const std::string Attr::Test = "std.internal.attributes.test";
const std::string Attr::Overload = "std.internal.attributes.overload";
FunctionStmt::FunctionStmt(std::string name, ExprPtr ret, std::vector<Param> args,
StmtPtr suite, Attr attributes,

View File

@ -409,6 +409,7 @@ struct Attr {
const static std::string Tuple;
// Standard library attributes
const static std::string Test;
const static std::string Overload;
// Function module
std::string module;
// Parent class (set for methods only)

View File

@ -100,7 +100,7 @@ int LinkType::unify(Type *typ, Unification *undo) {
if (undo) {
LOG_TYPECHECK("[unify] {} := {}", id, typ->debugString(true));
// Link current type to typ and ensure that this modification is recorded in undo.
undo->linked.push_back(getLink());
undo->linked.push_back(this);
kind = Link;
seqassert(!typ->getLink() || typ->getLink()->kind != Unbound ||
typ->getLink()->id <= id,
@ -108,7 +108,7 @@ int LinkType::unify(Type *typ, Unification *undo) {
type = typ->follow();
if (auto t = type->getLink())
if (trait && t->kind == Unbound && !t->trait) {
undo->traits.push_back(t->getLink());
undo->traits.push_back(t.get());
t->trait = trait;
}
}
@ -185,7 +185,7 @@ std::string LinkType::debugString(bool debug) const {
// fmt::format("{}->{}", id, type->debugString(debug));
}
std::string LinkType::realizedName() const {
if (kind == Unbound)
if (kind == Unbound || kind == Generic)
return "?";
seqassert(kind == Link, "unexpected generic link");
return type->realizedName();
@ -205,7 +205,7 @@ bool LinkType::occurs(Type *typ, Type::Unification *undo) {
if (tl->trait && occurs(tl->trait.get(), undo))
return true;
if (undo && tl->level > level) {
undo->leveled.emplace_back(make_pair(tl, tl->level));
undo->leveled.emplace_back(make_pair(tl.get(), tl->level));
tl->level = level;
}
return false;
@ -578,7 +578,7 @@ std::string PartialType::debugString(bool debug) const {
}
std::string PartialType::realizedName() const {
std::vector<std::string> gs;
// gs.push_back(func->realizedName());
gs.push_back(func->ast->name);
for (auto &a : generics)
if (!a.name.empty())
gs.push_back(a.type->realizedName());

View File

@ -39,13 +39,16 @@ struct Type : public codon::SrcObject, public std::enable_shared_from_this<Type>
/// Needed because the unify() is destructive.
struct Unification {
/// List of unbound types that have been changed.
std::vector<std::shared_ptr<LinkType>> linked;
std::vector<LinkType *> linked;
/// List of unbound types whose level has been changed.
std::vector<std::pair<std::shared_ptr<LinkType>, int>> leveled;
std::vector<std::pair<LinkType *, int>> leveled;
/// List of assigned traits.
std::vector<std::shared_ptr<LinkType>> traits;
std::vector<LinkType *> traits;
/// Pointer to a TypecheckVisitor to support realization function types.
TypecheckVisitor *realizator = nullptr;
/// List of pointers that are owned by unification process
/// (to avoid memory issues with undoing).
std::vector<std::shared_ptr<Type>> ownedTypes;
public:
/// Undo the unification step.

View File

@ -111,6 +111,7 @@ ir::Func *Cache::realizeFunction(types::FuncTypePtr type,
}
}
}
// LOG("--> realizing {}", type->debugString(1));
int oldAge = typeCtx->age;
typeCtx->age = 99999;
auto tv = TypecheckVisitor(typeCtx);

View File

@ -235,8 +235,8 @@ void SimplifyVisitor::visit(ForStmt *stmt) {
if (auto i = stmt->var->getId()) {
ctx->add(SimplifyItem::Var, i->value, ctx->generateCanonicalName(i->value));
auto var = transform(stmt->var);
forStmt = N<ForStmt>(var, clone(iter), transform(stmt->suite),
nullptr, decorator, ompArgs);
forStmt = N<ForStmt>(var, clone(iter), transform(stmt->suite), nullptr, decorator,
ompArgs);
} else {
std::string varName = ctx->cache->getTemporaryVar("for");
ctx->add(SimplifyItem::Var, varName, varName);
@ -476,7 +476,7 @@ void SimplifyVisitor::visit(FunctionStmt *stmt) {
// TODO: error on decorators
return;
}
bool overload = attr.has(Attr::Overload);
bool isClassMember = ctx->inClass();
std::string rootName;
if (isClassMember) {
@ -484,10 +484,11 @@ void SimplifyVisitor::visit(FunctionStmt *stmt) {
auto i = m.find(stmt->name);
if (i != m.end())
rootName = i->second;
} else if (auto c = ctx->find(stmt->name)) {
if (c->isFunc() && c->getModule() == ctx->getModule() &&
c->getBase() == ctx->getBase())
rootName = c->canonicalName;
} else if (overload) {
if (auto c = ctx->find(stmt->name))
if (c->isFunc() && c->getModule() == ctx->getModule() &&
c->getBase() == ctx->getBase())
rootName = c->canonicalName;
}
if (rootName.empty())
rootName = ctx->generateCanonicalName(stmt->name, true);

View File

@ -150,6 +150,7 @@ types::TypePtr TypecheckVisitor::realizeFunc(types::FuncType *type) {
LOG_REALIZE("[realize] fn {} -> {} : base {} ; depth = {}", type->ast->name,
type->realizedName(), ctx->getBase(), depth);
{
// Timer trx(fmt::format("fn {}", type->realizedName()));
getLogger().level++;
ctx->realizationDepth++;
ctx->addBlock();
@ -221,7 +222,9 @@ types::TypePtr TypecheckVisitor::realizeFunc(types::FuncType *type) {
// Realize the return type.
if (auto t = realize(type->args[0]))
unify(type->args[0], t);
LOG_REALIZE("... done with {} / {}", type->realizedName(), oldKey);
LOG_REALIZE("[realize] done with {} / {} =>{}", type->realizedName(), oldKey,
time);
// trx.log();
// Create and store IR node and a realized AST to be used
// during the code generation.

View File

@ -42,3 +42,6 @@ def C():
def realize_without_self():
pass
@__attribute__
def overload():
pass

View File

@ -1113,11 +1113,13 @@ print methodcaller('index')(v, 42) #: 1
def foo(x):
return 1, x
@overload
def foo(x, y):
def foo(x, y):
return f'{x}_{y}'
return 2, foo(x, y)
@overload
def foo(x):
if x == '':
return 3, 0
@ -1126,9 +1128,19 @@ def foo(x):
print foo('hi') #: (3, 2)
print foo('hi', 1) #: (2, 'hi_1')
#%% fn_shadow,barebones
def foo(x):
return 1, x
print foo('hi') #: (1, 'hi')
def foo(x):
return 2, x
print foo('hi') #: (2, 'hi')
#%% fn_overloads_error,barebones
def foo(x):
return 1, x
@overload
def foo(x, y):
return 2, x, y
foo('hooooooooy!', 1, 2) #! cannot find an overload 'foo' with arguments = str, = int, = int