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.
- package/core/System/Arena.nm +9 -7
- package/core/System/Array.nm +1 -1
- package/core/System/Atomic.nm +3 -3
- package/core/System/BigInt.nm +182 -23
- package/core/System/Buffer.nm +37 -35
- package/core/System/ClassBuffer.nm +18 -18
- package/core/System/Controls/Alert.nm +1 -1
- package/core/System/Controls/App.nm +5 -5
- package/core/System/Controls/Button.nm +1 -1
- package/core/System/Controls/CheckBox.nm +1 -1
- package/core/System/Controls/ColorPicker.nm +1 -1
- package/core/System/Controls/ComboBox.nm +1 -1
- package/core/System/Controls/Container.nm +34 -34
- package/core/System/Controls/DatePicker.nm +1 -1
- package/core/System/Controls/Form.nm +2 -2
- package/core/System/Controls/GroupBox.nm +1 -1
- package/core/System/Controls/ImageView.nm +1 -1
- package/core/System/Controls/Layout.nm +5 -5
- package/core/System/Controls/LevelIndicator.nm +1 -1
- package/core/System/Controls/ListView.nm +1 -1
- package/core/System/Controls/Menu.nm +1 -1
- package/core/System/Controls/NumberInput.nm +3 -3
- package/core/System/Controls/OtpInput.nm +2 -2
- package/core/System/Controls/OutlineView.nm +1 -1
- package/core/System/Controls/Pagination.nm +6 -6
- package/core/System/Controls/Popover.nm +1 -1
- package/core/System/Controls/Progress.nm +1 -1
- package/core/System/Controls/Radio.nm +1 -1
- package/core/System/Controls/Scrollable.nm +1 -1
- package/core/System/Controls/SearchField.nm +1 -1
- package/core/System/Controls/SecureField.nm +1 -1
- package/core/System/Controls/Segmented.nm +1 -1
- package/core/System/Controls/Select.nm +1 -1
- package/core/System/Controls/Separator.nm +1 -1
- package/core/System/Controls/Sheet.nm +1 -1
- package/core/System/Controls/Slider.nm +1 -1
- package/core/System/Controls/Spinner.nm +3 -3
- package/core/System/Controls/SplitView.nm +2 -2
- package/core/System/Controls/Stepper.nm +1 -1
- package/core/System/Controls/Switch.nm +1 -1
- package/core/System/Controls/Table.nm +1 -1
- package/core/System/Controls/Tabs.nm +1 -1
- package/core/System/Controls/Text.nm +1 -1
- package/core/System/Controls/TextBox.nm +1 -1
- package/core/System/Controls/TextView.nm +1 -1
- package/core/System/Controls/Toggle.nm +1 -1
- package/core/System/Controls/Toolbar.nm +1 -1
- package/core/System/Controls/Window.nm +11 -3
- package/core/System/Fiber.nm +16 -3
- package/core/System/Graph.nm +2 -2
- package/core/System/LinkedList.nm +8 -6
- package/core/System/List.nm +16 -13
- package/core/System/Map.nm +11 -9
- package/core/System/Random.nm +3 -3
- package/core/System/Set.nm +9 -7
- package/core/System/StableList.nm +7 -7
- package/core/System/Stream/File.nm +16 -16
- package/core/System/Stream/Http.nm +3 -3
- package/core/System/Stream/Tcp.nm +5 -5
- package/core/System/StringBuilder.nm +16 -16
- package/core/System/Task.nm +56 -64
- package/core/System/Test.nm +18 -18
- package/core/System/Text/Chars.nm +1 -1
- package/core/System/Text/Json.nm +12 -12
- package/core/System/Text/JsonTree.nm +8 -8
- package/core/System/Text/Regex.nm +20 -20
- package/core/System/Thread.nm +26 -3
- package/core/System/Tree.nm +19 -3
- package/dist/index.mjs +3036 -1845
- package/package.json +1 -1
package/core/System/Test.nm
CHANGED
|
@@ -96,7 +96,7 @@ pub mv struct Tester {
|
|
|
96
96
|
|
|
97
97
|
// (harness) Start timing `name` and clear the per-test state. Called by
|
|
98
98
|
// the `main` that `nomen test` generates — not by test code.
|
|
99
|
-
pub func begin_test = (ref self, string name) {
|
|
99
|
+
pub func begin_test = (ref self { current }, string name) {
|
|
100
100
|
self.has_failed = false
|
|
101
101
|
self.passed = 0
|
|
102
102
|
self.failed = 0
|
|
@@ -106,7 +106,7 @@ pub mv struct Tester {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// (harness) Close the current test and emit its `done` record.
|
|
109
|
-
pub func end_test = (ref self) {
|
|
109
|
+
pub func end_test = (ref self {}) {
|
|
110
110
|
const uint64 elapsed = Time.now_ns() - self.started
|
|
111
111
|
Console.write_line(
|
|
112
112
|
"\\nomen|done|" + self.current + "|\{self.passed}|\{self.failed}|\{elapsed}",
|
|
@@ -124,7 +124,7 @@ pub mv struct Tester {
|
|
|
124
124
|
*
|
|
125
125
|
* t.expect(result == 2, "add(1, 1) should be 2")
|
|
126
126
|
**/
|
|
127
|
-
pub func expect = (ref self, bool condition, string message) {
|
|
127
|
+
pub func expect = (ref self {}, bool condition, string message) {
|
|
128
128
|
if self.has_failed {
|
|
129
129
|
return
|
|
130
130
|
}
|
|
@@ -143,7 +143,7 @@ pub mv struct Tester {
|
|
|
143
143
|
* t.fail("expected to find the key")
|
|
144
144
|
* }
|
|
145
145
|
**/
|
|
146
|
-
pub func fail = (ref self, string message) {
|
|
146
|
+
pub func fail = (ref self {}, string message) {
|
|
147
147
|
if self.has_failed {
|
|
148
148
|
return
|
|
149
149
|
}
|
|
@@ -154,43 +154,43 @@ pub mv struct Tester {
|
|
|
154
154
|
//
|
|
155
155
|
// Nomen has no generic methods, so there is one overload per nullable
|
|
156
156
|
// type the compiler can compare against `null`.
|
|
157
|
-
pub func assert = (ref self, int? value, string message) {
|
|
157
|
+
pub func assert = (ref self {}, int? value, string message) {
|
|
158
158
|
self.expect(value != null, message)
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
pub func assert = (ref self, uint? value, string message) {
|
|
161
|
+
pub func assert = (ref self {}, uint? value, string message) {
|
|
162
162
|
self.expect(value != null, message)
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
pub func assert = (ref self, int64? value, string message) {
|
|
165
|
+
pub func assert = (ref self {}, int64? value, string message) {
|
|
166
166
|
self.expect(value != null, message)
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
pub func assert = (ref self, uint64? value, string message) {
|
|
169
|
+
pub func assert = (ref self {}, uint64? value, string message) {
|
|
170
170
|
self.expect(value != null, message)
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
pub func assert = (ref self, int8? value, string message) {
|
|
173
|
+
pub func assert = (ref self {}, int8? value, string message) {
|
|
174
174
|
self.expect(value != null, message)
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
pub func assert = (ref self, uint8? value, string message) {
|
|
177
|
+
pub func assert = (ref self {}, uint8? value, string message) {
|
|
178
178
|
self.expect(value != null, message)
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
pub func assert = (ref self, float? value, string message) {
|
|
181
|
+
pub func assert = (ref self {}, float? value, string message) {
|
|
182
182
|
self.expect(value != null, message)
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
pub func assert = (ref self, bool? value, string message) {
|
|
185
|
+
pub func assert = (ref self {}, bool? value, string message) {
|
|
186
186
|
self.expect(value != null, message)
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
pub func assert = (ref self, char? value, string message) {
|
|
189
|
+
pub func assert = (ref self {}, char? value, string message) {
|
|
190
190
|
self.expect(value != null, message)
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
pub func assert = (ref self, string? value, string message) {
|
|
193
|
+
pub func assert = (ref self {}, string? value, string message) {
|
|
194
194
|
self.expect(value != null, message)
|
|
195
195
|
}
|
|
196
196
|
|
|
@@ -212,7 +212,7 @@ pub mv struct Tester {
|
|
|
212
212
|
* (default 1000, override with `bench_n`) and computes min / median /
|
|
213
213
|
* mean / max / stddev over the per-iteration durations.
|
|
214
214
|
**/
|
|
215
|
-
pub func bench = (ref self, string label, func() body) {
|
|
215
|
+
pub func bench = (ref self { bench_label }, string label, func() body) {
|
|
216
216
|
if self.has_failed {
|
|
217
217
|
return
|
|
218
218
|
}
|
|
@@ -226,7 +226,7 @@ pub mv struct Tester {
|
|
|
226
226
|
* for slow functions (where the default 1000 would dominate the suite) or
|
|
227
227
|
* for reproducible sample counts.
|
|
228
228
|
**/
|
|
229
|
-
pub func bench_n = (ref self, string label, func() body, int samples) {
|
|
229
|
+
pub func bench_n = (ref self { bench_label }, string label, func() body, int samples) {
|
|
230
230
|
if self.has_failed {
|
|
231
231
|
return
|
|
232
232
|
}
|
|
@@ -244,7 +244,7 @@ pub mv struct Tester {
|
|
|
244
244
|
* this is a no-op.
|
|
245
245
|
**/
|
|
246
246
|
pub func record_bench = (
|
|
247
|
-
ref self,
|
|
247
|
+
ref self {},
|
|
248
248
|
string label,
|
|
249
249
|
int n,
|
|
250
250
|
int min,
|
|
@@ -263,7 +263,7 @@ pub mv struct Tester {
|
|
|
263
263
|
)
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
func record_failure = (ref self, string message) {
|
|
266
|
+
func record_failure = (ref self {}, string message) {
|
|
267
267
|
self.failed += 1
|
|
268
268
|
self.total_failed += 1
|
|
269
269
|
self.has_failed = true
|
|
@@ -21,7 +21,7 @@ pub struct Chars {
|
|
|
21
21
|
|
|
22
22
|
// The code point at the cursor, advancing past it. Malformed sequences
|
|
23
23
|
// yield U+FFFD. Panics when exhausted — check has_next first.
|
|
24
|
-
pub func next = (ref self, out int) {
|
|
24
|
+
pub func next = (ref self {}, out int) {
|
|
25
25
|
if self.byte_pos >= self.source.length {
|
|
26
26
|
panic("Chars exhausted; check has_next first")
|
|
27
27
|
}
|
package/core/System/Text/Json.nm
CHANGED
|
@@ -102,7 +102,7 @@ pub struct Json {
|
|
|
102
102
|
|
|
103
103
|
// Parse a JSON document into tree. The caller provides a JsonTree pool
|
|
104
104
|
// which is reset and filled. Returns the index of the root node.
|
|
105
|
-
pub func parse = (string s, ref JsonTree tree, out int) {
|
|
105
|
+
pub func parse = (string s, ref JsonTree tree { nodes }, out int) {
|
|
106
106
|
tree.reset()
|
|
107
107
|
var pos = Buffer<int>()
|
|
108
108
|
pos.alloc_int(1)
|
|
@@ -112,14 +112,14 @@ pub struct Json {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
// Serialize a node in the tree back to a JSON string.
|
|
115
|
-
pub func stringify = (ref JsonTree tree, int root, out string) {
|
|
115
|
+
pub func stringify = (ref JsonTree tree { nodes }, int root, out string) {
|
|
116
116
|
var sb = StringBuilder()
|
|
117
117
|
json_ser_value(ref tree, root, ref sb)
|
|
118
118
|
return sb.to_string()
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
func json_skip_ws = (string s, ref Buffer<int> pos, int len) {
|
|
122
|
+
func json_skip_ws = (string s, ref Buffer<int> pos {}, int len) {
|
|
123
123
|
while pos.load_int(0) < len {
|
|
124
124
|
var int i = pos.load_int(0)
|
|
125
125
|
var int code = s.at(i) as int
|
|
@@ -131,7 +131,7 @@ func json_skip_ws = (string s, ref Buffer<int> pos, int len) {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
func json_parse_string = (string s, ref Buffer<int> pos, int len, ref JsonTree tree, out int) {
|
|
134
|
+
func json_parse_string = (string s, ref Buffer<int> pos {}, int len, ref JsonTree tree { nodes }, out int) {
|
|
135
135
|
var int i = pos.load_int(0)
|
|
136
136
|
i += 1
|
|
137
137
|
var sb = StringBuilder()
|
|
@@ -193,7 +193,7 @@ func json_parse_string = (string s, ref Buffer<int> pos, int len, ref JsonTree t
|
|
|
193
193
|
return n
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
func json_parse_number = (string s, ref Buffer<int> pos, int len, ref JsonTree tree, out int) {
|
|
196
|
+
func json_parse_number = (string s, ref Buffer<int> pos {}, int len, ref JsonTree tree { nodes }, out int) {
|
|
197
197
|
var int i = pos.load_int(0)
|
|
198
198
|
var int start = i
|
|
199
199
|
while i < len {
|
|
@@ -215,7 +215,7 @@ func json_parse_number = (string s, ref Buffer<int> pos, int len, ref JsonTree t
|
|
|
215
215
|
return n
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
func json_parse_literal = (string s, ref Buffer<int> pos, int len, ref JsonTree tree, out int) {
|
|
218
|
+
func json_parse_literal = (string s, ref Buffer<int> pos {}, int len, ref JsonTree tree { nodes }, out int) {
|
|
219
219
|
var int i = pos.load_int(0)
|
|
220
220
|
var int code = s.at(i) as int
|
|
221
221
|
var int n = tree.alloc_node()
|
|
@@ -237,7 +237,7 @@ func json_parse_literal = (string s, ref Buffer<int> pos, int len, ref JsonTree
|
|
|
237
237
|
return n
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
func json_parse_value = (string s, ref Buffer<int> pos, int len, ref JsonTree tree, out int) {
|
|
240
|
+
func json_parse_value = (string s, ref Buffer<int> pos {}, int len, ref JsonTree tree { nodes }, out int) {
|
|
241
241
|
json_skip_ws(s, ref pos, len)
|
|
242
242
|
var int i = pos.load_int(0)
|
|
243
243
|
if i >= len {
|
|
@@ -267,7 +267,7 @@ func json_parse_value = (string s, ref Buffer<int> pos, int len, ref JsonTree tr
|
|
|
267
267
|
return json_parse_number(s, ref pos, len, ref tree)
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
func json_parse_elements = (string s, ref Buffer<int> pos, int len, ref JsonTree tree, out int) {
|
|
270
|
+
func json_parse_elements = (string s, ref Buffer<int> pos {}, int len, ref JsonTree tree { nodes }, out int) {
|
|
271
271
|
json_skip_ws(s, ref pos, len)
|
|
272
272
|
var int i = pos.load_int(0)
|
|
273
273
|
if i >= len {
|
|
@@ -289,7 +289,7 @@ func json_parse_elements = (string s, ref Buffer<int> pos, int len, ref JsonTree
|
|
|
289
289
|
return elem
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
func json_parse_pairs = (string s, ref Buffer<int> pos, int len, ref JsonTree tree, out int) {
|
|
292
|
+
func json_parse_pairs = (string s, ref Buffer<int> pos {}, int len, ref JsonTree tree { nodes }, out int) {
|
|
293
293
|
json_skip_ws(s, ref pos, len)
|
|
294
294
|
var int i = pos.load_int(0)
|
|
295
295
|
if i >= len {
|
|
@@ -321,7 +321,7 @@ func json_parse_pairs = (string s, ref Buffer<int> pos, int len, ref JsonTree tr
|
|
|
321
321
|
return key
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
func json_ser_list = (ref JsonTree tree, int first, ref StringBuilder sb) {
|
|
324
|
+
func json_ser_list = (ref JsonTree tree { nodes }, int first, ref StringBuilder sb {}) {
|
|
325
325
|
json_ser_value(ref tree, first, ref sb)
|
|
326
326
|
var int next = tree.get_next(first)
|
|
327
327
|
if next >= 0 {
|
|
@@ -330,7 +330,7 @@ func json_ser_list = (ref JsonTree tree, int first, ref StringBuilder sb) {
|
|
|
330
330
|
}
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
-
func json_ser_pairs = (ref JsonTree tree, int first, ref StringBuilder sb) {
|
|
333
|
+
func json_ser_pairs = (ref JsonTree tree { nodes }, int first, ref StringBuilder sb {}) {
|
|
334
334
|
sb.append_char('"')
|
|
335
335
|
sb.append_string_view(tree.get_text_view(first))
|
|
336
336
|
sb.append_string("\":")
|
|
@@ -347,7 +347,7 @@ func json_ser_pairs = (ref JsonTree tree, int first, ref StringBuilder sb) {
|
|
|
347
347
|
}
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
-
func json_ser_value = (ref JsonTree tree, int n, ref StringBuilder sb) {
|
|
350
|
+
func json_ser_value = (ref JsonTree tree { nodes }, int n, ref StringBuilder sb {}) {
|
|
351
351
|
var int k = tree.get_kind(n)
|
|
352
352
|
if k == 0 {
|
|
353
353
|
sb.append_string("null")
|
|
@@ -37,7 +37,7 @@ pub mv struct JsonTree {
|
|
|
37
37
|
var nodes = StableList<JsonNode>()
|
|
38
38
|
|
|
39
39
|
// Append a fresh node and return its index.
|
|
40
|
-
func alloc_node = (ref self, out int) {
|
|
40
|
+
func alloc_node = (ref self { nodes }, out int) {
|
|
41
41
|
self.nodes.push(JsonNode())
|
|
42
42
|
return self.nodes.length - 1
|
|
43
43
|
}
|
|
@@ -45,7 +45,7 @@ pub mv struct JsonTree {
|
|
|
45
45
|
// Drop the current document: the fresh StableList displaces the old one,
|
|
46
46
|
// whose destroy frees every node (texts included) and its slabs. The
|
|
47
47
|
// next parse starts from a clean pool.
|
|
48
|
-
func reset = (ref self) {
|
|
48
|
+
func reset = (ref self { nodes }) {
|
|
49
49
|
self.nodes = StableList<JsonNode>()
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -58,7 +58,7 @@ pub mv struct JsonTree {
|
|
|
58
58
|
// once, by the list's destroy or the next text store. For strings
|
|
59
59
|
// produced by a StringBuilder, `take_text` installs the builder's
|
|
60
60
|
// buffer with no copy at all.
|
|
61
|
-
func set_text = (ref self, int idx, mv string text) {
|
|
61
|
+
func set_text = (ref self {}, int idx, mv string text) {
|
|
62
62
|
if idx < 0 || idx >= self.nodes.length {
|
|
63
63
|
panic("index out of range")
|
|
64
64
|
}
|
|
@@ -75,7 +75,7 @@ pub mv struct JsonTree {
|
|
|
75
75
|
// temp free. (A `mv string` parameter cannot do this: the string-arg
|
|
76
76
|
// ownership convention makes mv string arguments caller-owned
|
|
77
77
|
// borrows, forcing the callee-side copy this method exists to skip.)
|
|
78
|
-
func take_text = (ref self, int idx, ref StringBuilder sb) {
|
|
78
|
+
func take_text = (ref self {}, int idx, ref StringBuilder sb {}) {
|
|
79
79
|
if idx < 0 || idx >= self.nodes.length {
|
|
80
80
|
panic("index out of range")
|
|
81
81
|
}
|
|
@@ -83,7 +83,7 @@ pub mv struct JsonTree {
|
|
|
83
83
|
n.text = sb.to_string()
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
func set_kind = (ref self, int idx, int val) {
|
|
86
|
+
func set_kind = (ref self {}, int idx, int val) {
|
|
87
87
|
if idx < 0 || idx >= self.nodes.length {
|
|
88
88
|
panic("index out of range")
|
|
89
89
|
}
|
|
@@ -91,7 +91,7 @@ pub mv struct JsonTree {
|
|
|
91
91
|
n.kind = val
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
func set_child = (ref self, int idx, int val) {
|
|
94
|
+
func set_child = (ref self {}, int idx, int val) {
|
|
95
95
|
if idx < 0 || idx >= self.nodes.length {
|
|
96
96
|
panic("index out of range")
|
|
97
97
|
}
|
|
@@ -99,7 +99,7 @@ pub mv struct JsonTree {
|
|
|
99
99
|
n.child = val
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
func set_next = (ref self, int idx, int val) {
|
|
102
|
+
func set_next = (ref self {}, int idx, int val) {
|
|
103
103
|
if idx < 0 || idx >= self.nodes.length {
|
|
104
104
|
panic("index out of range")
|
|
105
105
|
}
|
|
@@ -107,7 +107,7 @@ pub mv struct JsonTree {
|
|
|
107
107
|
n.next = val
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
func set_val = (ref self, int idx, int val) {
|
|
110
|
+
func set_val = (ref self {}, int idx, int val) {
|
|
111
111
|
if idx < 0 || idx >= self.nodes.length {
|
|
112
112
|
panic("index out of range")
|
|
113
113
|
}
|
|
@@ -69,7 +69,7 @@ pub struct Regex {
|
|
|
69
69
|
pub func captures = (
|
|
70
70
|
string pattern,
|
|
71
71
|
string input,
|
|
72
|
-
ref List<string> dst,
|
|
72
|
+
ref List<string> dst { items },
|
|
73
73
|
out bool
|
|
74
74
|
) { var int pat_len = pattern.length
|
|
75
75
|
var int len = input.length
|
|
@@ -117,7 +117,7 @@ pub struct Regex {
|
|
|
117
117
|
// first, so a reused RegexMatch carries nothing over. Scans every
|
|
118
118
|
// position: the first-byte prefilter would skip nullable patterns'
|
|
119
119
|
// empty matches at skipped positions, reporting a wrong .start.
|
|
120
|
-
pub func find = (string pattern, string input, ref RegexMatch dst) {
|
|
120
|
+
pub func find = (string pattern, string input, ref RegexMatch dst { text }) {
|
|
121
121
|
dst.found = false
|
|
122
122
|
dst.start = 0
|
|
123
123
|
dst.end = 0
|
|
@@ -232,13 +232,13 @@ pub struct Regex {
|
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
// find, ignoring ASCII case.
|
|
235
|
-
pub func find_ci = (string pattern, string input, ref RegexMatch dst) {
|
|
235
|
+
pub func find_ci = (string pattern, string input, ref RegexMatch dst { text }) {
|
|
236
236
|
var string folded = fold_pattern(pattern)
|
|
237
237
|
Regex.find(folded, input, ref dst)
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
// captures, ignoring ASCII case.
|
|
241
|
-
pub func captures_ci = (string pattern, string input, ref List<string> dst, out bool) {
|
|
241
|
+
pub func captures_ci = (string pattern, string input, ref List<string> dst { items }, out bool) {
|
|
242
242
|
var string folded = fold_pattern(pattern)
|
|
243
243
|
return Regex.captures(folded, input, ref dst)
|
|
244
244
|
}
|
|
@@ -308,7 +308,7 @@ func fold_pattern = (string pattern, mv out string) {
|
|
|
308
308
|
|
|
309
309
|
// fold a character class [cs..ce): copy its contents, adding the case
|
|
310
310
|
// counterpart of every letter member and mirroring letter ranges.
|
|
311
|
-
func fold_class = (string pattern, int cs, int ce, ref StringBuilder dst) {
|
|
311
|
+
func fold_class = (string pattern, int cs, int ce, ref StringBuilder dst {}) {
|
|
312
312
|
dst.append_char('[')
|
|
313
313
|
var int i = cs + 1
|
|
314
314
|
if i < ce - 1 {
|
|
@@ -435,7 +435,7 @@ func collect_first_bytes = (
|
|
|
435
435
|
string pattern,
|
|
436
436
|
int pat_pos,
|
|
437
437
|
int pat_end,
|
|
438
|
-
ref StringBuilder sb,
|
|
438
|
+
ref StringBuilder sb {},
|
|
439
439
|
out int
|
|
440
440
|
) {
|
|
441
441
|
var depth = 0
|
|
@@ -482,7 +482,7 @@ func collect_first_bytes = (
|
|
|
482
482
|
// atom — literal, escaped, class, or group — quantified with '?'/'*' is
|
|
483
483
|
// nullable: what FOLLOWS it can also be first, so the scan continues past it.
|
|
484
484
|
// A wildcard '.' or an empty alternative makes the set indeterminable.
|
|
485
|
-
func alt_first_bytes = (string pattern, int start, int end, ref StringBuilder sb, out int) {
|
|
485
|
+
func alt_first_bytes = (string pattern, int start, int end, ref StringBuilder sb {}, out int) {
|
|
486
486
|
var int i = start
|
|
487
487
|
while i < end {
|
|
488
488
|
var char c = pattern.at(i)
|
|
@@ -722,7 +722,7 @@ func add_class_chars = (
|
|
|
722
722
|
string pattern,
|
|
723
723
|
int start,
|
|
724
724
|
int end,
|
|
725
|
-
ref StringBuilder sb
|
|
725
|
+
ref StringBuilder sb {}
|
|
726
726
|
) { var int cs = start
|
|
727
727
|
if cs < end {
|
|
728
728
|
if pattern.at(cs) == '^' {
|
|
@@ -777,7 +777,7 @@ func match_here = (
|
|
|
777
777
|
string input,
|
|
778
778
|
int in_pos,
|
|
779
779
|
int in_len,
|
|
780
|
-
ref List<int> caps,
|
|
780
|
+
ref List<int> caps { items },
|
|
781
781
|
out int: out <= in_len
|
|
782
782
|
) {
|
|
783
783
|
// Handle top-level alternation: a '|' at bracket/paren depth 0 splits the
|
|
@@ -1036,7 +1036,7 @@ func match_group_then_rest = (
|
|
|
1036
1036
|
string input,
|
|
1037
1037
|
int in_pos,
|
|
1038
1038
|
int in_len,
|
|
1039
|
-
ref List<int> caps,
|
|
1039
|
+
ref List<int> caps { items },
|
|
1040
1040
|
out int
|
|
1041
1041
|
) {
|
|
1042
1042
|
var int g = group_index_at(pattern, atom_start)
|
|
@@ -1127,7 +1127,7 @@ func match_single_atom = (
|
|
|
1127
1127
|
string input,
|
|
1128
1128
|
int in_pos,
|
|
1129
1129
|
int in_len,
|
|
1130
|
-
ref List<int> caps,
|
|
1130
|
+
ref List<int> caps { items },
|
|
1131
1131
|
out int
|
|
1132
1132
|
) {
|
|
1133
1133
|
var char pc = pattern.at(atom_start)
|
|
@@ -1309,7 +1309,7 @@ func match_counted = (
|
|
|
1309
1309
|
int lazy,
|
|
1310
1310
|
int count,
|
|
1311
1311
|
int in_len,
|
|
1312
|
-
ref List<int> caps,
|
|
1312
|
+
ref List<int> caps { items },
|
|
1313
1313
|
out int
|
|
1314
1314
|
) {
|
|
1315
1315
|
var can_stop = count >= min_count
|
|
@@ -1407,7 +1407,7 @@ func match_star = (
|
|
|
1407
1407
|
int min_count,
|
|
1408
1408
|
int lazy,
|
|
1409
1409
|
int in_len,
|
|
1410
|
-
ref List<int> caps,
|
|
1410
|
+
ref List<int> caps { items },
|
|
1411
1411
|
out int
|
|
1412
1412
|
) {
|
|
1413
1413
|
var char pc = pattern.at(atom_start)
|
|
@@ -1490,7 +1490,7 @@ func match_star_group = (
|
|
|
1490
1490
|
int min_count,
|
|
1491
1491
|
int lazy,
|
|
1492
1492
|
int in_len,
|
|
1493
|
-
ref List<int> caps,
|
|
1493
|
+
ref List<int> caps { items },
|
|
1494
1494
|
out int
|
|
1495
1495
|
) {
|
|
1496
1496
|
if lazy > 0 {
|
|
@@ -1559,7 +1559,7 @@ func match_group_iteration = (
|
|
|
1559
1559
|
int min_count,
|
|
1560
1560
|
int lazy,
|
|
1561
1561
|
int in_len,
|
|
1562
|
-
ref List<int> caps,
|
|
1562
|
+
ref List<int> caps { items },
|
|
1563
1563
|
out int
|
|
1564
1564
|
) {
|
|
1565
1565
|
var int g = group_index_at(pattern, atom_start)
|
|
@@ -1626,7 +1626,7 @@ func match_optional = (
|
|
|
1626
1626
|
int in_pos,
|
|
1627
1627
|
int lazy,
|
|
1628
1628
|
int in_len,
|
|
1629
|
-
ref List<int> caps,
|
|
1629
|
+
ref List<int> caps { items },
|
|
1630
1630
|
out int
|
|
1631
1631
|
) {
|
|
1632
1632
|
if lazy > 0 {
|
|
@@ -1899,7 +1899,7 @@ func group_index_at = (string pattern, int open_pos, out int) {
|
|
|
1899
1899
|
// group_pos. A later span for the same group supersedes the earlier one, so
|
|
1900
1900
|
// a repeated group reports its last iteration; a failed group records
|
|
1901
1901
|
// (-1, -1) so stale spans from an abandoned attempt never surface.
|
|
1902
|
-
func record_capture = (ref List<int> caps, int group, int start, int end) {
|
|
1902
|
+
func record_capture = (ref List<int> caps { items }, int group, int start, int end) {
|
|
1903
1903
|
if group <= 0 {
|
|
1904
1904
|
return
|
|
1905
1905
|
}
|
|
@@ -1958,7 +1958,7 @@ func match_backref = (
|
|
|
1958
1958
|
int group,
|
|
1959
1959
|
int in_pos,
|
|
1960
1960
|
int in_len,
|
|
1961
|
-
ref List<int> caps,
|
|
1961
|
+
ref List<int> caps {},
|
|
1962
1962
|
out int
|
|
1963
1963
|
) {
|
|
1964
1964
|
var int at = last_capture_index(caps, group)
|
|
@@ -1994,7 +1994,7 @@ func match_star_backref = (
|
|
|
1994
1994
|
int min_count,
|
|
1995
1995
|
int lazy,
|
|
1996
1996
|
int in_len,
|
|
1997
|
-
ref List<int> caps,
|
|
1997
|
+
ref List<int> caps { items },
|
|
1998
1998
|
out int
|
|
1999
1999
|
) {
|
|
2000
2000
|
var int group = backref_group(pattern.at(atom_start + 1))
|
|
@@ -2116,7 +2116,7 @@ func matches_shorthand = (char c, char b, out bool) {
|
|
|
2116
2116
|
// first-byte charset. Complement shorthands (S/D/W) match "anything else" —
|
|
2117
2117
|
// not expressible as an inclusion set — so they return -1, which disables
|
|
2118
2118
|
// the caller's prefilter.
|
|
2119
|
-
func shorthand_members = (char c, ref StringBuilder sb, out int) {
|
|
2119
|
+
func shorthand_members = (char c, ref StringBuilder sb {}, out int) {
|
|
2120
2120
|
var int kind = c as int
|
|
2121
2121
|
if kind == 83 || kind == 68 || kind == 87 {
|
|
2122
2122
|
return -1
|
package/core/System/Thread.nm
CHANGED
|
@@ -82,9 +82,13 @@ pub mv struct Thread<T> : Spawnable<T> {
|
|
|
82
82
|
// fields, so #destroy becomes a no-op afterwards. The future's refs
|
|
83
83
|
// account for the trampoline, the returned handle, and the nursery (when
|
|
84
84
|
// captured).
|
|
85
|
-
pub func start = (ref self, mv out Task<T>) {
|
|
85
|
+
pub func start = (ref self {}, mv out Task<T>) {
|
|
86
86
|
```
|
|
87
87
|
#arch: c
|
|
88
|
+
// Single-launch contract: a consumed construction (started) owns
|
|
89
|
+
// nothing — the handles below are zeroed, and writing the ref count
|
|
90
|
+
// through the null future would fault. Abort with the reason.
|
|
91
|
+
if (self->started) __nomen_spawn_double_start_abort();
|
|
88
92
|
struct nomen_future *_f = (struct nomen_future *)self->future;
|
|
89
93
|
_f->refs = self->nursery_futures ? 3 : 2;
|
|
90
94
|
__nomen_pool_submit((struct nomen_closure *)self->task);
|
|
@@ -94,7 +98,12 @@ pub mv struct Thread<T> : Spawnable<T> {
|
|
|
94
98
|
```
|
|
95
99
|
```
|
|
96
100
|
#arch: aarch64
|
|
97
|
-
// x19 = self. f = self->future (#32); nursery_futures
|
|
101
|
+
// x19 = self. started at #40; f = self->future (#32); nursery_futures
|
|
102
|
+
// at #48. Single-launch contract first: a consumed construction has
|
|
103
|
+
// zeroed handles, and the ref-store below would write through null.
|
|
104
|
+
ldrb w9, [x19, #40]
|
|
105
|
+
cbnz w9, .Lnomen_start_double
|
|
106
|
+
// f = self->future (#32); nursery_futures at #48.
|
|
98
107
|
ldr x0, [x19, #32]
|
|
99
108
|
ldr x1, [x19, #48]
|
|
100
109
|
mov w2, #2
|
|
@@ -113,6 +122,10 @@ pub mv struct Thread<T> : Spawnable<T> {
|
|
|
113
122
|
ldr x3, [x19, #32]
|
|
114
123
|
bl ___nomen_nursery_track
|
|
115
124
|
.Lnomen_start_notrack:
|
|
125
|
+
b .Lnomen_start_done
|
|
126
|
+
.Lnomen_start_double:
|
|
127
|
+
bl ___nomen_spawn_double_start_abort
|
|
128
|
+
.Lnomen_start_done:
|
|
116
129
|
```
|
|
117
130
|
// The handle is a fresh heap Task built through the internal #init;
|
|
118
131
|
// the caller owns it (a discarded statement form is reclaimed at
|
|
@@ -136,9 +149,12 @@ pub mv struct Thread<T> : Spawnable<T> {
|
|
|
136
149
|
// mid-execution BY DESIGN. The unused future (a Thread always carries
|
|
137
150
|
// the full machinery) is released — first detaching the closure from it,
|
|
138
151
|
// so the daemon runner owns the closure now.
|
|
139
|
-
pub func detach = (ref self) {
|
|
152
|
+
pub func detach = (ref self {}) {
|
|
140
153
|
```
|
|
141
154
|
#arch: c
|
|
155
|
+
// Single-launch contract (see .start): a consumed construction has
|
|
156
|
+
// zeroed handles, and detaching the null closure would crash a worker.
|
|
157
|
+
if (self->started) __nomen_spawn_double_start_abort();
|
|
142
158
|
struct nomen_future *_uf = (struct nomen_future *)self->future;
|
|
143
159
|
if (_uf) {
|
|
144
160
|
_uf->owner_args = NULL;
|
|
@@ -148,6 +164,9 @@ pub mv struct Thread<T> : Spawnable<T> {
|
|
|
148
164
|
```
|
|
149
165
|
```
|
|
150
166
|
#arch: aarch64
|
|
167
|
+
// Single-launch contract first (see .start): started at #40.
|
|
168
|
+
ldrb w9, [x19, #40]
|
|
169
|
+
cbnz w9, .Lnomen_detach_double
|
|
151
170
|
// if (self->future) { owner_args = NULL; release it }
|
|
152
171
|
ldr x0, [x19, #32]
|
|
153
172
|
cbz x0, .Lnomen_detach_nofut
|
|
@@ -157,6 +176,10 @@ pub mv struct Thread<T> : Spawnable<T> {
|
|
|
157
176
|
// __nomen_task_detach(self->task)
|
|
158
177
|
ldr x0, [x19, #8]
|
|
159
178
|
bl ___nomen_task_detach
|
|
179
|
+
b .Lnomen_detach_done
|
|
180
|
+
.Lnomen_detach_double:
|
|
181
|
+
bl ___nomen_spawn_double_start_abort
|
|
182
|
+
.Lnomen_detach_done:
|
|
160
183
|
```
|
|
161
184
|
self.task = 0
|
|
162
185
|
self.future = 0
|
package/core/System/Tree.nm
CHANGED
|
@@ -13,7 +13,7 @@ pub mv struct Tree<T>: Enumerable {
|
|
|
13
13
|
var parents = Buffer<int>()
|
|
14
14
|
var count = 0
|
|
15
15
|
|
|
16
|
-
pub func add = (ref self, mv T value) {
|
|
16
|
+
pub func add = (ref self { lefts, parents, rights, values }, mv T value) {
|
|
17
17
|
const int idx = self.count
|
|
18
18
|
self.values.grow_int(idx + 1)
|
|
19
19
|
const int v = value
|
|
@@ -27,12 +27,12 @@ pub mv struct Tree<T>: Enumerable {
|
|
|
27
27
|
self.count = self.count + 1
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
pub func set_left = (ref self, int idx, int left) {
|
|
30
|
+
pub func set_left = (ref self { lefts, parents }, int idx, int left) {
|
|
31
31
|
self.lefts.store_int(idx, left)
|
|
32
32
|
self.parents.store_int(left, idx)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
pub func set_right = (ref self, int idx, int right) {
|
|
35
|
+
pub func set_right = (ref self { parents, rights }, int idx, int right) {
|
|
36
36
|
self.rights.store_int(idx, right)
|
|
37
37
|
self.parents.store_int(right, idx)
|
|
38
38
|
}
|
|
@@ -57,6 +57,22 @@ pub mv struct Tree<T>: Enumerable {
|
|
|
57
57
|
return self.values.load_int(idx)
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
// Bounds-checked access: `fallback` when idx is outside [0, self.count).
|
|
61
|
+
pub func at_or = (self, int idx, T fallback, out T) {
|
|
62
|
+
if idx >= 0 && idx < self.count {
|
|
63
|
+
return self.at(idx)
|
|
64
|
+
}
|
|
65
|
+
return fallback
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Bounds-checked access that traps when idx is outside [0, self.count).
|
|
69
|
+
pub func at_or_panic = (self, int idx, out T) {
|
|
70
|
+
if idx >= 0 && idx < self.count {
|
|
71
|
+
return self.at(idx)
|
|
72
|
+
}
|
|
73
|
+
panic("index out of range")
|
|
74
|
+
}
|
|
75
|
+
|
|
60
76
|
pub func count_nodes = (self, int idx, out int) {
|
|
61
77
|
if idx == -1 {
|
|
62
78
|
return 0
|