zuzu-js 0.1.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 (167) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +113 -0
  3. package/bin/zuzu +17 -0
  4. package/bin/zuzu-build-browser-bundle +57 -0
  5. package/bin/zuzu-generate-browser-stdlib +584 -0
  6. package/bin/zuzu-js +23 -0
  7. package/bin/zuzu-js-compile +152 -0
  8. package/bin/zuzu-js-electron +19 -0
  9. package/dist/zuzu-browser-worker.js +45574 -0
  10. package/dist/zuzu-browser.js +45362 -0
  11. package/lib/browser-bundle-entry.js +160 -0
  12. package/lib/browser-gui-renderer.js +387 -0
  13. package/lib/browser-runtime.js +167 -0
  14. package/lib/browser-worker-entry.js +413 -0
  15. package/lib/browser-ztests/runner.html +103 -0
  16. package/lib/browser-ztests/runner.js +369 -0
  17. package/lib/cli.js +350 -0
  18. package/lib/collections.js +367 -0
  19. package/lib/compiler.js +303 -0
  20. package/lib/electron/launcher.js +70 -0
  21. package/lib/electron/main.js +956 -0
  22. package/lib/electron/preload.js +80 -0
  23. package/lib/electron/renderer.html +122 -0
  24. package/lib/electron/renderer.js +24 -0
  25. package/lib/execution-metadata.js +18 -0
  26. package/lib/gui/dom-renderer.js +778 -0
  27. package/lib/host/browser-host.js +278 -0
  28. package/lib/host/capabilities.js +47 -0
  29. package/lib/host/electron-host.js +15 -0
  30. package/lib/host/node-host.js +74 -0
  31. package/lib/paths.js +150 -0
  32. package/lib/runtime-entrypoints.js +60 -0
  33. package/lib/runtime-helpers.js +886 -0
  34. package/lib/runtime.js +3529 -0
  35. package/lib/tap.js +37 -0
  36. package/lib/transpiler-new/ast.js +23 -0
  37. package/lib/transpiler-new/codegen.js +2455 -0
  38. package/lib/transpiler-new/errors.js +28 -0
  39. package/lib/transpiler-new/index.js +26 -0
  40. package/lib/transpiler-new/lexer.js +834 -0
  41. package/lib/transpiler-new/parser.js +2332 -0
  42. package/lib/transpiler-new/validate-bindings.js +326 -0
  43. package/lib/transpiler-utils.js +95 -0
  44. package/lib/transpiler.js +33 -0
  45. package/lib/zuzu.js +53 -0
  46. package/modules/javascript.js +193 -0
  47. package/modules/std/archive.js +603 -0
  48. package/modules/std/clib.js +338 -0
  49. package/modules/std/data/csv.js +1331 -0
  50. package/modules/std/data/json.js +531 -0
  51. package/modules/std/data/xml.js +441 -0
  52. package/modules/std/data/yaml.js +256 -0
  53. package/modules/std/db-worker.js +250 -0
  54. package/modules/std/db.js +664 -0
  55. package/modules/std/digest/_hash.js +443 -0
  56. package/modules/std/digest/md5.js +26 -0
  57. package/modules/std/digest/sha.js +72 -0
  58. package/modules/std/eval.js +10 -0
  59. package/modules/std/gui/objects.js +1519 -0
  60. package/modules/std/internals.js +571 -0
  61. package/modules/std/io/socks-worker.js +318 -0
  62. package/modules/std/io/socks.js +186 -0
  63. package/modules/std/io.js +475 -0
  64. package/modules/std/marshal/cbor.js +463 -0
  65. package/modules/std/marshal/graph.js +1624 -0
  66. package/modules/std/marshal.js +87 -0
  67. package/modules/std/math/bignum.js +91 -0
  68. package/modules/std/math.js +79 -0
  69. package/modules/std/net/dns.js +306 -0
  70. package/modules/std/net/http.js +820 -0
  71. package/modules/std/net/smtp.js +943 -0
  72. package/modules/std/net/url.js +109 -0
  73. package/modules/std/proc.js +602 -0
  74. package/modules/std/secure.js +3724 -0
  75. package/modules/std/string/base64.js +138 -0
  76. package/modules/std/string.js +299 -0
  77. package/modules/std/task.js +914 -0
  78. package/modules/std/time.js +579 -0
  79. package/modules/std/tui.js +188 -0
  80. package/modules/std/worker-thread.js +246 -0
  81. package/modules/std/worker.js +790 -0
  82. package/package.json +67 -0
  83. package/stdlib/modules/javascript.zzm +99 -0
  84. package/stdlib/modules/perl.zzm +105 -0
  85. package/stdlib/modules/std/archive.zzm +132 -0
  86. package/stdlib/modules/std/cache/lru.zzm +174 -0
  87. package/stdlib/modules/std/clib.zzm +112 -0
  88. package/stdlib/modules/std/colour.zzm +220 -0
  89. package/stdlib/modules/std/config.zzm +818 -0
  90. package/stdlib/modules/std/data/cbor.zzm +497 -0
  91. package/stdlib/modules/std/data/csv.zzm +285 -0
  92. package/stdlib/modules/std/data/ini.zzm +472 -0
  93. package/stdlib/modules/std/data/json/schema/core.zzm +573 -0
  94. package/stdlib/modules/std/data/json/schema/format.zzm +581 -0
  95. package/stdlib/modules/std/data/json/schema/model.zzm +255 -0
  96. package/stdlib/modules/std/data/json/schema/output.zzm +272 -0
  97. package/stdlib/modules/std/data/json/schema/relative_pointer.zzm +299 -0
  98. package/stdlib/modules/std/data/json/schema/validation.zzm +1503 -0
  99. package/stdlib/modules/std/data/json/schema.zzm +306 -0
  100. package/stdlib/modules/std/data/json.zzm +102 -0
  101. package/stdlib/modules/std/data/kdl/json.zzm +460 -0
  102. package/stdlib/modules/std/data/kdl/xml.zzm +387 -0
  103. package/stdlib/modules/std/data/kdl.zzm +1631 -0
  104. package/stdlib/modules/std/data/toml.zzm +756 -0
  105. package/stdlib/modules/std/data/toon.zzm +1017 -0
  106. package/stdlib/modules/std/data/xml/escape.zzm +156 -0
  107. package/stdlib/modules/std/data/xml.zzm +276 -0
  108. package/stdlib/modules/std/data/yaml.zzm +94 -0
  109. package/stdlib/modules/std/db.zzm +173 -0
  110. package/stdlib/modules/std/defer.zzm +75 -0
  111. package/stdlib/modules/std/digest/crc32.zzm +196 -0
  112. package/stdlib/modules/std/digest/md5.zzm +54 -0
  113. package/stdlib/modules/std/digest/sha.zzm +83 -0
  114. package/stdlib/modules/std/dump.zzm +317 -0
  115. package/stdlib/modules/std/eval.zzm +63 -0
  116. package/stdlib/modules/std/getopt.zzm +432 -0
  117. package/stdlib/modules/std/gui/dialogue.zzm +592 -0
  118. package/stdlib/modules/std/gui/objects.zzm +123 -0
  119. package/stdlib/modules/std/gui.zzm +1914 -0
  120. package/stdlib/modules/std/internals.zzm +139 -0
  121. package/stdlib/modules/std/io/socks.zzm +139 -0
  122. package/stdlib/modules/std/io.zzm +157 -0
  123. package/stdlib/modules/std/lingua/en.zzm +347 -0
  124. package/stdlib/modules/std/log.zzm +169 -0
  125. package/stdlib/modules/std/mail.zzm +2726 -0
  126. package/stdlib/modules/std/marshal.zzm +138 -0
  127. package/stdlib/modules/std/math/bignum.zzm +98 -0
  128. package/stdlib/modules/std/math/range.zzm +116 -0
  129. package/stdlib/modules/std/math/roman.zzm +156 -0
  130. package/stdlib/modules/std/math.zzm +141 -0
  131. package/stdlib/modules/std/net/dns.zzm +93 -0
  132. package/stdlib/modules/std/net/http.zzm +278 -0
  133. package/stdlib/modules/std/net/smtp.zzm +257 -0
  134. package/stdlib/modules/std/net/url.zzm +69 -0
  135. package/stdlib/modules/std/path/jsonpointer.zzm +526 -0
  136. package/stdlib/modules/std/path/kdl.zzm +1003 -0
  137. package/stdlib/modules/std/path/simple.zzm +520 -0
  138. package/stdlib/modules/std/path/z/context.zzm +147 -0
  139. package/stdlib/modules/std/path/z/evaluate.zzm +549 -0
  140. package/stdlib/modules/std/path/z/functions.zzm +874 -0
  141. package/stdlib/modules/std/path/z/lexer.zzm +490 -0
  142. package/stdlib/modules/std/path/z/node.zzm +1455 -0
  143. package/stdlib/modules/std/path/z/operators.zzm +445 -0
  144. package/stdlib/modules/std/path/z/parser.zzm +359 -0
  145. package/stdlib/modules/std/path/z.zzm +403 -0
  146. package/stdlib/modules/std/path/zz/functions.zzm +828 -0
  147. package/stdlib/modules/std/path/zz/operators.zzm +1036 -0
  148. package/stdlib/modules/std/path/zz.zzm +100 -0
  149. package/stdlib/modules/std/proc.zzm +155 -0
  150. package/stdlib/modules/std/result.zzm +149 -0
  151. package/stdlib/modules/std/secure.zzm +606 -0
  152. package/stdlib/modules/std/string/base64.zzm +66 -0
  153. package/stdlib/modules/std/string/quoted_printable.zzm +485 -0
  154. package/stdlib/modules/std/string.zzm +179 -0
  155. package/stdlib/modules/std/task.zzm +221 -0
  156. package/stdlib/modules/std/template/z.zzm +531 -0
  157. package/stdlib/modules/std/template/zz.zzm +62 -0
  158. package/stdlib/modules/std/time.zzm +188 -0
  159. package/stdlib/modules/std/tui.zzm +89 -0
  160. package/stdlib/modules/std/uuid.zzm +223 -0
  161. package/stdlib/modules/std/web/session.zzm +388 -0
  162. package/stdlib/modules/std/web/static.zzm +329 -0
  163. package/stdlib/modules/std/web.zzm +1942 -0
  164. package/stdlib/modules/std/worker.zzm +202 -0
  165. package/stdlib/modules/std/zuzuzoo.zzm +3960 -0
  166. package/stdlib/modules/test/more.zzm +528 -0
  167. package/stdlib/modules/test/parser.zzm +209 -0
@@ -0,0 +1,497 @@
1
+ =encoding utf8
2
+
3
+ =head1 NAME
4
+
5
+ std/data/cbor - CBOR encoding and decoding for ZuzuScript.
6
+
7
+ =head1 SYNOPSIS
8
+
9
+ from std/data/cbor import CBOR, TaggedValue;
10
+
11
+ let codec := new CBOR();
12
+ let bytes := codec.encode({ answer: 42 });
13
+ let value := codec.decode(bytes);
14
+
15
+ // Decode CBOR maps to Zuzu PairLists instead of Dicts.
16
+ // This preserves key order and allows duplicate keys.
17
+ codec := new CBOR( pairlists: true );
18
+
19
+ =head1 IMPLEMENTATION SUPPORT
20
+
21
+ This module is supported by zuzu.pl, zuzu-rust, and zuzu-js on Node and
22
+ Electron. It is partially supported by zuzu-js in the browser: in-memory
23
+ CBOR encode/decode coverage passes, but file-backed load/dump coverage is
24
+ unsupported because browser filesystem capability is unavailable.
25
+
26
+ =head1 DESCRIPTION
27
+
28
+ Pure-Zuzu implementation of CBOR (RFC 8949).
29
+
30
+ =head1 EXPORTS
31
+
32
+ =head2 Classes
33
+
34
+ =over
35
+
36
+ =item C<< TaggedValue({ tag: Number, value: value }) >>
37
+
38
+ Constructs a tagged CBOR value. Returns: C<TaggedValue>. Stores the CBOR
39
+ tag number and associated value.
40
+
41
+ =item C<< CBOR({ pairlists?: Boolean }) >>
42
+
43
+ Constructs a CBOR codec. Returns: C<CBOR>. The C<pairlists> option makes
44
+ decoded maps return as C<PairList> values instead of C<Dict> values.
45
+
46
+ =over
47
+
48
+ =item C<< codec.encode(value) >>
49
+
50
+ Parameters: C<value> is any CBOR-encodable ZuzuScript value. Returns:
51
+ C<BinaryString>. Encodes C<value> as CBOR bytes.
52
+
53
+ =item C<< codec.encode_binarystring(value) >>
54
+
55
+ Alias for C<codec.encode(value)>.
56
+
57
+ =item C<< codec.decode(BinaryString raw) >>
58
+
59
+ Parameters: C<raw> is CBOR data. Returns: value. Decodes CBOR bytes into
60
+ the equivalent ZuzuScript value.
61
+
62
+ =item C<< codec.decode_binarystring(BinaryString raw) >>
63
+
64
+ Alias for C<codec.decode(raw)>.
65
+
66
+ =item C<< codec.load(Path path) >>
67
+
68
+ Parameters: C<path> is a C<std/io> C<Path>. Returns: value. Reads CBOR
69
+ bytes from C<path> and decodes them.
70
+
71
+ =item C<< codec.dump(Path path, value) >>
72
+
73
+ Parameters: C<path> is a C<std/io> C<Path> and C<value> is any
74
+ CBOR-encodable value. Returns: C<null>. Encodes C<value> and writes CBOR
75
+ bytes to C<path>.
76
+
77
+ =back
78
+
79
+ =back
80
+
81
+ =head1 COPYRIGHT AND LICENCE
82
+
83
+ B<< std/data/cbor >> is copyright Toby Inkster.
84
+
85
+ It is free software; you may redistribute it and/or modify it under
86
+ the terms of either the Artistic License 1.0 or the GNU General Public
87
+ License version 2.
88
+
89
+ =cut
90
+
91
+ from std/string import substr, index;
92
+ from std/string/base64 import encode, decode;
93
+ from std/time import Time;
94
+
95
+
96
+ let _B64_ALPHABET := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
97
+
98
+ // Set to "PairList" to return CBOR objects as Zuzu PairLists.
99
+ let _DECODE_MAP_AS := "Dict";
100
+
101
+ class TaggedValue {
102
+ let Number tag;
103
+ let value;
104
+ }
105
+
106
+ function _div_floor ( Number n, Number d ) {
107
+ return floor( n / d ); // fix syntax highlighting
108
+ }
109
+
110
+ function _mod ( Number n, Number d ) {
111
+ return n - _div_floor( n, d ) * d;
112
+ }
113
+
114
+ function _bytes_to_binary ( Array bytes ) {
115
+ let out := "";
116
+ let i := 0;
117
+ let n := bytes.length();
118
+
119
+ while ( i < n ) {
120
+ let b0 := bytes[i];
121
+ let b1 := null;
122
+ let b2 := null;
123
+ if ( i + 1 < n ) {
124
+ b1 := bytes[i + 1];
125
+ }
126
+ if ( i + 2 < n ) {
127
+ b2 := bytes[i + 2];
128
+ }
129
+
130
+ let c0 := _div_floor( b0, 4 );
131
+ let c1 := _mod( b0, 4 ) * 16;
132
+ let c2 := 64;
133
+ let c3 := 64;
134
+
135
+ if ( b1 ≢ null ) {
136
+ c1 += _div_floor( b1, 16 );
137
+ c2 := _mod( b1, 16 ) * 4;
138
+ if ( b2 ≢ null ) {
139
+ c2 += _div_floor( b2, 64 );
140
+ c3 := _mod( b2, 64 );
141
+ }
142
+ }
143
+
144
+ out _= substr( _B64_ALPHABET, c0, 1 );
145
+ out _= substr( _B64_ALPHABET, c1, 1 );
146
+ if ( c2 ≡ 64 ) {
147
+ out _= "=";
148
+ }
149
+ else {
150
+ out _= substr( _B64_ALPHABET, c2, 1 );
151
+ }
152
+ if ( c3 ≡ 64 ) {
153
+ out _= "=";
154
+ }
155
+ else {
156
+ out _= substr( _B64_ALPHABET, c3, 1 );
157
+ }
158
+ i += 3;
159
+ }
160
+
161
+ return decode(out);
162
+ }
163
+
164
+ function _binary_to_bytes ( BinaryString raw ) {
165
+ let b64 := encode(raw);
166
+ let out := [];
167
+ let i := 0;
168
+ let n := length b64;
169
+
170
+ while ( i < n ) {
171
+ let c0 := index( _B64_ALPHABET, substr( b64, i, 1 ) );
172
+ let c1 := index( _B64_ALPHABET, substr( b64, i + 1, 1 ) );
173
+ let ch2 := substr( b64, i + 2, 1 );
174
+ let ch3 := substr( b64, i + 3, 1 );
175
+ let c2 := -1;
176
+ let c3 := -1;
177
+ if ( ch2 ≢ "=" ) {
178
+ c2 := index( _B64_ALPHABET, ch2 );
179
+ }
180
+ if ( ch3 ≢ "=" ) {
181
+ c3 := index( _B64_ALPHABET, ch3 );
182
+ }
183
+
184
+ out.push( c0 * 4 + _div_floor( c1, 16 ) );
185
+
186
+ if ( c2 >= 0 ) {
187
+ out.push( _mod( c1, 16 ) * 16 + _div_floor( c2, 4 ) );
188
+ }
189
+ if ( c3 >= 0 ) {
190
+ out.push( _mod( c2, 4 ) * 64 + c3 );
191
+ }
192
+
193
+ i += 4;
194
+ }
195
+
196
+ return out;
197
+ }
198
+
199
+ function _is_int ( value ) {
200
+ if ( not( value instanceof Number ) ) {
201
+ return false;
202
+ }
203
+
204
+ return _mod( value, 1 ) ≡ 0;
205
+ }
206
+
207
+ function _emit_uint ( Array out, Number major, Number n ) {
208
+ if ( n < 24 ) {
209
+ out.push( major * 32 + n );
210
+ return;
211
+ }
212
+ if ( n < 256 ) {
213
+ out.push( major * 32 + 24 );
214
+ out.push(n);
215
+ return;
216
+ }
217
+ if ( n < 65536 ) {
218
+ out.push( major * 32 + 25 );
219
+ out.push( _mod( _div_floor( n, 256 ), 256 ) );
220
+ out.push( _mod( n, 256 ) );
221
+ return;
222
+ }
223
+ if ( n < 4294967296 ) {
224
+ out.push( major * 32 + 26 );
225
+ out.push( _mod( _div_floor( n, 16777216 ), 256 ) );
226
+ out.push( _mod( _div_floor( n, 65536 ), 256 ) );
227
+ out.push( _mod( _div_floor( n, 256 ), 256 ) );
228
+ out.push( _mod( n, 256 ) );
229
+ return;
230
+ }
231
+
232
+ let hi := _div_floor( n, 4294967296 );
233
+ let lo := _mod( n, 4294967296 );
234
+ out.push( major * 32 + 27 );
235
+ out.push( _mod( _div_floor( hi, 16777216 ), 256 ) );
236
+ out.push( _mod( _div_floor( hi, 65536 ), 256 ) );
237
+ out.push( _mod( _div_floor( hi, 256 ), 256 ) );
238
+ out.push( _mod( hi, 256 ) );
239
+ out.push( _mod( _div_floor( lo, 16777216 ), 256 ) );
240
+ out.push( _mod( _div_floor( lo, 65536 ), 256 ) );
241
+ out.push( _mod( _div_floor( lo, 256 ), 256 ) );
242
+ out.push( _mod( lo, 256 ) );
243
+ }
244
+
245
+ function _encode_value ( Array out, value ) {
246
+ if ( value ≡ null ) {
247
+ out.push(246);
248
+ return;
249
+ }
250
+ if ( value ≡ true ) {
251
+ out.push(245);
252
+ return;
253
+ }
254
+ if ( value ≡ false ) {
255
+ out.push(244);
256
+ return;
257
+ }
258
+
259
+ if ( value instanceof Number ) {
260
+ die "CBOR.encode currently supports only integer Number values" if not _is_int(value);
261
+ if ( value >= 0 ) {
262
+ _emit_uint( out, 0, value );
263
+ }
264
+ else {
265
+ _emit_uint( out, 1, -1 - value );
266
+ }
267
+ return;
268
+ }
269
+
270
+ if ( value instanceof BinaryString ) {
271
+ let b := _binary_to_bytes(value);
272
+ _emit_uint( out, 2, b.length() );
273
+ let i := 0;
274
+ while ( i < b.length() ) {
275
+ out.push( b[i] );
276
+ i++;
277
+ }
278
+ return;
279
+ }
280
+
281
+ if ( value instanceof String ) {
282
+ let b := _binary_to_bytes( to_binary(value) );
283
+ _emit_uint( out, 3, b.length() );
284
+ let i := 0;
285
+ while ( i < b.length() ) {
286
+ out.push( b[i] );
287
+ i++;
288
+ }
289
+ return;
290
+ }
291
+
292
+ if ( value instanceof Array ) {
293
+ _emit_uint( out, 4, value.length() );
294
+ let i := 0;
295
+ while ( i < value.length() ) {
296
+ _encode_value( out, value[i] );
297
+ i++;
298
+ }
299
+ return;
300
+ }
301
+
302
+ if ( value instanceof Set ) {
303
+ _emit_uint( out, 6, 258 );
304
+ _encode_value( out, value.sortstr() );
305
+ return;
306
+ }
307
+
308
+ if ( value instanceof Bag ) {
309
+ _encode_value( out, value.sortstr() );
310
+ return;
311
+ }
312
+
313
+ if ( value instanceof PairList ) {
314
+ let pairs := value.to_Array();
315
+ _emit_uint( out, 5, pairs.length() );
316
+ let i := 0;
317
+ while ( i < pairs.length() ) {
318
+ let pair := pairs[i]{pair};
319
+ _encode_value( out, pair[0] );
320
+ _encode_value( out, pair[1] );
321
+ i++;
322
+ }
323
+ return;
324
+ }
325
+
326
+ if ( value instanceof Dict ) {
327
+ let keys := value.sorted_keys();
328
+ _emit_uint( out, 5, keys.length() );
329
+ let i := 0;
330
+ while ( i < keys.length() ) {
331
+ let k := keys[i];
332
+ _encode_value( out, k );
333
+ _encode_value( out, value.get(k) );
334
+ i++;
335
+ }
336
+ return;
337
+ }
338
+
339
+ if ( value instanceof TaggedValue ) {
340
+ _emit_uint( out, 6, value { tag } );
341
+ _encode_value( out, value { value } );
342
+ return;
343
+ }
344
+ if ( value instanceof Time ) {
345
+ _emit_uint( out, 6, 0 );
346
+ _encode_value( out, value.epoch() );
347
+ return;
348
+ }
349
+
350
+ die `CBOR cannot encode value of type ${typeof value}`;
351
+ }
352
+
353
+ function _read_uint ( Array bytes, Number ai, Number pos ) {
354
+ if ( ai < 24 ) {
355
+ return [ ai, pos ];
356
+ }
357
+ if ( ai ≡ 24 ) {
358
+ return [ bytes[pos], pos + 1 ];
359
+ }
360
+ if ( ai ≡ 25 ) {
361
+ return [ bytes[pos] * 256 + bytes[pos + 1], pos + 2 ];
362
+ }
363
+ if ( ai ≡ 26 ) {
364
+ return [ bytes[pos] * 16777216 + bytes[pos + 1] * 65536 + bytes[pos + 2] * 256 + bytes[pos + 3], pos + 4 ];
365
+ }
366
+ if ( ai ≡ 27 ) {
367
+ let hi := bytes[pos] * 16777216 + bytes[pos + 1] * 65536 + bytes[pos + 2] * 256 + bytes[pos + 3];
368
+ let lo := bytes[pos + 4] * 16777216 + bytes[pos + 5] * 65536 + bytes[pos + 6] * 256 + bytes[pos + 7];
369
+ return [ hi * 4294967296 + lo, pos + 8 ];
370
+ }
371
+
372
+ die `Unsupported CBOR additional info: ${ai}`;
373
+ }
374
+
375
+ function _decode_at ( Array bytes, Number pos ) {
376
+ let head := bytes[pos];
377
+ let major := _div_floor( head, 32 );
378
+ let ai := _mod( head, 32 );
379
+ let parsed := _read_uint( bytes, ai, pos + 1 );
380
+ let arg := parsed[0];
381
+ let p := parsed[1];
382
+
383
+ if ( major ≡ 0 ) {
384
+ return [ arg, p ];
385
+ }
386
+ if ( major ≡ 1 ) {
387
+ return [ -1 - arg, p ];
388
+ }
389
+ if ( major ≡ 2 ) {
390
+ let chunk := [];
391
+ let i := 0;
392
+ while ( i < arg ) {
393
+ chunk.push( bytes[p + i] );
394
+ i++;
395
+ }
396
+ return [ _bytes_to_binary(chunk), p + arg ];
397
+ }
398
+ if ( major ≡ 3 ) {
399
+ let chunk := [];
400
+ let i := 0;
401
+ while ( i < arg ) {
402
+ chunk.push( bytes[p + i] );
403
+ i++;
404
+ }
405
+ return [ to_string( _bytes_to_binary(chunk) ), p + arg ];
406
+ }
407
+ if ( major ≡ 4 ) {
408
+ let arr := [];
409
+ let i := 0;
410
+ let q := p;
411
+ while ( i < arg ) {
412
+ let item := _decode_at( bytes, q );
413
+ arr.push( item[0] );
414
+ q := item[1];
415
+ i++;
416
+ }
417
+ return [ arr, q ];
418
+ }
419
+ if ( major ≡ 5 ) {
420
+ let d := _DECODE_MAP_AS eq "PairList" ? new PairList() : new Dict();
421
+ let i := 0;
422
+ let q := p;
423
+ while ( i < arg ) {
424
+ let k := _decode_at( bytes, q );
425
+ let v := _decode_at( bytes, k[1] );
426
+ d.add( k[0], v[0] ) unless _DECODE_MAP_AS eq "Dict" and d.exists( k[0] );
427
+ q := v[1];
428
+ i++;
429
+ }
430
+ return [ d, q ];
431
+ }
432
+ if ( major ≡ 6 ) {
433
+ let tagged := _decode_at( bytes, p );
434
+ if ( arg ≡ 0 and tagged[0] instanceof Number ) {
435
+ return [ new Time( tagged[0] ), tagged[1] ];
436
+ }
437
+ if ( arg ≡ 258 and tagged[0] instanceof Array ) {
438
+ return [ tagged[0].to_Set(), tagged[1] ];
439
+ }
440
+ return [ new TaggedValue( tag: arg, value: tagged[0] ), tagged[1] ];
441
+ }
442
+ if ( major ≡ 7 ) {
443
+ if ( ai ≡ 20 ) {
444
+ return [ false, pos + 1 ];
445
+ }
446
+ if ( ai ≡ 21 ) {
447
+ return [ true, pos + 1 ];
448
+ }
449
+ if ( ai ≡ 22 ) {
450
+ return [ null, pos + 1 ];
451
+ }
452
+ die `Unsupported CBOR simple/float value (ai=${ai})`;
453
+ }
454
+
455
+ die `Unsupported CBOR major type: ${major}`;
456
+ }
457
+
458
+ class CBOR {
459
+ let pairlists := false;
460
+
461
+ method encode ( value ) {
462
+ let out := [];
463
+ _encode_value( out, value );
464
+ return _bytes_to_binary(out);
465
+ }
466
+
467
+ method encode_binarystring ( value ) {
468
+ return self.encode(value);
469
+ }
470
+
471
+ method decode ( BinaryString raw ) {
472
+ _DECODE_MAP_AS := pairlists ? "PairList" : "Dict";
473
+ let bytes := _binary_to_bytes(raw);
474
+ let parsed := _decode_at( bytes, 0 );
475
+ die "Trailing bytes after CBOR value" if parsed[1] < bytes.length();
476
+ return parsed[0];
477
+ }
478
+
479
+ method decode_binarystring ( BinaryString raw ) {
480
+ return self.decode(raw);
481
+ }
482
+
483
+ method load ( path ) {
484
+ from std/io import Path;
485
+ die "CBOR.load is denied by runtime policy" if __system__{deny_fs};
486
+ die "CBOR.load expects a std/io Path object" if not( path instanceof Path );
487
+ return self.decode( path.slurp() );
488
+ }
489
+
490
+ method dump ( path, value ) {
491
+ from std/io import Path;
492
+ die "CBOR.dump is denied by runtime policy" if __system__{deny_fs};
493
+ die "CBOR.dump expects a std/io Path object" if not( path instanceof Path );
494
+ path.spew( self.encode(value) );
495
+ return path;
496
+ }
497
+ }