mt-lang 0.2.0 → 0.2.1

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.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/docs/index.html +4 -3
  3. data/lib/milk_tea/base.rb +1 -1
  4. data/std/asset_pack.mt +267 -0
  5. data/std/async/libuv_runtime.mt +539 -0
  6. data/std/async/mailbox.mt +191 -0
  7. data/std/async/runtime.mt +87 -0
  8. data/std/async.mt +87 -0
  9. data/std/base64.mt +185 -0
  10. data/std/behavior_tree.mt +396 -0
  11. data/std/binary.mt +314 -0
  12. data/std/binary_heap.mt +157 -0
  13. data/std/bitset.mt +239 -0
  14. data/std/box2d.mt +535 -0
  15. data/std/bytes.mt +46 -0
  16. data/std/c/box2d.mt +1254 -0
  17. data/std/c/cgltf.mt +647 -0
  18. data/std/c/cjson.mt +106 -0
  19. data/std/c/crypto.mt +11 -0
  20. data/std/c/crypto_support.h +51 -0
  21. data/std/c/ctype.mt +19 -0
  22. data/std/c/ctype_bindgen.h +29 -0
  23. data/std/c/curl.mt +1223 -0
  24. data/std/c/enet.mt +473 -0
  25. data/std/c/errno.mt +41 -0
  26. data/std/c/errno_bindgen.h +53 -0
  27. data/std/c/flecs.mt +2945 -0
  28. data/std/c/fs.linux.mt +43 -0
  29. data/std/c/fs.windows.mt +43 -0
  30. data/std/c/fs_support.h +954 -0
  31. data/std/c/gl.mt +2065 -0
  32. data/std/c/gl_registry_helpers.h +10748 -0
  33. data/std/c/glfw.mt +499 -0
  34. data/std/c/libc.mt +167 -0
  35. data/std/c/libuv.mt +1491 -0
  36. data/std/c/math.mt +22 -0
  37. data/std/c/math_bindgen.h +31 -0
  38. data/std/c/miniaudio.mt +3420 -0
  39. data/std/c/pcre2.mt +735 -0
  40. data/std/c/process.mt +58 -0
  41. data/std/c/process_support.h +1147 -0
  42. data/std/c/raygui.mt +1602 -0
  43. data/std/c/raylib.mt +1245 -0
  44. data/std/c/raymath.mt +163 -0
  45. data/std/c/rlgl.mt +434 -0
  46. data/std/c/rpng.mt +60 -0
  47. data/std/c/rres.mt +187 -0
  48. data/std/c/sdl3.mt +4132 -0
  49. data/std/c/sqlite3.mt +951 -0
  50. data/std/c/stb_image.mt +52 -0
  51. data/std/c/stb_image_resize2.mt +128 -0
  52. data/std/c/stb_image_write.mt +19 -0
  53. data/std/c/stb_rect_pack.mt +38 -0
  54. data/std/c/stb_truetype.mt +175 -0
  55. data/std/c/stb_vorbis.mt +31 -0
  56. data/std/c/stdio.mt +90 -0
  57. data/std/c/steamworks.h +5769 -0
  58. data/std/c/steamworks.mt +4771 -0
  59. data/std/c/string.mt +16 -0
  60. data/std/c/string_bindgen.h +36 -0
  61. data/std/c/sync.mt +33 -0
  62. data/std/c/sync_support.h +219 -0
  63. data/std/c/terminal.mt +24 -0
  64. data/std/c/terminal_support.h +408 -0
  65. data/std/c/time.mt +26 -0
  66. data/std/c/tls.mt +24 -0
  67. data/std/c/tls_support.h +626 -0
  68. data/std/c/tracy.mt +53 -0
  69. data/std/c/zlib.mt +20 -0
  70. data/std/c/zlib_support.h +239 -0
  71. data/std/c/zstd.mt +231 -0
  72. data/std/cell.mt +60 -0
  73. data/std/cgltf.mt +115 -0
  74. data/std/cjson.mt +90 -0
  75. data/std/cli.mt +768 -0
  76. data/std/cookie.mt +198 -0
  77. data/std/counter.mt +160 -0
  78. data/std/crypto.mt +74 -0
  79. data/std/cstring.mt +13 -0
  80. data/std/ctype.mt +52 -0
  81. data/std/curl/runtime.mt +261 -0
  82. data/std/curl.mt +38 -0
  83. data/std/deque.mt +348 -0
  84. data/std/encoding.mt +93 -0
  85. data/std/enet.mt +133 -0
  86. data/std/env.mt +41 -0
  87. data/std/errno.mt +47 -0
  88. data/std/flecs.mt +978 -0
  89. data/std/fmt.mt +271 -0
  90. data/std/fs.linux.mt +696 -0
  91. data/std/fs.windows.mt +711 -0
  92. data/std/fsm.mt +267 -0
  93. data/std/gl.mt +2062 -0
  94. data/std/glfw.mt +471 -0
  95. data/std/goap.mt +342 -0
  96. data/std/graph.mt +521 -0
  97. data/std/gzip.mt +77 -0
  98. data/std/hash.mt +429 -0
  99. data/std/http/server.mt +810 -0
  100. data/std/http.mt +1227 -0
  101. data/std/intern.mt +53 -0
  102. data/std/jobs.mt +288 -0
  103. data/std/json.mt +627 -0
  104. data/std/libc.mt +34 -0
  105. data/std/libuv.mt +554 -0
  106. data/std/linear_algebra.mt +243 -0
  107. data/std/linked_map.mt +372 -0
  108. data/std/linked_map_view.mt +49 -0
  109. data/std/linked_set.mt +117 -0
  110. data/std/log.mt +69 -0
  111. data/std/map.mt +418 -0
  112. data/std/math.mt +24 -0
  113. data/std/mem/arena.mt +137 -0
  114. data/std/mem/endian.mt +51 -0
  115. data/std/mem/heap.mt +298 -0
  116. data/std/mem/pool.mt +164 -0
  117. data/std/mem/stack.mt +47 -0
  118. data/std/mem/tracking.mt +119 -0
  119. data/std/miniaudio.mt +1299 -0
  120. data/std/multiset.mt +191 -0
  121. data/std/net/channel.mt +727 -0
  122. data/std/net/clock.mt +237 -0
  123. data/std/net/discovery.mt +277 -0
  124. data/std/net/lobby.mt +813 -0
  125. data/std/net/manager.mt +539 -0
  126. data/std/net/mux.mt +839 -0
  127. data/std/net/nat.mt +122 -0
  128. data/std/net/packet.mt +219 -0
  129. data/std/net/punch.mt +162 -0
  130. data/std/net/rpc.mt +119 -0
  131. data/std/net/session.mt +1157 -0
  132. data/std/net/stun.mt +252 -0
  133. data/std/net/sync.mt +183 -0
  134. data/std/net/turn.mt +459 -0
  135. data/std/net.mt +2944 -0
  136. data/std/oauth2.mt +408 -0
  137. data/std/option.mt +51 -0
  138. data/std/ordered_map.mt +497 -0
  139. data/std/ordered_set.mt +348 -0
  140. data/std/path.mt +368 -0
  141. data/std/pcre2/runtime.mt +35 -0
  142. data/std/pcre2.mt +78 -0
  143. data/std/priority_queue.mt +55 -0
  144. data/std/process.mt +837 -0
  145. data/std/queue.mt +55 -0
  146. data/std/random.mt +146 -0
  147. data/std/raygui.mt +99 -0
  148. data/std/raylib/debug_console.mt +71 -0
  149. data/std/raylib/easing.mt +388 -0
  150. data/std/raylib/packed_assets.mt +255 -0
  151. data/std/raylib/runtime.mt +30 -0
  152. data/std/raylib/tracy_gpu.mt +37 -0
  153. data/std/raylib.mt +1510 -0
  154. data/std/raymath.mt +153 -0
  155. data/std/result.mt +89 -0
  156. data/std/rlgl.mt +268 -0
  157. data/std/rpng.mt +46 -0
  158. data/std/rres.mt +36 -0
  159. data/std/sdl3/runtime.mt +54 -0
  160. data/std/sdl3.mt +1731 -0
  161. data/std/serialize.mt +68 -0
  162. data/std/set.mt +124 -0
  163. data/std/spatial.mt +176 -0
  164. data/std/sqlite3.mt +151 -0
  165. data/std/stack.mt +55 -0
  166. data/std/stb_image.mt +47 -0
  167. data/std/stb_image_resize2.mt +41 -0
  168. data/std/stb_image_write.mt +17 -0
  169. data/std/stb_rect_pack.mt +15 -0
  170. data/std/stb_truetype.mt +77 -0
  171. data/std/stb_vorbis.mt +16 -0
  172. data/std/stdio.mt +88 -0
  173. data/std/steamworks.mt +1542 -0
  174. data/std/str.mt +293 -0
  175. data/std/string.mt +234 -0
  176. data/std/sync.mt +194 -0
  177. data/std/tar.mt +704 -0
  178. data/std/terminal.mt +1002 -0
  179. data/std/testing.mt +266 -0
  180. data/std/thread.mt +120 -0
  181. data/std/time.mt +105 -0
  182. data/std/tls.mt +616 -0
  183. data/std/toml.mt +1310 -0
  184. data/std/tracy.mt +42 -0
  185. data/std/uri.mt +118 -0
  186. data/std/url.mt +372 -0
  187. data/std/vec.mt +433 -0
  188. data/std/zstd.mt +94 -0
  189. metadata +187 -2
@@ -0,0 +1,396 @@
1
+ import std.vec as vec
2
+
3
+ public enum Status: ubyte
4
+ success = 0
5
+ failure = 1
6
+ running = 2
7
+
8
+ public enum NodeKind: ubyte
9
+ sequence = 0
10
+ selector = 1
11
+ parallel_all = 2
12
+ parallel_any = 3
13
+ condition = 4
14
+ action = 5
15
+ inverter = 6
16
+ succeeder = 7
17
+ failer = 8
18
+ repeater = 9
19
+ until_success = 10
20
+ until_failure = 11
21
+
22
+ struct RuntimeState:
23
+ active_child: ptr_uint
24
+ repeat_count: ptr_uint
25
+
26
+ public struct Node[Context]:
27
+ kind: NodeKind
28
+ condition_fn: fn(context: ptr[Context]) -> bool
29
+ action_fn: fn(context: ptr[Context]) -> Status
30
+ repeat_limit: ptr_uint
31
+ children: vec.Vec[ptr_uint]
32
+
33
+ public struct Tree[Context]:
34
+ nodes: vec.Vec[Node[Context]]
35
+ runtime: vec.Vec[RuntimeState]
36
+ root: ptr_uint
37
+ has_root: bool
38
+
39
+
40
+ function default_condition[Context](_context: ptr[Context]) -> bool:
41
+ return false
42
+
43
+
44
+ function default_action[Context](_context: ptr[Context]) -> Status:
45
+ return Status.failure
46
+
47
+
48
+ function create_runtime_state() -> RuntimeState:
49
+ return RuntimeState(active_child = 0, repeat_count = 0)
50
+
51
+
52
+ function child_exists[Context](tree: ref[Tree[Context]], node_id: ptr_uint) -> bool:
53
+ return node_id < tree.nodes.len()
54
+
55
+
56
+ function reset_runtime_state(runtime: ptr[RuntimeState]) -> void:
57
+ unsafe:
58
+ read(runtime).active_child = 0
59
+ read(runtime).repeat_count = 0
60
+
61
+
62
+ function tick_node[Context](tree: ref[Tree[Context]], node_id: ptr_uint, context: ref[Context]) -> Status:
63
+ let node_ptr = tree.nodes.get(node_id) else:
64
+ return Status.failure
65
+
66
+ let runtime_ptr = tree.runtime.get(node_id) else:
67
+ return Status.failure
68
+
69
+ unsafe:
70
+ let node = ptr[Node[Context]]<-node_ptr
71
+ let runtime = ptr[RuntimeState]<-runtime_ptr
72
+ match read(node).kind:
73
+ NodeKind.sequence:
74
+ if read(node).children.is_empty():
75
+ reset_runtime_state(runtime)
76
+ return Status.success
77
+
78
+ var child_index = read(runtime).active_child
79
+ while child_index < read(node).children.len():
80
+ let child_ptr = read(node).children.get(child_index) else:
81
+ reset_runtime_state(runtime)
82
+ return Status.failure
83
+
84
+ let child_status = tick_node(tree, read(child_ptr), context)
85
+ match child_status:
86
+ Status.success:
87
+ child_index += 1
88
+ continue
89
+ Status.failure:
90
+ reset_runtime_state(runtime)
91
+ return Status.failure
92
+ Status.running:
93
+ read(runtime).active_child = child_index
94
+ return Status.running
95
+
96
+ reset_runtime_state(runtime)
97
+ return Status.success
98
+
99
+ NodeKind.selector:
100
+ if read(node).children.is_empty():
101
+ reset_runtime_state(runtime)
102
+ return Status.failure
103
+
104
+ var child_index = read(runtime).active_child
105
+ while child_index < read(node).children.len():
106
+ let child_ptr = read(node).children.get(child_index) else:
107
+ reset_runtime_state(runtime)
108
+ return Status.failure
109
+
110
+ let child_status = tick_node(tree, read(child_ptr), context)
111
+ match child_status:
112
+ Status.success:
113
+ reset_runtime_state(runtime)
114
+ return Status.success
115
+ Status.failure:
116
+ child_index += 1
117
+ continue
118
+ Status.running:
119
+ read(runtime).active_child = child_index
120
+ return Status.running
121
+
122
+ reset_runtime_state(runtime)
123
+ return Status.failure
124
+
125
+ NodeKind.parallel_all:
126
+ if read(node).children.is_empty():
127
+ return Status.failure
128
+
129
+ var saw_running = false
130
+ for child_ptr in read(node).children:
131
+ let child_status = tick_node(tree, unsafe: read(child_ptr), context)
132
+ match child_status:
133
+ Status.success:
134
+ pass
135
+ Status.failure:
136
+ return Status.failure
137
+ Status.running:
138
+ saw_running = true
139
+
140
+ if saw_running:
141
+ return Status.running
142
+
143
+ return Status.success
144
+
145
+ NodeKind.parallel_any:
146
+ if read(node).children.is_empty():
147
+ return Status.failure
148
+
149
+ var saw_running = false
150
+ for child_ptr in read(node).children:
151
+ let child_status = tick_node(tree, unsafe: read(child_ptr), context)
152
+ match child_status:
153
+ Status.success:
154
+ return Status.success
155
+ Status.failure:
156
+ pass
157
+ Status.running:
158
+ saw_running = true
159
+
160
+ if saw_running:
161
+ return Status.running
162
+
163
+ return Status.failure
164
+
165
+ NodeKind.condition:
166
+ if read(node).condition_fn(ptr_of(context)):
167
+ return Status.success
168
+
169
+ return Status.failure
170
+
171
+ NodeKind.action:
172
+ return read(node).action_fn(ptr_of(context))
173
+
174
+ NodeKind.inverter:
175
+ let child_ptr = read(node).children.first() else:
176
+ return Status.failure
177
+
178
+ let child_status = tick_node(tree, read(child_ptr), context)
179
+ match child_status:
180
+ Status.success:
181
+ return Status.failure
182
+ Status.failure:
183
+ return Status.success
184
+ Status.running:
185
+ return Status.running
186
+
187
+ NodeKind.succeeder:
188
+ let child_ptr = read(node).children.first() else:
189
+ return Status.success
190
+
191
+ let child_status = tick_node(tree, read(child_ptr), context)
192
+ if child_status == Status.running:
193
+ return Status.running
194
+
195
+ return Status.success
196
+
197
+ NodeKind.failer:
198
+ let child_ptr = read(node).children.first() else:
199
+ return Status.failure
200
+
201
+ let child_status = tick_node(tree, read(child_ptr), context)
202
+ if child_status == Status.running:
203
+ return Status.running
204
+
205
+ return Status.failure
206
+
207
+ NodeKind.repeater:
208
+ let child_ptr = read(node).children.first() else:
209
+ return Status.failure
210
+
211
+ if read(node).repeat_limit == 0:
212
+ return Status.success
213
+
214
+ let child_status = tick_node(tree, read(child_ptr), context)
215
+ match child_status:
216
+ Status.success:
217
+ read(runtime).repeat_count += 1
218
+ if read(runtime).repeat_count >= read(node).repeat_limit:
219
+ reset_runtime_state(runtime)
220
+ return Status.success
221
+ return Status.running
222
+ Status.failure:
223
+ reset_runtime_state(runtime)
224
+ return Status.failure
225
+ Status.running:
226
+ return Status.running
227
+
228
+ NodeKind.until_success:
229
+ let child_ptr = read(node).children.first() else:
230
+ return Status.failure
231
+
232
+ let child_status = tick_node(tree, read(child_ptr), context)
233
+ match child_status:
234
+ Status.success:
235
+ return Status.success
236
+ Status.failure:
237
+ return Status.running
238
+ Status.running:
239
+ return Status.running
240
+
241
+ NodeKind.until_failure:
242
+ let child_ptr = read(node).children.first() else:
243
+ return Status.failure
244
+
245
+ let child_status = tick_node(tree, read(child_ptr), context)
246
+ match child_status:
247
+ Status.success:
248
+ return Status.running
249
+ Status.failure:
250
+ return Status.success
251
+ Status.running:
252
+ return Status.running
253
+
254
+ return Status.failure
255
+
256
+
257
+ extending Node[Context]:
258
+ static function create(kind: NodeKind) -> Node[Context]:
259
+ return Node[Context](
260
+ kind = kind,
261
+ condition_fn = default_condition[Context],
262
+ action_fn = default_action[Context],
263
+ repeat_limit = 0,
264
+ children = vec.Vec[ptr_uint].create()
265
+ )
266
+
267
+
268
+ public static function sequence() -> Node[Context]:
269
+ return Node[Context].create(NodeKind.sequence)
270
+
271
+
272
+ public static function selector() -> Node[Context]:
273
+ return Node[Context].create(NodeKind.selector)
274
+
275
+
276
+ public static function parallel_all() -> Node[Context]:
277
+ return Node[Context].create(NodeKind.parallel_all)
278
+
279
+
280
+ public static function parallel_any() -> Node[Context]:
281
+ return Node[Context].create(NodeKind.parallel_any)
282
+
283
+
284
+ public static function condition(check: fn(context: ptr[Context]) -> bool) -> Node[Context]:
285
+ var result = Node[Context].create(NodeKind.condition)
286
+ result.condition_fn = check
287
+ return result
288
+
289
+
290
+ public static function action(run: fn(context: ptr[Context]) -> Status) -> Node[Context]:
291
+ var result = Node[Context].create(NodeKind.action)
292
+ result.action_fn = run
293
+ return result
294
+
295
+
296
+ public static function inverter() -> Node[Context]:
297
+ return Node[Context].create(NodeKind.inverter)
298
+
299
+
300
+ public static function succeeder() -> Node[Context]:
301
+ return Node[Context].create(NodeKind.succeeder)
302
+
303
+
304
+ public static function failer() -> Node[Context]:
305
+ return Node[Context].create(NodeKind.failer)
306
+
307
+
308
+ public static function repeater(limit: ptr_uint) -> Node[Context]:
309
+ var result = Node[Context].create(NodeKind.repeater)
310
+ result.repeat_limit = limit
311
+ return result
312
+
313
+
314
+ public static function until_success() -> Node[Context]:
315
+ return Node[Context].create(NodeKind.until_success)
316
+
317
+
318
+ public static function until_failure() -> Node[Context]:
319
+ return Node[Context].create(NodeKind.until_failure)
320
+
321
+
322
+ public editable function release() -> void:
323
+ this.children.release()
324
+
325
+
326
+ extending Tree[Context]:
327
+ public static function create() -> Tree[Context]:
328
+ return Tree[Context](
329
+ nodes = vec.Vec[Node[Context]].create(),
330
+ runtime = vec.Vec[RuntimeState].create(),
331
+ root = 0,
332
+ has_root = false
333
+ )
334
+
335
+
336
+ public editable function release() -> void:
337
+ for node_ptr in this.nodes:
338
+ unsafe:
339
+ read(node_ptr).release()
340
+ this.nodes.release()
341
+ this.runtime.release()
342
+ this.root = 0
343
+ this.has_root = false
344
+
345
+
346
+ public editable function reset() -> void:
347
+ for entry in this.runtime:
348
+ reset_runtime_state(unsafe: ptr[RuntimeState]<-entry)
349
+
350
+
351
+ public function node_count() -> ptr_uint:
352
+ return this.nodes.len()
353
+
354
+
355
+ public function root_node() -> Option[ptr_uint]:
356
+ if not this.has_root:
357
+ return Option[ptr_uint].none
358
+
359
+ return Option[ptr_uint].some(value = this.root)
360
+
361
+
362
+ public editable function add_node(node: Node[Context]) -> ptr_uint:
363
+ let node_id = this.nodes.len()
364
+ this.nodes.push(node)
365
+ this.runtime.push(create_runtime_state())
366
+ return node_id
367
+
368
+
369
+ public editable function set_root(node_id: ptr_uint) -> bool:
370
+ if not child_exists(ref_of(this), node_id):
371
+ return false
372
+
373
+ this.root = node_id
374
+ this.has_root = true
375
+ return true
376
+
377
+
378
+ public editable function add_child(parent_id: ptr_uint, child_id: ptr_uint) -> bool:
379
+ if not child_exists(ref_of(this), parent_id):
380
+ return false
381
+ if not child_exists(ref_of(this), child_id):
382
+ return false
383
+
384
+ let parent_ptr = this.nodes.get(parent_id) else:
385
+ return false
386
+
387
+ unsafe:
388
+ read(parent_ptr).children.push(child_id)
389
+ return true
390
+
391
+
392
+ public editable function tick(context: ref[Context]) -> Status:
393
+ if not this.has_root:
394
+ return Status.failure
395
+
396
+ return tick_node(ref_of(this), this.root, context)
data/std/binary.mt ADDED
@@ -0,0 +1,314 @@
1
+ import std.bytes as bytes
2
+ import std.str as text
3
+ import std.string as string
4
+ import std.vec as vec
5
+
6
+ public struct Error:
7
+ code: int
8
+ message: string.String
9
+
10
+ public struct Writer:
11
+ buffer: vec.Vec[ubyte]
12
+
13
+ public struct Reader:
14
+ data: span[ubyte]
15
+ position: ptr_uint
16
+
17
+
18
+ function binary_error(code: int, message: str) -> Error:
19
+ return Error(code = code, message = string.String.from_str(message))
20
+
21
+
22
+ function writer_append_byte(writer: ref[Writer], value: ubyte) -> void:
23
+ writer.buffer.push(value)
24
+
25
+
26
+ function writer_append_span(writer: ref[Writer], data: span[ubyte]) -> void:
27
+ writer.buffer.append_span(data)
28
+
29
+
30
+ extending Error:
31
+ public editable function release() -> void:
32
+ this.message.release()
33
+
34
+
35
+ extending Writer:
36
+ public static function create() -> Writer:
37
+ return Writer(buffer = vec.Vec[ubyte].create())
38
+
39
+
40
+ public static function with_capacity(capacity: ptr_uint) -> Writer:
41
+ return Writer(buffer = vec.Vec[ubyte].with_capacity(capacity))
42
+
43
+
44
+ public editable function write_ubyte(value: ubyte) -> void:
45
+ writer_append_byte(ref_of(this), value)
46
+
47
+
48
+ public editable function write_ushort(value: ushort) -> void:
49
+ writer_append_byte(ref_of(this), ubyte<-(value & 0xFF))
50
+ writer_append_byte(ref_of(this), ubyte<-((value >> 8) & 0xFF))
51
+
52
+
53
+ public editable function write_uint(value: uint) -> void:
54
+ writer_append_byte(ref_of(this), ubyte<-(value & 0xFF))
55
+ writer_append_byte(ref_of(this), ubyte<-((value >> 8) & 0xFF))
56
+ writer_append_byte(ref_of(this), ubyte<-((value >> 16) & 0xFF))
57
+ writer_append_byte(ref_of(this), ubyte<-((value >> 24) & 0xFF))
58
+
59
+
60
+ public editable function write_ulong(value: ulong) -> void:
61
+ writer_append_byte(ref_of(this), ubyte<-(value & 0xFF))
62
+ writer_append_byte(ref_of(this), ubyte<-((value >> 8) & 0xFF))
63
+ writer_append_byte(ref_of(this), ubyte<-((value >> 16) & 0xFF))
64
+ writer_append_byte(ref_of(this), ubyte<-((value >> 24) & 0xFF))
65
+ writer_append_byte(ref_of(this), ubyte<-((value >> 32) & 0xFF))
66
+ writer_append_byte(ref_of(this), ubyte<-((value >> 40) & 0xFF))
67
+ writer_append_byte(ref_of(this), ubyte<-((value >> 48) & 0xFF))
68
+ writer_append_byte(ref_of(this), ubyte<-((value >> 56) & 0xFF))
69
+
70
+
71
+ public editable function write_byte(value: byte) -> void:
72
+ writer_append_byte(ref_of(this), ubyte<-value)
73
+
74
+
75
+ public editable function write_short(value: short) -> void:
76
+ this.write_ushort(ushort<-value)
77
+
78
+
79
+ public editable function write_int(value: int) -> void:
80
+ this.write_uint(uint<-value)
81
+
82
+
83
+ public editable function write_long(value: long) -> void:
84
+ this.write_ulong(ulong<-value)
85
+
86
+
87
+ public editable function write_float(value: float) -> void:
88
+ let bits = unsafe: reinterpret[uint](value)
89
+ this.write_uint(bits)
90
+
91
+
92
+ public editable function write_double(value: double) -> void:
93
+ let bits = unsafe: reinterpret[ulong](value)
94
+ this.write_ulong(bits)
95
+
96
+
97
+ public editable function write_bool(value: bool) -> void:
98
+ if value:
99
+ writer_append_byte(ref_of(this), 1)
100
+ else:
101
+ writer_append_byte(ref_of(this), 0)
102
+
103
+
104
+ public editable function write_bytes(data: span[ubyte]) -> void:
105
+ writer_append_span(ref_of(this), data)
106
+
107
+
108
+ public editable function write_str(value: str) -> void:
109
+ this.write_uint(uint<-value.len)
110
+ if value.len > 0:
111
+ writer_append_span(ref_of(this), text.as_byte_span(value))
112
+
113
+
114
+ public editable function write_uint_at(position: ptr_uint, value: uint) -> void:
115
+ let buffer_span = this.buffer.as_span()
116
+ if position + 4 > buffer_span.len:
117
+ fatal(c"binary.write_u32_at position out of bounds")
118
+ unsafe:
119
+ read(buffer_span.data + position) = ubyte<-(value & 0xFF)
120
+ read(buffer_span.data + position + 1) = ubyte<-((value >> 8) & 0xFF)
121
+ read(buffer_span.data + position + 2) = ubyte<-((value >> 16) & 0xFF)
122
+ read(buffer_span.data + position + 3) = ubyte<-((value >> 24) & 0xFF)
123
+
124
+
125
+ public function len() -> ptr_uint:
126
+ return this.buffer.len()
127
+
128
+
129
+ public function as_span() -> span[ubyte]:
130
+ return this.buffer.as_span()
131
+
132
+
133
+ public editable function finish() -> bytes.Bytes:
134
+ let result = bytes.Bytes.copy(this.buffer.as_span())
135
+ this.buffer.release()
136
+ return result
137
+
138
+
139
+ public editable function reset() -> void:
140
+ this.buffer.clear()
141
+
142
+
143
+ public editable function release() -> void:
144
+ this.buffer.release()
145
+
146
+
147
+ public function reader(data: span[ubyte]) -> Reader:
148
+ return Reader(data = data, position = 0)
149
+
150
+
151
+ public function reader_from_bytes(data: bytes.Bytes) -> Reader:
152
+ return Reader(data = data.as_span(), position = 0)
153
+
154
+
155
+ function reader_check_remaining(reader: ref[Reader], count: ptr_uint) -> Result[bool, Error]:
156
+ if reader.position > reader.data.len:
157
+ return Result[bool, Error].failure(error = binary_error(-1, "binary reader position overflow"))
158
+ if reader.data.len - reader.position < count:
159
+ return Result[bool, Error].failure(error = binary_error(-1, "binary reader unexpected end of buffer"))
160
+ return Result[bool, Error].success(value = true)
161
+
162
+
163
+ function reader_read_byte(reader: ref[Reader]) -> Result[ubyte, Error]:
164
+ reader_check_remaining(reader, 1)?
165
+ let value = unsafe: read(reader.data.data + reader.position)
166
+ reader.position += 1
167
+ return Result[ubyte, Error].success(value = value)
168
+
169
+
170
+ extending Reader:
171
+ public editable function read_ubyte() -> Result[ubyte, Error]:
172
+ return reader_read_byte(ref_of(this))
173
+
174
+
175
+ public editable function read_ushort() -> Result[ushort, Error]:
176
+ reader_check_remaining(ref_of(this), 2)?
177
+ let low = ushort<-unsafe: read(this.data.data + this.position)
178
+ let high = ushort<-unsafe: read(this.data.data + this.position + 1)
179
+ this.position += 2
180
+ return Result[ushort, Error].success(value = (high << 8) | low)
181
+
182
+
183
+ public editable function read_uint() -> Result[uint, Error]:
184
+ reader_check_remaining(ref_of(this), 4)?
185
+ var value: uint = 0
186
+ unsafe:
187
+ let b0 = uint<-read(this.data.data + this.position)
188
+ let b1 = uint<-read(this.data.data + this.position + 1)
189
+ let b2 = uint<-read(this.data.data + this.position + 2)
190
+ let b3 = uint<-read(this.data.data + this.position + 3)
191
+ value = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)
192
+ this.position += 4
193
+ return Result[uint, Error].success(value = value)
194
+
195
+
196
+ public editable function read_ulong() -> Result[ulong, Error]:
197
+ reader_check_remaining(ref_of(this), 8)?
198
+ var value: ulong = 0
199
+ unsafe:
200
+ let b0 = ulong<-read(this.data.data + this.position)
201
+ let b1 = ulong<-read(this.data.data + this.position + 1)
202
+ let b2 = ulong<-read(this.data.data + this.position + 2)
203
+ let b3 = ulong<-read(this.data.data + this.position + 3)
204
+ let b4 = ulong<-read(this.data.data + this.position + 4)
205
+ let b5 = ulong<-read(this.data.data + this.position + 5)
206
+ let b6 = ulong<-read(this.data.data + this.position + 6)
207
+ let b7 = ulong<-read(this.data.data + this.position + 7)
208
+ value = (
209
+ b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)
210
+ | (b4 << 32) | (b5 << 40) | (b6 << 48) | (b7 << 56)
211
+ )
212
+ this.position += 8
213
+ return Result[ulong, Error].success(value = value)
214
+
215
+
216
+ public editable function read_byte() -> Result[byte, Error]:
217
+ let value = this.read_ubyte()?
218
+ return Result[byte, Error].success(value = byte<-value)
219
+
220
+
221
+ public editable function read_short() -> Result[short, Error]:
222
+ let value = this.read_ushort()?
223
+ return Result[short, Error].success(value = short<-value)
224
+
225
+
226
+ public editable function read_int() -> Result[int, Error]:
227
+ let value = this.read_uint()?
228
+ return Result[int, Error].success(value = int<-value)
229
+
230
+
231
+ public editable function read_long() -> Result[long, Error]:
232
+ let value = this.read_ulong()?
233
+ return Result[long, Error].success(value = long<-value)
234
+
235
+
236
+ public editable function read_float() -> Result[float, Error]:
237
+ let value = this.read_uint()?
238
+ return Result[float, Error].success(value = unsafe: reinterpret[float](value))
239
+
240
+
241
+ public editable function read_double() -> Result[double, Error]:
242
+ let value = this.read_ulong()?
243
+ return Result[double, Error].success(value = unsafe: reinterpret[double](value))
244
+
245
+
246
+ public editable function read_bool() -> Result[bool, Error]:
247
+ let value = this.read_ubyte()?
248
+ if value == 0:
249
+ return Result[bool, Error].success(value = false)
250
+ if value == 1:
251
+ return Result[bool, Error].success(value = true)
252
+ return Result[bool, Error].failure(error = binary_error(-2, "binary reader invalid bool value"))
253
+
254
+
255
+ public editable function read_bytes(count: ptr_uint) -> Result[bytes.Bytes, Error]:
256
+ if count == 0:
257
+ return Result[bytes.Bytes, Error].success(value = bytes.Bytes.empty())
258
+
259
+ reader_check_remaining(ref_of(this), count)?
260
+ unsafe:
261
+ let result = bytes.Bytes.copy(span[ubyte](
262
+ data = this.data.data + this.position,
263
+ len = count
264
+ ))
265
+ this.position += count
266
+ return Result[bytes.Bytes, Error].success(value = result)
267
+
268
+
269
+ public editable function read_span(count: ptr_uint) -> Result[span[ubyte], Error]:
270
+ if count == 0:
271
+ let empty = unsafe: span[ubyte](data = this.data.data, len = 0)
272
+ return Result[span[ubyte], Error].success(value = empty)
273
+
274
+ reader_check_remaining(ref_of(this), count)?
275
+ unsafe:
276
+ let result = span[ubyte](data = this.data.data + this.position, len = count)
277
+ this.position += count
278
+ return Result[span[ubyte], Error].success(value = result)
279
+
280
+
281
+ public editable function read_str() -> Result[string.String, Error]:
282
+ let length = ptr_uint<-this.read_uint()?
283
+ if length == 0:
284
+ return Result[string.String, Error].success(value = string.String.create())
285
+
286
+ var data = this.read_bytes(length)?
287
+ let str_opt = text.utf8_byte_span_as_str(data.as_span())
288
+ match str_opt:
289
+ Option.none:
290
+ data.release()
291
+ return Result[string.String, Error].failure(error = binary_error(
292
+ -2,
293
+ "binary reader invalid UTF-8 string"
294
+ ))
295
+ Option.some as str_payload:
296
+ let result = string.String.from_str(str_payload.value)
297
+ data.release()
298
+ return Result[string.String, Error].success(value = result)
299
+
300
+
301
+ public editable function skip(count: ptr_uint) -> Result[bool, Error]:
302
+ reader_check_remaining(ref_of(this), count)?
303
+ this.position += count
304
+ return Result[bool, Error].success(value = true)
305
+
306
+
307
+ public function remaining() -> ptr_uint:
308
+ if this.position >= this.data.len:
309
+ return 0
310
+ return this.data.len - this.position
311
+
312
+
313
+ public function has_more() -> bool:
314
+ return this.position < this.data.len