affinirum 1.0.2 → 1.0.4

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 (108) hide show
  1. package/README.md +26 -19
  2. package/dst/Affinirum.d.ts +10 -10
  3. package/dst/Affinirum.js +52 -51
  4. package/dst/Atom.d.ts +5 -0
  5. package/dst/Atom.js +1 -0
  6. package/dst/Constant.d.ts +2 -2
  7. package/dst/Constant.js +1 -1
  8. package/dst/Constants.d.ts +1 -1
  9. package/dst/Constants.js +20 -20
  10. package/dst/Functions.d.ts +1 -1
  11. package/dst/Functions.js +75 -74
  12. package/dst/Keywords.js +15 -15
  13. package/dst/Node.d.ts +3 -3
  14. package/dst/Node.js +2 -2
  15. package/dst/ParserFrame.js +31 -31
  16. package/dst/ParserState.d.ts +8 -7
  17. package/dst/ParserState.js +129 -122
  18. package/dst/StaticScope.d.ts +1 -1
  19. package/dst/Type.d.ts +7 -13
  20. package/dst/Type.js +23 -23
  21. package/dst/Variable.d.ts +2 -2
  22. package/dst/Variable.js +1 -1
  23. package/dst/atom/ArrayAtom.d.ts +8 -7
  24. package/dst/atom/ArrayAtom.js +6 -6
  25. package/dst/atom/FunctionAtom.d.ts +8 -7
  26. package/dst/atom/FunctionAtom.js +10 -10
  27. package/dst/atom/ObjectAtom.d.ts +8 -7
  28. package/dst/atom/ObjectAtom.js +7 -7
  29. package/dst/atom/PrimitiveAtom.d.ts +4 -3
  30. package/dst/atom/PrimitiveAtom.js +11 -11
  31. package/dst/cjs/Affinirum.js +31 -30
  32. package/dst/cjs/Atom.js +2 -0
  33. package/dst/cjs/Constants.js +10 -10
  34. package/dst/cjs/Functions.js +66 -65
  35. package/dst/cjs/Keywords.js +15 -15
  36. package/dst/cjs/Node.js +1 -1
  37. package/dst/cjs/ParserFrame.js +31 -31
  38. package/dst/cjs/ParserState.js +120 -113
  39. package/dst/cjs/Type.js +19 -19
  40. package/dst/cjs/atom/ArrayAtom.js +6 -6
  41. package/dst/cjs/atom/FunctionAtom.js +9 -9
  42. package/dst/cjs/atom/ObjectAtom.js +7 -7
  43. package/dst/cjs/atom/PrimitiveAtom.js +11 -11
  44. package/dst/cjs/constant/Boolean.js +1 -1
  45. package/dst/cjs/constant/Buffer.js +44 -6
  46. package/dst/cjs/constant/Enumerable.js +6 -3
  47. package/dst/cjs/constant/Float.js +14 -14
  48. package/dst/cjs/constant/Integer.js +33 -33
  49. package/dst/cjs/constant/Iterable.js +24 -5
  50. package/dst/cjs/constant/Number.js +9 -9
  51. package/dst/cjs/constant/Object.js +3 -3
  52. package/dst/cjs/constant/String.js +26 -23
  53. package/dst/cjs/constant/Timestamp.js +4 -4
  54. package/dst/cjs/constant/Unknown.js +22 -22
  55. package/dst/cjs/constant/notation/AN.js +13 -13
  56. package/dst/cjs/constant/notation/JSON.js +1 -1
  57. package/dst/cjs/node/ArrayNode.js +1 -1
  58. package/dst/cjs/node/BlockNode.js +1 -1
  59. package/dst/cjs/node/CallNode.js +2 -2
  60. package/dst/cjs/node/ObjectNode.js +1 -1
  61. package/dst/cjs/node/SwitchNode.js +1 -1
  62. package/dst/constant/Array.d.ts +1 -1
  63. package/dst/constant/Array.js +3 -3
  64. package/dst/constant/Boolean.d.ts +1 -1
  65. package/dst/constant/Boolean.js +3 -3
  66. package/dst/constant/Buffer.d.ts +2 -1
  67. package/dst/constant/Buffer.js +44 -7
  68. package/dst/constant/Enumerable.d.ts +1 -1
  69. package/dst/constant/Enumerable.js +9 -6
  70. package/dst/constant/Float.d.ts +1 -1
  71. package/dst/constant/Float.js +16 -16
  72. package/dst/constant/Integer.d.ts +1 -1
  73. package/dst/constant/Integer.js +35 -35
  74. package/dst/constant/Iterable.d.ts +3 -1
  75. package/dst/constant/Iterable.js +25 -6
  76. package/dst/constant/Number.d.ts +1 -1
  77. package/dst/constant/Number.js +11 -11
  78. package/dst/constant/Object.d.ts +1 -1
  79. package/dst/constant/Object.js +5 -5
  80. package/dst/constant/String.d.ts +1 -3
  81. package/dst/constant/String.js +27 -23
  82. package/dst/constant/Timestamp.d.ts +1 -1
  83. package/dst/constant/Timestamp.js +6 -6
  84. package/dst/constant/Unknown.d.ts +2 -2
  85. package/dst/constant/Unknown.js +29 -29
  86. package/dst/constant/notation/AN.d.ts +2 -2
  87. package/dst/constant/notation/AN.js +17 -17
  88. package/dst/constant/notation/JSON.d.ts +2 -2
  89. package/dst/constant/notation/JSON.js +3 -3
  90. package/dst/index.d.ts +3 -3
  91. package/dst/index.js +3 -3
  92. package/dst/node/ArrayNode.d.ts +4 -4
  93. package/dst/node/ArrayNode.js +5 -5
  94. package/dst/node/BlockNode.d.ts +4 -4
  95. package/dst/node/BlockNode.js +5 -5
  96. package/dst/node/CallNode.d.ts +4 -4
  97. package/dst/node/CallNode.js +7 -7
  98. package/dst/node/ConstantNode.d.ts +5 -5
  99. package/dst/node/ConstantNode.js +1 -1
  100. package/dst/node/LoopNode.d.ts +4 -4
  101. package/dst/node/LoopNode.js +2 -2
  102. package/dst/node/ObjectNode.d.ts +4 -4
  103. package/dst/node/ObjectNode.js +5 -5
  104. package/dst/node/SwitchNode.d.ts +4 -4
  105. package/dst/node/SwitchNode.js +5 -5
  106. package/dst/node/VariableNode.d.ts +5 -5
  107. package/dst/node/VariableNode.js +1 -1
  108. package/package.json +1 -1
package/README.md CHANGED
@@ -13,38 +13,42 @@ Target: ES2022 [browser+NodeJS][ESM+CJS].
13
13
 
14
14
  ## Features
15
15
 
16
- - Efficient execution: Parse once, execute many times with different variable values
17
- - Variable support: Input and statement-scoped variables
18
- - Function support: Variadic and first-order function support for expressive scripting
19
- - Optimized evaluation: Constant expression folding with type checks
20
- - Comprehensive set of operators: Boolean, arithmetic, buffer, string, comparison, and indexing support
21
- - Built-in functions: Rich set of mathematical and composition utilities
16
+ - Efficient execution: Parse once, execute many times with different variable values.
17
+ - Variable support: Input and statement-scoped variables.
18
+ - Function support: Variadic and first-order function support for expressive scripting.
19
+ - Optimized evaluation: Constant expression folding with type checks.
20
+ - Comprehensive set of operators: Boolean, arithmetic, buffer, string, comparison, and indexing support.
21
+ - Built-in functions: Rich set of mathematical and composition utilities.
22
22
 
23
23
  ## Specifications
24
24
 
25
25
  Script can contain multiple semicolon-separated expressions, and blocks of statements.
26
26
  The value of a block is determined by the value of the last expression.
27
- - Scientific notation is supported for floating point numbers, like *0.1281e+2*
28
- - ISO Timestamps prefixed with **@**, like *@2025-05-11T19:09:21.320Z*
29
- - Hexadecimal buffer values are prefixed with **#**, like *#10ab0901*
30
- - String literals are enclosed in single (**'**), double (**"**), or backtick (**`**) quotes, like *'string value'*
27
+ - Scientific notation is supported for floating point numbers, like *0.1281e+2*.
28
+ - ISO Timestamps prefixed with **@**, like *@2025-05-11T19:09:21.320Z*.
29
+ - Hexadecimal buffer values are prefixed with **#**, like *#10ab0901*.
30
+ - String literals are enclosed in single (**'**), double (**"**), or backtick (**`**) quotes, like *'string value'*.
31
31
 
32
32
  Array is an ordered sequence of values of any type.
33
33
  It is defined by comma-separated values enclosed in brackets (**[]**),
34
34
  like *[0,1,2]*, *["a","b","c"]*.
35
35
  <br>An empty array is represented as **[]**.
36
36
 
37
- Array elements can be accessed using the dot (**.**) access operator with a index,
38
- or using brackets with a zero-based numeric index, like *theArray.23*, *theArray[0]*, *theArray[10]*, *theArray[indexVar]*
37
+ Array elements can be accessed using the access operator (**.**),
38
+ or using brackets with a zero-based numeric index, like *theArray.23*, *theArray[0]*, *theArray[10]*, *theArray[indexVar]*.
39
+
40
+ Easy way to check if array contains an index is to use presence operator (**?**), like *theArray?50*.
39
41
 
40
42
  Object is a container of named values of any type.
41
43
  It is defined by comma-separated key-value pair enclosed in brackets (**[]**) where key is separated from value by colon (**:**),
42
44
  like *["NumericProperty":100, "StringProperty":"abc"]*, *["a":0,"b":"str":"c":valueVar]*.
43
45
  <br>An empty object is represented as **[\:]**.
44
46
 
45
- Object properties can be accessed using the dot (**.**) access operator with a string literal,
46
- or with brackets containing a string key or numeric index,
47
- like *theObject."StringProperty"*, *theObject["StringProperty"]*, *theObject[indexVar]*
47
+ Object properties can be accessed using the access operator (**.**) with a string literal, token,
48
+ or with brackets containing a string key,
49
+ like *theObject."StringProperty"*, *theObject.stringProp*, *theObject["StringProperty"]*.
50
+
51
+ Easy way to check if object contains a key is to use presence operator (**?**), like *theObject?myKey*.
48
52
 
49
53
  A function is a callable code unit that produces a value.
50
54
  The set of built-in functions can be extended through configuration entries.
@@ -52,7 +56,7 @@ Additionally, subroutines (functions defined in code) can be created.
52
56
 
53
57
  Valid variable and function names must start with a letter or underscore (**\_**)
54
58
  and can be followed by any combination of alphanumeric characters or underscores,
55
- like *x*, *\_a1*, *abc25*
59
+ like *x*, *\_a1*, *abc25*.
56
60
 
57
61
  Whitespace characters are ignored.
58
62
 
@@ -103,6 +107,8 @@ Unknown or variant type is declared as **??**.
103
107
  - Arithmetic division: **/**
104
108
  - Arithmetic remainder: **%**
105
109
  - Exponentiation operator: **^**
110
+ - Access operator: **.**
111
+ - Presence operator: **?**
106
112
  - Assignment: **=**
107
113
  - Boolean disjunction (Logical OR) assignment: **|=**
108
114
  - Boolean conjunction (Logical AND) assignment: **&=**
@@ -177,7 +183,7 @@ Unknown or variant type is declared as **??**.
177
183
 
178
184
  #### JSON
179
185
  - **string JSON.Format(value: void | boolean | float | string | array | object, whitespace?: string)** — Format as JSON string
180
- - **void | boolean | float? | string? | array? | object? JSON.Parse(value?: string)** — Parse JSON-formatted string
186
+ - **void | boolean | float? | string | array | object JSON.Parse(value: string)** — Parse JSON-formatted string
181
187
 
182
188
 
183
189
  ### Functions
@@ -217,7 +223,9 @@ Unknown or variant type is declared as **??**.
217
223
 
218
224
  #### Iterable Functions
219
225
  - **integer buffer | string | array | object.Length()** — Get length
220
- - **?? array? | object?.At(index: integer | string)** — Access by index or key
226
+ - **boolean buffer | string | array | object.Contains(search: buffer | string | ??, startPos?: integer, ignoreCaseSpaceEtc?: boolean)** — Substring check
227
+ - **?? array? | object.At(index: integer | string)** — Access item in array or object by index or key
228
+ - **?? array? | object.Has(index: integer | string)** — Identify if array or object has index or key
221
229
 
222
230
  #### Number Functions
223
231
  - **boolean float | integer.GreaterThan(value)** — Greater than
@@ -242,7 +250,6 @@ Unknown or variant type is declared as **??**.
242
250
  #### String Functions
243
251
  - **boolean string.Like(value: string)** — Alphanumeric equality
244
252
  - **boolean string.Unlike(value: string)** — Alphanumeric inequality
245
- - **boolean string.Contains(search: string, startPos?: integer, ignoreCaseSpaceEtc?: boolean)** — Substring check
246
253
  - **boolean string.StartsWith(search: string, startPos?: integer, ignoreCaseSpaceEtc?: boolean)** — Prefix check
247
254
  - **boolean string.EndsWith(search: string, endPos?: integer, ignoreCaseSpaceEtc?: boolean)** — Suffix check
248
255
  - **string string.Char(pos: integer)** — Character at position
@@ -1,13 +1,13 @@
1
- import { Constant } from './Constant.js';
2
- import { Variable } from './Variable.js';
3
- import { Value } from './Value.js';
4
- import { Type } from './Type.js';
5
- import { Node } from './Node.js';
6
- import { LoopNode } from './node/LoopNode.js';
7
- import { SwitchNode } from './node/SwitchNode.js';
8
- import { ParserFrame } from './ParserFrame.js';
9
- import { ParserState } from './ParserState.js';
10
- import { StaticScope } from './StaticScope.js';
1
+ import { Constant } from "./Constant.js";
2
+ import { Variable } from "./Variable.js";
3
+ import { Value } from "./Value.js";
4
+ import { Type } from "./Type.js";
5
+ import { Node } from "./Node.js";
6
+ import { LoopNode } from "./node/LoopNode.js";
7
+ import { SwitchNode } from "./node/SwitchNode.js";
8
+ import { ParserFrame } from "./ParserFrame.js";
9
+ import { ParserState } from "./ParserState.js";
10
+ import { StaticScope } from "./StaticScope.js";
11
11
  export declare class Affinirum {
12
12
  static readonly keywords: string[];
13
13
  protected readonly _script: string;
package/dst/Affinirum.js CHANGED
@@ -1,24 +1,24 @@
1
- import { funcOr, funcAnd, funcNot } from './constant/Boolean.js';
2
- import { funcAdd } from './constant/Enumerable.js';
3
- import { funcAt } from './constant/Iterable.js';
4
- import { funcGreaterThan, funcLessThan, funcGreaterOrEqual, funcLessOrEqual, funcSubtract, funcMultiply, funcDivide, funcRemainder, funcPower, funcNegate } from './constant/Number.js';
5
- import { funcCoalesce, funcEqual, funcNotEqual } from './constant/Unknown.js';
6
- import { Constant } from './Constant.js';
7
- import { Variable } from './Variable.js';
8
- import { Type } from './Type.js';
9
- import { Keywords } from './Keywords.js';
10
- import { Constants } from './Constants.js';
11
- import { Functions } from './Functions.js';
12
- import { ArrayNode } from './node/ArrayNode.js';
13
- import { BlockNode } from './node/BlockNode.js';
14
- import { ConstantNode } from './node/ConstantNode.js';
15
- import { CallNode } from './node/CallNode.js';
16
- import { LoopNode } from './node/LoopNode.js';
17
- import { ObjectNode } from './node/ObjectNode.js';
18
- import { SwitchNode } from './node/SwitchNode.js';
19
- import { VariableNode } from './node/VariableNode.js';
20
- import { ParserState } from './ParserState.js';
21
- import { StaticScope } from './StaticScope.js';
1
+ import { funcOr, funcAnd, funcNot } from "./constant/Boolean.js";
2
+ import { funcAdd } from "./constant/Enumerable.js";
3
+ import { funcAt, funcHas } from "./constant/Iterable.js";
4
+ import { funcGreaterThan, funcLessThan, funcGreaterOrEqual, funcLessOrEqual, funcSubtract, funcMultiply, funcDivide, funcRemainder, funcPower, funcNegate } from "./constant/Number.js";
5
+ import { funcCoalesce, funcEqual, funcNotEqual } from "./constant/Unknown.js";
6
+ import { Constant } from "./Constant.js";
7
+ import { Variable } from "./Variable.js";
8
+ import { Type } from "./Type.js";
9
+ import { Keywords } from "./Keywords.js";
10
+ import { Constants } from "./Constants.js";
11
+ import { Functions } from "./Functions.js";
12
+ import { ArrayNode } from "./node/ArrayNode.js";
13
+ import { BlockNode } from "./node/BlockNode.js";
14
+ import { ConstantNode } from "./node/ConstantNode.js";
15
+ import { CallNode } from "./node/CallNode.js";
16
+ import { LoopNode } from "./node/LoopNode.js";
17
+ import { ObjectNode } from "./node/ObjectNode.js";
18
+ import { SwitchNode } from "./node/SwitchNode.js";
19
+ import { VariableNode } from "./node/VariableNode.js";
20
+ import { ParserState } from "./ParserState.js";
21
+ import { StaticScope } from "./StaticScope.js";
22
22
  export class Affinirum {
23
23
  static keywords = [...Keywords, ...Constants.map((c) => c[0])];
24
24
  _script;
@@ -47,7 +47,7 @@ export class Affinirum {
47
47
  const state = new ParserState(this._script);
48
48
  this._root = this._block(state.next(), this._scope);
49
49
  if (!state.isVoid) {
50
- state.throwError('unexpected expression token or expression end');
50
+ state.throwError("unexpected expression token or expression end");
51
51
  }
52
52
  this._root = this._root.compile(config?.type ?? Type.Unknown);
53
53
  }
@@ -186,11 +186,12 @@ export class Affinirum {
186
186
  }
187
187
  _accessor(state, scope) {
188
188
  let node = this._term(state, scope);
189
- while (state.operator === funcAt || state.isParenthesesOpen || state.isBracketsOpen) {
189
+ while (state.isDotMark || state.isQuestionMark || state.isParenthesesOpen || state.isBracketsOpen) {
190
190
  const frame = state.starts();
191
- if (state.operator === funcAt) {
192
- if (state.next().isLiteral && (typeof state.literalValue === 'string' || typeof state.literalValue === 'bigint')) {
193
- node = this._call(frame.ends(state), funcAt, [node, new ConstantNode(state, new Constant(state.literalValue))]);
191
+ if (state.isDotMark || state.isQuestionMark) {
192
+ const operator = state.isDotMark ? funcAt : funcHas;
193
+ if (state.next().isLiteral && (typeof state.literal.value === "string" || typeof state.literal.value === "bigint")) {
194
+ node = this._call(frame.ends(state), operator, [node, new ConstantNode(state, new Constant(state.literal.value))]);
194
195
  state.next();
195
196
  }
196
197
  else if (state.isToken) {
@@ -213,12 +214,12 @@ export class Affinirum {
213
214
  }
214
215
  }
215
216
  else {
216
- node = this._call(frame, funcAt, [node, new ConstantNode(state, new Constant(state.token))]);
217
+ node = this._call(frame, operator, [node, new ConstantNode(state, new Constant(state.token))]);
217
218
  state.next();
218
219
  }
219
220
  }
220
221
  else {
221
- state.throwError('missing array or object index');
222
+ state.throwError("missing array index or object key");
222
223
  }
223
224
  }
224
225
  else if (state.isParenthesesOpen) {
@@ -242,7 +243,7 @@ export class Affinirum {
242
243
  _term(state, scope) {
243
244
  if (state.isLiteral) {
244
245
  const frame = state.starts();
245
- const constant = new Constant(state.literalValue);
246
+ const constant = new Constant(state.literal.value);
246
247
  state.next();
247
248
  return new ConstantNode(frame, constant);
248
249
  }
@@ -250,11 +251,11 @@ export class Affinirum {
250
251
  const frame = state.starts();
251
252
  const constants = this._constants.get(state.token);
252
253
  if (constants != null) {
253
- if (state.next().operator !== funcAt) {
254
- state.throwError('missing constant accessor operator');
254
+ if (!state.next().isDotMark) {
255
+ state.throwError("missing constant accessor operator");
255
256
  }
256
257
  if (!state.next().isToken) {
257
- state.throwError('missing constant name');
258
+ state.throwError("missing constant name");
258
259
  }
259
260
  const constant = constants[state.token];
260
261
  if (!constant) {
@@ -281,10 +282,10 @@ export class Affinirum {
281
282
  }
282
283
  if (state.next().isAssignment) {
283
284
  if (variable.constant) {
284
- state.throwError('illegal constant assignment');
285
+ state.throwError("illegal constant assignment");
285
286
  }
286
- if (state.assignmentOperator) {
287
- const operator = state.assignmentOperator;
287
+ if (state.assignment.operator) {
288
+ const operator = state.assignment.operator;
288
289
  const subnodes = [new VariableNode(frame, variable), this._unit(state.next(), scope)];
289
290
  return new VariableNode(frame, variable, this._call(frame, operator, subnodes));
290
291
  }
@@ -300,7 +301,7 @@ export class Affinirum {
300
301
  return node;
301
302
  }
302
303
  else if (state.isBracesClose) {
303
- state.throwError('unexpected closing braces');
304
+ state.throwError("unexpected closing braces");
304
305
  }
305
306
  else if (state.isParenthesesOpen) {
306
307
  const node = this._unit(state.next(), scope);
@@ -308,7 +309,7 @@ export class Affinirum {
308
309
  return node;
309
310
  }
310
311
  else if (state.isParenthesesClose) {
311
- state.throwError('unexpected closing parentheses');
312
+ state.throwError("unexpected closing parentheses");
312
313
  }
313
314
  else if (state.isBracketsOpen) {
314
315
  const frame = state.starts();
@@ -335,21 +336,21 @@ export class Affinirum {
335
336
  frame.ends(state);
336
337
  state.closeBrackets().next();
337
338
  if (colon) {
338
- return new ObjectNode(frame, subnodes.map(([k, v]) => [typeof k === 'number' ? new ConstantNode(v, new Constant(String(k))) : k, v]));
339
+ return new ObjectNode(frame, subnodes.map(([k, v]) => [typeof k === "number" ? new ConstantNode(v, new Constant(String(k))) : k, v]));
339
340
  }
340
341
  return new ArrayNode(frame, subnodes.map(([, v]) => v));
341
342
  }
342
343
  else if (state.isBracketsClose) {
343
- state.throwError('unexpected closing brackets');
344
+ state.throwError("unexpected closing brackets");
344
345
  }
345
346
  else if (state.isVariableDefinition || state.isConstantDefinition) {
346
347
  const constant = state.isConstantDefinition;
347
348
  if (!state.next().isToken) {
348
- state.throwError(`missing ${constant ? 'constant' : 'variable'} name`);
349
+ state.throwError(`missing ${constant ? "constant" : "variable"} name`);
349
350
  }
350
351
  const token = state.token;
351
352
  if (scope.has(token)) {
352
- state.throwError(`illegal redefinition of ${constant ? 'constant' : 'variable'} ${token}`);
353
+ state.throwError(`illegal redefinition of ${constant ? "constant" : "variable"} ${token}`);
353
354
  }
354
355
  const frame = state.starts();
355
356
  let type;
@@ -359,8 +360,8 @@ export class Affinirum {
359
360
  const variable = new Variable(type, constant);
360
361
  scope.local(token, variable);
361
362
  if (state.isAssignment) {
362
- if (state.assignmentOperator) {
363
- state.throwError(`illegal assignment to ${constant ? 'constant' : 'variable'} ${token}`);
363
+ if (state.assignment.operator) {
364
+ state.throwError(`illegal assignment operator to ${constant ? "constant" : "variable"} ${token}`);
364
365
  }
365
366
  return new VariableNode(frame, variable, this._unit(state.next(), scope));
366
367
  }
@@ -376,9 +377,9 @@ export class Affinirum {
376
377
  return this._switch(state, scope);
377
378
  }
378
379
  else if (state.isVoid) {
379
- state.throwError('unexpected end of expression');
380
+ state.throwError("unexpected end of expression");
380
381
  }
381
- state.throwError('unexpected expression token');
382
+ state.throwError("unexpected expression token");
382
383
  }
383
384
  _function(state, scope) {
384
385
  const frame = state.starts();
@@ -391,11 +392,11 @@ export class Affinirum {
391
392
  const variables = new Map();
392
393
  while (!state.next().isParenthesesClose) {
393
394
  if (!state.isToken) {
394
- state.throwError('missing function argument name');
395
+ state.throwError("missing function argument name");
395
396
  }
396
397
  const token = state.token;
397
398
  if (scope.get(token)) {
398
- state.throwError('variable redefinition');
399
+ state.throwError("variable redefinition");
399
400
  }
400
401
  let argType = Type.Unknown;
401
402
  if (state.next().isColonSeparator) {
@@ -460,7 +461,7 @@ export class Affinirum {
460
461
  _type(state, scope) {
461
462
  if (state.isType) {
462
463
  let type = state.type;
463
- if (state.next().isOptionalType) {
464
+ if (state.next().isQuestionMark) {
464
465
  type = type.toOptional();
465
466
  state.next();
466
467
  }
@@ -487,7 +488,7 @@ export class Affinirum {
487
488
  itemPropTypes.push([token, this._type(state, scope)]);
488
489
  }
489
490
  else {
490
- state.throwError('missing type or property name');
491
+ state.throwError("missing type or property name");
491
492
  }
492
493
  if (!state.isCommaSeparator) {
493
494
  break;
@@ -516,7 +517,7 @@ export class Affinirum {
516
517
  break;
517
518
  }
518
519
  else {
519
- state.throwError('variadic function argument must be an array type');
520
+ state.throwError("variadic function argument must be an array type");
520
521
  }
521
522
  }
522
523
  if (!state.isCommaSeparator) {
@@ -530,7 +531,7 @@ export class Affinirum {
530
531
  return Type.functionType(retType, argTypes, variadic);
531
532
  }
532
533
  else {
533
- state.throwError('missing type name');
534
+ state.throwError("missing type name");
534
535
  }
535
536
  }
536
537
  }
package/dst/Atom.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export interface IAtom {
2
+ match(atom: IAtom): boolean;
3
+ weight(): number;
4
+ toString(): string;
5
+ }
package/dst/Atom.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dst/Constant.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Value } from './Value.js';
2
- import { Type } from './Type.js';
1
+ import { Value } from "./Value.js";
2
+ import { Type } from "./Type.js";
3
3
  export declare class Constant {
4
4
  protected readonly _value: Value;
5
5
  protected _type: Type;
package/dst/Constant.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Type } from './Type.js';
1
+ import { Type } from "./Type.js";
2
2
  export class Constant {
3
3
  _value;
4
4
  _type;
@@ -1,2 +1,2 @@
1
- import { Constant } from './Constant.js';
1
+ import { Constant } from "./Constant.js";
2
2
  export declare const Constants: [string, Record<string, Constant>][];
package/dst/Constants.js CHANGED
@@ -1,22 +1,22 @@
1
- import { constArray } from './constant/Array.js';
2
- import { constBoolean } from './constant/Boolean.js';
3
- import { constBuffer } from './constant/Buffer.js';
4
- import { constInteger } from './constant/Integer.js';
5
- import { constFloat } from './constant/Float.js';
6
- import { constObject } from './constant/Object.js';
7
- import { constString } from './constant/String.js';
8
- import { constTimestamp } from './constant/Timestamp.js';
9
- import { constAN } from './constant/notation/AN.js';
10
- import { constJSON } from './constant/notation/JSON.js';
1
+ import { constArray } from "./constant/Array.js";
2
+ import { constBoolean } from "./constant/Boolean.js";
3
+ import { constBuffer } from "./constant/Buffer.js";
4
+ import { constInteger } from "./constant/Integer.js";
5
+ import { constFloat } from "./constant/Float.js";
6
+ import { constObject } from "./constant/Object.js";
7
+ import { constString } from "./constant/String.js";
8
+ import { constTimestamp } from "./constant/Timestamp.js";
9
+ import { constAN } from "./constant/notation/AN.js";
10
+ import { constJSON } from "./constant/notation/JSON.js";
11
11
  export const Constants = [
12
- ['Array', constArray],
13
- ['Boolean', constBoolean],
14
- ['Buffer', constBuffer],
15
- ['Float', constFloat],
16
- ['Integer', constInteger],
17
- ['Object', constObject],
18
- ['String', constString],
19
- ['Timestamp', constTimestamp],
20
- ['AN', constAN],
21
- ['JSON', constJSON],
12
+ ["Array", constArray],
13
+ ["Boolean", constBoolean],
14
+ ["Buffer", constBuffer],
15
+ ["Float", constFloat],
16
+ ["Integer", constInteger],
17
+ ["Object", constObject],
18
+ ["String", constString],
19
+ ["Timestamp", constTimestamp],
20
+ ["AN", constAN],
21
+ ["JSON", constJSON],
22
22
  ];
@@ -1,2 +1,2 @@
1
- import { Constant } from './Constant.js';
1
+ import { Constant } from "./Constant.js";
2
2
  export declare const Functions: [string, Constant][];
package/dst/Functions.js CHANGED
@@ -1,85 +1,86 @@
1
- import { funcFirst, funcLast, funcFirstIndex, funcLastIndex, funcEvery, funcAny, funcFlatten, funcReverse, funcMutate, funcFilter, funcReduce, funcCompose, funcPrepend, funcAppend } from './constant/Array.js';
2
- import { funcByte } from './constant/Buffer.js';
3
- import { funcAdd, funcSlice, funcSplice, funcInject } from './constant/Enumerable.js';
4
- import { funcLength, funcAt } from './constant/Iterable.js';
5
- import { funcGreaterThan, funcLessThan, funcGreaterOrEqual, funcLessOrEqual, funcSubtract, funcMultiply, funcDivide, funcRemainder, funcModulo, funcPower, funcRoot, funcNegate, funcCast } from './constant/Number.js';
6
- import { funcEntries, funcKeys, funcValues } from './constant/Object.js';
7
- import { funcLike, funcUnlike, funcContains, funcStartsWith, funcEndsWith, funcChar, funcCharCode, funcTrim, funcTrimStart, funcTrimEnd, funcLowerCase, funcUpperCase, funcSplit } from './constant/String.js';
8
- import { funcYear, funcMonth, funcMonthIndex, funcWeekdayIndex, funcDay, funcHour, funcMinute, funcSecond, funcMillisecond, funcEpochTime } from './constant/Timestamp.js';
9
- import { funcCoalesce, funcEqual, funcNotEqual, funcEncode, funcFormat } from './constant/Unknown.js';
1
+ import { funcFirst, funcLast, funcFirstIndex, funcLastIndex, funcEvery, funcAny, funcFlatten, funcReverse, funcMutate, funcFilter, funcReduce, funcCompose, funcPrepend, funcAppend } from "./constant/Array.js";
2
+ import { funcByte } from "./constant/Buffer.js";
3
+ import { funcAdd, funcSlice, funcSplice, funcInject } from "./constant/Enumerable.js";
4
+ import { funcLength, funcContains, funcAt, funcHas } from "./constant/Iterable.js";
5
+ import { funcGreaterThan, funcLessThan, funcGreaterOrEqual, funcLessOrEqual, funcSubtract, funcMultiply, funcDivide, funcRemainder, funcModulo, funcPower, funcRoot, funcNegate, funcCast } from "./constant/Number.js";
6
+ import { funcEntries, funcKeys, funcValues } from "./constant/Object.js";
7
+ import { funcLike, funcUnlike, funcStartsWith, funcEndsWith, funcChar, funcCharCode, funcTrim, funcTrimStart, funcTrimEnd, funcLowerCase, funcUpperCase, funcSplit } from "./constant/String.js";
8
+ import { funcYear, funcMonth, funcMonthIndex, funcWeekdayIndex, funcDay, funcHour, funcMinute, funcSecond, funcMillisecond, funcEpochTime } from "./constant/Timestamp.js";
9
+ import { funcCoalesce, funcEqual, funcNotEqual, funcEncode, funcFormat } from "./constant/Unknown.js";
10
10
  export const Functions = [
11
11
  // Array
12
- ['First', funcFirst],
13
- ['Last', funcLast],
14
- ['FirstIndex', funcFirstIndex],
15
- ['LastIndex', funcLastIndex],
16
- ['Any', funcAny],
17
- ['Every', funcEvery],
18
- ['Flatten', funcFlatten],
19
- ['Reverse', funcReverse],
20
- ['Mutate', funcMutate],
21
- ['Filter', funcFilter],
22
- ['Reduce', funcReduce],
23
- ['Compose', funcCompose],
24
- ['Prepend', funcPrepend],
25
- ['Append', funcAppend],
12
+ ["First", funcFirst],
13
+ ["Last", funcLast],
14
+ ["FirstIndex", funcFirstIndex],
15
+ ["LastIndex", funcLastIndex],
16
+ ["Any", funcAny],
17
+ ["Every", funcEvery],
18
+ ["Flatten", funcFlatten],
19
+ ["Reverse", funcReverse],
20
+ ["Mutate", funcMutate],
21
+ ["Filter", funcFilter],
22
+ ["Reduce", funcReduce],
23
+ ["Compose", funcCompose],
24
+ ["Prepend", funcPrepend],
25
+ ["Append", funcAppend],
26
26
  // Buffer
27
- ['Byte', funcByte],
27
+ ["Byte", funcByte],
28
28
  // Enumerable
29
- ['Add', funcAdd],
30
- ['Slice', funcSlice],
31
- ['Splice', funcSplice],
32
- ['Inject', funcInject],
29
+ ["Add", funcAdd],
30
+ ["Slice", funcSlice],
31
+ ["Splice", funcSplice],
32
+ ["Inject", funcInject],
33
33
  // Iterable
34
- ['Length', funcLength],
35
- ['At', funcAt],
34
+ ["Length", funcLength],
35
+ ["Contains", funcContains],
36
+ ["At", funcAt],
37
+ ["Has", funcHas],
36
38
  // Number
37
- ['GreaterThan', funcGreaterThan],
38
- ['LessThan', funcLessThan],
39
- ['GreaterOrEqual', funcGreaterOrEqual],
40
- ['LessOrEqual', funcLessOrEqual],
41
- ['Subtract', funcSubtract],
42
- ['Multiply', funcMultiply],
43
- ['Divide', funcDivide],
44
- ['Remainder', funcRemainder],
45
- ['Modulo', funcModulo],
46
- ['Power', funcPower],
47
- ['Root', funcRoot],
48
- ['Negate', funcNegate],
49
- ['Cast', funcCast],
39
+ ["GreaterThan", funcGreaterThan],
40
+ ["LessThan", funcLessThan],
41
+ ["GreaterOrEqual", funcGreaterOrEqual],
42
+ ["LessOrEqual", funcLessOrEqual],
43
+ ["Subtract", funcSubtract],
44
+ ["Multiply", funcMultiply],
45
+ ["Divide", funcDivide],
46
+ ["Remainder", funcRemainder],
47
+ ["Modulo", funcModulo],
48
+ ["Power", funcPower],
49
+ ["Root", funcRoot],
50
+ ["Negate", funcNegate],
51
+ ["Cast", funcCast],
50
52
  // Object
51
- ['Entries', funcEntries],
52
- ['Keys', funcKeys],
53
- ['Values', funcValues],
53
+ ["Entries", funcEntries],
54
+ ["Keys", funcKeys],
55
+ ["Values", funcValues],
54
56
  // String
55
- ['Like', funcLike],
56
- ['Unlike', funcUnlike],
57
- ['Contains', funcContains],
58
- ['StartsWith', funcStartsWith],
59
- ['EndsWith', funcEndsWith],
60
- ['Char', funcChar],
61
- ['CharCode', funcCharCode],
62
- ['Trim', funcTrim],
63
- ['TrimStart', funcTrimStart],
64
- ['TrimEnd', funcTrimEnd],
65
- ['LowerCase', funcLowerCase],
66
- ['UpperCase', funcUpperCase],
67
- ['Split', funcSplit],
57
+ ["Like", funcLike],
58
+ ["Unlike", funcUnlike],
59
+ ["StartsWith", funcStartsWith],
60
+ ["EndsWith", funcEndsWith],
61
+ ["Char", funcChar],
62
+ ["CharCode", funcCharCode],
63
+ ["Trim", funcTrim],
64
+ ["TrimStart", funcTrimStart],
65
+ ["TrimEnd", funcTrimEnd],
66
+ ["LowerCase", funcLowerCase],
67
+ ["UpperCase", funcUpperCase],
68
+ ["Split", funcSplit],
68
69
  // Timestamp
69
- ['Year', funcYear],
70
- ['Month', funcMonth],
71
- ['MonthIndex', funcMonthIndex],
72
- ['WeekdayIndex', funcWeekdayIndex],
73
- ['Day', funcDay],
74
- ['Hour', funcHour],
75
- ['Minute', funcMinute],
76
- ['Second', funcSecond],
77
- ['Millisecond', funcMillisecond],
78
- ['EpochTime', funcEpochTime],
70
+ ["Year", funcYear],
71
+ ["Month", funcMonth],
72
+ ["MonthIndex", funcMonthIndex],
73
+ ["WeekdayIndex", funcWeekdayIndex],
74
+ ["Day", funcDay],
75
+ ["Hour", funcHour],
76
+ ["Minute", funcMinute],
77
+ ["Second", funcSecond],
78
+ ["Millisecond", funcMillisecond],
79
+ ["EpochTime", funcEpochTime],
79
80
  // Unknown
80
- ['Coalesce', funcCoalesce],
81
- ['Equal', funcEqual],
82
- ['Unequal', funcNotEqual],
83
- ['Encode', funcEncode],
84
- ['Format', funcFormat],
81
+ ["Coalesce", funcCoalesce],
82
+ ["Equal", funcEqual],
83
+ ["Unequal", funcNotEqual],
84
+ ["Encode", funcEncode],
85
+ ["Format", funcFormat],
85
86
  ];