nomen-lang 0.9.0 → 0.10.0

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 (70) hide show
  1. package/core/System/Arena.nm +9 -7
  2. package/core/System/Array.nm +1 -1
  3. package/core/System/Atomic.nm +3 -3
  4. package/core/System/BigInt.nm +182 -23
  5. package/core/System/Buffer.nm +37 -35
  6. package/core/System/ClassBuffer.nm +18 -18
  7. package/core/System/Controls/Alert.nm +1 -1
  8. package/core/System/Controls/App.nm +5 -5
  9. package/core/System/Controls/Button.nm +1 -1
  10. package/core/System/Controls/CheckBox.nm +1 -1
  11. package/core/System/Controls/ColorPicker.nm +1 -1
  12. package/core/System/Controls/ComboBox.nm +1 -1
  13. package/core/System/Controls/Container.nm +34 -34
  14. package/core/System/Controls/DatePicker.nm +1 -1
  15. package/core/System/Controls/Form.nm +2 -2
  16. package/core/System/Controls/GroupBox.nm +1 -1
  17. package/core/System/Controls/ImageView.nm +1 -1
  18. package/core/System/Controls/Layout.nm +5 -5
  19. package/core/System/Controls/LevelIndicator.nm +1 -1
  20. package/core/System/Controls/ListView.nm +1 -1
  21. package/core/System/Controls/Menu.nm +1 -1
  22. package/core/System/Controls/NumberInput.nm +3 -3
  23. package/core/System/Controls/OtpInput.nm +2 -2
  24. package/core/System/Controls/OutlineView.nm +1 -1
  25. package/core/System/Controls/Pagination.nm +6 -6
  26. package/core/System/Controls/Popover.nm +1 -1
  27. package/core/System/Controls/Progress.nm +1 -1
  28. package/core/System/Controls/Radio.nm +1 -1
  29. package/core/System/Controls/Scrollable.nm +1 -1
  30. package/core/System/Controls/SearchField.nm +1 -1
  31. package/core/System/Controls/SecureField.nm +1 -1
  32. package/core/System/Controls/Segmented.nm +1 -1
  33. package/core/System/Controls/Select.nm +1 -1
  34. package/core/System/Controls/Separator.nm +1 -1
  35. package/core/System/Controls/Sheet.nm +1 -1
  36. package/core/System/Controls/Slider.nm +1 -1
  37. package/core/System/Controls/Spinner.nm +3 -3
  38. package/core/System/Controls/SplitView.nm +2 -2
  39. package/core/System/Controls/Stepper.nm +1 -1
  40. package/core/System/Controls/Switch.nm +1 -1
  41. package/core/System/Controls/Table.nm +1 -1
  42. package/core/System/Controls/Tabs.nm +1 -1
  43. package/core/System/Controls/Text.nm +1 -1
  44. package/core/System/Controls/TextBox.nm +1 -1
  45. package/core/System/Controls/TextView.nm +1 -1
  46. package/core/System/Controls/Toggle.nm +1 -1
  47. package/core/System/Controls/Toolbar.nm +1 -1
  48. package/core/System/Controls/Window.nm +11 -3
  49. package/core/System/Fiber.nm +16 -3
  50. package/core/System/Graph.nm +2 -2
  51. package/core/System/LinkedList.nm +8 -6
  52. package/core/System/List.nm +16 -13
  53. package/core/System/Map.nm +11 -9
  54. package/core/System/Random.nm +3 -3
  55. package/core/System/Set.nm +9 -7
  56. package/core/System/StableList.nm +7 -7
  57. package/core/System/Stream/File.nm +16 -16
  58. package/core/System/Stream/Http.nm +3 -3
  59. package/core/System/Stream/Tcp.nm +5 -5
  60. package/core/System/StringBuilder.nm +16 -16
  61. package/core/System/Task.nm +56 -64
  62. package/core/System/Test.nm +18 -18
  63. package/core/System/Text/Chars.nm +1 -1
  64. package/core/System/Text/Json.nm +12 -12
  65. package/core/System/Text/JsonTree.nm +8 -8
  66. package/core/System/Text/Regex.nm +20 -20
  67. package/core/System/Thread.nm +26 -3
  68. package/core/System/Tree.nm +19 -3
  69. package/dist/index.mjs +3036 -1845
  70. package/package.json +1 -1
@@ -92,7 +92,7 @@ pub mv struct Spinner: Control {
92
92
  ```
93
93
  }
94
94
 
95
- pub func set_frame = (ref self, int x, int y, int width, int height) {
95
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
96
96
  ```
97
97
  #arch: c
98
98
  #platform: macos
@@ -123,7 +123,7 @@ pub mv struct Spinner: Control {
123
123
  ```
124
124
  }
125
125
 
126
- pub func start = (ref self) {
126
+ pub func start = (ref self {}) {
127
127
  ```
128
128
  #arch: c
129
129
  #platform: macos
@@ -154,7 +154,7 @@ pub mv struct Spinner: Control {
154
154
  ```
155
155
  }
156
156
 
157
- pub func stop = (ref self) {
157
+ pub func stop = (ref self {}) {
158
158
  ```
159
159
  #arch: c
160
160
  #platform: macos
@@ -334,7 +334,7 @@ pub mv struct SplitView: Control {
334
334
 
335
335
  // Move divider `index`. For a vertical split the position is the left
336
336
  // edge of the pane after the divider, in points from the left.
337
- pub func set_position = (ref self, float position, int divider) {
337
+ pub func set_position = (ref self {}, float position, int divider) {
338
338
  ```
339
339
  #arch: c
340
340
  #platform: macos
@@ -424,7 +424,7 @@ pub mv struct SplitView: Control {
424
424
  }
425
425
 
426
426
  // ── Control trait conformance ──
427
- pub func set_frame = (ref self, int x, int y, int width, int height) {
427
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
428
428
  ```
429
429
  #arch: c
430
430
  #platform: macos
@@ -87,7 +87,7 @@ pub mv struct Stepper: Control {
87
87
  ```
88
88
  }
89
89
 
90
- pub func set_frame = (ref self, int x, int y, int width, int height) {
90
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
91
91
  ```
92
92
  #arch: c
93
93
  #platform: macos
@@ -74,7 +74,7 @@ pub mv struct Switch: Control {
74
74
  ```
75
75
  }
76
76
 
77
- pub func set_frame = (ref self, int x, int y, int width, int height) {
77
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
78
78
  ```
79
79
  #arch: c
80
80
  #platform: macos
@@ -744,7 +744,7 @@ pub mv struct Table: Control {
744
744
  }
745
745
 
746
746
  // ── Control trait conformance ──
747
- pub func set_frame = (ref self, int x, int y, int width, int height) {
747
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
748
748
  ```
749
749
  #arch: c
750
750
  #platform: macos
@@ -415,7 +415,7 @@ pub mv struct Tabs: Control {
415
415
  }
416
416
 
417
417
  // ── Control trait conformance ──
418
- pub func set_frame = (ref self, int x, int y, int width, int height) {
418
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
419
419
  ```
420
420
  #arch: c
421
421
  #platform: macos
@@ -249,7 +249,7 @@ pub mv struct Text: Control {
249
249
  return s
250
250
  }
251
251
 
252
- pub func set_frame = (ref self, int x, int y, int width, int height) {
252
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
253
253
  ```
254
254
  #arch: c
255
255
  #platform: macos
@@ -111,7 +111,7 @@ pub mv struct TextBox: Control {
111
111
  ```
112
112
  }
113
113
 
114
- pub func set_frame = (ref self, int x, int y, int width, int height) {
114
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
115
115
  ```
116
116
  #arch: c
117
117
  #platform: macos
@@ -116,7 +116,7 @@ pub mv struct TextView: Control {
116
116
  ```
117
117
  }
118
118
 
119
- pub func set_frame = (ref self, int x, int y, int width, int height) {
119
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
120
120
  ```
121
121
  #arch: c
122
122
  #platform: macos
@@ -109,7 +109,7 @@ pub mv struct Toggle: Control {
109
109
  ```
110
110
  }
111
111
 
112
- pub func set_frame = (ref self, int x, int y, int width, int height) {
112
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
113
113
  ```
114
114
  #arch: c
115
115
  #platform: macos
@@ -456,7 +456,7 @@ pub mv struct Toolbar: Control {
456
456
  // ── Control trait conformance ──
457
457
  // A toolbar is window chrome: the layout engine never frames it (AppKit
458
458
  // owns the layout rect and shrinks the contentView itself).
459
- pub func set_frame = (ref self, int x, int y, int width, int height) {
459
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
460
460
  // No-op: the NSWindow carries the toolbar's geometry.
461
461
  }
462
462
 
@@ -1190,7 +1190,7 @@ pub mv struct Window: Control {
1190
1190
  // frame where the content rect changed. The grid must outlive the run
1191
1191
  // (an app field — registration stores its address). Call from
1192
1192
  // App.start; also arms the resize delegate's target pair.
1193
- pub func set_content = (ref self, ref Container grid) {
1193
+ pub func set_content = (ref self {}, ref Container grid { aligns, cols, dirty, dirty_idx, gaps, grows, h_kinds, h_vals, handles, kinds, measured_count, mh, mw, pads, pars, prh, prw, prx, pry, rh, rw, rx, ry, shrinks, spans, w_kinds, w_vals }) {
1194
1194
  ```
1195
1195
  #arch: c
1196
1196
  #platform: macos
@@ -1307,6 +1307,12 @@ pub mv struct Window: Control {
1307
1307
  // FORCED: it bypasses the close_requested interception (the delegate's
1308
1308
  // windowShouldClose: sees nomen_close_forced and allows). Only the red
1309
1309
  // button routes through `close_requested`.
1310
+ //
1311
+ // The forced latch is one-shot: it is armed immediately before
1312
+ // performClose: (which dispatches windowShouldClose: synchronously) and
1313
+ // disarmed right after. Left armed it is process-global — every LATER
1314
+ // red-button close (another window, a later run loop) would silently
1315
+ // bypass App.close_requested forever.
1310
1316
  pub func close = (self) {
1311
1317
  ```
1312
1318
  #arch: c
@@ -1314,6 +1320,7 @@ pub mv struct Window: Control {
1314
1320
  extern int nomen_close_forced;
1315
1321
  nomen_close_forced = 1;
1316
1322
  ((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("performClose:"), (id)0);
1323
+ nomen_close_forced = 0;
1317
1324
  ```
1318
1325
  ```
1319
1326
  #arch: aarch64_use_c
@@ -1321,6 +1328,7 @@ pub mv struct Window: Control {
1321
1328
  extern int nomen_close_forced;
1322
1329
  nomen_close_forced = 1;
1323
1330
  ((void(*)(id, SEL, id))objc_msgSend)((id)self->handle, sel_registerName("performClose:"), (id)0);
1331
+ nomen_close_forced = 0;
1324
1332
  ```
1325
1333
  ```
1326
1334
  #arch: c
@@ -1345,7 +1353,7 @@ pub mv struct Window: Control {
1345
1353
  // a FrameEvents each frame.
1346
1354
  // The app is consumed: it is destroyed when the loop exits (controls
1347
1355
  // release, buffers free).
1348
- pub func run = (ref self, mv App app) {
1356
+ pub func run = (ref self {}, mv App app) {
1349
1357
  app.start(ref self)
1350
1358
  Container.arm_resize_delegate(self)
1351
1359
  self.arm_mouse_moves()
@@ -1432,7 +1440,7 @@ pub mv struct Window: Control {
1432
1440
  return s
1433
1441
  }
1434
1442
 
1435
- pub func set_frame = (ref self, int x, int y, int width, int height) {
1443
+ pub func set_frame = (ref self {}, int x, int y, int width, int height) {
1436
1444
  ```
1437
1445
  #arch: c
1438
1446
  #platform: macos
@@ -71,9 +71,13 @@ pub mv struct Fiber<T> : Spawnable<T> {
71
71
  // out of the instance (started; #destroy no-ops), return the handle.
72
72
  // While the fiber waits, it parks and frees its worker instead of
73
73
  // blocking it.
74
- pub func start = (ref self, mv out Task<T>) {
74
+ pub func start = (ref self {}, mv out Task<T>) {
75
75
  ```
76
76
  #arch: c
77
+ // Single-launch contract: a consumed construction (started) owns
78
+ // nothing — the handles below are zeroed, and writing the ref count
79
+ // through the null future would fault. Abort with the reason.
80
+ if (self->started) __nomen_spawn_double_start_abort();
77
81
  struct nomen_future *_f = (struct nomen_future *)self->future;
78
82
  _f->refs = self->nursery_futures ? 3 : 2;
79
83
  __nomen_fiber_spawn((struct nomen_closure *)self->task, _f);
@@ -83,7 +87,12 @@ pub mv struct Fiber<T> : Spawnable<T> {
83
87
  ```
84
88
  ```
85
89
  #arch: aarch64
86
- // x19 = self. f = self->future (#32); nursery_futures at #48.
90
+ // x19 = self. started at #40; f = self->future (#32); nursery_futures
91
+ // at #48. Single-launch contract first: a consumed construction has
92
+ // zeroed handles, and the ref-store below would write through null.
93
+ ldrb w9, [x19, #40]
94
+ cbnz w9, .Lnomen_fstart_double
95
+ // f = self->future (#32); nursery_futures at #48.
87
96
  ldr x0, [x19, #32]
88
97
  ldr x1, [x19, #48]
89
98
  mov w2, #2
@@ -103,6 +112,10 @@ pub mv struct Fiber<T> : Spawnable<T> {
103
112
  ldr x3, [x19, #32]
104
113
  bl ___nomen_nursery_track
105
114
  .Lnomen_fstart_notrack:
115
+ b .Lnomen_fstart_done
116
+ .Lnomen_fstart_double:
117
+ bl ___nomen_spawn_double_start_abort
118
+ .Lnomen_fstart_done:
106
119
  ```
107
120
  var t = Task<T>()
108
121
  t.result_slot = self.result_slot
@@ -122,7 +135,7 @@ pub mv struct Fiber<T> : Spawnable<T> {
122
135
  // The fiber is launched exactly like start, but the handle is dropped
123
136
  // immediately: the future's refs are released as the discarded Task is
124
137
  // reclaimed, and the fiber completes into the void — nothing joins it.
125
- pub func detach = (ref self) {
138
+ pub func detach = (ref self {}) {
126
139
  self.start()
127
140
  }
128
141
 
@@ -14,7 +14,7 @@ pub mv struct Graph<T>: Enumerable {
14
14
  var node_count = 0
15
15
  var edge_count = 0
16
16
 
17
- pub func add_node = (ref self, mv T value) {
17
+ pub func add_node = (ref self { head_edge, values }, mv T value) {
18
18
  var int idx = self.node_count
19
19
  self.values.grow(idx + 1)
20
20
  self.values.store(idx, value)
@@ -23,7 +23,7 @@ pub mv struct Graph<T>: Enumerable {
23
23
  self.node_count = self.node_count + 1
24
24
  }
25
25
 
26
- pub func add_edge = (ref self, int from, int to) {
26
+ pub func add_edge = (ref self { edge_next, edge_target, head_edge }, int from, int to) {
27
27
  var int e = self.edge_count
28
28
  self.edge_target.grow_int(e + 1)
29
29
  self.edge_target.store_int(e, to)
@@ -13,13 +13,15 @@ pub mv struct LinkedList<T>: Enumerable {
13
13
  var int head = -1
14
14
  var count = 0
15
15
 
16
- pub func add = (ref self, mv T value) {
16
+ pub func add = (ref self { nexts, prevs, values }, mv T value) {
17
17
  var int idx = self.count
18
18
  self.values.grow(idx + 1)
19
19
  // The value arrives owned (`mv T value`): move a value-struct element
20
- // into the fresh slot (the caller's storage zeroes, no deep copy);
21
- // strings keep the deep-copying store (their pair arrives by value).
22
- if T_IS_VALUE_STRUCT {
20
+ // that OWNS resources into the fresh slot (the caller's storage
21
+ // zeroes, no deep copy). A non-owning value struct is a legal bare
22
+ // argument, so it keeps the copying store; strings keep the
23
+ // deep-copying store too (their pair arrives by value).
24
+ if T_TAKES_OWNERSHIP {
23
25
  self.values.store_take(idx, value)
24
26
  } else {
25
27
  self.values.store(idx, value)
@@ -34,14 +36,14 @@ pub mv struct LinkedList<T>: Enumerable {
34
36
  }
35
37
  }
36
38
 
37
- pub func set_next = (ref self, int idx, int next) {
39
+ pub func set_next = (ref self { nexts, prevs }, int idx, int next) {
38
40
  self.nexts.store_int(idx, next)
39
41
  if next >= 0 && next < self.prevs.cap {
40
42
  self.prevs.store_int(next, idx)
41
43
  }
42
44
  }
43
45
 
44
- pub func set_previous = (ref self, int idx, int prev) {
46
+ pub func set_previous = (ref self { nexts, prevs }, int idx, int prev) {
45
47
  self.prevs.store_int(idx, prev)
46
48
  if prev >= 0 && prev < self.nexts.cap {
47
49
  self.nexts.store_int(prev, idx)
@@ -5,13 +5,16 @@ pub mv struct List<T>: Viewable {
5
5
  var length = 0
6
6
  var items = Buffer<T>()
7
7
 
8
- pub func push = (ref self, mv T value) {
8
+ pub func push = (ref self { items }, mv T value) {
9
9
  if self.length < self.items.cap {
10
10
  // The value arrives owned (`mv T value`): a value-struct element
11
- // moves into the fresh slot (store_take — the caller's storage
12
- // zeroes, no deep copy); strings and scalars keep the
13
- // deep-copying store.
14
- if T_IS_VALUE_STRUCT {
11
+ // that OWNS resources moves into the fresh slot (store_take — the
12
+ // caller's storage zeroes, no deep copy). A non-owning value
13
+ // struct (a handle pair) is a legal bare argument (the checker
14
+ // does not demand `mv`), so taking it would silently zero the
15
+ // caller's copy — it keeps the copying store, like strings and
16
+ // scalars.
17
+ if T_TAKES_OWNERSHIP {
15
18
  self.items.store_take(self.length, value)
16
19
  } else {
17
20
  self.items.store(self.length, value)
@@ -20,7 +23,7 @@ pub mv struct List<T>: Viewable {
20
23
  return
21
24
  }
22
25
  self.reserve(1)
23
- if T_IS_VALUE_STRUCT {
26
+ if T_TAKES_OWNERSHIP {
24
27
  self.items.store_take(self.length, value)
25
28
  } else {
26
29
  self.items.store(self.length, value)
@@ -38,7 +41,7 @@ pub mv struct List<T>: Viewable {
38
41
  // #4). Sound for extra=1 by the same proof as push's old inline growth:
39
42
  // length + 1 > cap grows to exactly the capacity push would have grown
40
43
  // to.
41
- internal func reserve = (ref self, int extra: extra >= 0, out int) {
44
+ internal func reserve = (ref self { items }, int extra: extra >= 0, out int) {
42
45
  if self.length + extra <= self.items.cap {
43
46
  return self.items.cap
44
47
  }
@@ -52,7 +55,7 @@ pub mv struct List<T>: Viewable {
52
55
  return self.items.cap
53
56
  }
54
57
 
55
- pub func pop = (ref self, mv out T) {
58
+ pub func pop = (ref self { items }, mv out T) {
56
59
  if self.length <= 0 {
57
60
  return self.items.move(0)
58
61
  }
@@ -91,7 +94,7 @@ pub mv struct List<T>: Viewable {
91
94
  return self.items.slice(start, end)
92
95
  }
93
96
 
94
- pub func set = (ref self, int i: i >= 0 && i < self.length, mv T value) {
97
+ pub func set = (ref self { items }, int i: i >= 0 && i < self.length, mv T value) {
95
98
  self.items.replace(i, value)
96
99
  }
97
100
 
@@ -99,7 +102,7 @@ pub mv struct List<T>: Viewable {
99
102
  // for indices that can't be proven at compile time (cross-module calls
100
103
  // can never discharge `set`'s parameter constraint) and out-of-range is
101
104
  // a bug, not a case.
102
- pub func set_or_panic = (ref self, int i, mv T value) {
105
+ pub func set_or_panic = (ref self { items }, int i, mv T value) {
103
106
  if i >= 0 && i < self.length {
104
107
  self.set(i, value)
105
108
  return
@@ -111,7 +114,7 @@ pub mv struct List<T>: Viewable {
111
114
  // lowering's destination primitive, the in-place push contract). reserve must have
112
115
  // run, so the slot exists. Offsets mirror the mono layout: length @8,
113
116
  // items.data @24 (the Buffer mono is {_vt, data, cap} = 24 bytes).
114
- internal func append_slot_ptr = (ref self, out ptr T) {
117
+ internal func append_slot_ptr = (ref self { items }, out ptr T) {
115
118
  ```
116
119
  #arch: c
117
120
  // Byte math + void* — the body must compile for EVERY element kind
@@ -139,7 +142,7 @@ pub mv struct List<T>: Viewable {
139
142
  // rules. The length constraint is the caller's proof obligation — the
140
143
  // handler desugar's synthesized loops satisfy it from the loop
141
144
  // condition, exactly like `.at`.
142
- internal func slot_ptr = (ref self, int i: i >= 0 && i < self.length, out ptr T) {
145
+ internal func slot_ptr = (ref self { items }, int i: i >= 0 && i < self.length, out ptr T) {
143
146
  return self.items.slot_ptr(i)
144
147
  }
145
148
 
@@ -150,7 +153,7 @@ pub mv struct List<T>: Viewable {
150
153
  // resources are reclaimed when the binding's scope ends — binding the
151
154
  // result in a nested block is the way to free an owning element at a
152
155
  // chosen point (its #destroy runs at the block's closing brace).
153
- pub func remove_at_or_panic = (ref self, int i, mv out T) {
156
+ pub func remove_at_or_panic = (ref self { items }, int i, mv out T) {
154
157
  if i < 0 || i >= self.length {
155
158
  panic("index out of range")
156
159
  }
@@ -39,7 +39,7 @@ pub mv struct Map<TK: Hashable + Equatable, TV> {
39
39
  }
40
40
  }
41
41
 
42
- pub func set = (ref self, mv TK key, mv TV value) {
42
+ pub func set = (ref self { hashes, keys, used, values }, mv TK key, mv TV value) {
43
43
  var int cap = self.keys.cap
44
44
  if cap == 0 {
45
45
  // alloc_T: for Buffer<TK> it is T_SIZE-aware (string keys are
@@ -59,15 +59,17 @@ pub mv struct Map<TK: Hashable + Equatable, TV> {
59
59
  if self.used.load_u32(idx) == 0 {
60
60
  self.used.store_u32(idx, 1)
61
61
  // Both arrive owned (`mv TK key, mv TV value`): a value-struct
62
- // key/value moves into its fresh slot (the caller's storage
63
- // zeroes, no deep copy); strings keep the deep-copying store
64
- // (their pair arrives by value).
65
- if TK_IS_VALUE_STRUCT {
62
+ // key/value that OWNS resources moves into its fresh slot
63
+ // (store_take — the caller's storage zeroes, no deep copy). A
64
+ // non-owning value struct is a legal bare argument and keeps the
65
+ // copying store; strings keep the deep-copying store too (their
66
+ // pair arrives by value).
67
+ if TK_TAKES_OWNERSHIP {
66
68
  self.keys.store_take(idx, key)
67
69
  } else {
68
70
  self.keys.store(idx, key)
69
71
  }
70
- if TV_IS_VALUE_STRUCT {
72
+ if TV_TAKES_OWNERSHIP {
71
73
  self.values.store_take(idx, value)
72
74
  } else {
73
75
  self.values.store(idx, value)
@@ -92,7 +94,7 @@ pub mv struct Map<TK: Hashable + Equatable, TV> {
92
94
  // primitive: the raw pointer must not cross the library boundary, and
93
95
  // the caller must overwrite the slot before it is read or destroyed
94
96
  // again (both paths leave it owning nothing).
95
- internal func set_slot_ptr = (ref self, TK key, out ptr TV) {
97
+ internal func set_slot_ptr = (ref self { hashes, keys, used, values }, TK key, out ptr TV) {
96
98
  var int cap = self.keys.cap
97
99
  if cap == 0 {
98
100
  // alloc_T: for Buffer<TK> it is T_SIZE-aware (string keys are
@@ -195,7 +197,7 @@ pub mv struct Map<TK: Hashable + Equatable, TV> {
195
197
  return self.used.load_u32(idx) != 0
196
198
  }
197
199
 
198
- pub func remove = (ref self, TK key) {
200
+ pub func remove = (ref self { hashes, keys, used, values }, TK key) {
199
201
  var int cap = self.keys.cap
200
202
  if cap == 0 {
201
203
  return
@@ -330,7 +332,7 @@ pub mv struct Map<TK: Hashable + Equatable, TV> {
330
332
  // the other half of the Swiss-table trick; the old form re-inserted via
331
333
  // `self.set(mv k, mv v)`, re-hashing every key and re-comparing keys on
332
334
  // every probed slot.
333
- func rehash = (ref self, int new_cap) {
335
+ func rehash = (ref self { hashes, keys, used, values }, int new_cap) {
334
336
  var Buffer<TK> old_keys = mv self.keys swap Buffer<TK>()
335
337
  var Buffer<TV> old_values = mv self.values swap Buffer<TV>()
336
338
  var Buffer<int> old_used = mv self.used swap Buffer<int>()
@@ -44,7 +44,7 @@ pub mv struct Random {
44
44
  // operators, and hex literals all lower directly; the aarch64 64-bit
45
45
  // arithmetic folds (PERF_PLAN item 15) keep the emission within a few
46
46
  // instructions of a hand-written `#arch` body.
47
- pub func next = (ref self, out uint64) {
47
+ pub func next = (ref self {}, out uint64) {
48
48
  self.state = self.state + 0x9E3779B97F4A7C15
49
49
  var uint64 z = self.state
50
50
  z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9
@@ -54,7 +54,7 @@ pub mv struct Random {
54
54
 
55
55
  // The next value in [0, bound). A bound of 0 returns 0. Slight modulo
56
56
  // bias for very large bounds — irrelevant at demo scale.
57
- pub func below = (ref self, uint64 bound, out uint64) {
57
+ pub func below = (ref self {}, uint64 bound, out uint64) {
58
58
  if bound == 0 {
59
59
  return 0
60
60
  }
@@ -63,7 +63,7 @@ pub mv struct Random {
63
63
 
64
64
  // The next value in [lo, hi], both ends inclusive. A hi <= lo
65
65
  // returns lo.
66
- pub func range = (ref self, uint64 lo, uint64 hi, out uint64) {
66
+ pub func range = (ref self {}, uint64 lo, uint64 hi, out uint64) {
67
67
  if hi <= lo {
68
68
  return lo
69
69
  }
@@ -20,7 +20,7 @@ pub mv struct Set<T: Hashable + Equatable> {
20
20
  var used = Buffer<int>()
21
21
  var hashes = Buffer<int>()
22
22
 
23
- pub func add = (ref self, mv T value) {
23
+ pub func add = (ref self { hashes, slots, used }, mv T value) {
24
24
  var int cap = self.slots.cap
25
25
  if cap == 0 {
26
26
  cap = self.slots.alloc(8)
@@ -37,10 +37,12 @@ pub mv struct Set<T: Hashable + Equatable> {
37
37
  self.used.store_u32(idx, 1)
38
38
  // The value arrives owned (`mv T value`): a value-struct element
39
39
  // moves into the fresh slot (store_take — the caller's storage is
40
- // zeroed, no deep copy); a string's by-value pair keeps the
41
- // deep-copying store (the caller still owns its buffer), and a
42
- // class/trait handle is a pointer store either way.
43
- if T_IS_VALUE_STRUCT {
40
+ // zeroed, no deep copy) when it OWNS resources; a non-owning value
41
+ // struct is a legal bare argument and keeps the copying store, a
42
+ // string's by-value pair keeps the deep-copying store (the caller
43
+ // still owns its buffer), and a class/trait handle is a pointer
44
+ // store either way.
45
+ if T_TAKES_OWNERSHIP {
44
46
  self.slots.store_take(idx, value)
45
47
  } else {
46
48
  self.slots.store(idx, value)
@@ -98,7 +100,7 @@ pub mv struct Set<T: Hashable + Equatable> {
98
100
  return self.slots.load(idx)
99
101
  }
100
102
 
101
- pub func remove = (ref self, T value) {
103
+ pub func remove = (ref self { hashes, slots, used }, T value) {
102
104
  var int cap = self.slots.cap
103
105
  if cap == 0 {
104
106
  return
@@ -222,7 +224,7 @@ pub mv struct Set<T: Hashable + Equatable> {
222
224
  // compares (values arrive unique — they came from a valid set). The old
223
225
  // form re-inserted via `self.add(mv v)`, re-hashing every value and
224
226
  // re-comparing values on every probed slot.
225
- func rehash = (ref self, int new_cap) {
227
+ func rehash = (ref self { hashes, slots, used }, int new_cap) {
226
228
  var Buffer<T> old_slots = mv self.slots swap Buffer<T>()
227
229
  var Buffer<int> old_used = mv self.used swap Buffer<int>()
228
230
  var Buffer<int> old_hashes = mv self.hashes swap Buffer<int>()
@@ -40,7 +40,7 @@ pub mv struct StableList<T> {
40
40
  // slab is always null, so its field destroy reclaims nothing.
41
41
  var stage = Buffer<T>()
42
42
 
43
- pub func push = (ref self, mv T value) {
43
+ pub func push = (ref self { chunks, items, stage }, mv T value) {
44
44
  if self.items.cap == 0 {
45
45
  self.items.alloc(256)
46
46
  }
@@ -75,7 +75,7 @@ pub mv struct StableList<T> {
75
75
  // and constructs the callee's result directly into the append slot
76
76
  // (the in-place push contract). Byte-identical policy for extra=1: the same
77
77
  // alloc/dir-grow/first-touch sequence push's inline branches performed.
78
- internal func reserve = (ref self, int extra: extra >= 0, out int) {
78
+ internal func reserve = (ref self { chunks, items, stage }, int extra: extra >= 0, out int) {
79
79
  if self.items.cap == 0 {
80
80
  self.items.alloc(256)
81
81
  }
@@ -93,7 +93,7 @@ pub mv struct StableList<T> {
93
93
  // Calloc the directory chunk's slab on first touch (zero words mark
94
94
  // empty chunks) — push's tail store and the in-place append both rely on
95
95
  // the slab existing before a slot address is taken from it.
96
- internal func ensure_chunk = (ref self, int dir_index) {
96
+ internal func ensure_chunk = (ref self { chunks, items, stage }, int dir_index) {
97
97
  ```
98
98
  #arch: c
99
99
  if (((unsigned long long*)self->chunks.data)[dir_index] == 0) {
@@ -130,7 +130,7 @@ pub mv struct StableList<T> {
130
130
  // call's result straight through this address (sole ownership transfers
131
131
  // into the slot — the chunk slab is calloc'd on first touch by
132
132
  // `reserve`'s `ensure_chunk` before the slot address is taken).
133
- internal func append_slot_ptr = (ref self, out ptr T) {
133
+ internal func append_slot_ptr = (ref self { chunks, items, stage }, out ptr T) {
134
134
  ```
135
135
  #arch: c
136
136
  unsigned long long idx = (unsigned long long)self->length;
@@ -236,7 +236,7 @@ pub mv struct StableList<T> {
236
236
  // invalidation for this type, so the alias stays live and writes through
237
237
  // it land in the list. The length constraint is the caller's proof
238
238
  // obligation, exactly like `.at`.
239
- internal func slot_ptr = (ref self, int i: i >= 0 && i < self.length, out ptr T) {
239
+ internal func slot_ptr = (ref self { items }, int i: i >= 0 && i < self.length, out ptr T) {
240
240
  if i < self.items.cap {
241
241
  return self.items.slot_ptr(i)
242
242
  }
@@ -303,13 +303,13 @@ pub mv struct StableList<T> {
303
303
  // nothing.
304
304
  // (The old `stage` relay field is gone — push's tail path stores into
305
305
  // the chunk through a `Buffer.init_view` view.)
306
- func #destroy = (ref self) {
306
+ func #destroy = (ref self { chunks, items, stage }) {
307
307
  self.destroy_tails()
308
308
  }
309
309
 
310
310
  // Raw: destroy directory chunks 1.. — per chunk, `filled` slots + the
311
311
  // slab, via `T_buffer_destroy` on a cap=filled view.
312
- internal func destroy_tails = (ref self) {
312
+ internal func destroy_tails = (ref self { chunks, items, stage }) {
313
313
  ```
314
314
  #arch: c
315
315
  long n_dir = (self->length - 1L) / 256L;