functionalscript 0.1.600 → 0.1.601

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.
Files changed (39) hide show
  1. package/.github/workflows/npm-publish.yml +2 -0
  2. package/README.md +20 -9
  3. package/dev/module.mjs +20 -10
  4. package/dev/test/module.f.mjs +1 -1
  5. package/dev/test.mjs +3 -3
  6. package/djs/README.md +32 -8
  7. package/funding.json +61 -0
  8. package/issues/README.md +9 -5
  9. package/issues/djs.md +57 -0
  10. package/issues/fs-load.md +13 -0
  11. package/issues/lang/1000-json.md +12 -0
  12. package/issues/lang/2110-default-export.md +11 -0
  13. package/issues/lang/2120-const.md +14 -0
  14. package/issues/lang/2130-default-import.md +10 -0
  15. package/issues/lang/2210-block-comment.md +12 -0
  16. package/issues/lang/2220-namespace-import.md +25 -0
  17. package/issues/lang/2310-undefined.md +7 -0
  18. package/issues/lang/2320-bigint.md +7 -0
  19. package/issues/lang/2330-grouping.md +11 -0
  20. package/issues/lang/2340-operators.md +41 -0
  21. package/issues/lang/2351-property-accessor.md +44 -0
  22. package/issues/lang/2352-property-call.md +43 -0
  23. package/issues/lang/2353-property-at.md +19 -0
  24. package/issues/lang/2360-built-in.md +74 -0
  25. package/issues/lang/2410-identifier-property.md +9 -0
  26. package/issues/lang/2420-line-comment.md +10 -0
  27. package/issues/lang/2430-trailing-comma.md +13 -0
  28. package/issues/lang/2440-shorthand.md +8 -0
  29. package/issues/lang/2450-destructuring.md +12 -0
  30. package/issues/lang/3110-function.md +11 -0
  31. package/issues/lang/3120-parameters.md +9 -0
  32. package/issues/lang/3130-body-const.md +12 -0
  33. package/issues/lang/3220-let.md +11 -0
  34. package/issues/lang/3310-expression.md +12 -0
  35. package/issues/lang/3320-one-parameter.md +10 -0
  36. package/issues/lang/3330-assignments.md +23 -0
  37. package/issues/lang/README.md +80 -0
  38. package/jsr.json +116 -2
  39. package/package.json +1 -1
@@ -29,9 +29,11 @@ jobs:
29
29
  - run: npm run index
30
30
  - run: npm run tscp
31
31
  - run: npm publish
32
+ continue-on-error: true
32
33
  env:
33
34
  NODE_AUTH_TOKEN: ${{secrets.npm_token}}
34
35
  - run: deno publish --allow-dirty
36
+ continue-on-error: true
35
37
 
36
38
 
37
39
 
package/README.md CHANGED
@@ -12,11 +12,26 @@ FunctionalScript is a purely functional programming language and a strict subset
12
12
  as a subset of JavaScript.
13
13
  - [TypeScript](https://en.wikipedia.org/wiki/TypeScript), as a superset of JavaScript.
14
14
 
15
- [A brief description of FunctionalScript Programming Language](./doc/LANGUAGE.md).
15
+ [A working draft of the FunctionalScript specification](./issues/lang/README.md).
16
16
 
17
17
  Learn more about
18
- - [Purely Functional Programming in JavaScript](https://medium.com/@sergeyshandar/purely-functional-programming-in-javascript-91114b1b2dff),
19
- - [FunctionalScript and I/O](https://medium.com/@sergeyshandar/functionalscript-5cf817345376).
18
+ - [Purely Functional Programming in JavaScript](https://blog.bitsrc.io/purely-functional-programming-in-javascript-91114b1b2dff?sk=5f7132e56902f38fcf4c6164bfa681ed),
19
+ - [FunctionalScript and I/O](https://medium.com/@sergeyshandar/functionalscript-5cf817345376?sk=30b32189a81d1a2dad16c2244f32328d).
20
+
21
+ FunctionalScript is distributed under [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.en.html#license-text). Let us know if you need another license by sending an [email](mailto:sergey.oss@proton.me).
22
+
23
+ ## Vision
24
+
25
+ We aim to create a safe, cross-platform programming language that can work in any JS platform without any build step. There are thousands of programming languages, and we don't want to create another one that others must learn. Instead, we take the opposite approach: we remove everything that makes the most popular and cross-platform language unsafe, insecure, or less portable.
26
+
27
+ ## Applications
28
+
29
+ FunctionalScript code can be used:
30
+
31
+ - safely in any JavaScript/TypeScript application or library;
32
+ - as a JSON with expressions, see [DJS](https://medium.com/@sasha.gil/bridging-the-gap-from-json-to-javascript-without-dsls-fee273573f1b);
33
+ - as a query language,
34
+ - as a smart contract programming language in DeFi.
20
35
 
21
36
  ## Design Principles
22
37
 
@@ -27,13 +42,9 @@ In FunctionalScript:
27
42
  - A module can depend only on another FunctionalScript module.
28
43
  - It also has no standard library. Only a safe subset of standard JavaScript API can be used without referencing other modules.
29
44
 
30
- ## Applications
31
-
32
- FunctionalScript code can be used:
45
+ ## Our Next Step
33
46
 
34
- - in any JavaScript/TypeScript application,
35
- - as a JSON with expressions,
36
- - as a query language.
47
+ [Re-architecture of NaNVM](https://medium.com/@sergeyshandar/nanvm-re-architecture-8097f766ec1c?sk=d14ec1daf73ac5442f12ce20b2bc037a).
37
48
 
38
49
  ## Sponsors
39
50
 
package/dev/module.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { readdir, writeFile } from 'node:fs/promises'
1
+ import { readdir, writeFile, readFile } from 'node:fs/promises'
2
2
 
3
3
  /**
4
4
  * @typedef {{
@@ -66,12 +66,12 @@ export const exit = self.Deno ? self.Deno.exit : process.exit
66
66
  /** @type {(v: string) => string|undefined} */
67
67
  export const env =
68
68
  self.Deno ? self.Deno.env.get :
69
- a => {
70
- const r = Object.getOwnPropertyDescriptor(process.env, a)
71
- return r === void 0 ? void 0 :
72
- typeof r.get === 'function' ? r.get() :
73
- r.value
74
- }
69
+ a => {
70
+ const r = Object.getOwnPropertyDescriptor(process.env, a)
71
+ return r === void 0 ? void 0 :
72
+ typeof r.get === 'function' ? r.get() :
73
+ r.value
74
+ }
75
75
 
76
76
  export const loadModuleMap = async () => {
77
77
  /** @type {() => Promise<UnknownMap>} */
@@ -86,7 +86,7 @@ export const loadModuleMap = async () => {
86
86
  const file = `${p}/${name}`
87
87
  if (i.isDirectory()) {
88
88
  await f(file)
89
- } else if (name.endsWith('.f.cjs') || name.endsWith('.f.mjs')) {
89
+ } else if (name.endsWith('.f.cjs') || name.endsWith('.f.mjs') || name.endsWith('.f.js')) {
90
90
  const source = await import(`../${file}`)
91
91
  map.push([file, source.default])
92
92
  }
@@ -178,13 +178,23 @@ const codeAdd = i => p => m => {
178
178
  return [result, im]
179
179
  }
180
180
 
181
- export const index = async() => {
181
+ export const index = async () => {
182
+ {
183
+ const jj = './jsr.json'
184
+ const jsr_json = JSON.parse(await readFile(jj, { encoding: 'utf8' }))
185
+ const exports = Object.keys(await loadModuleMap())
186
+ await writeFile(
187
+ jj,
188
+ JSON.stringify({ ...jsr_json, exports }, null, 2))
189
+ }
190
+
191
+ //
182
192
  /** @type {FolderMap} */
183
193
  let m = {}
184
194
  for (const k in await loadModuleMap()) {
185
195
  const [, ...s] = k.split('/')
186
196
  switch (s[s.length - 1]) {
187
- case 'module.f.cjs': case 'module.f.mjs':
197
+ case 'module.f.cjs': case 'module.f.mjs': case 'module.f.js':
188
198
  m = folderMapAdd(m)(s)
189
199
  break
190
200
  }
@@ -46,7 +46,7 @@ import * as Result from '../../types/result/module.f.mjs'
46
46
  */
47
47
 
48
48
  /** @type {(s: string) => boolean} */
49
- const isTest = s => s.endsWith('test.f.cjs') || s.endsWith('test.f.mjs')
49
+ const isTest = s => s.endsWith('test.f.cjs') || s.endsWith('test.f.mjs') || s.endsWith('test.f.js')
50
50
 
51
51
  /**
52
52
  * @typedef {{
package/dev/test.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { loadModuleMap, exit, env } from './module.mjs'
2
+ import test from './test/module.f.mjs'
2
3
 
3
4
  /** @type {(f: (s: string) => void) => (s: string) => <T>(_: T) => T} */
4
5
  const anyLog = f => s => state => {
@@ -44,15 +45,14 @@ const measure = f => state => {
44
45
  const main = async() => {
45
46
  const moduleMap = await loadModuleMap()
46
47
 
47
- /** @type {any} */
48
- const f = moduleMap['./dev/test/module.f.mjs'].default
49
- const r = f({
48
+ const r = test({
50
49
  moduleMap,
51
50
  log: anyLog(console.log),
52
51
  error: anyLog(console.error),
53
52
  measure,
54
53
  tryCatch,
55
54
  env,
55
+ state: void 0,
56
56
  })
57
57
  exit(r[0])
58
58
  }
package/djs/README.md CHANGED
@@ -9,15 +9,31 @@
9
9
 
10
10
  ## Next steps
11
11
 
12
- - [ ] rename `fjson` to `djs` (data javascript), File extensions: `.d.cjs`, `.d.mjs`, `.d.js`.
12
+ - [ ] rename `fjson` to `djs` (data javascript), File extensions: `.d.mjs`, `.d.js`.
13
13
  - [x] use JS tokenizer
14
14
  - [x] identifiers `{a:5}`
15
15
  - [x] big int
16
- - [ ] `module.exports = ...`
17
- - [ ] constants `const a = [3];module.exports = { a: a, b: a }`. Serialization `const _0=[3];module.exports={a:_0,b:_0}`
18
- - [ ] import `const a = require('c.d.cjs');module.exports = { a: a, b: a}`
19
- - [ ] ES6 import `import a from 'c.d.mjs';export default { a: a, b: a}`
20
- - [ ] short form `const a = 5;module.exports = { a }`
16
+ - [ ] `export default ...`
17
+ - [ ] constants
18
+ ```js
19
+ const a = [3]
20
+ export default = { a: a, b: a }
21
+ ```
22
+ Serialization
23
+ ```js
24
+ const _0=[3]
25
+ export default {a:_0,b:_0}
26
+ ```
27
+ - [ ] import
28
+ ```js
29
+ import a from 'c.d.mjs'
30
+ export default { a: a, b: a}
31
+ ```
32
+ - [ ] short form
33
+ ```js
34
+ const a = 5;
35
+ export default { a }
36
+ ```
21
37
 
22
38
  Optional, for fun, syntax sugar:
23
39
 
@@ -26,5 +42,13 @@ Optional, for fun, syntax sugar:
26
42
 
27
43
  ## Decidable Language
28
44
 
29
- - [ ] using operator and functions `const a = 2+2+Math.abs(5); module.exports = { a: a };`
30
- - [ ] decidable functions `const f = a => b => a + b; module.exports = f(1)(2)`?
45
+ - [ ] using operator and functions
46
+ ```js
47
+ const a = 2+2+Math.abs(5)
48
+ export default { a: a }
49
+ ```
50
+ - [ ] decidable functions?
51
+ ```js
52
+ const f = a => b => a + b
53
+ export default f(1)(2)
54
+ ```
package/funding.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "version": "v1.0.0",
3
+ "entity": {
4
+ "type": "individual",
5
+ "role": "owner",
6
+ "name": "Sergey Shandar",
7
+ "email": "sergey.oss@proton.me",
8
+ "description": "Sergey is the main author of FunctionalScript, and other OSS projects related to content-addressable infrastructure",
9
+ "webpageUrl": {
10
+ "url": "https://github.com/functionalscript/functionalscript"
11
+ }
12
+ },
13
+ "projects": [
14
+ {
15
+ "guid": "functionalscript",
16
+ "name": "FunctionalScript",
17
+ "description": "FunctionalScript is a purely functional safe subset of JavaScript",
18
+ "webpageUrl": {
19
+ "url": "https://github.com/functionalscript/functionalscript"
20
+ },
21
+ "repositoryUrl": {
22
+ "url": "https://github.com/functionalscript/functionalscript"
23
+ },
24
+ "licenses": [
25
+ "spdx:AGPL-3.0-only"
26
+ ],
27
+ "tags": [
28
+ "programming",
29
+ "web-development",
30
+ "software-engineering",
31
+ "developer-tools",
32
+ "programming-language",
33
+ "cryptography",
34
+ "smart-contract"
35
+ ]
36
+ }
37
+ ],
38
+ "funding": {
39
+ "channels": [
40
+ {
41
+ "guid": "github",
42
+ "type": "other",
43
+ "address": "https://github.com/sponsors/sergey-shandar"
44
+ }
45
+ ],
46
+ "plans": [
47
+ {
48
+ "guid": "nanvm",
49
+ "status": "active",
50
+ "name": "NaNVM",
51
+ "description": "NaNVM is a virtual machine for the FunctionalScript",
52
+ "amount": 0,
53
+ "currency": "USD",
54
+ "frequency": "one-time",
55
+ "channels": [
56
+ "github"
57
+ ]
58
+ }
59
+ ]
60
+ }
61
+ }
package/issues/README.md CHANGED
@@ -2,19 +2,23 @@
2
2
 
3
3
  1. [X] [test-debug](./test-debug.md).
4
4
  2. [X] [esm](./esm.md)
5
- 3. [ ] [publish](publish.md)
6
- 4. [ ] fix index generation by including sub modules `{ ...m, add: mAdd, remove: mRemove}`.
7
- 5. [ ] Conventions:
5
+ 3. [ ] [djs](./djs.md)
6
+ 4. [ ] VM Rust project
7
+ 5. [ ] [publish](publish.md)
8
+ 6. [ ] fix index generation by including sub modules `{ ...m, add: mAdd, remove: mRemove}`.
9
+ 7. [ ] Conventions:
8
10
  ```js
9
11
  import list, * as List from 'list.mjs'
10
12
  // list is for objects.
11
13
  // List is for types and should be ignored by FJS or errored if used in code.
12
14
  ```
13
- 6. [X] PoC: Replace `while` with recursive generators. **Result:** doesn't work.
14
- 7. Two sets of property filters:
15
+ 8. Move logic from `.mjs` files to `.f.mjs` files.
16
+ 9. Two sets of property filters:
15
17
  - usage `.b`:
16
18
  - `constructor`
17
19
  - ...
18
20
  - call `.b()`:
19
21
  - `push`
20
22
  - ...
23
+ 10. [ ] 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
24
+ 11. [ ] [fs-load](./fs-load.md)
package/issues/djs.md ADDED
@@ -0,0 +1,57 @@
1
+ # DJS
2
+
3
+ Parse this code
4
+
5
+ ```js
6
+ import a from 'c.d.mjs'
7
+ const c = [12, 'x']
8
+ export default { a: a, b: a, c: c}
9
+ ```
10
+
11
+ Into this structure:
12
+
13
+ ```ts
14
+ type Module = {
15
+ modules: string[]
16
+ func: Func
17
+ }
18
+
19
+ // the last constant from the array is a return
20
+ type Func = Const[]
21
+
22
+ type Const = Primitive | CObject | CArray |CRef | ARef
23
+
24
+ type Primitive = number|string|boolean|null|bigint
25
+
26
+ type CRef = ['cref', number]
27
+
28
+ type ARef = ['aref', number]
29
+
30
+ type CObject = ['object', {
31
+ [k in string]: Const
32
+ }]
33
+
34
+ type CArray = ['array', [Const]]
35
+ ```
36
+
37
+ Where `func` is a description of the function:
38
+
39
+ ```js
40
+ (...args) => {
41
+ const const0 = [12, 'x']
42
+ return { a: args[0], b: args[0], c: const0}
43
+ }
44
+ ```
45
+
46
+ ## Parsed Example
47
+
48
+ ```js
49
+ export default
50
+ // array of constants
51
+ [
52
+ // const const0
53
+ ['array', [12, 'x']],
54
+ // return
55
+ ['object', { 'a': ['aref', 0], 'b': ['aref', 0], c: ['cref', 0] }]
56
+ ]
57
+ ```
@@ -0,0 +1,13 @@
1
+ # FS VM load/save
2
+
3
+ sketch / mention future documentation on errors / exceptions and execution scheme in general, for example:
4
+
5
+ The host environment has well defined operations like 'Load' (takes a "root" module path, optional extra parameters), 'Execute' (takes the successful result of 'Load', optional extra parameters), 'Save' (takes the successful result of 'Load', optional extra parameters).
6
+
7
+ 'Load' time errors are communicated to the host environment (e.g. to output error diagnostics on the console). In presence of load time errors there is no successful result of 'Load', so there is nothing to pass to Execute, Save. However, it makes sense to have results of a partially successful 'Load' even though they cannot be used in 'Execute', 'Save' - for example, in language server protocol scenarios.
8
+
9
+ 'Save' corresponds to code / data transformations other than 'Execute', e.g. bundling. 'Save' time errors are communicated to the host environment. It might make sense to have results of a partially successful 'Save' (similarly to abovementioned scenarios for partially successful 'Load' results).
10
+
11
+ 'Execute' corresponds to calling the function that is the default export of the "root" module and that takes produces side effects on the environment. Execution ends with a halt caused either by the inner logic of the code (e.g. the root function successfully completes, or an unhandled error happens), or by external causes (e.g. the user stops the execution).
12
+
13
+ Now, does a proper FS system provide user code means to handle errors, e.g. an exception handling mechanism similar to JS's exception handling?
@@ -0,0 +1,12 @@
1
+ # JSON
2
+
3
+ JSON forms a tree of values.
4
+
5
+ ```json
6
+ {
7
+ "a": null,
8
+ "b": [-42.5, false, "hello"]
9
+ }
10
+ ```
11
+
12
+ File extension: `.json`.
@@ -0,0 +1,11 @@
1
+ # Default Export
2
+
3
+ Parse `export default` and then JSON. This's enough to have the same functionality as JSON.
4
+
5
+ ```js
6
+ export default 5
7
+ ```
8
+
9
+ Depends on [JSON](./1110-json.md)
10
+
11
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#using_the_default_export.
@@ -0,0 +1,14 @@
1
+ # Constants
2
+
3
+ This is enough to provide basic DJS graph and serialization.
4
+
5
+ ```js
6
+ const a = null
7
+ export default {
8
+ "a": a,
9
+ }
10
+ ```
11
+
12
+ Depends on [default-export](./2110-default-export.md).
13
+
14
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
@@ -0,0 +1,10 @@
1
+ # Default Import
2
+
3
+ ```js
4
+ import a from './a.d.mjs'
5
+ export default [a]
6
+ ```
7
+
8
+ Depends on [default-export](./2110-default-export.md).
9
+
10
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#default_import.
@@ -0,0 +1,12 @@
1
+ # Block Comment
2
+
3
+ We need it to declare JSDoc/TypeScript types.
4
+
5
+ ```js
6
+ /** @type {number} */
7
+ export default -42.5
8
+ ```
9
+
10
+ Depends on [default-export](./2110-default-export.md).
11
+
12
+ See <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#line_comments>
@@ -0,0 +1,25 @@
1
+ # Namespace Import
2
+
3
+ We need it to import types from other modules.
4
+
5
+ ```js
6
+ import * as A from './a.d.mjs'
7
+ /** @type {A.Type} */
8
+ export default [5]
9
+ ```
10
+
11
+ Where `./a.d.mjs` may look like this:
12
+
13
+ ```js
14
+ // this type can be used in other modules
15
+ /** @typedef {readonly [number]} Type */
16
+
17
+ // export nothing
18
+ export default null
19
+ ```
20
+
21
+ FunctionalScript should use namespace import only as a mechanism to reference type definitions. Since, VM doesn't analyze types, namespace import can be ignored be VM. However different linters, such as TypeScript, can use the information.
22
+
23
+ Depends on [default-import](./2110-default-export.md).
24
+
25
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#namespace_import
@@ -0,0 +1,7 @@
1
+ # Undefined Type
2
+
3
+ ```js
4
+ export default void 0
5
+ ```
6
+
7
+ Depend on [default-export](./2110-default-export.md).
@@ -0,0 +1,7 @@
1
+ # BigInt
2
+
3
+ ```js
4
+ export default 34n
5
+ ```
6
+
7
+ Depend on [default-export](./2110-default-export.md).
@@ -0,0 +1,11 @@
1
+ # Grouping
2
+
3
+ Group parts of an expression.
4
+
5
+ ```js
6
+ export default (5)
7
+ ```
8
+
9
+ Depends on [export-default](./2110-default-export.md).
10
+
11
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Grouping
@@ -0,0 +1,41 @@
1
+ # Operators
2
+
3
+ |Type |Operator |Priority |
4
+ |-----------|---------|-----------|
5
+ |Comparison |`==` |not allowed|
6
+ | |`!=` |not allowed|
7
+ | |`===` |1 |
8
+ | |`!==` |1 |
9
+ | |`>` |1 |
10
+ | |`>=` |1 |
11
+ | |`<` |1 |
12
+ | |`<=` |1 |
13
+ |Arithmetics|`+` |1 |
14
+ | |`-` |1 |
15
+ | |`*` |1 |
16
+ | |`/` |1 |
17
+ | |`%` |1 |
18
+ | |unary `-`|1 |
19
+ | |unary `+`|1 |
20
+ | |`**` |1 |
21
+ |Bitwise |`&` |1 |
22
+ | |`\|` |1 |
23
+ | |`^` |1 |
24
+ | |`~` |1 |
25
+ | |`<<` |1 |
26
+ | |`>>` |1 |
27
+ | |`>>>` |1 |
28
+ |Logical |`&&` |1 |
29
+ | |`\|\|` |1 |
30
+ | |`??` |1 |
31
+ | |`!` |1 |
32
+ |Conditional|`?:` |1 |
33
+ |Comma |`,` |not allowed|
34
+
35
+ [Comma operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_operator) is useful only when we want to mutate. We have only one case where we can mutate an object; it's [let](./3320-let.md), and we would like to keep it as simple as possible to track life-time. So, NO for the `,` comma operator.
36
+
37
+ Depends on [default-export](./2110-default-export.md) and [undefined](./2310-undefined.md).
38
+
39
+ For mutating operators, see [assignments](./3330-assignments.md).
40
+
41
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_operators
@@ -0,0 +1,44 @@
1
+ # Property Accessor
2
+
3
+ - `.`
4
+ - `?.`
5
+
6
+ FunctionalScript is a strict subset of JavaScript and should behave the same way as JavaScript or reject JS code during compilation as non-valid FS code. However, every object in JavaScript has inherited properties, such as [`constructor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) and [`__proto__`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto). These properties can cause side effects. For example:
7
+
8
+ ```js
9
+ const f = (() => {}).constructor
10
+ const g = f(`console.log('hello')`)
11
+ g() // we received direct access to I/O
12
+ ```
13
+
14
+ According to FunctionScript principles, an FS compiler should reject such code during compilation. So, the compiler will prohibit the use of `construct` and `__proto__` after `.` and `?.`.
15
+
16
+ If an object has its own properties with such names (e.g. `constructor`) then we can access it using the [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor) function instead. The function doesn't return inherited properties.
17
+
18
+ ```js
19
+ const f = (() => {}).constructor
20
+ const g = Object.getOwnPropertyDescriptor(f, 'constructor') // g === undefined
21
+
22
+ const myObject = { constructor: 42 }
23
+ const c = Object.getOwnPropertyDescriptor(myObject, 'constructor').value // c === 42
24
+ ```
25
+
26
+ Here's the reason why we prohibit `__proto__`:
27
+
28
+ ```js
29
+ const p = (() => {}).__proto__
30
+ const f = Object.getOwnPropertyDescriptor(p, 'constructor').value
31
+ const g = f(`console.log('hello')`)
32
+ g() // side-effect
33
+ ```
34
+
35
+ ## Example
36
+
37
+ ```js
38
+ const a = { x: 3}
39
+ export default a.x
40
+ ```
41
+
42
+ Depends on [const](./2120-const.md), [default-import](./2130-default-import.md) and [undefined](./2310-undefined.md).
43
+
44
+ See <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors>.
@@ -0,0 +1,43 @@
1
+ # Function Call With Property Accessor
2
+
3
+ Operators `a.b()`, `a?.b()`.
4
+
5
+ ```js
6
+ const x = a.b(5)
7
+ ```
8
+
9
+ For `null?.b(x())`. We follow the same behavior as JS, so the `x` function will not be called.
10
+
11
+ Not allowed (additional to `constructor` and `__proto__`, see [property-accessor](./2351-property-accessor.md)):
12
+
13
+ - `__defineGetter__`
14
+ - `__defineSetter__`
15
+ - `__lookupGetter__`
16
+ - `__lookupSetter__`
17
+ - `isPrototypeOf` FS has no prototype concept because it has no inheritance.
18
+ - `toLocaleString` because it depends on the locale, which is a side-effect.
19
+
20
+ Also, from a function:
21
+
22
+ - `apply`
23
+ - `bind`
24
+ - `call`
25
+
26
+ Also, from an array:
27
+
28
+ - `copyWithin`
29
+ - `entries` - returns an iterator.
30
+ - `values` - returns an iterator.
31
+ - `keys` - returns an iterator.
32
+ - `pop`
33
+ - `push`
34
+ - `shift`
35
+ - `unshift`
36
+ - `sort`
37
+ - `reverse`
38
+
39
+ FunctionalScript doesn't allow direct access to iterators. An iterator can be mutated by `.next()` or `for()`. Indirect access to iterators is allowed through the `Iterable` interface. For example
40
+ ```js
41
+ for (const i of [1, 2]) { }
42
+ ```
43
+ In this example, the loop gets a temporary iterator from the iterable interface of `[1, 2]` then use it and discard it. A user can't have direct access to the iterator and can't make a copy of it.
@@ -0,0 +1,19 @@
1
+ # At
2
+
3
+ `a[42]`, `a['str']`, `a[+i]`.
4
+
5
+ ```js
6
+ import m from './m.f.mjs'
7
+ const a = [2, 3]
8
+ export default {
9
+ "a": a[0],
10
+ // we don't know what is the type of `m` so we force it to be a `number` or `bigint`.
11
+ "b": a[+m]
12
+ }
13
+ ```
14
+
15
+ In `a[i]`, `i` has to be a `number` or known `string`, which is not equal to prohibited words, see [property-accessor](./2351-property-accessor.md). If we don't know what is `i`, `+` requires before `i`.
16
+
17
+ It means that 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. In the future, FS may try deeper analyses and type inference can help a lot.
18
+
19
+ Depends on [property-accessor](./2351-property-accessor.md).
@@ -0,0 +1,74 @@
1
+ # Built-in Objects and Functions
2
+
3
+ The built-in objects are special. We can get a function, like `Object.getOwnPropertyDescriptor`, but not the `Object` itself.
4
+
5
+ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
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.
8
+
9
+ ## Object
10
+
11
+ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
12
+
13
+ Functions:
14
+
15
+ |Function |Priority |
16
+ |-------------------------|-----------|
17
+ |constructor |not allowed|
18
+ |assign |not allowed|
19
+ |create |not allowed|
20
+ |defineProperties |not allowed|
21
+ |defineProperty |not allowed|
22
+ |entries |1 |
23
+ |freeze |not allowed|
24
+ |fromEntries |1 |
25
+ |getOwnPropertyDescriptor |1 |
26
+ |getOwnPropertyDescriptors|1 |
27
+ |getOwnPropertyNames |1 |
28
+ |getOwnPropertySymbols |not allowed|
29
+ |getPrototypeOf |not allowed|
30
+ |groupBy |1 |
31
+ |hasOwn |1 |
32
+ |is |1 |
33
+ |isExtensible |not allowed|
34
+ |isFrozen |not allowed|
35
+ |isSealed |not allowed|
36
+ |keys |1 |
37
+ |preventExtensions |not allowed|
38
+ |seal |not allowed|
39
+ |setPrototypeOf |not allowed|
40
+ |values |1 |
41
+
42
+ ## Array
43
+
44
+ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
45
+
46
+ |Function |Priority |
47
+ |-------------------------|-----------|
48
+ |from |1 |
49
+ |fromAsync |1 |
50
+ |isArray |1 |
51
+ |of |1 |
52
+
53
+ ## BigInt
54
+
55
+ |Function |Priority |
56
+ |-------------------------|-----------|
57
+ |asIntN |1 |
58
+ |asUintN |1 |
59
+
60
+ ## JSON
61
+
62
+ |Function |Priority |
63
+ |-------------------------|-----------|
64
+ |`isRawJSON` |3 |
65
+ |`parse` |2 |
66
+ |`rawJSON` |3 |
67
+ |`stringify` |2 |
68
+
69
+ ## Others
70
+
71
+ `Infinity`
72
+ `isFinite()`
73
+ `isNaN()`
74
+ `NaN`
@@ -0,0 +1,9 @@
1
+ # Identifier Property
2
+
3
+ ```js
4
+ export default {
5
+ a: 'hello',
6
+ }
7
+ ```
8
+
9
+ Depends on [default-import](./2130-default-import.md).
@@ -0,0 +1,10 @@
1
+ # Line Comment
2
+
3
+ ```js
4
+ // this is an object
5
+ export default { "a": null }
6
+ ```
7
+
8
+ Depends on [export-default](./2110-default-export.md).
9
+
10
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#line_comments
@@ -0,0 +1,13 @@
1
+ # Trailing Comma
2
+
3
+ ```js
4
+ export default {
5
+ "b": [
6
+ "hello",
7
+ ],
8
+ }
9
+ ```
10
+
11
+ Depends on [default export](./2110-default-export.md).
12
+
13
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Trailing_commas
@@ -0,0 +1,8 @@
1
+ # Shorthand Property Names
2
+
3
+ ```js
4
+ const a = [null]
5
+ export default { a }
6
+ ```
7
+
8
+ Depends on [identifier-property](./2410-identifier-property.md).
@@ -0,0 +1,12 @@
1
+ # Destructuring Assignment
2
+
3
+ ```js
4
+ const { "a": a, "%": [c, d] } = { "a": null, "%": [true, false] }
5
+ export default {
6
+ "a": [a, c, d],
7
+ }
8
+ ```
9
+
10
+ Depends on [const](./2120-const.md) and [function parameters](./3120-parameters.md).
11
+
12
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment.
@@ -0,0 +1,11 @@
1
+ # Function
2
+
3
+ Parse a function that has no parameters and returns a constant.
4
+
5
+ ```js
6
+ export default () => { return 6 }
7
+ ```
8
+
9
+ Depends on [default export](./2110-default-export.md).
10
+
11
+ See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions.
@@ -0,0 +1,9 @@
1
+ # Function Parameters
2
+
3
+ Parse a function that has no parameters and returns a constant.
4
+
5
+ ```js
6
+ export default (a, b) => { return [a, b] }
7
+ ```
8
+
9
+ Depends on [function](./3110-function.md).
@@ -0,0 +1,12 @@
1
+ # Body Constants
2
+
3
+ Parse a const definition in a function body; a const can be used within that body after it is defined.
4
+
5
+ ```js
6
+ export default () => {
7
+ const x = 43
8
+ return [3, x]
9
+ }
10
+ ```
11
+
12
+ Depends on [function](./3110-function.md) and [const](./2120-const.md).
@@ -0,0 +1,11 @@
1
+ # Let statement
2
+
3
+ Introducing `let` and `=`.
4
+
5
+ ```js
6
+ export default () => {
7
+ let a = 0
8
+ a = 'Hello world!'
9
+ return a
10
+ }
11
+ ```
@@ -0,0 +1,12 @@
1
+ # Function Body
2
+
3
+ Parse a function with one expression.
4
+
5
+ ```js
6
+ export default {
7
+ "a": () => [3, 4],
8
+ "c": () => ({ "a": 5 })
9
+ }
10
+ ```
11
+
12
+ Depends on [function](./3110-function.md) and [grouping](2330-grouping.md)
@@ -0,0 +1,10 @@
1
+ # One Parameter
2
+
3
+ ```js
4
+ export default {
5
+ "id": a => a
6
+ "b": [-42.5, false, "hello"]
7
+ }
8
+ ```
9
+
10
+ Depends on [parameters](./3120-parameters.md).
@@ -0,0 +1,23 @@
1
+ # Additional Assignment Operators
2
+
3
+ These operators can be transformed into two operations in VM byte code.
4
+
5
+ |Type |Operator|Priority|
6
+ |-----------|--------|--------|
7
+ |Assignment |`+=` |2 |
8
+ | |`-=` |2 |
9
+ | |`*=` |2 |
10
+ | |`/=` |2 |
11
+ | |`%=` |2 |
12
+ | |`**=` |2 |
13
+ | |`<<=` |2 |
14
+ | |`>>=` |2 |
15
+ | |`>>>=` |2 |
16
+ | |`&=` |2 |
17
+ | |`^=` |2 |
18
+ | |`\|=` |2 |
19
+ | |`&&=` |2 |
20
+ | |`\|\|=` |2 |
21
+ | |`??=` |2 |
22
+ |Arithmetic |`++` |3 |
23
+ | |`--` |3 |
@@ -0,0 +1,80 @@
1
+ # FunctionalScript Language
2
+
3
+ When we implement features of FunctionalScript, the first priority is a simplification of the VM.
4
+
5
+ File Types:
6
+
7
+ |File Type|Extension |Notes |
8
+ |---------|-----------------|------------|
9
+ |JSON |`.json` |Not a graph.|
10
+ |DJS |`.d.js`, `.d.mjs`|A graph. |
11
+ |FJS |`.f.js`, `.f.mjs`|Functions. |
12
+
13
+ **Note**: An FJS value can't be serialized without additional run-time infrastructure.
14
+
15
+ ## 1. JSON
16
+
17
+ - [ ] [JSON](./1000-json.md).
18
+
19
+ ## 2. DJS
20
+
21
+ The DJS form a graph of values. It can be serialized without additional run-time information.
22
+
23
+ File extensions: `.d.js` and `.d.mjs`.
24
+
25
+ ### 2.1. Required
26
+
27
+ 1. [ ] [default-export](./2110-default-export.md)
28
+ 2. [ ] [const](./2120-const.md)
29
+ 3. [ ] [default-import](./2130-default-import.md)
30
+
31
+ ### 2.2. Priority 1
32
+
33
+ We need it to use JSDoc and TypeScript.
34
+
35
+ 1. [ ] [block-comment](./2210-block-comment.md)
36
+ 2. [ ] [namespace-import](./2220-namespace-import.md)
37
+
38
+ ### 2.3. Priority 2
39
+
40
+ 1. [ ] [undefined](./231-undefined.md)
41
+ 2. [ ] [bigint](./232-bigint.md)
42
+ 3. [ ] [grouping](./233-grouping.md)
43
+ 4. [ ] [operators](./234-operators.md)
44
+ 5. [ ] Property Accessors:
45
+ 1. [ ] [property-accessor](./2351-property-accessor.md)
46
+ 2. [ ] [property-call](./2352-property-call.md)
47
+ 3. [ ] [at](./2353-at.md)
48
+ 6. [ ] [global](./2360-built-in.md)
49
+
50
+ ### 2.4. Syntactic Sugar
51
+
52
+ 1. [ ] [identifier-property](./2410-identifier-property.md)
53
+ 2. [ ] [line-comment](./2420-line-comment.md)
54
+ 3. [ ] [trailing-comma](./2430-trailing-comma.md)
55
+ 4. [ ] [shorthand](./2440-shorthand.md)
56
+ 5. [ ] [destructuring](./2450-destructuring.md)
57
+
58
+ ## 3. FJS
59
+
60
+ The FJS can have functions. The format requires additional run-time information for serialization.
61
+
62
+ File extensions: `.f.js` and `.f.mjs`.
63
+
64
+ ### 3.1. Required
65
+
66
+ 1. [ ] [function](./3110-function.md)
67
+ 2. [ ] [parameters](./3120-parameters.md)
68
+ 3. [ ] [body-const](./3130-body-const.md)
69
+
70
+ ### 3.2. Priority 1
71
+
72
+ 1. [ ] `if`
73
+ 2. [ ] [let](./3220-let.md)
74
+ 3. [ ] `while`
75
+
76
+ ### 3.3. Syntactic Sugar
77
+
78
+ 1. [ ] [expression](./321-expression.md)
79
+ 2. [ ] [one-parameter](./322-one-parameter.md)
80
+ 3. [ ] [assignments](./3330-assignments.md)
package/jsr.json CHANGED
@@ -1,5 +1,119 @@
1
1
  {
2
2
  "name": "@functionalscript/functionalscript",
3
- "version": "0.1.600",
4
- "exports": "./index.f.mjs"
3
+ "version": "0.1.601",
4
+ "exports": [
5
+ "./com/cpp/module.f.mjs",
6
+ "./com/cpp/test.f.mjs",
7
+ "./com/cpp/testlib.f.mjs",
8
+ "./com/cs/module.f.mjs",
9
+ "./com/cs/test.f.mjs",
10
+ "./com/cs/testlib.f.mjs",
11
+ "./com/rust/module.f.mjs",
12
+ "./com/rust/test.f.mjs",
13
+ "./com/rust/testlib.f.mjs",
14
+ "./com/test/build.f.mjs",
15
+ "./com/types/module.f.mjs",
16
+ "./com/types/testlib.f.mjs",
17
+ "./commonjs/build/module.f.mjs",
18
+ "./commonjs/build/test.f.mjs",
19
+ "./commonjs/module.f.mjs",
20
+ "./commonjs/module/function/module.f.mjs",
21
+ "./commonjs/module/module.f.mjs",
22
+ "./commonjs/package/dependencies/module.f.mjs",
23
+ "./commonjs/package/dependencies/test.f.mjs",
24
+ "./commonjs/package/module.f.mjs",
25
+ "./commonjs/package/test.f.mjs",
26
+ "./commonjs/path/module.f.mjs",
27
+ "./commonjs/path/test.f.mjs",
28
+ "./dev/module.f.mjs",
29
+ "./dev/test.f.mjs",
30
+ "./dev/test/module.f.mjs",
31
+ "./djs/module.f.mjs",
32
+ "./djs/parser/module.f.mjs",
33
+ "./djs/parser/test.f.mjs",
34
+ "./djs/test.f.mjs",
35
+ "./djs/tokenizer/module.f.mjs",
36
+ "./djs/tokenizer/test.f.mjs",
37
+ "./fsc/module.f.mjs",
38
+ "./fsc/test.f.mjs",
39
+ "./fsm/module.f.mjs",
40
+ "./fsm/test.f.mjs",
41
+ "./html/module.f.mjs",
42
+ "./html/test.f.mjs",
43
+ "./index.f.mjs",
44
+ "./js/tokenizer/module.f.mjs",
45
+ "./js/tokenizer/test.f.mjs",
46
+ "./json/module.f.mjs",
47
+ "./json/parser/module.f.mjs",
48
+ "./json/parser/test.f.mjs",
49
+ "./json/serializer/module.f.mjs",
50
+ "./json/serializer/test.f.mjs",
51
+ "./json/test.f.mjs",
52
+ "./json/tokenizer/module.f.mjs",
53
+ "./json/tokenizer/test.f.mjs",
54
+ "./nodejs/version/module.f.mjs",
55
+ "./nodejs/version/test.f.mjs",
56
+ "./prime_field/module.f.mjs",
57
+ "./prime_field/test.f.mjs",
58
+ "./secp/module.f.mjs",
59
+ "./secp/test.f.mjs",
60
+ "./sha2/module.f.mjs",
61
+ "./sha2/test.f.mjs",
62
+ "./text/ascii/module.f.mjs",
63
+ "./text/ascii/test.f.mjs",
64
+ "./text/module.f.mjs",
65
+ "./text/sgr/module.f.mjs",
66
+ "./text/test.f.mjs",
67
+ "./text/utf16/module.f.mjs",
68
+ "./text/utf16/test.f.mjs",
69
+ "./text/utf8/module.f.mjs",
70
+ "./text/utf8/test.f.mjs",
71
+ "./types/array/module.f.mjs",
72
+ "./types/array/test.f.mjs",
73
+ "./types/bigfloat/module.f.mjs",
74
+ "./types/bigfloat/test.f.mjs",
75
+ "./types/bigint/module.f.mjs",
76
+ "./types/bigint/test.f.mjs",
77
+ "./types/btree/find/module.f.mjs",
78
+ "./types/btree/find/test.f.mjs",
79
+ "./types/btree/module.f.mjs",
80
+ "./types/btree/remove/module.f.mjs",
81
+ "./types/btree/remove/test.f.mjs",
82
+ "./types/btree/set/module.f.mjs",
83
+ "./types/btree/set/test.f.mjs",
84
+ "./types/btree/test.f.mjs",
85
+ "./types/btree/types/module.f.mjs",
86
+ "./types/byte_set/module.f.mjs",
87
+ "./types/byte_set/test.f.mjs",
88
+ "./types/function/compare/module.f.mjs",
89
+ "./types/function/compare/test.f.mjs",
90
+ "./types/function/module.f.mjs",
91
+ "./types/function/operator/module.f.mjs",
92
+ "./types/function/test.f.mjs",
93
+ "./types/list/module.f.mjs",
94
+ "./types/list/test.f.mjs",
95
+ "./types/map/module.f.mjs",
96
+ "./types/map/test.f.mjs",
97
+ "./types/nibble_set/module.f.mjs",
98
+ "./types/nibble_set/test.f.mjs",
99
+ "./types/nullable/module.f.mjs",
100
+ "./types/nullable/test.f.mjs",
101
+ "./types/number/module.f.mjs",
102
+ "./types/number/test.f.mjs",
103
+ "./types/object/module.f.mjs",
104
+ "./types/object/test.f.mjs",
105
+ "./types/range/module.f.mjs",
106
+ "./types/range/test.f.mjs",
107
+ "./types/range_map/module.f.mjs",
108
+ "./types/range_map/test.f.mjs",
109
+ "./types/result/module.f.mjs",
110
+ "./types/sorted_list/module.f.mjs",
111
+ "./types/sorted_list/test.f.mjs",
112
+ "./types/sorted_set/module.f.mjs",
113
+ "./types/sorted_set/test.f.mjs",
114
+ "./types/string/module.f.mjs",
115
+ "./types/string/test.f.mjs",
116
+ "./types/string_set/module.f.mjs",
117
+ "./types/string_set/test.f.mjs"
118
+ ]
5
119
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.1.600",
3
+ "version": "0.1.601",
4
4
  "type": "module",
5
5
  "description": "FunctionalScript is a functional subset of JavaScript",
6
6
  "main": "index.f.mjs",