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/build/cli.py
CHANGED
|
@@ -7,6 +7,7 @@ import socket
|
|
|
7
7
|
import socketserver
|
|
8
8
|
import sys
|
|
9
9
|
from pathlib import Path
|
|
10
|
+
from time import perf_counter
|
|
10
11
|
|
|
11
12
|
from sonolus.build.engine import package_engine
|
|
12
13
|
from sonolus.build.level import package_level_data
|
|
@@ -163,8 +164,13 @@ def main():
|
|
|
163
164
|
build_dir = Path(args.build_dir)
|
|
164
165
|
|
|
165
166
|
if args.command == "build":
|
|
167
|
+
start_time = perf_counter()
|
|
166
168
|
build_project(project, build_dir)
|
|
167
|
-
|
|
169
|
+
end_time = perf_counter()
|
|
170
|
+
print(f"Project built successfully to '{build_dir.resolve()}' in {end_time - start_time:.2f}s")
|
|
168
171
|
elif args.command == "dev":
|
|
172
|
+
start_time = perf_counter()
|
|
169
173
|
build_collection(project, build_dir)
|
|
174
|
+
end_time = perf_counter()
|
|
175
|
+
print(f"Build finished in {end_time - start_time:.2f}s")
|
|
170
176
|
run_server(build_dir / "site", port=args.port)
|
sonolus/build/compile.py
CHANGED
|
@@ -1,90 +1,88 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
|
|
3
|
-
from sonolus.backend.finalize import cfg_to_engine_node
|
|
4
|
-
from sonolus.backend.
|
|
5
|
-
from sonolus.backend.
|
|
6
|
-
from sonolus.backend.
|
|
7
|
-
from sonolus.backend.
|
|
8
|
-
from sonolus.backend.optimize import optimize_and_allocate
|
|
9
|
-
from sonolus.backend.visitor import compile_and_call
|
|
10
|
-
from sonolus.build.node import OutputNodeGenerator
|
|
11
|
-
from sonolus.script.archetype import
|
|
12
|
-
from sonolus.script.callbacks import CallbackInfo
|
|
13
|
-
from sonolus.script.internal.context import (
|
|
14
|
-
CallbackContextState,
|
|
15
|
-
Context,
|
|
16
|
-
GlobalContextState,
|
|
17
|
-
ReadOnlyMemory,
|
|
18
|
-
context_to_cfg,
|
|
19
|
-
ctx,
|
|
20
|
-
using_ctx,
|
|
21
|
-
)
|
|
22
|
-
from sonolus.script.num import
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def compile_mode(
|
|
26
|
-
mode: Mode,
|
|
27
|
-
rom: ReadOnlyMemory,
|
|
28
|
-
archetypes: list[type[
|
|
29
|
-
global_callbacks: list[tuple[CallbackInfo, Callable]] | None,
|
|
30
|
-
) -> dict:
|
|
31
|
-
global_state = GlobalContextState(
|
|
32
|
-
mode, {a: i for i, a in enumerate(archetypes)} if archetypes is not None else None, rom
|
|
33
|
-
)
|
|
34
|
-
nodes = OutputNodeGenerator()
|
|
35
|
-
results = {}
|
|
36
|
-
if archetypes is not None:
|
|
37
|
-
archetype_entries = []
|
|
38
|
-
for archetype in archetypes:
|
|
39
|
-
archetype_data = {
|
|
40
|
-
"name": archetype.name,
|
|
41
|
-
"hasInput": archetype.is_scored,
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
result = compile_and_call(callback
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
ctx().add_statements(IRInstr(Op.Break, [IRConst(1), result.ir()]))
|
|
90
|
-
return context_to_cfg(context)
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
|
|
3
|
+
from sonolus.backend.finalize import cfg_to_engine_node
|
|
4
|
+
from sonolus.backend.ir import IRConst, IRInstr
|
|
5
|
+
from sonolus.backend.mode import Mode
|
|
6
|
+
from sonolus.backend.ops import Op
|
|
7
|
+
from sonolus.backend.optimize.flow import BasicBlock
|
|
8
|
+
from sonolus.backend.optimize.optimize import optimize_and_allocate
|
|
9
|
+
from sonolus.backend.visitor import compile_and_call
|
|
10
|
+
from sonolus.build.node import OutputNodeGenerator
|
|
11
|
+
from sonolus.script.archetype import _BaseArchetype
|
|
12
|
+
from sonolus.script.internal.callbacks import CallbackInfo
|
|
13
|
+
from sonolus.script.internal.context import (
|
|
14
|
+
CallbackContextState,
|
|
15
|
+
Context,
|
|
16
|
+
GlobalContextState,
|
|
17
|
+
ReadOnlyMemory,
|
|
18
|
+
context_to_cfg,
|
|
19
|
+
ctx,
|
|
20
|
+
using_ctx,
|
|
21
|
+
)
|
|
22
|
+
from sonolus.script.num import _is_num
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def compile_mode(
|
|
26
|
+
mode: Mode,
|
|
27
|
+
rom: ReadOnlyMemory,
|
|
28
|
+
archetypes: list[type[_BaseArchetype]] | None,
|
|
29
|
+
global_callbacks: list[tuple[CallbackInfo, Callable]] | None,
|
|
30
|
+
) -> dict:
|
|
31
|
+
global_state = GlobalContextState(
|
|
32
|
+
mode, {a: i for i, a in enumerate(archetypes)} if archetypes is not None else None, rom
|
|
33
|
+
)
|
|
34
|
+
nodes = OutputNodeGenerator()
|
|
35
|
+
results = {}
|
|
36
|
+
if archetypes is not None:
|
|
37
|
+
archetype_entries = []
|
|
38
|
+
for archetype in archetypes:
|
|
39
|
+
archetype_data = {
|
|
40
|
+
"name": archetype.name,
|
|
41
|
+
"hasInput": archetype.is_scored,
|
|
42
|
+
"imports": [{"name": name, "index": index} for name, index in archetype._imported_keys_.items()],
|
|
43
|
+
}
|
|
44
|
+
if mode == Mode.PLAY:
|
|
45
|
+
archetype_data["exports"] = [
|
|
46
|
+
{"name": name, "index": index} for name, index in archetype._exported_keys_.items()
|
|
47
|
+
]
|
|
48
|
+
for cb_name, cb_info in archetype._supported_callbacks_.items():
|
|
49
|
+
cb = getattr(archetype, cb_name)
|
|
50
|
+
if cb in archetype._default_callbacks_:
|
|
51
|
+
continue
|
|
52
|
+
cb_order = getattr(cb, "_callback_order_", 0)
|
|
53
|
+
if not cb_info.supports_order and cb_order != 0:
|
|
54
|
+
raise ValueError(f"Callback '{cb_name}' does not support a non-zero order")
|
|
55
|
+
cfg = callback_to_cfg(global_state, cb, cb_info.name, archetype)
|
|
56
|
+
cfg = optimize_and_allocate(cfg)
|
|
57
|
+
node = cfg_to_engine_node(cfg)
|
|
58
|
+
node_index = nodes.add(node)
|
|
59
|
+
archetype_data[cb_info.name] = {
|
|
60
|
+
"index": node_index,
|
|
61
|
+
"order": cb_order,
|
|
62
|
+
}
|
|
63
|
+
archetype_entries.append(archetype_data)
|
|
64
|
+
results["archetypes"] = archetype_entries
|
|
65
|
+
if global_callbacks is not None:
|
|
66
|
+
for cb_info, cb in global_callbacks:
|
|
67
|
+
cfg = callback_to_cfg(global_state, cb, cb_info.name)
|
|
68
|
+
cfg = optimize_and_allocate(cfg)
|
|
69
|
+
node = cfg_to_engine_node(cfg)
|
|
70
|
+
node_index = nodes.add(node)
|
|
71
|
+
results[cb_info.name] = node_index
|
|
72
|
+
results["nodes"] = nodes.get()
|
|
73
|
+
return results
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def callback_to_cfg(
|
|
77
|
+
global_state: GlobalContextState, callback: Callable, name: str, archetype: type[_BaseArchetype] | None = None
|
|
78
|
+
) -> BasicBlock:
|
|
79
|
+
callback_state = CallbackContextState(name)
|
|
80
|
+
context = Context(global_state, callback_state)
|
|
81
|
+
with using_ctx(context):
|
|
82
|
+
if archetype is not None:
|
|
83
|
+
result = compile_and_call(callback, archetype._for_compilation())
|
|
84
|
+
else:
|
|
85
|
+
result = compile_and_call(callback)
|
|
86
|
+
if _is_num(result):
|
|
87
|
+
ctx().add_statements(IRInstr(Op.Break, [IRConst(1), result.ir()]))
|
|
88
|
+
return context_to_cfg(context)
|
sonolus/build/engine.py
CHANGED
|
@@ -7,15 +7,20 @@ from pathlib import Path
|
|
|
7
7
|
|
|
8
8
|
from sonolus.backend.mode import Mode
|
|
9
9
|
from sonolus.build.compile import compile_mode
|
|
10
|
-
from sonolus.script.archetype import
|
|
10
|
+
from sonolus.script.archetype import _BaseArchetype
|
|
11
11
|
from sonolus.script.bucket import Buckets
|
|
12
|
-
from sonolus.script.callbacks import navigate_callback, preprocess_callback, update_callback, update_spawn_callback
|
|
13
12
|
from sonolus.script.effect import Effects
|
|
14
13
|
from sonolus.script.engine import EngineData
|
|
15
14
|
from sonolus.script.instruction import (
|
|
16
15
|
TutorialInstructionIcons,
|
|
17
16
|
TutorialInstructions,
|
|
18
17
|
)
|
|
18
|
+
from sonolus.script.internal.callbacks import (
|
|
19
|
+
navigate_callback,
|
|
20
|
+
preprocess_callback,
|
|
21
|
+
update_callback,
|
|
22
|
+
update_spawn_callback,
|
|
23
|
+
)
|
|
19
24
|
from sonolus.script.internal.context import ReadOnlyMemory
|
|
20
25
|
from sonolus.script.options import Options
|
|
21
26
|
from sonolus.script.particle import Particles
|
|
@@ -101,7 +106,7 @@ def build_engine_configuration(
|
|
|
101
106
|
|
|
102
107
|
|
|
103
108
|
def build_play_mode(
|
|
104
|
-
archetypes: list[type[
|
|
109
|
+
archetypes: list[type[_BaseArchetype]],
|
|
105
110
|
skin: Skin,
|
|
106
111
|
effects: Effects,
|
|
107
112
|
particles: Particles,
|
|
@@ -118,7 +123,7 @@ def build_play_mode(
|
|
|
118
123
|
|
|
119
124
|
|
|
120
125
|
def build_watch_mode(
|
|
121
|
-
archetypes: list[type[
|
|
126
|
+
archetypes: list[type[_BaseArchetype]],
|
|
122
127
|
skin: Skin,
|
|
123
128
|
effects: Effects,
|
|
124
129
|
particles: Particles,
|
|
@@ -138,7 +143,7 @@ def build_watch_mode(
|
|
|
138
143
|
|
|
139
144
|
|
|
140
145
|
def build_preview_mode(
|
|
141
|
-
archetypes: list[type[
|
|
146
|
+
archetypes: list[type[_BaseArchetype]],
|
|
142
147
|
skin: Skin,
|
|
143
148
|
rom: ReadOnlyMemory,
|
|
144
149
|
):
|
sonolus/build/level.py
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
from sonolus.build.engine import package_output
|
|
2
|
-
from sonolus.script.level import LevelData
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def package_level_data(
|
|
6
|
-
level_data: LevelData,
|
|
7
|
-
):
|
|
8
|
-
return package_output(build_level_data(level_data))
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def build_level_data(
|
|
12
|
-
level_data: LevelData,
|
|
13
|
-
):
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
from sonolus.build.engine import package_output
|
|
2
|
+
from sonolus.script.level import LevelData
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def package_level_data(
|
|
6
|
+
level_data: LevelData,
|
|
7
|
+
):
|
|
8
|
+
return package_output(build_level_data(level_data))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def build_level_data(
|
|
12
|
+
level_data: LevelData,
|
|
13
|
+
):
|
|
14
|
+
level_refs = {entity: i for i, entity in enumerate(level_data.entities)}
|
|
15
|
+
return {
|
|
16
|
+
"bgmOffset": level_data.bgm_offset,
|
|
17
|
+
"entities": [
|
|
18
|
+
{
|
|
19
|
+
"archetype": entity.name,
|
|
20
|
+
"data": entity._level_data_entries(level_refs),
|
|
21
|
+
}
|
|
22
|
+
for entity in level_data.entities
|
|
23
|
+
],
|
|
24
|
+
}
|
sonolus/build/node.py
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
from typing import TypedDict
|
|
2
|
-
|
|
3
|
-
from sonolus.backend.node import ConstantNode, EngineNode, FunctionNode
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ValueOutputNode(TypedDict):
|
|
7
|
-
value: float
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class FunctionOutputNode(TypedDict):
|
|
11
|
-
func: str
|
|
12
|
-
args: list[int]
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class OutputNodeGenerator:
|
|
16
|
-
nodes: list[ValueOutputNode | FunctionOutputNode]
|
|
17
|
-
indexes: dict[EngineNode, int]
|
|
18
|
-
|
|
19
|
-
def __init__(self):
|
|
20
|
-
self.nodes = []
|
|
21
|
-
self.indexes = {}
|
|
22
|
-
|
|
23
|
-
def add(self, node: EngineNode):
|
|
24
|
-
if node in self.indexes:
|
|
25
|
-
return self.indexes[node]
|
|
26
|
-
|
|
27
|
-
match node:
|
|
28
|
-
case ConstantNode(value):
|
|
29
|
-
index = len(self.nodes)
|
|
30
|
-
self.nodes.append({"value": value})
|
|
31
|
-
self.indexes[node] = index
|
|
32
|
-
return index
|
|
33
|
-
case FunctionNode(func, args):
|
|
34
|
-
arg_indexes = [self.add(arg) for arg in args]
|
|
35
|
-
index = len(self.nodes)
|
|
36
|
-
self.nodes.append({"func": func.value, "args": arg_indexes})
|
|
37
|
-
self.indexes[node] = index
|
|
38
|
-
return index
|
|
39
|
-
case _:
|
|
40
|
-
raise ValueError("Invalid node")
|
|
41
|
-
|
|
42
|
-
def get(self):
|
|
43
|
-
return self.nodes
|
|
1
|
+
from typing import TypedDict
|
|
2
|
+
|
|
3
|
+
from sonolus.backend.node import ConstantNode, EngineNode, FunctionNode
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ValueOutputNode(TypedDict):
|
|
7
|
+
value: float
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FunctionOutputNode(TypedDict):
|
|
11
|
+
func: str
|
|
12
|
+
args: list[int]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class OutputNodeGenerator:
|
|
16
|
+
nodes: list[ValueOutputNode | FunctionOutputNode]
|
|
17
|
+
indexes: dict[EngineNode, int]
|
|
18
|
+
|
|
19
|
+
def __init__(self):
|
|
20
|
+
self.nodes = []
|
|
21
|
+
self.indexes = {}
|
|
22
|
+
|
|
23
|
+
def add(self, node: EngineNode):
|
|
24
|
+
if node in self.indexes:
|
|
25
|
+
return self.indexes[node]
|
|
26
|
+
|
|
27
|
+
match node:
|
|
28
|
+
case ConstantNode(value):
|
|
29
|
+
index = len(self.nodes)
|
|
30
|
+
self.nodes.append({"value": value})
|
|
31
|
+
self.indexes[node] = index
|
|
32
|
+
return index
|
|
33
|
+
case FunctionNode(func, args):
|
|
34
|
+
arg_indexes = [self.add(arg) for arg in args]
|
|
35
|
+
index = len(self.nodes)
|
|
36
|
+
self.nodes.append({"func": func.value, "args": arg_indexes})
|
|
37
|
+
self.indexes[node] = index
|
|
38
|
+
return index
|
|
39
|
+
case _:
|
|
40
|
+
raise ValueError("Invalid node")
|
|
41
|
+
|
|
42
|
+
def get(self):
|
|
43
|
+
return self.nodes
|