functionalscript 0.0.0 → 0.0.126
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/node.js.yml +29 -29
- package/.github/workflows/npm-publish.yml +53 -0
- package/.vscode/launch.json +16 -16
- package/LICENSE +201 -201
- package/README.md +149 -149
- package/doc/README.md +79 -79
- package/index.js +82 -82
- package/lib/index.js +163 -163
- package/lib/iterable/index.js +33 -33
- package/lib/iterable/test.js +40 -40
- package/lib/test.js +12 -12
- package/module-manager/index.js +97 -97
- package/module-manager/node/index.js +18 -18
- package/module-manager/node/test.js +75 -75
- package/module-manager/test.js +123 -123
- package/package.json +3 -2
- package/test.js +58 -58
- package/tsconfig.json +100 -100
- package/version.js +16 -0
package/README.md
CHANGED
|
@@ -1,149 +1,149 @@
|
|
|
1
|
-
# FunctionalScript
|
|
2
|
-
|
|
3
|
-
FunctionalScript is a pure functional programming language and a subset of [ECMAScript](https://en.wikipedia.org/wiki/ECMAScript)/[JavaScript](https://en.wikipedia.org/wiki/JavaScript). It's inspired by
|
|
4
|
-
|
|
5
|
-
- [JSON](https://en.wikipedia.org/wiki/JSON), as a subset of JavaScript; FunctionalScript is a superset of JSON.
|
|
6
|
-
- [asm.JS](https://en.wikipedia.org/wiki/Asm.js)/[WebAssembly](https://en.wikipedia.org/wiki/WebAssembly), as a subset of JavaScript;
|
|
7
|
-
- [TypeScript](https://en.wikipedia.org/wiki/TypeScript), as a superset of JavaScript.
|
|
8
|
-
|
|
9
|
-
Try FunctionalScript [here](https://functionalscript.com/).
|
|
10
|
-
|
|
11
|
-
Create a new FunctionalScript repository on GitHub [here](https://github.com/functionalscript/template/generate).
|
|
12
|
-
|
|
13
|
-
## JSON
|
|
14
|
-
|
|
15
|
-
```js
|
|
16
|
-
jsonFile = expression
|
|
17
|
-
expression = primitive | array | objects
|
|
18
|
-
primitive = 'true' | 'false' | 'null' | number | string
|
|
19
|
-
array = '[' (() | items) ']'
|
|
20
|
-
items = expression (() | ',' items)
|
|
21
|
-
object = '{' (() | properties) '}'
|
|
22
|
-
properties = propertyId ':' expression (() | ',' properties)
|
|
23
|
-
propertyId = string
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Stage 0
|
|
27
|
-
|
|
28
|
-
This stage can be used as an intermediate-code for VMs.
|
|
29
|
-
|
|
30
|
-
```js
|
|
31
|
-
fjsFile = expression
|
|
32
|
-
expression = primitive | array | object | func | id | propertyAccessor
|
|
33
|
-
func = ('()' | id) '=>' body
|
|
34
|
-
body = '{' statements 'return' expression ';' '}'
|
|
35
|
-
statements = () | (statement statements)
|
|
36
|
-
statement = decl | ifStatement
|
|
37
|
-
decl = `const` id `=` expression `;`
|
|
38
|
-
ifStatement = `if` `(` expression `)` body
|
|
39
|
-
propertyAccessor = expression `[` expression `]`
|
|
40
|
-
call = expression `(` ( expression | ()) `)`
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Stage 0.1. Node.js
|
|
44
|
-
|
|
45
|
-
```js
|
|
46
|
-
nodeFile = statements 'module.exports' '=' expression ';'
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### Stage 0.2.
|
|
50
|
-
|
|
51
|
-
#### Operators
|
|
52
|
-
|
|
53
|
-
```js
|
|
54
|
-
expression = ... | 'undefined' | groupingOperator | binaryOperatorExpression | unaryOperator | conditionalOperator
|
|
55
|
-
groupingOperator = '(' expression ')'
|
|
56
|
-
binaryOperatorExpression = expression binaryOperator expression
|
|
57
|
-
binaryOperator = comparisonOperator | arithmeticOperator | bitwiseOperator | logicalOperators | '??'
|
|
58
|
-
comparisonBinaryOperator = '===' | '!==' | '>' | '<' | '>=' | '<='
|
|
59
|
-
arithmeticBinaryOperator = '+' | '-' | '*' | '/' | '%' | '**'
|
|
60
|
-
bitwiseBinaryOperator = '&' | '|' | '^' | '<<' | '>>' | '>>>'
|
|
61
|
-
logicalBinaryOperator = '&&' | '||'
|
|
62
|
-
unaryOperator = '-' | '~' | '!'
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Note: the syntax should be fixed to reflect operator precedents.
|
|
66
|
-
|
|
67
|
-
No `==`, `!=`, `=...` operators.
|
|
68
|
-
|
|
69
|
-
#### Function Expression
|
|
70
|
-
|
|
71
|
-
```js
|
|
72
|
-
func = ('()' | id) '=>' (('{' statements 'return' expression ';' '}') | expression)
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
#### PropertyAccessor
|
|
76
|
-
|
|
77
|
-
```js
|
|
78
|
-
propertyAccessor = expression (('[' expression ']') | ('.' id))
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
```js
|
|
82
|
-
propertyId = string | id
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
#### BigInt
|
|
86
|
-
|
|
87
|
-
For example `42n`.
|
|
88
|
-
|
|
89
|
-
#### Additional Operators
|
|
90
|
-
|
|
91
|
-
```js
|
|
92
|
-
typeOfOperator = 'typeof' expression
|
|
93
|
-
inOperator = expression 'in' expression
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Stage 0.3. Syntax sugar
|
|
97
|
-
|
|
98
|
-
Hex, binary and octal literals
|
|
99
|
-
Functions with multiple parameters.
|
|
100
|
-
Spread syntax. For example `...object`.
|
|
101
|
-
Destructing assignments. For example `const {a,b} = exp;`, `const [a, b] = exp`.
|
|
102
|
-
Property Id expression `{ [exp]: exp }`.
|
|
103
|
-
Allow no semicolons.
|
|
104
|
-
Optional comma in arrays and objects.
|
|
105
|
-
Template literals ``const r= `onst r = ${exp}`;``.
|
|
106
|
-
An `if` statement `if (exp) { ... return exp }`
|
|
107
|
-
Multiline strings
|
|
108
|
-
```js
|
|
109
|
-
'sss\
|
|
110
|
-
wwww'
|
|
111
|
-
```
|
|
112
|
-
Regular expressions.
|
|
113
|
-
|
|
114
|
-
## Stage 1
|
|
115
|
-
|
|
116
|
-
Typing using [JSDoc](https://jsdoc.app/) and TypeScript types.
|
|
117
|
-
|
|
118
|
-
## Stage 2
|
|
119
|
-
|
|
120
|
-
Mutable types with exclusive ownership (similar to Rust mutability).
|
|
121
|
-
|
|
122
|
-
- `let`, `for`, `while` etc.
|
|
123
|
-
Note: `let` can work as an object name reuse.
|
|
124
|
-
In this case, `let` objects can't be used in nested functions. It means we can't reference `let` object.
|
|
125
|
-
```js
|
|
126
|
-
let x = 5 // ok
|
|
127
|
-
f(x)
|
|
128
|
-
x = 'hello!' // ok
|
|
129
|
-
f(x)
|
|
130
|
-
const r = () => {
|
|
131
|
-
return x // compilation error
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
Translated into
|
|
135
|
-
```js
|
|
136
|
-
const x0 = 5
|
|
137
|
-
f(x0)
|
|
138
|
-
const x1 = 'hello!'
|
|
139
|
-
f(x1)
|
|
140
|
-
```
|
|
141
|
-
- Generators `function*(){ ... yield ... }`.
|
|
142
|
-
- Async `async () => f(await exp())`.
|
|
143
|
-
- hopefully, we will have [ES pipe operator](https://tc39.es/proposal-pipeline-operator/) at this time.
|
|
144
|
-
- [pattern matching](https://github.com/tc39/proposal-pattern-matching)
|
|
145
|
-
|
|
146
|
-
Controversial ideas:
|
|
147
|
-
|
|
148
|
-
- Import and export `import x from "..."`, `export const x = ...`, `export default = ` e.t.c. This may break `new Function` runners.
|
|
149
|
-
- Functional-TypeScript as a subset of TypeScript. Note: FunctionalScript doesn't require an additional build step in contrast to TypeScript.
|
|
1
|
+
# FunctionalScript
|
|
2
|
+
|
|
3
|
+
FunctionalScript is a pure functional programming language and a subset of [ECMAScript](https://en.wikipedia.org/wiki/ECMAScript)/[JavaScript](https://en.wikipedia.org/wiki/JavaScript). It's inspired by
|
|
4
|
+
|
|
5
|
+
- [JSON](https://en.wikipedia.org/wiki/JSON), as a subset of JavaScript; FunctionalScript is a superset of JSON.
|
|
6
|
+
- [asm.JS](https://en.wikipedia.org/wiki/Asm.js)/[WebAssembly](https://en.wikipedia.org/wiki/WebAssembly), as a subset of JavaScript;
|
|
7
|
+
- [TypeScript](https://en.wikipedia.org/wiki/TypeScript), as a superset of JavaScript.
|
|
8
|
+
|
|
9
|
+
Try FunctionalScript [here](https://functionalscript.com/).
|
|
10
|
+
|
|
11
|
+
Create a new FunctionalScript repository on GitHub [here](https://github.com/functionalscript/template/generate).
|
|
12
|
+
|
|
13
|
+
## JSON
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
jsonFile = expression
|
|
17
|
+
expression = primitive | array | objects
|
|
18
|
+
primitive = 'true' | 'false' | 'null' | number | string
|
|
19
|
+
array = '[' (() | items) ']'
|
|
20
|
+
items = expression (() | ',' items)
|
|
21
|
+
object = '{' (() | properties) '}'
|
|
22
|
+
properties = propertyId ':' expression (() | ',' properties)
|
|
23
|
+
propertyId = string
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Stage 0
|
|
27
|
+
|
|
28
|
+
This stage can be used as an intermediate-code for VMs.
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
fjsFile = expression
|
|
32
|
+
expression = primitive | array | object | func | id | propertyAccessor
|
|
33
|
+
func = ('()' | id) '=>' body
|
|
34
|
+
body = '{' statements 'return' expression ';' '}'
|
|
35
|
+
statements = () | (statement statements)
|
|
36
|
+
statement = decl | ifStatement
|
|
37
|
+
decl = `const` id `=` expression `;`
|
|
38
|
+
ifStatement = `if` `(` expression `)` body
|
|
39
|
+
propertyAccessor = expression `[` expression `]`
|
|
40
|
+
call = expression `(` ( expression | ()) `)`
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Stage 0.1. Node.js
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
nodeFile = statements 'module.exports' '=' expression ';'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Stage 0.2.
|
|
50
|
+
|
|
51
|
+
#### Operators
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
expression = ... | 'undefined' | groupingOperator | binaryOperatorExpression | unaryOperator | conditionalOperator
|
|
55
|
+
groupingOperator = '(' expression ')'
|
|
56
|
+
binaryOperatorExpression = expression binaryOperator expression
|
|
57
|
+
binaryOperator = comparisonOperator | arithmeticOperator | bitwiseOperator | logicalOperators | '??'
|
|
58
|
+
comparisonBinaryOperator = '===' | '!==' | '>' | '<' | '>=' | '<='
|
|
59
|
+
arithmeticBinaryOperator = '+' | '-' | '*' | '/' | '%' | '**'
|
|
60
|
+
bitwiseBinaryOperator = '&' | '|' | '^' | '<<' | '>>' | '>>>'
|
|
61
|
+
logicalBinaryOperator = '&&' | '||'
|
|
62
|
+
unaryOperator = '-' | '~' | '!'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Note: the syntax should be fixed to reflect operator precedents.
|
|
66
|
+
|
|
67
|
+
No `==`, `!=`, `=...` operators.
|
|
68
|
+
|
|
69
|
+
#### Function Expression
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
func = ('()' | id) '=>' (('{' statements 'return' expression ';' '}') | expression)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### PropertyAccessor
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
propertyAccessor = expression (('[' expression ']') | ('.' id))
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
propertyId = string | id
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### BigInt
|
|
86
|
+
|
|
87
|
+
For example `42n`.
|
|
88
|
+
|
|
89
|
+
#### Additional Operators
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
typeOfOperator = 'typeof' expression
|
|
93
|
+
inOperator = expression 'in' expression
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Stage 0.3. Syntax sugar
|
|
97
|
+
|
|
98
|
+
Hex, binary and octal literals
|
|
99
|
+
Functions with multiple parameters.
|
|
100
|
+
Spread syntax. For example `...object`.
|
|
101
|
+
Destructing assignments. For example `const {a,b} = exp;`, `const [a, b] = exp`.
|
|
102
|
+
Property Id expression `{ [exp]: exp }`.
|
|
103
|
+
Allow no semicolons.
|
|
104
|
+
Optional comma in arrays and objects.
|
|
105
|
+
Template literals ``const r= `onst r = ${exp}`;``.
|
|
106
|
+
An `if` statement `if (exp) { ... return exp }`
|
|
107
|
+
Multiline strings
|
|
108
|
+
```js
|
|
109
|
+
'sss\
|
|
110
|
+
wwww'
|
|
111
|
+
```
|
|
112
|
+
Regular expressions.
|
|
113
|
+
|
|
114
|
+
## Stage 1
|
|
115
|
+
|
|
116
|
+
Typing using [JSDoc](https://jsdoc.app/) and TypeScript types.
|
|
117
|
+
|
|
118
|
+
## Stage 2
|
|
119
|
+
|
|
120
|
+
Mutable types with exclusive ownership (similar to Rust mutability).
|
|
121
|
+
|
|
122
|
+
- `let`, `for`, `while` etc.
|
|
123
|
+
Note: `let` can work as an object name reuse.
|
|
124
|
+
In this case, `let` objects can't be used in nested functions. It means we can't reference `let` object.
|
|
125
|
+
```js
|
|
126
|
+
let x = 5 // ok
|
|
127
|
+
f(x)
|
|
128
|
+
x = 'hello!' // ok
|
|
129
|
+
f(x)
|
|
130
|
+
const r = () => {
|
|
131
|
+
return x // compilation error
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
Translated into
|
|
135
|
+
```js
|
|
136
|
+
const x0 = 5
|
|
137
|
+
f(x0)
|
|
138
|
+
const x1 = 'hello!'
|
|
139
|
+
f(x1)
|
|
140
|
+
```
|
|
141
|
+
- Generators `function*(){ ... yield ... }`.
|
|
142
|
+
- Async `async () => f(await exp())`.
|
|
143
|
+
- hopefully, we will have [ES pipe operator](https://tc39.es/proposal-pipeline-operator/) at this time.
|
|
144
|
+
- [pattern matching](https://github.com/tc39/proposal-pattern-matching)
|
|
145
|
+
|
|
146
|
+
Controversial ideas:
|
|
147
|
+
|
|
148
|
+
- Import and export `import x from "..."`, `export const x = ...`, `export default = ` e.t.c. This may break `new Function` runners.
|
|
149
|
+
- Functional-TypeScript as a subset of TypeScript. Note: FunctionalScript doesn't require an additional build step in contrast to TypeScript.
|
package/doc/README.md
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
# Documentation
|
|
2
|
-
|
|
3
|
-
## 1. Creating a New Repository
|
|
4
|
-
|
|
5
|
-
Creating from a template https://github.com/functionalscript/template/generate
|
|
6
|
-
|
|
7
|
-
## 1.1. Creating From Scratch
|
|
8
|
-
|
|
9
|
-
Prerequisites:
|
|
10
|
-
|
|
11
|
-
- [Git](https://git-scm.com/).
|
|
12
|
-
- [Node.js](https://nodejs.org/en/).
|
|
13
|
-
- GitHub account.
|
|
14
|
-
|
|
15
|
-
Creating a new GitHub repository
|
|
16
|
-
|
|
17
|
-
1. Create a public git repository on GitHub using Node template.
|
|
18
|
-
2. Clone the repository.
|
|
19
|
-
3. Go to the root directory of the cloned repository.
|
|
20
|
-
4. Run `npm init`. It should create `package.json` file.
|
|
21
|
-
5. Create an `index.js` file in the repository root directory.
|
|
22
|
-
6. Edit the `index.js` file. For example
|
|
23
|
-
```js
|
|
24
|
-
module.exports = "Hello world!"
|
|
25
|
-
```
|
|
26
|
-
11. Go to [functionalscript.com](https://functionalscript.com) and enter `github:YOUR_GITHUB_NAME/YOUR_REPOSITORY_NAME`. Press `Build`.
|
|
27
|
-
|
|
28
|
-
### 1.1. Optional
|
|
29
|
-
|
|
30
|
-
1. Install [Visual Studio Code](https://code.visualstudio.com/).
|
|
31
|
-
2. Add [TypeScript](https://www.typescriptlang.org/) to your repository for static type checking.
|
|
32
|
-
1. Run `npm install -D typescript`.
|
|
33
|
-
2. Run `npx tsc --init`. It should create `tsconfig.json` file.
|
|
34
|
-
3. Uncomment `"allowJs": true,` and `"checkJs": true` in the `tsconfig.json` file.
|
|
35
|
-
|
|
36
|
-
## 2. Language
|
|
37
|
-
|
|
38
|
-
### 2.1. Exports
|
|
39
|
-
|
|
40
|
-
```js
|
|
41
|
-
module.exports = 'Hello world!
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
```js
|
|
45
|
-
module.exports = { a: 'hello', b: 42 }
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
```js
|
|
49
|
-
module.exports = x => x * x
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### 2.2. Reference Another Module
|
|
53
|
-
|
|
54
|
-
#### 2.2.1. Local File
|
|
55
|
-
|
|
56
|
-
```js
|
|
57
|
-
const x = require('./folder/index.js')
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 2.2.2. External Module
|
|
61
|
-
|
|
62
|
-
Run `npm install -D github:REPO/PACKAGE`
|
|
63
|
-
|
|
64
|
-
```js
|
|
65
|
-
const x = require(`PACKAGE/DIR/FILE.js`)
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### 2.3. Functions
|
|
69
|
-
|
|
70
|
-
```js
|
|
71
|
-
const f = x => x * x
|
|
72
|
-
const fResult = f(42)
|
|
73
|
-
|
|
74
|
-
const plus = a => b => a + b
|
|
75
|
-
const plusResult = plus(a)(b)
|
|
76
|
-
|
|
77
|
-
const sum = ar => ar.reduce((a, i) => a + i, 0)
|
|
78
|
-
const sumResult = sum([1, 2, 3])
|
|
79
|
-
```
|
|
1
|
+
# Documentation
|
|
2
|
+
|
|
3
|
+
## 1. Creating a New Repository
|
|
4
|
+
|
|
5
|
+
Creating from a template https://github.com/functionalscript/template/generate
|
|
6
|
+
|
|
7
|
+
## 1.1. Creating From Scratch
|
|
8
|
+
|
|
9
|
+
Prerequisites:
|
|
10
|
+
|
|
11
|
+
- [Git](https://git-scm.com/).
|
|
12
|
+
- [Node.js](https://nodejs.org/en/).
|
|
13
|
+
- GitHub account.
|
|
14
|
+
|
|
15
|
+
Creating a new GitHub repository
|
|
16
|
+
|
|
17
|
+
1. Create a public git repository on GitHub using Node template.
|
|
18
|
+
2. Clone the repository.
|
|
19
|
+
3. Go to the root directory of the cloned repository.
|
|
20
|
+
4. Run `npm init`. It should create `package.json` file.
|
|
21
|
+
5. Create an `index.js` file in the repository root directory.
|
|
22
|
+
6. Edit the `index.js` file. For example
|
|
23
|
+
```js
|
|
24
|
+
module.exports = "Hello world!"
|
|
25
|
+
```
|
|
26
|
+
11. Go to [functionalscript.com](https://functionalscript.com) and enter `github:YOUR_GITHUB_NAME/YOUR_REPOSITORY_NAME`. Press `Build`.
|
|
27
|
+
|
|
28
|
+
### 1.1. Optional
|
|
29
|
+
|
|
30
|
+
1. Install [Visual Studio Code](https://code.visualstudio.com/).
|
|
31
|
+
2. Add [TypeScript](https://www.typescriptlang.org/) to your repository for static type checking.
|
|
32
|
+
1. Run `npm install -D typescript`.
|
|
33
|
+
2. Run `npx tsc --init`. It should create `tsconfig.json` file.
|
|
34
|
+
3. Uncomment `"allowJs": true,` and `"checkJs": true` in the `tsconfig.json` file.
|
|
35
|
+
|
|
36
|
+
## 2. Language
|
|
37
|
+
|
|
38
|
+
### 2.1. Exports
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
module.exports = 'Hello world!
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
module.exports = { a: 'hello', b: 42 }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
module.exports = x => x * x
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2.2. Reference Another Module
|
|
53
|
+
|
|
54
|
+
#### 2.2.1. Local File
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
const x = require('./folder/index.js')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2.2.2. External Module
|
|
61
|
+
|
|
62
|
+
Run `npm install -D github:REPO/PACKAGE`
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
const x = require(`PACKAGE/DIR/FILE.js`)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 2.3. Functions
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
const f = x => x * x
|
|
72
|
+
const fResult = f(42)
|
|
73
|
+
|
|
74
|
+
const plus = a => b => a + b
|
|
75
|
+
const plusResult = plus(a)(b)
|
|
76
|
+
|
|
77
|
+
const sum = ar => ar.reduce((a, i) => a + i, 0)
|
|
78
|
+
const sumResult = sum([1, 2, 3])
|
|
79
|
+
```
|
package/index.js
CHANGED
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const lib = require('./lib')
|
|
4
|
-
|
|
5
|
-
const todo = () => lib.panic('not implemented')
|
|
6
|
-
|
|
7
|
-
/** @type {<F>(c: string, found: (before: string, after: string) => F, notFound: (c: string, source: string) => F) => (source: string) => F} */
|
|
8
|
-
const splitOne = (c, found, notFound) => source => {
|
|
9
|
-
const i = source.indexOf(c)
|
|
10
|
-
return i !== -1 ? found(source.substring(0, i), source.substring(i + 1)) : notFound(c, source)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/** @type {<T>(f: (_: T) => boolean) => (_: Iterable<T>) => boolean} */
|
|
14
|
-
const every = f => i => {
|
|
15
|
-
for (let e of i) {
|
|
16
|
-
if (!f(e)) {
|
|
17
|
-
return false
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return true
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** @typedef {{org: string, name: string}} RepoId */
|
|
24
|
-
/** @typedef {{repo: RepoId}} ModuleRepoId */
|
|
25
|
-
/** @typedef {{repo: RepoId, branch: string}} ModuleRepoBranchId */
|
|
26
|
-
/** @typedef {{repo: RepoId, commit: string}} ModuleRepoCommitId */
|
|
27
|
-
/** @typedef {ModuleRepoId|ModuleRepoBranchId|ModuleRepoCommitId} ModuleId */
|
|
28
|
-
|
|
29
|
-
/** @typedef {(..._: string[]) => string} GetMsg */
|
|
30
|
-
/** @typedef {'expected'|'unknownProtocol'} ErrorId */
|
|
31
|
-
/** @typedef {{[_ in ErrorId]: GetMsg}} ErrorMap */
|
|
32
|
-
/** @typedef {{ id: ErrorId, params: string[]}} ErrorValue */
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @template T
|
|
36
|
-
* @typedef {<R>(v: (_: T) => R, e: (_: ErrorValue) => R) => R} Result
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
/** @type {<T>(_: T) => Result<T>} */
|
|
40
|
-
const value = v => vf => vf(v)
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @typedef {<R, T>(_: (_: T) => R, e: (_: ErrorValue) => R) => R} ErrorResult
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
/** @type {(e: ErrorValue) => ErrorResult} */
|
|
47
|
-
const error = e => (_, ef) => ef(e)
|
|
48
|
-
|
|
49
|
-
/** @type {(id: ErrorId) => (...params: string[]) => ErrorResult} */
|
|
50
|
-
const createError = id => (...params) => error({ id, params })
|
|
51
|
-
|
|
52
|
-
/** @type {(_: string) => Result<ModuleId>} */
|
|
53
|
-
const parseRepo = repo => {
|
|
54
|
-
const s = repo.split('/')
|
|
55
|
-
return s.length === 2 ? value({ repo: { org: s[0], name: s[1] } }) : createError('expected')('/', repo)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** @type {(_: string) => boolean} */
|
|
59
|
-
const isCommit = name => name.length === 40 && every(c => "0123456789ABCDEFabcdef".includes(c))(name)
|
|
60
|
-
|
|
61
|
-
/** @type {(repo: string, branch: string) => Result<ModuleId>} */
|
|
62
|
-
const parseRepoAndBranchCommit = (repo, branchCommit) =>
|
|
63
|
-
parseRepo(repo)(
|
|
64
|
-
({repo}) => value(isCommit(branchCommit) ? { repo, commit: branchCommit } : { repo, branch: branchCommit }),
|
|
65
|
-
error)
|
|
66
|
-
|
|
67
|
-
const parseGitHubId = splitOne('#', parseRepoAndBranchCommit, (_, repo) => parseRepo(repo))
|
|
68
|
-
|
|
69
|
-
/** @type {(protocol: string, id: string) => Result<ModuleId>} */
|
|
70
|
-
const parseProtocolAndId = (protocol, id) => protocol === 'github'
|
|
71
|
-
? parseGitHubId(id) : createError('unknownProtocol')(protocol)
|
|
72
|
-
|
|
73
|
-
module.exports = {
|
|
74
|
-
every,
|
|
75
|
-
isCommit,
|
|
76
|
-
parseModuleUrl: splitOne(':', parseProtocolAndId, createError('expected')),
|
|
77
|
-
/** @type {ErrorMap} */
|
|
78
|
-
errorMap: {
|
|
79
|
-
expected: (c, s) => `expected '${c}' in '${s}'`,
|
|
80
|
-
unknownProtocol: protocol => `unknown protocol '${protocol}'`,
|
|
81
|
-
},
|
|
82
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const lib = require('./lib')
|
|
4
|
+
|
|
5
|
+
const todo = () => lib.panic('not implemented')
|
|
6
|
+
|
|
7
|
+
/** @type {<F>(c: string, found: (before: string, after: string) => F, notFound: (c: string, source: string) => F) => (source: string) => F} */
|
|
8
|
+
const splitOne = (c, found, notFound) => source => {
|
|
9
|
+
const i = source.indexOf(c)
|
|
10
|
+
return i !== -1 ? found(source.substring(0, i), source.substring(i + 1)) : notFound(c, source)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** @type {<T>(f: (_: T) => boolean) => (_: Iterable<T>) => boolean} */
|
|
14
|
+
const every = f => i => {
|
|
15
|
+
for (let e of i) {
|
|
16
|
+
if (!f(e)) {
|
|
17
|
+
return false
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return true
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** @typedef {{org: string, name: string}} RepoId */
|
|
24
|
+
/** @typedef {{repo: RepoId}} ModuleRepoId */
|
|
25
|
+
/** @typedef {{repo: RepoId, branch: string}} ModuleRepoBranchId */
|
|
26
|
+
/** @typedef {{repo: RepoId, commit: string}} ModuleRepoCommitId */
|
|
27
|
+
/** @typedef {ModuleRepoId|ModuleRepoBranchId|ModuleRepoCommitId} ModuleId */
|
|
28
|
+
|
|
29
|
+
/** @typedef {(..._: string[]) => string} GetMsg */
|
|
30
|
+
/** @typedef {'expected'|'unknownProtocol'} ErrorId */
|
|
31
|
+
/** @typedef {{[_ in ErrorId]: GetMsg}} ErrorMap */
|
|
32
|
+
/** @typedef {{ id: ErrorId, params: string[]}} ErrorValue */
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @template T
|
|
36
|
+
* @typedef {<R>(v: (_: T) => R, e: (_: ErrorValue) => R) => R} Result
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/** @type {<T>(_: T) => Result<T>} */
|
|
40
|
+
const value = v => vf => vf(v)
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {<R, T>(_: (_: T) => R, e: (_: ErrorValue) => R) => R} ErrorResult
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/** @type {(e: ErrorValue) => ErrorResult} */
|
|
47
|
+
const error = e => (_, ef) => ef(e)
|
|
48
|
+
|
|
49
|
+
/** @type {(id: ErrorId) => (...params: string[]) => ErrorResult} */
|
|
50
|
+
const createError = id => (...params) => error({ id, params })
|
|
51
|
+
|
|
52
|
+
/** @type {(_: string) => Result<ModuleId>} */
|
|
53
|
+
const parseRepo = repo => {
|
|
54
|
+
const s = repo.split('/')
|
|
55
|
+
return s.length === 2 ? value({ repo: { org: s[0], name: s[1] } }) : createError('expected')('/', repo)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** @type {(_: string) => boolean} */
|
|
59
|
+
const isCommit = name => name.length === 40 && every(c => "0123456789ABCDEFabcdef".includes(c))(name)
|
|
60
|
+
|
|
61
|
+
/** @type {(repo: string, branch: string) => Result<ModuleId>} */
|
|
62
|
+
const parseRepoAndBranchCommit = (repo, branchCommit) =>
|
|
63
|
+
parseRepo(repo)(
|
|
64
|
+
({repo}) => value(isCommit(branchCommit) ? { repo, commit: branchCommit } : { repo, branch: branchCommit }),
|
|
65
|
+
error)
|
|
66
|
+
|
|
67
|
+
const parseGitHubId = splitOne('#', parseRepoAndBranchCommit, (_, repo) => parseRepo(repo))
|
|
68
|
+
|
|
69
|
+
/** @type {(protocol: string, id: string) => Result<ModuleId>} */
|
|
70
|
+
const parseProtocolAndId = (protocol, id) => protocol === 'github'
|
|
71
|
+
? parseGitHubId(id) : createError('unknownProtocol')(protocol)
|
|
72
|
+
|
|
73
|
+
module.exports = {
|
|
74
|
+
every,
|
|
75
|
+
isCommit,
|
|
76
|
+
parseModuleUrl: splitOne(':', parseProtocolAndId, createError('expected')),
|
|
77
|
+
/** @type {ErrorMap} */
|
|
78
|
+
errorMap: {
|
|
79
|
+
expected: (c, s) => `expected '${c}' in '${s}'`,
|
|
80
|
+
unknownProtocol: protocol => `unknown protocol '${protocol}'`,
|
|
81
|
+
},
|
|
82
|
+
}
|