mirror of
https://github.com/exaloop/codon.git
synced 2025-06-03 15:03:52 +08:00
* Use Static[] for static inheritance * Support .seq extension * Fix #36 * Polymorphic typechecking; vtables [wip] * v-table dispatch [wip] * vtable routing [wip; bug] * vtable routing [MVP] * Fix texts * Add union type support * Update FAQs * Clarify * Add BSL license * Add makeUnion * Add IR UnionType * Update union representation in LLVM * Update README * Update README.md * Update README * Update README.md * Add benchmarks * Add more benchmarks and README * Add primes benchmark * Update benchmarks * Fix cpp * Clean up list * Update faq.md * Add binary trees benchmark * Add fannkuch benchmark * Fix paths * Add PyPy * Abort on fail * More benchmarks * Add cpp word_count * Update set_partition cpp * Add nbody cpp * Add TAQ cpp; fix word_count timing * Update CODEOWNERS * Update README * Update README.md * Update CODEOWNERS * Fix bench script * Update binary_trees.cpp * Update taq.cpp * Fix primes benchmark * Add mandelbrot benchmark * Fix OpenMP init * Add Module::unsafeGetUnionType * UnionType [wip] [skip ci] * Integrate IR unions and Union * UnionType refactor [skip ci] * Update README.md * Update docs * UnionType [wip] [skip ci] * UnionType and automatic unions * Add Slack * Update faq.md * Refactor types * New error reporting [wip] * New error reporting [wip] * peglib updates [wip] [skip_ci] * Fix parsing issues * Fix parsing issues * Fix error reporting issues * Make sure random module matches Python * Update releases.md * Fix tests * Fix #59 * Fix #57 * Fix #50 * Fix #49 * Fix #26; Fix #51; Fix #47; Fix #49 * Fix collection extension methods * Fix #62 * Handle *args/**kwargs with Callable[]; Fix #43 * Fix #43 * Fix Ptr.__sub__; Fix polymorphism issues * Add typeinfo * clang-format * Upgrade fmtlib to v9; Use CPM for fmtlib; format spec support; __format__ support * Use CPM for semver and toml++ * Remove extension check * Revamp str methods * Update str.zfill * Fix thunk crashes [wip] [skip_ci] * Fix str.__reversed__ * Fix count_with_max * Fix vtable memory allocation issues * Add poly AST tests * Use PDQsort when stability does not matter * Fix dotted imports; Fix issues * Fix kwargs passing to Python * Fix #61 * Fix #37 * Add isinstance support for unions; Union methods return Union type if different * clang-format * Nicely format error tracebacks * Fix build issues; clang-format * Fix OpenMP init * Fix OpenMP init * Update README.md * Fix tests * Update license [skip ci] * Update license [ci skip] * Add copyright header to all source files * Fix super(); Fix error recovery in ClassStmt * Clean up whitespace [ci skip] * Use Python 3.9 on CI * Print info in random test * Fix single unions * Update random_test.codon * Fix polymorhic thunk instantiation * Fix random test * Add operator.attrgetter and operator.methodcaller * Add code documentation * Update documentation * Update README.md * Fix tests * Fix random init Co-authored-by: A. R. Shajii <ars@ars.me>
540 lines
9.7 KiB
Python
540 lines
9.7 KiB
Python
class Exc1(Static[Exception]):
|
|
def __init__(self, msg: str):
|
|
super().__init__('Exc1', msg)
|
|
|
|
def show(self):
|
|
print self.message
|
|
|
|
class Exc2(Static[Exception]):
|
|
def __init__(self, msg: str):
|
|
super().__init__('Exc2', msg)
|
|
|
|
def show(self):
|
|
print self.message
|
|
|
|
class A(Static[Exception]):
|
|
def __init__(self, msg: str):
|
|
super().__init__('A', msg)
|
|
|
|
class B(Static[Exception]):
|
|
def __init__(self, msg: str):
|
|
super().__init__('B', msg)
|
|
|
|
class C(Static[Exception]):
|
|
def __init__(self, msg: str):
|
|
super().__init__('C', msg)
|
|
|
|
class D(Static[Exception]):
|
|
def __init__(self, msg: str):
|
|
super().__init__('D', msg)
|
|
|
|
class E(Static[Exception]):
|
|
def __init__(self, msg: str):
|
|
super().__init__('E', msg)
|
|
|
|
def foo1(x):
|
|
if x:
|
|
raise Exc1('e1')
|
|
else:
|
|
raise Exc2('e2')
|
|
|
|
def foo2(x):
|
|
foo1(x)
|
|
|
|
def foo(x):
|
|
foo2(x)
|
|
|
|
def square(x):
|
|
return x * x
|
|
|
|
def bar(x):
|
|
try:
|
|
print 'try'
|
|
foo(x)
|
|
print 'error'
|
|
except Exc1 as e:
|
|
print 'catch Exc1 1'
|
|
print e.message
|
|
print 'catch Exc1 2'
|
|
except Exc2 as e:
|
|
print 'catch Exc2 1'
|
|
print e.message
|
|
print 'catch Exc2 2'
|
|
finally:
|
|
print 'finally'
|
|
print 'done'
|
|
|
|
def baz(x):
|
|
try:
|
|
print 'try 1'
|
|
square(x)
|
|
print 'try 2'
|
|
except Exc1 as e:
|
|
print 'catch Exc1 1'
|
|
print e.message
|
|
print 'catch Exc1 2'
|
|
except Exc2 as e:
|
|
print 'catch Exc2 1'
|
|
print e.message
|
|
print 'catch Exc2 2'
|
|
finally:
|
|
print 'finally'
|
|
print 'done'
|
|
|
|
def baz1(x):
|
|
try:
|
|
print 'try 1.1'
|
|
foo(x)
|
|
print 'try 1.2'
|
|
except Exc1 as e:
|
|
print 'catch Exc1 1.1'
|
|
print e.message
|
|
print 'catch Exc1 1.2'
|
|
finally:
|
|
print 'finally 1'
|
|
print 'done 1'
|
|
|
|
def baz2(x):
|
|
try:
|
|
print 'try 2.1'
|
|
baz1(x)
|
|
print 'try 2.2'
|
|
except:
|
|
print 'catch Exc2'
|
|
finally:
|
|
print 'finally 2'
|
|
print 'done 2'
|
|
|
|
def nest1(b):
|
|
if b:
|
|
raise C('C')
|
|
else:
|
|
raise E('E')
|
|
|
|
def nest2(b):
|
|
try:
|
|
try:
|
|
try:
|
|
try:
|
|
nest1(b)
|
|
except A:
|
|
print 'A'
|
|
finally:
|
|
print 'f A'
|
|
except B:
|
|
print 'B'
|
|
finally:
|
|
print 'f B'
|
|
except C as c:
|
|
print c.message
|
|
finally:
|
|
print 'f C'
|
|
except D:
|
|
print 'D'
|
|
finally:
|
|
print 'f D'
|
|
|
|
def nest3(b):
|
|
try:
|
|
nest2(b)
|
|
except:
|
|
print 'except'
|
|
finally:
|
|
print 'done'
|
|
|
|
def finally_return(x):
|
|
try:
|
|
try:
|
|
return 'A'
|
|
finally:
|
|
if x < 5:
|
|
return 'B'
|
|
finally:
|
|
if x > 10:
|
|
return 'C'
|
|
|
|
def finally_return_void():
|
|
try:
|
|
try:
|
|
print 'A'
|
|
return
|
|
finally:
|
|
print 'B'
|
|
return
|
|
finally:
|
|
print 'C'
|
|
|
|
def finally_break_continue1():
|
|
try:
|
|
for i in range(3):
|
|
try:
|
|
continue
|
|
finally:
|
|
print i
|
|
continue
|
|
print 'X'
|
|
finally:
|
|
print 'f'
|
|
|
|
def finally_break_continue2():
|
|
try:
|
|
for i in range(5):
|
|
try:
|
|
if i == 4:
|
|
continue
|
|
|
|
for j in range(i):
|
|
try:
|
|
try:
|
|
if j == 3:
|
|
break
|
|
elif j == 1:
|
|
continue
|
|
print j
|
|
finally:
|
|
print 'f1'
|
|
finally:
|
|
print 'f2'
|
|
if j == 4:
|
|
break
|
|
finally:
|
|
print 'f3'
|
|
finally:
|
|
print 'f4'
|
|
|
|
def finally_break_continue3(n):
|
|
while n != 0:
|
|
print 'A'
|
|
try:
|
|
while n != 0:
|
|
print 'B'
|
|
if n == 42:
|
|
print 'C'
|
|
n -= 1
|
|
continue
|
|
try:
|
|
print 'D'
|
|
if n > 0:
|
|
print 'E'
|
|
continue
|
|
else:
|
|
print 'F'
|
|
break
|
|
finally:
|
|
print('G')
|
|
return -1
|
|
print 'H'
|
|
return -2
|
|
finally:
|
|
print 'I'
|
|
return n + 1
|
|
|
|
def test_try_with_loop1(_):
|
|
try:
|
|
print 'A'
|
|
while True:
|
|
print 'B'
|
|
try:
|
|
print 'C'
|
|
raise ValueError()
|
|
assert False
|
|
except ValueError:
|
|
print 'D'
|
|
break
|
|
finally:
|
|
print 'E'
|
|
|
|
def test_try_with_loop2(_):
|
|
try:
|
|
print 'A'
|
|
while True:
|
|
print 'B'
|
|
try:
|
|
print 'C'
|
|
raise ValueError()
|
|
assert False
|
|
except:
|
|
print 'D'
|
|
break
|
|
finally:
|
|
print 'E'
|
|
|
|
def test_try_with_loop3(_):
|
|
try:
|
|
try:
|
|
print 'A'
|
|
while True:
|
|
print 'B'
|
|
try:
|
|
print 'C'
|
|
raise ValueError()
|
|
assert False
|
|
except IOError:
|
|
print 'D'
|
|
break
|
|
finally:
|
|
print 'E'
|
|
except:
|
|
print 'F'
|
|
finally:
|
|
print 'G'
|
|
|
|
def test_try_with_loop4(_):
|
|
try:
|
|
try:
|
|
print 'A'
|
|
while True:
|
|
print 'B'
|
|
try:
|
|
print 'C'
|
|
raise ValueError()
|
|
assert False
|
|
except:
|
|
print 'D'
|
|
raise IOError()
|
|
break
|
|
finally:
|
|
print 'E'
|
|
except:
|
|
print 'F'
|
|
finally:
|
|
print 'G'
|
|
|
|
# EXPECT: try
|
|
# EXPECT: catch Exc1 1
|
|
# EXPECT: e1
|
|
# EXPECT: catch Exc1 2
|
|
# EXPECT: finally
|
|
# EXPECT: done
|
|
bar(True)
|
|
|
|
# EXPECT: try
|
|
# EXPECT: catch Exc2 1
|
|
# EXPECT: e2
|
|
# EXPECT: catch Exc2 2
|
|
# EXPECT: finally
|
|
# EXPECT: done
|
|
bar(0)
|
|
|
|
# EXPECT: try 1
|
|
# EXPECT: try 2
|
|
# EXPECT: finally
|
|
# EXPECT: done
|
|
baz(3.14)
|
|
|
|
# EXPECT: try 2.1
|
|
# EXPECT: try 1.1
|
|
# EXPECT: catch Exc1 1.1
|
|
# EXPECT: e1
|
|
# EXPECT: catch Exc1 1.2
|
|
# EXPECT: finally 1
|
|
# EXPECT: done 1
|
|
# EXPECT: try 2.2
|
|
# EXPECT: finally 2
|
|
# EXPECT: done 2
|
|
baz2(1)
|
|
|
|
# EXPECT: try 2.1
|
|
# EXPECT: try 1.1
|
|
# EXPECT: finally 1
|
|
# EXPECT: catch Exc2
|
|
# EXPECT: finally 2
|
|
# EXPECT: done 2
|
|
baz2(0)
|
|
|
|
# EXPECT: f A
|
|
# EXPECT: f B
|
|
# EXPECT: C
|
|
# EXPECT: f C
|
|
# EXPECT: f D
|
|
# EXPECT: done
|
|
nest3(True)
|
|
|
|
# EXPECT: f A
|
|
# EXPECT: f B
|
|
# EXPECT: f C
|
|
# EXPECT: f D
|
|
# EXPECT: except
|
|
# EXPECT: done
|
|
nest3(0)
|
|
|
|
print finally_return(3.14) # EXPECT: B
|
|
print finally_return(7) # EXPECT: A
|
|
print finally_return(11) # EXPECT: C
|
|
|
|
# EXPECT: A
|
|
# EXPECT: B
|
|
# EXPECT: C
|
|
finally_return_void()
|
|
|
|
# EXPECT: 0
|
|
# EXPECT: 1
|
|
# EXPECT: 2
|
|
# EXPECT: f
|
|
finally_break_continue1()
|
|
|
|
# EXPECT: f3
|
|
# EXPECT: 0
|
|
# EXPECT: f1
|
|
# EXPECT: f2
|
|
# EXPECT: f3
|
|
# EXPECT: 0
|
|
# EXPECT: f1
|
|
# EXPECT: f2
|
|
# EXPECT: f1
|
|
# EXPECT: f2
|
|
# EXPECT: f3
|
|
# EXPECT: 0
|
|
# EXPECT: f1
|
|
# EXPECT: f2
|
|
# EXPECT: f1
|
|
# EXPECT: f2
|
|
# EXPECT: 2
|
|
# EXPECT: f1
|
|
# EXPECT: f2
|
|
# EXPECT: f3
|
|
# EXPECT: f3
|
|
# EXPECT: f4
|
|
finally_break_continue2()
|
|
|
|
# EXPECT: A
|
|
# EXPECT: B
|
|
# EXPECT: C
|
|
# EXPECT: B
|
|
# EXPECT: D
|
|
# EXPECT: E
|
|
# EXPECT: G
|
|
# EXPECT: I
|
|
# EXPECT: 42
|
|
print finally_break_continue3(42)
|
|
|
|
# EXPECT: A
|
|
# EXPECT: B
|
|
# EXPECT: C
|
|
# EXPECT: D
|
|
# EXPECT: E
|
|
test_try_with_loop1(0)
|
|
|
|
# EXPECT: A
|
|
# EXPECT: B
|
|
# EXPECT: C
|
|
# EXPECT: D
|
|
# EXPECT: E
|
|
test_try_with_loop2(0.0)
|
|
|
|
# EXPECT: A
|
|
# EXPECT: B
|
|
# EXPECT: C
|
|
# EXPECT: E
|
|
# EXPECT: F
|
|
# EXPECT: G
|
|
test_try_with_loop3('')
|
|
|
|
# EXPECT: A
|
|
# EXPECT: B
|
|
# EXPECT: C
|
|
# EXPECT: D
|
|
# EXPECT: E
|
|
# EXPECT: F
|
|
# EXPECT: G
|
|
test_try_with_loop4(False)
|
|
|
|
class Foo:
|
|
i: int
|
|
def __enter__(self: Foo):
|
|
print '> foo! ' + str(self.i)
|
|
def __exit__(self: Foo):
|
|
print '< foo! ' + str(self.i)
|
|
def foo(self: Foo):
|
|
print 'woof'
|
|
|
|
class Bar:
|
|
s: str
|
|
def __enter__(self: Bar):
|
|
print '> bar! ' + self.s
|
|
def __exit__(self: Bar):
|
|
print '< bar! ' + self.s
|
|
def bar(self: Bar):
|
|
print 'meow'
|
|
|
|
def test_with():
|
|
with Foo(0) as f:
|
|
f.foo()
|
|
with Foo(1) as f, Bar('s') as b:
|
|
f.foo()
|
|
b.bar()
|
|
with Foo(2), Bar('t') as q:
|
|
print 'eeh'
|
|
q.bar()
|
|
|
|
# EXPECT: > foo! 0
|
|
# EXPECT: woof
|
|
# EXPECT: < foo! 0
|
|
# EXPECT: > foo! 1
|
|
# EXPECT: > bar! s
|
|
# EXPECT: woof
|
|
# EXPECT: meow
|
|
# EXPECT: < bar! s
|
|
# EXPECT: < foo! 1
|
|
# EXPECT: > foo! 2
|
|
# EXPECT: > bar! t
|
|
# EXPECT: eeh
|
|
# EXPECT: meow
|
|
# EXPECT: < bar! t
|
|
# EXPECT: < foo! 2
|
|
test_with()
|
|
|
|
|
|
class PropClass:
|
|
x: int
|
|
|
|
@property
|
|
def foo(self: PropClass):
|
|
raise IOError('foo')
|
|
|
|
def test_property_exceptions():
|
|
try:
|
|
PropClass(42).foo
|
|
print 'X'
|
|
except IOError as e:
|
|
print e.message
|
|
|
|
# EXPECT: foo
|
|
test_property_exceptions()
|
|
|
|
def test_empty_raise():
|
|
def foo(b):
|
|
if b:
|
|
raise ValueError('A')
|
|
else:
|
|
raise IOError('B')
|
|
|
|
def bar(b):
|
|
try:
|
|
foo(b)
|
|
print('X')
|
|
except IOError as e:
|
|
print(e)
|
|
raise
|
|
except:
|
|
raise
|
|
|
|
def baz(b):
|
|
try:
|
|
bar(b)
|
|
except ValueError as e:
|
|
print(e)
|
|
raise
|
|
|
|
for b in (False, True):
|
|
try:
|
|
baz(b)
|
|
except:
|
|
print('C')
|
|
|
|
# EXPECT: B
|
|
# EXPECT: C
|
|
# EXPECT: A
|
|
# EXPECT: C
|
|
test_empty_raise()
|