functionalscript 0.32.4 → 0.34.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/README.md +1 -1
- package/fs/asserts/module.f.d.ts +1 -1
- package/fs/asserts/module.f.js +4 -1
- package/fs/bnf/data/module.f.d.ts +0 -103
- package/fs/bnf/data/module.f.js +10 -246
- package/fs/bnf/data/proof.f.d.ts +0 -7
- package/fs/bnf/data/proof.f.js +3 -636
- package/fs/bnf/descent/module.f.d.ts +56 -0
- package/fs/bnf/descent/module.f.js +119 -0
- package/fs/bnf/descent/proof.f.d.ts +5 -0
- package/fs/bnf/descent/proof.f.js +296 -0
- package/fs/bnf/ll1/module.f.d.ts +72 -0
- package/fs/bnf/ll1/module.f.js +153 -0
- package/fs/bnf/ll1/proof.f.d.ts +9 -0
- package/fs/bnf/ll1/proof.f.js +358 -0
- package/fs/cas/cli/module.f.d.ts +6 -0
- package/fs/cas/cli/module.f.js +56 -0
- package/fs/cas/cli/proof.f.d.ts +14 -0
- package/fs/cas/cli/proof.f.js +149 -0
- package/fs/cas/mcp/module.f.d.ts +9 -17
- package/fs/cas/mcp/module.f.js +117 -83
- package/fs/cas/mcp/proof.f.d.ts +5 -1
- package/fs/cas/mcp/proof.f.js +79 -32
- package/fs/cas/module.f.d.ts +33 -27
- package/fs/cas/module.f.js +151 -126
- package/fs/cas/proof.f.d.ts +16 -13
- package/fs/cas/proof.f.js +255 -130
- package/fs/ci/config/module.f.d.ts +15 -15
- package/fs/ci/config/module.f.js +15 -15
- package/fs/ci/proof.f.js +8 -6
- package/fs/cli/proof.f.js +2 -12
- package/fs/djs/parser/module.f.d.ts +0 -5
- package/fs/djs/proof.f.js +5 -6
- package/fs/djs/serializer/module.f.d.ts +1 -3
- package/fs/djs/tokenizer-new/module.f.js +3 -2
- package/fs/djs/tokenizer-new/proof.f.d.ts +3 -0
- package/fs/djs/tokenizer-new/proof.f.js +458 -296
- package/fs/djs/transpiler/proof.f.js +10 -10
- package/fs/effects/list/module.f.d.ts +31 -0
- package/fs/effects/list/module.f.js +16 -0
- package/fs/effects/module.f.d.ts +11 -5
- package/fs/effects/module.f.js +16 -6
- package/fs/effects/node/module.f.d.ts +29 -3
- package/fs/effects/node/module.f.js +35 -1
- package/fs/effects/node/module.js +32 -18
- package/fs/effects/node/proof.f.js +36 -36
- package/fs/effects/node/virtual/module.f.d.ts +16 -2
- package/fs/effects/node/virtual/module.f.js +129 -20
- package/fs/effects/node/virtual/proof.f.d.ts +4 -0
- package/fs/effects/node/virtual/proof.f.js +47 -14
- package/fs/effects/proof.f.d.ts +4 -0
- package/fs/effects/proof.f.js +18 -1
- package/fs/emergent_testing/proof.f.js +3 -11
- package/fs/fjs/module.f.js +2 -8
- package/fs/fjs/proof.f.js +2 -11
- package/fs/html/module.f.js +6 -8
- package/fs/js/tokenizer/module.f.d.ts +5 -0
- package/fs/js/tokenizer/module.f.js +13 -0
- package/fs/json/serializer/module.f.js +0 -1
- package/fs/mcp/module.f.d.ts +1 -1
- package/fs/mime/module.f.d.ts +101 -5
- package/fs/mime/module.f.js +159 -6
- package/fs/mime/proof.f.d.ts +25 -0
- package/fs/mime/proof.f.js +193 -3
- package/fs/text/code_point/module.f.d.ts +39 -2
- package/fs/text/code_point/module.f.js +74 -2
- package/fs/text/code_point/proof.f.d.ts +8 -0
- package/fs/text/code_point/proof.f.js +72 -0
- package/fs/text/sgr/proof.f.js +2 -11
- package/fs/text/utf16/module.f.js +4 -26
- package/fs/text/utf8/module.f.d.ts +27 -0
- package/fs/text/utf8/module.f.js +8 -14
- package/fs/types/bigint/module.f.d.ts +8 -15
- package/fs/types/bigint/module.f.js +9 -22
- package/fs/types/bigint/proof.f.d.ts +0 -2
- package/fs/types/bigint/proof.f.js +6 -16
- package/fs/types/function/operator/module.f.d.ts +26 -0
- package/fs/types/list/module.f.d.ts +3 -0
- package/fs/types/result/module.d.ts +2 -4
- package/fs/types/result/module.js +9 -3
- package/package.json +3 -3
- package/issues/demo/data/data.f.js +0 -12
- package/issues/demo/data/shared.f.js +0 -3
- package/issues/demo/fs/app.js +0 -4
- package/issues/demo/fs/math.f.js +0 -4
- package/issues/demo/sample/proof.f.js +0 -13
- /package/{issues → todo}/031-json.f.d.ts +0 -0
- /package/{issues → todo}/031-json.f.js +0 -0
- /package/{issues → todo}/proof.f.d.ts +0 -0
- /package/{issues → todo}/proof.f.js +0 -0
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared Unicode code-point contract for the UTF-8 and UTF-16 decoders: the
|
|
3
|
-
* error-tag mask used to flag invalid sequences,
|
|
3
|
+
* error-tag mask used to flag invalid sequences, the streaming `decoder`
|
|
4
4
|
* factory that wraps a per-unit step and an end-of-input step into a single
|
|
5
|
-
* `List`-to-`List` conversion
|
|
5
|
+
* `List`-to-`List` conversion, and the code-point classification predicates
|
|
6
|
+
* (BMP / surrogate / supplementary-plane / overall validity) that both codecs
|
|
7
|
+
* share.
|
|
6
8
|
*
|
|
7
9
|
* @module
|
|
8
10
|
*/
|
|
9
11
|
import { flat, stateScan } from "../../types/list/module.f.js";
|
|
12
|
+
import { contains } from "../../types/range/module.f.js";
|
|
10
13
|
/**
|
|
11
14
|
* Error mask used to tag invalid code points or encoding errors. A decoded
|
|
12
15
|
* value with this bit set represents a malformed unit rather than a valid
|
|
@@ -29,3 +32,72 @@ export const decoder = (byteOp, eofOp) => {
|
|
|
29
32
|
const run = stateScan(op)(null);
|
|
30
33
|
return input => flat(run(flat([input, [null]])));
|
|
31
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Unicode code-point classification boundaries. The surrogate block
|
|
37
|
+
* (`0xD800`–`0xDFFF`) splits into a high half (`0xD800`–`0xDBFF`) and a low half
|
|
38
|
+
* (`0xDC00`–`0xDFFF`); the BMP ends at `0xFFFF` and `maxCodePoint` (`0x10FFFF`)
|
|
39
|
+
* is the largest assignable code point. Every predicate below is derived from
|
|
40
|
+
* these constants so the surrogate bounds and the maximum appear exactly once.
|
|
41
|
+
*/
|
|
42
|
+
const surrogateMin = 0xd800;
|
|
43
|
+
const lowSurrogateMin = 0xdc00;
|
|
44
|
+
const surrogateMax = 0xdfff;
|
|
45
|
+
const bmpMax = 0xffff;
|
|
46
|
+
const maxCodePoint = 0x10_ffff;
|
|
47
|
+
/**
|
|
48
|
+
* Checks whether the 16-bit word (U16) is a high surrogate.
|
|
49
|
+
* Range: 0xD800 - 0xDBFF.
|
|
50
|
+
*/
|
|
51
|
+
export const isHighSurrogate = contains([surrogateMin, lowSurrogateMin - 1]);
|
|
52
|
+
/**
|
|
53
|
+
* Checks whether the 16-bit word (U16) is a low surrogate.
|
|
54
|
+
* Range: 0xDC00 - 0xDFFF.
|
|
55
|
+
*/
|
|
56
|
+
export const isLowSurrogate = contains([lowSurrogateMin, surrogateMax]);
|
|
57
|
+
/**
|
|
58
|
+
* Ranges of code points for the lower (Low) and higher (High) parts of the BMP
|
|
59
|
+
* (Basic Multilingual Plane), i.e. the BMP with the surrogate block removed.
|
|
60
|
+
*/
|
|
61
|
+
const lowBmp = contains([0x0000, surrogateMin - 1]);
|
|
62
|
+
const highBmp = contains([surrogateMax + 1, bmpMax]);
|
|
63
|
+
/**
|
|
64
|
+
* Checks whether the code point is in the BMP range.
|
|
65
|
+
* BMP is the main Unicode plane that covers code points 0x0000 - 0xFFFF, except
|
|
66
|
+
* for the range of surrogates.
|
|
67
|
+
*/
|
|
68
|
+
export const isBmpCodePoint = (codePoint) => lowBmp(codePoint) || highBmp(codePoint);
|
|
69
|
+
/**
|
|
70
|
+
* Checks whether the code point belongs to a supplementary (additional) Unicode
|
|
71
|
+
* plane. Supplementary planes cover code points from 0x010000 to 0x10FFFF.
|
|
72
|
+
*/
|
|
73
|
+
export const isSupplementaryPlane = contains([bmpMax + 1, maxCodePoint]);
|
|
74
|
+
/**
|
|
75
|
+
* The full assignable code-point range and the surrogate block, used to gate
|
|
76
|
+
* overall validity below.
|
|
77
|
+
*/
|
|
78
|
+
const validRange = contains([0, maxCodePoint]);
|
|
79
|
+
const isSurrogate = contains([surrogateMin, surrogateMax]);
|
|
80
|
+
/**
|
|
81
|
+
* Checks whether the code point is a valid scalar value: within the assignable
|
|
82
|
+
* Unicode range (0x0000 - 0x10FFFF) and not a surrogate.
|
|
83
|
+
*/
|
|
84
|
+
export const isValidCodePoint = (c) => validRange(c) && !isSurrogate(c);
|
|
85
|
+
/**
|
|
86
|
+
* The control-character blocks and the whitespace exception used to separate
|
|
87
|
+
* *text* code points from binary control bytes. C0 controls span 0x0000 -
|
|
88
|
+
* 0x001F; 0x007F (DEL) and the C1 controls (0x0080 - 0x009F) form one
|
|
89
|
+
* contiguous run; the whitespace block 0x0009 - 0x000D (TAB, LF, VT, FF, CR) is
|
|
90
|
+
* the only control range legitimate in text.
|
|
91
|
+
*/
|
|
92
|
+
const c0Control = contains([0x00, 0x1f]);
|
|
93
|
+
const delAndC1Control = contains([0x7f, 0x9f]);
|
|
94
|
+
const textWhitespace = contains([0x09, 0x0d]);
|
|
95
|
+
/**
|
|
96
|
+
* Checks whether the code point is a *text* code point — distinct from
|
|
97
|
+
* {@link isValidCodePoint}, which gates well-formedness for decoding. A code
|
|
98
|
+
* point is text unless it is a control character: the controls are 0x0000 -
|
|
99
|
+
* 0x001F, 0x007F (DEL), and 0x0080 - 0x009F (C1), minus the whitespace block
|
|
100
|
+
* 0x0009 - 0x000D (TAB, LF, VT, FF, CR), which is legitimate in text. Every
|
|
101
|
+
* code point at or above 0x0020 that is not DEL or a C1 control is text.
|
|
102
|
+
*/
|
|
103
|
+
export const isTextCodePoint = (c) => textWhitespace(c) || !(c0Control(c) || delAndC1Control(c));
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { isBmpCodePoint, isHighSurrogate, isLowSurrogate, isSupplementaryPlane, isTextCodePoint, isValidCodePoint, } from "./module.f.js";
|
|
2
|
+
const check = (actual, expected) => {
|
|
3
|
+
if (actual !== expected) {
|
|
4
|
+
throw `${actual} !== ${expected}`;
|
|
5
|
+
}
|
|
6
|
+
};
|
|
7
|
+
export const proof = {
|
|
8
|
+
isHighSurrogate: [
|
|
9
|
+
() => check(isHighSurrogate(0xd800), true),
|
|
10
|
+
() => check(isHighSurrogate(0xdbff), true),
|
|
11
|
+
() => check(isHighSurrogate(0xd7ff), false),
|
|
12
|
+
() => check(isHighSurrogate(0xdc00), false),
|
|
13
|
+
],
|
|
14
|
+
isLowSurrogate: [
|
|
15
|
+
() => check(isLowSurrogate(0xdc00), true),
|
|
16
|
+
() => check(isLowSurrogate(0xdfff), true),
|
|
17
|
+
() => check(isLowSurrogate(0xdbff), false),
|
|
18
|
+
() => check(isLowSurrogate(0xe000), false),
|
|
19
|
+
],
|
|
20
|
+
isBmpCodePoint: [
|
|
21
|
+
// lowBmp branch true
|
|
22
|
+
() => check(isBmpCodePoint(0x0000), true),
|
|
23
|
+
() => check(isBmpCodePoint(0xd7ff), true),
|
|
24
|
+
// lowBmp false, highBmp true
|
|
25
|
+
() => check(isBmpCodePoint(0xe000), true),
|
|
26
|
+
() => check(isBmpCodePoint(0xffff), true),
|
|
27
|
+
// both false: surrogate and supplementary
|
|
28
|
+
() => check(isBmpCodePoint(0xd800), false),
|
|
29
|
+
() => check(isBmpCodePoint(0x10000), false),
|
|
30
|
+
],
|
|
31
|
+
isSupplementaryPlane: [
|
|
32
|
+
() => check(isSupplementaryPlane(0x10000), true),
|
|
33
|
+
() => check(isSupplementaryPlane(0x10ffff), true),
|
|
34
|
+
() => check(isSupplementaryPlane(0xffff), false),
|
|
35
|
+
() => check(isSupplementaryPlane(0x110000), false),
|
|
36
|
+
],
|
|
37
|
+
isValidCodePoint: [
|
|
38
|
+
// in range, not surrogate
|
|
39
|
+
() => check(isValidCodePoint(0x0000), true),
|
|
40
|
+
() => check(isValidCodePoint(0x10ffff), true),
|
|
41
|
+
// in range, surrogate -> invalid
|
|
42
|
+
() => check(isValidCodePoint(0xd800), false),
|
|
43
|
+
() => check(isValidCodePoint(0xdfff), false),
|
|
44
|
+
// out of range -> validRange short-circuits false
|
|
45
|
+
() => check(isValidCodePoint(-1), false),
|
|
46
|
+
() => check(isValidCodePoint(0x110000), false),
|
|
47
|
+
],
|
|
48
|
+
isTextCodePoint: [
|
|
49
|
+
// C0 controls are binary...
|
|
50
|
+
() => check(isTextCodePoint(0x00), false), // NUL
|
|
51
|
+
() => check(isTextCodePoint(0x08), false), // BS
|
|
52
|
+
() => check(isTextCodePoint(0x1b), false), // ESC
|
|
53
|
+
() => check(isTextCodePoint(0x1f), false), // US
|
|
54
|
+
// ...except the whitespace block 0x09 - 0x0D
|
|
55
|
+
() => check(isTextCodePoint(0x09), true), // TAB
|
|
56
|
+
() => check(isTextCodePoint(0x0a), true), // LF
|
|
57
|
+
() => check(isTextCodePoint(0x0b), true), // VT
|
|
58
|
+
() => check(isTextCodePoint(0x0c), true), // FF
|
|
59
|
+
() => check(isTextCodePoint(0x0d), true), // CR
|
|
60
|
+
// printable ASCII is text
|
|
61
|
+
() => check(isTextCodePoint(0x20), true), // space
|
|
62
|
+
() => check(isTextCodePoint(0x41), true), // 'A'
|
|
63
|
+
() => check(isTextCodePoint(0x7e), true), // '~'
|
|
64
|
+
// DEL and the C1 controls are binary
|
|
65
|
+
() => check(isTextCodePoint(0x7f), false), // DEL
|
|
66
|
+
() => check(isTextCodePoint(0x80), false), // C1 start
|
|
67
|
+
() => check(isTextCodePoint(0x9f), false), // C1 end
|
|
68
|
+
// above C1 is text again
|
|
69
|
+
() => check(isTextCodePoint(0xa0), true), // NBSP
|
|
70
|
+
() => check(isTextCodePoint(0x10ffff), true),
|
|
71
|
+
],
|
|
72
|
+
};
|
package/fs/text/sgr/proof.f.js
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import { fgRed, reset, createConsoleText, backspace, csiWrite } from "./module.f.js";
|
|
2
|
-
import { virtual, emptyState } from "../../effects/node/virtual/module.f.js";
|
|
3
|
-
const makeOptions = (isTTY) => ({
|
|
4
|
-
args: [],
|
|
5
|
-
env: {},
|
|
6
|
-
home: '.',
|
|
7
|
-
std: { stdout: { isTTY }, stderr: { isTTY } },
|
|
8
|
-
testContext: { test: async () => { } },
|
|
9
|
-
bunTestContext: { test: async () => { } },
|
|
10
|
-
playwrightTestContext: { test: async () => { } },
|
|
11
|
-
engine: 'node',
|
|
12
|
-
});
|
|
2
|
+
import { virtual, emptyState, defaultNodeProgramOptions } from "../../effects/node/virtual/module.f.js";
|
|
3
|
+
const makeOptions = (isTTY) => ({ ...defaultNodeProgramOptions, std: { stdout: { isTTY }, stderr: { isTTY } } });
|
|
13
4
|
export const proof = [
|
|
14
5
|
() => {
|
|
15
6
|
if (fgRed !== '\x1b[31m') {
|
|
@@ -9,33 +9,11 @@ import { map, reduce, flatMap, empty, } from "../../types/list/module.f.js";
|
|
|
9
9
|
import { concat } from "../../types/function/operator/module.f.js";
|
|
10
10
|
import { contains } from "../../types/range/module.f.js";
|
|
11
11
|
import { fn } from "../../types/function/module.f.js";
|
|
12
|
-
import { decoder, errorMask } from "../code_point/module.f.js";
|
|
13
|
-
/**
|
|
14
|
-
* Ranges of code points for the lower (Low) and higher (High) parts of the BMP (Basic Multilingual Plane) plane.
|
|
15
|
-
*/
|
|
16
|
-
const lowBmp = contains([0x0000, 0xd7ff]);
|
|
17
|
-
const highBmp = contains([0xe000, 0xffff]);
|
|
18
|
-
/**
|
|
19
|
-
* Checks whether the code point is in the BMP range.
|
|
20
|
-
* BMP is the main multi-plane Unicode plane that covers code points 0x0000 - 0xFFFF, except for the range of surrogates.
|
|
21
|
-
*/
|
|
22
|
-
const isBmpCodePoint = (codePoint) => lowBmp(codePoint) || highBmp(codePoint);
|
|
23
|
-
/**
|
|
24
|
-
* Checks whether the 16-bit word (U16) is a surrogate of the high part.
|
|
25
|
-
* Range: 0xD800 - 0xDBFF.
|
|
26
|
-
*/
|
|
27
|
-
const isHighSurrogate = contains([0xd800, 0xdbff]);
|
|
28
|
-
/**
|
|
29
|
-
* Checks whether the 16-bit word (U16) is a substitute for the low part.
|
|
30
|
-
* Range: 0xDC00 – 0xDFFF.
|
|
31
|
-
*/
|
|
32
|
-
const isLowSurrogate = contains([0xdc00, 0xdfff]);
|
|
33
|
-
/**
|
|
34
|
-
* Checks whether the code point belongs to the additional (Supplementary) plane of Unicode.
|
|
35
|
-
* Additional planes include code points from 0x010000 to 0x10FFFF.
|
|
36
|
-
*/
|
|
37
|
-
const isSupplementaryPlane = contains([0x01_0000, 0x10_ffff]);
|
|
12
|
+
import { decoder, errorMask, isBmpCodePoint, isHighSurrogate, isLowSurrogate, isSupplementaryPlane, } from "../code_point/module.f.js";
|
|
38
13
|
/**
|
|
14
|
+
* The BMP / surrogate / supplementary-plane predicates used below live in
|
|
15
|
+
* `code_point`, the shared Unicode contract; see that module for their ranges.
|
|
16
|
+
*
|
|
39
17
|
* Converts a Unicode code point to its corresponding UTF-16 representation.
|
|
40
18
|
*
|
|
41
19
|
* This function handles:
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { type List, type Thunk } from '../../types/list/module.f.ts';
|
|
7
|
+
import type { StateScan } from '../../types/function/operator/module.f.ts';
|
|
7
8
|
import type { Array1, Array2, Array3 } from '../../types/array/module.f.ts';
|
|
8
9
|
import { type Vec } from '../../types/bit_vec/module.f.ts';
|
|
9
10
|
/**
|
|
@@ -35,6 +36,32 @@ export type Utf8State = null | Utf8NonEmptyState;
|
|
|
35
36
|
* @returns A thunk that lazily produces a sequence of UTF-8 bytes.
|
|
36
37
|
*/
|
|
37
38
|
export declare const fromCodePointList: (input: List<number>) => Thunk<U8>;
|
|
39
|
+
/**
|
|
40
|
+
* Converts a non-empty UTF-8 decoding state to an error code.
|
|
41
|
+
*
|
|
42
|
+
* @param state - A non-empty UTF-8 decoding state.
|
|
43
|
+
* @returns An I32 error code derived from the invalid UTF-8 state.
|
|
44
|
+
*/
|
|
45
|
+
export declare const utf8StateToError: (state: Utf8NonEmptyState) => I32;
|
|
46
|
+
/**
|
|
47
|
+
* Decodes a byte into a Unicode code point, using a given UTF-8 state.
|
|
48
|
+
*
|
|
49
|
+
* @param state - The current UTF-8 decoding state.
|
|
50
|
+
* @param byte - A single byte to decode.
|
|
51
|
+
* @returns A tuple containing:
|
|
52
|
+
* - A list of decoded Unicode code points or error codes.
|
|
53
|
+
* - The updated UTF-8 state.
|
|
54
|
+
*/
|
|
55
|
+
export declare const utf8ByteToCodePointOp: StateScan<number, Utf8State, readonly I32[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Handles the end-of-file (EOF) case for UTF-8 decoding.
|
|
58
|
+
*
|
|
59
|
+
* @param state - The current UTF-8 decoding state.
|
|
60
|
+
* @returns A tuple containing:
|
|
61
|
+
* - A list of decoded Unicode code points or error codes.
|
|
62
|
+
* - The reset UTF-8 state (`null`).
|
|
63
|
+
*/
|
|
64
|
+
export declare const utf8EofToCodePointOp: (state: Utf8State) => readonly [List<I32>, Utf8State];
|
|
38
65
|
/**
|
|
39
66
|
* Converts a list of UTF-8 bytes into a list of Unicode code points.
|
|
40
67
|
*
|
package/fs/text/utf8/module.f.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { flatMap, toArray } from "../../types/list/module.f.js";
|
|
7
|
-
import { decoder, errorMask } from "../code_point/module.f.js";
|
|
7
|
+
import { decoder, errorMask, isValidCodePoint } from "../code_point/module.f.js";
|
|
8
8
|
import { msb, u8List, length } from "../../types/bit_vec/module.f.js";
|
|
9
9
|
import { codePointListToString } from "../utf16/module.f.js";
|
|
10
10
|
/**
|
|
@@ -106,7 +106,7 @@ export const fromCodePointList = flatMap(codePointToUtf8);
|
|
|
106
106
|
* @param state - A non-empty UTF-8 decoding state.
|
|
107
107
|
* @returns An I32 error code derived from the invalid UTF-8 state.
|
|
108
108
|
*/
|
|
109
|
-
const utf8StateToError = (state) => {
|
|
109
|
+
export const utf8StateToError = (state) => {
|
|
110
110
|
let x;
|
|
111
111
|
switch (state.length) {
|
|
112
112
|
case 1: {
|
|
@@ -127,8 +127,8 @@ const utf8StateToError = (state) => {
|
|
|
127
127
|
contPayload(s2) + 0b1000_0000_0000_0000;
|
|
128
128
|
break;
|
|
129
129
|
}
|
|
130
|
-
default:
|
|
131
|
-
|
|
130
|
+
//default:
|
|
131
|
+
// throw 'invalid state'
|
|
132
132
|
}
|
|
133
133
|
return x | errorMask;
|
|
134
134
|
};
|
|
@@ -141,7 +141,7 @@ const utf8StateToError = (state) => {
|
|
|
141
141
|
* - A list of decoded Unicode code points or error codes.
|
|
142
142
|
* - The updated UTF-8 state.
|
|
143
143
|
*/
|
|
144
|
-
const utf8ByteToCodePointOp = (byte, state) => {
|
|
144
|
+
export const utf8ByteToCodePointOp = (byte, state) => {
|
|
145
145
|
if (byte < 0x00 || byte > 0xff) {
|
|
146
146
|
return [[errorMask], state];
|
|
147
147
|
}
|
|
@@ -199,7 +199,7 @@ const utf8ByteToCodePointOp = (byte, state) => {
|
|
|
199
199
|
* - A list of decoded Unicode code points or error codes.
|
|
200
200
|
* - The reset UTF-8 state (`null`).
|
|
201
201
|
*/
|
|
202
|
-
const utf8EofToCodePointOp = (state) => [
|
|
202
|
+
export const utf8EofToCodePointOp = (state) => [
|
|
203
203
|
state === null ? null : [utf8StateToError(state)],
|
|
204
204
|
null,
|
|
205
205
|
];
|
|
@@ -216,18 +216,12 @@ export const toCodePointList = decoder(utf8ByteToCodePointOp, utf8EofToCodePoint
|
|
|
216
216
|
* code points.
|
|
217
217
|
*/
|
|
218
218
|
export const fromVec = (v) => {
|
|
219
|
-
if (length(v)
|
|
219
|
+
if ((length(v) & 7n) !== 0n) {
|
|
220
220
|
return null;
|
|
221
221
|
}
|
|
222
222
|
const arr = toArray(toCodePointList(u8List(msb)(v)));
|
|
223
223
|
for (const cp of arr) {
|
|
224
|
-
if (cp
|
|
225
|
-
return null;
|
|
226
|
-
}
|
|
227
|
-
if (cp > 0x10FFFF) {
|
|
228
|
-
return null;
|
|
229
|
-
}
|
|
230
|
-
if (cp >= 0xD800 && cp <= 0xDFFF) {
|
|
224
|
+
if (!isValidCodePoint(cp)) {
|
|
231
225
|
return null;
|
|
232
226
|
}
|
|
233
227
|
}
|
|
@@ -156,24 +156,17 @@ export declare const xor: Reduce;
|
|
|
156
156
|
export declare const divUp: (b: bigint) => Unary;
|
|
157
157
|
export declare const roundUp: (b: bigint) => Unary;
|
|
158
158
|
/**
|
|
159
|
-
*
|
|
159
|
+
* Converts a bit count to a byte count, rounding up — divides by `8`.
|
|
160
160
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
|
|
164
|
-
export declare const divUpE2: (e: bigint) => Unary;
|
|
165
|
-
/**
|
|
166
|
-
* Rounds a bigint value up to the nearest multiple of 2^e (shift-based, power-of-two only).
|
|
167
|
-
*
|
|
168
|
-
* @param e - The exponent (multiple = 2^e).
|
|
169
|
-
* @returns A function that rounds a value up to the nearest multiple of the given power of two.
|
|
170
|
-
*/
|
|
171
|
-
export declare const roundUpE2: (e: bigint) => Unary;
|
|
172
|
-
/**
|
|
173
|
-
* Converts a bit count to a byte count, rounding up — divides by `8` (`2^3` bits per byte).
|
|
161
|
+
* Domain: non-negative inputs (bit/byte counts). On negative inputs `divUp`
|
|
162
|
+
* truncates toward zero rather than flooring toward −∞, so the rounding
|
|
163
|
+
* direction is only meaningful for `v >= 0n`.
|
|
174
164
|
*/
|
|
175
165
|
export declare const divUp8: Unary;
|
|
176
166
|
/**
|
|
177
|
-
* Rounds a bit count up to the nearest whole byte — the nearest multiple of `8
|
|
167
|
+
* Rounds a bit count up to the nearest whole byte — the nearest multiple of `8`.
|
|
168
|
+
*
|
|
169
|
+
* Domain: non-negative inputs (bit/byte counts). See `divUp8` for the
|
|
170
|
+
* truncate-vs-floor caveat on negative values.
|
|
178
171
|
*/
|
|
179
172
|
export declare const roundUp8: Unary;
|
|
@@ -234,30 +234,17 @@ export const roundUp = (b) => {
|
|
|
234
234
|
return v => d(v) * b;
|
|
235
235
|
};
|
|
236
236
|
/**
|
|
237
|
-
*
|
|
237
|
+
* Converts a bit count to a byte count, rounding up — divides by `8`.
|
|
238
238
|
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
239
|
+
* Domain: non-negative inputs (bit/byte counts). On negative inputs `divUp`
|
|
240
|
+
* truncates toward zero rather than flooring toward −∞, so the rounding
|
|
241
|
+
* direction is only meaningful for `v >= 0n`.
|
|
241
242
|
*/
|
|
242
|
-
export const
|
|
243
|
-
const m = mask(e);
|
|
244
|
-
return v => (v + m) >> e;
|
|
245
|
-
};
|
|
243
|
+
export const divUp8 = divUp(8n);
|
|
246
244
|
/**
|
|
247
|
-
* Rounds a
|
|
245
|
+
* Rounds a bit count up to the nearest whole byte — the nearest multiple of `8`.
|
|
248
246
|
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*/
|
|
252
|
-
export const roundUpE2 = (e) => {
|
|
253
|
-
const d = divUpE2(e);
|
|
254
|
-
return v => d(v) << e;
|
|
255
|
-
};
|
|
256
|
-
/**
|
|
257
|
-
* Converts a bit count to a byte count, rounding up — divides by `8` (`2^3` bits per byte).
|
|
258
|
-
*/
|
|
259
|
-
export const divUp8 = divUpE2(3n);
|
|
260
|
-
/**
|
|
261
|
-
* Rounds a bit count up to the nearest whole byte — the nearest multiple of `8` (`2^3` bits per byte).
|
|
247
|
+
* Domain: non-negative inputs (bit/byte counts). See `divUp8` for the
|
|
248
|
+
* truncate-vs-floor caveat on negative values.
|
|
262
249
|
*/
|
|
263
|
-
export const roundUp8 =
|
|
250
|
+
export const roundUp8 = roundUp(8n);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sum, abs, serialize, log2, bitLength, mask, combination, factorial, xor, multiple, product, divUp, roundUp,
|
|
1
|
+
import { sum, abs, serialize, log2, bitLength, mask, combination, factorial, xor, multiple, product, divUp, roundUp, divUp8, roundUp8 } from "./module.f.js";
|
|
2
2
|
import { assertEq } from "../../asserts/module.f.js";
|
|
3
3
|
import { min } from "../function/compare/module.f.js";
|
|
4
4
|
const oldLog2 = (v) => {
|
|
@@ -463,32 +463,22 @@ export const proof = {
|
|
|
463
463
|
assertEq(roundUp(8n)(15n), 16n);
|
|
464
464
|
assertEq(roundUp(8n)(3n), 8n);
|
|
465
465
|
},
|
|
466
|
-
divUpE2: () => {
|
|
467
|
-
assertEq(divUpE2(3n)(8n), 1n);
|
|
468
|
-
assertEq(divUpE2(3n)(15n), 2n);
|
|
469
|
-
assertEq(divUpE2(3n)(0n), 0n);
|
|
470
|
-
assertEq(divUpE2(3n)(8n), 1n);
|
|
471
|
-
assertEq(divUpE2(3n)(9n), 2n);
|
|
472
|
-
},
|
|
473
|
-
roundUpE2: () => {
|
|
474
|
-
assertEq(roundUpE2(3n)(8n), 8n);
|
|
475
|
-
assertEq(roundUpE2(3n)(15n), 16n);
|
|
476
|
-
assertEq(roundUpE2(3n)(3n), 8n);
|
|
477
|
-
assertEq(roundUpE2(3n)(0n), 0n);
|
|
478
|
-
assertEq(roundUpE2(3n)(8n), 8n);
|
|
479
|
-
assertEq(roundUpE2(3n)(9n), 16n);
|
|
480
|
-
},
|
|
481
466
|
divUp8: () => {
|
|
482
467
|
assertEq(divUp8(0n), 0n);
|
|
483
468
|
assertEq(divUp8(1n), 1n);
|
|
484
469
|
assertEq(divUp8(8n), 1n);
|
|
470
|
+
assertEq(divUp8(8n), 1n);
|
|
485
471
|
assertEq(divUp8(9n), 2n);
|
|
472
|
+
assertEq(divUp8(15n), 2n);
|
|
486
473
|
},
|
|
487
474
|
roundUp8: () => {
|
|
488
475
|
assertEq(roundUp8(0n), 0n);
|
|
489
476
|
assertEq(roundUp8(1n), 8n);
|
|
477
|
+
assertEq(roundUp8(3n), 8n);
|
|
478
|
+
assertEq(roundUp8(8n), 8n);
|
|
490
479
|
assertEq(roundUp8(8n), 8n);
|
|
491
480
|
assertEq(roundUp8(9n), 16n);
|
|
481
|
+
assertEq(roundUp8(15n), 16n);
|
|
492
482
|
},
|
|
493
483
|
xor: () => {
|
|
494
484
|
assertEq(xor(5n)(3n), 6n);
|
|
@@ -12,6 +12,32 @@ export declare const logicalNot: Unary<boolean, boolean>;
|
|
|
12
12
|
export type Equal<T> = Binary<T, T, boolean>;
|
|
13
13
|
export declare const strictEqual: <T>(a: T) => (b: T) => boolean;
|
|
14
14
|
export type Scan<I, O> = (input: I) => readonly [O, Scan<I, O>];
|
|
15
|
+
/**
|
|
16
|
+
* One step of a stream transducer: given an `input` symbol and the `prior`
|
|
17
|
+
* state, produce an `output` and the next state. It both maps an input stream
|
|
18
|
+
* to an output stream and threads state, so it models tokenizers, decoders, and
|
|
19
|
+
* other stream-to-stream stages.
|
|
20
|
+
*
|
|
21
|
+
* This is the *shape* of a [Mealy machine](https://en.wikipedia.org/wiki/Mealy_machine)
|
|
22
|
+
* — a [finite-state transducer](https://en.wikipedia.org/wiki/Finite-state_transducer)
|
|
23
|
+
* — but only its signature. The state `S` (and `I`, `O`) is an arbitrary type,
|
|
24
|
+
* not a finite set, so a `StateScan` is strictly more expressive than a Mealy
|
|
25
|
+
* machine — its power is the power of `S`:
|
|
26
|
+
* - a finite `S`/`I`/`O` recovers the classical finite-state machine (e.g. the
|
|
27
|
+
* DFA states in `../../../fsm/module.f.ts`);
|
|
28
|
+
* - an `S` that is a stack makes it a
|
|
29
|
+
* [pushdown / stack machine](https://en.wikipedia.org/wiki/Pushdown_automaton)
|
|
30
|
+
* (context-free power — balanced brackets, nested structure, the AST tier);
|
|
31
|
+
* - an unbounded `S` like `bigint` can count, which no finite automaton can.
|
|
32
|
+
*
|
|
33
|
+
* And `O` may be a list (0+ symbols per input), not the single symbol strict
|
|
34
|
+
* Mealy emits. (Functional/coalgebraic usage still calls this `(input, state)
|
|
35
|
+
* => [output, state]` shape a "Mealy machine", finiteness aside.)
|
|
36
|
+
*
|
|
37
|
+
* A {@link Fold} is the output-less special case (state only); driving a
|
|
38
|
+
* `StateScan` over a `List` is `stateScan` in `../../list/module.f.ts`, and
|
|
39
|
+
* {@link stateScanToScan} hides the state to recover a {@link Scan}.
|
|
40
|
+
*/
|
|
15
41
|
export type StateScan<I, S, O> = (input: I, prior: S) => readonly [O, S];
|
|
16
42
|
export declare const stateScanToScan: <I, S, O>(op: StateScan<I, S, O>) => (prior: S) => Scan<I, O>;
|
|
17
43
|
export declare const foldToScan: <I, O>(fold: Fold<I, O>) => (prior: O) => Scan<I, O>;
|
|
@@ -4,6 +4,9 @@ type NotLazy<T> = Result<T> | Concat<T> | readonly T[];
|
|
|
4
4
|
type Empty = null;
|
|
5
5
|
export type Result<T> = Empty | NonEmpty<T>;
|
|
6
6
|
export type Thunk<T> = () => List<T>;
|
|
7
|
+
/**
|
|
8
|
+
* See also https://en.wikipedia.org/wiki/Cons#Lists
|
|
9
|
+
*/
|
|
7
10
|
export type NonEmpty<T> = {
|
|
8
11
|
readonly first: T;
|
|
9
12
|
readonly tail: List<T>;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import { type Result } from './module.f.ts';
|
|
2
|
-
declare const
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
export default _default;
|
|
2
|
+
export declare const tryCatch: <T>(f: () => T) => Result<T, unknown>;
|
|
3
|
+
export declare const asyncTryCatch: <T>(f: () => Promise<T>) => Promise<Result<T, unknown>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ok, error } from "./module.f.js";
|
|
2
|
-
const tryCatch = f => {
|
|
2
|
+
export const tryCatch = f => {
|
|
3
3
|
// Side effect: `try catch` is not allowed in FunctionalScript.
|
|
4
4
|
try {
|
|
5
5
|
return ok(f());
|
|
@@ -8,6 +8,12 @@ const tryCatch = f => {
|
|
|
8
8
|
return error(e);
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
|
-
export
|
|
12
|
-
|
|
11
|
+
export const asyncTryCatch = async (f) => {
|
|
12
|
+
// Side effect: `try catch` is not allowed in FunctionalScript.
|
|
13
|
+
try {
|
|
14
|
+
return ok(await f());
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
return error(e);
|
|
18
|
+
}
|
|
13
19
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
},
|
|
44
44
|
"homepage": "https://github.com/functionalscript/functionalscript#readme",
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@playwright/test": "1.61.
|
|
47
|
-
"@types/node": "26.0.
|
|
46
|
+
"@playwright/test": "1.61.1",
|
|
47
|
+
"@types/node": "26.0.1",
|
|
48
48
|
"typescript": "6.0.3"
|
|
49
49
|
}
|
|
50
50
|
}
|
package/issues/demo/fs/app.js
DELETED
package/issues/demo/fs/math.f.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const arrayOfTests = [
|
|
2
|
-
() => {
|
|
3
|
-
if (2 + 2 !== 4) throw "It's the end of the world as we know it!"
|
|
4
|
-
},
|
|
5
|
-
() => {
|
|
6
|
-
if (2n + 2n !== 4n) throw "It's the end of the world as we know it!"
|
|
7
|
-
}
|
|
8
|
-
]
|
|
9
|
-
|
|
10
|
-
export const proof = {
|
|
11
|
-
arrayOfTests,
|
|
12
|
-
generatingTests: () => arrayOfTests,
|
|
13
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|