mirror of https://github.com/exaloop/codon.git
Use @overload for top-level function overloads; Partial function bugfixes
parent
6f402ff810
commit
2506cb849e
|
@ -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")
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -42,3 +42,6 @@ def C():
|
|||
def realize_without_self():
|
||||
pass
|
||||
|
||||
@__attribute__
|
||||
def overload():
|
||||
pass
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue