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
@@ -0,0 +1,234 @@
1
+ import inspect
2
+ from typing import dataclass_transform
3
+
4
+ from sonolus.backend.blocks import Block, PlayBlock, PreviewBlock, TutorialBlock, WatchBlock
5
+ from sonolus.backend.mode import Mode
6
+ from sonolus.script.internal.descriptor import SonolusDescriptor
7
+ from sonolus.script.internal.generic import validate_concrete_type
8
+ from sonolus.script.internal.value import Value
9
+
10
+
11
+ class GlobalInfo:
12
+ def __init__(self, name: str, size: int, blocks: dict[Mode, Block], offset: int | None):
13
+ self.name = name
14
+ self.size = size
15
+ self.blocks = blocks
16
+ self.offset = offset
17
+
18
+
19
+ class GlobalField(SonolusDescriptor):
20
+ def __init__(self, name: str, type_: type[Value], index: int, offset: int):
21
+ self.name = name
22
+ self.type = type_
23
+ self.index = index
24
+ self.offset = offset
25
+
26
+ def __get__(self, instance, owner):
27
+ if instance is None:
28
+ return self
29
+
30
+ from sonolus.script.internal.context import ctx
31
+
32
+ info = owner._global_info_
33
+ if not ctx():
34
+ raise RuntimeError("Global field access outside of compilation")
35
+ base = ctx().get_global_base(info)
36
+ return self.type._from_place_(base.add_offset(self.offset))._get_()
37
+
38
+ def __set__(self, instance, value):
39
+ from sonolus.script.internal.context import ctx
40
+
41
+ info = instance._global_info_
42
+ if not ctx():
43
+ raise RuntimeError("Global field access outside of compilation")
44
+ base = ctx().get_global_base(info)
45
+ target = self.type._from_place_(base.add_offset(self.offset))
46
+ if self.type._is_value_type_():
47
+ target._set_(value)
48
+ else:
49
+ target._copy_from_(value)
50
+
51
+
52
+ class GlobalPlaceholder:
53
+ def __init__(self, type_: type[Value], blocks: dict[Mode, Block], offset: int | None):
54
+ self.type = type_
55
+ self.blocks = blocks
56
+ self.offset = offset
57
+ self.size = type_._size_()
58
+
59
+ def get(self):
60
+ from sonolus.script.internal.context import ctx
61
+
62
+ if not ctx():
63
+ raise RuntimeError("Global access outside of compilation")
64
+ base = ctx().get_global_base(self)
65
+ return self.type._from_place_(base)
66
+
67
+
68
+ def create_global(cls: type, blocks: dict[Mode, Block], offset: int | None):
69
+ if issubclass(cls, Value):
70
+ cls = validate_concrete_type(cls)
71
+ return GlobalPlaceholder(cls, blocks, offset)
72
+ if len(cls.__bases__) != 1:
73
+ raise TypeError("Expected a class with no bases or a Value subclass")
74
+ field_offset = 0
75
+ for i, (
76
+ name,
77
+ annotation,
78
+ ) in enumerate(inspect.get_annotations(cls, eval_str=True).items()):
79
+ type_ = validate_concrete_type(annotation)
80
+ setattr(cls, name, GlobalField(name, type_, i, field_offset))
81
+ field_offset += type_._size_()
82
+ cls._global_info_ = GlobalInfo(cls.__name__, field_offset, blocks, offset)
83
+ cls._is_comptime_value_ = True
84
+ return cls()
85
+
86
+
87
+ @dataclass_transform()
88
+ def _play_runtime_environment[T](cls: type[T]) -> T:
89
+ return create_global(cls, {Mode.Play: PlayBlock.RuntimeEnvironment}, 0)
90
+
91
+
92
+ @dataclass_transform()
93
+ def _watch_runtime_environment[T](cls: type[T]) -> T:
94
+ return create_global(cls, {Mode.Watch: WatchBlock.RuntimeEnvironment}, 0)
95
+
96
+
97
+ @dataclass_transform()
98
+ def _tutorial_runtime_environment[T](cls: type[T]) -> T:
99
+ return create_global(cls, {Mode.Tutorial: TutorialBlock.RuntimeEnvironment}, 0)
100
+
101
+
102
+ @dataclass_transform()
103
+ def _preview_runtime_environment[T](cls: type[T]) -> T:
104
+ return create_global(cls, {Mode.Preview: PreviewBlock.RuntimeEnvironment}, 0)
105
+
106
+
107
+ @dataclass_transform()
108
+ def _play_runtime_update[T](cls: type[T]) -> T:
109
+ return create_global(cls, {Mode.Play: PlayBlock.RuntimeUpdate}, 0)
110
+
111
+
112
+ @dataclass_transform()
113
+ def _watch_runtime_update[T](cls: type[T]) -> T:
114
+ return create_global(cls, {Mode.Watch: WatchBlock.RuntimeUpdate}, 0)
115
+
116
+
117
+ @dataclass_transform()
118
+ def _tutorial_runtime_update[T](cls: type[T]) -> T:
119
+ return create_global(cls, {Mode.Tutorial: TutorialBlock.RuntimeUpdate}, 0)
120
+
121
+
122
+ @dataclass_transform()
123
+ def _runtime_touch_array[T](cls: type[T]) -> T:
124
+ return create_global(cls, {Mode.Play: PlayBlock.RuntimeTouchArray}, 0)
125
+
126
+
127
+ @dataclass_transform()
128
+ def _runtime_skin_transform[T](cls: type[T]) -> T:
129
+ return create_global(
130
+ cls,
131
+ {
132
+ Mode.Play: PlayBlock.RuntimeSkinTransform,
133
+ Mode.Watch: WatchBlock.RuntimeSkinTransform,
134
+ Mode.Tutorial: TutorialBlock.RuntimeSkinTransform,
135
+ },
136
+ 0,
137
+ )
138
+
139
+
140
+ @dataclass_transform()
141
+ def _runtime_particle_transform[T](cls: type[T]) -> T:
142
+ return create_global(
143
+ cls,
144
+ {
145
+ Mode.Play: PlayBlock.RuntimeParticleTransform,
146
+ Mode.Watch: WatchBlock.RuntimeParticleTransform,
147
+ Mode.Tutorial: TutorialBlock.RuntimeParticleTransform,
148
+ },
149
+ 0,
150
+ )
151
+
152
+
153
+ @dataclass_transform()
154
+ def _runtime_background[T](cls: type[T]) -> T:
155
+ return create_global(
156
+ cls,
157
+ {
158
+ Mode.Play: PlayBlock.RuntimeBackground,
159
+ Mode.Watch: WatchBlock.RuntimeBackground,
160
+ Mode.Tutorial: TutorialBlock.RuntimeBackground,
161
+ },
162
+ 0,
163
+ )
164
+
165
+
166
+ @dataclass_transform()
167
+ def _runtime_ui[T](cls: type[T]) -> T:
168
+ return create_global(
169
+ cls,
170
+ {
171
+ Mode.Play: PlayBlock.RuntimeUI,
172
+ Mode.Watch: WatchBlock.RuntimeUI,
173
+ Mode.Tutorial: TutorialBlock.RuntimeUI,
174
+ Mode.Preview: PreviewBlock.RuntimeUI,
175
+ },
176
+ 0,
177
+ )
178
+
179
+
180
+ @dataclass_transform()
181
+ def _runtime_ui_configuration[T](cls: type[T]) -> T:
182
+ return create_global(
183
+ cls,
184
+ {
185
+ Mode.Play: PlayBlock.RuntimeUIConfiguration,
186
+ Mode.Watch: WatchBlock.RuntimeUIConfiguration,
187
+ Mode.Tutorial: TutorialBlock.RuntimeUIConfiguration,
188
+ Mode.Preview: PreviewBlock.RuntimeUIConfiguration,
189
+ },
190
+ 0,
191
+ )
192
+
193
+
194
+ @dataclass_transform()
195
+ def _tutorial_instruction[T](cls: type[T]) -> T:
196
+ return create_global(cls, {Mode.Tutorial: TutorialBlock.TutorialInstruction}, 0)
197
+
198
+
199
+ @dataclass_transform()
200
+ def level_memory[T](cls: type[T]) -> T:
201
+ return create_global(cls, {Mode.Play: PlayBlock.LevelMemory, Mode.Watch: WatchBlock.LevelMemory}, None)
202
+
203
+
204
+ @dataclass_transform()
205
+ def level_data[T](cls: type[T]) -> T:
206
+ return create_global(cls, {Mode.Play: PlayBlock.LevelData, Mode.Watch: WatchBlock.LevelData}, None)
207
+
208
+
209
+ # level_option is handled by the options decorator
210
+ # level_bucket is handled by the bucket decorator
211
+
212
+
213
+ @dataclass_transform()
214
+ def _level_score[T](cls: type[T]) -> T:
215
+ return create_global(cls, {Mode.Play: PlayBlock.LevelScore, Mode.Watch: WatchBlock.LevelScore}, 0)
216
+
217
+
218
+ @dataclass_transform()
219
+ def _level_life[T](cls: type[T]) -> T:
220
+ return create_global(cls, {Mode.Play: PlayBlock.LevelLife, Mode.Watch: WatchBlock.LevelLife}, 0)
221
+
222
+
223
+ # engine_rom is handled by the compiler
224
+ # entity memory is handled by the archetype
225
+ # entity data is handled by the archetype
226
+ # entity shared memory is handled by the archetype
227
+ # entity info is handled by the archetype
228
+ # entity despawn is handled by the archetype
229
+ # entity input is handled by the archetype
230
+ # entity data array is handled by the archetype
231
+ # entity shared memory array is handled by the archetype
232
+ # entity info array is handled by the archetype
233
+ # archetype life is handled by the archetype
234
+ # temporary memory is handled by the compiler
@@ -0,0 +1,141 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Protocol
4
+
5
+ from sonolus.script.record import Record
6
+ from sonolus.script.vec import Vec2
7
+
8
+
9
+ class Quad(Record):
10
+ bl: Vec2
11
+ tl: Vec2
12
+ tr: Vec2
13
+ br: Vec2
14
+
15
+
16
+ class Rect(Record):
17
+ t: float
18
+ r: float
19
+ b: float
20
+ l: float # noqa: E741
21
+
22
+ @classmethod
23
+ def from_xywh(cls, x: float, y: float, w: float, h: float) -> Rect:
24
+ return cls(
25
+ t=y + h,
26
+ r=x + w,
27
+ b=y,
28
+ l=x,
29
+ )
30
+
31
+ @classmethod
32
+ def from_center(cls, x: float, y: float, w: float, h: float) -> Rect:
33
+ return cls(
34
+ t=y + h / 2,
35
+ r=x + w / 2,
36
+ b=y - h / 2,
37
+ l=x - w / 2,
38
+ )
39
+
40
+ @property
41
+ def x(self) -> float:
42
+ return self.l
43
+
44
+ @x.setter
45
+ def x(self, value: float):
46
+ self.r += value - self.l
47
+ self.l = value
48
+
49
+ @property
50
+ def y(self) -> float:
51
+ return self.t
52
+
53
+ @y.setter
54
+ def y(self, value: float):
55
+ self.b += value - self.t
56
+ self.t = value
57
+
58
+ @property
59
+ def w(self) -> float:
60
+ return self.r - self.l
61
+
62
+ @w.setter
63
+ def w(self, value: float):
64
+ self.r = self.l + value
65
+
66
+ @property
67
+ def h(self) -> float:
68
+ return self.t - self.b
69
+
70
+ @h.setter
71
+ def h(self, value: float):
72
+ self.t = self.b + value
73
+
74
+ @property
75
+ def bl(self) -> Vec2:
76
+ return Vec2(self.l, self.b)
77
+
78
+ @property
79
+ def tl(self) -> Vec2:
80
+ return Vec2(self.l, self.t)
81
+
82
+ @property
83
+ def tr(self) -> Vec2:
84
+ return Vec2(self.r, self.t)
85
+
86
+ @property
87
+ def br(self) -> Vec2:
88
+ return Vec2(self.r, self.b)
89
+
90
+ @property
91
+ def center(self) -> Vec2:
92
+ return Vec2((self.l + self.r) / 2, (self.t + self.b) / 2)
93
+
94
+ def as_quad(self) -> Quad:
95
+ return Quad(
96
+ bl=self.bl,
97
+ tl=self.tl,
98
+ tr=self.tr,
99
+ br=self.br,
100
+ )
101
+
102
+ def scale(self, x: float, y: float | None, /):
103
+ if y is None:
104
+ y = x
105
+ self.l *= x
106
+ self.r *= x
107
+ self.t *= y
108
+ self.b *= y
109
+
110
+ def translate(self, x: float, y: float, /):
111
+ self.l += x
112
+ self.r += x
113
+ self.t += y
114
+ self.b += y
115
+
116
+
117
+ class QuadLike(Protocol):
118
+ @property
119
+ def bl(self) -> Vec2: ...
120
+
121
+ @property
122
+ def tl(self) -> Vec2: ...
123
+
124
+ @property
125
+ def tr(self) -> Vec2: ...
126
+
127
+ @property
128
+ def br(self) -> Vec2: ...
129
+
130
+
131
+ def flatten_quad(quad: QuadLike) -> tuple[float, float, float, float, float, float, float, float]:
132
+ return (
133
+ quad.bl.x,
134
+ quad.bl.y,
135
+ quad.tl.x,
136
+ quad.tl.y,
137
+ quad.tr.x,
138
+ quad.tr.y,
139
+ quad.br.x,
140
+ quad.br.y,
141
+ )
sonolus/script/icon.py ADDED
@@ -0,0 +1,73 @@
1
+ from enum import StrEnum
2
+
3
+
4
+ class StandardIcon(StrEnum):
5
+ ADVANCED = "advanced"
6
+ ANGLE_DOWN = "angleDown"
7
+ ANGLE_LEFT = "angleLeft"
8
+ ANGLE_RIGHT = "angleRight"
9
+ ANGLES_DOWN = "anglesDown"
10
+ ANGLES_LEFT = "anglesLeft"
11
+ ANGLES_RIGHT = "anglesRight"
12
+ ANGLES_UP = "anglesUp"
13
+ ANGLE_UP = "angleUp"
14
+ ARROW_DOWN = "arrowDown"
15
+ ARROW_LEFT = "arrowLeft"
16
+ ARROW_RIGHT = "arrowRight"
17
+ ARROW_UP = "arrowUp"
18
+ AWARD = "award"
19
+ BACKGROUND = "background"
20
+ BELL = "bell"
21
+ BELL_SLASH = "bellSlash"
22
+ BOOKMARK = "bookmark"
23
+ BOOKMARK_HOLLOW = "bookmarkHollow"
24
+ CHECK = "check"
25
+ CLOCK = "clock"
26
+ COMMENT = "comment"
27
+ CROWN = "crown"
28
+ DELETE = "delete"
29
+ EDIT = "edit"
30
+ EFFECT = "effect"
31
+ ENGINE = "engine"
32
+ ENVELOPE = "envelope"
33
+ ENVELOPE_OPEN = "envelopeOpen"
34
+ GLOBE = "globe"
35
+ HEART = "heart"
36
+ HEART_HOLLOW = "heartHollow"
37
+ HIDE = "hide"
38
+ INFORMATION = "information"
39
+ LEVEL = "level"
40
+ LOCK = "lock"
41
+ MEDAL = "medal"
42
+ MESSAGE = "message"
43
+ MINUS = "minus"
44
+ OPTIONS = "options"
45
+ PARTICLE = "particle"
46
+ PIN = "pin"
47
+ PLAYER = "player"
48
+ PLAYLIST = "playlist"
49
+ PLUS = "plus"
50
+ POST = "post"
51
+ QUESTION = "question"
52
+ RANKING = "ranking"
53
+ REPLAY = "replay"
54
+ REPLY = "reply"
55
+ RESTORE = "restore"
56
+ ROOM = "room"
57
+ SEARCH = "search"
58
+ SETTINGS = "settings"
59
+ SHOW = "show"
60
+ SHUFFLE = "shuffle"
61
+ SKIN = "skin"
62
+ STAR = "star"
63
+ STAR_HALF = "starHalf"
64
+ STAR_HOLLOW = "starHollow"
65
+ STOPWATCH = "stopwatch"
66
+ TAG = "tag"
67
+ THUMBS_DOWN = "thumbsDown"
68
+ THUMBS_DOWN_HOLLOW = "thumbsDownHollow"
69
+ THUMBS_UP = "thumbsUp"
70
+ THUMBS_UP_HOLLOW = "thumbsUpHollow"
71
+ TROPHY = "trophy"
72
+ UNLOCK = "unlock"
73
+ X_MARK = "xMark"
@@ -0,0 +1,5 @@
1
+ """Internal scripting details.
2
+
3
+ These are internal details of scripting which typically should not be used directly
4
+ in engine code.
5
+ """
@@ -0,0 +1,144 @@
1
+ from collections.abc import Iterable
2
+ from typing import overload
3
+
4
+ from sonolus.script.internal.context import ctx
5
+ from sonolus.script.internal.impl import meta_fn, validate_value
6
+ from sonolus.script.iterator import ArrayLike, Enumerator, SonolusIterator
7
+ from sonolus.script.math import MATH_BUILTIN_IMPLS
8
+ from sonolus.script.num import Num
9
+ from sonolus.script.range import Range
10
+
11
+
12
+ @meta_fn
13
+ def _isinstance(value, type_):
14
+ value = validate_value(value)
15
+ type_ = validate_value(type_)._as_py_()
16
+ return validate_value(isinstance(value, type_))
17
+
18
+
19
+ @meta_fn
20
+ def _len(value):
21
+ from sonolus.backend.visitor import compile_and_call
22
+
23
+ value = validate_value(value)
24
+ if not hasattr(value, "__len__"):
25
+ raise TypeError(f"object of type '{type(value).__name__}' has no len()")
26
+ return compile_and_call(value.__len__)
27
+
28
+
29
+ @meta_fn
30
+ def _enumerate(iterable, start=0):
31
+ from sonolus.backend.visitor import compile_and_call
32
+
33
+ iterable = validate_value(iterable)
34
+ if not hasattr(iterable, "__iter__"):
35
+ raise TypeError(f"'{type(iterable).__name__}' object is not iterable")
36
+ if isinstance(iterable, ArrayLike):
37
+ return compile_and_call(iterable.enumerate, start)
38
+ else:
39
+ iterator = compile_and_call(iterable.__iter__)
40
+ if not isinstance(iterator, SonolusIterator):
41
+ raise TypeError("Only subclasses of SonolusIterator are supported as iterators")
42
+ return Enumerator(0, start, iterator)
43
+
44
+
45
+ @meta_fn
46
+ def _abs(value):
47
+ from sonolus.backend.visitor import compile_and_call
48
+
49
+ value = validate_value(value)
50
+ if not hasattr(value, "__abs__"):
51
+ raise TypeError(f"bad operand type for abs(): '{type(value).__name__}'")
52
+ return compile_and_call(value.__abs__)
53
+
54
+
55
+ @overload
56
+ def _max[T](iterable: Iterable[T]) -> T: ...
57
+
58
+
59
+ @overload
60
+ def _max[T](a: T, b: T, *args: T) -> T: ...
61
+
62
+
63
+ @meta_fn
64
+ def _max(*args):
65
+ from sonolus.backend.visitor import compile_and_call
66
+
67
+ args = tuple(validate_value(arg) for arg in args)
68
+ if len(args) == 0:
69
+ raise ValueError("Expected at least one argument to max")
70
+ elif len(args) == 1:
71
+ (iterable,) = args
72
+ if isinstance(iterable, ArrayLike):
73
+ return iterable.max()
74
+ else:
75
+ raise TypeError(f"Unsupported type: {type(iterable)} for max")
76
+ else:
77
+ if not all(isinstance(arg, Num) for arg in args):
78
+ raise TypeError("Arguments to max must be numbers")
79
+ if ctx():
80
+ result = compile_and_call(_max2, args[0], args[1])
81
+ for arg in args[2:]:
82
+ result = compile_and_call(_max2, result, arg)
83
+ return result
84
+ else:
85
+ return max(arg._as_py_() for arg in args)
86
+
87
+
88
+ def _max2(a, b):
89
+ if a > b:
90
+ return a
91
+ else:
92
+ return b
93
+
94
+
95
+ @overload
96
+ def _min[T](iterable: Iterable[T]) -> T: ...
97
+
98
+
99
+ @overload
100
+ def _min[T](a: T, b: T, *args: T) -> T: ...
101
+
102
+
103
+ @meta_fn
104
+ def _min(*args):
105
+ from sonolus.backend.visitor import compile_and_call
106
+
107
+ args = tuple(validate_value(arg) for arg in args)
108
+ if len(args) == 0:
109
+ raise ValueError("Expected at least one argument to min")
110
+ elif len(args) == 1:
111
+ (iterable,) = args
112
+ if isinstance(iterable, ArrayLike):
113
+ return iterable.min()
114
+ else:
115
+ raise TypeError(f"Unsupported type: {type(iterable)} for min")
116
+ else:
117
+ if not all(isinstance(arg, Num) for arg in args):
118
+ raise TypeError("Arguments to min must be numbers")
119
+ if ctx():
120
+ result = compile_and_call(_min2, args[0], args[1])
121
+ for arg in args[2:]:
122
+ result = compile_and_call(_min2, result, arg)
123
+ return result
124
+ else:
125
+ return min(arg._as_py_() for arg in args)
126
+
127
+
128
+ def _min2(a, b):
129
+ if a < b:
130
+ return a
131
+ else:
132
+ return b
133
+
134
+
135
+ BUILTIN_IMPLS = {
136
+ id(isinstance): _isinstance,
137
+ id(len): _len,
138
+ id(enumerate): _enumerate,
139
+ id(abs): _abs,
140
+ id(max): _max,
141
+ id(min): _min,
142
+ id(range): Range,
143
+ **MATH_BUILTIN_IMPLS,
144
+ }