functionalscript 0.0.420 → 0.0.423
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/.github/workflows/bun.yml +1 -1
- package/.github/workflows/deno.yml +1 -1
- package/package.json +2 -2
- package/{deno-test → test.mjs} +42 -33
- package/text/utf16/module.f.cjs +40 -26
- package/text/utf8/module.f.cjs +9 -7
- package/tsconfig.json +1 -1
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.423",
|
|
4
4
|
"description": "FunctionalScript is a functional subset of JavaScript",
|
|
5
5
|
"main": "module.f.cjs",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"tsc": "tsc",
|
|
8
8
|
"test": "tsc && npm run test-only",
|
|
9
9
|
"version": "node ./nodejs/version/main.cjs",
|
|
10
|
-
"test-only": "node --trace-uncaught ./test.
|
|
10
|
+
"test-only": "node --trace-uncaught ./test.mjs"
|
|
11
11
|
},
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
package/{deno-test → test.mjs}
RENAMED
|
@@ -1,78 +1,86 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} = Deno
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {{
|
|
3
|
+
* readonly withFileTypes: true
|
|
4
|
+
* }} Options
|
|
5
|
+
*/
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* @typedef {{
|
|
10
|
-
* readonly isDirectory: boolean
|
|
11
|
-
* readonly isFile: boolean
|
|
12
|
-
* readonly isSymlink: boolean
|
|
13
9
|
* readonly name: string
|
|
14
|
-
*
|
|
10
|
+
* readonly isDirectory: () => boolean
|
|
11
|
+
* }} Dirent
|
|
15
12
|
*/
|
|
16
13
|
|
|
17
|
-
/** @typedef {{ exports?: unknown }} Module */
|
|
18
|
-
|
|
19
|
-
/** @typedef {(name: string) => unknown} Require */
|
|
20
|
-
|
|
21
14
|
/**
|
|
22
15
|
* @typedef {{
|
|
23
|
-
*
|
|
24
|
-
*
|
|
16
|
+
* readonly readdir: (path: string, options: Options) => Promise<readonly Dirent[]>
|
|
17
|
+
* readonly readFile: (path: string, options: 'utf8') => Promise<Buffer>
|
|
18
|
+
* }} FsPromises
|
|
25
19
|
*/
|
|
26
20
|
|
|
27
|
-
/** @type {
|
|
28
|
-
const
|
|
21
|
+
/** @type {FsPromises} */
|
|
22
|
+
const { readdir, readFile } = await import(globalThis.Deno ? 'https://deno.land/std/node/fs/promises.ts' : 'node:fs/promises')
|
|
23
|
+
|
|
24
|
+
const load = async() => {
|
|
29
25
|
/** @type {FunctionMap} */
|
|
30
26
|
const map = {}
|
|
31
27
|
/** @type {(path: string) => Promise<void>} */
|
|
32
28
|
const f = async p => {
|
|
33
|
-
for
|
|
29
|
+
for (const i of await readdir(p, { withFileTypes: true })) {
|
|
34
30
|
const { name } = i
|
|
35
31
|
if (!name.startsWith('.')) {
|
|
36
32
|
const file = `${p}/${name}`
|
|
37
|
-
if (i.isDirectory) {
|
|
33
|
+
if (i.isDirectory()) {
|
|
38
34
|
if (!['node_modules', 'target'].includes(name)) {
|
|
39
35
|
await f(file)
|
|
40
36
|
}
|
|
41
37
|
} else if (name.endsWith('.f.cjs')) {
|
|
42
|
-
|
|
43
|
-
const source = await
|
|
38
|
+
console.log(`loading ${file}`)
|
|
39
|
+
const source = await readFile(file, 'utf8')
|
|
44
40
|
map[file] = Function('module', 'require', `"use strict";${source}`)
|
|
45
41
|
}
|
|
46
42
|
}
|
|
47
43
|
}
|
|
48
44
|
}
|
|
49
|
-
await f(
|
|
45
|
+
await f('.')
|
|
50
46
|
return map
|
|
51
47
|
}
|
|
52
48
|
|
|
49
|
+
const map = await load()
|
|
50
|
+
|
|
51
|
+
/** @typedef {{ exports?: unknown }} Module */
|
|
52
|
+
|
|
53
|
+
/** @typedef {(name: string) => unknown} Require */
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @typedef {{
|
|
57
|
+
* [k in string]: Function
|
|
58
|
+
* }} FunctionMap
|
|
59
|
+
*/
|
|
60
|
+
|
|
53
61
|
/**
|
|
54
62
|
* @typedef {{
|
|
55
63
|
* [k in string]: unknown
|
|
56
64
|
* }} ModuleMap
|
|
57
65
|
*/
|
|
58
66
|
|
|
59
|
-
const
|
|
60
|
-
const m = await dir('.')
|
|
67
|
+
const build = async () => {
|
|
61
68
|
/** @type {ModuleMap} */
|
|
62
69
|
const d = {}
|
|
63
|
-
/** @type {(base: readonly string[]) => (k: string) => unknown} */
|
|
64
|
-
const req = p => k => {
|
|
70
|
+
/** @type {(base: readonly string[]) => (i: string) => (k: string) => unknown} */
|
|
71
|
+
const req = p => i => k => {
|
|
65
72
|
const relativePath = k.split('/')
|
|
66
|
-
const bPath = relativePath.filter(v => !['..', '.'].includes(v))
|
|
67
73
|
const dif = relativePath.filter(v => v === '..').length
|
|
68
|
-
const path = [p.slice(0, p.length - dif),
|
|
74
|
+
const path = [p.slice(0, p.length - dif), relativePath.filter(v => !['..', '.'].includes(v))]
|
|
75
|
+
.flat()
|
|
69
76
|
const pathStr = path.join('/')
|
|
70
77
|
const newBase = path.slice(0, path.length - 1)
|
|
71
78
|
const result = d[pathStr]
|
|
72
79
|
if (result === undefined) {
|
|
73
80
|
/** @type {Module} */
|
|
74
81
|
const me = {}
|
|
75
|
-
|
|
82
|
+
console.log(`${i}building ${pathStr}`)
|
|
83
|
+
map[pathStr](me, req(newBase)(`${i}| `))
|
|
76
84
|
const newResult = me.exports
|
|
77
85
|
d[pathStr] = newResult
|
|
78
86
|
return newResult
|
|
@@ -80,10 +88,11 @@ const run = async () => {
|
|
|
80
88
|
return result
|
|
81
89
|
}
|
|
82
90
|
}
|
|
83
|
-
const r = req(['.'])
|
|
84
|
-
for (const k of Object.keys(
|
|
91
|
+
const r = req(['.'])('')
|
|
92
|
+
for (const k of Object.keys(map)) {
|
|
85
93
|
r(k)
|
|
86
94
|
}
|
|
95
|
+
return d
|
|
87
96
|
}
|
|
88
97
|
|
|
89
|
-
|
|
98
|
+
const modules = await build()
|
package/text/utf16/module.f.cjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
const list = require('../../types/list/module.f.cjs')
|
|
2
2
|
const operator = require('../../types/function/operator/module.f.cjs')
|
|
3
|
-
const array = require('../../types/array/module.f.cjs')
|
|
4
3
|
const { contains } = require('../../types/range/module.f.cjs')
|
|
5
|
-
const {
|
|
6
|
-
const { map, flat, stateScan,
|
|
4
|
+
const { fn } = require('../../types/function/module.f.cjs')
|
|
5
|
+
const { map, flat, stateScan, reduce, flatMap } = list
|
|
7
6
|
|
|
8
7
|
/** @typedef {u16|undefined} WordOrEof */
|
|
9
8
|
|
|
@@ -13,48 +12,57 @@ const { map, flat, stateScan, concat, reduce, flatMap } = list
|
|
|
13
12
|
|
|
14
13
|
/** @typedef {number} i32 */
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
const
|
|
15
|
+
const lowBmp = contains([0x0000, 0xd7ff])
|
|
16
|
+
const highBmp = contains([0xe000, 0xffff])
|
|
18
17
|
|
|
18
|
+
/** @type {(codePoint: i32) => boolean} */
|
|
19
|
+
const isBmpCodePoint = codePoint => lowBmp(codePoint) || highBmp(codePoint)
|
|
20
|
+
|
|
21
|
+
/** @type {(codePoint: i32) => boolean} */
|
|
19
22
|
const isHighSurrogate = contains([0xd800, 0xdbff])
|
|
20
23
|
|
|
21
|
-
/** @type {(
|
|
24
|
+
/** @type {(codePoint: i32) => boolean} */
|
|
22
25
|
const isLowSurrogate = contains([0xdc00, 0xdfff])
|
|
23
26
|
|
|
24
27
|
const errorMask = 0b1000_0000_0000_0000_0000_0000_0000_0000
|
|
25
28
|
|
|
26
|
-
/** @type {(
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
/** @type {(a: i32) => boolean} */
|
|
30
|
+
const isSupplementaryPlane = contains([0x01_0000, 0x10_ffff])
|
|
31
|
+
|
|
32
|
+
/** @type {(input: i32) => list.List<u16>} */
|
|
33
|
+
const codePointToUtf16 = codePoint => {
|
|
34
|
+
if (isBmpCodePoint(codePoint)) { return [codePoint] }
|
|
35
|
+
if (isSupplementaryPlane(codePoint)) {
|
|
36
|
+
const n = codePoint - 0x1_0000
|
|
37
|
+
const high = (n >> 10) + 0xd800
|
|
38
|
+
const low = (n & 0b0011_1111_1111) + 0xdc00
|
|
33
39
|
return [high, low]
|
|
34
40
|
}
|
|
35
|
-
return [
|
|
41
|
+
return [codePoint & 0xffff]
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
const fromCodePointList = flatMap(codePointToUtf16)
|
|
39
45
|
|
|
46
|
+
const u16 = contains([0x0000, 0xFFFF])
|
|
47
|
+
|
|
40
48
|
/** @type {operator.StateScan<u16, Utf16State, list.List<i32>>} */
|
|
41
|
-
const utf16ByteToCodePointOp = state =>
|
|
42
|
-
if (
|
|
49
|
+
const utf16ByteToCodePointOp = state => word => {
|
|
50
|
+
if (!u16(word)) {
|
|
43
51
|
return [[0xffffffff], state]
|
|
44
52
|
}
|
|
45
53
|
if (state === undefined) {
|
|
46
|
-
if (isBmpCodePoint(
|
|
47
|
-
if (isHighSurrogate(
|
|
48
|
-
return [[
|
|
54
|
+
if (isBmpCodePoint(word)) { return [[word], undefined] }
|
|
55
|
+
if (isHighSurrogate(word)) { return [[], word] }
|
|
56
|
+
return [[word | errorMask], undefined]
|
|
49
57
|
}
|
|
50
|
-
if (isLowSurrogate(
|
|
58
|
+
if (isLowSurrogate(word)) {
|
|
51
59
|
const high = state - 0xd800
|
|
52
|
-
const low =
|
|
60
|
+
const low = word - 0xdc00
|
|
53
61
|
return [[(high << 10) + low + 0x10000], undefined]
|
|
54
62
|
}
|
|
55
|
-
if (isBmpCodePoint(
|
|
56
|
-
if (isHighSurrogate(
|
|
57
|
-
return [[state | errorMask,
|
|
63
|
+
if (isBmpCodePoint(word)) { return [[state | errorMask, word], undefined] }
|
|
64
|
+
if (isHighSurrogate(word)) { return [[state | errorMask], word] }
|
|
65
|
+
return [[state | errorMask, word | errorMask], undefined]
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
/** @type {(state: Utf16State) => readonly[list.List<i32>, Utf16State]} */
|
|
@@ -63,8 +71,11 @@ const utf16EofToCodePointOp = state => [state === undefined ? undefined : [state
|
|
|
63
71
|
/** @type {operator.StateScan<WordOrEof, Utf16State, list.List<i32>>} */
|
|
64
72
|
const utf16ByteOrEofToCodePointOp = state => input => input === undefined ? utf16EofToCodePointOp(state) : utf16ByteToCodePointOp(state)(input)
|
|
65
73
|
|
|
74
|
+
/** @type {list.List<WordOrEof>} */
|
|
75
|
+
const eofList = [undefined]
|
|
76
|
+
|
|
66
77
|
/** @type {(input: list.List<u16>) => list.List<i32>} */
|
|
67
|
-
const toCodePointList = input => flat(stateScan(utf16ByteOrEofToCodePointOp)(undefined)(
|
|
78
|
+
const toCodePointList = input => flat(stateScan(utf16ByteOrEofToCodePointOp)(undefined)(flat([input, eofList])))
|
|
68
79
|
|
|
69
80
|
/** @type {(s: string) => list.List<u16>} */
|
|
70
81
|
const stringToList = s => {
|
|
@@ -76,7 +87,10 @@ const stringToList = s => {
|
|
|
76
87
|
return at(0)
|
|
77
88
|
}
|
|
78
89
|
|
|
79
|
-
|
|
90
|
+
/** @type {(input: list.List<u16>) => string} */
|
|
91
|
+
const listToString = fn(map(String.fromCharCode))
|
|
92
|
+
.then(reduce(operator.concat)(''))
|
|
93
|
+
.result
|
|
80
94
|
|
|
81
95
|
module.exports = {
|
|
82
96
|
/** @readonly */
|
package/text/utf8/module.f.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const list = require('../../types/list/module.f.cjs')
|
|
2
2
|
const operator = require('../../types/function/operator/module.f.cjs')
|
|
3
3
|
const array = require('../../types/array/module.f.cjs')
|
|
4
|
-
const { flatMap } = list
|
|
4
|
+
const { flatMap, flat, stateScan } = list
|
|
5
5
|
|
|
6
6
|
/** @typedef {u8|undefined} ByteOrEof */
|
|
7
7
|
|
|
@@ -16,8 +16,7 @@ const { flatMap } = list
|
|
|
16
16
|
const errorMask = 0b1000_0000_0000_0000_0000_0000_0000_0000
|
|
17
17
|
|
|
18
18
|
/** @type {(input:number) => list.List<u8>} */
|
|
19
|
-
const codePointToUtf8 = input =>
|
|
20
|
-
{
|
|
19
|
+
const codePointToUtf8 = input => {
|
|
21
20
|
if (input >= 0x0000 && input <= 0x007f) { return [input & 0b01111_1111] }
|
|
22
21
|
if (input >= 0x0080 && input <= 0x07ff) { return [input >> 6 | 0b1100_0000, input & 0b0011_1111 | 0b1000_0000] }
|
|
23
22
|
if (input >= 0x0800 && input <= 0xffff) { return [input >> 12 | 0b1110_0000, input >> 6 & 0b0011_1111 | 0b1000_0000, input & 0b0011_1111 | 0b1000_0000] }
|
|
@@ -35,9 +34,9 @@ const fromCodePointList = flatMap(codePointToUtf8)
|
|
|
35
34
|
|
|
36
35
|
/** @type {(state: Utf8NonEmptyState) => i32}*/
|
|
37
36
|
const utf8StateToError = state => {
|
|
38
|
-
switch(state.length) {
|
|
37
|
+
switch (state.length) {
|
|
39
38
|
case 1:
|
|
40
|
-
|
|
39
|
+
return state[0] | errorMask
|
|
41
40
|
case 2:
|
|
42
41
|
if (state[0] < 0b1111_0000) return (((state[0] & 0b0000_1111) << 6) + (state[1] & 0b0011_1111) + 0b0000_0100_0000_0000) | errorMask
|
|
43
42
|
return (((state[0] & 0b0000_0111) << 6) + (state[1] & 0b0011_1111) + 0b0000_0010_0000_0000) | errorMask
|
|
@@ -57,7 +56,7 @@ const utf8ByteToCodePointOp = state => byte => {
|
|
|
57
56
|
return [[byte | errorMask], undefined]
|
|
58
57
|
}
|
|
59
58
|
if (byte >= 0b1000_0000 && byte < 0b1100_0000) {
|
|
60
|
-
switch(state.length) {
|
|
59
|
+
switch (state.length) {
|
|
61
60
|
case 1:
|
|
62
61
|
if (state[0] < 0b1110_0000) { return [[((state[0] & 0b0001_1111) << 6) + (byte & 0b0011_1111)], undefined] }
|
|
63
62
|
if (state[0] < 0b1111_1000) { return [[], [state[0], byte]] }
|
|
@@ -85,8 +84,11 @@ const utf8EofToCodePointOp = state => {
|
|
|
85
84
|
/** @type {operator.StateScan<ByteOrEof, Utf8State, list.List<i32>>} */
|
|
86
85
|
const utf8ByteOrEofToCodePointOp = state => input => input === undefined ? utf8EofToCodePointOp(state) : utf8ByteToCodePointOp(state)(input)
|
|
87
86
|
|
|
87
|
+
/** @type {list.List<ByteOrEof>} */
|
|
88
|
+
const eofList = [undefined]
|
|
89
|
+
|
|
88
90
|
/** @type {(input: list.List<u8>) => list.List<i32>} */
|
|
89
|
-
const toCodePointList = input =>
|
|
91
|
+
const toCodePointList = input => flat(stateScan(utf8ByteOrEofToCodePointOp)(undefined)(flat([input, eofList])))
|
|
90
92
|
|
|
91
93
|
module.exports = {
|
|
92
94
|
/** @readonly */
|
package/tsconfig.json
CHANGED