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
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** @type {(a: unknown) => (b: unknown) => void} */
|
|
2
|
+
const e = a => b => {
|
|
3
|
+
if (a === b) { } else { throw [a, '===', b] }
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/** @type {(a: unknown) => (b: unknown) => void} */
|
|
7
|
+
const n = a => b => {
|
|
8
|
+
if (a !== b) { } else { throw [a, '!==', b] }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
eq: {
|
|
13
|
+
nullish: () => {
|
|
14
|
+
e(null)(null)
|
|
15
|
+
e(undefined)(undefined)
|
|
16
|
+
n(null)(undefined)
|
|
17
|
+
},
|
|
18
|
+
boolean: {
|
|
19
|
+
boolean: () => {
|
|
20
|
+
e(true)(true)
|
|
21
|
+
e(false)(false)
|
|
22
|
+
n(true)(false)
|
|
23
|
+
},
|
|
24
|
+
nullish: () => {
|
|
25
|
+
n(false)(undefined)
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
number: {
|
|
29
|
+
number: () => {
|
|
30
|
+
e(2.3)(2.3)
|
|
31
|
+
n(2.3)(-5.4)
|
|
32
|
+
n(NaN)(NaN)
|
|
33
|
+
e(0)(-0)
|
|
34
|
+
if (!Object.is(-0, -0)) { throw -0 }
|
|
35
|
+
if (Object.is(0, -0)) { throw -0 }
|
|
36
|
+
e(Infinity)(Infinity)
|
|
37
|
+
e(-Infinity)(-Infinity)
|
|
38
|
+
n(Infinity)(-Infinity)
|
|
39
|
+
},
|
|
40
|
+
nullish: () => {
|
|
41
|
+
n(undefined)(NaN)
|
|
42
|
+
n(undefined)(0)
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
string: {
|
|
46
|
+
string: () => {
|
|
47
|
+
e("hello")("hello")
|
|
48
|
+
n("hello")("world")
|
|
49
|
+
},
|
|
50
|
+
number: () => {
|
|
51
|
+
n(0)("0")
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
bigint: {
|
|
55
|
+
bigint: () => {
|
|
56
|
+
e(12n)(12n)
|
|
57
|
+
n(12n)(-12n)
|
|
58
|
+
n(12n)(13n)
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
array: {
|
|
62
|
+
array: () => {
|
|
63
|
+
/** @type {any} */
|
|
64
|
+
const a = []
|
|
65
|
+
e(a)(a)
|
|
66
|
+
n([])([])
|
|
67
|
+
const a0 = ['0']
|
|
68
|
+
e(a0)(a0)
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
object: {
|
|
72
|
+
object: () => {
|
|
73
|
+
const o = { '0': '0' }
|
|
74
|
+
e(o)(o)
|
|
75
|
+
n(o)({ '0': '0' })
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
use nanvm_lib::{interface::{Complex, Container, Extension, Any, Utf8}, naive, nullish::Nullish, sign::Sign, simple::Simple};
|
|
2
|
+
|
|
3
|
+
fn eq<A: Any>() {
|
|
4
|
+
// nullish
|
|
5
|
+
let null0: A = Simple::Nullish(Nullish::Null).to_unknown();
|
|
6
|
+
let null1 = Simple::Nullish(Nullish::Null).to_unknown();
|
|
7
|
+
let undefined0 = Simple::Nullish(Nullish::Undefined).to_unknown();
|
|
8
|
+
let undefined1 = Simple::Nullish(Nullish::Undefined).to_unknown();
|
|
9
|
+
{
|
|
10
|
+
assert_eq!(null0, null1);
|
|
11
|
+
assert_eq!(undefined0, undefined1);
|
|
12
|
+
assert_ne!(null1, undefined0);
|
|
13
|
+
}
|
|
14
|
+
// boolean
|
|
15
|
+
let true0: A = Simple::Boolean(true).to_unknown();
|
|
16
|
+
let true1 = Simple::Boolean(true).to_unknown();
|
|
17
|
+
let false0 = Simple::Boolean(false).to_unknown();
|
|
18
|
+
let false1 = Simple::Boolean(false).to_unknown();
|
|
19
|
+
{
|
|
20
|
+
// boolean
|
|
21
|
+
{
|
|
22
|
+
assert_eq!(true0, true1);
|
|
23
|
+
assert_eq!(false0, false1);
|
|
24
|
+
assert_ne!(true0, false0);
|
|
25
|
+
}
|
|
26
|
+
// nullish
|
|
27
|
+
{
|
|
28
|
+
assert_ne!(false0, undefined0);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// number
|
|
32
|
+
let number00: A = Simple::Number(2.3).to_unknown();
|
|
33
|
+
let number01: A = Simple::Number(2.3).to_unknown();
|
|
34
|
+
let number1: A = Simple::Number(-5.4).to_unknown();
|
|
35
|
+
let number_nan: A = Simple::Number(f64::NAN).to_unknown();
|
|
36
|
+
let number_p0: A = Simple::Number(0.0).to_unknown();
|
|
37
|
+
let number_n0: A = Simple::Number(-0.0).to_unknown();
|
|
38
|
+
let number_p_inf0: A = Simple::Number(f64::INFINITY).to_unknown();
|
|
39
|
+
let number_p_inf1: A = Simple::Number(f64::INFINITY).to_unknown();
|
|
40
|
+
let number_n_inf0: A = Simple::Number(-f64::INFINITY).to_unknown();
|
|
41
|
+
let number_n_inf1: A = Simple::Number(-f64::INFINITY).to_unknown();
|
|
42
|
+
{
|
|
43
|
+
// number
|
|
44
|
+
{
|
|
45
|
+
assert_eq!(number00, number01);
|
|
46
|
+
assert_ne!(number00, number1);
|
|
47
|
+
assert_ne!(number_nan, number_nan);
|
|
48
|
+
assert_eq!(number_p0, number_n0);
|
|
49
|
+
// Object.is()
|
|
50
|
+
assert_eq!((-0f64).to_bits(), (-0f64).to_bits());
|
|
51
|
+
assert_ne!(0f64.to_bits(), (-0f64).to_bits());
|
|
52
|
+
assert_eq!(number_p_inf0, number_p_inf1);
|
|
53
|
+
assert_eq!(number_n_inf0, number_n_inf1);
|
|
54
|
+
assert_ne!(number_p_inf0, number_n_inf0);
|
|
55
|
+
}
|
|
56
|
+
// nullish
|
|
57
|
+
{
|
|
58
|
+
assert_ne!(number_nan, undefined0);
|
|
59
|
+
assert_ne!(number00, undefined0);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// string
|
|
63
|
+
let string_hello0: A = "Hello!".to_unknown();
|
|
64
|
+
let string_hello1: A = "Hello!".to_unknown();
|
|
65
|
+
let string_world0: A = "world!".to_unknown();
|
|
66
|
+
let string0: A = "0".to_unknown();
|
|
67
|
+
let s0 = "0".to_string16::<A>();
|
|
68
|
+
{
|
|
69
|
+
{
|
|
70
|
+
assert_eq!(string_hello0, string_hello1);
|
|
71
|
+
assert_ne!(string_hello0, string_world0);
|
|
72
|
+
}
|
|
73
|
+
{
|
|
74
|
+
assert_ne!(number_p0, string0.clone());
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// bigint
|
|
78
|
+
let bigint12_0: A = A::BigInt::new(Sign::Positive, [12]).to_unknown();
|
|
79
|
+
let bigint12_1: A = A::BigInt::new(Sign::Positive, [12]).to_unknown();
|
|
80
|
+
let bigint12m: A = A::BigInt::new(Sign::Negative, [12]).to_unknown();
|
|
81
|
+
let bigint13: A = A::BigInt::new(Sign::Positive, [13]).to_unknown();
|
|
82
|
+
{
|
|
83
|
+
assert_eq!(bigint12_0, bigint12_1);
|
|
84
|
+
assert_ne!(bigint12_0, bigint12m);
|
|
85
|
+
assert_ne!(bigint12_0, bigint13);
|
|
86
|
+
}
|
|
87
|
+
// array
|
|
88
|
+
let array0: A = [].to_array_unknown();
|
|
89
|
+
let array1: A = [].to_array_unknown();
|
|
90
|
+
let array2: A = [string0.clone()].to_array_unknown();
|
|
91
|
+
{
|
|
92
|
+
assert_eq!(array0, array0);
|
|
93
|
+
assert_ne!(array0, array1);
|
|
94
|
+
assert_eq!(array2, array2);
|
|
95
|
+
}
|
|
96
|
+
// object
|
|
97
|
+
let object0: A = [(s0.clone(), string0.clone())].to_object_unknown();
|
|
98
|
+
let object1: A = [(s0, string0)].to_object_unknown();
|
|
99
|
+
{
|
|
100
|
+
assert_eq!(object0, object0);
|
|
101
|
+
assert_ne!(object0, object1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#[test]
|
|
106
|
+
fn naive_eq() {
|
|
107
|
+
eq::<naive::Any>();
|
|
108
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.609",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "FunctionalScript is a functional subset of JavaScript",
|
|
6
|
-
"main": "index.f.mjs",
|
|
7
6
|
"scripts": {
|
|
8
7
|
"tscp": "tsc --declaration --emitDeclarationOnly --noEmit false",
|
|
9
8
|
"tsc": "tsc",
|
package/text/README.md
CHANGED
|
@@ -34,7 +34,7 @@ Total error states:
|
|
|
34
34
|
- 34_432
|
|
35
35
|
- < 2^16
|
|
36
36
|
|
|
37
|
-
### utf8/module.f.
|
|
37
|
+
### utf8/module.f.mjs
|
|
38
38
|
|
|
39
39
|
```js
|
|
40
40
|
/** @type {(input: List<u8|null>) => List<i32>} */
|
|
@@ -69,7 +69,7 @@ Requirement: no loss for UTF16 => codepoint => UTF16
|
|
|
69
69
|
|
|
70
70
|
Total error states: 11 bit
|
|
71
71
|
|
|
72
|
-
### utf16/module.f.
|
|
72
|
+
### utf16/module.f.mjs
|
|
73
73
|
|
|
74
74
|
```js
|
|
75
75
|
/** @type {(input: List<u16|null>) => List<i32>} */
|
package/index.f.d.mts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
declare namespace _default {
|
|
2
|
-
export namespace com {
|
|
3
|
-
export { com$cpp as cpp };
|
|
4
|
-
export { com$cs as cs };
|
|
5
|
-
export { com$rust as rust };
|
|
6
|
-
export { com$types as types };
|
|
7
|
-
}
|
|
8
|
-
export { commonjs };
|
|
9
|
-
export { dev };
|
|
10
|
-
export { djs };
|
|
11
|
-
export { fsc };
|
|
12
|
-
export { fsm };
|
|
13
|
-
export { html };
|
|
14
|
-
export namespace js {
|
|
15
|
-
export { js$tokenizer as tokenizer };
|
|
16
|
-
}
|
|
17
|
-
export { json };
|
|
18
|
-
export namespace nodejs {
|
|
19
|
-
export { nodejs$version as version };
|
|
20
|
-
}
|
|
21
|
-
export { prime_field };
|
|
22
|
-
export { secp };
|
|
23
|
-
export { sha2 };
|
|
24
|
-
export { text };
|
|
25
|
-
export namespace types {
|
|
26
|
-
export { types$array as array };
|
|
27
|
-
export { types$bigfloat as bigfloat };
|
|
28
|
-
export { types$bigint as bigint };
|
|
29
|
-
export { types$btree as btree };
|
|
30
|
-
export { types$byte_set as byte_set };
|
|
31
|
-
export { types$function as function };
|
|
32
|
-
export { types$list as list };
|
|
33
|
-
export { types$map as map };
|
|
34
|
-
export { types$nibble_set as nibble_set };
|
|
35
|
-
export { types$nullable as nullable };
|
|
36
|
-
export { types$number as number };
|
|
37
|
-
export { types$object as object };
|
|
38
|
-
export { types$range as range };
|
|
39
|
-
export { types$range_map as range_map };
|
|
40
|
-
export { types$result as result };
|
|
41
|
-
export { types$sorted_list as sorted_list };
|
|
42
|
-
export { types$sorted_set as sorted_set };
|
|
43
|
-
export { types$string as string };
|
|
44
|
-
export { types$string_set as string_set };
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
export default _default;
|
|
48
|
-
import com$cpp from './com/cpp/module.f.mjs';
|
|
49
|
-
import com$cs from './com/cs/module.f.mjs';
|
|
50
|
-
import com$rust from './com/rust/module.f.mjs';
|
|
51
|
-
import com$types from './com/types/module.f.mjs';
|
|
52
|
-
import commonjs from './commonjs/module.f.mjs';
|
|
53
|
-
import dev from './dev/module.f.mjs';
|
|
54
|
-
import djs from './djs/module.f.mjs';
|
|
55
|
-
import fsc from './fsc/module.f.mjs';
|
|
56
|
-
import fsm from './fsm/module.f.mjs';
|
|
57
|
-
import html from './html/module.f.mjs';
|
|
58
|
-
import js$tokenizer from './js/tokenizer/module.f.mjs';
|
|
59
|
-
import json from './json/module.f.mjs';
|
|
60
|
-
import nodejs$version from './nodejs/version/module.f.mjs';
|
|
61
|
-
import prime_field from './prime_field/module.f.mjs';
|
|
62
|
-
import secp from './secp/module.f.mjs';
|
|
63
|
-
import sha2 from './sha2/module.f.mjs';
|
|
64
|
-
import text from './text/module.f.mjs';
|
|
65
|
-
import types$array from './types/array/module.f.mjs';
|
|
66
|
-
import types$bigfloat from './types/bigfloat/module.f.mjs';
|
|
67
|
-
import types$bigint from './types/bigint/module.f.mjs';
|
|
68
|
-
import types$btree from './types/btree/module.f.mjs';
|
|
69
|
-
import types$byte_set from './types/byte_set/module.f.mjs';
|
|
70
|
-
import types$function from './types/function/module.f.mjs';
|
|
71
|
-
import types$list from './types/list/module.f.mjs';
|
|
72
|
-
import types$map from './types/map/module.f.mjs';
|
|
73
|
-
import types$nibble_set from './types/nibble_set/module.f.mjs';
|
|
74
|
-
import types$nullable from './types/nullable/module.f.mjs';
|
|
75
|
-
import types$number from './types/number/module.f.mjs';
|
|
76
|
-
import types$object from './types/object/module.f.mjs';
|
|
77
|
-
import types$range from './types/range/module.f.mjs';
|
|
78
|
-
import types$range_map from './types/range_map/module.f.mjs';
|
|
79
|
-
import types$result from './types/result/module.f.mjs';
|
|
80
|
-
import types$sorted_list from './types/sorted_list/module.f.mjs';
|
|
81
|
-
import types$sorted_set from './types/sorted_set/module.f.mjs';
|
|
82
|
-
import types$string from './types/string/module.f.mjs';
|
|
83
|
-
import types$string_set from './types/string_set/module.f.mjs';
|
package/index.f.mjs
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
// Generated file.
|
|
2
|
-
import com$cpp from './com/cpp/module.f.mjs'
|
|
3
|
-
import com$cs from './com/cs/module.f.mjs'
|
|
4
|
-
import com$rust from './com/rust/module.f.mjs'
|
|
5
|
-
import com$types from './com/types/module.f.mjs'
|
|
6
|
-
import commonjs from './commonjs/module.f.mjs'
|
|
7
|
-
import dev from './dev/module.f.mjs'
|
|
8
|
-
import djs from './djs/module.f.mjs'
|
|
9
|
-
import fsc from './fsc/module.f.mjs'
|
|
10
|
-
import fsm from './fsm/module.f.mjs'
|
|
11
|
-
import html from './html/module.f.mjs'
|
|
12
|
-
import js$tokenizer from './js/tokenizer/module.f.mjs'
|
|
13
|
-
import json from './json/module.f.mjs'
|
|
14
|
-
import nodejs$version from './nodejs/version/module.f.mjs'
|
|
15
|
-
import prime_field from './prime_field/module.f.mjs'
|
|
16
|
-
import secp from './secp/module.f.mjs'
|
|
17
|
-
import sha2 from './sha2/module.f.mjs'
|
|
18
|
-
import text from './text/module.f.mjs'
|
|
19
|
-
import types$array from './types/array/module.f.mjs'
|
|
20
|
-
import types$bigfloat from './types/bigfloat/module.f.mjs'
|
|
21
|
-
import types$bigint from './types/bigint/module.f.mjs'
|
|
22
|
-
import types$btree from './types/btree/module.f.mjs'
|
|
23
|
-
import types$byte_set from './types/byte_set/module.f.mjs'
|
|
24
|
-
import types$function from './types/function/module.f.mjs'
|
|
25
|
-
import types$list from './types/list/module.f.mjs'
|
|
26
|
-
import types$map from './types/map/module.f.mjs'
|
|
27
|
-
import types$nibble_set from './types/nibble_set/module.f.mjs'
|
|
28
|
-
import types$nullable from './types/nullable/module.f.mjs'
|
|
29
|
-
import types$number from './types/number/module.f.mjs'
|
|
30
|
-
import types$object from './types/object/module.f.mjs'
|
|
31
|
-
import types$range from './types/range/module.f.mjs'
|
|
32
|
-
import types$range_map from './types/range_map/module.f.mjs'
|
|
33
|
-
import types$result from './types/result/module.f.mjs'
|
|
34
|
-
import types$sorted_list from './types/sorted_list/module.f.mjs'
|
|
35
|
-
import types$sorted_set from './types/sorted_set/module.f.mjs'
|
|
36
|
-
import types$string from './types/string/module.f.mjs'
|
|
37
|
-
import types$string_set from './types/string_set/module.f.mjs'
|
|
38
|
-
export default {
|
|
39
|
-
com: {
|
|
40
|
-
cpp: com$cpp,
|
|
41
|
-
cs: com$cs,
|
|
42
|
-
rust: com$rust,
|
|
43
|
-
types: com$types,
|
|
44
|
-
},
|
|
45
|
-
commonjs: commonjs,
|
|
46
|
-
dev: dev,
|
|
47
|
-
djs: djs,
|
|
48
|
-
fsc: fsc,
|
|
49
|
-
fsm: fsm,
|
|
50
|
-
html: html,
|
|
51
|
-
js: {
|
|
52
|
-
tokenizer: js$tokenizer,
|
|
53
|
-
},
|
|
54
|
-
json: json,
|
|
55
|
-
nodejs: {
|
|
56
|
-
version: nodejs$version,
|
|
57
|
-
},
|
|
58
|
-
prime_field: prime_field,
|
|
59
|
-
secp: secp,
|
|
60
|
-
sha2: sha2,
|
|
61
|
-
text: text,
|
|
62
|
-
types: {
|
|
63
|
-
array: types$array,
|
|
64
|
-
bigfloat: types$bigfloat,
|
|
65
|
-
bigint: types$bigint,
|
|
66
|
-
btree: types$btree,
|
|
67
|
-
byte_set: types$byte_set,
|
|
68
|
-
function: types$function,
|
|
69
|
-
list: types$list,
|
|
70
|
-
map: types$map,
|
|
71
|
-
nibble_set: types$nibble_set,
|
|
72
|
-
nullable: types$nullable,
|
|
73
|
-
number: types$number,
|
|
74
|
-
object: types$object,
|
|
75
|
-
range: types$range,
|
|
76
|
-
range_map: types$range_map,
|
|
77
|
-
result: types$result,
|
|
78
|
-
sorted_list: types$sorted_list,
|
|
79
|
-
sorted_set: types$sorted_set,
|
|
80
|
-
string: types$string,
|
|
81
|
-
string_set: types$string_set,
|
|
82
|
-
},
|
|
83
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
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>.
|
|
@@ -1,43 +0,0 @@
|
|
|
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.
|
|
@@ -1,19 +0,0 @@
|
|
|
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).
|
package/issues/test-debug.md
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# Allow Debugging During Test Run
|
|
2
|
-
|
|
3
|
-
Currently, we read files as strings and then parse them as functions. See [dev/test.mjs](../dev/test.mjs). In this case, the
|
|
4
|
-
debugger doesn't know about the source code and can't debug the functions. The main reason for loading modules as functions was
|
|
5
|
-
that Deno v1 didn't support `.cjs` files. However, Deno v2 supports them.
|
|
6
|
-
|
|
7
|
-
We can fix the issue by changing our test runner. The test runner will scan all directories, find all `test.f.cjs` files, and
|
|
8
|
-
then load them using `require`.
|
|
9
|
-
|
|
10
|
-
Limitations: we will not able to check test module dependencies to have module coverage but, anyway, without a parser, we are not able to get full coverage. So, we can drop support for it right now.
|
|
11
|
-
|
|
12
|
-
**Note:** In this case, we may drop support for Deno v1. At least until we switch to [ESM](./esm.md).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|