functionalscript 0.0.354 → 0.0.355
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/com/cs/main.f.js +112 -0
- package/com/cs/test/Program.cs +2 -0
- package/com/cs/test/build.js +11 -0
- package/com/cs/test/test.csproj +11 -0
- package/com/{test.f.js → cs/test.f.js} +20 -6
- package/com/main.f.js +2 -132
- package/com/types/main.f.js +55 -0
- package/package.json +1 -1
- package/test.f.js +1 -1
package/com/cs/main.f.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const types = require('../types/main.f.js')
|
|
2
|
+
const text = require('../../text/main.f.js')
|
|
3
|
+
const list = require('../../types/list/main.f.js')
|
|
4
|
+
const obj = require('../../types/object/main.f.js')
|
|
5
|
+
|
|
6
|
+
/** @type {(v: string) => string} */
|
|
7
|
+
const csUsing = v => `using ${v};`
|
|
8
|
+
|
|
9
|
+
/** @type {(type: string) => (name: string) => (body: text.Block) => text.Block} */
|
|
10
|
+
const csBlock = type => name => body => [`${type} ${name}`, '{', body, '}']
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @type {(attributes: list.List<string>) =>
|
|
14
|
+
* (type: string) =>
|
|
15
|
+
* (name: string) =>
|
|
16
|
+
* (body: text.Block) =>
|
|
17
|
+
* list.List<text.Item>}
|
|
18
|
+
*/
|
|
19
|
+
const csTypeDef = attributes => type => name => body =>
|
|
20
|
+
list.flat([
|
|
21
|
+
list.map(v => `[${v}]`)(attributes),
|
|
22
|
+
csBlock(`public ${type}`)(name)(body)
|
|
23
|
+
])
|
|
24
|
+
|
|
25
|
+
/** @type {(t: types.BaseType) => string} */
|
|
26
|
+
const csBaseType = t => {
|
|
27
|
+
switch (t) {
|
|
28
|
+
case 'bool': return 'bool'
|
|
29
|
+
case 'f32': return 'float'
|
|
30
|
+
case 'f64': return 'double'
|
|
31
|
+
case 'i16': return 'short'
|
|
32
|
+
case 'i32': return 'int'
|
|
33
|
+
case 'i64': return 'long'
|
|
34
|
+
case 'i8': return 'sbyte'
|
|
35
|
+
case 'isize': return 'IntPtr'
|
|
36
|
+
case 'u16': return 'ushort'
|
|
37
|
+
case 'u32': return 'uint'
|
|
38
|
+
case 'u64': return 'ulong'
|
|
39
|
+
case 'u8': return 'byte'
|
|
40
|
+
case 'usize': return 'UIntPtr'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** @type {(isUnsafe: boolean) => string} */
|
|
45
|
+
const unsafe = isUnsafe => isUnsafe ? 'unsafe ' : ''
|
|
46
|
+
|
|
47
|
+
/** @type {(t: types.Type) => readonly[boolean, string]} */
|
|
48
|
+
const csType = t =>
|
|
49
|
+
typeof (t) === 'string' ? [false, csBaseType(t)] :
|
|
50
|
+
t instanceof Array ? [false, t[0]] :
|
|
51
|
+
[true, `${csType(t['*'])[1]}*`]
|
|
52
|
+
|
|
53
|
+
/** @type {(f: types.Field) => string} */
|
|
54
|
+
const csParam = ([name, type]) => `${csType(type)[1]} ${name}`
|
|
55
|
+
|
|
56
|
+
/** @type {(f: types.Field) => string} */
|
|
57
|
+
const csField = ([name, type]) => {
|
|
58
|
+
const [isUnsafe, t] = csType(type)
|
|
59
|
+
return `public ${unsafe(isUnsafe)}${t} ${name};`
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** @type {(m: types.Method) => readonly[boolean, string]} */
|
|
63
|
+
const csResult = m => m.length === 2 ? [false, 'void'] : csType(m[2])
|
|
64
|
+
|
|
65
|
+
/** @type {(field: types.Field) => boolean} */
|
|
66
|
+
const isUnsafeField = field => csType(field[1])[0]
|
|
67
|
+
|
|
68
|
+
/** @type {(m: types.Method) => readonly string[]} */
|
|
69
|
+
const csMethod = m => {
|
|
70
|
+
const result = csResult(m)
|
|
71
|
+
const isUnsafe = result[0] || list.some(list.map(isUnsafeField)(m[1]))
|
|
72
|
+
return [
|
|
73
|
+
'[PreserveSig]',
|
|
74
|
+
`${unsafe(isUnsafe)}${result[1]} ${m[0]}(${list.join(', ')(list.map(csParam)(m[1]))});`
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** @type {(e: obj.Entry<types.Definition>) => list.List<text.Item>} */
|
|
79
|
+
const csDef = ([n, d]) => {
|
|
80
|
+
const i = d.interface
|
|
81
|
+
return i === undefined ?
|
|
82
|
+
csTypeDef
|
|
83
|
+
(['StructLayout(LayoutKind.Sequential)'])
|
|
84
|
+
('struct')
|
|
85
|
+
(n)
|
|
86
|
+
(() => list.map(csField)(d.struct)) :
|
|
87
|
+
csTypeDef
|
|
88
|
+
([`Guid("${d.guid}")`, 'InterfaceType(ComInterfaceType.InterfaceIsIUnknown)'])
|
|
89
|
+
('interface')
|
|
90
|
+
(n)
|
|
91
|
+
(() => list.flatMap(csMethod)(d.interface))
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** @type {(name: string) => (library: types.Library) => text.Block} */
|
|
95
|
+
const cs = name => library => {
|
|
96
|
+
const v = list.flatMap(csDef)(Object.entries(library))
|
|
97
|
+
|
|
98
|
+
/** @type {text.Block} */
|
|
99
|
+
const h = [
|
|
100
|
+
csUsing('System'),
|
|
101
|
+
csUsing('System.Runtime.InteropServices'),
|
|
102
|
+
''
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
const ns = csBlock('namespace')(name)(() => v)
|
|
106
|
+
return () => list.flat([h, ns])
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = {
|
|
110
|
+
/** @readonly */
|
|
111
|
+
cs,
|
|
112
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const fs = require('node:fs')
|
|
2
|
+
const cp = require('node:child_process')
|
|
3
|
+
const cs = require('../test.f.js').result
|
|
4
|
+
|
|
5
|
+
fs.writeFileSync('_result.cs', cs)
|
|
6
|
+
try {
|
|
7
|
+
console.log(cp.execSync('dotnet build').toString())
|
|
8
|
+
} catch (e) {
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
console.log(e.output.toString())
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
|
+
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<OutputType>Exe</OutputType>
|
|
5
|
+
<TargetFramework>net6.0</TargetFramework>
|
|
6
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
7
|
+
<Nullable>enable</Nullable>
|
|
8
|
+
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
|
9
|
+
</PropertyGroup>
|
|
10
|
+
|
|
11
|
+
</Project>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
const types = require('../types/main.f.js')
|
|
1
2
|
const _ = require('./main.f.js')
|
|
2
|
-
const list = require('
|
|
3
|
-
const text = require('
|
|
3
|
+
const list = require('../../types/list/main.f.js')
|
|
4
|
+
const text = require('../../text/main.f.js')
|
|
4
5
|
|
|
5
|
-
/** @type {
|
|
6
|
+
/** @type {types.Library} */
|
|
6
7
|
const library = {
|
|
7
8
|
Slice: {
|
|
8
9
|
struct: [
|
|
@@ -15,10 +16,13 @@ const library = {
|
|
|
15
16
|
interface: [
|
|
16
17
|
['GetSlice', [], ['Slice']],
|
|
17
18
|
['SetSlice', [['slice', ['Slice']]]],
|
|
19
|
+
['GetUnsafe', [], {'*': 'bool'}],
|
|
20
|
+
['SetUnsafe', [['p', {'*': ['Slice']}], ['size', 'u32']]],
|
|
18
21
|
],
|
|
19
22
|
}
|
|
20
23
|
}
|
|
21
24
|
|
|
25
|
+
const f = () =>
|
|
22
26
|
{
|
|
23
27
|
const cs = list.join('\n')(text.flat(' ')(_.cs('My')(library)))
|
|
24
28
|
const e =
|
|
@@ -30,20 +34,30 @@ const library = {
|
|
|
30
34
|
' [StructLayout(LayoutKind.Sequential)]\n' +
|
|
31
35
|
' public struct Slice\n' +
|
|
32
36
|
' {\n' +
|
|
33
|
-
' public byte* Start;\n' +
|
|
37
|
+
' public unsafe byte* Start;\n' +
|
|
34
38
|
' public UIntPtr Size;\n' +
|
|
35
39
|
' }\n' +
|
|
36
40
|
' [Guid("C66FB270-2D80-49AD-BB6E-88C1F90B805D")]\n' +
|
|
37
|
-
' [InterfaceType(ComInterfaceType.
|
|
41
|
+
' [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n' +
|
|
38
42
|
' public interface IMy\n' +
|
|
39
43
|
' {\n' +
|
|
40
44
|
' [PreserveSig]\n' +
|
|
41
45
|
' Slice GetSlice();\n' +
|
|
42
46
|
' [PreserveSig]\n' +
|
|
43
47
|
' void SetSlice(Slice slice);\n' +
|
|
48
|
+
' [PreserveSig]\n' +
|
|
49
|
+
' unsafe bool* GetUnsafe();\n' +
|
|
50
|
+
' [PreserveSig]\n' +
|
|
51
|
+
' unsafe void SetUnsafe(Slice* p, uint size);\n' +
|
|
44
52
|
' }\n' +
|
|
45
53
|
'}'
|
|
46
54
|
if (cs !== e) { throw [cs,e] }
|
|
55
|
+
return cs
|
|
47
56
|
}
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
const result = f()
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
/** @readonly */
|
|
62
|
+
result,
|
|
63
|
+
}
|
package/com/main.f.js
CHANGED
|
@@ -1,136 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
const list = require('../types/list/main.f')
|
|
3
|
-
const obj = require('../types/object/main.f.js')
|
|
4
|
-
|
|
5
|
-
/** @typedef {{readonly[k in string]: Definition}} Library */
|
|
6
|
-
|
|
7
|
-
/** @typedef {Struct|Interface} Definition */
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @typedef {{
|
|
11
|
-
* readonly interface?: undefined
|
|
12
|
-
* readonly struct: FieldArray
|
|
13
|
-
* }} Struct
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/** @typedef {readonly Field[]} FieldArray */
|
|
17
|
-
|
|
18
|
-
/** @typedef {[string, Type]} Field */
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @typedef {{
|
|
22
|
-
* readonly interface: MethodArray
|
|
23
|
-
* readonly guid: string
|
|
24
|
-
* }} Interface
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
/** @typedef {readonly Method[]} MethodArray */
|
|
28
|
-
|
|
29
|
-
/** @typedef {readonly[string, FieldArray, Type]} GetMethod */
|
|
30
|
-
|
|
31
|
-
/** @typedef {readonly[string, FieldArray]} SetMethod */
|
|
32
|
-
|
|
33
|
-
/** @typedef {GetMethod|SetMethod} Method */
|
|
34
|
-
|
|
35
|
-
/** @typedef {BaseType|Id|Pointer} Type */
|
|
36
|
-
|
|
37
|
-
/** @typedef {readonly[string]} Id */
|
|
38
|
-
|
|
39
|
-
/** @typedef {'u8'|'i8'|'u16'|'i16'|'u32'|'i32'|'u64'|'i64'|'usize'|'isize'|'f32'|'f64'|'bool'} BaseType */
|
|
40
|
-
|
|
41
|
-
/** @typedef {{readonly '*': Type}} Pointer */
|
|
42
|
-
|
|
43
|
-
/** @type {(v: string) => string} */
|
|
44
|
-
const csUsing = v => `using ${v};`
|
|
45
|
-
|
|
46
|
-
/** @type {(type: string) => (name: string) => (body: text.Block) => text.Block} */
|
|
47
|
-
const csBlock = type => name => body => [`${type} ${name}`, '{', body, '}']
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @type {(attributes: list.List<string>) =>
|
|
51
|
-
* (type: string) =>
|
|
52
|
-
* (name: string) =>
|
|
53
|
-
* (body: text.Block) =>
|
|
54
|
-
* list.List<text.Item>}
|
|
55
|
-
*/
|
|
56
|
-
const csTypeDef = attributes => type => name => body =>
|
|
57
|
-
list.flat([
|
|
58
|
-
list.map(v=>`[${v}]`)(attributes),
|
|
59
|
-
csBlock(`public ${type}`)(name)(body)
|
|
60
|
-
])
|
|
61
|
-
|
|
62
|
-
/** @type {(t: BaseType) => string} */
|
|
63
|
-
const csBaseType = t => {
|
|
64
|
-
switch (t) {
|
|
65
|
-
case 'bool': return 'bool'
|
|
66
|
-
case 'f32': return 'float'
|
|
67
|
-
case 'f64': return 'double'
|
|
68
|
-
case 'i16': return 'short'
|
|
69
|
-
case 'i32': return 'int'
|
|
70
|
-
case 'i64': return 'long'
|
|
71
|
-
case 'i8': return 'sbyte'
|
|
72
|
-
case 'isize': return 'IntPtr'
|
|
73
|
-
case 'u16': return 'ushort'
|
|
74
|
-
case 'u32': return 'uint'
|
|
75
|
-
case 'u64': return 'ulong'
|
|
76
|
-
case 'u8': return 'byte'
|
|
77
|
-
case 'usize': return 'UIntPtr'
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** @type {(t: Type) => string} */
|
|
82
|
-
const csType = t =>
|
|
83
|
-
typeof(t) === 'string' ? csBaseType(t) :
|
|
84
|
-
t instanceof Array ? t[0] :
|
|
85
|
-
`${csType(t['*'])}*`
|
|
86
|
-
|
|
87
|
-
/** @type {(f: Field) => string} */
|
|
88
|
-
const csParam = ([name, type]) => `${csType(type)} ${name}`
|
|
89
|
-
|
|
90
|
-
/** @type {(f: Field) => string} */
|
|
91
|
-
const csField = f => `public ${csParam(f)};`
|
|
92
|
-
|
|
93
|
-
/** @type {(m: Method) => string} */
|
|
94
|
-
const csResult = m => m.length === 2 ? 'void' : csType(m[2])
|
|
95
|
-
|
|
96
|
-
/** @type {(m: Method) => readonly string[]} */
|
|
97
|
-
const csMethod = m => [
|
|
98
|
-
'[PreserveSig]',
|
|
99
|
-
`${csResult(m)} ${m[0]}(${list.join(',')(list.map(csParam)(m[1]))});`
|
|
100
|
-
]
|
|
101
|
-
|
|
102
|
-
/** @type {(e: obj.Entry<Definition>) => list.List<text.Item>} */
|
|
103
|
-
const csDef = ([n, d]) => {
|
|
104
|
-
const i = d.interface
|
|
105
|
-
return i === undefined ?
|
|
106
|
-
csTypeDef
|
|
107
|
-
(['StructLayout(LayoutKind.Sequential)'])
|
|
108
|
-
('struct')
|
|
109
|
-
(n)
|
|
110
|
-
(() => list.map(csField)(d.struct)) :
|
|
111
|
-
csTypeDef
|
|
112
|
-
([`Guid("${d.guid}")`,'InterfaceType(ComInterfaceType.InterfaceIsUnknown)'])
|
|
113
|
-
('interface')
|
|
114
|
-
(n)
|
|
115
|
-
(() => list.flatMap(csMethod)(d.interface))
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** @type {(name: string) => (library: Library) => text.Block} */
|
|
119
|
-
const cs = name => library => {
|
|
120
|
-
const v = list.flatMap(csDef)(Object.entries(library))
|
|
121
|
-
|
|
122
|
-
/** @type {text.Block} */
|
|
123
|
-
const h = [
|
|
124
|
-
csUsing('System'),
|
|
125
|
-
csUsing('System.Runtime.InteropServices'),
|
|
126
|
-
''
|
|
127
|
-
]
|
|
128
|
-
|
|
129
|
-
const ns = csBlock('namespace')(name)(() => v)
|
|
130
|
-
return () => list.flat([h, ns])
|
|
131
|
-
}
|
|
1
|
+
const types = require('./types/main.f.js');
|
|
132
2
|
|
|
133
3
|
module.exports = {
|
|
134
4
|
/** @readonly */
|
|
135
|
-
|
|
5
|
+
types,
|
|
136
6
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** @typedef {{readonly[k in string]: Definition}} Library */
|
|
2
|
+
|
|
3
|
+
/** @typedef {Struct|Interface} Definition */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {{
|
|
7
|
+
* readonly interface?: undefined
|
|
8
|
+
* readonly struct: FieldArray
|
|
9
|
+
* }} Struct
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** @typedef {readonly Field[]} FieldArray */
|
|
13
|
+
|
|
14
|
+
/** @typedef {readonly[string, Type]} Field */
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {{
|
|
18
|
+
* readonly interface: MethodArray
|
|
19
|
+
* readonly guid: string
|
|
20
|
+
* }} Interface
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** @typedef {readonly Method[]} MethodArray */
|
|
24
|
+
|
|
25
|
+
/** @typedef {readonly[string, FieldArray, Type]} GetMethod */
|
|
26
|
+
|
|
27
|
+
/** @typedef {readonly[string, FieldArray]} SetMethod */
|
|
28
|
+
|
|
29
|
+
/** @typedef {GetMethod|SetMethod} Method */
|
|
30
|
+
|
|
31
|
+
/** @typedef {BaseType|Id|Pointer} Type */
|
|
32
|
+
|
|
33
|
+
/** @typedef {readonly[string]} Id */
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @typedef {|
|
|
37
|
+
* 'u8'|
|
|
38
|
+
* 'i8'|
|
|
39
|
+
* 'u16'|
|
|
40
|
+
* 'i16'|
|
|
41
|
+
* 'u32'|
|
|
42
|
+
* 'i32'|
|
|
43
|
+
* 'u64'|
|
|
44
|
+
* 'i64'|
|
|
45
|
+
* 'usize'|
|
|
46
|
+
* 'isize'|
|
|
47
|
+
* 'f32'|
|
|
48
|
+
* 'f64'|
|
|
49
|
+
* 'bool'
|
|
50
|
+
* } BaseType
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/** @typedef {{readonly '*': Type}} Pointer */
|
|
54
|
+
|
|
55
|
+
module.exports = {}
|
package/package.json
CHANGED
package/test.f.js
CHANGED
|
@@ -17,7 +17,7 @@ require('./commonjs/build/test.f.js')
|
|
|
17
17
|
require('./types/range/test.f.js')
|
|
18
18
|
require('./html/test.f.js')
|
|
19
19
|
require('./text/test.f.js')
|
|
20
|
-
require('./com/test.f.js')
|
|
20
|
+
require('./com/cs/test.f.js')
|
|
21
21
|
|
|
22
22
|
/** @type {() => never} */
|
|
23
23
|
const assert = () => { throw 'assert' }
|