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.
- package/NOMEN_AGENTS.md +235 -0
- package/core/System/Ansi.nm +150 -0
- package/core/System/Array.nm +358 -0
- package/core/System/BigInt.nm +887 -0
- package/core/System/Buffer.nm +526 -0
- package/core/System/Channel.nm +198 -0
- package/core/System/ClassBuffer.nm +229 -0
- package/core/System/Console.nm +211 -0
- package/core/System/Controls/Button.nm +138 -0
- package/core/System/Controls/CheckBox.nm +158 -0
- package/core/System/Controls/Container.nm +1562 -0
- package/core/System/Controls/Control.nm +28 -0
- package/core/System/Controls/Geometry.nm +101 -0
- package/core/System/Controls/Layout.nm +228 -0
- package/core/System/Controls/LayoutParams.nm +50 -0
- package/core/System/Controls/Text.nm +129 -0
- package/core/System/Controls/TextBox.nm +157 -0
- package/core/System/Controls/Window.nm +280 -0
- package/core/System/Disposable.nm +8 -0
- package/core/System/Enumerable.nm +10 -0
- package/core/System/Equatable.nm +10 -0
- package/core/System/Graph.nm +68 -0
- package/core/System/Hashable.nm +13 -0
- package/core/System/Init.nm +21 -0
- package/core/System/LinkedList.nm +64 -0
- package/core/System/List.nm +44 -0
- package/core/System/Map.nm +153 -0
- package/core/System/Math.nm +54 -0
- package/core/System/Mutex.nm +78 -0
- package/core/System/Nursery.nm +27 -0
- package/core/System/Sendable.nm +9 -0
- package/core/System/Set.nm +97 -0
- package/core/System/Stream/Directory.nm +176 -0
- package/core/System/Stream/File.nm +432 -0
- package/core/System/Stream/Http.nm +453 -0
- package/core/System/String.nm +154 -0
- package/core/System/StringBuilder.nm +249 -0
- package/core/System/Stringable.nm +8 -0
- package/core/System/Task.nm +263 -0
- package/core/System/Test.nm +241 -0
- package/core/System/Text/Json.nm +377 -0
- package/core/System/Text/JsonTree.nm +187 -0
- package/core/System/Text/Regex.nm +655 -0
- package/core/System/Time.nm +112 -0
- package/core/System/Tree.nm +70 -0
- package/core/System/Viewable.nm +27 -0
- package/core/System/bool.nm +66 -0
- package/core/System/char.nm +42 -0
- package/core/System/float.nm +43 -0
- package/core/System/int.nm +54 -0
- package/core/System/int64.nm +42 -0
- package/core/System/int8.nm +42 -0
- package/core/System/uint.nm +42 -0
- package/core/System/uint64.nm +42 -0
- package/core/System/uint8.nm +42 -0
- package/core/docs/System/Ansi.md +40 -0
- package/core/docs/System/Array.md +16 -0
- package/core/docs/System/BigInt.md +30 -0
- package/core/docs/System/Buffer.md +31 -0
- package/core/docs/System/Channel.md +10 -0
- package/core/docs/System/ClassBuffer.md +15 -0
- package/core/docs/System/Console.md +13 -0
- package/core/docs/System/Controls/Button.md +12 -0
- package/core/docs/System/Controls/CheckBox.md +15 -0
- package/core/docs/System/Controls/Container.md +82 -0
- package/core/docs/System/Controls/Control.md +5 -0
- package/core/docs/System/Controls/Geometry.md +26 -0
- package/core/docs/System/Controls/Layout.md +37 -0
- package/core/docs/System/Controls/LayoutParams.md +13 -0
- package/core/docs/System/Controls/Text.md +12 -0
- package/core/docs/System/Controls/TextBox.md +13 -0
- package/core/docs/System/Controls/Window.md +20 -0
- package/core/docs/System/Disposable.md +5 -0
- package/core/docs/System/Enumerable.md +5 -0
- package/core/docs/System/Graph.md +17 -0
- package/core/docs/System/Init.md +9 -0
- package/core/docs/System/LinkedList.md +16 -0
- package/core/docs/System/List.md +13 -0
- package/core/docs/System/Map.md +14 -0
- package/core/docs/System/Math.md +11 -0
- package/core/docs/System/Mutex.md +10 -0
- package/core/docs/System/Nursery.md +5 -0
- package/core/docs/System/Sendable.md +5 -0
- package/core/docs/System/Set.md +14 -0
- package/core/docs/System/Stream/Directory.md +12 -0
- package/core/docs/System/Stream/File.md +21 -0
- package/core/docs/System/String.md +14 -0
- package/core/docs/System/StringBuilder.md +12 -0
- package/core/docs/System/Stringable.md +5 -0
- package/core/docs/System/Task.md +15 -0
- package/core/docs/System/Text/Json.md +12 -0
- package/core/docs/System/Text/JsonTree.md +21 -0
- package/core/docs/System/Text/Regex.md +12 -0
- package/core/docs/System/Time.md +11 -0
- package/core/docs/System/Tree.md +18 -0
- package/core/docs/System/Viewable.md +5 -0
- package/core/docs/System/bool.md +9 -0
- package/core/docs/System/char.md +9 -0
- package/core/docs/System/float.md +9 -0
- package/core/docs/System/int.md +10 -0
- package/core/docs/System/int64.md +9 -0
- package/core/docs/System/int8.md +9 -0
- package/core/docs/System/uint.md +9 -0
- package/core/docs/System/uint64.md +9 -0
- package/core/docs/System/uint8.md +9 -0
- package/core/package.jsonc +4 -0
- package/dist/index.mjs +417 -5490
- package/package.json +33 -30
- package/src/args.ts +171 -0
- package/src/index.ts +53 -104
- package/src/init.ts +128 -0
- package/src/test.ts +6 -2
- package/test/fixtures/build/calc.test +0 -0
- package/test/fixtures/build/calc.test.c +0 -969
- package/test/fixtures/build/main.h +0 -170
- package/test/fixtures/calc.test.nm +0 -32
- package/tsconfig.json +0 -21
- package/vite.config.ts +0 -7
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A file handle for reading and writing, plus static one-shot helpers.
|
|
3
|
+
*
|
|
4
|
+
* `File` is a handle opened with a mode string (`"r"`, `"w"`, …) and closed
|
|
5
|
+
* automatically by its `#destroy` when it goes out of scope. Read methods set
|
|
6
|
+
* the `eof` flag when the end of the file is reached.
|
|
7
|
+
*
|
|
8
|
+
* var File w = File()
|
|
9
|
+
* w.open("notes.txt", "w")
|
|
10
|
+
* w.writeLine("hello")
|
|
11
|
+
* w.writeLine("world")
|
|
12
|
+
* w.close()
|
|
13
|
+
*
|
|
14
|
+
* var File r = File()
|
|
15
|
+
* r.open("notes.txt", "r")
|
|
16
|
+
* const string first = r.readLine() // "hello"
|
|
17
|
+
* const string rest = r.readAll() // read the remaining bytes
|
|
18
|
+
*
|
|
19
|
+
* Static one-shot helpers do the open/read/close in one call:
|
|
20
|
+
*
|
|
21
|
+
* File.write_all("out.txt", "payload")
|
|
22
|
+
* const string body = File.read_all("out.txt")
|
|
23
|
+
* const bool ok = File.exists("out.txt")
|
|
24
|
+
* File.delete("out.txt")
|
|
25
|
+
**/
|
|
26
|
+
pub struct File {
|
|
27
|
+
var uint64 handle = 0
|
|
28
|
+
pub var eof = false
|
|
29
|
+
|
|
30
|
+
// Open the file at `path` with a C mode string ("r", "w", "a", …).
|
|
31
|
+
pub func open = (ref self, string path, string mode) {
|
|
32
|
+
```
|
|
33
|
+
#arch: c
|
|
34
|
+
self->handle = (unsigned long long)fopen(path, mode);
|
|
35
|
+
```
|
|
36
|
+
```
|
|
37
|
+
#arch: aarch64
|
|
38
|
+
mov x0, x1
|
|
39
|
+
mov x1, x2
|
|
40
|
+
bl _fopen
|
|
41
|
+
str x0, [x19, #8]
|
|
42
|
+
```
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Close the handle. Also performed automatically by #destroy; calling
|
|
46
|
+
// close explicitly releases the resource early.
|
|
47
|
+
pub func close = (ref self) {
|
|
48
|
+
```
|
|
49
|
+
#arch: c
|
|
50
|
+
if (self->handle) {
|
|
51
|
+
fclose((FILE*)(unsigned long long)self->handle);
|
|
52
|
+
self->handle = 0;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
```
|
|
56
|
+
#arch: aarch64
|
|
57
|
+
ldr x0, [x19, #8]
|
|
58
|
+
cbz x0, .Lfile_close_end
|
|
59
|
+
bl _fclose
|
|
60
|
+
.Lfile_close_end:
|
|
61
|
+
str xzr, [x19, #8]
|
|
62
|
+
```
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Read every byte from the current position to EOF and return it. Sets
|
|
66
|
+
// `eof`.
|
|
67
|
+
pub func readAll = (ref self, out string) {
|
|
68
|
+
```
|
|
69
|
+
#arch: c
|
|
70
|
+
FILE *f = (FILE*)(unsigned long long)self->handle;
|
|
71
|
+
fseek(f, 0, SEEK_END);
|
|
72
|
+
long size = ftell(f);
|
|
73
|
+
fseek(f, 0, SEEK_SET);
|
|
74
|
+
char *buf = (char*)malloc(size + 1);
|
|
75
|
+
fread(buf, 1, size, f);
|
|
76
|
+
buf[size] = 0;
|
|
77
|
+
self->eof = 1;
|
|
78
|
+
return buf;
|
|
79
|
+
```
|
|
80
|
+
```
|
|
81
|
+
#arch: aarch64
|
|
82
|
+
sub sp, sp, #16
|
|
83
|
+
ldr x0, [x19, #8]
|
|
84
|
+
mov x1, #0
|
|
85
|
+
mov x2, #2
|
|
86
|
+
bl _fseek
|
|
87
|
+
ldr x0, [x19, #8]
|
|
88
|
+
bl _ftell
|
|
89
|
+
str x0, [sp, #0]
|
|
90
|
+
ldr x0, [x19, #8]
|
|
91
|
+
mov x1, #0
|
|
92
|
+
mov x2, #0
|
|
93
|
+
bl _fseek
|
|
94
|
+
ldr x0, [sp, #0]
|
|
95
|
+
add x0, x0, #1
|
|
96
|
+
bl _malloc
|
|
97
|
+
str x0, [sp, #8]
|
|
98
|
+
ldr x0, [sp, #8]
|
|
99
|
+
mov x1, #1
|
|
100
|
+
ldr x2, [sp, #0]
|
|
101
|
+
ldr x3, [x19, #8]
|
|
102
|
+
bl _fread
|
|
103
|
+
ldr x0, [sp, #8]
|
|
104
|
+
ldr x1, [sp, #0]
|
|
105
|
+
strb wzr, [x0, x1]
|
|
106
|
+
mov w1, #1
|
|
107
|
+
strb w1, [x19, #16]
|
|
108
|
+
ldr x0, [sp, #8]
|
|
109
|
+
add sp, sp, #16
|
|
110
|
+
b .return_File_readAll
|
|
111
|
+
```
|
|
112
|
+
return ""
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Write a string at the current position.
|
|
116
|
+
pub func writeAll = (self, string data) {
|
|
117
|
+
```
|
|
118
|
+
#arch: c
|
|
119
|
+
FILE *f = (FILE*)(unsigned long long)self->handle;
|
|
120
|
+
fputs(data, f);
|
|
121
|
+
```
|
|
122
|
+
```
|
|
123
|
+
#arch: aarch64
|
|
124
|
+
mov x0, x1
|
|
125
|
+
ldr x1, [x19, #8]
|
|
126
|
+
bl _fputs
|
|
127
|
+
```
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Read up to the next '\n' (the newline is not included). Sets `eof`
|
|
131
|
+
// when the end of the file is reached.
|
|
132
|
+
pub func readLine = (ref self, out string) {
|
|
133
|
+
```
|
|
134
|
+
#arch: c
|
|
135
|
+
FILE *f = (FILE*)(unsigned long long)self->handle;
|
|
136
|
+
int cap = 16;
|
|
137
|
+
int len = 0;
|
|
138
|
+
char *buf = (char*)malloc(cap);
|
|
139
|
+
int c = fgetc(f);
|
|
140
|
+
while (c != EOF && c != '\n') {
|
|
141
|
+
if (len + 1 >= cap) {
|
|
142
|
+
cap *= 2;
|
|
143
|
+
buf = (char*)realloc(buf, cap);
|
|
144
|
+
}
|
|
145
|
+
buf[len++] = (char)c;
|
|
146
|
+
c = fgetc(f);
|
|
147
|
+
}
|
|
148
|
+
buf[len] = 0;
|
|
149
|
+
if (c == EOF) self->eof = 1;
|
|
150
|
+
return buf;
|
|
151
|
+
```
|
|
152
|
+
```
|
|
153
|
+
#arch: aarch64
|
|
154
|
+
sub sp, sp, #32
|
|
155
|
+
mov x0, #16
|
|
156
|
+
bl _malloc
|
|
157
|
+
str x0, [sp, #0]
|
|
158
|
+
mov x1, #16
|
|
159
|
+
str x1, [sp, #8]
|
|
160
|
+
str xzr, [sp, #16]
|
|
161
|
+
ldr x0, [x19, #8]
|
|
162
|
+
bl _fgetc
|
|
163
|
+
str w0, [sp, #24]
|
|
164
|
+
.Lfile_readline_loop:
|
|
165
|
+
ldr w0, [sp, #24]
|
|
166
|
+
cmp w0, #0
|
|
167
|
+
blt .Lfile_readline_done
|
|
168
|
+
cmp w0, #10
|
|
169
|
+
beq .Lfile_readline_done
|
|
170
|
+
ldr x0, [sp, #16]
|
|
171
|
+
add x0, x0, #1
|
|
172
|
+
ldr x1, [sp, #8]
|
|
173
|
+
cmp x0, x1
|
|
174
|
+
ble .Lfile_readline_store
|
|
175
|
+
ldr x1, [sp, #8]
|
|
176
|
+
lsl x1, x1, #1
|
|
177
|
+
str x1, [sp, #8]
|
|
178
|
+
ldr x0, [sp, #0]
|
|
179
|
+
bl _realloc
|
|
180
|
+
str x0, [sp, #0]
|
|
181
|
+
.Lfile_readline_store:
|
|
182
|
+
ldr x0, [sp, #0]
|
|
183
|
+
ldr x1, [sp, #16]
|
|
184
|
+
ldr w2, [sp, #24]
|
|
185
|
+
strb w2, [x0, x1]
|
|
186
|
+
ldr x0, [sp, #16]
|
|
187
|
+
add x0, x0, #1
|
|
188
|
+
str x0, [sp, #16]
|
|
189
|
+
ldr x0, [x19, #8]
|
|
190
|
+
bl _fgetc
|
|
191
|
+
str w0, [sp, #24]
|
|
192
|
+
b .Lfile_readline_loop
|
|
193
|
+
.Lfile_readline_done:
|
|
194
|
+
ldr x0, [sp, #0]
|
|
195
|
+
ldr x1, [sp, #16]
|
|
196
|
+
strb wzr, [x0, x1]
|
|
197
|
+
ldr w0, [sp, #24]
|
|
198
|
+
cmp w0, #0
|
|
199
|
+
bge .Lfile_readline_ret
|
|
200
|
+
mov w1, #1
|
|
201
|
+
strb w1, [x19, #16]
|
|
202
|
+
.Lfile_readline_ret:
|
|
203
|
+
ldr x0, [sp, #0]
|
|
204
|
+
add sp, sp, #32
|
|
205
|
+
b .return_File_readLine
|
|
206
|
+
```
|
|
207
|
+
return ""
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Write a string followed by '\n'.
|
|
211
|
+
pub func writeLine = (self, string data) {
|
|
212
|
+
```
|
|
213
|
+
#arch: c
|
|
214
|
+
FILE *f = (FILE*)(unsigned long long)self->handle;
|
|
215
|
+
fputs(data, f);
|
|
216
|
+
fputc('\n', f);
|
|
217
|
+
```
|
|
218
|
+
```
|
|
219
|
+
#arch: aarch64
|
|
220
|
+
mov x0, x1
|
|
221
|
+
ldr x1, [x19, #8]
|
|
222
|
+
bl _fputs
|
|
223
|
+
mov w0, #10
|
|
224
|
+
ldr x1, [x19, #8]
|
|
225
|
+
bl _fputc
|
|
226
|
+
```
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Read up to `size` bytes from the current position. Sets `eof` if fewer
|
|
230
|
+
// than `size` bytes remain.
|
|
231
|
+
pub func readChunk = (ref self, int size, out string) {
|
|
232
|
+
```
|
|
233
|
+
#arch: c
|
|
234
|
+
FILE *f = (FILE*)(unsigned long long)self->handle;
|
|
235
|
+
char *buf = (char*)malloc(size + 1);
|
|
236
|
+
long n = fread(buf, 1, size, f);
|
|
237
|
+
buf[n] = 0;
|
|
238
|
+
if (n < size) self->eof = 1;
|
|
239
|
+
return buf;
|
|
240
|
+
```
|
|
241
|
+
```
|
|
242
|
+
#arch: aarch64
|
|
243
|
+
sub sp, sp, #16
|
|
244
|
+
str x1, [sp, #0]
|
|
245
|
+
ldr x0, [sp, #0]
|
|
246
|
+
add x0, x0, #1
|
|
247
|
+
bl _malloc
|
|
248
|
+
str x0, [sp, #8]
|
|
249
|
+
ldr x0, [sp, #8]
|
|
250
|
+
mov x1, #1
|
|
251
|
+
ldr x2, [sp, #0]
|
|
252
|
+
ldr x3, [x19, #8]
|
|
253
|
+
bl _fread
|
|
254
|
+
ldr x1, [sp, #8]
|
|
255
|
+
strb wzr, [x1, x0]
|
|
256
|
+
ldr x2, [sp, #0]
|
|
257
|
+
cmp x0, x2
|
|
258
|
+
bge .Lfile_readchunk_ret
|
|
259
|
+
mov w3, #1
|
|
260
|
+
strb w3, [x19, #16]
|
|
261
|
+
.Lfile_readchunk_ret:
|
|
262
|
+
ldr x0, [sp, #8]
|
|
263
|
+
add sp, sp, #16
|
|
264
|
+
b .return_File_readChunk
|
|
265
|
+
```
|
|
266
|
+
return ""
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Write the first `size` bytes of `data` at the current position.
|
|
270
|
+
pub func writeChunk = (self, string data, int size) {
|
|
271
|
+
```
|
|
272
|
+
#arch: c
|
|
273
|
+
FILE *f = (FILE*)(unsigned long long)self->handle;
|
|
274
|
+
fwrite(data, 1, size, f);
|
|
275
|
+
```
|
|
276
|
+
```
|
|
277
|
+
#arch: aarch64
|
|
278
|
+
mov x0, x1
|
|
279
|
+
mov x1, #1
|
|
280
|
+
ldr x3, [x19, #8]
|
|
281
|
+
bl _fwrite
|
|
282
|
+
```
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// (static) Whether a file exists at `path`.
|
|
286
|
+
pub func exists = (string path, out bool) {
|
|
287
|
+
```
|
|
288
|
+
#arch: c
|
|
289
|
+
struct stat st;
|
|
290
|
+
return stat(path, &st) == 0 ? 1 : 0;
|
|
291
|
+
```
|
|
292
|
+
```
|
|
293
|
+
#arch: aarch64
|
|
294
|
+
sub sp, sp, #160
|
|
295
|
+
mov x1, sp
|
|
296
|
+
bl _stat
|
|
297
|
+
cmp x0, #0
|
|
298
|
+
cset x0, eq
|
|
299
|
+
add sp, sp, #160
|
|
300
|
+
b .return_File_exists
|
|
301
|
+
```
|
|
302
|
+
return false
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// (static) Remove the file at `path`.
|
|
306
|
+
pub func delete = (string path) {
|
|
307
|
+
```
|
|
308
|
+
#arch: c
|
|
309
|
+
remove(path);
|
|
310
|
+
```
|
|
311
|
+
```
|
|
312
|
+
#arch: aarch64
|
|
313
|
+
bl _remove
|
|
314
|
+
```
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// (static) Read the entire contents of `path` in one open/read/close.
|
|
318
|
+
// Returns an empty string if the file cannot be opened.
|
|
319
|
+
pub func read_all = (string path, out string) {
|
|
320
|
+
```
|
|
321
|
+
#arch: c
|
|
322
|
+
FILE *f = fopen(path, "r");
|
|
323
|
+
if (!f) return strdup("");
|
|
324
|
+
fseek(f, 0, SEEK_END);
|
|
325
|
+
long size = ftell(f);
|
|
326
|
+
fseek(f, 0, SEEK_SET);
|
|
327
|
+
char *buf = (char*)malloc(size + 1);
|
|
328
|
+
fread(buf, 1, size, f);
|
|
329
|
+
buf[size] = 0;
|
|
330
|
+
fclose(f);
|
|
331
|
+
return buf;
|
|
332
|
+
```
|
|
333
|
+
```
|
|
334
|
+
#arch: aarch64
|
|
335
|
+
sub sp, sp, #48
|
|
336
|
+
str x0, [sp, #0]
|
|
337
|
+
adr x1, .Lfile_read_all_mode
|
|
338
|
+
bl _fopen
|
|
339
|
+
str x0, [sp, #8]
|
|
340
|
+
cbz x0, .Lfile_read_all_empty
|
|
341
|
+
ldr x0, [sp, #8]
|
|
342
|
+
mov x1, #0
|
|
343
|
+
mov x2, #2
|
|
344
|
+
bl _fseek
|
|
345
|
+
ldr x0, [sp, #8]
|
|
346
|
+
bl _ftell
|
|
347
|
+
str x0, [sp, #16]
|
|
348
|
+
ldr x0, [sp, #8]
|
|
349
|
+
mov x1, #0
|
|
350
|
+
mov x2, #0
|
|
351
|
+
bl _fseek
|
|
352
|
+
ldr x0, [sp, #16]
|
|
353
|
+
add x0, x0, #1
|
|
354
|
+
bl _malloc
|
|
355
|
+
str x0, [sp, #24]
|
|
356
|
+
ldr x0, [sp, #24]
|
|
357
|
+
mov x1, #1
|
|
358
|
+
ldr x2, [sp, #16]
|
|
359
|
+
ldr x3, [sp, #8]
|
|
360
|
+
bl _fread
|
|
361
|
+
ldr x0, [sp, #24]
|
|
362
|
+
ldr x1, [sp, #16]
|
|
363
|
+
strb wzr, [x0, x1]
|
|
364
|
+
ldr x0, [sp, #8]
|
|
365
|
+
bl _fclose
|
|
366
|
+
ldr x0, [sp, #24]
|
|
367
|
+
add sp, sp, #48
|
|
368
|
+
b .return_File_read_all
|
|
369
|
+
.Lfile_read_all_empty:
|
|
370
|
+
adr x0, .Lfile_read_all_empty_str
|
|
371
|
+
bl _strdup
|
|
372
|
+
add sp, sp, #48
|
|
373
|
+
b .return_File_read_all
|
|
374
|
+
.Lfile_read_all_mode: .asciz "r"
|
|
375
|
+
.Lfile_read_all_empty_str: .asciz ""
|
|
376
|
+
.p2align 2
|
|
377
|
+
```
|
|
378
|
+
return ""
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// (static) Write `data` to `path` (replacing any existing contents) in
|
|
382
|
+
// one open/write/close.
|
|
383
|
+
pub func write_all = (string path, string data) {
|
|
384
|
+
```
|
|
385
|
+
#arch: c
|
|
386
|
+
FILE *f = fopen(path, "w");
|
|
387
|
+
if (!f) return;
|
|
388
|
+
fputs(data, f);
|
|
389
|
+
fclose(f);
|
|
390
|
+
```
|
|
391
|
+
```
|
|
392
|
+
#arch: aarch64
|
|
393
|
+
sub sp, sp, #32
|
|
394
|
+
str x0, [sp, #0]
|
|
395
|
+
str x1, [sp, #8]
|
|
396
|
+
adr x1, .Lfile_write_all_mode
|
|
397
|
+
bl _fopen
|
|
398
|
+
str x0, [sp, #16]
|
|
399
|
+
cbz x0, .Lfile_write_all_done
|
|
400
|
+
ldr x0, [sp, #8]
|
|
401
|
+
ldr x1, [sp, #16]
|
|
402
|
+
bl _fputs
|
|
403
|
+
ldr x0, [sp, #16]
|
|
404
|
+
bl _fclose
|
|
405
|
+
.Lfile_write_all_done:
|
|
406
|
+
add sp, sp, #32
|
|
407
|
+
b .return_File_write_all
|
|
408
|
+
.Lfile_write_all_mode: .asciz "w"
|
|
409
|
+
.p2align 2
|
|
410
|
+
```
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Closes the handle if still open (no-op after close). Runs automatically
|
|
414
|
+
// at scope exit, so an unclosed `File` never leaks.
|
|
415
|
+
func #destroy = () {
|
|
416
|
+
```
|
|
417
|
+
#arch: c
|
|
418
|
+
if (self->handle) {
|
|
419
|
+
fclose((FILE*)(unsigned long long)self->handle);
|
|
420
|
+
self->handle = 0;
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
```
|
|
424
|
+
#arch: aarch64
|
|
425
|
+
ldr x0, [x19, #8]
|
|
426
|
+
cbz x0, .Lfile_destroy_end
|
|
427
|
+
bl _fclose
|
|
428
|
+
.Lfile_destroy_end:
|
|
429
|
+
str xzr, [x19, #8]
|
|
430
|
+
```
|
|
431
|
+
}
|
|
432
|
+
}
|