nomen-lang 0.9.0 → 0.11.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/Format.nm +751 -0
- 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 +3423 -1849
- package/package.json +1 -1
- package/src/docs.ts +10 -1
|
@@ -18,7 +18,7 @@ pub struct StringBuilder {
|
|
|
18
18
|
// this doesn't even require an unsafe context.
|
|
19
19
|
// `internal`: capacity plumbing for the builder's own appenders; not
|
|
20
20
|
// part of the user surface.
|
|
21
|
-
internal func ensure = (ref self, int needed) {
|
|
21
|
+
internal func ensure = (ref self {}, int needed) {
|
|
22
22
|
if self.cap >= needed {
|
|
23
23
|
return
|
|
24
24
|
}
|
|
@@ -32,7 +32,7 @@ pub struct StringBuilder {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// Append a single byte (char).
|
|
35
|
-
pub inline func append_char = (ref self, char c) {
|
|
35
|
+
pub inline func append_char = (ref self {}, char c) {
|
|
36
36
|
```
|
|
37
37
|
#arch: c
|
|
38
38
|
int idx = self->len;
|
|
@@ -89,7 +89,7 @@ pub struct StringBuilder {
|
|
|
89
89
|
// plus the intermediate string's malloc/free collapse to a few
|
|
90
90
|
// instructions against the buffer. The raw body is spliced per call site
|
|
91
91
|
// (labels renamed by the splicer), so the digit loop is truly inline.
|
|
92
|
-
pub inline func append_int = (ref self, int n) {
|
|
92
|
+
pub inline func append_int = (ref self {}, int n) {
|
|
93
93
|
```
|
|
94
94
|
#arch: c
|
|
95
95
|
long v = n;
|
|
@@ -196,7 +196,7 @@ pub struct StringBuilder {
|
|
|
196
196
|
// Append a float with the SAME text `float.to_string` produces ("%f"):
|
|
197
197
|
// one snprintf into a stack scratch, then a bulk copy into the buffer —
|
|
198
198
|
// no sizing pass and no intermediate string allocation.
|
|
199
|
-
pub inline func append_float = (ref self, float f) {
|
|
199
|
+
pub inline func append_float = (ref self {}, float f) {
|
|
200
200
|
```
|
|
201
201
|
#arch: c
|
|
202
202
|
char tmp[360];
|
|
@@ -276,22 +276,22 @@ pub struct StringBuilder {
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
// Append a borrowed view without materializing it.
|
|
279
|
-
pub func append = (ref self, view string s) {
|
|
279
|
+
pub func append = (ref self {}, view string s) {
|
|
280
280
|
self.append_string_view(s)
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
// Append an int without materializing a string (see `append_int`).
|
|
284
|
-
pub func append = (ref self, int n) {
|
|
284
|
+
pub func append = (ref self {}, int n) {
|
|
285
285
|
self.append_int(n)
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
// Append a float without materializing a string (see `append_float`).
|
|
289
|
-
pub func append = (ref self, float f) {
|
|
289
|
+
pub func append = (ref self {}, float f) {
|
|
290
290
|
self.append_float(f)
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
// Append a single byte. (Overload, so `sb.append(c)` works for chars.)
|
|
294
|
-
pub func append = (ref self, char c) {
|
|
294
|
+
pub func append = (ref self {}, char c) {
|
|
295
295
|
self.append_char(c)
|
|
296
296
|
}
|
|
297
297
|
|
|
@@ -300,7 +300,7 @@ pub struct StringBuilder {
|
|
|
300
300
|
// `internal`: a library-implementation append — user code appends with
|
|
301
301
|
// `append_char` / `append_string_view`; the library's own structs (Json,
|
|
302
302
|
// Regex) are on the trusted side of the boundary.
|
|
303
|
-
internal func append_string = (ref self, string s) {
|
|
303
|
+
internal func append_string = (ref self {}, string s) {
|
|
304
304
|
unsafe {
|
|
305
305
|
var int sl = s.length
|
|
306
306
|
self.ensure(self.len + sl + 1)
|
|
@@ -314,7 +314,7 @@ pub struct StringBuilder {
|
|
|
314
314
|
// call. Views lower to the same (ptr, len) fat pair, so the bytes are
|
|
315
315
|
// memcpy'd straight out of the borrowed buffer (used by
|
|
316
316
|
// `string.replace_first`/`replace_all`).
|
|
317
|
-
pub func append_string_view = (ref self, view string s) {
|
|
317
|
+
pub func append_string_view = (ref self {}, view string s) {
|
|
318
318
|
unsafe {
|
|
319
319
|
var int sl = s.length
|
|
320
320
|
self.ensure(self.len + sl + 1)
|
|
@@ -327,7 +327,7 @@ pub struct StringBuilder {
|
|
|
327
327
|
// way to start a StringBuilder from a slice without a `to_string()`
|
|
328
328
|
// copy: the view's bytes are copied once into fresh storage, so the
|
|
329
329
|
// result is owned and independent of the source.
|
|
330
|
-
pub func seed = (ref self, view string s) {
|
|
330
|
+
pub func seed = (ref self {}, view string s) {
|
|
331
331
|
unsafe {
|
|
332
332
|
var int sl = s.length
|
|
333
333
|
self.ensure(sl + 1)
|
|
@@ -346,7 +346,7 @@ pub struct StringBuilder {
|
|
|
346
346
|
// Whether the buffer's current bytes end with `suffix` (an empty suffix
|
|
347
347
|
// is always true). Reads the buffer tail in place — no copy of either
|
|
348
348
|
// side (`view string` avoids materializing the checked suffix).
|
|
349
|
-
pub func ends_with = (ref self, view string suffix, out bool) {
|
|
349
|
+
pub func ends_with = (ref self {}, view string suffix, out bool) {
|
|
350
350
|
unsafe {
|
|
351
351
|
var int sl = suffix.length
|
|
352
352
|
if sl > self.len {
|
|
@@ -365,7 +365,7 @@ pub struct StringBuilder {
|
|
|
365
365
|
|
|
366
366
|
// Truncate the buffer to `new_len` bytes (clamped to [0, len]). Capacity
|
|
367
367
|
// is kept, so a subsequent append reuses the storage without a realloc.
|
|
368
|
-
pub func truncate = (ref self, int new_len) {
|
|
368
|
+
pub func truncate = (ref self {}, int new_len) {
|
|
369
369
|
var int n = new_len
|
|
370
370
|
if n < 0 {
|
|
371
371
|
n = 0
|
|
@@ -378,7 +378,7 @@ pub struct StringBuilder {
|
|
|
378
378
|
|
|
379
379
|
// Drop the last byte (a no-op when the buffer is empty). The common
|
|
380
380
|
// chomp-the-trailing-separator shape.
|
|
381
|
-
pub func chomp = (ref self) {
|
|
381
|
+
pub func chomp = (ref self {}) {
|
|
382
382
|
if self.len > 0 {
|
|
383
383
|
self.len = self.len - 1
|
|
384
384
|
}
|
|
@@ -391,7 +391,7 @@ pub struct StringBuilder {
|
|
|
391
391
|
// to [0, len]; the returned string is always an independent allocation.
|
|
392
392
|
// (`mv out string` — the raw body mallocs the result, so the caller
|
|
393
393
|
// owns it by signature, like `Console.read_line`.)
|
|
394
|
-
pub func take_since = (ref self, int mark, mv out string) {
|
|
394
|
+
pub func take_since = (ref self {}, int mark, mv out string) {
|
|
395
395
|
```
|
|
396
396
|
#arch: c
|
|
397
397
|
int start = mark;
|
|
@@ -459,7 +459,7 @@ pub struct StringBuilder {
|
|
|
459
459
|
// Explicitly `pub`: struct members default to pub, but this is the
|
|
460
460
|
// builder's primary read-back — the contract should not depend on the
|
|
461
461
|
// default.
|
|
462
|
-
pub func to_string = (ref self, out string) {
|
|
462
|
+
pub func to_string = (ref self {}, out string) {
|
|
463
463
|
```
|
|
464
464
|
#arch: c
|
|
465
465
|
int idx = self->len;
|
package/core/System/Task.nm
CHANGED
|
@@ -23,8 +23,6 @@
|
|
|
23
23
|
* Conforms to `Awaitable`: `.wait()` may park the current execution context.
|
|
24
24
|
**/
|
|
25
25
|
pub mv struct Task<T> : Awaitable {
|
|
26
|
-
pub var uint64 handle = 0
|
|
27
|
-
pub var done = false
|
|
28
26
|
pub var uint64 result_slot = 0
|
|
29
27
|
pub var uint64 cancel_flag = 0
|
|
30
28
|
pub var uint64 future = 0
|
|
@@ -46,8 +44,6 @@ pub mv struct Task<T> : Awaitable {
|
|
|
46
44
|
// names. Struct receivers travel by address regardless (the raw body
|
|
47
45
|
// reads `self->future`), so the ABI is unchanged; the bare spelling is
|
|
48
46
|
// what lets the read-only `Awaitable` dispatch form typecheck.
|
|
49
|
-
// The legacy `pthread_join` fallback is gone — `handle` has been
|
|
50
|
-
// permanently zero since the pool migration.
|
|
51
47
|
pub func wait = (self) {
|
|
52
48
|
```
|
|
53
49
|
#arch: c
|
|
@@ -58,7 +54,7 @@ pub mv struct Task<T> : Awaitable {
|
|
|
58
54
|
```
|
|
59
55
|
#arch: aarch64
|
|
60
56
|
// if (self->future) __nomen_future_wait(self->future)
|
|
61
|
-
ldr x0, [x19, #
|
|
57
|
+
ldr x0, [x19, #24]
|
|
62
58
|
cbz x0, .Lwait_done
|
|
63
59
|
bl ___nomen_future_wait
|
|
64
60
|
.Lwait_done:
|
|
@@ -71,18 +67,22 @@ pub mv struct Task<T> : Awaitable {
|
|
|
71
67
|
// trampoline writes the function's return value there before exiting.
|
|
72
68
|
// The result is MOVED OUT: the slot is zeroed as the value leaves, and
|
|
73
69
|
// `mv out T` marks the caller as the owner. Call it once; a second call
|
|
74
|
-
// returns the zero value.
|
|
75
|
-
//
|
|
76
|
-
|
|
70
|
+
// returns the zero value. An empty handle (never launched, machinery
|
|
71
|
+
// already destroyed) owns no slot — it also returns the zero value
|
|
72
|
+
// rather than reading through a null pointer. For tasks with no return
|
|
73
|
+
// value (void functions), returns the zero value.
|
|
74
|
+
pub func result = (ref self {}, mv out T) {
|
|
77
75
|
```
|
|
78
76
|
#arch: c
|
|
79
77
|
if (self->future) {
|
|
80
78
|
__nomen_future_wait((struct nomen_future *)self->future);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
}
|
|
80
|
+
// An empty or already-consumed handle owns no result cell — return
|
|
81
|
+
// the zero value instead of reading through a null slot.
|
|
82
|
+
if (!self->result_slot) {
|
|
83
|
+
T _z;
|
|
84
|
+
memset(&_z, 0, sizeof(T));
|
|
85
|
+
return _z;
|
|
86
86
|
}
|
|
87
87
|
T _r = *(T *)self->result_slot;
|
|
88
88
|
memset((void *)self->result_slot, 0, sizeof(T));
|
|
@@ -91,72 +91,64 @@ pub mv struct Task<T> : Awaitable {
|
|
|
91
91
|
```
|
|
92
92
|
#arch: aarch64
|
|
93
93
|
// Wait for completion (same as wait method)
|
|
94
|
-
ldr x0, [x19, #
|
|
95
|
-
cbz x0, .Lresult_handle
|
|
96
|
-
bl ___nomen_future_wait
|
|
97
|
-
b .Lresult_read
|
|
98
|
-
.Lresult_handle:
|
|
99
|
-
ldr x0, [x19, #8]
|
|
94
|
+
ldr x0, [x19, #24]
|
|
100
95
|
cbz x0, .Lresult_read
|
|
101
|
-
|
|
102
|
-
cbnz w1, .Lresult_read
|
|
103
|
-
sub sp, sp, #16
|
|
104
|
-
mov x1, sp
|
|
105
|
-
bl _pthread_join
|
|
106
|
-
add sp, sp, #16
|
|
107
|
-
str xzr, [x19, #8]
|
|
108
|
-
mov w0, #1
|
|
109
|
-
strb w0, [x19, #16]
|
|
96
|
+
bl ___nomen_future_wait
|
|
110
97
|
.Lresult_read:
|
|
98
|
+
// An empty or already-consumed handle owns no result cell: return
|
|
99
|
+
// the zero T instead of reading through a null slot.
|
|
100
|
+
ldr x8, [x19, #8]
|
|
101
|
+
cbz x8, .Lresult_zero
|
|
111
102
|
// The result cell is always 16 bytes (see the spawn build phase):
|
|
112
103
|
// load the full pair — a fat string returns (ptr, len) in x0/x1, a
|
|
113
104
|
// scalar returns its word in x0 — then zero the cell (the value is
|
|
114
105
|
// moved out; a second call observes the zero).
|
|
115
|
-
ldr x8, [x19, #24]
|
|
116
106
|
ldr x0, [x8]
|
|
117
107
|
ldr x1, [x8, #8]
|
|
118
108
|
stp xzr, xzr, [x8]
|
|
109
|
+
b .Lresult_end
|
|
110
|
+
.Lresult_zero:
|
|
111
|
+
mov x0, #0
|
|
112
|
+
mov x1, #0
|
|
113
|
+
.Lresult_end:
|
|
119
114
|
```
|
|
120
115
|
}
|
|
121
116
|
|
|
122
117
|
// Block until the task finishes, then return its result as a uint64.
|
|
123
118
|
// Convenience for the common case; same as result() for uint64 tasks.
|
|
124
|
-
|
|
119
|
+
// Like result(), it zeroes the cell as the value leaves (one end state
|
|
120
|
+
// for a consumed handle), and an empty handle returns zero.
|
|
121
|
+
pub func result_uint64 = (ref self {}, out uint64) {
|
|
125
122
|
```
|
|
126
123
|
#arch: c
|
|
127
124
|
if (self->future) {
|
|
128
125
|
__nomen_future_wait((struct nomen_future *)self->future);
|
|
129
|
-
} else if (self->handle && !self->done) {
|
|
130
|
-
void *ret;
|
|
131
|
-
pthread_join((pthread_t)self->handle, &ret);
|
|
132
|
-
self->handle = 0;
|
|
133
|
-
self->done = 1;
|
|
134
126
|
}
|
|
135
|
-
|
|
127
|
+
if (!self->result_slot) {
|
|
128
|
+
return 0;
|
|
129
|
+
}
|
|
130
|
+
unsigned long long _r = *(unsigned long long *)self->result_slot;
|
|
131
|
+
*(unsigned long long *)self->result_slot = 0;
|
|
132
|
+
return _r;
|
|
136
133
|
```
|
|
137
134
|
```
|
|
138
135
|
#arch: aarch64
|
|
139
136
|
// Wait for completion
|
|
140
|
-
ldr x0, [x19, #
|
|
141
|
-
cbz x0, .Lru64_handle
|
|
142
|
-
bl ___nomen_future_wait
|
|
143
|
-
b .Lru64_read
|
|
144
|
-
.Lru64_handle:
|
|
145
|
-
ldr x0, [x19, #8]
|
|
137
|
+
ldr x0, [x19, #24]
|
|
146
138
|
cbz x0, .Lru64_read
|
|
147
|
-
|
|
148
|
-
cbnz w1, .Lru64_read
|
|
149
|
-
sub sp, sp, #16
|
|
150
|
-
mov x1, sp
|
|
151
|
-
bl _pthread_join
|
|
152
|
-
add sp, sp, #16
|
|
153
|
-
str xzr, [x19, #8]
|
|
154
|
-
mov w0, #1
|
|
155
|
-
strb w0, [x19, #16]
|
|
139
|
+
bl ___nomen_future_wait
|
|
156
140
|
.Lru64_read:
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
141
|
+
// An empty or already-consumed handle owns no result cell: return
|
|
142
|
+
// zero instead of reading through a null slot. Otherwise zero the
|
|
143
|
+
// cell as the value leaves (matching result()'s end state).
|
|
144
|
+
ldr x8, [x19, #8]
|
|
145
|
+
cbz x8, .Lru64_zero
|
|
146
|
+
ldr x0, [x8]
|
|
147
|
+
str xzr, [x8]
|
|
148
|
+
b .Lru64_end
|
|
149
|
+
.Lru64_zero:
|
|
150
|
+
mov x0, #0
|
|
151
|
+
.Lru64_end:
|
|
160
152
|
```
|
|
161
153
|
}
|
|
162
154
|
|
|
@@ -165,7 +157,7 @@ pub mv struct Task<T> : Awaitable {
|
|
|
165
157
|
// handle whose machinery was already consumed). The missing peek
|
|
166
158
|
// between wait (blocking) and cancel (cooperative): event loops use it
|
|
167
159
|
// to notice a finished task without parking the UI thread.
|
|
168
|
-
pub func is_done = (ref self, out bool) {
|
|
160
|
+
pub func is_done = (ref self {}, out bool) {
|
|
169
161
|
```
|
|
170
162
|
#arch: c
|
|
171
163
|
return __nomen_future_is_done((struct nomen_future *)self->future);
|
|
@@ -173,14 +165,14 @@ pub mv struct Task<T> : Awaitable {
|
|
|
173
165
|
```
|
|
174
166
|
#arch: aarch64
|
|
175
167
|
// x0 = self->future; result in x0.
|
|
176
|
-
ldr x0, [x19, #
|
|
168
|
+
ldr x0, [x19, #24]
|
|
177
169
|
bl ___nomen_future_is_done
|
|
178
170
|
```
|
|
179
171
|
}
|
|
180
172
|
|
|
181
173
|
// Request that the task stop. Cooperative — the task observes this via
|
|
182
174
|
// `Task.current_cancelled()` at its own checkpoints. No preemption.
|
|
183
|
-
pub func cancel = (ref self) {
|
|
175
|
+
pub func cancel = (ref self {}) {
|
|
184
176
|
```
|
|
185
177
|
#arch: c
|
|
186
178
|
// Sets the flag and wakes any fiber parked on this task's future, so
|
|
@@ -195,12 +187,12 @@ pub mv struct Task<T> : Awaitable {
|
|
|
195
187
|
#arch: aarch64
|
|
196
188
|
// if (self->future) __nomen_future_cancel(self->future);
|
|
197
189
|
// else if (self->cancel_flag) *(self->cancel_flag) = 1
|
|
198
|
-
ldr x0, [x19, #
|
|
190
|
+
ldr x0, [x19, #24]
|
|
199
191
|
cbz x0, .Lcancel_flag_path
|
|
200
192
|
bl ___nomen_future_cancel
|
|
201
193
|
b .Lcancel_done
|
|
202
194
|
.Lcancel_flag_path:
|
|
203
|
-
ldr x0, [x19, #
|
|
195
|
+
ldr x0, [x19, #16]
|
|
204
196
|
cbz x0, .Lcancel_done
|
|
205
197
|
mov x1, #1
|
|
206
198
|
str x1, [x0]
|
|
@@ -393,12 +385,12 @@ pub mv struct Task<T> : Awaitable {
|
|
|
393
385
|
```
|
|
394
386
|
#arch: aarch64
|
|
395
387
|
// if (self->future) { free an unconsumed string result; release; zero fields }
|
|
396
|
-
ldr x0, [x19, #
|
|
388
|
+
ldr x0, [x19, #24]
|
|
397
389
|
cbz x0, .Ldestroy_done
|
|
398
390
|
// An unconsumed string result: the cell still holds (ptr, len) —
|
|
399
391
|
// result() zeroes it when it moves the value out. The T_FAT dispatch
|
|
400
392
|
// folds to a constant branch after monomorphization.
|
|
401
|
-
ldr x8, [x19, #
|
|
393
|
+
ldr x8, [x19, #8]
|
|
402
394
|
mov x0, #T_FAT
|
|
403
395
|
cmp x0, #0
|
|
404
396
|
b.eq .Ldestroy_nofree
|
|
@@ -411,11 +403,11 @@ pub mv struct Task<T> : Awaitable {
|
|
|
411
403
|
stp xzr, xzr, [x8]
|
|
412
404
|
bl _free
|
|
413
405
|
.Ldestroy_nofree:
|
|
414
|
-
ldr x0, [x19, #
|
|
406
|
+
ldr x0, [x19, #24]
|
|
415
407
|
bl ___nomen_future_release
|
|
416
|
-
str xzr, [x19, #40]
|
|
417
408
|
str xzr, [x19, #24]
|
|
418
|
-
str xzr, [x19, #
|
|
409
|
+
str xzr, [x19, #8]
|
|
410
|
+
str xzr, [x19, #16]
|
|
419
411
|
.Ldestroy_done:
|
|
420
412
|
```
|
|
421
413
|
}
|
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
|
}
|