@amritk/nish-x86_64-linux 0.12.0 → 0.13.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.
- package/INSTALL.md +13 -13
- package/bin/nish +0 -0
- package/package.json +1 -1
- package/runtime/nish.d.ts +20 -1
- package/runtime/nish.h +31 -11
- package/runtime/nish.mjs +3 -3
- package/runtime/{runtime_os.c → runtime-os.c} +1 -1
- package/runtime/{runtime_parallel.c → runtime-parallel.c} +112 -4
- package/runtime/{runtime_wasm.c → runtime-wasm.c} +6 -1
- package/runtime/runtime.c +5 -5
- package/runtime/shim.mjs +6 -6
- package/scripts/build.sh +14 -9
- package/std/README.md +2 -2
- package/std/collections.ts +194 -188
- package/std/json.ts +136 -136
- package/std/map.ts +9 -7
- package/std/pair.ts +2 -2
- package/std/testing.ts +67 -67
- package/std/text.ts +54 -54
- package/std/threads.ts +126 -38
package/std/json.ts
CHANGED
|
@@ -53,18 +53,18 @@
|
|
|
53
53
|
* (`docs/wp26-stdlib.md` §4).
|
|
54
54
|
*/
|
|
55
55
|
|
|
56
|
-
const JSON_TAB: i32 = 9
|
|
57
|
-
const JSON_NEWLINE: i32 = 10
|
|
58
|
-
const JSON_CARRIAGE_RETURN: i32 = 13
|
|
59
|
-
const JSON_SPACE: i32 = 32
|
|
60
|
-
const JSON_QUOTE: i32 = 34
|
|
61
|
-
const JSON_COMMA: i32 = 44
|
|
62
|
-
const JSON_COLON: i32 = 58
|
|
63
|
-
const JSON_BACKSLASH: i32 = 92
|
|
64
|
-
const JSON_OPEN_BRACKET: i32 = 91
|
|
65
|
-
const JSON_CLOSE_BRACKET: i32 = 93
|
|
66
|
-
const JSON_OPEN_BRACE: i32 = 123
|
|
67
|
-
const JSON_CLOSE_BRACE: i32 = 125
|
|
56
|
+
const JSON_TAB: i32 = 9
|
|
57
|
+
const JSON_NEWLINE: i32 = 10
|
|
58
|
+
const JSON_CARRIAGE_RETURN: i32 = 13
|
|
59
|
+
const JSON_SPACE: i32 = 32
|
|
60
|
+
const JSON_QUOTE: i32 = 34
|
|
61
|
+
const JSON_COMMA: i32 = 44
|
|
62
|
+
const JSON_COLON: i32 = 58
|
|
63
|
+
const JSON_BACKSLASH: i32 = 92
|
|
64
|
+
const JSON_OPEN_BRACKET: i32 = 91
|
|
65
|
+
const JSON_CLOSE_BRACKET: i32 = 93
|
|
66
|
+
const JSON_OPEN_BRACE: i32 = 123
|
|
67
|
+
const JSON_CLOSE_BRACE: i32 = 125
|
|
68
68
|
/**
|
|
69
69
|
* The UTF-8 tags a `\u` escape is rebuilt out of: a two-byte lead is
|
|
70
70
|
* `110xxxxx`, a three-byte lead `1110xxxx`, a continuation byte `10xxxxxx`, and
|
|
@@ -77,19 +77,19 @@ const JSON_CLOSE_BRACE: i32 = 125;
|
|
|
77
77
|
* (`docs/wp26-stdlib.md` §4, and `tests/link/std_text_f64` is what says so). A
|
|
78
78
|
* constant declared `i32` means the same thing in both modes.
|
|
79
79
|
*/
|
|
80
|
-
const JSON_UTF8_TWO_BYTE_LEAD: i32 = 192
|
|
81
|
-
const JSON_UTF8_THREE_BYTE_LEAD: i32 = 224
|
|
82
|
-
const JSON_UTF8_CONTINUATION: i32 = 128
|
|
83
|
-
const JSON_UTF8_LOW_SIX: i32 = 63
|
|
80
|
+
const JSON_UTF8_TWO_BYTE_LEAD: i32 = 192
|
|
81
|
+
const JSON_UTF8_THREE_BYTE_LEAD: i32 = 224
|
|
82
|
+
const JSON_UTF8_CONTINUATION: i32 = 128
|
|
83
|
+
const JSON_UTF8_LOW_SIX: i32 = 63
|
|
84
84
|
/** The first code point that needs two UTF-8 bytes, and the first that needs three. */
|
|
85
|
-
const JSON_UTF8_TWO_BYTE_FLOOR: i32 = 128
|
|
86
|
-
const JSON_UTF8_THREE_BYTE_FLOOR: i32 = 2048
|
|
85
|
+
const JSON_UTF8_TWO_BYTE_FLOOR: i32 = 128
|
|
86
|
+
const JSON_UTF8_THREE_BYTE_FLOOR: i32 = 2048
|
|
87
87
|
/** The base `jsonHex4` accumulates in. */
|
|
88
|
-
const JSON_HEX_BASE: i32 = 16
|
|
88
|
+
const JSON_HEX_BASE: i32 = 16
|
|
89
89
|
|
|
90
90
|
/** The four bytes JSON allows between tokens. */
|
|
91
91
|
const jsonIsBlankByte = (code: i32): boolean =>
|
|
92
|
-
code === JSON_SPACE || code === JSON_TAB || code === JSON_NEWLINE || code === JSON_CARRIAGE_RETURN
|
|
92
|
+
code === JSON_SPACE || code === JSON_TAB || code === JSON_NEWLINE || code === JSON_CARRIAGE_RETURN
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
95
|
* The first index at or after `from` that is not blank, or the length.
|
|
@@ -100,15 +100,15 @@ const jsonIsBlankByte = (code: i32): boolean =>
|
|
|
100
100
|
*/
|
|
101
101
|
const jsonSkipBlank = (text: string, from: i32): i32 => {
|
|
102
102
|
if (from < 0) {
|
|
103
|
-
return from
|
|
103
|
+
return from
|
|
104
104
|
}
|
|
105
|
-
const length: i32 = toI32(text.length)
|
|
106
|
-
let i: i32 = from
|
|
105
|
+
const length: i32 = toI32(text.length)
|
|
106
|
+
let i: i32 = from
|
|
107
107
|
while (i < length && jsonIsBlankByte(toI32(text.charCodeAt(i)))) {
|
|
108
|
-
i += 1
|
|
108
|
+
i += 1
|
|
109
109
|
}
|
|
110
|
-
return i
|
|
111
|
-
}
|
|
110
|
+
return i
|
|
111
|
+
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
114
|
* The index just past the string literal whose opening quote is at `at`, or `-1`
|
|
@@ -117,24 +117,24 @@ const jsonSkipBlank = (text: string, from: i32): i32 => {
|
|
|
117
117
|
* literal and `\\` cannot make the next quote an escape.
|
|
118
118
|
*/
|
|
119
119
|
const jsonEndOfString = (text: string, at: i32): i32 => {
|
|
120
|
-
const length: i32 = toI32(text.length)
|
|
120
|
+
const length: i32 = toI32(text.length)
|
|
121
121
|
if (at < 0) {
|
|
122
|
-
return -1
|
|
122
|
+
return -1
|
|
123
123
|
}
|
|
124
|
-
let i: i32 = at + 1
|
|
124
|
+
let i: i32 = at + 1
|
|
125
125
|
while (i < length) {
|
|
126
|
-
const code: i32 = toI32(text.charCodeAt(i))
|
|
126
|
+
const code: i32 = toI32(text.charCodeAt(i))
|
|
127
127
|
if (code === JSON_BACKSLASH) {
|
|
128
|
-
i += 2
|
|
129
|
-
continue
|
|
128
|
+
i += 2
|
|
129
|
+
continue
|
|
130
130
|
}
|
|
131
131
|
if (code === JSON_QUOTE) {
|
|
132
|
-
return i + 1
|
|
132
|
+
return i + 1
|
|
133
133
|
}
|
|
134
|
-
i += 1
|
|
134
|
+
i += 1
|
|
135
135
|
}
|
|
136
|
-
return -1
|
|
137
|
-
}
|
|
136
|
+
return -1
|
|
137
|
+
}
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
140
|
* The index just past the value that starts at `at`, or `-1` when it does not
|
|
@@ -152,91 +152,91 @@ const jsonEndOfString = (text: string, at: i32): i32 => {
|
|
|
152
152
|
* and one assigned a callee's answer does not.
|
|
153
153
|
*/
|
|
154
154
|
const jsonEndOfValue = (text: string, at: i32): i32 => {
|
|
155
|
-
const length: i32 = toI32(text.length)
|
|
155
|
+
const length: i32 = toI32(text.length)
|
|
156
156
|
if (at < 0 || at >= length) {
|
|
157
|
-
return -1
|
|
157
|
+
return -1
|
|
158
158
|
}
|
|
159
|
-
const first: i32 = toI32(text.charCodeAt(at))
|
|
159
|
+
const first: i32 = toI32(text.charCodeAt(at))
|
|
160
160
|
if (first === JSON_QUOTE) {
|
|
161
|
-
return jsonEndOfString(text, at)
|
|
161
|
+
return jsonEndOfString(text, at)
|
|
162
162
|
}
|
|
163
163
|
if (first === JSON_OPEN_BRACE || first === JSON_OPEN_BRACKET) {
|
|
164
|
-
let depth: i32 = 0
|
|
165
|
-
let inString: boolean = false
|
|
166
|
-
let i: i32 = at
|
|
164
|
+
let depth: i32 = 0
|
|
165
|
+
let inString: boolean = false
|
|
166
|
+
let i: i32 = at
|
|
167
167
|
while (i < length) {
|
|
168
|
-
const code: i32 = toI32(text.charCodeAt(i))
|
|
168
|
+
const code: i32 = toI32(text.charCodeAt(i))
|
|
169
169
|
if (inString) {
|
|
170
170
|
// `jsonEndOfString`'s rule: a backslash takes the byte after it along.
|
|
171
171
|
if (code === JSON_BACKSLASH) {
|
|
172
|
-
i += 2
|
|
173
|
-
continue
|
|
172
|
+
i += 2
|
|
173
|
+
continue
|
|
174
174
|
}
|
|
175
175
|
if (code === JSON_QUOTE) {
|
|
176
|
-
inString = false
|
|
176
|
+
inString = false
|
|
177
177
|
}
|
|
178
|
-
i += 1
|
|
179
|
-
continue
|
|
178
|
+
i += 1
|
|
179
|
+
continue
|
|
180
180
|
}
|
|
181
181
|
if (code === JSON_QUOTE) {
|
|
182
|
-
inString = true
|
|
182
|
+
inString = true
|
|
183
183
|
} else if (code === JSON_OPEN_BRACE || code === JSON_OPEN_BRACKET) {
|
|
184
|
-
depth += 1
|
|
184
|
+
depth += 1
|
|
185
185
|
} else if (code === JSON_CLOSE_BRACE || code === JSON_CLOSE_BRACKET) {
|
|
186
|
-
depth -= 1
|
|
186
|
+
depth -= 1
|
|
187
187
|
if (depth === 0) {
|
|
188
|
-
return i + 1
|
|
188
|
+
return i + 1
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
-
i += 1
|
|
191
|
+
i += 1
|
|
192
192
|
}
|
|
193
|
-
return -1
|
|
193
|
+
return -1
|
|
194
194
|
}
|
|
195
|
-
let i: i32 = at
|
|
195
|
+
let i: i32 = at
|
|
196
196
|
while (i < length) {
|
|
197
|
-
const code: i32 = toI32(text.charCodeAt(i))
|
|
197
|
+
const code: i32 = toI32(text.charCodeAt(i))
|
|
198
198
|
if (code === JSON_COMMA || code === JSON_CLOSE_BRACE || code === JSON_CLOSE_BRACKET) {
|
|
199
|
-
return i
|
|
199
|
+
return i
|
|
200
200
|
}
|
|
201
201
|
if (jsonIsBlankByte(code)) {
|
|
202
|
-
return i
|
|
202
|
+
return i
|
|
203
203
|
}
|
|
204
|
-
i += 1
|
|
204
|
+
i += 1
|
|
205
205
|
}
|
|
206
|
-
return length
|
|
207
|
-
}
|
|
206
|
+
return length
|
|
207
|
+
}
|
|
208
208
|
|
|
209
209
|
/** The value of one lower-case or upper-case hex digit, or `-1`. */
|
|
210
210
|
const jsonHexDigit = (code: i32): i32 => {
|
|
211
211
|
if (code >= 48 && code <= 57) {
|
|
212
|
-
return code - 48
|
|
212
|
+
return code - 48
|
|
213
213
|
}
|
|
214
214
|
if (code >= 97 && code <= 102) {
|
|
215
|
-
return code - 87
|
|
215
|
+
return code - 87
|
|
216
216
|
}
|
|
217
217
|
if (code >= 65 && code <= 70) {
|
|
218
|
-
return code - 55
|
|
218
|
+
return code - 55
|
|
219
219
|
}
|
|
220
|
-
return -1
|
|
221
|
-
}
|
|
220
|
+
return -1
|
|
221
|
+
}
|
|
222
222
|
|
|
223
223
|
/** The four hex digits at `at` as one code point, or `-1` when they are not four hex digits. */
|
|
224
224
|
const jsonHex4 = (text: string, at: i32, end: i32): i32 => {
|
|
225
225
|
if (at + 4 > end) {
|
|
226
|
-
return -1
|
|
226
|
+
return -1
|
|
227
227
|
}
|
|
228
|
-
let value: i32 = 0
|
|
229
|
-
let i: i32 = 0
|
|
228
|
+
let value: i32 = 0
|
|
229
|
+
let i: i32 = 0
|
|
230
230
|
while (i < 4) {
|
|
231
|
-
const digit: i32 = jsonHexDigit(toI32(text.charCodeAt(at + i)))
|
|
231
|
+
const digit: i32 = jsonHexDigit(toI32(text.charCodeAt(at + i)))
|
|
232
232
|
if (digit < 0) {
|
|
233
|
-
return -1
|
|
233
|
+
return -1
|
|
234
234
|
}
|
|
235
|
-
value = value * JSON_HEX_BASE + digit
|
|
236
|
-
i += 1
|
|
235
|
+
value = value * JSON_HEX_BASE + digit
|
|
236
|
+
i += 1
|
|
237
237
|
}
|
|
238
|
-
return value
|
|
239
|
-
}
|
|
238
|
+
return value
|
|
239
|
+
}
|
|
240
240
|
|
|
241
241
|
/**
|
|
242
242
|
* `code` as UTF-8, one to three bytes.
|
|
@@ -244,22 +244,22 @@ const jsonHex4 = (text: string, at: i32, end: i32): i32 => {
|
|
|
244
244
|
* A surrogate pair is **not** recombined: each half becomes its own three-byte
|
|
245
245
|
* sequence, which is what `😀` reads as here. Nothing this module
|
|
246
246
|
* exists to read produces one — `JSON.stringify`, and `jsonQuote` in
|
|
247
|
-
* `
|
|
247
|
+
* `src/strings.ts` which matches it byte for byte, escape only the seven short
|
|
248
248
|
* forms and `\u00xx` below `0x20`, and pass every other byte through as itself —
|
|
249
249
|
* so the alternative would be code with no caller to keep it honest.
|
|
250
250
|
*/
|
|
251
251
|
const jsonUtf8 = (code: i32): string => {
|
|
252
252
|
if (code < JSON_UTF8_TWO_BYTE_FLOOR) {
|
|
253
|
-
return String.fromCharCode(code)
|
|
253
|
+
return String.fromCharCode(code)
|
|
254
254
|
}
|
|
255
255
|
if (code < JSON_UTF8_THREE_BYTE_FLOOR) {
|
|
256
|
-
const lead: string = String.fromCharCode(JSON_UTF8_TWO_BYTE_LEAD + (code >> 6))
|
|
257
|
-
return `${lead}${String.fromCharCode(JSON_UTF8_CONTINUATION + (code & JSON_UTF8_LOW_SIX))}
|
|
256
|
+
const lead: string = String.fromCharCode(JSON_UTF8_TWO_BYTE_LEAD + (code >> 6))
|
|
257
|
+
return `${lead}${String.fromCharCode(JSON_UTF8_CONTINUATION + (code & JSON_UTF8_LOW_SIX))}`
|
|
258
258
|
}
|
|
259
|
-
const lead: string = String.fromCharCode(JSON_UTF8_THREE_BYTE_LEAD + (code >> 12))
|
|
260
|
-
const middle: string = String.fromCharCode(JSON_UTF8_CONTINUATION + ((code >> 6) & JSON_UTF8_LOW_SIX))
|
|
261
|
-
return `${lead}${middle}${String.fromCharCode(JSON_UTF8_CONTINUATION + (code & JSON_UTF8_LOW_SIX))}
|
|
262
|
-
}
|
|
259
|
+
const lead: string = String.fromCharCode(JSON_UTF8_THREE_BYTE_LEAD + (code >> 12))
|
|
260
|
+
const middle: string = String.fromCharCode(JSON_UTF8_CONTINUATION + ((code >> 6) & JSON_UTF8_LOW_SIX))
|
|
261
|
+
return `${lead}${middle}${String.fromCharCode(JSON_UTF8_CONTINUATION + (code & JSON_UTF8_LOW_SIX))}`
|
|
262
|
+
}
|
|
263
263
|
|
|
264
264
|
/**
|
|
265
265
|
* The bytes of `text[at..end)` with the JSON escapes decoded — the body of a
|
|
@@ -277,21 +277,21 @@ const jsonUnescape = (text: string, at: i32, end: i32): string => {
|
|
|
277
277
|
// `0 <= at` and `end <= text.length` always hold. Saying so here is what
|
|
278
278
|
// proves every read below in range and drops the `substring` clamps.
|
|
279
279
|
if (at < 0 || end > toI32(text.length)) {
|
|
280
|
-
return ""
|
|
280
|
+
return ""
|
|
281
281
|
}
|
|
282
|
-
let i: i32 = at
|
|
282
|
+
let i: i32 = at
|
|
283
283
|
while (i < end && toI32(text.charCodeAt(i)) !== JSON_BACKSLASH) {
|
|
284
|
-
i += 1
|
|
284
|
+
i += 1
|
|
285
285
|
}
|
|
286
286
|
if (i >= end) {
|
|
287
|
-
return text.substring(at, end)
|
|
287
|
+
return text.substring(at, end)
|
|
288
288
|
}
|
|
289
|
-
const parts: string[] = []
|
|
290
|
-
let start: i32 = at
|
|
289
|
+
const parts: string[] = []
|
|
290
|
+
let start: i32 = at
|
|
291
291
|
while (i < end) {
|
|
292
292
|
if (toI32(text.charCodeAt(i)) !== JSON_BACKSLASH) {
|
|
293
|
-
i += 1
|
|
294
|
-
continue
|
|
293
|
+
i += 1
|
|
294
|
+
continue
|
|
295
295
|
}
|
|
296
296
|
// `start === i` is an escape straight after another, and the empty run
|
|
297
297
|
// between them adds nothing to the join. The `start >= 0` half is always
|
|
@@ -299,49 +299,49 @@ const jsonUnescape = (text: string, at: i32, end: i32): string => {
|
|
|
299
299
|
// there because `start` is reassigned in the loop, which is where the
|
|
300
300
|
// bounds proof stops following it.
|
|
301
301
|
if (start >= 0 && start < i) {
|
|
302
|
-
parts.push(text.substring(start, i))
|
|
302
|
+
parts.push(text.substring(start, i))
|
|
303
303
|
}
|
|
304
304
|
// A trailing backslash has nothing after it: `0` is no escape letter, so it
|
|
305
305
|
// falls to the default below and stands for itself.
|
|
306
|
-
const letter: i32 = i + 1 < end ? toI32(text.charCodeAt(i + 1)) : 0
|
|
306
|
+
const letter: i32 = i + 1 < end ? toI32(text.charCodeAt(i + 1)) : 0
|
|
307
307
|
if (letter === 110) {
|
|
308
|
-
parts.push("\n")
|
|
309
|
-
i += 2
|
|
308
|
+
parts.push("\n")
|
|
309
|
+
i += 2
|
|
310
310
|
} else if (letter === 116) {
|
|
311
|
-
parts.push("\t")
|
|
312
|
-
i += 2
|
|
311
|
+
parts.push("\t")
|
|
312
|
+
i += 2
|
|
313
313
|
} else if (letter === 114) {
|
|
314
|
-
parts.push("\r")
|
|
315
|
-
i += 2
|
|
314
|
+
parts.push("\r")
|
|
315
|
+
i += 2
|
|
316
316
|
} else if (letter === 98) {
|
|
317
|
-
parts.push(String.fromCharCode(8))
|
|
318
|
-
i += 2
|
|
317
|
+
parts.push(String.fromCharCode(8))
|
|
318
|
+
i += 2
|
|
319
319
|
} else if (letter === 102) {
|
|
320
|
-
parts.push(String.fromCharCode(12))
|
|
321
|
-
i += 2
|
|
320
|
+
parts.push(String.fromCharCode(12))
|
|
321
|
+
i += 2
|
|
322
322
|
} else if (letter === 117) {
|
|
323
|
-
const code: i32 = jsonHex4(text, i + 2, end)
|
|
323
|
+
const code: i32 = jsonHex4(text, i + 2, end)
|
|
324
324
|
if (code < 0) {
|
|
325
325
|
// Not four hex digits after the `u`: the escape is broken, and copying it
|
|
326
326
|
// through unchanged is the reading that loses nothing.
|
|
327
|
-
parts.push("\\u")
|
|
328
|
-
i += 2
|
|
327
|
+
parts.push("\\u")
|
|
328
|
+
i += 2
|
|
329
329
|
} else {
|
|
330
|
-
parts.push(jsonUtf8(code))
|
|
331
|
-
i += 6
|
|
330
|
+
parts.push(jsonUtf8(code))
|
|
331
|
+
i += 6
|
|
332
332
|
}
|
|
333
333
|
} else if (letter === 0) {
|
|
334
|
-
parts.push("\\")
|
|
335
|
-
i += 1
|
|
334
|
+
parts.push("\\")
|
|
335
|
+
i += 1
|
|
336
336
|
} else {
|
|
337
|
-
parts.push(String.fromCharCode(letter))
|
|
338
|
-
i += 2
|
|
337
|
+
parts.push(String.fromCharCode(letter))
|
|
338
|
+
i += 2
|
|
339
339
|
}
|
|
340
|
-
start = i
|
|
340
|
+
start = i
|
|
341
341
|
}
|
|
342
|
-
parts.push(text.substring(start, end))
|
|
343
|
-
return parts.join("")
|
|
344
|
-
}
|
|
342
|
+
parts.push(text.substring(start, end))
|
|
343
|
+
return parts.join("")
|
|
344
|
+
}
|
|
345
345
|
|
|
346
346
|
/**
|
|
347
347
|
* The value of `name` in `object`, or `null` when the object does not have that
|
|
@@ -358,45 +358,45 @@ const jsonUnescape = (text: string, at: i32, end: i32): string => {
|
|
|
358
358
|
* and it is the shape the compiler's `--json` line has.
|
|
359
359
|
*/
|
|
360
360
|
export const jsonField = (object: string, name: string): string | null => {
|
|
361
|
-
const length: i32 = toI32(object.length)
|
|
362
|
-
let i: i32 = jsonSkipBlank(object, 0)
|
|
361
|
+
const length: i32 = toI32(object.length)
|
|
362
|
+
let i: i32 = jsonSkipBlank(object, 0)
|
|
363
363
|
if (i >= length || toI32(object.charCodeAt(i)) !== JSON_OPEN_BRACE) {
|
|
364
|
-
return null
|
|
364
|
+
return null
|
|
365
365
|
}
|
|
366
|
-
i = jsonSkipBlank(object, i + 1)
|
|
366
|
+
i = jsonSkipBlank(object, i + 1)
|
|
367
367
|
// `jsonSkipBlank` never answers a negative index for a non-negative one, but
|
|
368
368
|
// the bounds proof does not look inside a callee, so every cursor it answers
|
|
369
369
|
// is tested for `i < 0` beside `i >= length`: the pair is what lets each read
|
|
370
370
|
// below go without a check.
|
|
371
371
|
while (i >= 0 && i < length && toI32(object.charCodeAt(i)) === JSON_QUOTE) {
|
|
372
|
-
const keyEnd: i32 = jsonEndOfString(object, i)
|
|
372
|
+
const keyEnd: i32 = jsonEndOfString(object, i)
|
|
373
373
|
if (keyEnd < 0) {
|
|
374
|
-
return null
|
|
374
|
+
return null
|
|
375
375
|
}
|
|
376
|
-
const key: string = jsonUnescape(object, i + 1, keyEnd - 1)
|
|
377
|
-
i = jsonSkipBlank(object, keyEnd)
|
|
376
|
+
const key: string = jsonUnescape(object, i + 1, keyEnd - 1)
|
|
377
|
+
i = jsonSkipBlank(object, keyEnd)
|
|
378
378
|
if (i < 0 || i >= length || toI32(object.charCodeAt(i)) !== JSON_COLON) {
|
|
379
|
-
return null
|
|
379
|
+
return null
|
|
380
380
|
}
|
|
381
|
-
const valueAt: i32 = jsonSkipBlank(object, i + 1)
|
|
382
|
-
const valueEnd: i32 = jsonEndOfValue(object, valueAt)
|
|
381
|
+
const valueAt: i32 = jsonSkipBlank(object, i + 1)
|
|
382
|
+
const valueEnd: i32 = jsonEndOfValue(object, valueAt)
|
|
383
383
|
// `jsonEndOfValue` answers `-1` for a `valueAt` outside the object and never
|
|
384
384
|
// answers past its end, so the last three tests change no answer: they are
|
|
385
385
|
// the range the value's first byte and its `substring` are proved in.
|
|
386
386
|
if (valueEnd < 0 || valueAt < 0 || valueAt >= length || valueEnd > toI32(object.length)) {
|
|
387
|
-
return null
|
|
387
|
+
return null
|
|
388
388
|
}
|
|
389
389
|
if (key === name) {
|
|
390
390
|
if (toI32(object.charCodeAt(valueAt)) === JSON_QUOTE) {
|
|
391
|
-
return jsonUnescape(object, valueAt + 1, valueEnd - 1)
|
|
391
|
+
return jsonUnescape(object, valueAt + 1, valueEnd - 1)
|
|
392
392
|
}
|
|
393
|
-
return object.substring(valueAt, valueEnd)
|
|
393
|
+
return object.substring(valueAt, valueEnd)
|
|
394
394
|
}
|
|
395
|
-
i = jsonSkipBlank(object, valueEnd)
|
|
395
|
+
i = jsonSkipBlank(object, valueEnd)
|
|
396
396
|
if (i < 0 || i >= length || toI32(object.charCodeAt(i)) !== JSON_COMMA) {
|
|
397
|
-
return null
|
|
397
|
+
return null
|
|
398
398
|
}
|
|
399
|
-
i = jsonSkipBlank(object, i + 1)
|
|
399
|
+
i = jsonSkipBlank(object, i + 1)
|
|
400
400
|
}
|
|
401
|
-
return null
|
|
402
|
-
}
|
|
401
|
+
return null
|
|
402
|
+
}
|
package/std/map.ts
CHANGED
|
@@ -15,12 +15,14 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Make room in `
|
|
18
|
+
* Make room in `_m` for `_n` entries in all, so that inserting up to `_n` never
|
|
19
19
|
* grows the table. Only the speed of a program depends on it: natively it
|
|
20
20
|
* presizes the bucket table, and under Node, which has no such call, it does
|
|
21
21
|
* nothing. A count that is not positive does nothing either way.
|
|
22
22
|
*/
|
|
23
|
-
export const reserve = <K, V>(
|
|
23
|
+
export const reserve = <K, V>(_m: Map<K, V>, _n: number): void => {
|
|
24
|
+
// Nothing to do here: natively the compiler lowers the call itself, and Node has no table to presize.
|
|
25
|
+
}
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* The value of `key` in `m`; or, when `key` is missing, `value`, after
|
|
@@ -28,10 +30,10 @@ export const reserve = <K, V>(m: Map<K, V>, n: number): void => {};
|
|
|
28
30
|
* `value` is evaluated either way, as every argument is.
|
|
29
31
|
*/
|
|
30
32
|
export const getOrInsert = <K, V>(m: Map<K, V>, key: K, value: V): V => {
|
|
31
|
-
const found = m.get(key)
|
|
33
|
+
const found = m.get(key)
|
|
32
34
|
if (found !== undefined) {
|
|
33
|
-
return found
|
|
35
|
+
return found
|
|
34
36
|
}
|
|
35
|
-
m.set(key, value)
|
|
36
|
-
return value
|
|
37
|
-
}
|
|
37
|
+
m.set(key, value)
|
|
38
|
+
return value
|
|
39
|
+
}
|
package/std/pair.ts
CHANGED