functionalscript 0.3.12 → 0.3.13

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.
@@ -55,5 +55,38 @@ declare const _default: {
55
55
  };
56
56
  function: () => void;
57
57
  };
58
+ unary_minus: () => {
59
+ null: () => void;
60
+ undefined: () => void;
61
+ boolean: {
62
+ false: () => void;
63
+ true: () => void;
64
+ };
65
+ number: {
66
+ zero: () => void;
67
+ positive: () => void;
68
+ negative: () => void;
69
+ };
70
+ string: {
71
+ empty: () => void;
72
+ zero: () => void;
73
+ positive: () => void;
74
+ nan: () => void;
75
+ };
76
+ bigint: {
77
+ positive: () => void;
78
+ negative: () => void;
79
+ };
80
+ array: {
81
+ empty: () => void;
82
+ single_number: () => void;
83
+ single_string: () => void;
84
+ multiple: () => void;
85
+ };
86
+ object: {
87
+ empty: () => void;
88
+ };
89
+ function: () => void;
90
+ };
58
91
  };
59
92
  export default _default;
@@ -10,6 +10,12 @@ const n = a => b => {
10
10
  throw [a, '!==', b];
11
11
  }
12
12
  };
13
+ const nan_res = op => n => {
14
+ let result = op(n);
15
+ if (!Number.isNaN(result)) {
16
+ throw result;
17
+ }
18
+ };
13
19
  export default {
14
20
  eq: {
15
21
  nullish: () => {
@@ -84,12 +90,7 @@ export default {
84
90
  },
85
91
  unary_plus: () => {
86
92
  const op = (n) => +n;
87
- const nan = (n) => {
88
- let result = op(n);
89
- if (!Number.isNaN(result)) {
90
- throw result;
91
- }
92
- };
93
+ const nan = nan_res(op);
93
94
  return {
94
95
  null: () => e(op(null))(0),
95
96
  undefined: () => nan(undefined),
@@ -123,5 +124,43 @@ export default {
123
124
  },
124
125
  function: () => nan(op(() => { }))
125
126
  };
127
+ },
128
+ unary_minus: () => {
129
+ const op = (n) => -n;
130
+ const nan = nan_res(op);
131
+ return {
132
+ null: () => e(op(null))(0),
133
+ undefined: () => nan(undefined),
134
+ boolean: {
135
+ false: () => e(op(false))(0),
136
+ true: () => e(op(true))(-1)
137
+ },
138
+ number: {
139
+ zero: () => e(op(0))(0),
140
+ positive: () => e(op(2.3))(-2.3),
141
+ negative: () => e(op(-2.3))(2.3)
142
+ },
143
+ string: {
144
+ empty: () => e(op(""))(0),
145
+ zero: () => e(op("0"))(0),
146
+ positive: () => e(op("2.3"))(-2.3),
147
+ nan: () => nan("a")
148
+ },
149
+ bigint: {
150
+ positive: () => e(op(1n))(-1n),
151
+ negative: () => e(op(-1n))(1n),
152
+ },
153
+ array: {
154
+ empty: () => e(op([]))(0),
155
+ single_number: () => e(op([2.3]))(-2.3),
156
+ single_string: () => e(op(["-2.3"]))(2.3),
157
+ multiple: () => nan([null, null])
158
+ },
159
+ object: {
160
+ empty: () => nan({})
161
+ // TODO: test objects with valueOf, toString functions - when Rust logic is implemented
162
+ },
163
+ function: () => nan(op(() => { }))
164
+ };
126
165
  }
127
166
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.3.12",
3
+ "version": "0.3.13",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.f.d.ts",
@@ -11,11 +11,13 @@
11
11
  "tsc-emit": "tsc --NoEmit false",
12
12
  "prepack": "npm run tsc-emit",
13
13
  "test20": "npm run prepack && node --trace-uncaught ./dev/test.js",
14
- "test": "tsc && node --experimental-strip-types --trace-uncaught ./dev/test.ts",
15
- "comtest": "node --experimental-strip-types ./com/test/build.ts",
16
- "index": "node --experimental-strip-types ./dev/index.ts",
17
- "version": "node --experimental-strip-types ./nodejs/version/main.ts",
18
- "fsc": "node --experimental-strip-types ./main.ts"
14
+ "test22": "tsc && node --experimental-strip-types --trace-uncaught ./dev/test.ts",
15
+ "test": "tsc && node --trace-uncaught ./dev/test.ts",
16
+ "comtest": "node ./com/test/build.ts",
17
+ "index": "node ./dev/index.ts",
18
+ "version": "node ./nodejs/version/main.ts",
19
+ "fsc": "node ./main.ts",
20
+ "update": "npm run version && npm run index && npm install"
19
21
  },
20
22
  "repository": {
21
23
  "type": "git",
@@ -37,7 +39,7 @@
37
39
  },
38
40
  "homepage": "https://github.com/functionalscript/functionalscript#readme",
39
41
  "devDependencies": {
40
- "@types/node": "^22.10.2",
42
+ "@types/node": "^22.10.5",
41
43
  "typescript": "^5.7.2"
42
44
  }
43
45
  }
@@ -1,3 +1,8 @@
1
+ /**
2
+ * JavaScript immutable arrays.
3
+ *
4
+ * @module
5
+ */
1
6
  export type Array1<T> = readonly [T];
2
7
  export type Index1 = 0;
3
8
  export type Array2<T> = readonly [T, T];
@@ -5,16 +10,17 @@ export type Tuple2<T0, T1> = readonly [T0, T1];
5
10
  export type Index2 = 0 | 1;
6
11
  export type Array3<T> = readonly [T, T, T];
7
12
  export type Tuple3<T0, T1, T2> = readonly [T0, T1, T2];
8
- export type Index3 = 0 | 1 | 2;
13
+ export type Index3 = Index2 | 2;
9
14
  export type Array4<T> = readonly [T, T, T, T];
10
- export type Index4 = 0 | 1 | 2 | 3;
15
+ export type Index4 = Index3 | 3;
11
16
  export type Array5<T> = readonly [T, T, T, T, T];
17
+ export type Index5 = Index4 | 4;
12
18
  export type Array8<T> = readonly [T, T, T, T, T, T, T, T];
19
+ export type Index8 = Index5 | 5 | 6 | 7;
13
20
  export type Array16<T> = readonly [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T];
14
- export type Index16 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
21
+ export type Index16 = Index8 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
15
22
  export type Array1_5<T> = Array1<T> | Array2<T> | Array3<T> | Array4<T> | Array5<T>;
16
- export type Index5 = 0 | 1 | 2 | 3 | 4;
17
- export type KeyOf<T> = T extends Array1<infer _> ? Index1 : T extends Array2<infer _> ? Index2 : T extends Array3<infer _> ? Index3 : T extends Array4<infer _> ? Index4 : T extends Array5<infer _> ? Index5 : T extends readonly (infer _)[] ? number : never;
23
+ export type KeyOf<T> = T extends Array1<infer _> ? Index1 : T extends Array2<infer _> ? Index2 : T extends Array3<infer _> ? Index3 : T extends Array4<infer _> ? Index4 : T extends Array5<infer _> ? Index5 : T extends Array8<infer _> ? Index8 : T extends Array16<infer _> ? Index16 : T extends readonly (infer _)[] ? number : never;
18
24
  export declare const at: (i: number) => <T>(a: readonly T[]) => T | null;
19
25
  export declare const first: <T>(_: readonly T[]) => T | null;
20
26
  export declare const last: <T>(a: readonly T[]) => T | null;
@@ -22,3 +28,11 @@ export declare const tail: <T>(a: readonly T[]) => readonly T[] | null;
22
28
  export declare const splitFirst: <T>(a: readonly T[]) => readonly [T, readonly T[]] | null;
23
29
  export declare const head: <T>(a: readonly T[]) => readonly T[] | null;
24
30
  export declare const splitLast: <T>(a: readonly T[]) => readonly [readonly T[], T] | null;
31
+ /**
32
+ * An empty immutable array.
33
+ *
34
+ * Two JavaScript empty arrays are different and has to have two different values.
35
+ * Usually, it requires memory allocation. If we use the same an empty array everywhere,
36
+ * we may minimize memory a number of memory allocations.
37
+ */
38
+ export declare const empty: readonly [];
@@ -1,3 +1,8 @@
1
+ /**
2
+ * JavaScript immutable arrays.
3
+ *
4
+ * @module
5
+ */
1
6
  import { map } from "../nullable/module.f.js";
2
7
  const uncheckTail = (a) => a.slice(1);
3
8
  const uncheckHead = (a) => a.slice(0, -1);
@@ -20,3 +25,11 @@ export const splitLast = (a) => {
20
25
  }
21
26
  return [uncheckHead(a), lastA];
22
27
  };
28
+ /**
29
+ * An empty immutable array.
30
+ *
31
+ * Two JavaScript empty arrays are different and has to have two different values.
32
+ * Usually, it requires memory allocation. If we use the same an empty array everywhere,
33
+ * we may minimize memory a number of memory allocations.
34
+ */
35
+ export const empty = [];
@@ -7,5 +7,6 @@ declare const _default: {
7
7
  tail: (() => void)[];
8
8
  splitFirst: (() => void)[];
9
9
  splitLast: (() => void)[];
10
+ empty: () => void;
10
11
  };
11
12
  export default _default;
@@ -1,4 +1,4 @@
1
- import { at, first, last, head, tail, splitFirst, splitLast } from "./module.f.js";
1
+ import { at, first, last, head, tail, splitFirst, splitLast, empty } from "./module.f.js";
2
2
  import * as json from "../../json/module.f.js";
3
3
  import { sort } from "../object/module.f.js";
4
4
  const stringify = json.stringify(sort);
@@ -113,5 +113,14 @@ export default {
113
113
  throw result;
114
114
  }
115
115
  }
116
- ]
116
+ ],
117
+ empty: () => {
118
+ const x = empty;
119
+ const a = x;
120
+ const b = x;
121
+ const c = [...a, ...b, ...x];
122
+ if (c.length !== 0) {
123
+ throw c;
124
+ }
125
+ }
117
126
  };
package/bnf/module.f.d.ts DELETED
@@ -1,135 +0,0 @@
1
- /**
2
- * Types for defining language grammars using Backus-Naur Form (BNF).
3
- *
4
- * @module
5
- *
6
- * @description
7
- *
8
- * The primary utility of this module is to define grammars for text processing,
9
- * parsing, and lexing in a structured and reusable way.
10
- *
11
- * See [Backus-Naur form](https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form).
12
- *
13
- * @example
14
- *
15
- * ```js
16
- * import { firstSet, type Rule, type Set } from './module.f.ts'
17
- *
18
- * const grammar: Rule = [
19
- * { or: [[65, 90], [97, 122], [48, 57]] }, // Matches 'A-Z', 'a-z', and '0-9'
20
- * ];
21
- *
22
- * const s = firstSet(grammar)
23
- * if (s.empty) { throw s }
24
- * if (setOp.get('0'.codePointAt(0))(s.map) !== true) { throw s }
25
- * if (setOp.get('h'.codePointAt(0))(s.map) !== true) { throw s }
26
- * if (setOp.get('$'.codePointAt(0))(s.map) !== false) { throw s }
27
- * ```
28
- */
29
- import { type CodePoint } from '../text/utf16/module.f.ts';
30
- import { type RangeMapOp, type RangeMapArray } from '../types/range_map/module.f.ts';
31
- /**
32
- * Represents a terminal range as a pair of Unicode code points.
33
- * Typically used to define character ranges.
34
- *
35
- * @example
36
- *
37
- * ```ts
38
- * const alpha: TerminalRange = [65, 90] // Matches 'A-Z'
39
- * ```
40
- */
41
- export type TerminalRange = readonly [CodePoint, CodePoint];
42
- /**
43
- * Represents a sequence of rules that must match in order.
44
- *
45
- * @example
46
- *
47
- * ```ts
48
- * const alpha: TerminalRange = [65, 90] // Matches 'A-Z'
49
- * const id2: Sequence = [alpha, alpha] // Matches two uppercase letters
50
- * ```
51
- */
52
- export type Sequence = readonly Rule[];
53
- /**
54
- * Represents a logical "or" operation between multiple sequences.
55
- * Allows defining alternatives within the grammar.
56
- *
57
- * @example
58
- *
59
- * ```ts
60
- * const alpha: TerminalRange = [65, 90] // Matches 'A-Z'
61
- * const id2: Sequence = [alpha, alpha] // Matches two uppercase letters
62
- * const digit: TerminalRange = [48, 57] // Matches '0-9'
63
- * // Matches two uppercase letters or one digit
64
- * const id2OrDigit: Or = { or: [
65
- * id2,
66
- * digit,
67
- * ] }
68
- * ```
69
- */
70
- export type Or = {
71
- readonly or: Sequence;
72
- };
73
- /**
74
- * Represents a grammar rule, which can be:
75
- * - A sequence of rules (`Sequence`)
76
- * - An "or" operation (`Or`)
77
- * - A terminal range (`TerminalRange`)
78
- * - A string (representing a literal sequence of characters)
79
- *
80
- * @remarks The rule can't have recursions.
81
- *
82
- * @example
83
- *
84
- * ```ts
85
- * // Matches 'true', 'false'
86
- * const bool: DataRule = { or: [
87
- * 'true',
88
- * 'false',
89
- * ] }
90
- */
91
- export type DataRule = Or | Sequence | TerminalRange | string;
92
- /**
93
- * Represents a lazy grammar rule for recursive definitions.
94
- *
95
- * @example
96
- *
97
- * ```ts
98
- * const alpha: TerminalRange = [65, 90] // Matches 'A-Z'
99
- * // Matches a string of uppercase letters
100
- * const id: LazyRule = () => [alpha, { or: [
101
- * [], // Empty
102
- * id // Recursive
103
- * ] }]
104
- * ```
105
- */
106
- export type LazyRule = () => DataRule;
107
- /**
108
- * Represents a rule in the grammar.
109
- */
110
- export type Rule = DataRule | LazyRule;
111
- export declare const toTerminalRangeSequence: (s: string) => readonly TerminalRange[];
112
- /**
113
- * A set that represents possible code points.
114
- */
115
- export type CpSet = {
116
- /**
117
- * Whether a grammar rule allows an empty sequence.
118
- */
119
- readonly empty: boolean;
120
- /**
121
- * The range map representing a set of possible code points.
122
- */
123
- readonly map: RangeMapArray<boolean>;
124
- };
125
- /**
126
- * Operations on code point sets.
127
- */
128
- export declare const setOp: RangeMapOp<boolean>;
129
- /**
130
- * Processes a `Rule` and converts it into a `Set` of possible code points at the start of the rule.
131
- *
132
- * @param rule - The grammar rule to process.
133
- * @returns A set representing the first possible code points in the grammar rule.
134
- */
135
- export declare const firstSet: (rule: Rule) => CpSet;
package/bnf/module.f.js DELETED
@@ -1,142 +0,0 @@
1
- /**
2
- * Types for defining language grammars using Backus-Naur Form (BNF).
3
- *
4
- * @module
5
- *
6
- * @description
7
- *
8
- * The primary utility of this module is to define grammars for text processing,
9
- * parsing, and lexing in a structured and reusable way.
10
- *
11
- * See [Backus-Naur form](https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form).
12
- *
13
- * @example
14
- *
15
- * ```js
16
- * import { firstSet, type Rule, type Set } from './module.f.ts'
17
- *
18
- * const grammar: Rule = [
19
- * { or: [[65, 90], [97, 122], [48, 57]] }, // Matches 'A-Z', 'a-z', and '0-9'
20
- * ];
21
- *
22
- * const s = firstSet(grammar)
23
- * if (s.empty) { throw s }
24
- * if (setOp.get('0'.codePointAt(0))(s.map) !== true) { throw s }
25
- * if (setOp.get('h'.codePointAt(0))(s.map) !== true) { throw s }
26
- * if (setOp.get('$'.codePointAt(0))(s.map) !== false) { throw s }
27
- * ```
28
- */
29
- import { stringToCodePointList } from "../text/utf16/module.f.js";
30
- import { map, toArray } from "../types/list/module.f.js";
31
- import { rangeMap } from "../types/range_map/module.f.js";
32
- const toTerminalRangeMap = map((cp) => [cp, cp]);
33
- export const toTerminalRangeSequence = (s) => toArray(toTerminalRangeMap(stringToCodePointList(s)));
34
- /**
35
- * Operations on code point sets.
36
- */
37
- export const setOp = rangeMap({
38
- union: a => b => a || b,
39
- equal: a => b => a === b,
40
- def: false
41
- });
42
- const { merge, fromRange } = setOp;
43
- const rangeToSet = (r) => ({ empty: false, map: fromRange(r)(true) });
44
- const isTerminalRange = (rule) => typeof rule[0] === 'number';
45
- const passSet = { empty: true, map: [] };
46
- /**
47
- * Processes a `Rule` and converts it into a `Set` of possible code points at the start of the rule.
48
- *
49
- * @param rule - The grammar rule to process.
50
- * @returns A set representing the first possible code points in the grammar rule.
51
- */
52
- export const firstSet = (rule) => {
53
- if (typeof rule === 'function') {
54
- rule = rule();
55
- }
56
- if (typeof rule === 'string') {
57
- const first = toTerminalRangeSequence(rule).at(0);
58
- if (first === undefined) {
59
- return passSet;
60
- }
61
- return rangeToSet(first);
62
- }
63
- if (rule instanceof Array) {
64
- if (isTerminalRange(rule)) {
65
- return rangeToSet(rule);
66
- }
67
- let result = [];
68
- for (const r of rule) {
69
- const { empty, map } = firstSet(r);
70
- result = toArray(merge(result)(map));
71
- if (!empty) {
72
- return { empty: false, map: result };
73
- }
74
- }
75
- return { empty: true, map: result };
76
- }
77
- let empty = false;
78
- let map = [];
79
- for (const r of rule.or) {
80
- const { empty: rEmpty, map: rMap } = firstSet(r);
81
- map = toArray(merge(map)(rMap));
82
- empty ||= rEmpty;
83
- }
84
- return { empty, map };
85
- };
86
- // type MatchMap = {
87
- // empty: boolean
88
- // map: RangeMapArray<MatchMap>
89
- // }
90
- // const defMatchMap: MatchMap = { empty: false, map: [] }
91
- // const unionMap = (a: MatchMap) => (b: MatchMap) =>
92
- // ({ empty: a.empty || b.empty, map: toArray(matchMapOp.merge(a.map)(b.map)) })
93
- // /**
94
- // * Operations on code point map.
95
- // */
96
- // const matchMapOp: RangeMapOp<MatchMap> = rangeMap({
97
- // union: unionMap,
98
- // equal: a => b => a === b,
99
- // def: defMatchMap
100
- // })
101
- // const { merge: mergeMap, fromRange: fromRangeMap } = matchMapOp
102
- // const pass: MatchMap = { empty: true, map: [] }
103
- // const rangeToMatchMap = (r: TerminalRange, p: MatchMap): MatchMap => ({ empty: false, map: fromRangeMap(r)(p) })
104
- // /**
105
- // * Processes a `Rule` and converts it into a `Set` of possible code points at the start of the rule.
106
- // *
107
- // * @param rule - The grammar rule to process.
108
- // * @returns A set representing the first possible code points in the grammar rule.
109
- // */
110
- // export const matchMap = (rule: Rule): MatchMap => {
111
- // if (typeof rule === 'function') {
112
- // rule = rule()
113
- // }
114
- // if (typeof rule === 'string') {
115
- // const a = toTerminalRangeSequence(rule)
116
- // let result = pass
117
- // for (const r of a) {
118
- // result = rangeToMatchMap(r, result)
119
- // }
120
- // return result
121
- // }
122
- // if (rule instanceof Array) {
123
- // if (isTerminalRange(rule)) {
124
- // return rangeToMatchMap(rule, pass)
125
- // }
126
- // let result = pass
127
- // for (const r of rule.toReversed()) {
128
- // todo()
129
- // /*
130
- // const rMap = matchMap(r)
131
- // result = unionMap(result)(rMap)
132
- // */
133
- // }
134
- // return result
135
- // }
136
- // let result = pass
137
- // for (const r of rule.or) {
138
- // const rMap = matchMap(r)
139
- // result = unionMap(result)(rMap)
140
- // }
141
- // return result
142
- // }
package/bnf/test.f.d.ts DELETED
@@ -1,65 +0,0 @@
1
- declare const _default: {
2
- example: {
3
- module: () => void;
4
- types: () => void;
5
- };
6
- classic: () => {
7
- ws: () => void;
8
- sign: () => void;
9
- digits: () => void;
10
- exponent: () => void;
11
- fraction: () => void;
12
- onenine: () => void;
13
- digit: () => void;
14
- string: () => void;
15
- member: () => void;
16
- members: () => void;
17
- object: () => void;
18
- array: () => void;
19
- integer: () => void;
20
- number: () => void;
21
- value: () => void;
22
- element: () => void;
23
- elements: () => void;
24
- json: () => void;
25
- hex: () => void;
26
- escape: () => void;
27
- character: () => void;
28
- characters: () => void;
29
- };
30
- deterministic: () => {
31
- ws: () => void;
32
- sign: () => void;
33
- digits1: () => void;
34
- digits: () => void;
35
- exponent: () => void;
36
- fraction: () => void;
37
- onenine: () => void;
38
- digit: () => void;
39
- string: () => void;
40
- member1: () => void;
41
- member: () => void;
42
- members2: () => void;
43
- members1: () => void;
44
- members: () => void;
45
- object1: () => void;
46
- object: () => void;
47
- array1: () => void;
48
- array: () => void;
49
- integer1: () => void;
50
- integer: () => void;
51
- number: () => void;
52
- value: () => void;
53
- element1: () => void;
54
- element: () => void;
55
- elements2: () => void;
56
- elements1: () => void;
57
- elements: () => void;
58
- json: () => void;
59
- hex: () => void;
60
- escape: () => void;
61
- character: () => void;
62
- characters: () => void;
63
- };
64
- };
65
- export default _default;