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/iterator.py
CHANGED
|
@@ -1,214 +1,167 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from abc import abstractmethod
|
|
4
|
-
from collections.abc import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
from sonolus.script.
|
|
8
|
-
from sonolus.script.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class SonolusIterator[T](Iterator[T]):
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return
|
|
77
|
-
|
|
78
|
-
def
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
i
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
self.
|
|
168
|
-
return value
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
class ArrayReverser[V: ArrayLike](Record, ArrayLike):
|
|
172
|
-
array: V
|
|
173
|
-
|
|
174
|
-
def size(self) -> int:
|
|
175
|
-
return self.array.size()
|
|
176
|
-
|
|
177
|
-
def __getitem__(self, index: Num) -> V:
|
|
178
|
-
return self.array[self.size() - 1 - index]
|
|
179
|
-
|
|
180
|
-
def __setitem__(self, index: Num, value: V):
|
|
181
|
-
self.array[self.size() - 1 - index] = value
|
|
182
|
-
|
|
183
|
-
def reversed(self) -> ArrayLike[V]:
|
|
184
|
-
return self.array
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
class Enumerator[V: SonolusIterator](Record, SonolusIterator):
|
|
188
|
-
i: int
|
|
189
|
-
offset: int
|
|
190
|
-
iterator: V
|
|
191
|
-
|
|
192
|
-
def has_next(self) -> bool:
|
|
193
|
-
return self.iterator.has_next()
|
|
194
|
-
|
|
195
|
-
def next(self):
|
|
196
|
-
value = self.iterator.next()
|
|
197
|
-
index = self.i + self.offset
|
|
198
|
-
self.i += 1
|
|
199
|
-
return index, value
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
class ArrayEnumerator[V: ArrayLike](Record, SonolusIterator):
|
|
203
|
-
i: int
|
|
204
|
-
offset: int
|
|
205
|
-
array: V
|
|
206
|
-
|
|
207
|
-
def has_next(self) -> bool:
|
|
208
|
-
return self.i < self.array.size()
|
|
209
|
-
|
|
210
|
-
def next(self):
|
|
211
|
-
value = self.array[self.i]
|
|
212
|
-
index = self.i + self.offset
|
|
213
|
-
self.i += 1
|
|
214
|
-
return index, value
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import abstractmethod
|
|
4
|
+
from collections.abc import Iterator
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from sonolus.script.internal.impl import meta_fn
|
|
8
|
+
from sonolus.script.record import Record
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SonolusIterator[T](Iterator[T]):
|
|
12
|
+
"""Base class for Sonolus iterators.
|
|
13
|
+
|
|
14
|
+
This class is used to define custom iterators that can be used in Sonolus.py.
|
|
15
|
+
|
|
16
|
+
Inheritors must implement the `has_next`, `get`, and `advance` methods.
|
|
17
|
+
The `__next__` and `__iter__` methods are implemented by default.
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
```python
|
|
21
|
+
class MyIterator(Record, SonolusIterator):
|
|
22
|
+
def has_next(self) -> bool:
|
|
23
|
+
...
|
|
24
|
+
|
|
25
|
+
def get(self) -> Any:
|
|
26
|
+
...
|
|
27
|
+
|
|
28
|
+
def advance(self):
|
|
29
|
+
...
|
|
30
|
+
```
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def next(self) -> T:
|
|
34
|
+
result = self.get()
|
|
35
|
+
self.advance()
|
|
36
|
+
return result
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def has_next(self) -> bool:
|
|
40
|
+
"""Return whether the iterator has more elements."""
|
|
41
|
+
raise NotImplementedError
|
|
42
|
+
|
|
43
|
+
@abstractmethod
|
|
44
|
+
def get(self) -> T:
|
|
45
|
+
"""Return the next element of the iterator.
|
|
46
|
+
|
|
47
|
+
May be called multiple times before calling `advance`.
|
|
48
|
+
|
|
49
|
+
Must not be called if `has_next` returns `False`.
|
|
50
|
+
"""
|
|
51
|
+
raise NotImplementedError
|
|
52
|
+
|
|
53
|
+
@abstractmethod
|
|
54
|
+
def advance(self):
|
|
55
|
+
"""Advance the iterator to the next element.
|
|
56
|
+
|
|
57
|
+
Must not be called if `has_next` returns `False`.
|
|
58
|
+
"""
|
|
59
|
+
raise NotImplementedError
|
|
60
|
+
|
|
61
|
+
def __next__(self) -> T:
|
|
62
|
+
if not self.has_next():
|
|
63
|
+
raise StopIteration
|
|
64
|
+
return self.next()
|
|
65
|
+
|
|
66
|
+
def __iter__(self) -> SonolusIterator[T]:
|
|
67
|
+
return self
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class _Enumerator[V: SonolusIterator](Record, SonolusIterator):
|
|
71
|
+
i: int
|
|
72
|
+
offset: int
|
|
73
|
+
iterator: V
|
|
74
|
+
|
|
75
|
+
def has_next(self) -> bool:
|
|
76
|
+
return self.iterator.has_next()
|
|
77
|
+
|
|
78
|
+
def get(self) -> tuple[int, Any]:
|
|
79
|
+
return self.i + self.offset, self.iterator.get()
|
|
80
|
+
|
|
81
|
+
def advance(self):
|
|
82
|
+
self.i += 1
|
|
83
|
+
self.iterator.advance()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class _Zipper[T](Record, SonolusIterator):
|
|
87
|
+
# Can be a, Pair[a, b], Pair[a, Pair[b, c]], etc.
|
|
88
|
+
iterators: T
|
|
89
|
+
|
|
90
|
+
@meta_fn
|
|
91
|
+
def has_next(self) -> bool:
|
|
92
|
+
from sonolus.backend.visitor import compile_and_call
|
|
93
|
+
|
|
94
|
+
return compile_and_call(self._has_next, self._get_iterators())
|
|
95
|
+
|
|
96
|
+
def _get_iterators(self) -> tuple[SonolusIterator, ...]:
|
|
97
|
+
from sonolus.script.containers import Pair
|
|
98
|
+
|
|
99
|
+
iterators = []
|
|
100
|
+
v = self.iterators
|
|
101
|
+
while isinstance(v, Pair):
|
|
102
|
+
iterators.append(v.first)
|
|
103
|
+
v = v.second
|
|
104
|
+
iterators.append(v)
|
|
105
|
+
return tuple(iterators)
|
|
106
|
+
|
|
107
|
+
def _has_next(self, iterators: tuple[SonolusIterator, ...]) -> bool:
|
|
108
|
+
for iterator in iterators: # noqa: SIM110
|
|
109
|
+
if not iterator.has_next():
|
|
110
|
+
return False
|
|
111
|
+
return True
|
|
112
|
+
|
|
113
|
+
@meta_fn
|
|
114
|
+
def get(self) -> tuple[Any, ...]:
|
|
115
|
+
from sonolus.backend.visitor import compile_and_call
|
|
116
|
+
|
|
117
|
+
return tuple(compile_and_call(iterator.get) for iterator in self._get_iterators())
|
|
118
|
+
|
|
119
|
+
@meta_fn
|
|
120
|
+
def advance(self):
|
|
121
|
+
from sonolus.backend.visitor import compile_and_call
|
|
122
|
+
|
|
123
|
+
for iterator in self._get_iterators():
|
|
124
|
+
compile_and_call(iterator.advance)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class _EmptyIterator(Record, SonolusIterator):
|
|
128
|
+
def has_next(self) -> bool:
|
|
129
|
+
return False
|
|
130
|
+
|
|
131
|
+
def get(self) -> Any:
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
def advance(self):
|
|
135
|
+
pass
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class _MappingIterator[T, Fn](Record, SonolusIterator):
|
|
139
|
+
fn: Fn
|
|
140
|
+
iterator: T
|
|
141
|
+
|
|
142
|
+
def has_next(self) -> bool:
|
|
143
|
+
return self.iterator.has_next()
|
|
144
|
+
|
|
145
|
+
def get(self) -> Any:
|
|
146
|
+
return self.fn(self.iterator.get())
|
|
147
|
+
|
|
148
|
+
def advance(self):
|
|
149
|
+
self.iterator.advance()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class _FilteringIterator[T, Fn](Record, SonolusIterator):
|
|
153
|
+
fn: Fn
|
|
154
|
+
iterator: T
|
|
155
|
+
|
|
156
|
+
def has_next(self) -> bool:
|
|
157
|
+
while self.iterator.has_next():
|
|
158
|
+
if self.fn(self.iterator.get()):
|
|
159
|
+
return True
|
|
160
|
+
self.iterator.advance()
|
|
161
|
+
return False
|
|
162
|
+
|
|
163
|
+
def get(self) -> Any:
|
|
164
|
+
return self.iterator.get()
|
|
165
|
+
|
|
166
|
+
def advance(self):
|
|
167
|
+
self.iterator.advance()
|
sonolus/script/level.py
CHANGED
|
@@ -5,6 +5,19 @@ from sonolus.script.archetype import PlayArchetype, StandardArchetypeName, Stand
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class Level:
|
|
8
|
+
"""A Sonolus level.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
name: The name of the level.
|
|
12
|
+
title: The title of the level.
|
|
13
|
+
rating: The rating of the level.
|
|
14
|
+
artists: The artists of the level.
|
|
15
|
+
author: The author of the level.
|
|
16
|
+
cover: The cover of the level.
|
|
17
|
+
bgm: The background music of the level.
|
|
18
|
+
data: The data of the level.
|
|
19
|
+
"""
|
|
20
|
+
|
|
8
21
|
version = 1
|
|
9
22
|
|
|
10
23
|
def __init__(
|
|
@@ -30,6 +43,13 @@ class Level:
|
|
|
30
43
|
|
|
31
44
|
|
|
32
45
|
class LevelData:
|
|
46
|
+
"""The data of a Sonolus level.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
bgm_offset: The background music audio offset.
|
|
50
|
+
entities: The entities of the level.
|
|
51
|
+
"""
|
|
52
|
+
|
|
33
53
|
bgm_offset: float
|
|
34
54
|
entities: list[PlayArchetype]
|
|
35
55
|
|
|
@@ -39,6 +59,8 @@ class LevelData:
|
|
|
39
59
|
|
|
40
60
|
|
|
41
61
|
class BpmChange(PlayArchetype):
|
|
62
|
+
"""The standard bpm change archetype."""
|
|
63
|
+
|
|
42
64
|
name = StandardArchetypeName.BPM_CHANGE
|
|
43
65
|
|
|
44
66
|
beat: StandardImport.BEAT
|
|
@@ -46,6 +68,8 @@ class BpmChange(PlayArchetype):
|
|
|
46
68
|
|
|
47
69
|
|
|
48
70
|
class TimescaleChange(PlayArchetype):
|
|
71
|
+
"""The standard timescale change archetype."""
|
|
72
|
+
|
|
49
73
|
name = StandardArchetypeName.TIMESCALE_CHANGE
|
|
50
74
|
|
|
51
75
|
beat: StandardImport.BEAT
|