nomen-lang 0.2.3 → 0.4.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 (49) hide show
  1. package/NOMEN_AGENTS.md +7 -1
  2. package/core/System/Arena.nm +166 -0
  3. package/core/System/Array.nm +30 -161
  4. package/core/System/BigInt.nm +36 -57
  5. package/core/System/Buffer.nm +197 -279
  6. package/core/System/ClassBuffer.nm +120 -130
  7. package/core/System/Console.nm +4 -2
  8. package/core/System/Controls/Button.nm +4 -4
  9. package/core/System/Controls/CheckBox.nm +1 -1
  10. package/core/System/Controls/LayoutParams.nm +1 -1
  11. package/core/System/Controls/Text.nm +2 -2
  12. package/core/System/Controls/TextBox.nm +6 -6
  13. package/core/System/Controls/Window.nm +2 -2
  14. package/core/System/Graph.nm +4 -4
  15. package/core/System/LinkedList.nm +4 -4
  16. package/core/System/List.nm +6 -6
  17. package/core/System/Map.nm +33 -30
  18. package/core/System/Set.nm +24 -24
  19. package/core/System/Stream/Directory.nm +4 -4
  20. package/core/System/Stream/File.nm +19 -12
  21. package/core/System/String.nm +300 -34
  22. package/core/System/StringBuilder.nm +53 -117
  23. package/core/System/Text/CharIndex.nm +144 -0
  24. package/core/System/Text/Chars.nm +32 -0
  25. package/core/System/Text/JsonTree.nm +48 -96
  26. package/core/System/Text/Regex.nm +726 -40
  27. package/core/System/Text/Utf8.nm +163 -0
  28. package/core/System/bool.nm +2 -1
  29. package/core/System/char.nm +27 -1
  30. package/core/System/float.nm +2 -1
  31. package/core/System/float32.nm +2 -1
  32. package/core/System/float64.nm +2 -1
  33. package/core/System/int.nm +4 -2
  34. package/core/System/int16.nm +2 -1
  35. package/core/System/int32.nm +2 -1
  36. package/core/System/int64.nm +2 -1
  37. package/core/System/int8.nm +2 -1
  38. package/core/System/ufloat.nm +2 -1
  39. package/core/System/ufloat32.nm +2 -1
  40. package/core/System/ufloat64.nm +2 -1
  41. package/core/System/uint.nm +2 -1
  42. package/core/System/uint16.nm +2 -1
  43. package/core/System/uint32.nm +2 -1
  44. package/core/System/uint64.nm +2 -1
  45. package/core/System/uint8.nm +2 -1
  46. package/core/docs/System/BigInt.md +0 -1
  47. package/dist/index.mjs +5273 -1339
  48. package/package.json +1 -1
  49. package/src/index.ts +58 -7
@@ -27,22 +27,25 @@ pub struct Map<TK: Hashable + Equatable, TV> {
27
27
  pub func set = (ref self, move TK key, move TV value) {
28
28
  var int cap = self.keys.cap
29
29
  if cap == 0 {
30
- cap = self.keys.alloc_T(8)
31
- self.values.alloc_T(8)
32
- self.used.alloc(8)
30
+ // alloc_T: for Buffer<TK> it is T_SIZE-aware (string keys are
31
+ // 16-byte slots); for ClassBuffer<TV> it delegates to alloc_int
32
+ // (one pointer per slot). Both have it for generic parity.
33
+ cap = self.keys.alloc(8)
34
+ self.values.alloc(8)
35
+ self.used.alloc_u32(8)
33
36
  }
34
37
  if self.length * 4 >= cap * 3 {
35
38
  self.rehash(cap * 2)
36
39
  cap = self.keys.cap
37
40
  }
38
41
  var int idx = self.find_slot(key, cap)
39
- if self.used.load(idx) == 0 {
40
- self.used.store(idx, 1)
41
- self.keys.store_T(idx, key)
42
- self.values.store_T(idx, value)
42
+ if self.used.load_u32(idx) == 0 {
43
+ self.used.store_u32(idx, 1)
44
+ self.keys.store(idx, key)
45
+ self.values.store(idx, value)
43
46
  self.length += 1
44
47
  } else {
45
- self.values.replace_T(idx, value)
48
+ self.values.replace(idx, value)
46
49
  }
47
50
  }
48
51
 
@@ -52,10 +55,10 @@ pub struct Map<TK: Hashable + Equatable, TV> {
52
55
  return 0
53
56
  }
54
57
  var int idx = self.find_slot(key, cap)
55
- if self.used.load(idx) == 0 {
58
+ if self.used.load_u32(idx) == 0 {
56
59
  return 0
57
60
  }
58
- return self.values.load_T(idx)
61
+ return self.values.load(idx)
59
62
  }
60
63
 
61
64
  // Fused lookup-with-fallback: one probe instead of the `has` + `get`
@@ -66,10 +69,10 @@ pub struct Map<TK: Hashable + Equatable, TV> {
66
69
  return fallback
67
70
  }
68
71
  var int idx = self.find_slot(key, cap)
69
- if self.used.load(idx) == 0 {
72
+ if self.used.load_u32(idx) == 0 {
70
73
  return fallback
71
74
  }
72
- return self.values.load_T(idx)
75
+ return self.values.load(idx)
73
76
  }
74
77
 
75
78
  // Lookup that traps when the key is absent — for when a missing key is
@@ -80,10 +83,10 @@ pub struct Map<TK: Hashable + Equatable, TV> {
80
83
  panic("key not found")
81
84
  }
82
85
  var int idx = self.find_slot(key, cap)
83
- if self.used.load(idx) == 0 {
86
+ if self.used.load_u32(idx) == 0 {
84
87
  panic("key not found")
85
88
  }
86
- return self.values.load_T(idx)
89
+ return self.values.load(idx)
87
90
  }
88
91
 
89
92
  pub func has = (self, TK key, out bool) {
@@ -92,7 +95,7 @@ pub struct Map<TK: Hashable + Equatable, TV> {
92
95
  return false
93
96
  }
94
97
  var int idx = self.find_slot(key, cap)
95
- return self.used.load(idx) != 0
98
+ return self.used.load_u32(idx) != 0
96
99
  }
97
100
 
98
101
  pub func remove = (ref self, TK key) {
@@ -101,7 +104,7 @@ pub struct Map<TK: Hashable + Equatable, TV> {
101
104
  return
102
105
  }
103
106
  var int idx = self.find_slot(key, cap)
104
- if self.used.load(idx) == 0 {
107
+ if self.used.load_u32(idx) == 0 {
105
108
  return
106
109
  }
107
110
  // Backward-shift deletion for linear probing. `gap` is the empty slot
@@ -121,10 +124,10 @@ pub struct Map<TK: Hashable + Equatable, TV> {
121
124
  if k >= cap {
122
125
  k = 0
123
126
  }
124
- if self.used.load(k) == 0 {
127
+ if self.used.load_u32(k) == 0 {
125
128
  break
126
129
  }
127
- var int home = (self.keys.load_T(k).hash() as int) & (cap - 1)
130
+ var int home = (self.keys.load(k).hash() as int) & (cap - 1)
128
131
  var int dgap = gap - home
129
132
  if dgap < 0 {
130
133
  dgap = dgap + cap
@@ -139,13 +142,13 @@ pub struct Map<TK: Hashable + Equatable, TV> {
139
142
  // would strdup a fresh copy into gap while leaving the source
140
143
  // slot's pointer stranded at the vacated slot — leaked once
141
144
  // used.store marks it empty (the buffer destroy skips it).
142
- self.keys.shift_T(gap, k)
143
- self.values.shift_T(gap, k)
144
- self.used.store(gap, 1)
145
+ self.keys.shift(gap, k)
146
+ self.values.shift(gap, k)
147
+ self.used.store_u32(gap, 1)
145
148
  gap = k
146
149
  }
147
150
  }
148
- self.used.store(gap, 0)
151
+ self.used.store_u32(gap, 0)
149
152
  self.length = self.length - 1
150
153
  }
151
154
 
@@ -153,8 +156,8 @@ pub struct Map<TK: Hashable + Equatable, TV> {
153
156
  // cap is a power of two, so this is `hash mod cap` via a mask —
154
157
  // non-negative for any hash (two's complement), no adjustment.
155
158
  var int idx = (key.hash() as int) & (cap - 1)
156
- while self.used.load(idx) != 0 {
157
- if self.keys.load_T(idx) == key {
159
+ while self.used.load_u32(idx) != 0 {
160
+ if self.keys.load(idx) == key {
158
161
  return idx
159
162
  }
160
163
  idx += 1
@@ -171,14 +174,14 @@ pub struct Map<TK: Hashable + Equatable, TV> {
171
174
  var Buffer<int> old_used = move self.used swap Buffer<int>()
172
175
  var int old_cap = old_keys.cap
173
176
 
174
- self.keys.alloc_T(new_cap)
175
- self.values.alloc_T(new_cap)
176
- self.used.alloc(new_cap)
177
+ self.keys.alloc(new_cap)
178
+ self.values.alloc(new_cap)
179
+ self.used.alloc_u32(new_cap)
177
180
  self.length = 0
178
181
 
179
182
  var i = 0
180
183
  while i < old_cap; i += 1 {
181
- if old_used.load(i) != 0 {
184
+ if old_used.load_u32(i) != 0 {
182
185
  // move_T (not load_T) relinquishes the old slot, so each
183
186
  // key/value is owned by exactly one buffer (the new self)
184
187
  // afterwards. load_T would leave the old slot referencing
@@ -188,8 +191,8 @@ pub struct Map<TK: Hashable + Equatable, TV> {
188
191
  // store_T strdup's) is freed here once the new buffer has
189
192
  // made its own copy — passing them inline would orphan the
190
193
  // move_T results.
191
- var TK k = old_keys.move_T(i)
192
- var TV v = old_values.move_T(i)
194
+ var TK k = old_keys.move(i)
195
+ var TV v = old_values.move(i)
193
196
  self.set(move k, move v)
194
197
  }
195
198
  }
@@ -15,17 +15,17 @@ pub struct Set<T: Hashable + Equatable> {
15
15
  pub func add = (ref self, move T value) {
16
16
  var int cap = self.slots.cap
17
17
  if cap == 0 {
18
- cap = self.slots.alloc_T(8)
19
- self.used.alloc(8)
18
+ cap = self.slots.alloc(8)
19
+ self.used.alloc_u32(8)
20
20
  }
21
21
  if self.length * 4 >= cap * 3 {
22
22
  self.rehash(cap * 2)
23
23
  cap = self.slots.cap
24
24
  }
25
25
  var int idx = self.find_slot(value, cap)
26
- if self.used.load(idx) == 0 {
27
- self.used.store(idx, 1)
28
- self.slots.store_T(idx, value)
26
+ if self.used.load_u32(idx) == 0 {
27
+ self.used.store_u32(idx, 1)
28
+ self.slots.store(idx, value)
29
29
  self.length += 1
30
30
  }
31
31
  }
@@ -36,7 +36,7 @@ pub struct Set<T: Hashable + Equatable> {
36
36
  return false
37
37
  }
38
38
  var int idx = self.find_slot(value, cap)
39
- return self.used.load(idx) != 0
39
+ return self.used.load_u32(idx) != 0
40
40
  }
41
41
 
42
42
  pub func get = (self, T key, out T) {
@@ -45,10 +45,10 @@ pub struct Set<T: Hashable + Equatable> {
45
45
  return 0
46
46
  }
47
47
  var int idx = self.find_slot(key, cap)
48
- if self.used.load(idx) == 0 {
48
+ if self.used.load_u32(idx) == 0 {
49
49
  return 0
50
50
  }
51
- return self.slots.load_T(idx)
51
+ return self.slots.load(idx)
52
52
  }
53
53
 
54
54
  // Membership lookup with a fallback value: `fallback` when the value is
@@ -59,10 +59,10 @@ pub struct Set<T: Hashable + Equatable> {
59
59
  return fallback
60
60
  }
61
61
  var int idx = self.find_slot(key, cap)
62
- if self.used.load(idx) == 0 {
62
+ if self.used.load_u32(idx) == 0 {
63
63
  return fallback
64
64
  }
65
- return self.slots.load_T(idx)
65
+ return self.slots.load(idx)
66
66
  }
67
67
 
68
68
  // Membership lookup that traps when the value is not in the set.
@@ -72,10 +72,10 @@ pub struct Set<T: Hashable + Equatable> {
72
72
  panic("value not found in set")
73
73
  }
74
74
  var int idx = self.find_slot(key, cap)
75
- if self.used.load(idx) == 0 {
75
+ if self.used.load_u32(idx) == 0 {
76
76
  panic("value not found in set")
77
77
  }
78
- return self.slots.load_T(idx)
78
+ return self.slots.load(idx)
79
79
  }
80
80
 
81
81
  pub func remove = (ref self, T value) {
@@ -84,7 +84,7 @@ pub struct Set<T: Hashable + Equatable> {
84
84
  return
85
85
  }
86
86
  var int idx = self.find_slot(value, cap)
87
- if self.used.load(idx) == 0 {
87
+ if self.used.load_u32(idx) == 0 {
88
88
  return
89
89
  }
90
90
  // Backward-shift deletion for linear probing. `gap` is the empty slot
@@ -104,10 +104,10 @@ pub struct Set<T: Hashable + Equatable> {
104
104
  if k >= cap {
105
105
  k = 0
106
106
  }
107
- if self.used.load(k) == 0 {
107
+ if self.used.load_u32(k) == 0 {
108
108
  break
109
109
  }
110
- var int home = (self.slots.load_T(k).hash() as int) & (cap - 1)
110
+ var int home = (self.slots.load(k).hash() as int) & (cap - 1)
111
111
  var int dgap = gap - home
112
112
  if dgap < 0 {
113
113
  dgap = dgap + cap
@@ -122,12 +122,12 @@ pub struct Set<T: Hashable + Equatable> {
122
122
  // fresh copy into gap while stranding the source slot's
123
123
  // pointer at the vacated slot (leaked once used.store marks it
124
124
  // empty; the buffer destroy skips unused slots).
125
- self.slots.shift_T(gap, k)
126
- self.used.store(gap, 1)
125
+ self.slots.shift(gap, k)
126
+ self.used.store_u32(gap, 1)
127
127
  gap = k
128
128
  }
129
129
  }
130
- self.used.store(gap, 0)
130
+ self.used.store_u32(gap, 0)
131
131
  self.length = self.length - 1
132
132
  }
133
133
 
@@ -135,8 +135,8 @@ pub struct Set<T: Hashable + Equatable> {
135
135
  // cap is a power of two: `hash mod cap` via a mask, non-negative
136
136
  // for any hash — no adjustment needed.
137
137
  var int idx = (value.hash() as int) & (cap - 1)
138
- while self.used.load(idx) != 0 {
139
- if self.slots.load_T(idx) == value {
138
+ while self.used.load_u32(idx) != 0 {
139
+ if self.slots.load(idx) == value {
140
140
  return idx
141
141
  }
142
142
  idx += 1
@@ -152,13 +152,13 @@ pub struct Set<T: Hashable + Equatable> {
152
152
  var Buffer<int> old_used = move self.used swap Buffer<int>()
153
153
  var int old_cap = old_slots.cap
154
154
 
155
- self.slots.alloc_T(new_cap)
156
- self.used.alloc(new_cap)
155
+ self.slots.alloc(new_cap)
156
+ self.used.alloc_u32(new_cap)
157
157
  self.length = 0
158
158
 
159
159
  var i = 0
160
160
  while i < old_cap; i += 1 {
161
- if old_used.load(i) != 0 {
161
+ if old_used.load_u32(i) != 0 {
162
162
  // move_T (not load_T) relinquishes the old slot, so each value
163
163
  // is owned by exactly one buffer (the new self) afterwards.
164
164
  // load_T would leave the old slot referencing the same class
@@ -167,7 +167,7 @@ pub struct Set<T: Hashable + Equatable> {
167
167
  // `Buffer<string>` slot, which store_T strdup's) is freed here
168
168
  // once the new buffer has made its own copy — passing it inline
169
169
  // would orphan the move_T result.
170
- var T v = old_slots.move_T(i)
170
+ var T v = old_slots.move(i)
171
171
  self.add(move v)
172
172
  }
173
173
  }
@@ -43,7 +43,7 @@ pub struct Directory {
43
43
  ```
44
44
  ```
45
45
  #arch: c
46
- if (mkdir(path, 0777)) return errno;
46
+ if (mkdir(path.ptr, 0777)) return errno;
47
47
  return 0;
48
48
  ```
49
49
  ```
@@ -76,7 +76,7 @@ pub struct Directory {
76
76
  func raw_remove = (string path, out int) {
77
77
  ```
78
78
  #arch: c
79
- if (rmdir(path)) return errno;
79
+ if (rmdir(path.ptr)) return errno;
80
80
  return 0;
81
81
  ```
82
82
  ```
@@ -109,7 +109,7 @@ pub struct Directory {
109
109
  ```
110
110
  #arch: c
111
111
  struct stat st;
112
- return stat(path, &st) == 0 ? 1 : 0;
112
+ return stat(path.ptr, &st) == 0 ? 1 : 0;
113
113
  ```
114
114
  ```
115
115
  #arch: aarch64
@@ -147,7 +147,7 @@ pub struct Directory {
147
147
  ```
148
148
  #arch: c
149
149
  Result_string_DirectoryError r;
150
- DIR *d = opendir(path);
150
+ DIR *d = opendir(path.ptr);
151
151
  if (!d) {
152
152
  int e = errno;
153
153
  long de = 4;
@@ -72,7 +72,8 @@ pub struct File {
72
72
  ```
73
73
  ```
74
74
  #arch: c
75
- self->handle = (unsigned long long)fopen(path, mode);
75
+ // Fat-string ABI: strings pass their ptr half at FFI boundaries.
76
+ self->handle = (unsigned long long)fopen(path.ptr, mode.ptr);
76
77
  if (self->handle) {
77
78
  self->error = 0;
78
79
  } else {
@@ -236,21 +237,24 @@ pub struct File {
236
237
  #arch: c
237
238
  FILE *f = (FILE*)(unsigned long long)self->handle;
238
239
  if (!f) { self->error = 9; return; }
239
- fputs(data, f);
240
+ // Byte-exact write of the tracked length (fputs stopped at the
241
+ // first embedded NUL).
242
+ fwrite(data.ptr, 1, data.len, f);
240
243
  self->error = 0;
241
244
  ```
242
245
  ```
243
246
  #arch: aarch64
244
- // Fat-string ABI: data = (x1, x2).
247
+ // Fat-string ABI: data = (x1 ptr, x2 len).
245
248
  ldr x3, [x19, #8]
246
249
  cbnz x3, .Lfile_write_all_go
247
250
  mov x0, #9
248
251
  str x0, [x19, #24]
249
252
  b .return_File_raw_write_all
250
253
  .Lfile_write_all_go:
254
+ // fwrite(ptr, 1, len, f) — byte-exact (fputs truncated at NUL)
251
255
  mov x0, x1
252
- mov x1, x3
253
- bl _fputs
256
+ mov x1, #1
257
+ bl _fwrite
254
258
  str xzr, [x19, #24]
255
259
  ```
256
260
  }
@@ -375,22 +379,25 @@ pub struct File {
375
379
  #arch: c
376
380
  FILE *f = (FILE*)(unsigned long long)self->handle;
377
381
  if (!f) { self->error = 9; return; }
378
- fputs(data, f);
382
+ // Byte-exact write of the tracked length (fputs stopped at the
383
+ // first embedded NUL).
384
+ fwrite(data.ptr, 1, data.len, f);
379
385
  fputc('\n', f);
380
386
  self->error = 0;
381
387
  ```
382
388
  ```
383
389
  #arch: aarch64
384
- // Fat-string ABI: data = (x1, x2).
390
+ // Fat-string ABI: data = (x1 ptr, x2 len).
385
391
  ldr x3, [x19, #8]
386
392
  cbnz x3, .Lfile_write_line_go
387
393
  mov x0, #9
388
394
  str x0, [x19, #24]
389
395
  b .return_File_raw_write_line
390
396
  .Lfile_write_line_go:
397
+ // fwrite(ptr, 1, len, f) — byte-exact (fputs truncated at NUL)
391
398
  mov x0, x1
392
- mov x1, x3
393
- bl _fputs
399
+ mov x1, #1
400
+ bl _fwrite
394
401
  mov w0, #10
395
402
  ldr x1, [x19, #8]
396
403
  bl _fputc
@@ -476,7 +483,7 @@ pub struct File {
476
483
  #arch: c
477
484
  FILE *f = (FILE*)(unsigned long long)self->handle;
478
485
  if (!f) { self->error = 9; return; }
479
- fwrite(data, 1, size, f);
486
+ fwrite(data.ptr, 1, size, f);
480
487
  self->error = 0;
481
488
  ```
482
489
  ```
@@ -513,7 +520,7 @@ pub struct File {
513
520
  ```
514
521
  #arch: c
515
522
  struct stat st;
516
- return stat(path, &st) == 0 ? 1 : 0;
523
+ return stat(path.ptr, &st) == 0 ? 1 : 0;
517
524
  ```
518
525
  ```
519
526
  #arch: aarch64
@@ -532,7 +539,7 @@ pub struct File {
532
539
  func raw_delete = (string path, out int) {
533
540
  ```
534
541
  #arch: c
535
- if (remove(path)) return errno;
542
+ if (remove(path.ptr)) return errno;
536
543
  return 0;
537
544
  ```
538
545
  ```