nomen-lang 0.0.7 → 0.0.8

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 (118) hide show
  1. package/NOMEN_AGENTS.md +235 -0
  2. package/core/System/Ansi.nm +150 -0
  3. package/core/System/Array.nm +358 -0
  4. package/core/System/BigInt.nm +887 -0
  5. package/core/System/Buffer.nm +526 -0
  6. package/core/System/Channel.nm +198 -0
  7. package/core/System/ClassBuffer.nm +229 -0
  8. package/core/System/Console.nm +211 -0
  9. package/core/System/Controls/Button.nm +138 -0
  10. package/core/System/Controls/CheckBox.nm +158 -0
  11. package/core/System/Controls/Container.nm +1562 -0
  12. package/core/System/Controls/Control.nm +28 -0
  13. package/core/System/Controls/Geometry.nm +101 -0
  14. package/core/System/Controls/Layout.nm +228 -0
  15. package/core/System/Controls/LayoutParams.nm +50 -0
  16. package/core/System/Controls/Text.nm +129 -0
  17. package/core/System/Controls/TextBox.nm +157 -0
  18. package/core/System/Controls/Window.nm +280 -0
  19. package/core/System/Disposable.nm +8 -0
  20. package/core/System/Enumerable.nm +10 -0
  21. package/core/System/Equatable.nm +10 -0
  22. package/core/System/Graph.nm +68 -0
  23. package/core/System/Hashable.nm +13 -0
  24. package/core/System/Init.nm +21 -0
  25. package/core/System/LinkedList.nm +64 -0
  26. package/core/System/List.nm +44 -0
  27. package/core/System/Map.nm +153 -0
  28. package/core/System/Math.nm +54 -0
  29. package/core/System/Mutex.nm +78 -0
  30. package/core/System/Nursery.nm +27 -0
  31. package/core/System/Sendable.nm +9 -0
  32. package/core/System/Set.nm +97 -0
  33. package/core/System/Stream/Directory.nm +176 -0
  34. package/core/System/Stream/File.nm +432 -0
  35. package/core/System/Stream/Http.nm +453 -0
  36. package/core/System/String.nm +154 -0
  37. package/core/System/StringBuilder.nm +249 -0
  38. package/core/System/Stringable.nm +8 -0
  39. package/core/System/Task.nm +263 -0
  40. package/core/System/Test.nm +241 -0
  41. package/core/System/Text/Json.nm +377 -0
  42. package/core/System/Text/JsonTree.nm +187 -0
  43. package/core/System/Text/Regex.nm +655 -0
  44. package/core/System/Time.nm +112 -0
  45. package/core/System/Tree.nm +70 -0
  46. package/core/System/Viewable.nm +27 -0
  47. package/core/System/bool.nm +66 -0
  48. package/core/System/char.nm +42 -0
  49. package/core/System/float.nm +43 -0
  50. package/core/System/int.nm +54 -0
  51. package/core/System/int64.nm +42 -0
  52. package/core/System/int8.nm +42 -0
  53. package/core/System/uint.nm +42 -0
  54. package/core/System/uint64.nm +42 -0
  55. package/core/System/uint8.nm +42 -0
  56. package/core/docs/System/Ansi.md +40 -0
  57. package/core/docs/System/Array.md +16 -0
  58. package/core/docs/System/BigInt.md +30 -0
  59. package/core/docs/System/Buffer.md +31 -0
  60. package/core/docs/System/Channel.md +10 -0
  61. package/core/docs/System/ClassBuffer.md +15 -0
  62. package/core/docs/System/Console.md +13 -0
  63. package/core/docs/System/Controls/Button.md +12 -0
  64. package/core/docs/System/Controls/CheckBox.md +15 -0
  65. package/core/docs/System/Controls/Container.md +82 -0
  66. package/core/docs/System/Controls/Control.md +5 -0
  67. package/core/docs/System/Controls/Geometry.md +26 -0
  68. package/core/docs/System/Controls/Layout.md +37 -0
  69. package/core/docs/System/Controls/LayoutParams.md +13 -0
  70. package/core/docs/System/Controls/Text.md +12 -0
  71. package/core/docs/System/Controls/TextBox.md +13 -0
  72. package/core/docs/System/Controls/Window.md +20 -0
  73. package/core/docs/System/Disposable.md +5 -0
  74. package/core/docs/System/Enumerable.md +5 -0
  75. package/core/docs/System/Graph.md +17 -0
  76. package/core/docs/System/Init.md +9 -0
  77. package/core/docs/System/LinkedList.md +16 -0
  78. package/core/docs/System/List.md +13 -0
  79. package/core/docs/System/Map.md +14 -0
  80. package/core/docs/System/Math.md +11 -0
  81. package/core/docs/System/Mutex.md +10 -0
  82. package/core/docs/System/Nursery.md +5 -0
  83. package/core/docs/System/Sendable.md +5 -0
  84. package/core/docs/System/Set.md +14 -0
  85. package/core/docs/System/Stream/Directory.md +12 -0
  86. package/core/docs/System/Stream/File.md +21 -0
  87. package/core/docs/System/String.md +14 -0
  88. package/core/docs/System/StringBuilder.md +12 -0
  89. package/core/docs/System/Stringable.md +5 -0
  90. package/core/docs/System/Task.md +15 -0
  91. package/core/docs/System/Text/Json.md +12 -0
  92. package/core/docs/System/Text/JsonTree.md +21 -0
  93. package/core/docs/System/Text/Regex.md +12 -0
  94. package/core/docs/System/Time.md +11 -0
  95. package/core/docs/System/Tree.md +18 -0
  96. package/core/docs/System/Viewable.md +5 -0
  97. package/core/docs/System/bool.md +9 -0
  98. package/core/docs/System/char.md +9 -0
  99. package/core/docs/System/float.md +9 -0
  100. package/core/docs/System/int.md +10 -0
  101. package/core/docs/System/int64.md +9 -0
  102. package/core/docs/System/int8.md +9 -0
  103. package/core/docs/System/uint.md +9 -0
  104. package/core/docs/System/uint64.md +9 -0
  105. package/core/docs/System/uint8.md +9 -0
  106. package/core/package.jsonc +4 -0
  107. package/dist/index.mjs +417 -5490
  108. package/package.json +33 -30
  109. package/src/args.ts +171 -0
  110. package/src/index.ts +53 -104
  111. package/src/init.ts +128 -0
  112. package/src/test.ts +6 -2
  113. package/test/fixtures/build/calc.test +0 -0
  114. package/test/fixtures/build/calc.test.c +0 -969
  115. package/test/fixtures/build/main.h +0 -170
  116. package/test/fixtures/calc.test.nm +0 -32
  117. package/tsconfig.json +0 -21
  118. package/vite.config.ts +0 -7
@@ -0,0 +1,453 @@
1
+ /**
2
+ * A minimal blocking HTTP/1.1 client.
3
+ *
4
+ * Plain `http://` only — no TLS (an `https://` URL cannot be served; use a
5
+ * TLS proxy or wait for a TLS-capable transport). Construct an instance,
6
+ * call `get`/`post` (which block until the full response is received), then
7
+ * read the `status` field for the response's status code. `status` is 0 when
8
+ * DNS resolution or the connection fails.
9
+ *
10
+ * URLs may carry an explicit port (`http://host:8080/path`); the default is
11
+ * 80 and the default path is `/`. `post` sends `body` with a
12
+ * `Content-Type: application/x-www-form-urlencoded` header and a matching
13
+ * `Content-Length`; only the response body (after the blank header/body
14
+ * separator line) is returned.
15
+ *
16
+ * var Http h = Http()
17
+ * var string body = h.get("http://example.com/")
18
+ * var int code = h.status
19
+ * var string r = h.post("http://example.com/submit", "hello=world")
20
+ **/
21
+ pub struct Http {
22
+ // HTTP status code from the most recent request (e.g. 200). 0 if DNS or
23
+ // the connection failed.
24
+ pub var int status = 0
25
+
26
+ // Shared socket round-trip used by get/post. `method` is the request
27
+ // method string ("GET" / "POST"); a leading 'P' selects POST semantics
28
+ // (sends `body` and the Content-* headers). Sets self->status and returns
29
+ // the response body (empty string on failure).
30
+ func exchange = (ref self, string method, string url, string body, out string) {
31
+ ```
32
+ #arch: c
33
+ #scope: file
34
+ #include <sys/socket.h>
35
+ #include <netdb.h>
36
+ #include <unistd.h>
37
+ #include <string.h>
38
+ #include <stdlib.h>
39
+ ```
40
+ ```
41
+ #arch: c
42
+ const char *scheme = strstr(url, "://");
43
+ const char *hp = scheme ? scheme + 3 : url;
44
+ const char *colon = strchr(hp, ':');
45
+ const char *slash = strchr(hp, '/');
46
+ char host[256];
47
+ int port = 80;
48
+ const char *path = "/";
49
+
50
+ if (colon && (!slash || colon < slash)) {
51
+ int hlen = (int)(colon - hp);
52
+ if (hlen > 255) hlen = 255;
53
+ memcpy(host, hp, hlen);
54
+ host[hlen] = 0;
55
+ port = atoi(colon + 1);
56
+ } else {
57
+ const char *end = slash ? slash : hp + strlen(hp);
58
+ int hlen = (int)(end - hp);
59
+ if (hlen > 255) hlen = 255;
60
+ memcpy(host, hp, hlen);
61
+ host[hlen] = 0;
62
+ }
63
+ if (slash) path = slash;
64
+
65
+ struct addrinfo hints, *res;
66
+ memset(&hints, 0, sizeof(hints));
67
+ hints.ai_family = AF_INET;
68
+ hints.ai_socktype = SOCK_STREAM;
69
+ char portstr[16];
70
+ snprintf(portstr, sizeof(portstr), "%d", port);
71
+ if (getaddrinfo(host, portstr, &hints, &res) != 0) {
72
+ self->status = 0;
73
+ return strdup("");
74
+ }
75
+ int sock = socket(AF_INET, SOCK_STREAM, 0);
76
+ if (sock < 0) {
77
+ freeaddrinfo(res);
78
+ self->status = 0;
79
+ return strdup("");
80
+ }
81
+ if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
82
+ freeaddrinfo(res);
83
+ close(sock);
84
+ self->status = 0;
85
+ return strdup("");
86
+ }
87
+ freeaddrinfo(res);
88
+
89
+ char req[1600];
90
+ int off = snprintf(req, sizeof(req),
91
+ "%s %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n",
92
+ method, path, host);
93
+ if (method[0] == 'P') {
94
+ int blen = (int)strlen(body);
95
+ off += snprintf(req + off, sizeof(req) - off,
96
+ "Content-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n\r\n",
97
+ blen);
98
+ send(sock, req, off, 0);
99
+ send(sock, body, blen, 0);
100
+ } else {
101
+ off += snprintf(req + off, sizeof(req) - off, "\r\n");
102
+ send(sock, req, off, 0);
103
+ }
104
+
105
+ int cap = 4096, len = 0;
106
+ char *buf = (char*)malloc(cap);
107
+ int n;
108
+ while ((n = recv(sock, buf + len, cap - len - 1, 0)) > 0) {
109
+ len += n;
110
+ if (len + 1 >= cap) {
111
+ cap *= 2;
112
+ buf = (char*)realloc(buf, cap);
113
+ }
114
+ }
115
+ buf[len] = 0;
116
+ close(sock);
117
+
118
+ int code = 0;
119
+ if (len >= 12 && strncmp(buf, "HTTP/", 5) == 0) {
120
+ code = atoi(buf + 9);
121
+ }
122
+ self->status = code;
123
+
124
+ char *body_start = strstr(buf, "\r\n\r\n");
125
+ if (body_start) {
126
+ char *result = strdup(body_start + 4);
127
+ free(buf);
128
+ return result;
129
+ }
130
+ return buf;
131
+ ```
132
+ ```
133
+ #arch: aarch64
134
+ // x0=self(->x19), x1=method, x2=url, x3=body
135
+ // macOS arm64 passes variadic args on the caller stack at [sp+0..], so
136
+ // [sp+0..47] is reserved scratch for snprintf variadic args and the
137
+ // addrinfo hints live above it. Stack frame (2048 bytes):
138
+ // #0 variadic scratch (snprintf args)
139
+ // #48 hints (struct addrinfo, 48 bytes)
140
+ // #96 res* #104 sock fd
141
+ // #112 port #120 hp (host start)
142
+ // #128 method #136 url
143
+ // #144 body #152 path
144
+ // #160 colon/blen/buf #168 slash/cap
145
+ // #176 hostlen/req_off #184 portstr (16)
146
+ // #208 host buffer (256) #464 request buffer (1584)
147
+ sub sp, sp, #2048
148
+ str x1, [sp, #128]
149
+ str x2, [sp, #136]
150
+ str x3, [sp, #144]
151
+ mov x0, #80
152
+ str x0, [sp, #112]
153
+ adr x0, .Lhttp_slash
154
+ str x0, [sp, #152]
155
+
156
+ // hp = (strstr(url, "://") ?: url) + 3 when scheme present
157
+ ldr x0, [sp, #136]
158
+ adr x1, .Lhttp_scheme
159
+ bl _strstr
160
+ cbz x0, .Lhttp_sethp
161
+ add x0, x0, #3
162
+ .Lhttp_sethp:
163
+ str x0, [sp, #120]
164
+
165
+ // colon = strchr(hp, ':'); slash = strchr(hp, '/')
166
+ ldr x0, [sp, #120]
167
+ mov x1, #0x3A
168
+ bl _strchr
169
+ str x0, [sp, #160]
170
+ ldr x0, [sp, #120]
171
+ mov x1, #0x2F
172
+ bl _strchr
173
+ str x0, [sp, #168]
174
+
175
+ // if (colon && (!slash || colon < slash)) -> port branch
176
+ ldr x0, [sp, #160]
177
+ cbz x0, .Lhttp_np
178
+ ldr x1, [sp, #168]
179
+ cbz x1, .Lhttp_port
180
+ cmp x0, x1
181
+ b.lo .Lhttp_port
182
+ .Lhttp_np:
183
+ // hostlen = slash ? (slash - hp) : strlen(hp); path = slash
184
+ ldr x0, [sp, #168]
185
+ cbz x0, .Lhttp_np_strlen
186
+ ldr x1, [sp, #120]
187
+ sub x0, x0, x1
188
+ str x0, [sp, #176]
189
+ ldr x0, [sp, #168]
190
+ str x0, [sp, #152]
191
+ b .Lhttp_cph
192
+ .Lhttp_np_strlen:
193
+ ldr x0, [sp, #120]
194
+ bl _strlen
195
+ str x0, [sp, #176]
196
+ b .Lhttp_cph
197
+ .Lhttp_port:
198
+ // hostlen = colon - hp; port = atoi(colon + 1)
199
+ ldr x0, [sp, #120]
200
+ ldr x1, [sp, #160]
201
+ sub x0, x1, x0
202
+ str x0, [sp, #176]
203
+ ldr x0, [sp, #160]
204
+ add x0, x0, #1
205
+ bl _atoi
206
+ str x0, [sp, #112]
207
+ ldr x0, [sp, #168]
208
+ cbz x0, .Lhttp_cph
209
+ str x0, [sp, #152]
210
+
211
+ // hostlen = min(hostlen, 255); memcpy(hostbuf, hp, hostlen); hostbuf[hostlen]=0
212
+ .Lhttp_cph:
213
+ ldr x0, [sp, #176]
214
+ mov x9, #255
215
+ cmp x0, x9
216
+ csel x0, x0, x9, ls
217
+ str x0, [sp, #176]
218
+ add x0, sp, #208
219
+ ldr x1, [sp, #120]
220
+ ldr x2, [sp, #176]
221
+ bl _memcpy
222
+ add x0, sp, #208
223
+ ldr x1, [sp, #176]
224
+ strb wzr, [x0, x1]
225
+
226
+ // memset(&hints, 0, 48); hints.ai_family=AF_INET(2); hints.ai_socktype=SOCK_STREAM(1)
227
+ add x0, sp, #48
228
+ mov x1, xzr
229
+ mov x2, #48
230
+ bl _memset
231
+ mov w0, #2
232
+ str w0, [sp, #52]
233
+ mov w0, #1
234
+ str w0, [sp, #56]
235
+ // snprintf(portstr, 16, "%ld", port) — variadic arg on stack at [sp+0]
236
+ ldr x9, [sp, #112]
237
+ str x9, [sp, #0]
238
+ add x0, sp, #184
239
+ mov x1, #16
240
+ adr x2, .Lhttp_fmt_ld
241
+ bl _snprintf
242
+ // getaddrinfo(host, portstr, &hints, &res)
243
+ add x0, sp, #208
244
+ add x1, sp, #184
245
+ add x2, sp, #48
246
+ add x3, sp, #96
247
+ bl _getaddrinfo
248
+ cbnz w0, .Lhttp_fail
249
+
250
+ // sock = socket(AF_INET, SOCK_STREAM, 0)
251
+ mov x0, #2
252
+ mov x1, #1
253
+ mov x2, xzr
254
+ bl _socket
255
+ cmp w0, #0
256
+ b.ge .Lhttp_sockok
257
+ ldr x0, [sp, #96]
258
+ bl _freeaddrinfo
259
+ b .Lhttp_fail
260
+ .Lhttp_sockok:
261
+ str w0, [sp, #104]
262
+ // connect(sock, res->ai_addr (off 32), res->ai_addrlen (off 16))
263
+ ldr x9, [sp, #96]
264
+ ldr x1, [x9, #32]
265
+ ldr w2, [x9, #16]
266
+ ldr w0, [sp, #104]
267
+ bl _connect
268
+ cmp w0, #0
269
+ b.ge .Lhttp_connected
270
+ ldr x0, [sp, #96]
271
+ bl _freeaddrinfo
272
+ ldr w0, [sp, #104]
273
+ bl _close
274
+ b .Lhttp_fail
275
+ .Lhttp_connected:
276
+ ldr x0, [sp, #96]
277
+ bl _freeaddrinfo
278
+
279
+ // off = snprintf(req, 1584, common_fmt, method, path, host)
280
+ // variadic args on stack: method@[0], path@[8], host@[16]
281
+ ldr x9, [sp, #128]
282
+ str x9, [sp, #0]
283
+ ldr x9, [sp, #152]
284
+ str x9, [sp, #8]
285
+ add x9, sp, #208
286
+ str x9, [sp, #16]
287
+ add x0, sp, #464
288
+ mov x1, #1584
289
+ adr x2, .Lhttp_reqcommon
290
+ bl _snprintf
291
+ sxtw x0, w0
292
+ str x0, [sp, #176]
293
+
294
+ // if method[0] == 'P' (0x50) -> POST
295
+ ldr x0, [sp, #128]
296
+ ldrb w0, [x0]
297
+ cmp w0, #0x50
298
+ b.ne .Lhttp_getsend
299
+
300
+ // POST: blen = strlen(body); append Content-Length; send headers; send body
301
+ ldr x0, [sp, #144]
302
+ bl _strlen
303
+ str x0, [sp, #160]
304
+ // snprintf(req+off, 1584-off, reqpost, blen) — blen on stack at [sp+0]
305
+ ldr x9, [sp, #160]
306
+ str x9, [sp, #0]
307
+ add x0, sp, #464
308
+ ldr x1, [sp, #176]
309
+ add x0, x0, x1
310
+ mov x1, #1584
311
+ ldr x2, [sp, #176]
312
+ sub x1, x1, x2
313
+ adr x2, .Lhttp_reqpost
314
+ bl _snprintf
315
+ sxtw x0, w0
316
+ ldr x1, [sp, #176]
317
+ add x1, x1, x0
318
+ str x1, [sp, #176]
319
+ ldr w0, [sp, #104]
320
+ add x1, sp, #464
321
+ ldr x2, [sp, #176]
322
+ mov x3, xzr
323
+ bl _send
324
+ ldr x0, [sp, #144]
325
+ bl _strlen
326
+ mov x2, x0
327
+ ldr w0, [sp, #104]
328
+ ldr x1, [sp, #144]
329
+ mov x3, xzr
330
+ bl _send
331
+ b .Lhttp_recv
332
+
333
+ .Lhttp_getsend:
334
+ // GET: append trailing "\r\n" (no variadic) and send
335
+ add x0, sp, #464
336
+ ldr x1, [sp, #176]
337
+ add x0, x0, x1
338
+ mov x1, #1584
339
+ ldr x2, [sp, #176]
340
+ sub x1, x1, x2
341
+ adr x2, .Lhttp_crlf
342
+ bl _snprintf
343
+ sxtw x0, w0
344
+ ldr x1, [sp, #176]
345
+ add x1, x1, x0
346
+ str x1, [sp, #176]
347
+ ldr w0, [sp, #104]
348
+ add x1, sp, #464
349
+ ldr x2, [sp, #176]
350
+ mov x3, xzr
351
+ bl _send
352
+
353
+ // recv loop: buf = malloc(4096); grow as needed
354
+ .Lhttp_recv:
355
+ mov x0, #4096
356
+ bl _malloc
357
+ str x0, [sp, #160]
358
+ mov x0, #4096
359
+ str x0, [sp, #168]
360
+ str xzr, [sp, #96]
361
+ .Lhttp_recvloop:
362
+ ldr w0, [sp, #104]
363
+ ldr x1, [sp, #160]
364
+ ldr x2, [sp, #96]
365
+ add x1, x1, x2
366
+ ldr x2, [sp, #168]
367
+ ldr x3, [sp, #96]
368
+ sub x2, x2, x3
369
+ sub x2, x2, #1
370
+ mov x3, xzr
371
+ bl _recv
372
+ cmp x0, #0
373
+ ble .Lhttp_recvdone
374
+ ldr x1, [sp, #96]
375
+ add x1, x1, x0
376
+ str x1, [sp, #96]
377
+ add x2, x1, #1
378
+ ldr x3, [sp, #168]
379
+ cmp x2, x3
380
+ blt .Lhttp_recvloop
381
+ ldr x0, [sp, #168]
382
+ lsl x0, x0, #1
383
+ str x0, [sp, #168]
384
+ mov x1, x0
385
+ ldr x0, [sp, #160]
386
+ bl _realloc
387
+ str x0, [sp, #160]
388
+ b .Lhttp_recvloop
389
+
390
+ .Lhttp_recvdone:
391
+ // buf[len] = 0; close(sock)
392
+ ldr x0, [sp, #160]
393
+ ldr x1, [sp, #96]
394
+ strb wzr, [x0, x1]
395
+ ldr w0, [sp, #104]
396
+ bl _close
397
+ // self->status = atoi(buf + 9)
398
+ ldr x0, [sp, #160]
399
+ add x0, x0, #9
400
+ bl _atoi
401
+ sxtw x0, w0
402
+ str x0, [x19, #8]
403
+ // body_start = strstr(buf, "\r\n\r\n")
404
+ ldr x0, [sp, #160]
405
+ adr x1, .Lhttp_hdrsep
406
+ bl _strstr
407
+ cbz x0, .Lhttp_retbuf
408
+ // result = strdup(body_start + 4); free(buf); return result
409
+ add x0, x0, #4
410
+ bl _strdup
411
+ str x0, [sp, #112]
412
+ ldr x0, [sp, #160]
413
+ bl _free
414
+ ldr x0, [sp, #112]
415
+ add sp, sp, #2048
416
+ b .return_Http_exchange
417
+ .Lhttp_retbuf:
418
+ ldr x0, [sp, #160]
419
+ add sp, sp, #2048
420
+ b .return_Http_exchange
421
+ .Lhttp_fail:
422
+ str xzr, [x19, #8]
423
+ adr x0, .Lhttp_empty
424
+ bl _strdup
425
+ add sp, sp, #2048
426
+ b .return_Http_exchange
427
+
428
+ .Lhttp_scheme: .asciz "://"
429
+ .Lhttp_slash: .asciz "/"
430
+ .Lhttp_fmt_ld: .asciz "%ld"
431
+ .Lhttp_crlf: .asciz "\r\n"
432
+ .Lhttp_hdrsep: .asciz "\r\n\r\n"
433
+ .Lhttp_empty: .asciz ""
434
+ .Lhttp_reqcommon: .asciz "%s %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n"
435
+ .Lhttp_reqpost: .asciz "Content-Type: application/x-www-form-urlencoded\r\nContent-Length: %ld\r\n\r\n"
436
+ .p2align 2
437
+ ```
438
+ return ""
439
+ }
440
+
441
+ // Issue a blocking GET request to `url`. Returns the response body and
442
+ // sets `self.status` to the response's status code (0 on failure).
443
+ pub func get = (ref self, string url, out string) {
444
+ return self.exchange("GET", url, "")
445
+ }
446
+
447
+ // Issue a blocking POST request to `url` with `body` as the payload.
448
+ // Returns the response body and sets `self.status` to the response's
449
+ // status code (0 on failure).
450
+ pub func post = (ref self, string url, string body, out string) {
451
+ return self.exchange("POST", url, body)
452
+ }
453
+ }
@@ -0,0 +1,154 @@
1
+ /**
2
+ * A UTF-8 text string — a heap-owned, length-tracked sequence of bytes
3
+ **/
4
+ pub struct string: Stringable {
5
+ pub func to_string = (self, out string) {
6
+ ```
7
+ #arch: c
8
+ return strdup(self);
9
+ ```
10
+ ```
11
+ #arch: aarch64
12
+ mov x0, x19
13
+ ```
14
+ }
15
+
16
+ pub func at = (self, int index: index >= 0 && index < self.length, out char) {
17
+ ```
18
+ #arch: c
19
+ return self[index];
20
+ ```
21
+ ```
22
+ #arch: aarch64
23
+ // x19 = self (pointer), x1 = index
24
+ ldrb w0, [x19, x1]
25
+ ```
26
+ }
27
+
28
+ // A non-owning slice [start, end) into self's buffer. Returns a `view
29
+ // string` (ptr, len) that borrows from self: it may not outlive self's
30
+ // scope and is invalidated if self is reassigned. Use .to_string() to
31
+ // materialize an owned copy.
32
+ pub func slice = (
33
+ self,
34
+ int start: start >= 0 && start <= self.length,
35
+ int end: end >= start && end <= self.length,
36
+ out view string
37
+ ) {
38
+ ```
39
+ #arch: c
40
+ nomen_view _r;
41
+ _r.ptr = (void*)(self + start);
42
+ _r.len = (long)(end - start);
43
+ return _r;
44
+ ```
45
+ ```
46
+ #arch: aarch64
47
+ // view string is (ptr, len), returned in the x0/x1 register pair.
48
+ // x19 = self (char*), x1 = start, x2 = end (retained through prologue).
49
+ add x0, x19, x1 // ptr = self + start
50
+ sub x1, x2, x1 // len = end - start
51
+ ```
52
+ }
53
+
54
+ pub func set = (ref self, int index: index >= 0 && index < self.length, char value) {
55
+ ```
56
+ #arch: c
57
+ (*self)[index] = value;
58
+ ```
59
+ ```
60
+ #arch: aarch64
61
+ // x19 = self (pointer), x1 = index, w2 = value
62
+ strb w2, [x19, x1]
63
+ ```
64
+ }
65
+
66
+ pub func #op_eq = (self, string other, out bool) {
67
+ ```
68
+ #arch: c
69
+ return strcmp(self, other) == 0;
70
+ ```
71
+ ```
72
+ #arch: aarch64
73
+ // x0 = self, x1 = other on entry
74
+ bl _strcmp
75
+ cmp x0, #0
76
+ cset x0, eq
77
+ ```
78
+ }
79
+
80
+ pub func #op_add = (self, string other, out string) {
81
+ ```
82
+ #arch: c
83
+ int left_len = strlen(self);
84
+ int right_len = strlen(other);
85
+ char* result = malloc(left_len + right_len + 1);
86
+ strcpy(result, self);
87
+ strcat(result, other);
88
+ return result;
89
+ ```
90
+ ```
91
+ #arch: aarch64
92
+ stp x20, x21, [sp, #-16]!
93
+ mov x20, x1
94
+ bl _strlen
95
+ mov x21, x0
96
+ mov x0, x20
97
+ bl _strlen
98
+ add x0, x21, x0
99
+ add x0, x0, #1
100
+ bl _malloc
101
+ mov x21, x0
102
+ mov x1, x19
103
+ bl _strcpy
104
+ mov x0, x21
105
+ mov x1, x20
106
+ bl _strcat
107
+ mov x0, x21
108
+ ldp x20, x21, [sp], #16
109
+ ```
110
+ }
111
+
112
+ pub func #op_mul = (self, int count, out string) {
113
+ ```
114
+ #arch: c
115
+ size_t str_len = strlen(self);
116
+ size_t total = str_len * (size_t)count + 1;
117
+ char* buf = malloc(total);
118
+ char* p = buf;
119
+ for (int i = 0; i < count; i++) {
120
+ memcpy(p, self, str_len);
121
+ p += str_len;
122
+ }
123
+ *p = 0;
124
+ return buf;
125
+ ```
126
+ ```
127
+ #arch: aarch64
128
+ stp x20, x21, [sp, #-16]!
129
+ stp x22, xzr, [sp, #-16]!
130
+ mov x20, x1
131
+ bl _strlen
132
+ mov x21, x0
133
+ mul x0, x0, x20
134
+ add x0, x0, #1
135
+ bl _malloc
136
+ str x0, [x29, #8]
137
+ mov x22, x0
138
+ .Lmul_loop:
139
+ cbz x20, .Lmul_done
140
+ mov x0, x22
141
+ mov x1, x19
142
+ mov x2, x21
143
+ bl _memcpy
144
+ add x22, x22, x21
145
+ sub x20, x20, #1
146
+ b .Lmul_loop
147
+ .Lmul_done:
148
+ strb wzr, [x22]
149
+ ldr x0, [x29, #8]
150
+ ldp x22, xzr, [sp], #16
151
+ ldp x20, x21, [sp], #16
152
+ ```
153
+ }
154
+ }