@shd101wyy/yo 0.1.26 → 0.1.27

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 (167) hide show
  1. package/.github/skills/yo-async-effects/SKILL.md +4 -4
  2. package/.github/skills/yo-async-effects/async-effects-recipes.md +34 -34
  3. package/.github/skills/yo-core-patterns/SKILL.md +1 -1
  4. package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +26 -26
  5. package/.github/skills/yo-project-workflow/SKILL.md +6 -3
  6. package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +34 -11
  7. package/.github/skills/yo-syntax/SKILL.md +7 -6
  8. package/.github/skills/yo-syntax/syntax-cheatsheet.md +73 -60
  9. package/.github/skills/yo-wasm-integration/wasm-integration-cheatsheet.md +3 -3
  10. package/README.md +10 -8
  11. package/out/cjs/index.cjs +456 -438
  12. package/out/cjs/yo-cli.cjs +576 -543
  13. package/out/cjs/yo-lsp.cjs +559 -532
  14. package/out/esm/index.mjs +281 -263
  15. package/out/types/src/formatter.d.ts +11 -0
  16. package/out/types/src/lsp/formatting.d.ts +2 -0
  17. package/out/types/src/tests/formatter.test.d.ts +1 -0
  18. package/out/types/tsconfig.tsbuildinfo +1 -1
  19. package/package.json +1 -1
  20. package/std/alg/hash.yo +13 -21
  21. package/std/allocator.yo +25 -40
  22. package/std/async.yo +3 -7
  23. package/std/build.yo +105 -151
  24. package/std/cli/arg_parser.yo +184 -169
  25. package/std/collections/array_list.yo +350 -314
  26. package/std/collections/btree_map.yo +142 -131
  27. package/std/collections/deque.yo +132 -128
  28. package/std/collections/hash_map.yo +542 -566
  29. package/std/collections/hash_set.yo +623 -687
  30. package/std/collections/linked_list.yo +275 -293
  31. package/std/collections/ordered_map.yo +113 -85
  32. package/std/collections/priority_queue.yo +73 -73
  33. package/std/crypto/md5.yo +191 -95
  34. package/std/crypto/random.yo +56 -64
  35. package/std/crypto/sha256.yo +151 -107
  36. package/std/encoding/base64.yo +87 -81
  37. package/std/encoding/hex.yo +43 -50
  38. package/std/encoding/html.yo +56 -81
  39. package/std/encoding/html_char_utils.yo +7 -13
  40. package/std/encoding/html_entities.yo +2248 -2253
  41. package/std/encoding/json.yo +316 -224
  42. package/std/encoding/punycode.yo +86 -116
  43. package/std/encoding/toml.yo +67 -66
  44. package/std/encoding/utf16.yo +37 -44
  45. package/std/env.yo +62 -91
  46. package/std/error.yo +7 -15
  47. package/std/fmt/display.yo +5 -9
  48. package/std/fmt/index.yo +8 -14
  49. package/std/fmt/to_string.yo +330 -315
  50. package/std/fmt/writer.yo +58 -87
  51. package/std/fs/dir.yo +83 -102
  52. package/std/fs/file.yo +147 -180
  53. package/std/fs/metadata.yo +45 -78
  54. package/std/fs/temp.yo +55 -65
  55. package/std/fs/types.yo +27 -40
  56. package/std/fs/walker.yo +53 -68
  57. package/std/gc.yo +5 -8
  58. package/std/glob.yo +30 -43
  59. package/std/http/client.yo +107 -120
  60. package/std/http/http.yo +106 -96
  61. package/std/http/index.yo +4 -6
  62. package/std/imm/list.yo +88 -93
  63. package/std/imm/map.yo +528 -464
  64. package/std/imm/set.yo +52 -57
  65. package/std/imm/sorted_map.yo +340 -286
  66. package/std/imm/sorted_set.yo +57 -63
  67. package/std/imm/string.yo +404 -345
  68. package/std/imm/vec.yo +173 -181
  69. package/std/io/reader.yo +3 -6
  70. package/std/io/writer.yo +4 -8
  71. package/std/libc/assert.yo +5 -9
  72. package/std/libc/ctype.yo +32 -22
  73. package/std/libc/dirent.yo +26 -25
  74. package/std/libc/errno.yo +164 -90
  75. package/std/libc/fcntl.yo +52 -45
  76. package/std/libc/float.yo +66 -44
  77. package/std/libc/limits.yo +42 -33
  78. package/std/libc/math.yo +53 -82
  79. package/std/libc/signal.yo +72 -47
  80. package/std/libc/stdatomic.yo +217 -188
  81. package/std/libc/stdint.yo +5 -29
  82. package/std/libc/stdio.yo +5 -29
  83. package/std/libc/stdlib.yo +32 -39
  84. package/std/libc/string.yo +5 -23
  85. package/std/libc/sys/stat.yo +58 -56
  86. package/std/libc/time.yo +5 -19
  87. package/std/libc/unistd.yo +5 -20
  88. package/std/libc/wctype.yo +6 -9
  89. package/std/libc/windows.yo +26 -30
  90. package/std/log.yo +41 -55
  91. package/std/net/addr.yo +102 -97
  92. package/std/net/dns.yo +27 -28
  93. package/std/net/errors.yo +50 -49
  94. package/std/net/tcp.yo +113 -124
  95. package/std/net/udp.yo +55 -66
  96. package/std/os/env.yo +35 -33
  97. package/std/os/signal.yo +15 -25
  98. package/std/path.yo +276 -311
  99. package/std/prelude.yo +6304 -4315
  100. package/std/process/command.yo +87 -103
  101. package/std/process/index.yo +12 -31
  102. package/std/regex/compiler.yo +196 -95
  103. package/std/regex/flags.yo +58 -39
  104. package/std/regex/index.yo +157 -173
  105. package/std/regex/match.yo +20 -31
  106. package/std/regex/node.yo +134 -152
  107. package/std/regex/parser.yo +283 -259
  108. package/std/regex/unicode.yo +172 -202
  109. package/std/regex/vm.yo +155 -171
  110. package/std/string/index.yo +5 -7
  111. package/std/string/rune.yo +45 -55
  112. package/std/string/string.yo +937 -964
  113. package/std/string/string_builder.yo +94 -104
  114. package/std/string/unicode.yo +46 -64
  115. package/std/sync/channel.yo +72 -73
  116. package/std/sync/cond.yo +31 -36
  117. package/std/sync/mutex.yo +30 -32
  118. package/std/sync/once.yo +13 -16
  119. package/std/sync/rwlock.yo +26 -31
  120. package/std/sync/waitgroup.yo +20 -25
  121. package/std/sys/advise.yo +16 -24
  122. package/std/sys/bufio/buf_reader.yo +77 -93
  123. package/std/sys/bufio/buf_writer.yo +52 -65
  124. package/std/sys/clock.yo +4 -9
  125. package/std/sys/constants.yo +77 -61
  126. package/std/sys/copy.yo +4 -10
  127. package/std/sys/dir.yo +26 -43
  128. package/std/sys/dns.yo +41 -61
  129. package/std/sys/errors.yo +95 -103
  130. package/std/sys/events.yo +45 -57
  131. package/std/sys/externs.yo +319 -267
  132. package/std/sys/fallocate.yo +7 -11
  133. package/std/sys/fcntl.yo +14 -22
  134. package/std/sys/file.yo +26 -40
  135. package/std/sys/future.yo +5 -8
  136. package/std/sys/iov.yo +12 -25
  137. package/std/sys/lock.yo +12 -13
  138. package/std/sys/mmap.yo +38 -43
  139. package/std/sys/path.yo +3 -8
  140. package/std/sys/perm.yo +7 -21
  141. package/std/sys/pipe.yo +5 -12
  142. package/std/sys/process.yo +23 -29
  143. package/std/sys/seek.yo +10 -12
  144. package/std/sys/signal.yo +7 -13
  145. package/std/sys/signals.yo +52 -35
  146. package/std/sys/socket.yo +63 -58
  147. package/std/sys/socketpair.yo +3 -6
  148. package/std/sys/sockinfo.yo +11 -20
  149. package/std/sys/statfs.yo +11 -34
  150. package/std/sys/statx.yo +25 -52
  151. package/std/sys/sysinfo.yo +15 -20
  152. package/std/sys/tcp.yo +62 -92
  153. package/std/sys/temp.yo +5 -9
  154. package/std/sys/time.yo +5 -15
  155. package/std/sys/timer.yo +6 -11
  156. package/std/sys/tty.yo +10 -18
  157. package/std/sys/udp.yo +22 -39
  158. package/std/sys/umask.yo +3 -6
  159. package/std/sys/unix.yo +33 -52
  160. package/std/testing/bench.yo +49 -52
  161. package/std/thread.yo +10 -15
  162. package/std/time/datetime.yo +105 -89
  163. package/std/time/duration.yo +43 -56
  164. package/std/time/instant.yo +13 -18
  165. package/std/time/sleep.yo +5 -9
  166. package/std/url/index.yo +184 -209
  167. package/std/worker.yo +6 -10
@@ -12,21 +12,18 @@
12
12
  //! v := json_parse(`{"x": 1}`);
13
13
  //! println(json_stringify(v));
14
14
  //! ```
15
-
16
- open import "../string";
17
- { ArrayList } :: import "../collections/array_list";
18
- { snprintf } :: import "../libc/stdio";
19
- { Error, AnyError, Exception } :: import "../error";
20
- { ToString } :: import "../fmt";
21
-
15
+ open(import("../string"));
16
+ { ArrayList } :: import("../collections/array_list");
17
+ { snprintf } :: import("../libc/stdio");
18
+ { Error, AnyError, Exception } :: import("../error");
19
+ { ToString } :: import("../fmt");
22
20
  // ============================================================================
23
21
  // JsonError
24
22
  // ============================================================================
25
-
26
23
  /// JSON parsing error type.
27
24
  JsonError :: enum(
28
25
  /// Encountered an unexpected character at the given position.
29
- UnexpectedChar(ch: u8, pos: usize),
26
+ UnexpectedChar(ch : u8, pos : usize),
30
27
  /// Input ended unexpectedly.
31
28
  UnexpectedEnd,
32
29
  /// Failed to parse a numeric literal.
@@ -36,162 +33,156 @@ JsonError :: enum(
36
33
  /// Invalid Unicode escape in a string.
37
34
  InvalidUnicode,
38
35
  /// Other error with a descriptive message.
39
- Other(msg: String)
36
+ Other(msg : String)
40
37
  );
41
-
42
- impl(JsonError, ToString(
43
- to_string : (self ->
44
- match(self,
45
- .UnexpectedChar(ch, pos) => `unexpected character at position ${pos}`,
46
- .UnexpectedEnd => `unexpected end of input`,
47
- .InvalidNumber => `invalid number`,
48
- .InvalidEscape => `invalid escape sequence`,
49
- .InvalidUnicode => `invalid unicode`,
50
- .Other(msg) => `JSON error: ${msg}`
38
+ impl(
39
+ JsonError,
40
+ ToString(
41
+ to_string : (
42
+ self ->
43
+ match(
44
+ self,
45
+ .UnexpectedChar(ch, pos) => `unexpected character at position ${pos}`,
46
+ .UnexpectedEnd => `unexpected end of input`,
47
+ .InvalidNumber => `invalid number`,
48
+ .InvalidEscape => `invalid escape sequence`,
49
+ .InvalidUnicode => `invalid unicode`,
50
+ .Other(msg) => `JSON error: ${msg}`
51
+ )
51
52
  )
52
53
  )
53
- ));
54
-
54
+ );
55
55
  impl(JsonError, Error());
56
-
57
- export JsonError;
58
-
56
+ export(JsonError);
59
57
  // ============================================================================
60
58
  // JsonValue
61
59
  // ============================================================================
62
-
63
60
  /// Dynamically-typed JSON value tree.
64
61
  JsonValue :: enum(
65
62
  /// JSON null.
66
63
  Null,
67
64
  /// JSON boolean.
68
- Bool(value: bool),
65
+ Bool(value : bool),
69
66
  /// JSON number (IEEE 754 double).
70
- Number(value: f64),
67
+ Number(value : f64),
71
68
  /// JSON string.
72
- Str(value: String),
69
+ Str(value : String),
73
70
  /// JSON array of values.
74
- Array(items: ArrayList(Self)),
71
+ Array(items : ArrayList(Self)),
75
72
  /// JSON object with ordered key-value pairs.
76
- Object(keys: ArrayList(String), values: ArrayList(Self))
73
+ Object(keys : ArrayList(String), values : ArrayList(Self))
77
74
  );
78
-
79
75
  // ============================================================================
80
76
  // JsonKV - key/value pair convenience struct for Object
81
77
  // ============================================================================
82
-
83
78
  /// Key-value pair for JSON object entries.
84
79
  JsonKV :: struct(
85
- key : String,
80
+ key : String,
86
81
  value : JsonValue
87
82
  );
88
-
89
- impl(JsonValue,
83
+ impl(
84
+ JsonValue,
90
85
  /// Get a field from an Object value by key. Returns `.None` if not an Object or key is missing.
91
- get : (fn(self: Self, key: String) -> Option(JsonValue))(
92
- match(self,
86
+ get : (fn(self : Self, key : String) -> Option(JsonValue))(
87
+ match(
88
+ self,
93
89
  .Object(keys, values) => {
94
90
  i := usize(0);
95
- while (i < keys.len()), (i = (i + usize(1))), {
91
+ while(i < keys.len(), i = (i + usize(1)), {
96
92
  cond(
97
93
  (keys.get(i).unwrap() == key) => {
98
- return .Some(values.get(i).unwrap());
94
+ return(.Some(values.get(i).unwrap()));
99
95
  },
100
96
  true => ()
101
97
  );
102
- };
98
+ });
103
99
  .None
104
100
  },
105
- _ => .None
101
+ _ =>.None
106
102
  )
107
103
  ),
108
-
109
104
  /// Get an element from an Array value by index.
110
- at : (fn(self: Self, index: usize) -> Option(JsonValue))(
111
- match(self,
105
+ at : (fn(self : Self, index : usize) -> Option(JsonValue))(
106
+ match(
107
+ self,
112
108
  .Array(items) => items.get(index),
113
- _ => .None
109
+ _ =>.None
114
110
  )
115
111
  ),
116
-
117
112
  /// Extract the boolean value, or `.None` if not a `Bool`.
118
- as_bool : (fn(self: Self) -> Option(bool))(
119
- match(self,
120
- .Bool(b) => .Some(b),
121
- _ => .None
113
+ as_bool : (fn(self : Self) -> Option(bool))(
114
+ match(
115
+ self,
116
+ .Bool(b) =>.Some(b),
117
+ _ =>.None
122
118
  )
123
119
  ),
124
-
125
120
  /// Extract the numeric value, or `.None` if not a `Number`.
126
- as_number : (fn(self: Self) -> Option(f64))(
127
- match(self,
128
- .Number(n) => .Some(n),
129
- _ => .None
121
+ as_number : (fn(self : Self) -> Option(f64))(
122
+ match(
123
+ self,
124
+ .Number(n) =>.Some(n),
125
+ _ =>.None
130
126
  )
131
127
  ),
132
-
133
128
  /// Extract the string value, or `.None` if not a `Str`.
134
- as_string : (fn(self: Self) -> Option(String))(
135
- match(self,
136
- .Str(s) => .Some(s),
137
- _ => .None
129
+ as_string : (fn(self : Self) -> Option(String))(
130
+ match(
131
+ self,
132
+ .Str(s) =>.Some(s),
133
+ _ =>.None
138
134
  )
139
135
  ),
140
-
141
136
  /// Extract the array items, or `.None` if not an `Array`.
142
- as_array : (fn(self: Self) -> Option(ArrayList(JsonValue)))(
143
- match(self,
144
- .Array(items) => .Some(items),
145
- _ => .None
137
+ as_array : (fn(self : Self) -> Option(ArrayList(JsonValue)))(
138
+ match(
139
+ self,
140
+ .Array(items) =>.Some(items),
141
+ _ =>.None
146
142
  )
147
143
  ),
148
-
149
144
  /// Extract object entries as `ArrayList(JsonKV)`, or `.None` if not an `Object`.
150
- as_object : (fn(self: Self) -> Option(ArrayList(JsonKV)))(
151
- match(self,
145
+ as_object : (fn(self : Self) -> Option(ArrayList(JsonKV)))(
146
+ match(
147
+ self,
152
148
  .Object(keys, values) => {
153
149
  result := ArrayList(JsonKV).new();
154
150
  i := usize(0);
155
- while (i < keys.len()), (i = (i + usize(1))), {
156
- result.push(JsonKV(key: keys.get(i).unwrap(), value: values.get(i).unwrap()));
157
- };
151
+ while(i < keys.len(), i = (i + usize(1)), {
152
+ result.push(JsonKV(key : keys.get(i).unwrap(), value : values.get(i).unwrap()));
153
+ });
158
154
  .Some(result)
159
155
  },
160
- _ => .None
156
+ _ =>.None
161
157
  )
162
158
  )
163
159
  );
164
-
165
- export JsonValue, JsonKV;
166
-
160
+ export(JsonValue, JsonKV);
167
161
  // ============================================================================
168
162
  // Parser state
169
163
  // ============================================================================
170
-
171
164
  _Parser :: object(
172
165
  src : str,
173
166
  pos : usize
174
167
  );
175
-
176
- impl(_Parser,
177
- new : (fn(src: str) -> Self)(
178
- Self(src: src, pos: usize(0))
168
+ impl(
169
+ _Parser,
170
+ new : (fn(src : str) -> Self)(
171
+ Self(src : src, pos : usize(0))
179
172
  ),
180
-
181
- peek : (fn(self: Self) -> Option(u8))(
173
+ peek : (fn(self : Self) -> Option(u8))(
182
174
  cond(
183
- (self.pos < self.src.len()) => .Some(self.src.bytes(self.pos)),
184
- true => .None
175
+ (self.pos < self.src.len()) =>.Some(self.src.bytes(self.pos)),
176
+ true =>.None
185
177
  )
186
178
  ),
187
-
188
- advance : (fn(self: Self) -> unit)({
179
+ advance : (fn(self : Self) -> unit)({
189
180
  self.pos = (self.pos + usize(1));
190
181
  }),
191
-
192
- skip_ws : (fn(self: Self) -> unit)({
193
- while runtime(true), {
194
- match(self.peek(),
182
+ skip_ws : (fn(self : Self) -> unit)({
183
+ while(runtime(true), {
184
+ match(
185
+ self.peek(),
195
186
  .None => break,
196
187
  .Some(c) => {
197
188
  cond(
@@ -202,52 +193,69 @@ impl(_Parser,
202
193
  );
203
194
  }
204
195
  );
205
- };
196
+ });
206
197
  }),
207
-
208
- expect : (fn(self: Self, ch: u8) -> Result(unit, JsonError))({
198
+ expect : (fn(self : Self, ch : u8) -> Result(unit, JsonError))({
209
199
  self.skip_ws();
210
- match(self.peek(),
211
- .None => .Err(.UnexpectedEnd),
200
+ match(
201
+ self.peek(),
202
+ .None =>.Err(.UnexpectedEnd),
212
203
  .Some(c) =>
213
204
  cond(
214
205
  (c == ch) => {
215
206
  self.advance();
216
207
  .Ok(())
217
208
  },
218
- true => .Err(.UnexpectedChar(c, self.pos))
209
+ true =>.Err(.UnexpectedChar(c, self.pos))
219
210
  )
220
211
  )
221
212
  }),
222
-
223
- parse_string : (fn(self: Self) -> Result(String, JsonError))({
213
+ parse_string : (fn(self : Self) -> Result(String, JsonError))({
224
214
  self.advance(); // skip opening '"'
225
215
  bytes := ArrayList(u8).new();
226
- while runtime(true), {
227
- match(self.peek(),
228
- .None => { return .Err(.UnexpectedEnd); },
216
+ while(runtime(true), {
217
+ match(
218
+ self.peek(),
219
+ .None => {
220
+ return(.Err(.UnexpectedEnd));
221
+ },
229
222
  .Some(c) => {
230
223
  cond(
231
- (c == u8(34)) => { // '"'
224
+ (c == u8(34)) => {
225
+ // '"'
232
226
  self.advance();
233
227
  break;
234
228
  },
235
- (c == u8(92)) => { // '\'
229
+ (c == u8(92)) => {
230
+ // '\'
236
231
  self.advance();
237
- match(self.peek(),
238
- .None => { return .Err(.UnexpectedEnd); },
232
+ match(
233
+ self.peek(),
234
+ .None => {
235
+ return(.Err(.UnexpectedEnd));
236
+ },
239
237
  .Some(e) => {
240
238
  self.advance();
241
239
  cond(
242
- (e == u8(110)) => bytes.push(u8(10)), // \n
243
- (e == u8(116)) => bytes.push(u8(9)), // \t
244
- (e == u8(114)) => bytes.push(u8(13)), // \r
245
- (e == u8(34)) => bytes.push(u8(34)), // \"
246
- (e == u8(92)) => bytes.push(u8(92)), // \\
247
- (e == u8(47)) => bytes.push(u8(47)), // \/
248
- (e == u8(98)) => bytes.push(u8(8)), // \b
249
- (e == u8(102)) => bytes.push(u8(12)), // \f
250
- true => { return .Err(.InvalidEscape); }
240
+ (e == u8(110)) => bytes.push(u8(10)),
241
+ // \n
242
+ (e == u8(116)) => bytes.push(u8(9)),
243
+ // \t
244
+ (e == u8(114)) => bytes.push(u8(13)),
245
+ // \r
246
+ (e == u8(34)) => bytes.push(u8(34)),
247
+ // \"
248
+ (e == u8(92)) => bytes.push(u8(92)),
249
+ // \\
250
+ (e == u8(47)) => bytes.push(u8(47)),
251
+ // \/
252
+ (e == u8(98)) => bytes.push(u8(8)),
253
+ // \b
254
+ (e == u8(102)) => bytes.push(u8(12)),
255
+ // \f
256
+ true => {
257
+ return(.Err(.InvalidEscape));
258
+ }
251
259
  );
252
260
  }
253
261
  );
@@ -259,23 +267,25 @@ impl(_Parser,
259
267
  );
260
268
  }
261
269
  );
262
- };
270
+ });
263
271
  .Ok(String.from_bytes(bytes))
264
272
  }),
265
-
266
- parse_number : (fn(self: Self) -> Result(f64, JsonError))({
273
+ parse_number : (fn(self : Self) -> Result(f64, JsonError))({
267
274
  start := self.pos;
268
- match(self.peek(),
275
+ match(
276
+ self.peek(),
269
277
  .Some(c) => {
270
278
  cond(
271
- (c == u8(45)) => self.advance(), // '-'
279
+ (c == u8(45)) => self.advance(),
280
+ // '-'
272
281
  true => ()
273
282
  );
274
283
  },
275
284
  .None => ()
276
285
  );
277
- while runtime(true), {
278
- match(self.peek(),
286
+ while(runtime(true), {
287
+ match(
288
+ self.peek(),
279
289
  .Some(c) => {
280
290
  cond(
281
291
  ((c >= u8(48)) && (c <= u8(57))) => self.advance(),
@@ -284,14 +294,17 @@ impl(_Parser,
284
294
  },
285
295
  .None => break
286
296
  );
287
- };
288
- match(self.peek(),
297
+ });
298
+ match(
299
+ self.peek(),
289
300
  .Some(c) => {
290
301
  cond(
291
- (c == u8(46)) => { // '.'
302
+ (c == u8(46)) => {
303
+ // '.'
292
304
  self.advance();
293
- while runtime(true), {
294
- match(self.peek(),
305
+ while(runtime(true), {
306
+ match(
307
+ self.peek(),
295
308
  .Some(d) => {
296
309
  cond(
297
310
  ((d >= u8(48)) && (d <= u8(57))) => self.advance(),
@@ -300,19 +313,22 @@ impl(_Parser,
300
313
  },
301
314
  .None => break
302
315
  );
303
- };
316
+ });
304
317
  },
305
318
  true => ()
306
319
  );
307
320
  },
308
321
  .None => ()
309
322
  );
310
- match(self.peek(),
323
+ match(
324
+ self.peek(),
311
325
  .Some(c) => {
312
326
  cond(
313
- ((c == u8(101)) || (c == u8(69))) => { // 'e' or 'E'
327
+ ((c == u8(101)) || (c == u8(69))) => {
328
+ // 'e' or 'E'
314
329
  self.advance();
315
- match(self.peek(),
330
+ match(
331
+ self.peek(),
316
332
  .Some(s) => {
317
333
  cond(
318
334
  ((s == u8(43)) || (s == u8(45))) => self.advance(),
@@ -321,8 +337,9 @@ impl(_Parser,
321
337
  },
322
338
  .None => ()
323
339
  );
324
- while runtime(true), {
325
- match(self.peek(),
340
+ while(runtime(true), {
341
+ match(
342
+ self.peek(),
326
343
  .Some(d) => {
327
344
  cond(
328
345
  ((d >= u8(48)) && (d <= u8(57))) => self.advance(),
@@ -331,7 +348,7 @@ impl(_Parser,
331
348
  },
332
349
  .None => break
333
350
  );
334
- };
351
+ });
335
352
  },
336
353
  true => ()
337
354
  );
@@ -339,84 +356,108 @@ impl(_Parser,
339
356
  .None => ()
340
357
  );
341
358
  num_len := (self.pos - start);
342
- num_buf := ArrayList(u8).with_capacity((num_len + usize(1)));
359
+ num_buf := ArrayList(u8).with_capacity(num_len + usize(1));
343
360
  j := usize(0);
344
- while (j < num_len), (j = (j + usize(1))), {
345
- num_buf.push(self.src.bytes((start + j)));
346
- };
361
+ while(j < num_len, j = (j + usize(1)), {
362
+ num_buf.push(self.src.bytes(start + j));
363
+ });
347
364
  num_buf.push(u8(0));
348
365
  num_ptr := *(char)(num_buf.ptr().unwrap());
349
- { atof } :: import "../libc/stdlib";
366
+ { atof } :: import("../libc/stdlib");
350
367
  val := atof(num_ptr);
351
368
  .Ok(val)
352
369
  })
353
370
  );
354
-
355
371
  // ============================================================================
356
372
  // Recursive value parser (standalone for self-recursion support)
357
373
  // ============================================================================
358
-
359
374
  // Tiny helpers to avoid begin blocks in cond branches (works around codegen temp var issue)
360
- _parse_true_lit :: (fn(p: _Parser) -> Result(JsonValue, JsonError))({
361
- p.advance(); p.advance(); p.advance(); p.advance();
375
+ _parse_true_lit :: (fn(p : _Parser) -> Result(JsonValue, JsonError))({
376
+ p.advance();
377
+ p.advance();
378
+ p.advance();
379
+ p.advance();
362
380
  .Ok(.Bool(true))
363
381
  });
364
- _parse_false_lit :: (fn(p: _Parser) -> Result(JsonValue, JsonError))({
365
- p.advance(); p.advance(); p.advance(); p.advance(); p.advance();
382
+ _parse_false_lit :: (fn(p : _Parser) -> Result(JsonValue, JsonError))({
383
+ p.advance();
384
+ p.advance();
385
+ p.advance();
386
+ p.advance();
387
+ p.advance();
366
388
  .Ok(.Bool(false))
367
389
  });
368
- _parse_null_lit :: (fn(p: _Parser) -> Result(JsonValue, JsonError))({
369
- p.advance(); p.advance(); p.advance(); p.advance();
390
+ _parse_null_lit :: (fn(p : _Parser) -> Result(JsonValue, JsonError))({
391
+ p.advance();
392
+ p.advance();
393
+ p.advance();
394
+ p.advance();
370
395
  .Ok(.Null)
371
396
  });
372
-
373
- _parse_value :: (fn(p: _Parser) -> Result(JsonValue, JsonError))({
397
+ _parse_value :: (fn(p : _Parser) -> Result(JsonValue, JsonError))({
374
398
  p.skip_ws();
375
- match(p.peek(),
376
- .None => .Err(.UnexpectedEnd),
399
+ match(
400
+ p.peek(),
401
+ .None =>.Err(.UnexpectedEnd),
377
402
  .Some(c) =>
378
403
  cond(
379
404
  (c == u8(34)) =>
380
- match(p.parse_string(), .Err(e) => .Err(e), .Ok(s) => .Ok(.Str(s))),
381
- (c == u8(123)) => { // '{' — parse object
405
+ match(p.parse_string(),.Err(e) =>.Err(e),.Ok(s) =>.Ok(.Str(s))),
406
+ (c == u8(123)) => {
407
+ // '{' — parse object
382
408
  p.advance();
383
409
  keys := ArrayList(String).new();
384
410
  vals := ArrayList(JsonValue).new();
385
411
  p.skip_ws();
386
- match(p.peek(),
412
+ match(
413
+ p.peek(),
387
414
  .Some(c2) => {
388
415
  cond(
389
416
  (c2 == u8(125)) => {
390
417
  p.advance();
391
- return .Ok(.Object(keys, vals));
418
+ return(.Ok(.Object(keys, vals)));
392
419
  },
393
420
  true => ()
394
421
  );
395
422
  },
396
423
  .None => ()
397
424
  );
398
- while runtime(true), {
425
+ while(runtime(true), {
399
426
  p.skip_ws();
400
- match(p.peek(),
401
- .None => { return .Err(.UnexpectedEnd); },
427
+ match(
428
+ p.peek(),
429
+ .None => {
430
+ return(.Err(.UnexpectedEnd));
431
+ },
402
432
  .Some(c2) => {
403
433
  cond(
404
- (c2 != u8(34)) => { return .Err(.UnexpectedChar(c2, p.pos)); },
434
+ (c2 != u8(34)) => {
435
+ return(.Err(.UnexpectedChar(c2, p.pos)));
436
+ },
405
437
  true => ()
406
438
  );
407
439
  }
408
440
  );
409
441
  key_r := p.parse_string();
410
- match(key_r,
411
- .Err(e) => { return .Err(e); },
442
+ match(
443
+ key_r,
444
+ .Err(e) => {
445
+ return(.Err(e));
446
+ },
412
447
  .Ok(key) => {
413
448
  p.skip_ws();
414
- match(p.expect(u8(58)),
415
- .Err(e) => { return .Err(e); },
416
- .Ok(_) => ()
449
+ match(
450
+ p.expect(u8(58)),
451
+ .Err(e) => {
452
+ return(.Err(e));
453
+ },
454
+ .Ok(_) => ()
417
455
  );
418
- match(recur(p),
419
- .Err(e) => { return .Err(e); },
456
+ match(
457
+ recur(p),
458
+ .Err(e) => {
459
+ return(.Err(e));
460
+ },
420
461
  .Ok(val) => {
421
462
  keys.push(key);
422
463
  vals.push(val);
@@ -425,112 +466,162 @@ _parse_value :: (fn(p: _Parser) -> Result(JsonValue, JsonError))({
425
466
  }
426
467
  );
427
468
  p.skip_ws();
428
- match(p.peek(),
469
+ match(
470
+ p.peek(),
429
471
  .Some(c2) => {
430
472
  cond(
431
- (c2 == u8(44)) => { p.advance(); },
432
- (c2 == u8(125)) => { p.advance(); break; },
433
- true => { return .Err(.UnexpectedChar(c2, p.pos)); }
473
+ (c2 == u8(44)) => {
474
+ p.advance();
475
+ },
476
+ (c2 == u8(125)) => {
477
+ p.advance();
478
+ break;
479
+ },
480
+ true => {
481
+ return(.Err(.UnexpectedChar(c2, p.pos)));
482
+ }
434
483
  );
435
484
  },
436
- .None => { return .Err(.UnexpectedEnd); }
485
+ .None => {
486
+ return(.Err(.UnexpectedEnd));
487
+ }
437
488
  );
438
- };
489
+ });
439
490
  .Ok(.Object(keys, vals))
440
491
  },
441
- (c == u8(91)) => { // '[' — parse array
492
+ (c == u8(91)) => {
493
+ // '[' — parse array
442
494
  p.advance();
443
495
  items := ArrayList(JsonValue).new();
444
496
  p.skip_ws();
445
- match(p.peek(),
497
+ match(
498
+ p.peek(),
446
499
  .Some(c2) => {
447
500
  cond(
448
501
  (c2 == u8(93)) => {
449
502
  p.advance();
450
- return .Ok(.Array(items));
503
+ return(.Ok(.Array(items)));
451
504
  },
452
505
  true => ()
453
506
  );
454
507
  },
455
508
  .None => ()
456
509
  );
457
- while runtime(true), {
458
- match(recur(p),
459
- .Err(e) => { return .Err(e); },
460
- .Ok(v) => { items.push(v); }
510
+ while(runtime(true), {
511
+ match(
512
+ recur(p),
513
+ .Err(e) => {
514
+ return(.Err(e));
515
+ },
516
+ .Ok(v) => {
517
+ items.push(v);
518
+ }
461
519
  );
462
520
  p.skip_ws();
463
- match(p.peek(),
521
+ match(
522
+ p.peek(),
464
523
  .Some(c2) => {
465
524
  cond(
466
- (c2 == u8(44)) => { p.advance(); },
467
- (c2 == u8(93)) => { p.advance(); break; },
468
- true => { return .Err(.UnexpectedChar(c2, p.pos)); }
525
+ (c2 == u8(44)) => {
526
+ p.advance();
527
+ },
528
+ (c2 == u8(93)) => {
529
+ p.advance();
530
+ break;
531
+ },
532
+ true => {
533
+ return(.Err(.UnexpectedChar(c2, p.pos)));
534
+ }
469
535
  );
470
536
  },
471
- .None => { return .Err(.UnexpectedEnd); }
537
+ .None => {
538
+ return(.Err(.UnexpectedEnd));
539
+ }
472
540
  );
473
- };
541
+ });
474
542
  .Ok(.Array(items))
475
543
  },
476
544
  (c == u8(116)) => _parse_true_lit(p),
477
545
  (c == u8(102)) => _parse_false_lit(p),
478
546
  (c == u8(110)) => _parse_null_lit(p),
479
547
  true =>
480
- match(p.parse_number(), .Err(e) => .Err(e), .Ok(n) => .Ok(.Number(n)))
548
+ match(p.parse_number(),.Err(e) =>.Err(e),.Ok(n) =>.Ok(.Number(n)))
481
549
  )
482
550
  )
483
551
  });
484
-
485
552
  // ============================================================================
486
553
  // Public API
487
554
  // ============================================================================
488
-
489
555
  /// Parse a JSON string into a `JsonValue` tree. Throws via `Exception` on invalid input.
490
- json_parse :: (fn(s: str, using(exn : Exception)) -> JsonValue)({
556
+ json_parse :: (fn(s : str, using(exn : Exception)) -> JsonValue)({
491
557
  p := _Parser.new(s);
492
- match(_parse_value(p),
558
+ match(
559
+ _parse_value(p),
493
560
  .Ok(v) => v,
494
- .Err(e) => exn.throw(dyn e)
561
+ .Err(e) => exn.throw(dyn(e))
495
562
  )
496
563
  });
497
-
498
- export json_parse;
499
-
564
+ export(json_parse);
500
565
  // ============================================================================
501
566
  // Serialisation
502
567
  // ============================================================================
503
-
504
- _write_str_escaped :: (fn(s: String, out: ArrayList(u8)) -> unit)({
568
+ _write_str_escaped :: (fn(s : String, out : ArrayList(u8)) -> unit)({
505
569
  out.push(u8(34)); // '"'
506
570
  bytes := s.as_bytes();
507
571
  i := usize(0);
508
- while (i < bytes.len()), (i = (i + usize(1))), {
572
+ while(i < bytes.len(), i = (i + usize(1)), {
509
573
  b := bytes.get(i).unwrap();
510
574
  cond(
511
- (b == u8(34)) => { out.push(u8(92)); out.push(u8(34)); },
512
- (b == u8(92)) => { out.push(u8(92)); out.push(u8(92)); },
513
- (b == u8(10)) => { out.push(u8(92)); out.push(u8(110)); },
514
- (b == u8(9)) => { out.push(u8(92)); out.push(u8(116)); },
515
- (b == u8(13)) => { out.push(u8(92)); out.push(u8(114)); },
516
- true => { out.push(b); }
575
+ (b == u8(34)) => {
576
+ out.push(u8(92));
577
+ out.push(u8(34));
578
+ },
579
+ (b == u8(92)) => {
580
+ out.push(u8(92));
581
+ out.push(u8(92));
582
+ },
583
+ (b == u8(10)) => {
584
+ out.push(u8(92));
585
+ out.push(u8(110));
586
+ },
587
+ (b == u8(9)) => {
588
+ out.push(u8(92));
589
+ out.push(u8(116));
590
+ },
591
+ (b == u8(13)) => {
592
+ out.push(u8(92));
593
+ out.push(u8(114));
594
+ },
595
+ true => {
596
+ out.push(b);
597
+ }
517
598
  );
518
- };
599
+ });
519
600
  out.push(u8(34)); // '"'
520
601
  });
521
-
522
- _stringify_into :: (fn(value: JsonValue, out: ArrayList(u8)) -> unit)({
523
- match(value,
602
+ _stringify_into :: (fn(value : JsonValue, out : ArrayList(u8)) -> unit)({
603
+ match(
604
+ value,
524
605
  .Null => {
525
- out.push(u8(110)); out.push(u8(117)); out.push(u8(108)); out.push(u8(108));
606
+ out.push(u8(110));
607
+ out.push(u8(117));
608
+ out.push(u8(108));
609
+ out.push(u8(108));
526
610
  },
527
611
  .Bool(b) => {
528
612
  cond(
529
613
  b => {
530
- out.push(u8(116)); out.push(u8(114)); out.push(u8(117)); out.push(u8(101));
614
+ out.push(u8(116));
615
+ out.push(u8(114));
616
+ out.push(u8(117));
617
+ out.push(u8(101));
531
618
  },
532
619
  true => {
533
- out.push(u8(102)); out.push(u8(97)); out.push(u8(108)); out.push(u8(115)); out.push(u8(101));
620
+ out.push(u8(102));
621
+ out.push(u8(97));
622
+ out.push(u8(108));
623
+ out.push(u8(115));
624
+ out.push(u8(101));
534
625
  }
535
626
  );
536
627
  },
@@ -541,9 +632,9 @@ _stringify_into :: (fn(value: JsonValue, out: ArrayList(u8)) -> unit)({
541
632
  s2 := String.from_cstr(buf_ptr).unwrap();
542
633
  bytes := s2.as_bytes();
543
634
  i := usize(0);
544
- while (i < bytes.len()), (i = (i + usize(1))), {
635
+ while(i < bytes.len(), i = (i + usize(1)), {
545
636
  out.push(bytes.get(i).unwrap());
546
- };
637
+ });
547
638
  },
548
639
  .Str(s) => {
549
640
  _write_str_escaped(s, out);
@@ -551,42 +642,43 @@ _stringify_into :: (fn(value: JsonValue, out: ArrayList(u8)) -> unit)({
551
642
  .Array(items) => {
552
643
  out.push(u8(91)); // '['
553
644
  i := usize(0);
554
- while (i < items.len()), (i = (i + usize(1))), {
645
+ while(i < items.len(), i = (i + usize(1)), {
555
646
  cond(
556
- (i > usize(0)) => { out.push(u8(44)); },
647
+ (i > usize(0)) => {
648
+ out.push(u8(44));
649
+ },
557
650
  true => ()
558
651
  );
559
652
  recur(items.get(i).unwrap(), out);
560
- };
653
+ });
561
654
  out.push(u8(93)); // ']'
562
655
  },
563
656
  .Object(keys, values) => {
564
657
  out.push(u8(123)); // '{'
565
658
  i := usize(0);
566
- while (i < keys.len()), (i = (i + usize(1))), {
659
+ while(i < keys.len(), i = (i + usize(1)), {
567
660
  cond(
568
- (i > usize(0)) => { out.push(u8(44)); },
661
+ (i > usize(0)) => {
662
+ out.push(u8(44));
663
+ },
569
664
  true => ()
570
665
  );
571
666
  _write_str_escaped(keys.get(i).unwrap(), out);
572
667
  out.push(u8(58)); // ':'
573
668
  recur(values.get(i).unwrap(), out);
574
- };
669
+ });
575
670
  out.push(u8(125)); // '}'
576
671
  }
577
672
  );
578
673
  });
579
-
580
674
  /// Serialize a `JsonValue` to a compact JSON string.
581
- json_stringify :: (fn(value: JsonValue) -> String)({
675
+ json_stringify :: (fn(value : JsonValue) -> String)({
582
676
  out := ArrayList(u8).new();
583
677
  _stringify_into(value, out);
584
678
  String.from_bytes(out)
585
679
  });
586
-
587
680
  /// Serialize a `JsonValue` to a pretty-printed JSON string.
588
- json_stringify_pretty :: (fn(value: JsonValue, _indent: usize) -> String)(
681
+ json_stringify_pretty :: (fn(value : JsonValue, _indent : usize) -> String)(
589
682
  json_stringify(value)
590
683
  );
591
-
592
- export json_stringify, json_stringify_pretty;
684
+ export(json_stringify, json_stringify_pretty);