functionalscript 0.3.15 → 0.4.1
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/bnf/djs/test.f.js +36 -41
- package/bnf/func/module.f.d.ts +12 -5
- package/bnf/func/module.f.js +27 -6
- package/bnf/func/test.f.js +25 -84
- package/bnf/tag/module.f.d.ts +30 -0
- package/bnf/tag/module.f.js +37 -0
- package/bnf/tag/test.f.d.ts +1 -0
- package/bnf/tag/test.f.js +138 -0
- package/fsc/bnf.f.d.ts +2 -0
- package/fsc/bnf.f.js +54 -0
- package/fsc/json.f.d.ts +7 -0
- package/fsc/json.f.js +89 -0
- package/package.json +2 -3
- package/types/array/module.f.d.ts +1 -0
- package/types/array/module.f.js +1 -0
- package/types/bigint/module.f.d.ts +6 -0
- package/types/bigint/module.f.js +27 -5
- package/types/bigint/test.f.d.ts +8 -5
- package/types/bigint/test.f.js +91 -19
- package/com/cpp/module.f.d.ts +0 -10
- package/com/cpp/module.f.js +0 -106
- package/com/cpp/test.f.d.ts +0 -2
- package/com/cpp/test.f.js +0 -40
- package/com/cpp/testlib.f.d.ts +0 -2
- package/com/cpp/testlib.f.js +0 -5
- package/com/cs/module.f.d.ts +0 -12
- package/com/cs/module.f.js +0 -79
- package/com/cs/test.f.d.ts +0 -2
- package/com/cs/test.f.js +0 -43
- package/com/cs/testlib.f.d.ts +0 -2
- package/com/cs/testlib.f.js +0 -5
- package/com/rust/module.f.d.ts +0 -15
- package/com/rust/module.f.js +0 -164
- package/com/rust/test.f.d.ts +0 -2
- package/com/rust/test.f.js +0 -123
- package/com/rust/testlib.f.d.ts +0 -2
- package/com/rust/testlib.f.js +0 -5
- package/com/test/build.f.d.ts +0 -20
- package/com/test/build.f.js +0 -58
- package/com/types/module.f.d.ts +0 -28
- package/com/types/module.f.js +0 -7
- package/com/types/testlib.f.d.ts +0 -44
- package/com/types/testlib.f.js +0 -28
- package/commonjs/build/module.f.d.ts +0 -6
- package/commonjs/build/module.f.js +0 -66
- package/commonjs/build/test.f.d.ts +0 -2
- package/commonjs/build/test.f.js +0 -92
- package/commonjs/module/function/module.f.d.ts +0 -8
- package/commonjs/module/function/module.f.js +0 -4
- package/commonjs/module/module.f.d.ts +0 -18
- package/commonjs/module/module.f.js +0 -11
- package/commonjs/module.f.d.ts +0 -6
- package/commonjs/module.f.js +0 -1
- package/commonjs/package/dependencies/module.f.d.ts +0 -7
- package/commonjs/package/dependencies/module.f.js +0 -13
- package/commonjs/package/dependencies/test.f.d.ts +0 -2
- package/commonjs/package/dependencies/test.f.js +0 -15
- package/commonjs/package/module.f.d.ts +0 -17
- package/commonjs/package/module.f.js +0 -18
- package/commonjs/package/test.f.d.ts +0 -2
- package/commonjs/package/test.f.js +0 -27
- package/commonjs/path/module.f.d.ts +0 -24
- package/commonjs/path/module.f.js +0 -112
- package/commonjs/path/test.f.d.ts +0 -25
- package/commonjs/path/test.f.js +0 -221
package/fsc/json.f.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Rule, type TerminalRange } from '../bnf/func/module.f.ts';
|
|
2
|
+
export declare const wsNoNewLine0: Rule;
|
|
3
|
+
export declare const ws0: Rule;
|
|
4
|
+
export declare const ws1: Rule;
|
|
5
|
+
export declare const json: Rule;
|
|
6
|
+
export declare const unicode: TerminalRange;
|
|
7
|
+
export declare const digit: Rule;
|
package/fsc/json.f.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { cp, join0, range, remove, repeat0, set, str } from "../bnf/func/module.f.js";
|
|
2
|
+
// space
|
|
3
|
+
const wsNoNewLineItem = () => set(' \t\r');
|
|
4
|
+
export const wsNoNewLine0 = () => [
|
|
5
|
+
[],
|
|
6
|
+
[wsNoNewLineItem, wsNoNewLine0],
|
|
7
|
+
];
|
|
8
|
+
const wsItem = () => [
|
|
9
|
+
[wsNoNewLineItem],
|
|
10
|
+
str('\n'),
|
|
11
|
+
];
|
|
12
|
+
export const ws0 = () => [
|
|
13
|
+
[],
|
|
14
|
+
[ws1],
|
|
15
|
+
];
|
|
16
|
+
export const ws1 = () => [
|
|
17
|
+
[wsItem, ws0]
|
|
18
|
+
];
|
|
19
|
+
//
|
|
20
|
+
export const json = () => [
|
|
21
|
+
[object],
|
|
22
|
+
[array],
|
|
23
|
+
[number],
|
|
24
|
+
[string],
|
|
25
|
+
str('true'),
|
|
26
|
+
str('false'),
|
|
27
|
+
str('null'),
|
|
28
|
+
];
|
|
29
|
+
//
|
|
30
|
+
const separator = () => [[cp(','), ws0]];
|
|
31
|
+
// object
|
|
32
|
+
const member = () => [[string, ws0, cp(':'), ws0, json, ws0]];
|
|
33
|
+
const object = () => [
|
|
34
|
+
[cp('{'), ws0, join0(member, separator), cp('}')]
|
|
35
|
+
];
|
|
36
|
+
// array
|
|
37
|
+
const element = () => [
|
|
38
|
+
[json, ws0]
|
|
39
|
+
];
|
|
40
|
+
const array = () => [
|
|
41
|
+
[cp('['), ws0, join0(element, separator), cp(']')]
|
|
42
|
+
];
|
|
43
|
+
// string
|
|
44
|
+
const character = () => [
|
|
45
|
+
...remove(unicode, [cp('"'), cp('\\')]),
|
|
46
|
+
[cp('\\'), escape],
|
|
47
|
+
];
|
|
48
|
+
const string = () => [[cp('"'), repeat0(character), cp('"')]];
|
|
49
|
+
export const unicode = [0x20, 0x10FFFF];
|
|
50
|
+
const escape = () => [
|
|
51
|
+
...set('"\\/bfnrt'),
|
|
52
|
+
[cp('u'), hex, hex, hex, hex] // 117
|
|
53
|
+
];
|
|
54
|
+
const hex = () => [
|
|
55
|
+
[digit],
|
|
56
|
+
[range('AF')],
|
|
57
|
+
[range('af')],
|
|
58
|
+
];
|
|
59
|
+
// number
|
|
60
|
+
const number = () => [
|
|
61
|
+
[uNumber],
|
|
62
|
+
[cp('-'), uNumber],
|
|
63
|
+
];
|
|
64
|
+
const uNumber = () => [
|
|
65
|
+
[uint, fraction0, exponent0],
|
|
66
|
+
];
|
|
67
|
+
const uint = () => [
|
|
68
|
+
str('0'),
|
|
69
|
+
[range('19'), digits0]
|
|
70
|
+
];
|
|
71
|
+
export const digit = () => [[range('09')]];
|
|
72
|
+
const digits0 = repeat0(digit);
|
|
73
|
+
const digits1 = () => [
|
|
74
|
+
[digit, digits0]
|
|
75
|
+
];
|
|
76
|
+
const fraction0 = () => [
|
|
77
|
+
[],
|
|
78
|
+
[cp('.'), digits1]
|
|
79
|
+
];
|
|
80
|
+
const exponent0 = () => [
|
|
81
|
+
[],
|
|
82
|
+
[e, sign, digits1],
|
|
83
|
+
];
|
|
84
|
+
const e = () => set('eE');
|
|
85
|
+
const sign = () => [
|
|
86
|
+
[],
|
|
87
|
+
[cp('+')],
|
|
88
|
+
[cp('-')],
|
|
89
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.f.d.ts",
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
"test20": "npm run prepack && node --trace-uncaught ./dev/test.js",
|
|
14
14
|
"test22": "tsc && node --experimental-strip-types --trace-uncaught ./dev/test.ts",
|
|
15
15
|
"test": "tsc && node --trace-uncaught ./dev/test.ts",
|
|
16
|
-
"comtest": "node ./com/test/build.ts",
|
|
17
16
|
"index": "node ./dev/index.ts",
|
|
18
17
|
"version": "node ./nodejs/version/main.ts",
|
|
19
18
|
"fsc": "node ./main.ts",
|
|
@@ -40,6 +39,6 @@
|
|
|
40
39
|
"homepage": "https://github.com/functionalscript/functionalscript#readme",
|
|
41
40
|
"devDependencies": {
|
|
42
41
|
"@types/node": "^22.10.5",
|
|
43
|
-
"typescript": "^5.7.
|
|
42
|
+
"typescript": "^5.7.3"
|
|
44
43
|
}
|
|
45
44
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
export type Array1<T> = readonly [T];
|
|
7
7
|
export type Index1 = 0;
|
|
8
8
|
export type Array2<T> = readonly [T, T];
|
|
9
|
+
export declare const isArray2: <T>(a: readonly T[]) => a is Array2<T>;
|
|
9
10
|
export type Tuple2<T0, T1> = readonly [T0, T1];
|
|
10
11
|
export type Index2 = 0 | 1;
|
|
11
12
|
export type Array3<T> = readonly [T, T, T];
|
package/types/array/module.f.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* const logValue = log2(8n) // 3n
|
|
14
14
|
* const bitCount = bitLength(255n) // 8n
|
|
15
15
|
* const bitmask = mask(5n) // 31n
|
|
16
|
+
* const m = min(3n)(13n) // 3n
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
19
|
import { type Sign } from '../function/compare/module.f.ts';
|
|
@@ -42,6 +43,7 @@ export declare const serialize: (a: bigint) => string;
|
|
|
42
43
|
* of the most significant bit.
|
|
43
44
|
* 2. **Binary Search Phase:** Refines the result by halving the step size and incrementally
|
|
44
45
|
* determining the exact value of the logarithm.
|
|
46
|
+
* 3. **Remainder Phase:** Using `Math.log2`.
|
|
45
47
|
*/
|
|
46
48
|
export declare const log2: (v: bigint) => bigint;
|
|
47
49
|
/**
|
|
@@ -78,3 +80,7 @@ export declare const bitLength: (v: bigint) => bigint;
|
|
|
78
80
|
* ```
|
|
79
81
|
*/
|
|
80
82
|
export declare const mask: (len: bigint) => bigint;
|
|
83
|
+
/**
|
|
84
|
+
* A minimal value.
|
|
85
|
+
*/
|
|
86
|
+
export declare const min: (a: bigint) => (b: bigint) => bigint;
|
package/types/bigint/module.f.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* const logValue = log2(8n) // 3n
|
|
14
14
|
* const bitCount = bitLength(255n) // 8n
|
|
15
15
|
* const bitmask = mask(5n) // 31n
|
|
16
|
+
* const m = min(3n)(13n) // 3n
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
19
|
import { unsafeCmp } from "../function/compare/module.f.js";
|
|
@@ -39,13 +40,19 @@ export const serialize = (a) => `${a}n`;
|
|
|
39
40
|
* of the most significant bit.
|
|
40
41
|
* 2. **Binary Search Phase:** Refines the result by halving the step size and incrementally
|
|
41
42
|
* determining the exact value of the logarithm.
|
|
43
|
+
* 3. **Remainder Phase:** Using `Math.log2`.
|
|
42
44
|
*/
|
|
43
45
|
export const log2 = (v) => {
|
|
44
46
|
if (v <= 0n) {
|
|
45
47
|
return -1n;
|
|
46
48
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
//
|
|
50
|
+
// 1. Fast Doubling.
|
|
51
|
+
//
|
|
52
|
+
let result = -1n;
|
|
53
|
+
// `bigints` higher than 2**1023 may lead to `Inf` during conversion to `number`.
|
|
54
|
+
// For example: `Number((1n << 1024n) - (1n << 970n)) === Inf`.
|
|
55
|
+
let i = 1023n;
|
|
49
56
|
while (true) {
|
|
50
57
|
const n = v >> i;
|
|
51
58
|
if (n === 0n) {
|
|
@@ -56,9 +63,12 @@ export const log2 = (v) => {
|
|
|
56
63
|
result += i;
|
|
57
64
|
i <<= 1n;
|
|
58
65
|
}
|
|
66
|
+
//
|
|
67
|
+
// 2. Binary Search.
|
|
68
|
+
//
|
|
59
69
|
// We know that `v` is not 0 so it doesn't make sense to check `n` when `i` is 0.
|
|
60
|
-
// Because of this, We check if `i` is greater than
|
|
61
|
-
while (i !==
|
|
70
|
+
// Because of this, We check if `i` is greater than 1023 before we divide it by 2.
|
|
71
|
+
while (i !== 1023n) {
|
|
62
72
|
i >>= 1n;
|
|
63
73
|
const n = v >> i;
|
|
64
74
|
if (n !== 0n) {
|
|
@@ -66,7 +76,15 @@ export const log2 = (v) => {
|
|
|
66
76
|
v = n;
|
|
67
77
|
}
|
|
68
78
|
}
|
|
69
|
-
|
|
79
|
+
//
|
|
80
|
+
// 3. Remainder Phase.
|
|
81
|
+
//
|
|
82
|
+
// We know that `v` is less than `1n << 1023` so we can calculate a remainder using
|
|
83
|
+
// `Math.log2`.
|
|
84
|
+
const rem = BigInt(Math.log2(Number(v)) | 0);
|
|
85
|
+
// (v >> rem) is either `0` or `1`, and it's used as a correction for
|
|
86
|
+
// Math.log2 rounding.
|
|
87
|
+
return result + rem + (v >> rem);
|
|
70
88
|
};
|
|
71
89
|
/**
|
|
72
90
|
* Calculates the bit length of a given BigInt.
|
|
@@ -110,3 +128,7 @@ export const bitLength = (v) => {
|
|
|
110
128
|
* ```
|
|
111
129
|
*/
|
|
112
130
|
export const mask = (len) => (1n << len) - 1n;
|
|
131
|
+
/**
|
|
132
|
+
* A minimal value.
|
|
133
|
+
*/
|
|
134
|
+
export const min = (a) => (b) => a < b ? a : b;
|
package/types/bigint/test.f.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
export declare const clz32Log2: (v: bigint) => bigint;
|
|
1
2
|
declare const _default: {
|
|
2
3
|
example: () => void;
|
|
3
|
-
benchmark: {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
benchmark: () => {
|
|
5
|
+
big: {
|
|
6
|
+
[k: string]: () => void;
|
|
7
|
+
};
|
|
8
|
+
small: {
|
|
9
|
+
[k: string]: () => void;
|
|
10
|
+
};
|
|
8
11
|
};
|
|
9
12
|
mask: () => void;
|
|
10
13
|
sum: () => void;
|
package/types/bigint/test.f.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sum, abs, serialize, log2, bitLength, mask } from "./module.f.js";
|
|
1
|
+
import { sum, abs, serialize, log2, bitLength, mask, min } from "./module.f.js";
|
|
2
2
|
const oldLog2 = (v) => {
|
|
3
3
|
if (v <= 0n) {
|
|
4
4
|
return -1n;
|
|
@@ -27,24 +27,83 @@ const oldLog2 = (v) => {
|
|
|
27
27
|
}
|
|
28
28
|
return result;
|
|
29
29
|
};
|
|
30
|
-
const
|
|
31
|
-
const
|
|
30
|
+
const strBinLog2 = (v) => BigInt(v.toString(2).length) - 1n;
|
|
31
|
+
const strHexLog2 = (v) => {
|
|
32
32
|
const len = (BigInt(v.toString(16).length) - 1n) << 2n;
|
|
33
|
-
|
|
34
|
-
return len + 31n - BigInt(Math.clz32(Number(x)));
|
|
33
|
+
return len + 31n - BigInt(Math.clz32(Number(v >> len)));
|
|
35
34
|
};
|
|
36
|
-
const
|
|
35
|
+
const str32Log2 = (v) => {
|
|
36
|
+
const len = (BigInt(v.toString(32).length) - 1n) * 5n;
|
|
37
|
+
return len + 31n - BigInt(Math.clz32(Number(v >> len)));
|
|
38
|
+
};
|
|
39
|
+
export const clz32Log2 = (v) => {
|
|
40
|
+
if (v <= 0n) {
|
|
41
|
+
return -1n;
|
|
42
|
+
}
|
|
43
|
+
let result = 31n;
|
|
44
|
+
let i = 32n;
|
|
45
|
+
while (true) {
|
|
46
|
+
const n = v >> i;
|
|
47
|
+
if (n === 0n) {
|
|
48
|
+
// overshot
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
v = n;
|
|
52
|
+
result += i;
|
|
53
|
+
i <<= 1n;
|
|
54
|
+
}
|
|
55
|
+
// We know that `v` is not 0 so it doesn't make sense to check `n` when `i` is 0.
|
|
56
|
+
// Because of this, We check if `i` is greater than 32 before we divide it by 2.
|
|
57
|
+
while (i !== 32n) {
|
|
58
|
+
i >>= 1n;
|
|
59
|
+
const n = v >> i;
|
|
60
|
+
if (n !== 0n) {
|
|
61
|
+
result += i;
|
|
62
|
+
v = n;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return result - BigInt(Math.clz32(Number(v)));
|
|
66
|
+
};
|
|
67
|
+
const benchmark = f => () => {
|
|
37
68
|
let e = 1048575n;
|
|
38
69
|
let c = 1n << e;
|
|
39
|
-
for (let i = 0n; i <
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
70
|
+
for (let i = 0n; i < 1_100; ++i) {
|
|
71
|
+
{
|
|
72
|
+
const x = f(c);
|
|
73
|
+
if (x !== e) {
|
|
74
|
+
throw x;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
{
|
|
78
|
+
const x = f(c - 1n);
|
|
79
|
+
if (x !== e - 1n) {
|
|
80
|
+
throw [e, x];
|
|
81
|
+
}
|
|
43
82
|
}
|
|
44
83
|
c >>= 1n;
|
|
45
84
|
--e;
|
|
46
85
|
}
|
|
47
86
|
};
|
|
87
|
+
const benchmarkSmall = f => () => {
|
|
88
|
+
let e = 2000n;
|
|
89
|
+
let c = 1n << e;
|
|
90
|
+
do {
|
|
91
|
+
{
|
|
92
|
+
const x = f(c);
|
|
93
|
+
if (x !== e) {
|
|
94
|
+
throw [e, x];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
for (let j = 1n; j < min(c >> 1n)(1000n); ++j) {
|
|
98
|
+
const x = f(c - j);
|
|
99
|
+
if (x !== e - 1n) {
|
|
100
|
+
throw [j, e, x];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
c >>= 1n;
|
|
104
|
+
--e;
|
|
105
|
+
} while (c !== 0n);
|
|
106
|
+
};
|
|
48
107
|
export default {
|
|
49
108
|
example: () => {
|
|
50
109
|
const total = sum([1n, 2n, 3n]); // 6n
|
|
@@ -53,26 +112,39 @@ export default {
|
|
|
53
112
|
}
|
|
54
113
|
const absoluteValue = abs(-42n); // 42n
|
|
55
114
|
if (absoluteValue !== 42n) {
|
|
56
|
-
throw
|
|
115
|
+
throw absoluteValue;
|
|
57
116
|
}
|
|
58
117
|
const logValue = log2(8n); // 3n
|
|
59
118
|
if (logValue !== 3n) {
|
|
60
|
-
throw
|
|
119
|
+
throw logValue;
|
|
61
120
|
}
|
|
62
121
|
const bitCount = bitLength(255n); // 8n
|
|
63
122
|
if (bitCount !== 8n) {
|
|
64
|
-
throw
|
|
123
|
+
throw bitCount;
|
|
65
124
|
}
|
|
66
125
|
const bitmask = mask(5n); // 31n
|
|
67
126
|
if (bitmask !== 31n) {
|
|
68
|
-
throw
|
|
127
|
+
throw benchmark;
|
|
128
|
+
}
|
|
129
|
+
const m = min(3n)(13n); // 3n
|
|
130
|
+
if (m !== 3n) {
|
|
131
|
+
throw m;
|
|
69
132
|
}
|
|
70
133
|
},
|
|
71
|
-
benchmark: {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
134
|
+
benchmark: () => {
|
|
135
|
+
const list = {
|
|
136
|
+
strBinLog2,
|
|
137
|
+
strHexLog2,
|
|
138
|
+
str32Log2,
|
|
139
|
+
oldLog2,
|
|
140
|
+
clz32Log2,
|
|
141
|
+
log2,
|
|
142
|
+
};
|
|
143
|
+
const transform = (b) => Object.fromEntries(Object.entries(list).map(([k, f]) => [k, b(f)]));
|
|
144
|
+
return {
|
|
145
|
+
big: transform(benchmark),
|
|
146
|
+
small: transform(benchmarkSmall),
|
|
147
|
+
};
|
|
76
148
|
},
|
|
77
149
|
mask: () => {
|
|
78
150
|
const result = mask(3n); // 7n
|
package/com/cpp/module.f.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module generates C++ code blocks, including structs, interfaces, and method headers,
|
|
3
|
-
* based on a COM library of type definitions.
|
|
4
|
-
*/
|
|
5
|
-
import { type Library } from '../types/module.f.ts';
|
|
6
|
-
import * as text from '../../text/module.f.ts';
|
|
7
|
-
/**
|
|
8
|
-
* Generates the C++ code for a library.
|
|
9
|
-
*/
|
|
10
|
-
export declare const cpp: (name: string) => (lib: Library) => text.Block;
|
package/com/cpp/module.f.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module generates C++ code blocks, including structs, interfaces, and method headers,
|
|
3
|
-
* based on a COM library of type definitions.
|
|
4
|
-
*/
|
|
5
|
-
import { paramList, result, } from "../types/module.f.js";
|
|
6
|
-
import * as text from "../../text/module.f.js";
|
|
7
|
-
import { map, flatMap, flat } from "../../types/list/module.f.js";
|
|
8
|
-
import { join } from "../../types/string/module.f.js";
|
|
9
|
-
const { entries } = Object;
|
|
10
|
-
const struct = (name) => (body) => [`struct ${name}`, '{', body, '};'];
|
|
11
|
-
const baseTypeMap = {
|
|
12
|
-
u8: 'uint8_t',
|
|
13
|
-
i8: 'int8_t',
|
|
14
|
-
u16: 'uint16_t',
|
|
15
|
-
i16: 'int16_t',
|
|
16
|
-
u32: 'uint32_t',
|
|
17
|
-
i32: 'int32_t',
|
|
18
|
-
u64: 'uint64_t',
|
|
19
|
-
i64: 'int64_t',
|
|
20
|
-
usize: 'size_t',
|
|
21
|
-
isize: 'ptrdiff_t',
|
|
22
|
-
f32: 'float',
|
|
23
|
-
f64: 'double',
|
|
24
|
-
bool: 'bool',
|
|
25
|
-
};
|
|
26
|
-
const baseType = (t) => baseTypeMap[t];
|
|
27
|
-
const resultVoid = result('void');
|
|
28
|
-
const namespace = text.curly('namespace');
|
|
29
|
-
const comRef = (id) => `::nanocom::ref<${id}>`;
|
|
30
|
-
const ptr = (id) => `${id} const*`;
|
|
31
|
-
const ref = (id) => `${id} const&`;
|
|
32
|
-
const paramName = ([name]) => name;
|
|
33
|
-
const mapParamName = map(paramName);
|
|
34
|
-
const joinComma = join(', ');
|
|
35
|
-
/**
|
|
36
|
-
* Generates the C++ code for a library.
|
|
37
|
-
*/
|
|
38
|
-
export const cpp = (name) => (lib) => {
|
|
39
|
-
const interface_ = (t) => {
|
|
40
|
-
if (!(t instanceof Array) || t.length !== 1) {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
const [name] = t;
|
|
44
|
-
return 'interface' in lib[name] ? name : null;
|
|
45
|
-
};
|
|
46
|
-
const objectType = (i) => (t) => {
|
|
47
|
-
if (typeof (t) === 'string') {
|
|
48
|
-
return baseType(t);
|
|
49
|
-
}
|
|
50
|
-
if (t.length === 2) {
|
|
51
|
-
return `${type(t[1])} const*`;
|
|
52
|
-
}
|
|
53
|
-
const [id] = t;
|
|
54
|
-
return 'interface' in lib[id] ? i(id) : id;
|
|
55
|
-
};
|
|
56
|
-
const type = objectType(comRef);
|
|
57
|
-
const resultType = objectType(ptr);
|
|
58
|
-
const field = ([name, t]) => `${type(t)} ${name};`;
|
|
59
|
-
const mapField = map(field);
|
|
60
|
-
const defStruct = (s) => mapField(entries(s.struct));
|
|
61
|
-
const cppResult = resultVoid(resultType);
|
|
62
|
-
const param = ([name, t]) => `${objectType(ref)(t)} ${name}`;
|
|
63
|
-
const mapParam = map(param);
|
|
64
|
-
const methodHeader = (result) => (paramArrayStr) => (name) => `virtual ${result} ${name}${paramArrayStr} const noexcept = 0;`;
|
|
65
|
-
const method = ([name, paramArray]) => {
|
|
66
|
-
const result = cppResult(paramArray);
|
|
67
|
-
const paramL = paramList(paramArray);
|
|
68
|
-
const paramArrayStr = `(${joinComma(mapParam(paramL))})`;
|
|
69
|
-
const m = methodHeader(result)(paramArrayStr);
|
|
70
|
-
const resultName = interface_(paramArray._);
|
|
71
|
-
if (resultName === null) {
|
|
72
|
-
return [m(name)];
|
|
73
|
-
}
|
|
74
|
-
return [
|
|
75
|
-
m(`${name}_`),
|
|
76
|
-
`${comRef(resultName)} ${name}${paramArrayStr} const noexcept`,
|
|
77
|
-
'{',
|
|
78
|
-
[`return ::nanocom::move_to_ref(${name}_(${joinComma(mapParamName(paramL))}));`],
|
|
79
|
-
'}',
|
|
80
|
-
];
|
|
81
|
-
};
|
|
82
|
-
const mapMethod = flatMap(method);
|
|
83
|
-
const defInterface = ({ guid, interface: i }) => {
|
|
84
|
-
const g = guid.replaceAll('-', '');
|
|
85
|
-
const lo = g.substring(0, 16);
|
|
86
|
-
const hi = g.substring(16);
|
|
87
|
-
return flat([
|
|
88
|
-
[`constexpr static ::nanocom::GUID const guid = ::nanocom::GUID(0x${lo}, 0x${hi});`],
|
|
89
|
-
mapMethod(entries(i))
|
|
90
|
-
]);
|
|
91
|
-
};
|
|
92
|
-
const def = ([name, d]) => 'interface' in d ?
|
|
93
|
-
[`class ${name} : public ::nanocom::IUnknown`,
|
|
94
|
-
'{',
|
|
95
|
-
'public:',
|
|
96
|
-
defInterface(d),
|
|
97
|
-
'};'
|
|
98
|
-
] :
|
|
99
|
-
struct(name)(defStruct(d));
|
|
100
|
-
const forward = ([name]) => [`struct ${name};`];
|
|
101
|
-
const e = entries(lib);
|
|
102
|
-
return flat([
|
|
103
|
-
['#pragma once', ''],
|
|
104
|
-
namespace(name)(flat([flatMap(forward)(e), flatMap(def)(e)]))
|
|
105
|
-
]);
|
|
106
|
-
};
|
package/com/cpp/test.f.d.ts
DELETED
package/com/cpp/test.f.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import cpp from "./testlib.f.js";
|
|
2
|
-
const f = () => {
|
|
3
|
-
const e = '#pragma once\n' +
|
|
4
|
-
'\n' +
|
|
5
|
-
'namespace My\n' +
|
|
6
|
-
'{\n' +
|
|
7
|
-
' struct Slice;\n' +
|
|
8
|
-
' struct ManagedStruct;\n' +
|
|
9
|
-
' struct IMy;\n' +
|
|
10
|
-
' struct Slice\n' +
|
|
11
|
-
' {\n' +
|
|
12
|
-
' uint8_t const* Start;\n' +
|
|
13
|
-
' size_t Size;\n' +
|
|
14
|
-
' };\n' +
|
|
15
|
-
' struct ManagedStruct\n' +
|
|
16
|
-
' {\n' +
|
|
17
|
-
' ::nanocom::ref<IMy> M;\n' +
|
|
18
|
-
' };\n' +
|
|
19
|
-
' class IMy : public ::nanocom::IUnknown\n' +
|
|
20
|
-
' {\n' +
|
|
21
|
-
' public:\n' +
|
|
22
|
-
' constexpr static ::nanocom::GUID const guid = ::nanocom::GUID(0xC66FB2702D8049AD, 0xBB6E88C1F90B805D);\n' +
|
|
23
|
-
' virtual Slice GetSlice() const noexcept = 0;\n' +
|
|
24
|
-
' virtual void SetSlice(Slice slice) const noexcept = 0;\n' +
|
|
25
|
-
' virtual bool const* GetUnsafe() const noexcept = 0;\n' +
|
|
26
|
-
' virtual void SetUnsafe(Slice const* p, uint32_t size) const noexcept = 0;\n' +
|
|
27
|
-
' virtual bool Some(IMy const& p) const noexcept = 0;\n' +
|
|
28
|
-
' virtual IMy const* GetIMy_(uint16_t a, int16_t b) const noexcept = 0;\n' +
|
|
29
|
-
' ::nanocom::ref<IMy> GetIMy(uint16_t a, int16_t b) const noexcept\n' +
|
|
30
|
-
' {\n' +
|
|
31
|
-
' return ::nanocom::move_to_ref(GetIMy_(a, b));\n' +
|
|
32
|
-
' }\n' +
|
|
33
|
-
' virtual void SetManagedStruct(ManagedStruct a) const noexcept = 0;\n' +
|
|
34
|
-
' };\n' +
|
|
35
|
-
'}';
|
|
36
|
-
if (cpp() !== e) {
|
|
37
|
-
throw cpp;
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
export default f;
|
package/com/cpp/testlib.f.d.ts
DELETED
package/com/cpp/testlib.f.js
DELETED
package/com/cs/module.f.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module generates C# code blocks for COM interop from a high-level type library definition.
|
|
3
|
-
*
|
|
4
|
-
* The module maps type definitions (e.g., structs, interfaces, and methods) into C# constructs
|
|
5
|
-
* with appropriate attributes for COM interop, such as `[StructLayout]`, `[Guid]`, and `[InterfaceType]`.
|
|
6
|
-
*/
|
|
7
|
-
import { type Library } from '../types/module.f.ts';
|
|
8
|
-
import { type Block } from '../../text/module.f.ts';
|
|
9
|
-
/**
|
|
10
|
-
* Generates the C# code for a library.
|
|
11
|
-
*/
|
|
12
|
-
export declare const cs: (name: string) => (library: Library) => Block;
|
package/com/cs/module.f.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module generates C# code blocks for COM interop from a high-level type library definition.
|
|
3
|
-
*
|
|
4
|
-
* The module maps type definitions (e.g., structs, interfaces, and methods) into C# constructs
|
|
5
|
-
* with appropriate attributes for COM interop, such as `[StructLayout]`, `[Guid]`, and `[InterfaceType]`.
|
|
6
|
-
*/
|
|
7
|
-
import { result, paramList, } from "../types/module.f.js";
|
|
8
|
-
import { curly } from "../../text/module.f.js";
|
|
9
|
-
import { flat, map, some, flatMap } from "../../types/list/module.f.js";
|
|
10
|
-
import { join } from "../../types/string/module.f.js";
|
|
11
|
-
const { entries } = Object;
|
|
12
|
-
const using = (v) => `using ${v};`;
|
|
13
|
-
const typeDef = (attributes) => (type) => (name) => (body) => flat([
|
|
14
|
-
map(v => `[${v}]`)(attributes),
|
|
15
|
-
curly(`public ${type}`)(name)(body)
|
|
16
|
-
]);
|
|
17
|
-
const baseTypeMap = {
|
|
18
|
-
bool: 'byte',
|
|
19
|
-
f32: 'float',
|
|
20
|
-
f64: 'double',
|
|
21
|
-
i16: 'short',
|
|
22
|
-
i32: 'int',
|
|
23
|
-
i64: 'long',
|
|
24
|
-
i8: 'sbyte',
|
|
25
|
-
isize: 'IntPtr',
|
|
26
|
-
u16: 'ushort',
|
|
27
|
-
u32: 'uint',
|
|
28
|
-
u64: 'ulong',
|
|
29
|
-
u8: 'byte',
|
|
30
|
-
usize: 'UIntPtr',
|
|
31
|
-
};
|
|
32
|
-
const baseType = (t) => baseTypeMap[t];
|
|
33
|
-
const unsafe = (isUnsafe) => isUnsafe ? 'unsafe ' : '';
|
|
34
|
-
const fullType = (t) => typeof (t) === 'string' ?
|
|
35
|
-
[false, baseType(t)] :
|
|
36
|
-
t.length === 1 ?
|
|
37
|
-
[false, t[0]] :
|
|
38
|
-
[true, `${type(t[1])}*`];
|
|
39
|
-
const type = (t) => fullType(t)[1];
|
|
40
|
-
const param = ([name, t]) => `${type(t)} ${name}`;
|
|
41
|
-
const mapParam = map(param);
|
|
42
|
-
const field = ([name, comType]) => {
|
|
43
|
-
const [isUnsafe, t] = fullType(comType);
|
|
44
|
-
return `public ${unsafe(isUnsafe)}${t} ${name};`;
|
|
45
|
-
};
|
|
46
|
-
const isUnsafeField = (field) => fullType(field[1])[0];
|
|
47
|
-
const mapIsUnsafeField = map(isUnsafeField);
|
|
48
|
-
const resultVoid = result('void');
|
|
49
|
-
const joinComma = join(', ');
|
|
50
|
-
const method = ([name, m]) => {
|
|
51
|
-
const paramAndResultList = entries(m);
|
|
52
|
-
const pl = paramList(m);
|
|
53
|
-
const isUnsafe = some(mapIsUnsafeField(paramAndResultList));
|
|
54
|
-
return [
|
|
55
|
-
'[PreserveSig]',
|
|
56
|
-
`${unsafe(isUnsafe)}${resultVoid(type)(m)} ${name}(${joinComma(mapParam(pl))});`
|
|
57
|
-
];
|
|
58
|
-
};
|
|
59
|
-
const struct = typeDef(['StructLayout(LayoutKind.Sequential)'])('struct');
|
|
60
|
-
const mapField = map(field);
|
|
61
|
-
const flatMapMethod = flatMap(method);
|
|
62
|
-
const def = ([n, d]) => !('interface' in d) ?
|
|
63
|
-
struct(n)(mapField(entries(d.struct))) :
|
|
64
|
-
typeDef([`Guid("${d.guid}")`, 'InterfaceType(ComInterfaceType.InterfaceIsIUnknown)'])('interface')(n)(flatMapMethod(entries(d.interface)));
|
|
65
|
-
const flatMapDef = flatMap(def);
|
|
66
|
-
const namespace = curly('namespace');
|
|
67
|
-
const header = [
|
|
68
|
-
using('System'),
|
|
69
|
-
using('System.Runtime.InteropServices'),
|
|
70
|
-
''
|
|
71
|
-
];
|
|
72
|
-
/**
|
|
73
|
-
* Generates the C# code for a library.
|
|
74
|
-
*/
|
|
75
|
-
export const cs = (name) => (library) => {
|
|
76
|
-
const v = flatMapDef(entries(library));
|
|
77
|
-
const ns = namespace(name)(v);
|
|
78
|
-
return flat([header, ns]);
|
|
79
|
-
};
|
package/com/cs/test.f.d.ts
DELETED