sonolus.py 0.1.3__py3-none-any.whl → 0.1.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sonolus.py might be problematic. Click here for more details.
- sonolus/backend/blocks.py +756 -756
- sonolus/backend/excepthook.py +37 -37
- sonolus/backend/finalize.py +77 -69
- sonolus/backend/interpret.py +7 -7
- sonolus/backend/ir.py +29 -3
- sonolus/backend/mode.py +24 -24
- sonolus/backend/node.py +40 -40
- sonolus/backend/ops.py +197 -197
- sonolus/backend/optimize/__init__.py +0 -0
- sonolus/backend/optimize/allocate.py +126 -0
- sonolus/backend/optimize/constant_evaluation.py +374 -0
- sonolus/backend/optimize/copy_coalesce.py +85 -0
- sonolus/backend/optimize/dead_code.py +185 -0
- sonolus/backend/optimize/dominance.py +96 -0
- sonolus/backend/{flow.py → optimize/flow.py} +122 -92
- sonolus/backend/optimize/inlining.py +137 -0
- sonolus/backend/optimize/liveness.py +177 -0
- sonolus/backend/optimize/optimize.py +44 -0
- sonolus/backend/optimize/passes.py +52 -0
- sonolus/backend/optimize/simplify.py +191 -0
- sonolus/backend/optimize/ssa.py +200 -0
- sonolus/backend/place.py +17 -25
- sonolus/backend/utils.py +58 -48
- sonolus/backend/visitor.py +1151 -882
- sonolus/build/cli.py +7 -1
- sonolus/build/compile.py +88 -90
- sonolus/build/engine.py +10 -5
- sonolus/build/level.py +24 -23
- sonolus/build/node.py +43 -43
- sonolus/script/archetype.py +438 -139
- sonolus/script/array.py +27 -10
- sonolus/script/array_like.py +297 -0
- sonolus/script/bucket.py +253 -191
- sonolus/script/containers.py +257 -51
- sonolus/script/debug.py +26 -10
- sonolus/script/easing.py +365 -0
- sonolus/script/effect.py +191 -131
- sonolus/script/engine.py +71 -4
- sonolus/script/globals.py +303 -269
- sonolus/script/instruction.py +205 -151
- sonolus/script/internal/__init__.py +5 -5
- sonolus/script/internal/builtin_impls.py +255 -144
- sonolus/script/{callbacks.py → internal/callbacks.py} +127 -127
- sonolus/script/internal/constant.py +139 -0
- sonolus/script/internal/context.py +26 -9
- sonolus/script/internal/descriptor.py +17 -17
- sonolus/script/internal/dict_impl.py +65 -0
- sonolus/script/internal/generic.py +6 -9
- sonolus/script/internal/impl.py +38 -13
- sonolus/script/internal/introspection.py +17 -14
- sonolus/script/internal/math_impls.py +121 -0
- sonolus/script/internal/native.py +40 -38
- sonolus/script/internal/random.py +67 -0
- sonolus/script/internal/range.py +81 -0
- sonolus/script/internal/transient.py +51 -0
- sonolus/script/internal/tuple_impl.py +113 -0
- sonolus/script/internal/value.py +3 -3
- sonolus/script/interval.py +338 -112
- sonolus/script/iterator.py +167 -214
- sonolus/script/level.py +24 -0
- sonolus/script/num.py +80 -48
- sonolus/script/options.py +257 -191
- sonolus/script/particle.py +190 -157
- sonolus/script/pointer.py +30 -30
- sonolus/script/print.py +102 -81
- sonolus/script/project.py +8 -0
- sonolus/script/quad.py +263 -0
- sonolus/script/record.py +47 -16
- sonolus/script/runtime.py +52 -1
- sonolus/script/sprite.py +418 -333
- sonolus/script/text.py +409 -407
- sonolus/script/timing.py +114 -42
- sonolus/script/transform.py +332 -48
- sonolus/script/ui.py +216 -160
- sonolus/script/values.py +6 -13
- sonolus/script/vec.py +196 -78
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.5.dist-info}/METADATA +1 -1
- sonolus_py-0.1.5.dist-info/RECORD +89 -0
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.5.dist-info}/WHEEL +1 -1
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.5.dist-info}/licenses/LICENSE +21 -21
- sonolus/backend/allocate.py +0 -51
- sonolus/backend/optimize.py +0 -9
- sonolus/backend/passes.py +0 -6
- sonolus/backend/simplify.py +0 -30
- sonolus/script/comptime.py +0 -160
- sonolus/script/graphics.py +0 -150
- sonolus/script/math.py +0 -92
- sonolus/script/range.py +0 -58
- sonolus_py-0.1.3.dist-info/RECORD +0 -75
- {sonolus_py-0.1.3.dist-info → sonolus_py-0.1.5.dist-info}/entry_points.txt +0 -0
sonolus/script/num.py
CHANGED
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
|
|
4
4
|
import operator
|
|
5
5
|
from collections.abc import Callable, Iterable
|
|
6
|
-
from typing import TYPE_CHECKING, Any, Self, TypeIs, final
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Self, TypeIs, final, runtime_checkable
|
|
7
7
|
|
|
8
8
|
from sonolus.backend.ir import IRConst, IRGet, IRPureInstr, IRSet
|
|
9
9
|
from sonolus.backend.ops import Op
|
|
@@ -14,18 +14,18 @@ from sonolus.script.internal.impl import meta_fn
|
|
|
14
14
|
from sonolus.script.internal.value import Value
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
class
|
|
17
|
+
class _NumMeta(type):
|
|
18
18
|
def __instancecheck__(cls, instance):
|
|
19
|
-
return isinstance(instance, float | int | bool) or
|
|
19
|
+
return isinstance(instance, float | int | bool) or _is_num(instance)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def
|
|
22
|
+
def _is_num(value: Any) -> TypeIs[Num]:
|
|
23
23
|
"""Check if a value is a precisely Num instance."""
|
|
24
24
|
return type.__instancecheck__(Num, value) # type: ignore # noqa: PLC2801
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
@final
|
|
28
|
-
class _Num(Value, metaclass=
|
|
28
|
+
class _Num(Value, metaclass=_NumMeta):
|
|
29
29
|
# This works for ints, floats, and bools
|
|
30
30
|
# Since we don't support complex numbers, real is equal to the original number
|
|
31
31
|
__match_args__ = ("real",)
|
|
@@ -37,7 +37,7 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
37
37
|
raise TypeError("Cannot create a Num from a complex number")
|
|
38
38
|
if isinstance(data, int):
|
|
39
39
|
data = float(data)
|
|
40
|
-
if
|
|
40
|
+
if _is_num(data):
|
|
41
41
|
raise InternalError("Cannot create a Num from a Num")
|
|
42
42
|
self.data = data
|
|
43
43
|
|
|
@@ -73,7 +73,7 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
73
73
|
def _accept_(cls, value: Any) -> Self:
|
|
74
74
|
if not cls._accepts_(value):
|
|
75
75
|
raise TypeError(f"Cannot accept {value}")
|
|
76
|
-
if
|
|
76
|
+
if _is_num(value):
|
|
77
77
|
return value
|
|
78
78
|
return cls(value)
|
|
79
79
|
|
|
@@ -92,7 +92,7 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
92
92
|
value = next(iter(values))
|
|
93
93
|
return Num(value)
|
|
94
94
|
|
|
95
|
-
def _to_list_(self) -> list[float | BlockPlace]:
|
|
95
|
+
def _to_list_(self, level_refs: dict[Any, int] | None = None) -> list[float | BlockPlace]:
|
|
96
96
|
return [self.data]
|
|
97
97
|
|
|
98
98
|
@classmethod
|
|
@@ -122,7 +122,10 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
122
122
|
raise ValueError("Cannot assign to a number")
|
|
123
123
|
|
|
124
124
|
def _copy_(self) -> Self:
|
|
125
|
-
|
|
125
|
+
if ctx():
|
|
126
|
+
return self._get_()
|
|
127
|
+
else:
|
|
128
|
+
return Num(self.data)
|
|
126
129
|
|
|
127
130
|
@classmethod
|
|
128
131
|
def _alloc_(cls) -> Self:
|
|
@@ -168,7 +171,7 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
168
171
|
def __eq__(self, other) -> Self:
|
|
169
172
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
170
173
|
if a._is_py_() and b._is_py_():
|
|
171
|
-
return Num(a.
|
|
174
|
+
return Num(a._as_py_() == b._as_py_())
|
|
172
175
|
if a.data == b.data:
|
|
173
176
|
return Num(True)
|
|
174
177
|
return None
|
|
@@ -184,7 +187,7 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
184
187
|
def __ne__(self, other) -> Self:
|
|
185
188
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
186
189
|
if a._is_py_() and b._is_py_():
|
|
187
|
-
return Num(a.
|
|
190
|
+
return Num(a._as_py_() != b._as_py_())
|
|
188
191
|
if a.data == b.data:
|
|
189
192
|
return Num(False)
|
|
190
193
|
return None
|
|
@@ -195,7 +198,7 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
195
198
|
def __lt__(self, other) -> Self:
|
|
196
199
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
197
200
|
if a._is_py_() and b._is_py_():
|
|
198
|
-
return Num(a.
|
|
201
|
+
return Num(a._as_py_() < b._as_py_())
|
|
199
202
|
if a.data == b.data:
|
|
200
203
|
return Num(False)
|
|
201
204
|
return None
|
|
@@ -206,7 +209,9 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
206
209
|
def __le__(self, other) -> Self:
|
|
207
210
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
208
211
|
if a._is_py_() and b._is_py_():
|
|
209
|
-
return Num(a.
|
|
212
|
+
return Num(a._as_py_() <= b._as_py_())
|
|
213
|
+
if a.data == b.data:
|
|
214
|
+
return Num(True)
|
|
210
215
|
return None
|
|
211
216
|
|
|
212
217
|
return self._bin_op(other, const_fn, Op.LessOr)
|
|
@@ -215,7 +220,7 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
215
220
|
def __gt__(self, other) -> Self:
|
|
216
221
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
217
222
|
if a._is_py_() and b._is_py_():
|
|
218
|
-
return Num(a.
|
|
223
|
+
return Num(a._as_py_() > b._as_py_())
|
|
219
224
|
if a.data == b.data:
|
|
220
225
|
return Num(False)
|
|
221
226
|
return None
|
|
@@ -226,7 +231,9 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
226
231
|
def __ge__(self, other) -> Self:
|
|
227
232
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
228
233
|
if a._is_py_() and b._is_py_():
|
|
229
|
-
return Num(a.
|
|
234
|
+
return Num(a._as_py_() >= b._as_py_())
|
|
235
|
+
if a.data == b.data:
|
|
236
|
+
return Num(True)
|
|
230
237
|
return None
|
|
231
238
|
|
|
232
239
|
return self._bin_op(other, const_fn, Op.GreaterOr)
|
|
@@ -235,10 +242,10 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
235
242
|
def __add__(self, other) -> Self:
|
|
236
243
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
237
244
|
if a._is_py_() and b._is_py_():
|
|
238
|
-
return Num(a.
|
|
239
|
-
if a._is_py_() and a.
|
|
245
|
+
return Num(a._as_py_() + b._as_py_())
|
|
246
|
+
if a._is_py_() and a._as_py_() == 0:
|
|
240
247
|
return b
|
|
241
|
-
if b._is_py_() and b.
|
|
248
|
+
if b._is_py_() and b._as_py_() == 0:
|
|
242
249
|
return a
|
|
243
250
|
return None
|
|
244
251
|
|
|
@@ -248,10 +255,10 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
248
255
|
def __sub__(self, other) -> Self:
|
|
249
256
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
250
257
|
if a._is_py_() and b._is_py_():
|
|
251
|
-
return Num(a.
|
|
252
|
-
if a._is_py_() and a.
|
|
258
|
+
return Num(a._as_py_() - b._as_py_())
|
|
259
|
+
if a._is_py_() and a._as_py_() == 0:
|
|
253
260
|
return -b
|
|
254
|
-
if b._is_py_() and b.
|
|
261
|
+
if b._is_py_() and b._as_py_() == 0:
|
|
255
262
|
return a
|
|
256
263
|
return None
|
|
257
264
|
|
|
@@ -261,16 +268,16 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
261
268
|
def __mul__(self, other) -> Self:
|
|
262
269
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
263
270
|
if a._is_py_() and b._is_py_():
|
|
264
|
-
return Num(a.
|
|
271
|
+
return Num(a._as_py_() * b._as_py_())
|
|
265
272
|
if a._is_py_():
|
|
266
|
-
if a.
|
|
273
|
+
if a._as_py_() == 0:
|
|
267
274
|
return Num(0)
|
|
268
|
-
if a.
|
|
275
|
+
if a._as_py_() == 1:
|
|
269
276
|
return b
|
|
270
277
|
if b._is_py_():
|
|
271
|
-
if b.
|
|
278
|
+
if b._as_py_() == 0:
|
|
272
279
|
return Num(0)
|
|
273
|
-
if b.
|
|
280
|
+
if b._as_py_() == 1:
|
|
274
281
|
return a
|
|
275
282
|
return None
|
|
276
283
|
|
|
@@ -280,13 +287,13 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
280
287
|
def __truediv__(self, other) -> Self:
|
|
281
288
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
282
289
|
if a._is_py_() and b._is_py_():
|
|
283
|
-
if b.
|
|
290
|
+
if b._as_py_() == 0:
|
|
284
291
|
return None
|
|
285
|
-
return Num(a.
|
|
292
|
+
return Num(a._as_py_() / b._as_py_())
|
|
286
293
|
if b._is_py_():
|
|
287
|
-
if b.
|
|
294
|
+
if b._as_py_() == 1:
|
|
288
295
|
return a
|
|
289
|
-
if b.
|
|
296
|
+
if b._as_py_() == -1:
|
|
290
297
|
return -a
|
|
291
298
|
return None
|
|
292
299
|
|
|
@@ -296,13 +303,13 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
296
303
|
def __floordiv__(self, other) -> Self:
|
|
297
304
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
298
305
|
if a._is_py_() and b._is_py_():
|
|
299
|
-
if b.
|
|
306
|
+
if b._as_py_() == 0:
|
|
300
307
|
return None
|
|
301
|
-
return Num(a.
|
|
308
|
+
return Num(a._as_py_() // b._as_py_())
|
|
302
309
|
if b._is_py_():
|
|
303
|
-
if b.
|
|
310
|
+
if b._as_py_() == 1:
|
|
304
311
|
return a
|
|
305
|
-
if b.
|
|
312
|
+
if b._as_py_() == -1:
|
|
306
313
|
return -a
|
|
307
314
|
return None
|
|
308
315
|
|
|
@@ -312,9 +319,9 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
312
319
|
def __mod__(self, other) -> Self:
|
|
313
320
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
314
321
|
if a._is_py_() and b._is_py_():
|
|
315
|
-
if b.
|
|
322
|
+
if b._as_py_() == 0:
|
|
316
323
|
return None
|
|
317
|
-
return Num(a.
|
|
324
|
+
return Num(a._as_py_() % b._as_py_())
|
|
318
325
|
return None
|
|
319
326
|
|
|
320
327
|
return self._bin_op(other, const_fn, Op.Mod)
|
|
@@ -324,13 +331,13 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
324
331
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
325
332
|
if a._is_py_() and b._is_py_():
|
|
326
333
|
try:
|
|
327
|
-
return Num(a.
|
|
334
|
+
return Num(a._as_py_() ** b._as_py_())
|
|
328
335
|
except OverflowError:
|
|
329
336
|
return None
|
|
330
337
|
if b._is_py_():
|
|
331
|
-
if b.
|
|
338
|
+
if b._as_py_() == 0:
|
|
332
339
|
return Num(1)
|
|
333
|
-
if b.
|
|
340
|
+
if b._as_py_() == 1:
|
|
334
341
|
return a
|
|
335
342
|
return None
|
|
336
343
|
|
|
@@ -360,9 +367,9 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
360
367
|
def and_(self, other) -> Self:
|
|
361
368
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
362
369
|
if a._is_py_() and b._is_py_():
|
|
363
|
-
return Num(a.
|
|
370
|
+
return Num(a._as_py_() and b._as_py_())
|
|
364
371
|
if a._is_py_():
|
|
365
|
-
if a.
|
|
372
|
+
if a._as_py_() == 0:
|
|
366
373
|
return a
|
|
367
374
|
else:
|
|
368
375
|
return b
|
|
@@ -373,9 +380,9 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
373
380
|
def or_(self, other) -> Self:
|
|
374
381
|
def const_fn(a: Self, b: Self) -> Num | None:
|
|
375
382
|
if a._is_py_() and b._is_py_():
|
|
376
|
-
return Num(a.
|
|
383
|
+
return Num(a._as_py_() or b._as_py_())
|
|
377
384
|
if a._is_py_():
|
|
378
|
-
if a.
|
|
385
|
+
if a._as_py_() == 0:
|
|
379
386
|
return b
|
|
380
387
|
else:
|
|
381
388
|
return a
|
|
@@ -396,11 +403,36 @@ class _Num(Value, metaclass=NumMeta):
|
|
|
396
403
|
|
|
397
404
|
|
|
398
405
|
if TYPE_CHECKING:
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
406
|
+
from typing import Protocol
|
|
407
|
+
|
|
408
|
+
@runtime_checkable
|
|
409
|
+
class Num[T](Protocol, int, bool, float):
|
|
410
|
+
def __add__(self, other: T, /) -> Num: ...
|
|
411
|
+
def __sub__(self, other: T, /) -> Num: ...
|
|
412
|
+
def __mul__(self, other: T, /) -> Num: ...
|
|
413
|
+
def __truediv__(self, other: T, /) -> Num: ...
|
|
414
|
+
def __floordiv__(self, other: T, /) -> Num: ...
|
|
415
|
+
def __mod__(self, other: T, /) -> Num: ...
|
|
416
|
+
def __pow__(self, other: T, /) -> Num: ...
|
|
417
|
+
|
|
418
|
+
def __neg__(self, /) -> Num: ...
|
|
419
|
+
def __pos__(self, /) -> Num: ...
|
|
420
|
+
def __abs__(self, /) -> Num: ...
|
|
421
|
+
|
|
422
|
+
def __eq__(self, other: Any, /) -> bool: ...
|
|
423
|
+
def __ne__(self, other: Any, /) -> bool: ...
|
|
424
|
+
def __lt__(self, other: T, /) -> bool: ...
|
|
425
|
+
def __le__(self, other: T, /) -> bool: ...
|
|
426
|
+
def __gt__(self, other: T, /) -> bool: ...
|
|
427
|
+
def __ge__(self, other: T, /) -> bool: ...
|
|
428
|
+
|
|
429
|
+
def __hash__(self, /) -> int: ...
|
|
430
|
+
|
|
431
|
+
@property
|
|
432
|
+
def real(self) -> Num: ...
|
|
433
|
+
|
|
434
|
+
@property
|
|
435
|
+
def imag(self) -> Num: ...
|
|
404
436
|
else:
|
|
405
437
|
# Need to do this to satisfy type checkers (especially Pycharm)
|
|
406
438
|
_Num.__name__ = "Num"
|