mt-lang 0.3.1 → 0.3.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e212444d219545cf86e5711bdcd0eb02028b94fd8b0ae1ac8b6ade08b25967da
4
- data.tar.gz: fce0d6413dfc434af53103228604527bf9f08fef30dcbd7013fd50f5bd30878b
3
+ metadata.gz: ed7c9f0e80bb1fcfc3b458b277a0a2eda3b55ca295950af89c99a769b74e4be2
4
+ data.tar.gz: 4eb3fdfcbdb1557b3ed87a1f60ce8704f1f1de943e58e2c096318fc802da55a2
5
5
  SHA512:
6
- metadata.gz: acc176d3ad35b7184b3df7e4beb4fb6a411bcf613bc7905fa16f215388d0ff26a6a0cea201f124f861f571efa7166098e969cffbe5e600ccf2e30614c5351065
7
- data.tar.gz: 7664d2ceb6235804d8ee78e6dd594ece82492f2e1d00c792762c696d122e3ad669b57dd4825acbada2c5d83dcb1fddef0b366dacd2f363d475bbedefba6122a9
6
+ metadata.gz: f900ebf361a8f2c8acec00fb63ccae9d6b23cd6059ba2edc27b4a3c89fe288453498d9aca753cba2b1139db6b69a82e52038e976c5d4b692d052845735afd754
7
+ data.tar.gz: 0a2bffc30d6485314ef351fb3917696298978798494e8eb655b27ed045c2d0c74674ab53d2c8b8764241b1e07fef092c3bbd6b35b73451d0237ac250a4d7a21c
data/lib/milk_tea/base.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require "pathname"
4
4
 
5
5
  module MilkTea
6
- VERSION = "0.3.1"
6
+ VERSION = "0.3.2"
7
7
 
8
8
  def self.root
9
9
  @root ||= Pathname.new(File.expand_path("../..", __dir__))
@@ -18,6 +18,7 @@ module MilkTea
18
18
  local_name = import.alias_name || import.path.parts.last
19
19
  next if ignored_binding_name?(local_name)
20
20
  next if used.include?(local_name)
21
+ next if import_provides_extending_methods?(import)
21
22
 
22
23
  @warnings << Warning.new(
23
24
  path: @path,
@@ -31,6 +32,15 @@ module MilkTea
31
32
  end
32
33
  end
33
34
 
35
+ def import_provides_extending_methods?(import)
36
+ return false unless @sema_facts.respond_to?(:imports)
37
+
38
+ module_binding = @sema_facts.imports[import.alias_name || import.path.parts.last]
39
+ return false unless module_binding&.respond_to?(:methods)
40
+
41
+ module_binding.methods.any?
42
+ end
43
+
34
44
  def check_platform_api_drift(source_file)
35
45
  resolved_path = self.class.resolve_lint_path(@path)
36
46
  return unless resolved_path&.end_with?(".mt")
@@ -239,16 +239,37 @@ module MilkTea
239
239
  true
240
240
  elsif stmt.is_a?(AST::Assignment) && stmt.value.is_a?(AST::Identifier) && stmt.value.name == name
241
241
  true
242
+ elsif stmt.is_a?(AST::ReturnStmt) && own_cast_in_unsafe?(stmt.value, name)
243
+ true
242
244
  else
243
245
  false
244
246
  end
245
247
  end
246
248
  end
247
249
 
250
+ def own_cast_in_unsafe?(expr, name)
251
+ case expr
252
+ when AST::UnsafeExpr
253
+ case expr.expression
254
+ when AST::PrefixCast
255
+ expr.expression.expression.is_a?(AST::Identifier) && expr.expression.expression.name == name
256
+ end
257
+ else
258
+ false
259
+ end
260
+ end
261
+
248
262
  def own_struct_field_transfer?(expr, name)
249
- return false unless expr.is_a?(AST::Call)
250
- expr.arguments.any? do |arg|
251
- arg.is_a?(AST::Argument) && arg.value.is_a?(AST::Identifier) && arg.value.name == name
263
+ case expr
264
+ when AST::Call
265
+ expr.arguments.any? do |arg|
266
+ next unless arg.is_a?(AST::Argument)
267
+
268
+ arg.value.is_a?(AST::Identifier) && arg.value.name == name ||
269
+ own_struct_field_transfer?(arg.value, name)
270
+ end
271
+ else
272
+ false
252
273
  end
253
274
  end
254
275
 
@@ -152,6 +152,7 @@ module MilkTea
152
152
  column: statement.column,
153
153
  var: statement.kind == :var
154
154
  )
155
+ with_scope { visit_statement_list(statement.else_body) } if statement.else_body
155
156
  check_redundant_type_annotation(statement)
156
157
  flag_redundant_widening_cast(statement.value) if statement.type && statement.value
157
158
  record_ptr_candidate(statement)
data/std/iter.mt ADDED
@@ -0,0 +1,304 @@
1
+ ## std.iter — composable, lazy iteration adaptors.
2
+ ##
3
+ ## Each source/adaptor creates heap-allocated state linked through
4
+ ## function pointers. Release walks the chain to free all allocations.
5
+ ## Callbacks use fn types (function pointers, no captures).
6
+ ##
7
+ ## iter_map stores the mapped value inline in the adaptor state and
8
+ ## returns a pointer to it — no per-item allocation.
9
+ ##
10
+ ## Usage:
11
+ ## import std.iter
12
+ ## let it = iter.from_array(ref_of(arr))
13
+ ## let it2 = iter.iter_filter(it, pred)
14
+ ## let v = iter.collect_vec(it2)
15
+
16
+ import std.mem.heap as heap
17
+ import std.mem.ptr as ptr
18
+ import std.vec as v
19
+
20
+ ## ── Core Iter type ───────────────────────────────────────────────────
21
+
22
+ struct Iter[T]:
23
+ state: ptr[void]
24
+ next_fn: fn(state: ptr[void]) -> ptr[T]?
25
+ release_fn: fn(state: ptr[void]) -> void
26
+
27
+ ## ── Ownership helpers ────────────────────────────────────────────────
28
+
29
+ public function own_to_ptr[T](owned: own[T]) -> ptr[void]:
30
+ return unsafe: ptr[void]<-owned
31
+
32
+ ## ── Source: Vec ─────────────────────────────────────────────────────
33
+
34
+ public function from_vec[T](vec: ref[v.Vec[T]]) -> Iter[T]:
35
+ return from_span(vec.as_span())
36
+
37
+ ## ── Source: array ────────────────────────────────────────────────────
38
+
39
+ public function from_array[T, N](arr: ref[array[T, N]]) -> Iter[T]:
40
+ return from_span(arr.as_span())
41
+
42
+ ## ── .as_iter() extending blocks ──────────────────────────────────────
43
+
44
+ extending v.Vec[T]:
45
+ public editable function as_iter() -> Iter[T]:
46
+ return from_vec(ref_of(this))
47
+
48
+ extending array[T, N]:
49
+ public editable function as_iter() -> Iter[T]:
50
+ return from_array[T, N](ref_of(this))
51
+
52
+ extending span[T]:
53
+ public function as_iter() -> Iter[T]:
54
+ return from_span(this)
55
+
56
+ ## ── Source: span ─────────────────────────────────────────────────────
57
+
58
+ struct SpanIterState[T]:
59
+ sp: span[T]
60
+ index: ptr_uint
61
+
62
+ public function span_advance[T](state: ptr[void]) -> ptr[T]?:
63
+ let s = unsafe: ptr[SpanIterState[T]]<-state
64
+ let _this = unsafe: read(s)
65
+ if _this.index >= _this.sp.len:
66
+ return null
67
+ let item = unsafe: _this.sp.data + _this.index
68
+ unsafe: read(s).index += 1
69
+ return item
70
+
71
+ public function span_release[T](state: ptr[void]) -> void:
72
+ let s = unsafe: ptr[SpanIterState[T]]<-state
73
+ heap.release[SpanIterState[T]](s)
74
+
75
+ public function from_span[T](sp: span[T]) -> Iter[T]:
76
+ let state = heap.must_alloc[SpanIterState[T]](1)
77
+ state.index = 0
78
+ state.sp = sp
79
+ let p = own_to_ptr(state)
80
+ return Iter[T](state = p, next_fn = span_advance[T], release_fn = span_release[T])
81
+
82
+ ## ── Adaptor: Filter ──────────────────────────────────────────────────
83
+
84
+ struct FilterState[T]:
85
+ inner: Iter[T]
86
+ pred: fn(value: T) -> bool
87
+
88
+ public function filter_advance[T](state: ptr[void]) -> ptr[T]?:
89
+ let s = unsafe: ptr[FilterState[T]]<-state
90
+ let _this = unsafe: read(s)
91
+ var item = _this.inner.next_fn(_this.inner.state)
92
+ while item != null:
93
+ if _this.pred(item.load()):
94
+ return item
95
+ item = _this.inner.next_fn(_this.inner.state)
96
+ return null
97
+
98
+ public function filter_release[T](state: ptr[void]) -> void:
99
+ let s = unsafe: ptr[FilterState[T]]<-state
100
+ let _this = unsafe: read(s)
101
+ _this.inner.release_fn(_this.inner.state)
102
+ heap.release[FilterState[T]](s)
103
+
104
+ public function iter_filter[T](iter: Iter[T], pred: fn(value: T) -> bool) -> Iter[T]:
105
+ let state = heap.must_alloc[FilterState[T]](1)
106
+ state.inner = iter
107
+ state.pred = pred
108
+ let p = own_to_ptr(state)
109
+ return Iter[T](state = p, next_fn = filter_advance[T], release_fn = filter_release[T])
110
+
111
+ ## ── Adaptor: Map ─────────────────────────────────────────────────────
112
+
113
+ struct MapState[T, U]:
114
+ inner: Iter[T]
115
+ map_fn: fn(value: T) -> U
116
+ current: U
117
+
118
+ public function map_advance[T, U](state: ptr[void]) -> ptr[U]?:
119
+ let s = unsafe: ptr[MapState[T, U]]<-state
120
+ let current_offset = offset_of(MapState[T, U], current)
121
+ let p = unsafe: read(s)
122
+ let item = p.inner.next_fn(p.inner.state) else:
123
+ return null
124
+ let base: ptr[ubyte] = unsafe: ptr[ubyte]<-s
125
+ let field_ptr = unsafe: base + ptr_uint<-current_offset
126
+ let target: ptr[U] = unsafe: ptr[U]<-field_ptr
127
+ target.store(p.map_fn(item.load()))
128
+ return target
129
+
130
+ public function map_release[T, U](state: ptr[void]) -> void:
131
+ let s = unsafe: ptr[MapState[T, U]]<-state
132
+ let _this = unsafe: read(s)
133
+ _this.inner.release_fn(_this.inner.state)
134
+ heap.release[MapState[T, U]](s)
135
+
136
+ public function iter_map[T, U](iter: Iter[T], f: fn(value: T) -> U) -> Iter[U]:
137
+ let state = heap.must_alloc[MapState[T, U]](1)
138
+ state.inner = iter
139
+ state.map_fn = f
140
+ let p = own_to_ptr(state)
141
+ return Iter[U](state = p, next_fn = map_advance[T, U], release_fn = map_release[T, U])
142
+
143
+ ## ── Adaptor: Take ────────────────────────────────────────────────────
144
+
145
+ struct TakeState[T]:
146
+ inner: Iter[T]
147
+ remaining: int
148
+
149
+ public function take_advance[T](state: ptr[void]) -> ptr[T]?:
150
+ let s = unsafe: ptr[TakeState[T]]<-state
151
+ let _this = unsafe: read(s)
152
+ if _this.remaining <= 0:
153
+ return null
154
+ unsafe: read(s).remaining -= 1
155
+ return _this.inner.next_fn(_this.inner.state)
156
+
157
+ public function take_release[T](state: ptr[void]) -> void:
158
+ let s = unsafe: ptr[TakeState[T]]<-state
159
+ let _this = unsafe: read(s)
160
+ _this.inner.release_fn(_this.inner.state)
161
+ heap.release[TakeState[T]](s)
162
+
163
+ public function iter_take[T](iter: Iter[T], n: int) -> Iter[T]:
164
+ let state = heap.must_alloc[TakeState[T]](1)
165
+ state.inner = iter
166
+ state.remaining = n
167
+ let p = own_to_ptr(state)
168
+ return Iter[T](state = p, next_fn = take_advance[T], release_fn = take_release[T])
169
+
170
+ ## ── Adaptor: Skip ────────────────────────────────────────────────────
171
+
172
+ struct SkipState[T]:
173
+ inner: Iter[T]
174
+ skip_count: int
175
+
176
+ public function skip_advance[T](state: ptr[void]) -> ptr[T]?:
177
+ let s = unsafe: ptr[SkipState[T]]<-state
178
+ let _this = unsafe: read(s)
179
+ while _this.skip_count > 0:
180
+ let _ = _this.inner.next_fn(_this.inner.state) else:
181
+ return null
182
+ unsafe: read(s).skip_count -= 1
183
+ return _this.inner.next_fn(_this.inner.state)
184
+
185
+ public function skip_release[T](state: ptr[void]) -> void:
186
+ let s = unsafe: ptr[SkipState[T]]<-state
187
+ let _this = unsafe: read(s)
188
+ _this.inner.release_fn(_this.inner.state)
189
+ heap.release[SkipState[T]](s)
190
+
191
+ public function iter_skip[T](iter: Iter[T], n: int) -> Iter[T]:
192
+ let state = heap.must_alloc[SkipState[T]](1)
193
+ state.inner = iter
194
+ state.skip_count = n
195
+ let p = own_to_ptr(state)
196
+ return Iter[T](state = p, next_fn = skip_advance[T], release_fn = skip_release[T])
197
+
198
+ ## ── Adaptor: Enumerate ────────────────────────────────────────────────
199
+
200
+ struct Enumerated[T]:
201
+ index: ptr_uint
202
+ value: T
203
+
204
+ struct EnumerateState[T]:
205
+ inner: Iter[T]
206
+ index: ptr_uint
207
+ current: Enumerated[T]
208
+
209
+ public function enum_advance[T](state: ptr[void]) -> ptr[Enumerated[T]]?:
210
+ let s = unsafe: ptr[EnumerateState[T]]<-state
211
+ let current_offset = offset_of(EnumerateState[T], current)
212
+ let p = unsafe: read(s)
213
+ let item = p.inner.next_fn(p.inner.state) else:
214
+ return null
215
+ let base: ptr[ubyte] = unsafe: ptr[ubyte]<-s
216
+ let field_ptr = unsafe: base + ptr_uint<-current_offset
217
+ let target: ptr[Enumerated[T]] = unsafe: ptr[Enumerated[T]]<-field_ptr
218
+ target.store(Enumerated[T](index = p.index, value = item.load()))
219
+ unsafe: read(s).index += 1
220
+ return target
221
+
222
+ public function enum_release[T](state: ptr[void]) -> void:
223
+ let s = unsafe: ptr[EnumerateState[T]]<-state
224
+ let _this = unsafe: read(s)
225
+ _this.inner.release_fn(_this.inner.state)
226
+ heap.release[EnumerateState[T]](s)
227
+
228
+ public function iter_enumerate[T](iter: Iter[T]) -> Iter[Enumerated[T]]:
229
+ let state = heap.must_alloc[EnumerateState[T]](1)
230
+ state.inner = iter
231
+ state.index = 0
232
+ let p = own_to_ptr(state)
233
+ let enum_it = Iter[Enumerated[T]](state = p, next_fn = enum_advance[T], release_fn = enum_release[T])
234
+ return enum_it
235
+
236
+ ## ── Consumer: Fold ───────────────────────────────────────────────────
237
+
238
+ public function iter_fold[T, U](iter: Iter[T], init: U, f: fn(accum: U, value: T) -> U) -> U:
239
+ var accum = init
240
+ var item = iter.next_fn(iter.state)
241
+ while item != null:
242
+ accum = f(accum, item.load())
243
+ item = iter.next_fn(iter.state)
244
+ iter.release_fn(iter.state)
245
+ return accum
246
+
247
+ ## ── Consumer: Find ───────────────────────────────────────────────────
248
+
249
+ public function iter_find[T](iter: Iter[T], pred: fn(value: T) -> bool) -> Option[T]:
250
+ var item = iter.next_fn(iter.state)
251
+ while item != null:
252
+ if pred(item.load()):
253
+ let val = item.load()
254
+ iter.release_fn(iter.state)
255
+ return Option[T].some(value = val)
256
+ item = iter.next_fn(iter.state)
257
+ iter.release_fn(iter.state)
258
+ return Option[T].none
259
+
260
+ ## ── Consumer: Any ────────────────────────────────────────────────────
261
+
262
+ public function iter_any[T](iter: Iter[T], pred: fn(value: T) -> bool) -> bool:
263
+ var item = iter.next_fn(iter.state)
264
+ while item != null:
265
+ if pred(item.load()):
266
+ iter.release_fn(iter.state)
267
+ return true
268
+ item = iter.next_fn(iter.state)
269
+ iter.release_fn(iter.state)
270
+ return false
271
+
272
+ ## ── Consumer: All ────────────────────────────────────────────────────
273
+
274
+ public function iter_all[T](iter: Iter[T], pred: fn(value: T) -> bool) -> bool:
275
+ var item = iter.next_fn(iter.state)
276
+ while item != null:
277
+ if not pred(item.load()):
278
+ iter.release_fn(iter.state)
279
+ return false
280
+ item = iter.next_fn(iter.state)
281
+ iter.release_fn(iter.state)
282
+ return true
283
+
284
+ ## ── Consumer: Count ──────────────────────────────────────────────────
285
+
286
+ public function iter_count[T](iter: Iter[T]) -> ptr_uint:
287
+ var count: ptr_uint = 0
288
+ var item = iter.next_fn(iter.state)
289
+ while item != null:
290
+ count += 1
291
+ item = iter.next_fn(iter.state)
292
+ iter.release_fn(iter.state)
293
+ return count
294
+
295
+ ## ── Collect: Vec ─────────────────────────────────────────────────────
296
+
297
+ public function collect_vec[T](iter: Iter[T]) -> v.Vec[T]:
298
+ var result = v.Vec[T].create()
299
+ var item = iter.next_fn(iter.state)
300
+ while item != null:
301
+ result.push(item.load())
302
+ item = iter.next_fn(iter.state)
303
+ iter.release_fn(iter.state)
304
+ return result
data/std/mem/ptr.mt ADDED
@@ -0,0 +1,12 @@
1
+ ## Pointer load/store — safe wrappers around unsafe: read(ptr).
2
+ ##
3
+ ## import std.mem.ptr as ptr
4
+ ## p.store(42)
5
+ ## let v = p.load()
6
+
7
+ extending ptr[T]:
8
+ public function load() -> T:
9
+ return unsafe: read(this)
10
+
11
+ public function store(value: T) -> void:
12
+ unsafe: read(this) = value
data/std/simd.mt ADDED
@@ -0,0 +1,100 @@
1
+ ## SIMD helpers — load, store, and reduction operations
2
+ ## for the built-in simd[T, N] type constructor.
3
+ ##
4
+ ## Load and store use unsafe ptr casts internally; the user-facing
5
+ ## surface is safe because only valid pointer dereferencing is involved.
6
+ ##
7
+ ## Usage:
8
+ ## import std.simd as simd
9
+ ## let v = simd.load_aligned_float4(ptr)
10
+ ## let s = simd.horizontal_sum_float4(v)
11
+
12
+ import std.mem.ptr as ptr
13
+
14
+ ## ── simd[float, 4] ──────────────────────────────────────────────────
15
+
16
+ public function load_aligned_float4(p: ptr[float]) -> simd[float, 4]:
17
+ let sp = unsafe: ptr[simd[float, 4]]<-p
18
+ return sp.load()
19
+
20
+ public function load_unaligned_float4(p: ptr[float]) -> simd[float, 4]:
21
+ return load_aligned_float4(p)
22
+
23
+ public function store_aligned_float4(p: ptr[float], value: simd[float, 4]) -> void:
24
+ let sp = unsafe: ptr[simd[float, 4]]<-p
25
+ sp.store(value)
26
+
27
+ public function store_unaligned_float4(p: ptr[float], value: simd[float, 4]) -> void:
28
+ store_aligned_float4(p, value)
29
+
30
+ public function horizontal_sum_float4(v: simd[float, 4]) -> float:
31
+ return v[0] + v[1] + v[2] + v[3]
32
+
33
+ public function dot_float4(a: simd[float, 4], b: simd[float, 4]) -> float:
34
+ return horizontal_sum_float4(a * b)
35
+
36
+ ## ── simd[int, 4] ────────────────────────────────────────────────────
37
+
38
+ public function load_aligned_int4(p: ptr[int]) -> simd[int, 4]:
39
+ let sp = unsafe: ptr[simd[int, 4]]<-p
40
+ return sp.load()
41
+
42
+ public function load_unaligned_int4(p: ptr[int]) -> simd[int, 4]:
43
+ return load_aligned_int4(p)
44
+
45
+ public function store_aligned_int4(p: ptr[int], value: simd[int, 4]) -> void:
46
+ let sp = unsafe: ptr[simd[int, 4]]<-p
47
+ sp.store(value)
48
+
49
+ public function store_unaligned_int4(p: ptr[int], value: simd[int, 4]) -> void:
50
+ store_aligned_int4(p, value)
51
+
52
+ public function horizontal_sum_int4(v: simd[int, 4]) -> int:
53
+ return v[0] + v[1] + v[2] + v[3]
54
+
55
+ public function dot_int4(a: simd[int, 4], b: simd[int, 4]) -> int:
56
+ return horizontal_sum_int4(a * b)
57
+
58
+ ## ── simd[float, 8] (AVX) ────────────────────────────────────────────
59
+
60
+ public function load_aligned_float8(p: ptr[float]) -> simd[float, 8]:
61
+ let sp = unsafe: ptr[simd[float, 8]]<-p
62
+ return sp.load()
63
+
64
+ public function load_unaligned_float8(p: ptr[float]) -> simd[float, 8]:
65
+ return load_aligned_float8(p)
66
+
67
+ public function store_aligned_float8(p: ptr[float], value: simd[float, 8]) -> void:
68
+ let sp = unsafe: ptr[simd[float, 8]]<-p
69
+ sp.store(value)
70
+
71
+ public function store_unaligned_float8(p: ptr[float], value: simd[float, 8]) -> void:
72
+ store_aligned_float8(p, value)
73
+
74
+ public function horizontal_sum_float8(v: simd[float, 8]) -> float:
75
+ return v[0] + v[1] + v[2] + v[3] + v[4] + v[5] + v[6] + v[7]
76
+
77
+ public function dot_float8(a: simd[float, 8], b: simd[float, 8]) -> float:
78
+ return horizontal_sum_float8(a * b)
79
+
80
+ ## ── simd[double, 2] ─────────────────────────────────────────────────
81
+
82
+ public function load_aligned_double2(p: ptr[double]) -> simd[double, 2]:
83
+ let sp = unsafe: ptr[simd[double, 2]]<-p
84
+ return sp.load()
85
+
86
+ public function load_unaligned_double2(p: ptr[double]) -> simd[double, 2]:
87
+ return load_aligned_double2(p)
88
+
89
+ public function store_aligned_double2(p: ptr[double], value: simd[double, 2]) -> void:
90
+ let sp = unsafe: ptr[simd[double, 2]]<-p
91
+ sp.store(value)
92
+
93
+ public function store_unaligned_double2(p: ptr[double], value: simd[double, 2]) -> void:
94
+ store_aligned_double2(p, value)
95
+
96
+ public function horizontal_sum_double2(v: simd[double, 2]) -> double:
97
+ return v[0] + v[1]
98
+
99
+ public function dot_double2(a: simd[double, 2], b: simd[double, 2]) -> double:
100
+ return horizontal_sum_double2(a * b)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mt-lang
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Long (Teefan) Tran
@@ -489,6 +489,7 @@ files:
489
489
  - std/http.mt
490
490
  - std/http/server.mt
491
491
  - std/intern.mt
492
+ - std/iter.mt
492
493
  - std/jobs.mt
493
494
  - std/json.mt
494
495
  - std/libc.mt
@@ -505,6 +506,7 @@ files:
505
506
  - std/mem/endian.mt
506
507
  - std/mem/heap.mt
507
508
  - std/mem/pool.mt
509
+ - std/mem/ptr.mt
508
510
  - std/mem/stack.mt
509
511
  - std/mem/tracking.mt
510
512
  - std/miniaudio.mt
@@ -552,6 +554,7 @@ files:
552
554
  - std/sdl3/runtime.mt
553
555
  - std/serialize.mt
554
556
  - std/set.mt
557
+ - std/simd.mt
555
558
  - std/sparse_set.mt
556
559
  - std/spatial.mt
557
560
  - std/sqlite3.mt
@@ -586,7 +589,7 @@ metadata:
586
589
  homepage_uri: https://teefan.github.io/mt-lang/
587
590
  source_code_uri: https://github.com/teefan/mt-lang
588
591
  post_install_message: |
589
- Milk Tea 0.3.1 installed!
592
+ Milk Tea 0.3.2 installed!
590
593
 
591
594
  System requirements:
592
595
  - A C compiler (gcc or clang) must be available on PATH