sonolus.py 0.1.0__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.

Files changed (75) hide show
  1. sonolus/__init__.py +0 -0
  2. sonolus/backend/__init__.py +0 -0
  3. sonolus/backend/allocate.py +51 -0
  4. sonolus/backend/blocks.py +756 -0
  5. sonolus/backend/excepthook.py +37 -0
  6. sonolus/backend/finalize.py +69 -0
  7. sonolus/backend/flow.py +92 -0
  8. sonolus/backend/interpret.py +333 -0
  9. sonolus/backend/ir.py +89 -0
  10. sonolus/backend/mode.py +24 -0
  11. sonolus/backend/node.py +40 -0
  12. sonolus/backend/ops.py +197 -0
  13. sonolus/backend/optimize.py +9 -0
  14. sonolus/backend/passes.py +6 -0
  15. sonolus/backend/place.py +90 -0
  16. sonolus/backend/simplify.py +30 -0
  17. sonolus/backend/utils.py +48 -0
  18. sonolus/backend/visitor.py +880 -0
  19. sonolus/build/__init__.py +0 -0
  20. sonolus/build/cli.py +170 -0
  21. sonolus/build/collection.py +293 -0
  22. sonolus/build/compile.py +90 -0
  23. sonolus/build/defaults.py +32 -0
  24. sonolus/build/engine.py +149 -0
  25. sonolus/build/level.py +23 -0
  26. sonolus/build/node.py +43 -0
  27. sonolus/build/project.py +94 -0
  28. sonolus/py.typed +0 -0
  29. sonolus/script/__init__.py +0 -0
  30. sonolus/script/archetype.py +651 -0
  31. sonolus/script/array.py +241 -0
  32. sonolus/script/bucket.py +192 -0
  33. sonolus/script/callbacks.py +105 -0
  34. sonolus/script/comptime.py +146 -0
  35. sonolus/script/containers.py +247 -0
  36. sonolus/script/debug.py +70 -0
  37. sonolus/script/effect.py +132 -0
  38. sonolus/script/engine.py +101 -0
  39. sonolus/script/globals.py +234 -0
  40. sonolus/script/graphics.py +141 -0
  41. sonolus/script/icon.py +73 -0
  42. sonolus/script/internal/__init__.py +5 -0
  43. sonolus/script/internal/builtin_impls.py +144 -0
  44. sonolus/script/internal/context.py +365 -0
  45. sonolus/script/internal/descriptor.py +17 -0
  46. sonolus/script/internal/error.py +15 -0
  47. sonolus/script/internal/generic.py +197 -0
  48. sonolus/script/internal/impl.py +69 -0
  49. sonolus/script/internal/introspection.py +14 -0
  50. sonolus/script/internal/native.py +38 -0
  51. sonolus/script/internal/value.py +144 -0
  52. sonolus/script/interval.py +98 -0
  53. sonolus/script/iterator.py +211 -0
  54. sonolus/script/level.py +52 -0
  55. sonolus/script/math.py +92 -0
  56. sonolus/script/num.py +382 -0
  57. sonolus/script/options.py +194 -0
  58. sonolus/script/particle.py +158 -0
  59. sonolus/script/pointer.py +30 -0
  60. sonolus/script/project.py +17 -0
  61. sonolus/script/range.py +58 -0
  62. sonolus/script/record.py +293 -0
  63. sonolus/script/runtime.py +526 -0
  64. sonolus/script/sprite.py +332 -0
  65. sonolus/script/text.py +404 -0
  66. sonolus/script/timing.py +42 -0
  67. sonolus/script/transform.py +118 -0
  68. sonolus/script/ui.py +160 -0
  69. sonolus/script/values.py +43 -0
  70. sonolus/script/vec.py +48 -0
  71. sonolus_py-0.1.0.dist-info/METADATA +10 -0
  72. sonolus_py-0.1.0.dist-info/RECORD +75 -0
  73. sonolus_py-0.1.0.dist-info/WHEEL +4 -0
  74. sonolus_py-0.1.0.dist-info/entry_points.txt +2 -0
  75. sonolus_py-0.1.0.dist-info/licenses/LICENSE +21 -0
sonolus/backend/ops.py ADDED
@@ -0,0 +1,197 @@
1
+ from enum import StrEnum
2
+
3
+
4
+ class Op(StrEnum):
5
+ def __new__(cls, name: str, side_effects: bool, pure: bool, control_flow: bool):
6
+ obj = str.__new__(cls, name)
7
+ obj._value_ = name
8
+ obj.side_effects = side_effects
9
+ obj.pure = pure
10
+ obj.control_flow = control_flow
11
+ return obj
12
+
13
+ Abs = ("Abs", False, True, False)
14
+ Add = ("Add", False, True, False)
15
+ And = ("And", False, True, True)
16
+ Arccos = ("Arccos", False, True, False)
17
+ Arcsin = ("Arcsin", False, True, False)
18
+ Arctan = ("Arctan", False, True, False)
19
+ Arctan2 = ("Arctan2", False, True, False)
20
+ BeatToBPM = ("BeatToBPM", False, True, False)
21
+ BeatToStartingBeat = ("BeatToStartingBeat", False, True, False)
22
+ BeatToStartingTime = ("BeatToStartingTime", False, True, False)
23
+ BeatToTime = ("BeatToTime", False, True, False)
24
+ Block = ("Block", False, True, True)
25
+ Break = ("Break", True, False, True)
26
+ Ceil = ("Ceil", False, True, False)
27
+ Clamp = ("Clamp", False, True, False)
28
+ Copy = ("Copy", True, False, False)
29
+ Cos = ("Cos", False, True, False)
30
+ Cosh = ("Cosh", False, True, False)
31
+ DebugLog = ("DebugLog", True, False, False)
32
+ DebugPause = ("DebugPause", True, False, False)
33
+ DecrementPost = ("DecrementPost", True, False, False)
34
+ DecrementPostPointed = ("DecrementPostPointed", True, False, False)
35
+ DecrementPostShifted = ("DecrementPostShifted", True, False, False)
36
+ DecrementPre = ("DecrementPre", True, False, False)
37
+ DecrementPrePointed = ("DecrementPrePointed", True, False, False)
38
+ DecrementPreShifted = ("DecrementPreShifted", True, False, False)
39
+ Degree = ("Degree", False, True, False)
40
+ DestroyParticleEffect = ("DestroyParticleEffect", True, False, False)
41
+ Divide = ("Divide", False, True, False)
42
+ DoWhile = ("DoWhile", False, True, True)
43
+ Draw = ("Draw", True, False, False)
44
+ DrawCurvedB = ("DrawCurvedB", True, False, False)
45
+ DrawCurvedBT = ("DrawCurvedBT", True, False, False)
46
+ DrawCurvedL = ("DrawCurvedL", True, False, False)
47
+ DrawCurvedLR = ("DrawCurvedLR", True, False, False)
48
+ DrawCurvedR = ("DrawCurvedR", True, False, False)
49
+ DrawCurvedT = ("DrawCurvedT", True, False, False)
50
+ EaseInBack = ("EaseInBack", False, True, False)
51
+ EaseInCirc = ("EaseInCirc", False, True, False)
52
+ EaseInCubic = ("EaseInCubic", False, True, False)
53
+ EaseInElastic = ("EaseInElastic", False, True, False)
54
+ EaseInExpo = ("EaseInExpo", False, True, False)
55
+ EaseInOutBack = ("EaseInOutBack", False, True, False)
56
+ EaseInOutCirc = ("EaseInOutCirc", False, True, False)
57
+ EaseInOutCubic = ("EaseInOutCubic", False, True, False)
58
+ EaseInOutElastic = ("EaseInOutElastic", False, True, False)
59
+ EaseInOutExpo = ("EaseInOutExpo", False, True, False)
60
+ EaseInOutQuad = ("EaseInOutQuad", False, True, False)
61
+ EaseInOutQuart = ("EaseInOutQuart", False, True, False)
62
+ EaseInOutQuint = ("EaseInOutQuint", False, True, False)
63
+ EaseInOutSine = ("EaseInOutSine", False, True, False)
64
+ EaseInQuad = ("EaseInQuad", False, True, False)
65
+ EaseInQuart = ("EaseInQuart", False, True, False)
66
+ EaseInQuint = ("EaseInQuint", False, True, False)
67
+ EaseInSine = ("EaseInSine", False, True, False)
68
+ EaseOutBack = ("EaseOutBack", False, True, False)
69
+ EaseOutCirc = ("EaseOutCirc", False, True, False)
70
+ EaseOutCubic = ("EaseOutCubic", False, True, False)
71
+ EaseOutElastic = ("EaseOutElastic", False, True, False)
72
+ EaseOutExpo = ("EaseOutExpo", False, True, False)
73
+ EaseOutInBack = ("EaseOutInBack", False, True, False)
74
+ EaseOutInCirc = ("EaseOutInCirc", False, True, False)
75
+ EaseOutInCubic = ("EaseOutInCubic", False, True, False)
76
+ EaseOutInElastic = ("EaseOutInElastic", False, True, False)
77
+ EaseOutInExpo = ("EaseOutInExpo", False, True, False)
78
+ EaseOutInQuad = ("EaseOutInQuad", False, True, False)
79
+ EaseOutInQuart = ("EaseOutInQuart", False, True, False)
80
+ EaseOutInQuint = ("EaseOutInQuint", False, True, False)
81
+ EaseOutInSine = ("EaseOutInSine", False, True, False)
82
+ EaseOutQuad = ("EaseOutQuad", False, True, False)
83
+ EaseOutQuart = ("EaseOutQuart", False, True, False)
84
+ EaseOutQuint = ("EaseOutQuint", False, True, False)
85
+ EaseOutSine = ("EaseOutSine", False, True, False)
86
+ Equal = ("Equal", False, True, False)
87
+ Execute = ("Execute", False, True, False)
88
+ Execute0 = ("Execute0", False, True, False)
89
+ ExportValue = ("ExportValue", True, False, False)
90
+ Floor = ("Floor", False, True, False)
91
+ Frac = ("Frac", False, True, False)
92
+ Get = ("Get", False, False, False)
93
+ GetPointed = ("GetPointed", False, False, False)
94
+ GetShifted = ("GetShifted", False, False, False)
95
+ Greater = ("Greater", False, True, False)
96
+ GreaterOr = ("GreaterOr", False, True, False)
97
+ HasEffectClip = ("HasEffectClip", False, True, False)
98
+ HasParticleEffect = ("HasParticleEffect", False, True, False)
99
+ HasSkinSprite = ("HasSkinSprite", False, True, False)
100
+ If = ("If", False, True, True)
101
+ IncrementPost = ("IncrementPost", True, False, False)
102
+ IncrementPostPointed = ("IncrementPostPointed", True, False, False)
103
+ IncrementPostShifted = ("IncrementPostShifted", True, False, False)
104
+ IncrementPre = ("IncrementPre", True, False, False)
105
+ IncrementPrePointed = ("IncrementPrePointed", True, False, False)
106
+ IncrementPreShifted = ("IncrementPreShifted", True, False, False)
107
+ Judge = ("Judge", False, True, False)
108
+ JudgeSimple = ("JudgeSimple", False, True, False)
109
+ JumpLoop = ("JumpLoop", False, True, True)
110
+ Lerp = ("Lerp", False, True, False)
111
+ LerpClamped = ("LerpClamped", False, True, False)
112
+ Less = ("Less", False, True, False)
113
+ LessOr = ("LessOr", False, True, False)
114
+ Log = ("Log", False, True, False)
115
+ Max = ("Max", False, True, False)
116
+ Min = ("Min", False, True, False)
117
+ Mod = ("Mod", False, True, False)
118
+ MoveParticleEffect = ("MoveParticleEffect", True, False, False)
119
+ Multiply = ("Multiply", False, True, False)
120
+ Negate = ("Negate", False, True, False)
121
+ Not = ("Not", False, True, False)
122
+ NotEqual = ("NotEqual", False, True, False)
123
+ Or = ("Or", False, True, True)
124
+ Paint = ("Paint", True, False, False)
125
+ Play = ("Play", True, False, False)
126
+ PlayLooped = ("PlayLooped", True, False, False)
127
+ PlayLoopedScheduled = ("PlayLoopedScheduled", True, False, False)
128
+ PlayScheduled = ("PlayScheduled", True, False, False)
129
+ Power = ("Power", False, True, False)
130
+ Print = ("Print", True, False, False)
131
+ Radian = ("Radian", False, True, False)
132
+ Random = ("Random", False, False, False)
133
+ RandomInteger = ("RandomInteger", False, False, False)
134
+ Rem = ("Rem", False, True, False)
135
+ Remap = ("Remap", False, True, False)
136
+ RemapClamped = ("RemapClamped", False, True, False)
137
+ Round = ("Round", False, True, False)
138
+ Set = ("Set", True, False, False)
139
+ SetAdd = ("SetAdd", True, False, False)
140
+ SetAddPointed = ("SetAddPointed", True, False, False)
141
+ SetAddShifted = ("SetAddShifted", True, False, False)
142
+ SetDivide = ("SetDivide", True, False, False)
143
+ SetDividePointed = ("SetDividePointed", True, False, False)
144
+ SetDivideShifted = ("SetDivideShifted", True, False, False)
145
+ SetMod = ("SetMod", True, False, False)
146
+ SetModPointed = ("SetModPointed", True, False, False)
147
+ SetModShifted = ("SetModShifted", True, False, False)
148
+ SetMultiply = ("SetMultiply", True, False, False)
149
+ SetMultiplyPointed = ("SetMultiplyPointed", True, False, False)
150
+ SetMultiplyShifted = ("SetMultiplyShifted", True, False, False)
151
+ SetPointed = ("SetPointed", True, False, False)
152
+ SetPower = ("SetPower", True, False, False)
153
+ SetPowerPointed = ("SetPowerPointed", True, False, False)
154
+ SetPowerShifted = ("SetPowerShifted", True, False, False)
155
+ SetRem = ("SetRem", True, False, False)
156
+ SetRemPointed = ("SetRemPointed", True, False, False)
157
+ SetRemShifted = ("SetRemShifted", True, False, False)
158
+ SetShifted = ("SetShifted", True, False, False)
159
+ SetSubtract = ("SetSubtract", True, False, False)
160
+ SetSubtractPointed = ("SetSubtractPointed", True, False, False)
161
+ SetSubtractShifted = ("SetSubtractShifted", True, False, False)
162
+ Sign = ("Sign", False, True, False)
163
+ Sin = ("Sin", False, True, False)
164
+ Sinh = ("Sinh", False, True, False)
165
+ Spawn = ("Spawn", True, False, False)
166
+ SpawnParticleEffect = ("SpawnParticleEffect", True, False, False)
167
+ StackEnter = ("StackEnter", True, False, False)
168
+ StackGet = ("StackGet", False, False, False)
169
+ StackGetFrame = ("StackGetFrame", False, False, False)
170
+ StackGetFramePointer = ("StackGetFramePointer", False, False, False)
171
+ StackGetPointer = ("StackGetPointer", False, False, False)
172
+ StackGrow = ("StackGrow", True, False, False)
173
+ StackInit = ("StackInit", True, False, False)
174
+ StackLeave = ("StackLeave", True, False, False)
175
+ StackPop = ("StackPop", True, False, False)
176
+ StackPush = ("StackPush", True, False, False)
177
+ StackSet = ("StackSet", True, False, False)
178
+ StackSetFrame = ("StackSetFrame", True, False, False)
179
+ StackSetFramePointer = ("StackSetFramePointer", True, False, False)
180
+ StackSetPointer = ("StackSetPointer", True, False, False)
181
+ StopLooped = ("StopLooped", True, False, False)
182
+ StopLoopedScheduled = ("StopLoopedScheduled", True, False, False)
183
+ Subtract = ("Subtract", False, True, False)
184
+ Switch = ("Switch", False, True, True)
185
+ SwitchInteger = ("SwitchInteger", False, True, True)
186
+ SwitchIntegerWithDefault = ("SwitchIntegerWithDefault", False, True, True)
187
+ SwitchWithDefault = ("SwitchWithDefault", False, True, True)
188
+ Tan = ("Tan", False, True, False)
189
+ Tanh = ("Tanh", False, True, False)
190
+ TimeToScaledTime = ("TimeToScaledTime", False, True, False)
191
+ TimeToStartingScaledTime = ("TimeToStartingScaledTime", False, True, False)
192
+ TimeToStartingTime = ("TimeToStartingTime", False, True, False)
193
+ TimeToTimeScale = ("TimeToTimeScale", False, True, False)
194
+ Trunc = ("Trunc", False, True, False)
195
+ Unlerp = ("Unlerp", False, True, False)
196
+ UnlerpClamped = ("UnlerpClamped", False, True, False)
197
+ While = ("While", False, True, True)
@@ -0,0 +1,9 @@
1
+ from sonolus.backend.allocate import AllocateBasic
2
+ from sonolus.backend.flow import BasicBlock
3
+ from sonolus.backend.simplify import CoalesceFlow
4
+
5
+
6
+ def optimize_and_allocate(cfg: BasicBlock):
7
+ cfg = CoalesceFlow().run(cfg)
8
+ cfg = AllocateBasic().run(cfg)
9
+ return cfg
@@ -0,0 +1,6 @@
1
+ from sonolus.backend.flow import BasicBlock
2
+
3
+
4
+ class CompilerPass:
5
+ def run(self, entry: BasicBlock) -> BasicBlock:
6
+ pass
@@ -0,0 +1,90 @@
1
+ from collections.abc import Iterator
2
+ from typing import Self
3
+
4
+ from sonolus.backend.blocks import Block
5
+
6
+ type Place = BlockPlace | SSAPlace
7
+ type BlockValue = Block | int | TempBlock | Place
8
+ type IndexValue = int | Place
9
+
10
+
11
+ class TempBlock:
12
+ name: str
13
+ size: int
14
+
15
+ def __init__(self, name: str, size: int = 1):
16
+ self.name = name
17
+ self.size = size
18
+
19
+ def __repr__(self):
20
+ return f"TempBlock(name={self.name!r}, size={self.size!r})"
21
+
22
+ def __str__(self):
23
+ return f"{self.name}"
24
+
25
+ def __getitem__(self, item) -> "BlockPlace":
26
+ return BlockPlace(self, item)
27
+
28
+ def __iter__(self) -> "Iterator[BlockPlace]":
29
+ for i in range(self.size):
30
+ yield self[i]
31
+
32
+ def __eq__(self, other):
33
+ return isinstance(other, TempBlock) and self.name == other.name and self.size == other.size
34
+
35
+ def __hash__(self):
36
+ return hash((self.name, self.size))
37
+
38
+
39
+ class BlockPlace:
40
+ block: BlockValue
41
+ index: IndexValue
42
+ offset: int = 0
43
+
44
+ def __init__(self, block: BlockValue, index: IndexValue = 0, offset: int = 0):
45
+ self.block = block
46
+ self.index = index
47
+ self.offset = offset
48
+
49
+ def __repr__(self):
50
+ return f"BlockPlace(block={self.block!r}, index={self.index!r}, offset={self.offset!r})"
51
+
52
+ def __str__(self):
53
+ if isinstance(self.block, TempBlock) and self.block.size == 1 and self.index == 0 and self.offset == 0:
54
+ return f"{self.block}"
55
+ elif isinstance(self.index, int):
56
+ return f"{self.block}[{self.index + self.offset}]"
57
+ elif self.offset == 0:
58
+ return f"{self.block}[{self.index}]"
59
+ else:
60
+ return f"{self.block}[{self.index} + {self.offset}]"
61
+
62
+ def __eq__(self, other):
63
+ return isinstance(other, BlockPlace) and self.block == other.block and self.index == other.index
64
+
65
+ def __hash__(self):
66
+ return hash((self.block, self.index))
67
+
68
+ def add_offset(self, offset: int) -> Self:
69
+ return BlockPlace(self.block, self.index, self.offset + offset)
70
+
71
+
72
+ class SSAPlace:
73
+ name: str
74
+ num: int
75
+
76
+ def __init__(self, name: str, num: int):
77
+ self.name = name
78
+ self.num = num
79
+
80
+ def __repr__(self):
81
+ return f"SSAPlace(name={self.name!r}, num={self.num!r})"
82
+
83
+ def __str__(self):
84
+ return f"{self.name}.{self.num}"
85
+
86
+ def __eq__(self, other):
87
+ return isinstance(other, SSAPlace) and self.name == other.name and self.num == other.num
88
+
89
+ def __hash__(self):
90
+ return hash((self.name, self.num))
@@ -0,0 +1,30 @@
1
+ from sonolus.backend.flow import BasicBlock
2
+ from sonolus.backend.passes import CompilerPass
3
+
4
+
5
+ class CoalesceFlow(CompilerPass):
6
+ def run(self, entry: BasicBlock) -> BasicBlock:
7
+ queue = [entry]
8
+ processed = set()
9
+ while queue:
10
+ block = queue.pop()
11
+ if block in processed:
12
+ continue
13
+ processed.add(block)
14
+ if len(block.outgoing) != 1:
15
+ queue.extend(edge.dst for edge in block.outgoing)
16
+ continue
17
+ next_block = next(iter(block.outgoing)).dst
18
+ if len(next_block.incoming) != 1:
19
+ queue.append(next_block)
20
+ continue
21
+ block.statements.extend(next_block.statements)
22
+ block.test = next_block.test
23
+ for edge in next_block.outgoing:
24
+ edge.src = block
25
+ block.outgoing = next_block.outgoing
26
+ processed.add(next_block)
27
+ queue.extend(edge.dst for edge in block.outgoing)
28
+ processed.remove(block)
29
+ queue.append(block)
30
+ return entry
@@ -0,0 +1,48 @@
1
+ # ruff: noqa: N802
2
+ import ast
3
+ import inspect
4
+ from collections.abc import Callable
5
+ from pathlib import Path
6
+
7
+
8
+ def get_function(fn: Callable) -> tuple[str, ast.FunctionDef]:
9
+ # This preserves both line number and column number in the returned node
10
+ source_file = inspect.getsourcefile(fn)
11
+ _, start_line = inspect.getsourcelines(fn)
12
+ base_tree = ast.parse(Path(source_file).read_text(encoding="utf-8"))
13
+ return source_file, find_function(base_tree, start_line)
14
+
15
+
16
+ class FindFunction(ast.NodeVisitor):
17
+ def __init__(self, line):
18
+ self.line = line
19
+ self.node: ast.FunctionDef | None = None
20
+
21
+ def visit_FunctionDef(self, node: ast.FunctionDef):
22
+ if node.lineno == self.line or (
23
+ node.decorator_list and (node.decorator_list[-1].end_lineno <= self.line <= node.lineno)
24
+ ):
25
+ self.node = node
26
+ else:
27
+ self.generic_visit(node)
28
+
29
+
30
+ def find_function(tree: ast.Module, line: int):
31
+ visitor = FindFunction(line)
32
+ visitor.visit(tree)
33
+ return visitor.node
34
+
35
+
36
+ class ScanWrites(ast.NodeVisitor):
37
+ def __init__(self):
38
+ self.writes = []
39
+
40
+ def visit_Name(self, node):
41
+ if isinstance(node.ctx, ast.Store | ast.Delete):
42
+ self.writes.append(node.id)
43
+
44
+
45
+ def scan_writes(node: ast.AST) -> set[str]:
46
+ visitor = ScanWrites()
47
+ visitor.visit(node)
48
+ return set(visitor.writes)