Refactor CallExpr routing

typecheck-v2
Ibrahim Numanagić 2024-08-14 18:56:02 -07:00
parent b3bfdc8655
commit 3ce5295f45
4 changed files with 24 additions and 22 deletions

View File

@ -62,9 +62,6 @@ void TypecheckVisitor::visit(CallExpr *expr) {
expr->setAttribute("TupleFn");
}
if (in(expr->toString(-1), "dixpatch"))
log(expr->toString(-1));
// Check if this call is partial call
PartialCallData part;
@ -122,13 +119,18 @@ void TypecheckVisitor::visit(CallExpr *expr) {
calleeFn->funcParent ? calleeFn->funcParent->getClass() : nullptr, methods,
expr->items, expr->getExpr()->getType()->getPartial()));
}
bool doDispatch = !m || m->size() == 0;
if (m && m->size() > 1) {
// partials have dangling ellipsis that messes up with the unbound check below
bool doDispatch = !m || m->size() == 0 || part.isPartial;
if (!doDispatch && m && m->size() > 1) {
auto unbounds = 0;
for (auto &a : *expr) {
if (auto u = a.value->getType()->getUnbound()) {
return; // wait until it becomes known
if (a.value->getType()->getUnbound()) {
return; // typecheck this later once we know the argument
}
}
if (unbounds) {
return;
}
}
if (!doDispatch) {
calleeFn = ctx->instantiate(m->front(), calleeFn->funcParent
@ -789,7 +791,7 @@ Expr *TypecheckVisitor::transformNamedTuple(CallExpr *expr) {
std::vector<Param> generics, params;
auto orig = cast<TupleExpr>(expr->front().value->getOrigExpr());
size_t ti = 1;
for (auto *i: *orig) {
for (auto *i : *orig) {
if (auto s = cast<StringExpr>(i)) {
generics.emplace_back(format("T{}", ti), N<IdExpr>("type"), nullptr, true);
params.emplace_back(s->getValue(), N<IdExpr>(format("T{}", ti++)), nullptr);
@ -797,8 +799,8 @@ Expr *TypecheckVisitor::transformNamedTuple(CallExpr *expr) {
}
auto t = cast<TupleExpr>(i);
if (t && t->size() == 2 && cast<StringExpr>((*t)[0])) {
params.emplace_back(cast<StringExpr>((*t)[0])->getValue(),
transformType((*t)[1]), nullptr);
params.emplace_back(cast<StringExpr>((*t)[0])->getValue(), transformType((*t)[1]),
nullptr);
continue;
}
E(Error::CALL_NAMEDTUPLE, i);

View File

@ -336,19 +336,18 @@ void TypecheckVisitor::visit(IndexExpr *expr) {
/// Instantiate(foo, [bar]) -> Id("foo[bar]")
void TypecheckVisitor::visit(InstantiateExpr *expr) {
expr->expr = transformType(expr->expr);
// std::shared_ptr<types::StaticType> repeats = nullptr;
// if (expr->typeExpr->isId(TYPE_TUPLE) && !expr->typeParams.empty()) {
// transform(expr->typeParams[0]);
// if (expr->typeParams[0]->staticValue.type == StaticValue::INT) {
// repeats = Type::makeStatic(ctx->cache, expr->typeParams[0]);
// }
// }
TypePtr typ = nullptr;
bool hasRepeats = false;
size_t typeParamsSize = expr->size() - hasRepeats;
if (getType(expr->expr)->is(TYPE_TUPLE)) {
typ = ctx->instantiate(generateTuple(typeParamsSize));
// if (expr->size() > 1) {
// expr->items[0] = transform(expr->front(), true);
// if (expr->front()->getType()->isStaticType()) {
// hasRepeats = true;
// }
// }
typ = ctx->instantiate(generateTuple(typeParamsSize - hasRepeats));
} else {
typ = ctx->instantiate(expr->expr->getSrcInfo(), getType(expr->expr));
}

View File

@ -639,9 +639,10 @@ print(y['b'])
#: 6
z = 6
print(y['c'])
#: 7
#: 6
# TODO: should be 7 once by-ref capture lands
print(y)
#: {'a': 5, 'b': 6, 'c': 7}
#: {'a': 5, 'b': 6, 'c': 6}
xx = dd(lambda: 'empty')
xx.update({1: 's', 2: 'b'})

View File

@ -683,8 +683,8 @@ def test_side_effect_analysis():
foo()
x = foo()
bar()
y = bar()
# bar() TODO: fix partials
# y = bar()
assert baz() == 43
baz()
assert some_global == 44