functionalscript 0.1.607 → 0.1.609
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/CHANGELOG.md +10 -0
- package/Cargo.lock +4 -0
- package/Cargo.toml +4 -2
- package/README.md +1 -1
- package/com/rust/nanocom/src/cobject.rs +1 -1
- package/com/test/rust/src/lib.rs +4 -4
- package/dev/module.mjs +10 -33
- package/dev/test/module.f.mjs +1 -1
- package/djs/parser/module.f.d.mts +51 -31
- package/djs/parser/module.f.mjs +275 -122
- package/djs/parser/test.f.d.mts +4 -0
- package/djs/parser/test.f.mjs +179 -63
- package/djs/tokenizer/module.f.d.mts +1 -1
- package/djs/tokenizer/module.f.mjs +3 -1
- package/djs/tokenizer/test.f.mjs +1 -1
- package/doc/LANGUAGE.md +17 -16
- package/doc/README.md +14 -50
- package/fsc/README.md +0 -3
- package/fsm/README.md +1 -1
- package/html/README.md +24 -0
- package/issues/01-test-debug.md +3 -0
- package/issues/{publish.md → 05-publish.md} +8 -8
- package/issues/17-djs-extension.md +6 -0
- package/issues/README.md +20 -13
- package/issues/lang/1000-json.md +38 -0
- package/issues/lang/2110-default-export.md +2 -2
- package/issues/lang/2310-undefined.md +1 -1
- package/issues/lang/2330-property-accessor.md +225 -0
- package/issues/lang/2360-built-in.md +54 -47
- package/issues/lang/3240-export.md +44 -0
- package/issues/lang/README.md +64 -22
- package/issues/test.f.d.mts +16 -0
- package/issues/test.f.mjs +57 -0
- package/js/tokenizer/module.f.d.mts +8 -2
- package/js/tokenizer/module.f.mjs +29 -3
- package/js/tokenizer/test.f.mjs +9 -6
- package/json/tokenizer/module.f.mjs +2 -1
- package/jsr.json +1 -1
- package/nanvm-lib/Cargo.toml +6 -0
- package/nanvm-lib/src/extension.rs +119 -0
- package/nanvm-lib/src/interface.rs +136 -0
- package/nanvm-lib/src/lib.rs +7 -0
- package/nanvm-lib/src/naive.rs +229 -0
- package/nanvm-lib/src/nanenum.rs +230 -0
- package/nanvm-lib/src/nullish.rs +7 -0
- package/nanvm-lib/src/sign.rs +5 -0
- package/nanvm-lib/src/simple.rs +32 -0
- package/nanvm-lib/tests/test.f.d.mts +36 -0
- package/nanvm-lib/tests/test.f.mjs +79 -0
- package/nanvm-lib/tests/test.rs +108 -0
- package/package.json +1 -2
- package/text/README.md +2 -2
- package/index.f.d.mts +0 -83
- package/index.f.mjs +0 -83
- package/issues/lang/2351-property-accessor.md +0 -44
- package/issues/lang/2352-property-call.md +0 -43
- package/issues/lang/2353-property-at.md +0 -19
- package/issues/test-debug.md +0 -12
- /package/issues/{esm.md → 02-esm.md} +0 -0
- /package/issues/{djs.md → 03-djs.md} +0 -0
- /package/issues/{fs-load.md → 11-fs-load.md} +0 -0
- /package/issues/lang/{2330-grouping.md → 2350-grouping.md} +0 -0
package/doc/README.md
CHANGED
|
@@ -1,76 +1,40 @@
|
|
|
1
1
|
# Documentation
|
|
2
2
|
|
|
3
|
-
FunctionalScript files have `.f.
|
|
4
|
-
ESM support when we have the first parser working. See
|
|
5
|
-
[ESM. Resolver Algorithm Specification](https://nodejs.org/api/esm.html#resolver-algorithm-specification)
|
|
6
|
-
and [ESM. Enabling](https://nodejs.org/docs/latest-v13.x/api/esm.html#esm_enabling).
|
|
3
|
+
FunctionalScript files have `.f.mjs` file extensions because it's using the ES module system.
|
|
7
4
|
|
|
8
|
-
## 1.
|
|
5
|
+
## 1. Language
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
## 1.1. Creating From Scratch
|
|
13
|
-
|
|
14
|
-
Prerequisites:
|
|
15
|
-
|
|
16
|
-
- [Git](https://git-scm.com/).
|
|
17
|
-
- [Node.js](https://nodejs.org/en/).
|
|
18
|
-
- GitHub account.
|
|
19
|
-
|
|
20
|
-
Creating a new GitHub repository
|
|
21
|
-
|
|
22
|
-
1. Create a public git repository on GitHub using Node template.
|
|
23
|
-
2. Clone the repository.
|
|
24
|
-
3. Go to the root directory of the cloned repository.
|
|
25
|
-
4. Run `npm init`. It should create `package.json` file.
|
|
26
|
-
5. Create a `main.f.cjs` file in the repository root directory.
|
|
27
|
-
6. Edit the `main.f.cjs` file. For example
|
|
28
|
-
```js
|
|
29
|
-
module.exports = "Hello world!"
|
|
30
|
-
```
|
|
31
|
-
11. Go to [functionalscript.com](https://functionalscript.com) and enter `github:YOUR_GITHUB_NAME/YOUR_REPOSITORY_NAME`. Press `Build`.
|
|
32
|
-
|
|
33
|
-
### 1.1. Optional
|
|
34
|
-
|
|
35
|
-
1. Install [Visual Studio Code](https://code.visualstudio.com/).
|
|
36
|
-
2. Add [TypeScript](https://www.typescriptlang.org/) to your repository for static type checking.
|
|
37
|
-
1. Run `npm install -D typescript`.
|
|
38
|
-
2. Run `npx tsc --init`. It should create `tsconfig.json` file.
|
|
39
|
-
3. Uncomment `"allowJs": true,` and `"checkJs": true` in the `tsconfig.json` file.
|
|
40
|
-
|
|
41
|
-
## 2. Language
|
|
42
|
-
|
|
43
|
-
### 2.1. Exports
|
|
7
|
+
### 1.1. Exports
|
|
44
8
|
|
|
45
9
|
```js
|
|
46
|
-
|
|
10
|
+
export default 'Hello world!'
|
|
47
11
|
```
|
|
48
12
|
|
|
49
13
|
```js
|
|
50
|
-
|
|
14
|
+
export default { a: 'hello', b: 42 }
|
|
51
15
|
```
|
|
52
16
|
|
|
53
17
|
```js
|
|
54
|
-
|
|
18
|
+
export default x => x * x
|
|
55
19
|
```
|
|
56
20
|
|
|
57
|
-
###
|
|
21
|
+
### 1.2. Reference Another Module
|
|
58
22
|
|
|
59
|
-
####
|
|
23
|
+
#### 1.2.1. Local File
|
|
60
24
|
|
|
61
25
|
```js
|
|
62
|
-
|
|
26
|
+
import x from './folder/main.f.mjs'
|
|
63
27
|
```
|
|
64
28
|
|
|
65
|
-
###
|
|
29
|
+
### 1.2.2. External Module
|
|
66
30
|
|
|
67
31
|
Run `npm install -D github:USER/REPO`
|
|
68
32
|
|
|
69
33
|
```js
|
|
70
|
-
|
|
34
|
+
import x from `REPO/DIR/FILE.f.mjs`
|
|
71
35
|
```
|
|
72
36
|
|
|
73
|
-
###
|
|
37
|
+
### 1.3. Functions
|
|
74
38
|
|
|
75
39
|
```js
|
|
76
40
|
const f = x => x * x
|
|
@@ -83,9 +47,9 @@ const sum = ar => ar.reduce((a, i) => a + i, 0)
|
|
|
83
47
|
const sumResult = sum([1, 2, 3])
|
|
84
48
|
```
|
|
85
49
|
|
|
86
|
-
##
|
|
50
|
+
## 2. Advanced
|
|
87
51
|
|
|
88
|
-
###
|
|
52
|
+
### 2.1. Generators
|
|
89
53
|
|
|
90
54
|
```js
|
|
91
55
|
const range5 = {*[System.iterator]() {
|
package/fsc/README.md
CHANGED
|
@@ -76,7 +76,6 @@
|
|
|
76
76
|
- `do` ?
|
|
77
77
|
- `else`
|
|
78
78
|
- `export`
|
|
79
|
-
- `exports` <= non-standard
|
|
80
79
|
- `false`
|
|
81
80
|
- `function` ?
|
|
82
81
|
- `globalThis` ?
|
|
@@ -86,11 +85,9 @@
|
|
|
86
85
|
- `in`
|
|
87
86
|
- `instanceof`
|
|
88
87
|
- `let`
|
|
89
|
-
- `module` <= non-standard
|
|
90
88
|
- `new` ?
|
|
91
89
|
- `null`
|
|
92
90
|
- `of`
|
|
93
|
-
- `require` <= non-standard
|
|
94
91
|
- `return`
|
|
95
92
|
- `super`
|
|
96
93
|
- `switch`
|
package/fsm/README.md
CHANGED
|
@@ -107,7 +107,7 @@ const b = { ...a, z: 7 }
|
|
|
107
107
|
## How to Add a Property # 2
|
|
108
108
|
|
|
109
109
|
```js
|
|
110
|
-
|
|
110
|
+
import map from './types/map/module.f.mjs'
|
|
111
111
|
const a = map.fromEntries(Object.entries({ x: 5, y: 6 }))
|
|
112
112
|
const b = map.setReplace('z')(7)(a)
|
|
113
113
|
```
|
package/html/README.md
CHANGED
|
@@ -5,3 +5,27 @@
|
|
|
5
5
|
|`<br>` |`['br']` |
|
|
6
6
|
|`<img src="https://example.com/image.jpg">` |`['img',{src:'https://example.com/image.jpg'}]` |
|
|
7
7
|
|`<a href="https://example.com/">Example</a>`|`['a',{href:'https://example.com/'},['Example']]`|
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<html>
|
|
13
|
+
<head>
|
|
14
|
+
<title>Page</title>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
<a href="https://example.com/">Example</a>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
['html', [
|
|
24
|
+
['head', [
|
|
25
|
+
['title', ['Page']]
|
|
26
|
+
]]
|
|
27
|
+
['body', [
|
|
28
|
+
['a', { href: 'https://example.com/' }, ['Example']]
|
|
29
|
+
]]
|
|
30
|
+
]]
|
|
31
|
+
```
|
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
We are targeting the following systems:
|
|
4
4
|
|
|
5
5
|
- JS:
|
|
6
|
-
- NPM
|
|
7
|
-
- JSR
|
|
8
|
-
- https://esm.sh/ optional
|
|
6
|
+
- [X] NPM
|
|
7
|
+
- [X] JSR
|
|
8
|
+
- [ ] https://esm.sh/ optional
|
|
9
9
|
- Rust:
|
|
10
|
-
- https://crates.io/
|
|
10
|
+
- [ ] https://crates.io/
|
|
11
11
|
|
|
12
|
-
## Creating `./index.f.
|
|
12
|
+
## Creating `./index.f.mjs`
|
|
13
13
|
|
|
14
|
-
Currently, we regenerate [./index.f.
|
|
14
|
+
Currently, we regenerate [./index.f.mjs](./index.f.mjs) using `npm run index` during CD (publishing). However, we don't check in CI if it was regenerated. The idea is that CI should check if all generated files in Git are updated:
|
|
15
15
|
|
|
16
16
|
- [package.json](./package.json) `version` property
|
|
17
17
|
- [jsr.json](./jsr.json), `version` property
|
|
18
|
-
- [index.f.
|
|
18
|
+
- [index.f.mjs](./index.f.mjs)
|
|
19
19
|
|
|
20
20
|
`version` property should be `version` calculated on a `main` branch.
|
|
21
21
|
|
|
@@ -25,7 +25,7 @@ We may abandon the idea to publish on every commit on `main`. Instead, we will p
|
|
|
25
25
|
|
|
26
26
|
Before publishing, we have to be sure that
|
|
27
27
|
|
|
28
|
-
1. [index.f.
|
|
28
|
+
1. [index.f.mjs](./index.f.mjs) is up to date
|
|
29
29
|
2. `version` is updated in [jsr.json](./jsr.json) and [package.json](./package.json).
|
|
30
30
|
|
|
31
31
|
## CI Jobs
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# `.d.js` extension conflict
|
|
2
|
+
|
|
3
|
+
We use an extension `.d.js` for data JS files, but if we can't use it for TypeScript files, like `.d.ts` because it means declaration TypeScript files. There are several solutions to the problem:
|
|
4
|
+
|
|
5
|
+
1. Use only `.f.js` extension but make sure that `export default` has no functions at the end. In this case we can reference `.f.js` files as well to use functions to transform data (preferred).
|
|
6
|
+
2. Don't use it for TypeScript until we have type annotations in JavaScript.
|
package/issues/README.md
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
# Issues
|
|
2
2
|
|
|
3
|
-
1. [X] [test-debug](./test-debug.md).
|
|
4
|
-
2. [X] [esm](./esm.md)
|
|
5
|
-
3. [ ] [djs](./djs.md)
|
|
3
|
+
1. [X] [test-debug](./01-test-debug.md).
|
|
4
|
+
2. [X] [esm](./02-esm.md)
|
|
5
|
+
3. [ ] [djs](./03-djs.md)
|
|
6
6
|
4. [ ] VM Rust project
|
|
7
|
-
5. [ ] [publish](publish.md)
|
|
7
|
+
5. [ ] [publish](./05-publish.md)
|
|
8
8
|
6. [ ] fix index generation by including sub modules `{ ...m, add: mAdd, remove: mRemove}`.
|
|
9
9
|
7. [ ] Conventions:
|
|
10
|
+
|
|
10
11
|
```js
|
|
11
12
|
import list, * as List from 'list.mjs'
|
|
12
13
|
// list is for objects.
|
|
13
14
|
// List is for types and should be ignored by FJS or errored if used in code.
|
|
14
15
|
```
|
|
16
|
+
|
|
15
17
|
8. Move logic from `.mjs` files to `.f.mjs` files.
|
|
16
|
-
9.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
9. [ ] Generating a Website.
|
|
19
|
+
10. [ ] Short URL table.
|
|
20
|
+
11. [ ] [fs-load](./11-fs-load.md)
|
|
21
|
+
12. [ ] Replace file extensions from `.mjs` to `.js`. Make sure `package.json/type` is equal to `module`. May be later: https://v8.dev/features/modules#mjs
|
|
22
|
+
13. [ ] Docs for JSR. See https://jsr.io/@functionalscript/functionalscript/score
|
|
23
|
+
14. [ ] Combine `npm run index` and `npm run version`
|
|
24
|
+
15. [ ] Generate `package.json/exports` instead of `index.f.mjs`.
|
|
25
|
+
16. [ ] License in JSR file?
|
|
26
|
+
17. [ ] [djs-extension](./17-djs-extension.md).
|
|
27
|
+
18. [ ] Formatter for `.f.js` and `.f.ts` files.
|
|
28
|
+
19. [ ] Convert FunctionalScript code using non-default `export`.
|
|
29
|
+
20. [ ] Test framework should be able to run a subset of tests.
|
|
30
|
+
21. [ ] Test Framework silent mode. Show progress and failled tests only.
|
|
31
|
+
22. [ ] bit sequences based on bigint
|
package/issues/lang/1000-json.md
CHANGED
|
@@ -10,3 +10,41 @@ JSON forms a tree of values.
|
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
File extension: `.json`.
|
|
13
|
+
|
|
14
|
+
## NPN (Normal Polish Notation)
|
|
15
|
+
|
|
16
|
+
We will use [NPN](https://en.wikipedia.org/wiki/Polish_notation) as a command format for our VM because it allows us to allocate required objects during streaming as a stack automata.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
{2} "a" null "b" [3] -42.5 false "hello"
|
|
21
|
+
|
|
22
|
+
// evolution
|
|
23
|
+
<> {2} "a" null "b" [3] -42.5 false "hello"
|
|
24
|
+
{ ?: ?, ?: ? } <{4}> "a" null "b" [3] -42.5 false "hello"
|
|
25
|
+
{ "a": ?, ?: ? } <{3}> null "b" [3] -42.5 false "hello"
|
|
26
|
+
{ "a": null, ?: ? } <{2}> "b" [3] -42.5 false "hello"
|
|
27
|
+
{ "a": null, "b": ? } <{1}> [3] -42.5 false "hello"
|
|
28
|
+
{ "a": null, "b": [?, ?, ?] } <{0}[3]> -42.5 false "hello"
|
|
29
|
+
{ "a": null, "b": [-42.5, ?, ?] } <{0}[2]> false "hello"
|
|
30
|
+
{ "a": null, "b": [-42.5, false, ?] } <{0}[1]> "hello"
|
|
31
|
+
{ "a": null, "b": [-42.5, false, "hello"] } <>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## RPN, just for fun
|
|
35
|
+
|
|
36
|
+
[Reverse Polish Notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation):
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
"a" null "b" -42.5 false "hello" [3] {2}
|
|
40
|
+
|
|
41
|
+
// evolution:
|
|
42
|
+
"a" <> null "b" -42.5 false "hello" [3] {2}
|
|
43
|
+
"a" null <> "b" -42.5 false "hello" [3] {2}
|
|
44
|
+
"a" null "b" <> -42.5 false "hello" [3] {2}
|
|
45
|
+
"a" null "b" -42.5 <> false "hello" [3] {2}
|
|
46
|
+
"a" null "b" -42.5 false <> "hello" [3] {2}
|
|
47
|
+
"a" null "b" -42.5 false "hello" <> [3] {2}
|
|
48
|
+
"a" null "b" [-42.5, false, "hello"] <> {2}
|
|
49
|
+
{ "a" : null, "b": [-42.5, false, "hello"] } <>
|
|
50
|
+
```
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Default Export
|
|
2
2
|
|
|
3
|
-
Parse `export default` and then JSON. This
|
|
3
|
+
Parse `export default` and then JSON. This is enough to have the same functionality as JSON.
|
|
4
4
|
|
|
5
5
|
```js
|
|
6
6
|
export default 5
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Depends on [JSON](./
|
|
9
|
+
Depends on [JSON](./1000-json.md)
|
|
10
10
|
|
|
11
11
|
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#using_the_default_export.
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Get Property
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
const own_property = a => b => Object.getOwnPropertyDescriptor(obj, property)?.value
|
|
5
|
+
// Or
|
|
6
|
+
const own_property = a => b => Object.hasOwn(obj, property) ? obj[property] : void 0
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
It's translated into the VM command `own_property`:
|
|
10
|
+
|
|
11
|
+
```rust
|
|
12
|
+
struct OwnProperty {
|
|
13
|
+
obj: Expression
|
|
14
|
+
property: Expression
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Instance Property
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
obj.property
|
|
22
|
+
obj.['property']
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
It's translated into the VM command `instance_property`:
|
|
26
|
+
|
|
27
|
+
```rust
|
|
28
|
+
struct InstanceProperty {
|
|
29
|
+
obj: Expression
|
|
30
|
+
index: u8
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If the property name is one of the implemented property names, it should be translated into `index: u8`.
|
|
35
|
+
|
|
36
|
+
If a property name is one of the prohibited property names or one of the method names, then it's a compilation error.
|
|
37
|
+
|
|
38
|
+
All other property names generate `own_property` commands.
|
|
39
|
+
|
|
40
|
+
[Object Instance Properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#instance_properties),
|
|
41
|
+
|
|
42
|
+
|name |side-effect |
|
|
43
|
+
|-------------|------------------------------|
|
|
44
|
+
|`__proto__` |access to function constructor|
|
|
45
|
+
|`constructor`|access to function constructor|
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
const f = () => {}
|
|
49
|
+
{
|
|
50
|
+
const c = f.constructor
|
|
51
|
+
const g = c(`console.log('hello')`)
|
|
52
|
+
g() // side effect
|
|
53
|
+
}
|
|
54
|
+
{
|
|
55
|
+
const p = f.__proto__
|
|
56
|
+
const c = Object.getOwnPropertyDescriptor(p, 'constructor').value
|
|
57
|
+
const g = c(`console.log('hello')`)
|
|
58
|
+
g() // side-effect
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
[Array Instance Properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_properties).
|
|
63
|
+
|
|
64
|
+
| |name |side-effect|
|
|
65
|
+
|-|--------|-----------|
|
|
66
|
+
|0|`length`|no |
|
|
67
|
+
|
|
68
|
+
[Function Instance Properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function#instance_properties)
|
|
69
|
+
|
|
70
|
+
| |name |side-effect|run-time |
|
|
71
|
+
|-|-------------|-----------|---------|
|
|
72
|
+
| |`arguments` |no |error |
|
|
73
|
+
| |`caller` |no |error |
|
|
74
|
+
| |`displayName`|no | |
|
|
75
|
+
| |`name` |no |error |
|
|
76
|
+
| |`prototype` |no |undefined|
|
|
77
|
+
|
|
78
|
+
## Instance Method Call
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
obj.property(parameters)
|
|
82
|
+
obj.['property'](parameters)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
It's translated into VM command `instance_method_call`:
|
|
86
|
+
|
|
87
|
+
```rust
|
|
88
|
+
struct InstanceMethodCall {
|
|
89
|
+
obj: Expression
|
|
90
|
+
property: String16
|
|
91
|
+
parameters: Array<Expression>
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Note**: All known instance methods can't be used in `instance_property` command! Even if they don't have side effects.
|
|
96
|
+
|
|
97
|
+
[Object Instance Methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#instance_methods)
|
|
98
|
+
|
|
99
|
+
|name |side-effect |
|
|
100
|
+
|----------------------|----------------|
|
|
101
|
+
|`__defineGetter__` |mutate |
|
|
102
|
+
|`__defineSetter__` |mutate |
|
|
103
|
+
|`__lookupGetter__` |'__proto__' |
|
|
104
|
+
|`__lookupSetter__` |'__proto__' |
|
|
105
|
+
|`hasOwnProperty` |no |
|
|
106
|
+
|`isPrototypeOf` |no |
|
|
107
|
+
|`propertyIsEnumerable`|no |
|
|
108
|
+
|`toLocaleString` |access to locale|
|
|
109
|
+
|`toString` |no |
|
|
110
|
+
|`valueOf` |no |
|
|
111
|
+
|
|
112
|
+
[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods)
|
|
113
|
+
|
|
114
|
+
|name |side-effect|notes |
|
|
115
|
+
|----------------------|-----------|--------|
|
|
116
|
+
|`at` |no | |
|
|
117
|
+
|`concat` |no | |
|
|
118
|
+
|`copyWith` |no | |
|
|
119
|
+
|`entries` |yes |iterator|
|
|
120
|
+
|`every` |no | |
|
|
121
|
+
|`fill` |yes |mutate |
|
|
122
|
+
|`filter` |no | |
|
|
123
|
+
|`find` |no | |
|
|
124
|
+
|`findIndex` |no | |
|
|
125
|
+
|`findLast` |no | |
|
|
126
|
+
|`findLastIndex` |no | |
|
|
127
|
+
|`flat` |no | |
|
|
128
|
+
|`flatMap` |no | |
|
|
129
|
+
|`forEach` |no | |
|
|
130
|
+
|`includes` |no | |
|
|
131
|
+
|`indexOf` |no | |
|
|
132
|
+
|`join` |no | |
|
|
133
|
+
|`keys` |yes |iterator|
|
|
134
|
+
|`lastIndexOf` |no | |
|
|
135
|
+
|`map` |no | |
|
|
136
|
+
|`pop` |yes |mutate |
|
|
137
|
+
|`push` |yes |mutate |
|
|
138
|
+
|`reduce` |no | |
|
|
139
|
+
|`reduceRight` |no | |
|
|
140
|
+
|`reverse` |yes |mutate |
|
|
141
|
+
|`shift` |yes |mutate |
|
|
142
|
+
|`slice` |no | |
|
|
143
|
+
|`some` |no | |
|
|
144
|
+
|`sort` |yes |mutate |
|
|
145
|
+
|`splice` |yes |mutate |
|
|
146
|
+
|`toReversed` |no | |
|
|
147
|
+
|`toSorted` |no | |
|
|
148
|
+
|`toSpliced` |no | |
|
|
149
|
+
|`unshift` |yes |mutate |
|
|
150
|
+
|`values` |yes |iterator|
|
|
151
|
+
|`with` |no | |
|
|
152
|
+
|
|
153
|
+
[Function Instance Methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function#instance_methods)
|
|
154
|
+
|
|
155
|
+
|name |side-effect|notes |
|
|
156
|
+
|-------|-----------|-----------------|
|
|
157
|
+
|`apply`|no |`this` is ignored|
|
|
158
|
+
|`bind` |no |`this` is ignored|
|
|
159
|
+
|`call` |no |`this` is ignored|
|
|
160
|
+
|
|
161
|
+
## At
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
obj[42]
|
|
165
|
+
obj[+index]
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
It's translated into VM command `at`:
|
|
169
|
+
|
|
170
|
+
```rust
|
|
171
|
+
struct InstanceMethodCall {
|
|
172
|
+
obj: Expression
|
|
173
|
+
index: Expression
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
import m from './m.f.mjs'
|
|
179
|
+
const a = [2, 3]
|
|
180
|
+
export default {
|
|
181
|
+
"a": a[0],
|
|
182
|
+
// we don't know what is the type of `m` so we force it to be a `number` or `bigint`.
|
|
183
|
+
"b": a[+m]
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
In `obj[index]`, `index` has to be a `number`. If we don't know what is `index`, `+` requires before `index`. It means the byte code for the expression inside the `[]` should be either the unary `+`, a number literal, or a string literal (excluding some strings). If it references an object, FS gives up. FS may try deeper analyses in the future, and type inference can help a lot.
|
|
188
|
+
|
|
189
|
+
## Iterators
|
|
190
|
+
|
|
191
|
+
Direct access to an object with the [`Iterator` protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) is not allowed in FunctionalScript.
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
type Value<T> = { done: true } | { done?: false, value: T }
|
|
195
|
+
type Iterator<T> = {
|
|
196
|
+
next: () => Value<T>
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
However, FunctionalScript allows access to objects with the `Iterable` protocol.
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
type Iterable<T> = {
|
|
204
|
+
[Symbol.iterator]: () => Iterator<T>
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
For example, JS Array implements the `Iterable` protocol.
|
|
209
|
+
|
|
210
|
+
If we need to implement support for [generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator) in the FunctionalScript, the generator function has to be wrapped into `Iterable` interface. For example,
|
|
211
|
+
|
|
212
|
+
```js
|
|
213
|
+
// compilation error!
|
|
214
|
+
const iterator = *() {
|
|
215
|
+
yield 4
|
|
216
|
+
yield 2
|
|
217
|
+
}
|
|
218
|
+
// ok
|
|
219
|
+
const iterable = {
|
|
220
|
+
*[Symbol.iterator]() {
|
|
221
|
+
yield 4
|
|
222
|
+
yield 2
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
@@ -1,74 +1,81 @@
|
|
|
1
1
|
# Built-in Objects and Functions
|
|
2
2
|
|
|
3
|
-
The built-in objects are special. We can
|
|
3
|
+
The built-in objects are special. We can call a function, like `Object.getOwnPropertyDescriptor()`, but not the `Object` or the function.
|
|
4
4
|
|
|
5
5
|
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
|
|
6
6
|
|
|
7
|
-
Some of the JS built-in objects and functions are "not allowed" in FS. It means, an FS compiler rejects code that contains "not allowed" objects and functions.
|
|
7
|
+
Some of the JS built-in objects and functions are "not allowed" in FS. It means, an FS compiler rejects code that contains "not allowed" objects and functions.
|
|
8
8
|
|
|
9
9
|
## Object
|
|
10
10
|
|
|
11
11
|
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
|
16
|
-
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|seal |not allowed|
|
|
39
|
-
|setPrototypeOf |not allowed|
|
|
40
|
-
|values |1 |
|
|
13
|
+
|Function |side-effect |
|
|
14
|
+
|-------------------------|---------------------------|
|
|
15
|
+
|assign |mutate |
|
|
16
|
+
|create |creates a special prototype|
|
|
17
|
+
|defineProperties |mutate |
|
|
18
|
+
|defineProperty |mutate |
|
|
19
|
+
|entries |no |
|
|
20
|
+
|freeze |mutate |
|
|
21
|
+
|fromEntries |no |
|
|
22
|
+
|getOwnPropertyDescriptor |no |
|
|
23
|
+
|getOwnPropertyDescriptors|no |
|
|
24
|
+
|getOwnPropertyNames |no |
|
|
25
|
+
|getOwnPropertySymbols |return symbols |
|
|
26
|
+
|getPrototypeOf |return prototypes |
|
|
27
|
+
|groupBy |return null-property object|
|
|
28
|
+
|hasOwn |no |
|
|
29
|
+
|is |no |
|
|
30
|
+
|isExtensible |no |
|
|
31
|
+
|isFrozen |no |
|
|
32
|
+
|isSealed |no |
|
|
33
|
+
|keys |no |
|
|
34
|
+
|preventExtensions |mutate |
|
|
35
|
+
|seal |mutate |
|
|
36
|
+
|setPrototypeOf |mutate |
|
|
37
|
+
|values |no |
|
|
41
38
|
|
|
42
39
|
## Array
|
|
43
40
|
|
|
44
41
|
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
|
|
45
42
|
|
|
46
|
-
|Function |
|
|
43
|
+
|Function |side-effect|
|
|
47
44
|
|-------------------------|-----------|
|
|
48
|
-
|from |
|
|
49
|
-
|fromAsync
|
|
50
|
-
|isArray |
|
|
51
|
-
|of |
|
|
45
|
+
|from |no |
|
|
46
|
+
|fromAsync |? |
|
|
47
|
+
|isArray |no |
|
|
48
|
+
|of |no |
|
|
52
49
|
|
|
53
50
|
## BigInt
|
|
54
51
|
|
|
55
|
-
|Function |
|
|
52
|
+
|Function |side-effect|
|
|
56
53
|
|-------------------------|-----------|
|
|
57
|
-
|asIntN |
|
|
58
|
-
|asUintN |
|
|
54
|
+
|asIntN |no |
|
|
55
|
+
|asUintN |no |
|
|
59
56
|
|
|
60
57
|
## JSON
|
|
61
58
|
|
|
62
|
-
|Function |
|
|
59
|
+
|Function |side-effects|
|
|
63
60
|
|-------------------------|-----------|
|
|
64
|
-
|`isRawJSON` |
|
|
65
|
-
|`parse` |
|
|
66
|
-
|`rawJSON` |
|
|
67
|
-
|`stringify` |
|
|
61
|
+
|`isRawJSON` |no |
|
|
62
|
+
|`parse` |no |
|
|
63
|
+
|`rawJSON` |no |
|
|
64
|
+
|`stringify` |no |
|
|
68
65
|
|
|
69
66
|
## Others
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
`
|
|
68
|
+
|Function |side-effect|
|
|
69
|
+
|-------------------------|-----------|
|
|
70
|
+
|`decodeURI()` |no |
|
|
71
|
+
|`decodeURIComponent()` |no |
|
|
72
|
+
|`encodeURI()` |no |
|
|
73
|
+
|`encodeURIComponent()` |no |
|
|
74
|
+
|`eval()` |no |
|
|
75
|
+
|
|
76
|
+
|Property |side-effect|
|
|
77
|
+
|------------|-----------|
|
|
78
|
+
|`Infinity` |no |
|
|
79
|
+
|`isFinite()`|no |
|
|
80
|
+
|`isNaN()` |no |
|
|
81
|
+
|`NaN` |no |
|