1
0
mirror of https://github.com/exaloop/codon.git synced 2025-06-03 15:03:52 +08:00
codon/test/python/myextension2.codon
A. R. Shajii 5613c1a84b
v0.16 (#335)
* Add Python extension lowering pass

* Add DocstringAttribute

* Add extension module codegen

* Handle different argument counts efficiently

* Add warnings to extension lowering

* Fix module name

* Fix extension codegen

* Fix argument check

* Auto-convert Codon exceptions to Python exceptions

* Fix #183

* Fix #162; Fix #135

* Fix #155

* Fix CPython interface in codegen

* Fix #191

* Fix #187

* Fix #189

* Generate object file in pyext mode

* Convert Codon exceptions to Python exceptions

* Fix vtable init; Fix failing tests on Linux

* Fix #190

* Fix #156

* Fix union routing

* Remove need for import python

* Automatic @export and wrapping for toplevel functions

* Reorganize API

* Add Python extension IR structs

* Add special calls for no-suspend yield-expr

* Add special calls for no-suspend yield-expr

* pyextension.h support [wip]

* pyextension.h support [wip]

* pyextension.h support

* pyextension.h support for toplevel functions

* clang-format

* Add PyFunction::nargs field

* Update pyextension codegen (WIP)

* SUpport nargs

* Add support for @pycapture

* PyType codegen (WIP)

* Py method codegen (WIP)

* Add type ptr hook

* Add getset codegen

* Add type alloc function

* Add type pointer hook codegen

* Re-organize codegen

* Add member codegen

* Update module init codegen

* Update module init codegen

* Add support for typePtrHook and new to/from_py hooks

* Fix extension codegen

* Fix init codegen

* Fix init codegen; add "tp_new" slot

* Fix type hook

* Add extra flags

* Specialized wrappers (PyType specs)

* Add static Python link option

* Fix C imports

* Add guards

* Remove unused field

* Python mode only when pyExt set

* Update python module

* Fix assert

* Update codegen/passes

* Fix tuple parsing in index expression

* Fix empty tuple unification

* Do not Cythonize underscore fns

* clang-format

* Fix switch

* Add Py support for cmp/setitem

* Add Py support for cmp/setitem

* Add type is support

* GetSet support

* clang-format

* GetSet support (fixes)

* Avoid useless vtable alloc

* Add iter support

* Fix size_t capture bug

* clang-format

* Fix POD type unification with tuples

* Add __try_from_py__ API

* Fix annotation

* Add static reflection methods (setattr; internal.static.*); refactor PyExt to python.codon; handle errors and kwargs in PyExt

* Python compat fixes

* Update Python object conversions

* Fix PyErrors

* clang-format; add copyright

* Add PyFunction::keywords field

* Fix JIT MRO handling; Refactor out Jupyter support

* Refactor out Jupyter support

* Add support for custom linking args (link=[]) to TOML plugins

* Fix tests

* Use g++ instead of gcc

* Fix Jupyter CMAKE

* Fix Jupyter CMAKE

* Add _PyArg_Parser definition

* Add complex64 type

* Add extra complex64 tests

* Fix Python calls; add staticenumerate

* Fix call

* Fix calls

* Update pyext wrappers

* Fix staticenumerate; Support static calls in tuple()

* Fix pyext routing

* Add add/mul for tuples

* clang-format

* Fix pyext codegen

* Fix wrap_multiple

* Add seq_alloc_atomic_uncollectable

* Fix default generics issue

* Add binary/ternary ops

* Fix missing generic issue

* Fix number slots

* Update pow

* Remove unnecessary pyobj

* Fix allocation

* Refactor errors

* Add test extension

* Fix formatting

* clang-format

* Fix getitem/setitem/delitem in pyext

* Fix pyext iterators

* Add builtin pow() (fix #294)

* Fix #244

* Fix #231

* Fix #229

* Fix #205

* Update docs

* Fix error message

* Add pyext tests

* Add pyext support for @property

* Add pyext support for toplevel fns and @tuple classes

* More pyext tests

* More pyext tests

* Fix file error checking

* More pyext tests

* Update pyext tests

* Update docs

* Add pyext test to CI

* Add pyext support for @tuple.__new__

* Add pyext support for @tuple.__new__

* Fix hetero-tuple issue with fn_overloads

* More pyext tests

* Bump versions

* Fix del magic in pyext

* Fix init magic for tuples in pyext

* Have test-pypi only run on develop branch

* Make exception type indices unnamed-addr

* Fix #316; Fix #317 (slash issue)

* Use uncollectible-alloc for vtable

* Fix #249

* Add pyext docs

* Fix #249; Fix clashing vtables; Fix super() and class_copy

* Add content-atomic type property instruction

* __contents_atomic__ support

* Update internal functions

* Use PIC when generating Python extension

* Cleanup

* Add Dockerfile & fix -fPIC

* Cleanup

* Fix setup.py

* Fix pyext fn iteration

* Fix CI

* clang-format

* Update long conversions in Py bridge

* Support wide-int to str conversions

* Fix test

* Add pow for arbitrary-width ints

* Fix Linux backtraces

* Cleanup

* Add more tests

* Fix docs; Remove tuple.__add__ for scalars

* Update docs

---------

Co-authored-by: Ibrahim Numanagić <ibrahimpasa@gmail.com>
2023-04-12 18:13:54 -04:00

288 lines
6.9 KiB
Python

print('Hello from Codon 2')
@tuple
class Vec:
a: float
b: float
tag: str
n: ClassVar[int] = 0
d: ClassVar[int] = 0
def __new__(a: float, b: float, tag: str) -> Vec:
return (a, b, tag)
def __new__(a: float = 0.0, b: float = 0.0):
v = Vec(a, b, 'v' + str(Vec.n))
Vec.n += 1
return v
def foo(self, a: float = 1.11, b: float = 2.22):
return (self.a, a, b)
def bar(self):
return self
def baz(a: float = 1.11, b: float = 2.22):
return (a, b)
def nop():
return 'nop'
@property
def c(self):
return self.a + self.b
def __str__(self):
return f'{self.tag}: <{self.a}, {self.b}>'
def __repr__(self):
return f'Vec({self.a}, {self.b}, {repr(self.tag)})'
def __add__(self, other: Vec):
return Vec(self.a + other.a, self.b + other.b, f'({self.tag}+{other.tag})')
def __iadd__(self, other: Vec):
a, b = self.a, self.b
a += other.a
b += other.b
tag = f'({self.tag}+={other.tag})'
return Vec(a, b, tag)
def __add__(self, x: float):
return Vec(self.a + x, self.b + x, f'({self.tag}+{x})')
def __iadd__(self, x: float):
a, b = self.a, self.b
a += x
b += x
tag = f'({self.tag}+={x})'
return Vec(a, b, tag)
def __add__(self, x: int):
return Vec(self.a + x, self.b + x, f'({self.tag}++{x})')
def __sub__(self, other: Vec):
return Vec(self.a - other.a, self.b - other.b, f'({self.tag}-{other.tag})')
def __isub__(self, other: Vec):
a, b = self.a, self.b
a -= other.a
b -= other.b
tag = f'({self.tag}-={other.tag})'
return Vec(a, b, tag)
def __mul__(self, x: float):
return Vec(self.a * x, self.b * x, f'({self.tag}*{x})')
def __imul__(self, x: float):
a, b = self.a, self.b
a *= x
b *= x
tag = f'({self.tag}*={x})'
return Vec(a, b, tag)
def __mod__(self, x: float):
return Vec(self.a % x, self.b % x, f'({self.tag}%{x})')
def __imod__(self, x: float):
a, b = self.a, self.b
a %= x
b %= x
tag = f'({self.tag}%={x})'
return Vec(a, b, tag)
def __divmod__(self, x: float):
raise ArithmeticError('no divmod')
# return self.a / x, self.a % x
def __pow__(self, x: float):
return Vec(self.a ** x, self.b ** x, f'({self.tag}**{x})')
def __ipow__(self, x: float):
a, b = self.a, self.b
a **= x
b **= x
tag = f'({self.tag}**={x})'
return Vec(a, b, tag)
def __neg__(self):
return Vec(-self.a, -self.b, f'(-{self.tag})')
def __pos__(self):
return Vec(self.a, self.b, f'(+{self.tag})')
def __abs__(self):
import math
return math.hypot(self.a, self.b)
def __bool__(self):
return bool(self.a) and bool(self.b)
def __invert__(self):
return Vec(-self.a - 1, -self.b - 1, f'(~{self.tag})')
def __lshift__(self, x: int):
y = 1 << x
return Vec(self.a * y, self.b * y, f'({self.tag}<<{x})')
def __ilshift__(self, x: int):
a, b = self.a, self.b
y = 1 << x
a *= y
b *= y
tag = f'({self.tag}<<={x})'
return Vec(a, b, tag)
def __rshift__(self, x: int):
y = 1 << x
return Vec(self.a / y, self.b / y, f'({self.tag}>>{x})')
def __irshift__(self, x: int):
a, b = self.a, self.b
y = 1 << x
a /= y
b /= y
tag = f'({self.tag}>>={x})'
return Vec(a, b, tag)
def __and__(self, x: int):
return Vec(int(self.a) & x, int(self.b) & x, f'({self.tag}&{x})')
def __iand__(self, x: int):
a, b = self.a, self.b
a = int(self.a) & x
b = int(self.b) & x
tag = f'({self.tag}&={x})'
return Vec(a, b, tag)
def __or__(self, x: int):
return Vec(int(self.a) | x, int(self.b) | x, f'({self.tag}|{x})')
def __ior__(self, x: int):
a, b = self.a, self.b
a = int(self.a) | x
b = int(self.b) | x
tag = f'({self.tag}|={x})'
return Vec(a, b, tag)
def __xor__(self, x: int):
return Vec(int(self.a) ^ x, int(self.b) ^ x, f'({self.tag}^{x})')
def __ixor__(self, x: int):
a, b = self.a, self.b
a = int(self.a) ^ x
b = int(self.b) ^ x
tag = f'({self.tag}^={x})'
return Vec(a, b, tag)
#def __int__(self):
# return int(self.b)
#def __float__(self):
# return self.b
#def __index__(self):
# return int(self.a)
def __floordiv__(self, x: float):
return Vec(self.a // x, self.b // x, f'({self.tag}//{x})')
def __ifloordiv__(self, x: float):
a, b = self.a, self.b
a //= x
b //= x
tag = f'({self.tag}//={x})'
return Vec(a, b, tag)
def __truediv__(self, x: float):
return Vec(self.a / x, self.b / x, f'({self.tag}/{x})')
def __itruediv__(self, x: float):
a, b = self.a, self.b
a /= x
b /= x
tag = f'({self.tag}/={x})'
return Vec(a, b, tag)
def __matmul__(self, other: Vec):
return (self.a * other.a) + (self.b * other.b)
def __imatmul__(self, x: float):
a, b = self.a, self.b
a *= x
b *= x
tag = f'({self.tag}@={x})'
return Vec(a, b, tag)
def __len__(self):
return len(self.tag)
def __getitem__(self, idx: int):
if idx == 0:
return self.a
elif idx == 1:
return self.b
elif idx == 11:
return self.a + self.b
else:
raise KeyError('bad vec key ' + str(idx))
def __contains__(self, val: float):
return self.a == val or self.b == val
def __contains__(self, val: str):
return self.tag == val
def __hash__(self):
return int(self.a + self.b)
def __call__(self, a: float = 1.11, b: float = 2.22):
return self.foo(a=a, b=b)
def __call__(self, x: str):
return (self.a, self.b, x)
def __call__(self):
return Vec(self.a, self.b, f'({self.tag}())')
def __iter__(self):
for c in self.tag:
yield c
def __eq__(self, other: Vec):
return self.a == other.a and self.b == other.b
def __eq__(self, x: float):
return self.a == x and self.b == x
def __ne__(self, other: Vec):
return self.a != other.a or self.b != other.b
def __lt__(self, other: Vec):
return abs(self) < abs(other)
def __le__(self, other: Vec):
return abs(self) <= abs(other)
def __gt__(self, other: Vec):
return abs(self) > abs(other)
def __ge__(self, other: Vec):
return abs(self) >= abs(other)
def __del__(self):
Vec.d += 1
def nd():
return Vec.d
def reset():
Vec.n = 0
def par_sum(n: int):
m = 0
@par(num_threads=4)
for i in range(n):
m += 3*i + 7
return m