Skip to content

Commit

Permalink
Union hasattr (#500)
Browse files Browse the repository at this point in the history
* Fix __from_gpu_new__

* Fix GPU tests

* Update GPU debug codegen

* Add will-return attribute for GPU compilation

* Fix isinstance on unresolved types

* Fix union type instantiation and pendingRealizations placement

* Add float16, bfloat16 and float128 IR types

* Add float16, bfloat16 and float128 types

* Mark complex64 as no-python

* Fix float methods

* Add float tests

* Disable some float tests

* Fix bitset in reaching definitions analysis

* Fix static bool unification

* Add property setters

* Remove log

* Add Union hasattr support

---------

Co-authored-by: Ibrahim Numanagić <[email protected]>
  • Loading branch information
arshajii and inumanag authored Nov 27, 2023
1 parent 7fdbc7f commit 78a3d7d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
19 changes: 19 additions & 0 deletions codon/parser/visitors/typecheck/call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,25 @@ ExprPtr TypecheckVisitor::transformHasAttr(CallExpr *expr) {
}
}

if (typ->getUnion()) {
ExprPtr cond = nullptr;
auto unionTypes = typ->getUnion()->getRealizationTypes();
int tag = -1;
for (size_t ui = 0; ui < unionTypes.size(); ui++) {
auto tu = realize(unionTypes[ui]);
if (!tu)
return nullptr;
auto te = N<IdExpr>(tu->getClass()->realizedTypeName());
auto e = N<BinaryExpr>(
N<CallExpr>(N<IdExpr>("isinstance"), expr->args[0].value, te), "&&",
N<CallExpr>(N<IdExpr>("hasattr"), te, N<StringExpr>(member)));
cond = !cond ? e : N<BinaryExpr>(cond, "||", e);
}
if (!cond)
return transform(N<BoolExpr>(false));
return transform(cond);
}

bool exists = !ctx->findMethod(typ->getClass().get(), member).empty() ||
ctx->findMember(typ->getClass(), member);
if (exists && args.size() > 1)
Expand Down
27 changes: 27 additions & 0 deletions test/parser/types.codon
Original file line number Diff line number Diff line change
Expand Up @@ -2030,3 +2030,30 @@ def correlate(a, b, mode = 'valid'):
raise ValueError(f"mode must be one of 'valid', 'same', or 'full' (got {repr(mode)})")
return xret
print(correlate([1], [2], 'full')) # 5z

#%% union_hasattr,barebones
class A:
def foo(self):
print('foo')
def bar(self):
print('bar')
class B:
def foo(self):
print('foo')
def baz(self):
print('baz')

a = A()
print(hasattr(a, 'foo'), hasattr(a, 'bar'), hasattr(a, 'baz'))
#: True True False
b = B()
print(hasattr(b, 'foo'), hasattr(b, 'bar'), hasattr(b, 'baz'))
#: True False True

c: Union[A, B] = A()
print(hasattr(c, 'foo'), hasattr(c, 'bar'), hasattr(c, 'baz'))
#: True True False

c = B()
print(hasattr(c, 'foo'), hasattr(c, 'bar'), hasattr(c, 'baz'))
#: True False True

0 comments on commit 78a3d7d

Please sign in to comment.