functionalscript 0.0.371 → 0.0.374
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/.vscode/tasks.json +41 -0
- package/com/cpp/com.hpp +18 -12
- package/com/cpp/module.f.cjs +70 -2
- package/com/cpp/test/build.cjs +7 -3
- package/com/cpp/test/main.cpp +4 -0
- package/com/cpp/test.f.cjs +34 -1
- package/com/cs/module.f.cjs +10 -16
- package/com/cs/test.f.cjs +5 -22
- package/com/types/module.f.cjs +25 -2
- package/com/types/test.f.cjs +25 -0
- package/{io/commonjs → commonjs}/module.cjs +3 -3
- package/{io/commonjs → commonjs}/test.cjs +1 -1
- package/{io/nodejs → nodejs}/version/main.cjs +1 -1
- package/package.json +2 -2
- package/test.f.cjs +2 -1
- package/text/encoding/module.f.cjs +104 -6
- package/text/encoding/test.f.cjs +80 -0
- package/tsconfig.json +1 -1
- package/{io → types}/result/module.cjs +1 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"tasks": [
|
|
4
|
+
{
|
|
5
|
+
"label": "build",
|
|
6
|
+
"command": "dotnet",
|
|
7
|
+
"type": "process",
|
|
8
|
+
"args": [
|
|
9
|
+
"build",
|
|
10
|
+
"${workspaceFolder}/com/cs/test/test.csproj",
|
|
11
|
+
"/property:GenerateFullPaths=true",
|
|
12
|
+
"/consoleloggerparameters:NoSummary"
|
|
13
|
+
],
|
|
14
|
+
"problemMatcher": "$msCompile"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"label": "publish",
|
|
18
|
+
"command": "dotnet",
|
|
19
|
+
"type": "process",
|
|
20
|
+
"args": [
|
|
21
|
+
"publish",
|
|
22
|
+
"${workspaceFolder}/com/cs/test/test.csproj",
|
|
23
|
+
"/property:GenerateFullPaths=true",
|
|
24
|
+
"/consoleloggerparameters:NoSummary"
|
|
25
|
+
],
|
|
26
|
+
"problemMatcher": "$msCompile"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"label": "watch",
|
|
30
|
+
"command": "dotnet",
|
|
31
|
+
"type": "process",
|
|
32
|
+
"args": [
|
|
33
|
+
"watch",
|
|
34
|
+
"run",
|
|
35
|
+
"--project",
|
|
36
|
+
"${workspaceFolder}/com/cs/test/test.csproj"
|
|
37
|
+
],
|
|
38
|
+
"problemMatcher": "$msCompile"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
package/com/cpp/com.hpp
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
#
|
|
2
|
-
#define COM_HPP
|
|
1
|
+
#pragma once
|
|
3
2
|
|
|
4
3
|
#include <cstdint>
|
|
4
|
+
#include <cstddef>
|
|
5
|
+
|
|
6
|
+
#if defined(__aarch64__)
|
|
7
|
+
#define COM_STDCALL
|
|
8
|
+
#elif defined(__clang__)
|
|
9
|
+
#define COM_STDCALL __attribute__((stdcall))
|
|
10
|
+
#else
|
|
11
|
+
#define COM_STDCALL __stdcall
|
|
12
|
+
#endif
|
|
5
13
|
|
|
6
14
|
namespace com
|
|
7
15
|
{
|
|
@@ -14,34 +22,32 @@ namespace com
|
|
|
14
22
|
|
|
15
23
|
typedef uint32_t HRESULT;
|
|
16
24
|
typedef uint32_t ULONG;
|
|
25
|
+
typedef int32_t BOOL;
|
|
17
26
|
|
|
18
27
|
class IUnknown
|
|
19
28
|
{
|
|
20
29
|
public:
|
|
21
|
-
virtual HRESULT
|
|
22
|
-
virtual ULONG
|
|
23
|
-
virtual ULONG
|
|
30
|
+
virtual HRESULT COM_STDCALL QueryInterface(GUID const &riid, IUnknown **const ppvObject) noexcept = 0;
|
|
31
|
+
virtual ULONG COM_STDCALL AddRef() noexcept = 0;
|
|
32
|
+
virtual ULONG COM_STDCALL Release() noexcept = 0;
|
|
24
33
|
};
|
|
25
34
|
|
|
26
35
|
template <class I>
|
|
27
|
-
class
|
|
36
|
+
class ref
|
|
28
37
|
{
|
|
29
38
|
public:
|
|
30
|
-
explicit
|
|
39
|
+
explicit ref(I &other) noexcept : p(other.p)
|
|
31
40
|
{
|
|
32
41
|
p.AddRef();
|
|
33
42
|
}
|
|
34
|
-
|
|
43
|
+
ref(ref const &other) noexcept : ref(other.p)
|
|
35
44
|
{
|
|
36
45
|
}
|
|
37
|
-
~
|
|
46
|
+
~ref() noexcept
|
|
38
47
|
{
|
|
39
48
|
p.Release();
|
|
40
49
|
}
|
|
41
|
-
|
|
42
50
|
private:
|
|
43
51
|
I &p;
|
|
44
52
|
};
|
|
45
53
|
}
|
|
46
|
-
|
|
47
|
-
#endif
|
package/com/cpp/module.f.cjs
CHANGED
|
@@ -1,8 +1,76 @@
|
|
|
1
1
|
const types = require('../types/module.f.cjs')
|
|
2
2
|
const text = require('../../text/module.f.cjs')
|
|
3
|
+
const obj = require('../../types/object/module.f.cjs')
|
|
4
|
+
const { list } = require('../../types/module.f.cjs')
|
|
3
5
|
|
|
4
|
-
/** @type {(name: string) => (
|
|
5
|
-
const
|
|
6
|
+
/** @type {(name: string) => (body: text.Block) => text.Block} */
|
|
7
|
+
const struct = name => body => [`struct ${name}`, '{', body, '};']
|
|
8
|
+
|
|
9
|
+
/** @type {(t: types.BaseType) => string} */
|
|
10
|
+
const baseType = t => {
|
|
11
|
+
switch (t) {
|
|
12
|
+
case 'u8': return 'uint8_t'
|
|
13
|
+
case 'i8': return 'int8_t'
|
|
14
|
+
case 'u16': return 'uint16_t'
|
|
15
|
+
case 'i16': return 'int16_t'
|
|
16
|
+
case 'u32': return 'uint32_t'
|
|
17
|
+
case 'i32': return 'int32_t'
|
|
18
|
+
case 'u64': return 'uint64_t'
|
|
19
|
+
case 'i64': return 'int64_t'
|
|
20
|
+
case 'usize': return 'size_t'
|
|
21
|
+
case 'isize': return 'ptrdiff_t'
|
|
22
|
+
case 'f32': return 'float'
|
|
23
|
+
case 'f64': return 'double'
|
|
24
|
+
case 'bool': return '::com::BOOL'
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @type {(name: string) => (lib: types.Library) => text.Block} */
|
|
29
|
+
const cpp = name => lib => {
|
|
30
|
+
|
|
31
|
+
/** @type {(i: (t: string) => string) => (t: types.Type) => string} */
|
|
32
|
+
const objectType = i => t => {
|
|
33
|
+
if (typeof(t) === 'string') { return baseType(t) }
|
|
34
|
+
if (t.length === 2) { return `${type(t[1])}*` }
|
|
35
|
+
const [id] = t
|
|
36
|
+
if (lib[id].interface === undefined) { return id }
|
|
37
|
+
return i(id)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const type = objectType(id => `::com::ref<${id}>`)
|
|
41
|
+
|
|
42
|
+
/** @type {(s: types.Field) => text.Item} */
|
|
43
|
+
const field = ([name, t]) => `${type(t)} ${name};`
|
|
44
|
+
|
|
45
|
+
/** @type {(s: types.Struct) => text.Block} */
|
|
46
|
+
const defStruct = s => list.map(field)(Object.entries(s.struct))
|
|
47
|
+
|
|
48
|
+
/** @type {(fa: types.FieldArray) => string} */
|
|
49
|
+
const result = types.result('void')(type)
|
|
50
|
+
|
|
51
|
+
/** @type {(p: types.Field) => string} */
|
|
52
|
+
const param = ([name, t]) => `${objectType(id => `${id}&`)(t)} ${name}`
|
|
53
|
+
|
|
54
|
+
/** @type {(m: types.Method) => text.Item} */
|
|
55
|
+
const method = ([name, paramArray]) =>
|
|
56
|
+
`virtual ${result(paramArray)} COM_STDCALL ${name}(${list.join(', ')(list.map(param)(types.paramList(paramArray)))}) = 0;`
|
|
57
|
+
|
|
58
|
+
/** @type {(i: types.Interface) => text.Block} */
|
|
59
|
+
const defInterface = i => list.map(method)(Object.entries(i.interface))
|
|
60
|
+
|
|
61
|
+
/** @type {(kv: obj.Entry<types.Definition>) => text.Block} */
|
|
62
|
+
const def = ([name, d]) => d.interface === undefined
|
|
63
|
+
? struct(name)(defStruct(d))
|
|
64
|
+
: struct(`${name}: ::com::IUnknown`)(defInterface(d))
|
|
65
|
+
|
|
66
|
+
return list.flat([
|
|
67
|
+
['#pragma once', ''],
|
|
68
|
+
text.curly
|
|
69
|
+
('namespace')
|
|
70
|
+
(name)
|
|
71
|
+
(list.flatMap(def)(Object.entries(lib)))
|
|
72
|
+
])
|
|
73
|
+
}
|
|
6
74
|
|
|
7
75
|
module.exports = {
|
|
8
76
|
/** @readonly */
|
package/com/cpp/test/build.cjs
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
const fs = require('node:fs')
|
|
2
2
|
const cp = require('node:child_process')
|
|
3
|
-
|
|
3
|
+
const os = require('node:os');
|
|
4
|
+
const cpp = require('../test.f.cjs').result
|
|
5
|
+
const list = require('../../../types/list/module.f.cjs')
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
fs.writeFileSync('_result.hpp', cpp)
|
|
6
8
|
try {
|
|
7
|
-
|
|
9
|
+
const flags = os.platform() === 'win32' ? [] : ['-std=c++11', '-lc++']
|
|
10
|
+
const line = list.join(' ')(list.flat([['clang'], flags, ['main.cpp']]))
|
|
11
|
+
console.log(cp.execSync(line).toString())
|
|
8
12
|
} catch (e) {
|
|
9
13
|
// @ts-ignore
|
|
10
14
|
console.error(e.output.toString())
|
package/com/cpp/test/main.cpp
CHANGED
package/com/cpp/test.f.cjs
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
1
|
const _ = require('./module.f.cjs')
|
|
2
|
+
const library = require('../types/test.f.cjs')
|
|
3
|
+
const text = require('../../text/module.f.cjs')
|
|
4
|
+
const list = require('../../types/list/module.f.cjs')
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
const f = () =>
|
|
7
|
+
{
|
|
8
|
+
const r = list.join('\n')(text.flat(' ')(_.cpp('My')(library)))
|
|
9
|
+
const e =
|
|
10
|
+
'#pragma once\n' +
|
|
11
|
+
'\n' +
|
|
12
|
+
'namespace My\n' +
|
|
13
|
+
'{\n' +
|
|
14
|
+
' struct Slice\n' +
|
|
15
|
+
' {\n' +
|
|
16
|
+
' uint8_t* Start;\n' +
|
|
17
|
+
' size_t Size;\n' +
|
|
18
|
+
' };\n' +
|
|
19
|
+
' struct IMy: ::com::IUnknown\n' +
|
|
20
|
+
' {\n' +
|
|
21
|
+
' virtual Slice COM_STDCALL GetSlice() = 0;\n' +
|
|
22
|
+
' virtual void COM_STDCALL SetSlice(Slice slice) = 0;\n' +
|
|
23
|
+
' virtual ::com::BOOL* COM_STDCALL GetUnsafe() = 0;\n' +
|
|
24
|
+
' virtual void COM_STDCALL SetUnsafe(Slice* p, uint32_t size) = 0;\n' +
|
|
25
|
+
' virtual ::com::BOOL COM_STDCALL Some(IMy& p) = 0;\n' +
|
|
26
|
+
' virtual ::com::ref<IMy> COM_STDCALL GetIMy() = 0;\n' +
|
|
27
|
+
' };\n' +
|
|
28
|
+
'}'
|
|
29
|
+
if (r !== e) { throw r }
|
|
30
|
+
return r
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = {
|
|
34
|
+
/** @readonly */
|
|
35
|
+
result: f()
|
|
36
|
+
}
|
package/com/cs/module.f.cjs
CHANGED
|
@@ -42,40 +42,34 @@ const baseType = t => {
|
|
|
42
42
|
const unsafe = isUnsafe => isUnsafe ? 'unsafe ' : ''
|
|
43
43
|
|
|
44
44
|
/** @type {(t: types.Type) => readonly[boolean, string]} */
|
|
45
|
-
const
|
|
45
|
+
const fullType = t =>
|
|
46
46
|
typeof (t) === 'string' ? [false, baseType(t)] :
|
|
47
47
|
t.length === 1 ? [false, t[0]] :
|
|
48
|
-
[true, `${type(t[1])
|
|
48
|
+
[true, `${type(t[1])}*`]
|
|
49
|
+
|
|
50
|
+
/** @type {(m: types.Type) => string} */
|
|
51
|
+
const type = t => fullType(t)[1]
|
|
49
52
|
|
|
50
53
|
/** @type {(f: types.Field) => string} */
|
|
51
|
-
const param = ([name, t]) => `${type(t)
|
|
54
|
+
const param = ([name, t]) => `${type(t)} ${name}`
|
|
52
55
|
|
|
53
56
|
/** @type {(f: types.Field) => string} */
|
|
54
57
|
const field = ([name, comType]) => {
|
|
55
|
-
const [isUnsafe, t] =
|
|
58
|
+
const [isUnsafe, t] = fullType(comType)
|
|
56
59
|
return `public ${unsafe(isUnsafe)}${t} ${name};`
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
/** @type {(m: types.FieldArray) => string} */
|
|
60
|
-
const result = m => {
|
|
61
|
-
const result = m._
|
|
62
|
-
return result === undefined ? 'void' : type(result)[1]
|
|
63
|
-
}
|
|
64
|
-
|
|
65
62
|
/** @type {(field: types.Field) => boolean} */
|
|
66
|
-
const isUnsafeField = field =>
|
|
67
|
-
|
|
68
|
-
/** @type {(kv: obj.Entry<types.Type>) => boolean} */
|
|
69
|
-
const isParam = kv => kv[0] !== '_'
|
|
63
|
+
const isUnsafeField = field => fullType(field[1])[0]
|
|
70
64
|
|
|
71
65
|
/** @type {(e: obj.Entry<types.FieldArray>) => readonly string[]} */
|
|
72
66
|
const method = ([name, m]) => {
|
|
73
67
|
const paramAndResultList = Object.entries(m)
|
|
74
|
-
const
|
|
68
|
+
const pl = types.paramList(m)
|
|
75
69
|
const isUnsafe = list.some(list.map(isUnsafeField)(paramAndResultList))
|
|
76
70
|
return [
|
|
77
71
|
'[PreserveSig]',
|
|
78
|
-
`${unsafe(isUnsafe)}${result(m)} ${name}(${list.join(', ')(list.map(param)(
|
|
72
|
+
`${unsafe(isUnsafe)}${types.result('void')(type)(m)} ${name}(${list.join(', ')(list.map(param)(pl))});`
|
|
79
73
|
]
|
|
80
74
|
}
|
|
81
75
|
|
package/com/cs/test.f.cjs
CHANGED
|
@@ -2,28 +2,7 @@ const types = require('../types/module.f.cjs')
|
|
|
2
2
|
const _ = require('./module.f.cjs')
|
|
3
3
|
const list = require('../../types/list/module.f.cjs')
|
|
4
4
|
const text = require('../../text/module.f.cjs')
|
|
5
|
-
|
|
6
|
-
/** @type {types.Library} */
|
|
7
|
-
const library = {
|
|
8
|
-
Slice: {
|
|
9
|
-
struct: {
|
|
10
|
-
Start: ['*', 'u8'],
|
|
11
|
-
Size: 'usize',
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
IMy: {
|
|
15
|
-
guid: 'C66FB270-2D80-49AD-BB6E-88C1F90B805D',
|
|
16
|
-
interface: {
|
|
17
|
-
GetSlice: { _: ['Slice'] },
|
|
18
|
-
SetSlice: { slice: ['Slice'] },
|
|
19
|
-
GetUnsafe: { _: ['*', 'bool'] },
|
|
20
|
-
SetUnsafe: {
|
|
21
|
-
p: ['*', ['Slice']],
|
|
22
|
-
size: 'u32'
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
}
|
|
26
|
-
}
|
|
5
|
+
const library = require('../types/test.f.cjs')
|
|
27
6
|
|
|
28
7
|
const f = () =>
|
|
29
8
|
{
|
|
@@ -52,6 +31,10 @@ const f = () =>
|
|
|
52
31
|
' unsafe bool* GetUnsafe();\n' +
|
|
53
32
|
' [PreserveSig]\n' +
|
|
54
33
|
' unsafe void SetUnsafe(Slice* p, uint size);\n' +
|
|
34
|
+
' [PreserveSig]\n' +
|
|
35
|
+
' bool Some(IMy p);\n' +
|
|
36
|
+
' [PreserveSig]\n' +
|
|
37
|
+
' IMy GetIMy();\n' +
|
|
55
38
|
' }\n' +
|
|
56
39
|
'}'
|
|
57
40
|
if (cs !== e) { throw [cs,e] }
|
package/com/types/module.f.cjs
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
const obj = require('../../types/object/module.f.cjs')
|
|
2
|
+
const list = require('../../types/list/module.f.cjs')
|
|
3
|
+
const { types } = require('../module.f.cjs')
|
|
4
|
+
|
|
1
5
|
/** @typedef {{readonly[k in string]: Definition}} Library */
|
|
2
6
|
|
|
3
7
|
/** @typedef {Struct|Interface} Definition */
|
|
@@ -11,7 +15,7 @@
|
|
|
11
15
|
|
|
12
16
|
/** @typedef {{readonly[k in string]: Type}} FieldArray */
|
|
13
17
|
|
|
14
|
-
/** @typedef {
|
|
18
|
+
/** @typedef {obj.Entry<Type>} Field */
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* @typedef {{
|
|
@@ -22,6 +26,8 @@
|
|
|
22
26
|
|
|
23
27
|
/** @typedef {{readonly[k in string]: FieldArray}} MethodArray */
|
|
24
28
|
|
|
29
|
+
/** @typedef {obj.Entry<FieldArray>} Method */
|
|
30
|
+
|
|
25
31
|
/** @typedef {BaseType|Id|Pointer} Type */
|
|
26
32
|
|
|
27
33
|
/** @typedef {readonly[string]} Id */
|
|
@@ -46,4 +52,21 @@
|
|
|
46
52
|
|
|
47
53
|
/** @typedef {readonly['*', Type]} Pointer */
|
|
48
54
|
|
|
49
|
-
|
|
55
|
+
/** @type {(kv: obj.Entry<Type>) => boolean} */
|
|
56
|
+
const isParam = ([name]) => name !== '_'
|
|
57
|
+
|
|
58
|
+
/** @type {(fa: FieldArray) => list.List<Field> } */
|
|
59
|
+
const paramList = fa => list.filter(isParam)(Object.entries(fa))
|
|
60
|
+
|
|
61
|
+
/** @type {<T>(v: T) => (f: (type: Type) => T) => (fa: FieldArray) => T} */
|
|
62
|
+
const result = v => f => fa => {
|
|
63
|
+
const type = fa._
|
|
64
|
+
return type === undefined ? v : f(type)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = {
|
|
68
|
+
/** @readonly */
|
|
69
|
+
paramList,
|
|
70
|
+
/** @readonly */
|
|
71
|
+
result,
|
|
72
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const _ = require('./module.f.cjs')
|
|
2
|
+
|
|
3
|
+
/** @type {_.Library} */
|
|
4
|
+
module.exports = {
|
|
5
|
+
Slice: {
|
|
6
|
+
struct: {
|
|
7
|
+
Start: ['*', 'u8'],
|
|
8
|
+
Size: 'usize',
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
IMy: {
|
|
12
|
+
guid: 'C66FB270-2D80-49AD-BB6E-88C1F90B805D',
|
|
13
|
+
interface: {
|
|
14
|
+
GetSlice: { _: ['Slice'] },
|
|
15
|
+
SetSlice: { slice: ['Slice'] },
|
|
16
|
+
GetUnsafe: { _: ['*', 'bool'] },
|
|
17
|
+
SetUnsafe: {
|
|
18
|
+
p: ['*', ['Slice']],
|
|
19
|
+
size: 'u32'
|
|
20
|
+
},
|
|
21
|
+
Some: { p: ['IMy'], _: 'bool' },
|
|
22
|
+
GetIMy: { _: ['IMy'] }
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const { tryCatch } = require('../result/module.cjs')
|
|
2
|
-
const { unwrap } = require('
|
|
3
|
-
const moduleFunction = require('
|
|
1
|
+
const { tryCatch } = require('../types/result/module.cjs')
|
|
2
|
+
const { unwrap } = require('../types/result/module.f.cjs')
|
|
3
|
+
const moduleFunction = require('./module/function/module.f.cjs')
|
|
4
4
|
|
|
5
5
|
/** @type {(f: Function) => moduleFunction.Function_} */
|
|
6
6
|
const build = f => immutableRequire => mutableData => {
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.374",
|
|
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
|
-
"version": "node ./
|
|
9
|
+
"version": "node ./nodejs/version/main.cjs",
|
|
10
10
|
"test-only": "node --trace-uncaught ./test.f.cjs"
|
|
11
11
|
},
|
|
12
12
|
"repository": {
|
package/test.f.cjs
CHANGED
|
@@ -7,7 +7,7 @@ require('./sha2/test.f.cjs')
|
|
|
7
7
|
require('./json/test.f.cjs')
|
|
8
8
|
require('./json/tokenizer/test.f.cjs')
|
|
9
9
|
require('./types/object/test.f.cjs')
|
|
10
|
-
require('./
|
|
10
|
+
require('./commonjs/test.cjs')
|
|
11
11
|
require('./commonjs/package/dependencies/test.f.cjs')
|
|
12
12
|
require('./commonjs/package/test.f.cjs')
|
|
13
13
|
require('./commonjs/path/test.f.cjs')
|
|
@@ -20,6 +20,7 @@ require('./html/test.f.cjs')
|
|
|
20
20
|
require('./text/test.f.cjs')
|
|
21
21
|
require('./text/encoding/test.f.cjs')
|
|
22
22
|
require('./com/cs/test.f.cjs')
|
|
23
|
+
require('./com/cpp/test.f.cjs')
|
|
23
24
|
|
|
24
25
|
/** @type {() => never} */
|
|
25
26
|
const assert = () => { throw 'assert' }
|
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
const result = require('../../types/result/module.f.cjs')
|
|
2
2
|
const list = require('../../types/list/module.f.cjs')
|
|
3
|
+
const operator = require('../../types/function/operator/module.f.cjs')
|
|
4
|
+
const array = require('../../types/array/module.f.cjs')
|
|
5
|
+
const { contains } = require('../../types/range/module.f.cjs')
|
|
3
6
|
const { ok, error } = result
|
|
4
7
|
|
|
5
|
-
/** @typedef {result.Result<number,number>}
|
|
8
|
+
/** @typedef {result.Result<number,number>} ByteResult */
|
|
6
9
|
|
|
7
|
-
/** @
|
|
10
|
+
/** @typedef {result.Result<number,readonly number[]>} CodePointResult */
|
|
11
|
+
|
|
12
|
+
/** @typedef {number|undefined} ByteOrEof */
|
|
13
|
+
|
|
14
|
+
/** @typedef {undefined|array.Array1<number>|array.Array2<number>|array.Array3<number>} Utf8State */
|
|
15
|
+
|
|
16
|
+
/** @typedef {undefined|array.Array1<number>|array.Array2<number>|array.Array3<number>} Utf16State */
|
|
17
|
+
|
|
18
|
+
/** @type {(a:number) => boolean} */
|
|
19
|
+
const isBmpCodePoint = a => a >= 0x0000 && a <= 0xd7ff || a >= 0xe000 && a <= 0xffff
|
|
20
|
+
|
|
21
|
+
const isHighSurrogate = contains([0xd800, 0xdbff])
|
|
22
|
+
|
|
23
|
+
/** @type {(a:number) => boolean} */
|
|
24
|
+
const isLowSurrogate = contains([0xdc00, 0xdfff])
|
|
25
|
+
|
|
26
|
+
/** @type {(input:number) => list.List<ByteResult>} */
|
|
8
27
|
const codePointToUtf8 = input =>
|
|
9
28
|
{
|
|
10
29
|
if (input >= 0x0000 && input <= 0x007f) { return [ok(input & 0x7f)] }
|
|
@@ -14,10 +33,10 @@ const codePointToUtf8 = input =>
|
|
|
14
33
|
return [error(input)]
|
|
15
34
|
}
|
|
16
35
|
|
|
17
|
-
/** @type {(input:number) => list.List<
|
|
36
|
+
/** @type {(input:number) => list.List<ByteResult>} */
|
|
18
37
|
const codePointToUtf16 = input =>
|
|
19
38
|
{
|
|
20
|
-
if (input
|
|
39
|
+
if (isBmpCodePoint(input)) { return [ok(input >> 8), ok(input & 0xff)] }
|
|
21
40
|
if (input >= 0x010000 && input <= 0x10ffff) {
|
|
22
41
|
const high = ((input - 0x10000) >> 10) + 0xd800
|
|
23
42
|
const low = ((input - 0x10000) & 0x3ff) + 0xdc00
|
|
@@ -26,15 +45,94 @@ const codePointToUtf16 = input =>
|
|
|
26
45
|
return [error(input)]
|
|
27
46
|
}
|
|
28
47
|
|
|
29
|
-
/** @type {(input: list.List<number>) => list.List<
|
|
48
|
+
/** @type {(input: list.List<number>) => list.List<ByteResult>} */
|
|
30
49
|
const codePointListToUtf8 = list.flatMap(codePointToUtf8)
|
|
31
50
|
|
|
32
|
-
/** @type {(input: list.List<number>) => list.List<
|
|
51
|
+
/** @type {(input: list.List<number>) => list.List<ByteResult>} */
|
|
33
52
|
const codePointListToUtf16 = list.flatMap(codePointToUtf16)
|
|
34
53
|
|
|
54
|
+
/** @type {operator.StateScan<number, Utf8State, list.List<CodePointResult>>} */
|
|
55
|
+
const utf8ByteToCodePointOp = state => byte => {
|
|
56
|
+
if (byte < 0x00 || byte > 0xff) {
|
|
57
|
+
return [[error([byte])], state]
|
|
58
|
+
}
|
|
59
|
+
if (state == undefined) {
|
|
60
|
+
if (byte < 0x80) { return [[ok(byte)], undefined] }
|
|
61
|
+
if (byte >= 0xc2 && byte <= 0xf4) { return [[], [byte]] }
|
|
62
|
+
return [[error([byte])], undefined]
|
|
63
|
+
}
|
|
64
|
+
if (byte >= 0x80 && byte < 0xc0)
|
|
65
|
+
{
|
|
66
|
+
switch(state.length)
|
|
67
|
+
{
|
|
68
|
+
case 1:
|
|
69
|
+
if (state[0] < 0xe0) { return [[ok(((state[0] & 0x1f) << 6) + (byte & 0x3f))], undefined] }
|
|
70
|
+
if (state[0] < 0xf8) { return [[], [state[0], byte]] }
|
|
71
|
+
break
|
|
72
|
+
case 2:
|
|
73
|
+
if (state[0] < 0xf0) { return [[ok(((state[0] & 0x0f) << 12) + ((state[1] & 0x3f) << 6) + (byte & 0x3f))], undefined] }
|
|
74
|
+
if (state[0] < 0xf8) { return [[], [state[0], state[1], byte]] }
|
|
75
|
+
break
|
|
76
|
+
case 3:
|
|
77
|
+
return [[ok(((state[0] & 0x07) << 18) + ((state[1] & 0x3f) << 12) + ((state[2] & 0x3f) << 6) + (byte & 0x3f))], undefined]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return [[error(list.toArray(list.concat(state)([byte])))], undefined]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** @type {(state: Utf8State) => readonly[list.List<CodePointResult>, Utf8State]} */
|
|
84
|
+
const utf8EofToCodePointOp = state => [state == undefined ? undefined : [error(state)], undefined]
|
|
85
|
+
|
|
86
|
+
/** @type {operator.StateScan<ByteOrEof, Utf8State, list.List<CodePointResult>>} */
|
|
87
|
+
const utf8ByteOrEofToCodePointOp = state => input => input === undefined ? utf8EofToCodePointOp(state) : utf8ByteToCodePointOp(state)(input)
|
|
88
|
+
|
|
89
|
+
/** @type {(input: list.List<number>) => list.List<CodePointResult>} */
|
|
90
|
+
const utf8ListToCodePoint = input => list.flat(list.stateScan(utf8ByteOrEofToCodePointOp)(undefined)(list.concat(/** @type {list.List<ByteOrEof>} */(input))([undefined])))
|
|
91
|
+
|
|
92
|
+
/** @type {operator.StateScan<number, Utf16State, list.List<CodePointResult>>} */
|
|
93
|
+
const utf16ByteToCodePointOp = state => byte => {
|
|
94
|
+
if (byte < 0x00 || byte > 0xff) {
|
|
95
|
+
return [[error([byte])], state]
|
|
96
|
+
}
|
|
97
|
+
if (state == undefined) {
|
|
98
|
+
return [[], [byte]]
|
|
99
|
+
}
|
|
100
|
+
switch(state.length)
|
|
101
|
+
{
|
|
102
|
+
case 1:
|
|
103
|
+
const codeUnit = (state[0] << 8) + byte
|
|
104
|
+
if (isBmpCodePoint(codeUnit)) { return [[ok(codeUnit)], undefined] }
|
|
105
|
+
if (isHighSurrogate(codeUnit)) { return [[], [state[0], byte]] }
|
|
106
|
+
break
|
|
107
|
+
case 2:
|
|
108
|
+
return [[], [state[0], state[1], byte]]
|
|
109
|
+
case 3:
|
|
110
|
+
if (isLowSurrogate((state[2] << 8) + byte)) {
|
|
111
|
+
const high = (state[0] << 8) + state[1] - 0xd800
|
|
112
|
+
const low = (state[2] << 8) + byte - 0xdc00
|
|
113
|
+
return [[ok((high << 10) + low + 0x10000)], undefined]
|
|
114
|
+
}
|
|
115
|
+
break
|
|
116
|
+
}
|
|
117
|
+
return [[error(list.toArray(list.concat(state)([byte])))], undefined]
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** @type {(state: Utf8State) => readonly[list.List<CodePointResult>, Utf16State]} */
|
|
121
|
+
const utf16EofToCodePointOp = state => [state == undefined ? undefined : [error(state)], undefined]
|
|
122
|
+
|
|
123
|
+
/** @type {operator.StateScan<ByteOrEof, Utf8State, list.List<CodePointResult>>} */
|
|
124
|
+
const utf16ByteOrEofToCodePointOp = state => input => input === undefined ? utf16EofToCodePointOp(state) : utf16ByteToCodePointOp(state)(input)
|
|
125
|
+
|
|
126
|
+
/** @type {(input: list.List<number>) => list.List<CodePointResult>} */
|
|
127
|
+
const utf16ListToCodePoint = input => list.flat(list.stateScan(utf16ByteOrEofToCodePointOp)(undefined)(list.concat(/** @type {list.List<ByteOrEof>} */(input))([undefined])))
|
|
128
|
+
|
|
35
129
|
module.exports = {
|
|
36
130
|
/** @readonly */
|
|
37
131
|
codePointListToUtf8,
|
|
38
132
|
/** @readonly */
|
|
39
133
|
codePointListToUtf16,
|
|
134
|
+
/** @readonly */
|
|
135
|
+
utf8ListToCodePoint,
|
|
136
|
+
/** @readonly */
|
|
137
|
+
utf16ListToCodePoint
|
|
40
138
|
}
|
package/text/encoding/test.f.cjs
CHANGED
|
@@ -116,4 +116,84 @@ const stringify = a => json.stringify(sort)(a)
|
|
|
116
116
|
if (result !== '[["error",-1],["error",55296],["error",57343],["error",1114112]]') { throw result }
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
{
|
|
120
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([-1, 256])))
|
|
121
|
+
if (result !== '[["error",[-1]],["error",[256]]]') { throw result }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
{
|
|
125
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([128, 193, 245, 255])))
|
|
126
|
+
if (result !== '[["error",[128]],["error",[193]],["error",[245]],["error",[255]]]') { throw result }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
{
|
|
130
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([0, 1, 127])))
|
|
131
|
+
if (result !== '[["ok",0],["ok",1],["ok",127]]') { throw result }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
{
|
|
135
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([194, 128, 194, 169, 223, 191])))
|
|
136
|
+
if (result !== '[["ok",128],["ok",169],["ok",2047]]') { throw result }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
{
|
|
140
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([194, 127, 194, 192, 194])))
|
|
141
|
+
if (result !== '[["error",[194,127]],["error",[194,192]],["error",[194]]]') { throw result }
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
{
|
|
145
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([224, 160, 128, 224, 160, 129, 239, 191, 191])))
|
|
146
|
+
if (result !== '[["ok",2048],["ok",2049],["ok",65535]]') { throw result }
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
{
|
|
150
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([224, 160, 127, 224, 160, 192, 224, 160])))
|
|
151
|
+
if (result !== '[["error",[224,160,127]],["error",[224,160,192]],["error",[224,160]]]') { throw result }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
{
|
|
155
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([240, 144, 128, 128, 240, 144, 128, 129, 244, 143, 191, 191])))
|
|
156
|
+
if (result !== '[["ok",65536],["ok",65537],["ok",1114111]]') { throw result }
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
{
|
|
160
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([240, 144, 128, 127, 240, 144, 128, 192, 240, 144, 128])))
|
|
161
|
+
if (result !== '[["error",[240,144,128,127]],["error",[240,144,128,192]],["error",[240,144,128]]]') { throw result }
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
{
|
|
165
|
+
const result = stringify(list.toArray(encoding.utf8ListToCodePoint([194, -1, 128])))
|
|
166
|
+
if (result !== '[["error",[-1]],["ok",128]]') { throw result }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
{
|
|
170
|
+
const result = stringify(list.toArray(encoding.utf16ListToCodePoint([-1, 256,])))
|
|
171
|
+
if (result !== '[["error",[-1]],["error",[256]]]') { throw result }
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
const result = stringify(list.toArray(encoding.utf16ListToCodePoint([0, 0, 0, 36, 32, 172, 215, 255, 224, 0, 255, 255])))
|
|
176
|
+
if (result !== '[["ok",0],["ok",36],["ok",8364],["ok",55295],["ok",57344],["ok",65535]]') { throw result }
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
{
|
|
180
|
+
const result = stringify(list.toArray(encoding.utf16ListToCodePoint([220, 0, 223, 255])))
|
|
181
|
+
if (result !== '[["error",[220,0]],["error",[223,255]]]') { throw result }
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
{
|
|
185
|
+
const result = stringify(list.toArray(encoding.utf16ListToCodePoint([216, 0, 220, 0, 216, 1, 220, 55, 216, 82, 223, 98, 219, 255, 223, 255])))
|
|
186
|
+
if (result !== '[["ok",65536],["ok",66615],["ok",150370],["ok",1114111]]') { throw result }
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
{
|
|
190
|
+
const result = stringify(list.toArray(encoding.utf16ListToCodePoint([216, 0, 216, 0])))
|
|
191
|
+
if (result !== '[["error",[216,0,216,0]]]') { throw result }
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
{
|
|
195
|
+
const result = stringify(list.toArray(encoding.utf16ListToCodePoint([216, 0, 0, 0])))
|
|
196
|
+
if (result !== '[["error",[216,0,0,0]]]') { throw result }
|
|
197
|
+
}
|
|
198
|
+
|
|
119
199
|
module.exports = {}
|
package/tsconfig.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
12
12
|
|
|
13
13
|
/* Language and Environment */
|
|
14
|
-
"target": "
|
|
14
|
+
"target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
|
15
15
|
// "lib": ["ES2021"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
16
16
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
|
17
17
|
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|