functionalscript 0.0.352 → 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.
@@ -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,2 @@
1
+ // See https://aka.ms/new-console-template for more information
2
+ Console.WriteLine("Hello, World!");
@@ -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>
@@ -0,0 +1,63 @@
1
+ const types = require('../types/main.f.js')
2
+ const _ = require('./main.f.js')
3
+ const list = require('../../types/list/main.f.js')
4
+ const text = require('../../text/main.f.js')
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', [['p', {'*': ['Slice']}], ['size', 'u32']]],
21
+ ],
22
+ }
23
+ }
24
+
25
+ const f = () =>
26
+ {
27
+ const cs = list.join('\n')(text.flat(' ')(_.cs('My')(library)))
28
+ const e =
29
+ 'using System;\n' +
30
+ 'using System.Runtime.InteropServices;\n' +
31
+ '\n' +
32
+ 'namespace My\n' +
33
+ '{\n' +
34
+ ' [StructLayout(LayoutKind.Sequential)]\n' +
35
+ ' public struct Slice\n' +
36
+ ' {\n' +
37
+ ' public unsafe byte* Start;\n' +
38
+ ' public UIntPtr Size;\n' +
39
+ ' }\n' +
40
+ ' [Guid("C66FB270-2D80-49AD-BB6E-88C1F90B805D")]\n' +
41
+ ' [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n' +
42
+ ' public interface IMy\n' +
43
+ ' {\n' +
44
+ ' [PreserveSig]\n' +
45
+ ' Slice GetSlice();\n' +
46
+ ' [PreserveSig]\n' +
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' +
52
+ ' }\n' +
53
+ '}'
54
+ if (cs !== e) { throw [cs,e] }
55
+ return cs
56
+ }
57
+
58
+ const result = f()
59
+
60
+ module.exports = {
61
+ /** @readonly */
62
+ result,
63
+ }
package/com/main.f.js CHANGED
@@ -1,30 +1,6 @@
1
- /** @typedef {{readonly[k in string]: Definition}} Library */
1
+ const types = require('./types/main.f.js');
2
2
 
3
- /** @typedef {Struct|Interface} Definition */
4
-
5
- /** @typedef {{readonly struct: FieldArray}} Struct */
6
-
7
- /** @typedef {readonly Field[]} FieldArray */
8
-
9
- /** @typedef {[string, Type]} Field */
10
-
11
- /**
12
- * @typedef {{
13
- * readonly interface: MethodArray
14
- * readonly guid: string
15
- * }} Interface
16
- */
17
-
18
- /** @typedef {readonly Method[]} MethodArray */
19
-
20
- /** @typedef {readonly[string, FieldArray, Type]} Method */
21
-
22
- /** @typedef {BaseType|Id|Pointer} Type */
23
-
24
- /** @typedef {readonly[string]} Id */
25
-
26
- /** @typedef {'u8'|'i8'|'u16'|'i16'|'u32'|'i32'|'u64'|'i64'|'usize'|'isize'|'f32'|'f64'|'bool'|''} BaseType */
27
-
28
- /** @typedef {{readonly '*': Type}} Pointer */
29
-
30
- module.exports = {}
3
+ module.exports = {
4
+ /** @readonly */
5
+ types,
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.352",
3
+ "version": "0.0.355",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "main.f.js",
6
6
  "scripts": {
package/test.f.js CHANGED
@@ -17,6 +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/cs/test.f.js')
20
21
 
21
22
  /** @type {() => never} */
22
23
  const assert = () => { throw 'assert' }
package/text/main.f.js CHANGED
@@ -1,21 +1,27 @@
1
1
  const list = require('../types/list/main.f.js')
2
2
 
3
- /** @typedef {readonly Item[]} Text */
3
+ /** @typedef {ItemThunk|ItemArray} Block */
4
4
 
5
- /** @typedef {string|Text} Item */
5
+ /** @typedef {readonly Item[]} ItemArray */
6
6
 
7
- /** @type {(indent: string) => (text: Text) => list.List<string>} */
7
+ /** @typedef {() => list.List<Item>} ItemThunk */
8
+
9
+ /** @typedef {string|ItemArray|ItemThunk} Item */
10
+
11
+ /** @type {(indent: string) => (text: Block) => list.List<string>} */
8
12
  const flat = indent => {
9
- /** @type {(v: string) => string} */
10
- const indentFn = v => `${indent}${v}`
11
- const map = list.map(indentFn)
12
- /** @type {(item: Item) => list.List<string>} */
13
- const flatItem = item => typeof(item) === 'string' ? [item] : map(flatText(item))
14
- const flatText = list.flatMap(flatItem)
15
- return flatText
13
+
14
+ /** @type {(prefix: string) => (text: Block) => list.List<string>} */
15
+ const f = prefix => {
16
+ /** @type {(item: Item) => list.List<string>} */
17
+ const g = item => typeof (item) === 'string' ? [`${prefix}${item}`] : f(`${prefix}${indent}`)(item)
18
+ return list.flatMap(g)
19
+ }
20
+
21
+ return f('')
16
22
  }
17
23
 
18
24
  module.exports = {
19
25
  /** @readonly */
20
26
  flat,
21
- }
27
+ }
package/text/test.f.js CHANGED
@@ -2,17 +2,18 @@ const _ = require('./main.f.js')
2
2
  const list = require('../types/list/main.f.js')
3
3
 
4
4
  {
5
- /** @type {_.Text} */
5
+ /** @type {_.Block} */
6
6
  const text = [
7
7
  'a',
8
8
  'b',
9
- [
9
+ () => [
10
10
  'c',
11
- ['d'],
12
- ]
11
+ () => ['d'],
12
+ ],
13
+ 'e',
13
14
  ]
14
- const result = list.join('\n')(_.flat('_')(text))
15
- if (result !== 'a\nb\n_c\n__d') { throw result }
15
+ const result = list.join('\n')(_.flat(':')(text))
16
+ if (result !== 'a\nb\n:c\n::d\ne') { throw result }
16
17
  }
17
18
 
18
19
  module.exports = {}
@@ -172,8 +172,7 @@ const drop = n => apply(dropStep(n))
172
172
  /** @type {<D>(def: D) => <T>(input: List<T>) => D|T} */
173
173
  const first = def => input => {
174
174
  const result = next(input)
175
- if (result === undefined) { return def }
176
- return result.first
175
+ return result === undefined ? def : result.first
177
176
  }
178
177
 
179
178
  /** @type {<D>(first: D) => <T>(tail: List<T>) => D|T} */
@@ -215,6 +214,9 @@ const countdown = count => () => {
215
214
  return { first, tail: countdown(first) }
216
215
  }
217
216
 
217
+ /** @type {<T>(v: T) => (c: number) => List<T>} */
218
+ const repeat = v => n => map(() => v)(countdown(n))
219
+
218
220
  /** @type {<T>(list: List<T>) => List<T>} */
219
221
  const cycle = list => () => {
220
222
  const i = next(list)
@@ -355,6 +357,8 @@ module.exports = {
355
357
  /** @readonly */
356
358
  countdown,
357
359
  /** @readonly */
360
+ repeat,
361
+ /** @readonly */
358
362
  cycle,
359
363
  /** @readonly */
360
364
  scan,
@@ -354,6 +354,16 @@ const stress = () => {
354
354
  }
355
355
  }
356
356
 
357
+ {
358
+ const s = _.join('.')(_.repeat('x')(0))
359
+ if (s != '') { throw s }
360
+ }
361
+
362
+ {
363
+ const s = _.join('.')(_.repeat('x')(5))
364
+ if (s != 'x.x.x.x.x') { throw s }
365
+ }
366
+
357
367
  // stress()
358
368
 
359
369
  module.exports = {
package/com/test.f.js DELETED
@@ -1,23 +0,0 @@
1
- const _ = require('./main.f.js')
2
-
3
- /** @type {_.Library} */
4
- const library = {
5
- Slice: {
6
- struct: [
7
- ['Start', { '*': 'u8' }],
8
- ['End', 'usize'],
9
- ]
10
- },
11
- IMy: {
12
- guid: 'C66FB270-2D80-49AD-BB6E-88C1F90B805D',
13
- interface: [
14
- ['GetSlice', [], ['Slice']],
15
- ['SetSlice',
16
- [['slice', ['Slice']]],
17
- ''
18
- ],
19
- ],
20
- }
21
- }
22
-
23
- module.exports = {}