affinirum 1.0.1 → 1.0.2

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/dst/Type.d.ts CHANGED
@@ -28,8 +28,8 @@ export declare class Type implements IType {
28
28
  get isFunction(): boolean;
29
29
  get isNumeric(): boolean;
30
30
  toOptional(): Type;
31
- mergeFunctionAtomRetType(type: Type): Type;
32
- mergeFunctionAtom(type: Type, argc: number): FunctionAtom | undefined;
31
+ functionAtomRetType(type: Type): Type;
32
+ functionAtoms(type: Type, argc: number): FunctionAtom[];
33
33
  reduce(mask: Type): Type | undefined;
34
34
  match(type: IType): boolean;
35
35
  weight(): number;
package/dst/Type.js CHANGED
@@ -53,19 +53,15 @@ export class Type {
53
53
  toOptional() {
54
54
  return this._atoms.length ? Type.union(Type.Void, this) : this;
55
55
  }
56
- mergeFunctionAtomRetType(type) {
57
- const atoms = this._atoms.filter((i) => i instanceof FunctionAtom && (!i.retType || i.retType.match(type)));
58
- return Type.union(...atoms.map((i) => i.retType ?? Type.Unknown));
56
+ functionAtomRetType(type) {
57
+ const atoms = this._atoms.filter((i) => i instanceof FunctionAtom && i.retType.match(type));
58
+ return Type.union(...atoms.map((i) => i.retType));
59
59
  }
60
- mergeFunctionAtom(type, argc) {
61
- if (this.isUnknown || type.isVoid) {
62
- return Type._functionAtom(type, Array.from({ length: argc }).map(() => Type.Unknown), false);
63
- }
64
- const atoms = this._atoms.filter((i) => i instanceof FunctionAtom && i.minArity <= argc && i.maxArity >= argc && (!i.retType || i.retType.match(type)));
65
- if (!atoms.length) {
66
- return undefined;
60
+ functionAtoms(type, argc) {
61
+ if (this.isUnknown) {
62
+ return Type.Function._atoms;
67
63
  }
68
- return Type._functionAtom(Type.union(...atoms.map((i) => i.retType ?? Type.Unknown)), Array.from({ length: argc }).map((_, ix) => Type.union(...atoms.map((i) => i.argType(ix)))), atoms.some((i) => i.isVariadic));
64
+ return this._atoms.filter((i) => i instanceof FunctionAtom && i.minArity <= argc && i.maxArity >= argc && (type.isVoid || i.retType.match(type)));
69
65
  }
70
66
  reduce(mask) {
71
67
  if (mask.isUnknown || mask.isVoid) {
@@ -1,16 +1,17 @@
1
- import { IType } from '../Type.js';
1
+ import { IType, Type } from '../Type.js';
2
2
  export declare class FunctionAtom implements IType {
3
3
  protected readonly _retType?: IType | undefined;
4
4
  protected readonly _argTypes: IType[];
5
5
  protected readonly _minArity: number;
6
6
  protected readonly _isVariadic: boolean;
7
7
  constructor(_retType?: IType | undefined, _argTypes?: IType[], _minArity?: number, _isVariadic?: boolean);
8
- get retType(): IType | undefined;
8
+ get retType(): Type;
9
9
  get minArity(): number;
10
10
  get maxArity(): number;
11
11
  get isVariadic(): boolean;
12
+ get arity(): number;
12
13
  subtypes(): IType[];
13
- argType(index: number): IType;
14
+ argType(index: number): Type;
14
15
  match(type: IType): boolean;
15
16
  weight(): number;
16
17
  toString(): string;
@@ -1,3 +1,4 @@
1
+ import { Type } from '../Type.js';
1
2
  export class FunctionAtom {
2
3
  _retType;
3
4
  _argTypes;
@@ -10,7 +11,7 @@ export class FunctionAtom {
10
11
  this._isVariadic = _isVariadic;
11
12
  }
12
13
  get retType() {
13
- return this._retType;
14
+ return this._retType ?? Type.Unknown;
14
15
  }
15
16
  get minArity() {
16
17
  return this._minArity;
@@ -21,11 +22,14 @@ export class FunctionAtom {
21
22
  get isVariadic() {
22
23
  return this._isVariadic;
23
24
  }
25
+ get arity() {
26
+ return this._argTypes.length;
27
+ }
24
28
  subtypes() {
25
29
  return this._retType ? [this._retType, ...this._argTypes] : [];
26
30
  }
27
31
  argType(index) {
28
- return this._argTypes[index] ?? this._argTypes[this._argTypes.length - 1];
32
+ return (this._argTypes[index] ?? this._argTypes[this._argTypes.length - 1]);
29
33
  }
30
34
  match(type) {
31
35
  if (type instanceof FunctionAtom) {
package/dst/cjs/Type.js CHANGED
@@ -56,19 +56,15 @@ class Type {
56
56
  toOptional() {
57
57
  return this._atoms.length ? Type.union(Type.Void, this) : this;
58
58
  }
59
- mergeFunctionAtomRetType(type) {
60
- const atoms = this._atoms.filter((i) => i instanceof FunctionAtom_js_1.FunctionAtom && (!i.retType || i.retType.match(type)));
61
- return Type.union(...atoms.map((i) => i.retType ?? Type.Unknown));
59
+ functionAtomRetType(type) {
60
+ const atoms = this._atoms.filter((i) => i instanceof FunctionAtom_js_1.FunctionAtom && i.retType.match(type));
61
+ return Type.union(...atoms.map((i) => i.retType));
62
62
  }
63
- mergeFunctionAtom(type, argc) {
64
- if (this.isUnknown || type.isVoid) {
65
- return Type._functionAtom(type, Array.from({ length: argc }).map(() => Type.Unknown), false);
66
- }
67
- const atoms = this._atoms.filter((i) => i instanceof FunctionAtom_js_1.FunctionAtom && i.minArity <= argc && i.maxArity >= argc && (!i.retType || i.retType.match(type)));
68
- if (!atoms.length) {
69
- return undefined;
63
+ functionAtoms(type, argc) {
64
+ if (this.isUnknown) {
65
+ return Type.Function._atoms;
70
66
  }
71
- return Type._functionAtom(Type.union(...atoms.map((i) => i.retType ?? Type.Unknown)), Array.from({ length: argc }).map((_, ix) => Type.union(...atoms.map((i) => i.argType(ix)))), atoms.some((i) => i.isVariadic));
67
+ return this._atoms.filter((i) => i instanceof FunctionAtom_js_1.FunctionAtom && i.minArity <= argc && i.maxArity >= argc && (type.isVoid || i.retType.match(type)));
72
68
  }
73
69
  reduce(mask) {
74
70
  if (mask.isUnknown || mask.isVoid) {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FunctionAtom = void 0;
4
+ const Type_js_1 = require("../Type.js");
4
5
  class FunctionAtom {
5
6
  _retType;
6
7
  _argTypes;
@@ -13,7 +14,7 @@ class FunctionAtom {
13
14
  this._isVariadic = _isVariadic;
14
15
  }
15
16
  get retType() {
16
- return this._retType;
17
+ return this._retType ?? Type_js_1.Type.Unknown;
17
18
  }
18
19
  get minArity() {
19
20
  return this._minArity;
@@ -24,11 +25,14 @@ class FunctionAtom {
24
25
  get isVariadic() {
25
26
  return this._isVariadic;
26
27
  }
28
+ get arity() {
29
+ return this._argTypes.length;
30
+ }
27
31
  subtypes() {
28
32
  return this._retType ? [this._retType, ...this._argTypes] : [];
29
33
  }
30
34
  argType(index) {
31
- return this._argTypes[index] ?? this._argTypes[this._argTypes.length - 1];
35
+ return (this._argTypes[index] ?? this._argTypes[this._argTypes.length - 1]);
32
36
  }
33
37
  match(type) {
34
38
  if (type instanceof FunctionAtom) {
@@ -4,6 +4,7 @@ exports.CallNode = void 0;
4
4
  const Node_js_1 = require("../Node.js");
5
5
  const Constant_js_1 = require("../Constant.js");
6
6
  const ConstantNode_js_1 = require("./ConstantNode.js");
7
+ const ArrayNode_js_1 = require("./ArrayNode.js");
7
8
  const Type_js_1 = require("../Type.js");
8
9
  class CallNode extends Node_js_1.Node {
9
10
  _fnode;
@@ -13,30 +14,45 @@ class CallNode extends Node_js_1.Node {
13
14
  super(frame);
14
15
  this._fnode = _fnode;
15
16
  this._subnodes = _subnodes;
16
- this._type = this._fnode.type.mergeFunctionAtom(Type_js_1.Type.Unknown, _subnodes.length)?.retType ?? Type_js_1.Type.Unknown;
17
+ const functionAtoms = this._fnode.type.functionAtoms(Type_js_1.Type.Unknown, this._subnodes.length);
18
+ if (!functionAtoms.length) {
19
+ this.throwError(`function ${this._fnode.type} does not take ${this._subnodes.length} arguments)`);
20
+ }
21
+ this._type = Type_js_1.Type.union(...functionAtoms.map((i) => i.retType));
17
22
  }
18
23
  get type() {
19
24
  return this._type;
20
25
  }
21
26
  compile(type) {
22
27
  this._fnode = this._fnode.compile(this._fnode.type);
23
- const mergedFunctionAtom = this._fnode.type.mergeFunctionAtom(type, this._subnodes.length);
24
- if (!mergedFunctionAtom) {
25
- this.throwError(`function ${this._fnode.type} does not return ${type} or take ${this._subnodes.length} arguments)`);
28
+ const functionAtoms = this._fnode.type.functionAtoms(type, this._subnodes.length);
29
+ if (!functionAtoms.length) {
30
+ this.throwError(`function ${this._fnode.type} does not take ${this._subnodes.length} arguments returning ${type})`);
31
+ }
32
+ this._type = Type_js_1.Type.union(...functionAtoms.map((i) => i.retType));
33
+ /*
34
+ if (this._subnodes.length < functionAtoms.minArity) {
35
+ this.throwError(`function requires at least ${functionAtoms.minArity} arguments not ${this._subnodes.length}`);
26
36
  }
27
- this._type = mergedFunctionAtom.retType;
28
- if (this._subnodes.length < mergedFunctionAtom.minArity) {
29
- this.throwError(`function requires at least ${mergedFunctionAtom.minArity} arguments not ${this._subnodes.length}`);
37
+ if (this._subnodes.length > functionAtoms.maxArity) {
38
+ this.throwError(`function requires at most ${functionAtoms.maxArity} arguments not ${this._subnodes.length}`);
30
39
  }
31
- if (this._subnodes.length > mergedFunctionAtom.maxArity) {
32
- this.throwError(`function requires at most ${mergedFunctionAtom.maxArity} arguments not ${this._subnodes.length}`);
40
+ */
41
+ if (this._fnode.constant) {
42
+ let constant = true;
43
+ for (let i = 0; i < this._subnodes.length; ++i) {
44
+ const argType = Type_js_1.Type.union(...functionAtoms.map((a) => a.argType(i)));
45
+ this._subnodes[i] = this._subnodes[i].compile(argType);
46
+ constant &&= this._subnodes[i].constant;
47
+ }
48
+ return constant ? new ConstantNode_js_1.ConstantNode(this, new Constant_js_1.Constant(this.evaluate(), this.type)) : this;
33
49
  }
34
- let constant = this._fnode.constant;
35
- for (let i = 0; i < this._subnodes.length; ++i) {
36
- this._subnodes[i] = this._subnodes[i].compile(mergedFunctionAtom.argType(i));
37
- constant &&= this._subnodes[i].constant;
50
+ const arity = functionAtoms.filter((i) => i.isVariadic).map((i) => i.arity).reduce((acc, val) => Math.max(acc, val), 0);
51
+ if (arity > 0) {
52
+ const frame = this._subnodes[arity - 1].starts();
53
+ this._subnodes = this._subnodes.slice(0, arity - 1).concat(new ArrayNode_js_1.ArrayNode(frame.ends(this._subnodes[this._subnodes.length - 1]), this._subnodes.slice(arity - 1)));
38
54
  }
39
- return constant ? new ConstantNode_js_1.ConstantNode(this, new Constant_js_1.Constant(this.evaluate(), this.type)) : this;
55
+ return this;
40
56
  }
41
57
  evaluate() {
42
58
  const func = this._fnode.evaluate();
@@ -15,7 +15,7 @@ class ConstantNode extends Node_js_1.Node {
15
15
  }
16
16
  compile(type) {
17
17
  this._constant.type = this.reduceType(type);
18
- this._subnode = this._subnode?.compile(this._constant.type.mergeFunctionAtomRetType(type));
18
+ this._subnode = this._subnode?.compile(this._constant.type.functionAtomRetType(type));
19
19
  return this;
20
20
  }
21
21
  evaluate() {
@@ -24,14 +24,15 @@ class SwitchNode extends Node_js_1.Node {
24
24
  compile(type) {
25
25
  this._cnode = this._cnode.compile(Type_js_1.Type.Boolean);
26
26
  this._type = type;
27
- let constant = this._cnode.constant;
28
- for (let i = 0; i < this._subnodes.length; ++i) {
29
- this._subnodes[i] = this._subnodes[i].compile(type);
30
- constant &&= this._subnodes[i].constant;
27
+ if (this._cnode.constant) {
28
+ let constant = true;
29
+ for (let i = 0; i < this._subnodes.length; ++i) {
30
+ this._subnodes[i] = this._subnodes[i].compile(type);
31
+ constant &&= this._subnodes[i].constant;
32
+ }
33
+ return constant ? new ConstantNode_js_1.ConstantNode(this, new Constant_js_1.Constant(this.evaluate(), this.type)) : this;
31
34
  }
32
- return constant
33
- ? new ConstantNode_js_1.ConstantNode(this, new Constant_js_1.Constant(this.evaluate(), this.type))
34
- : this;
35
+ return this;
35
36
  }
36
37
  evaluate() {
37
38
  return this._cnode.evaluate() ? this._subnodes[0].evaluate() : this._subnodes[1].evaluate();
@@ -1,6 +1,7 @@
1
1
  import { Node } from '../Node.js';
2
2
  import { Constant } from '../Constant.js';
3
3
  import { ConstantNode } from './ConstantNode.js';
4
+ import { ArrayNode } from './ArrayNode.js';
4
5
  import { Type } from '../Type.js';
5
6
  export class CallNode extends Node {
6
7
  _fnode;
@@ -10,30 +11,45 @@ export class CallNode extends Node {
10
11
  super(frame);
11
12
  this._fnode = _fnode;
12
13
  this._subnodes = _subnodes;
13
- this._type = this._fnode.type.mergeFunctionAtom(Type.Unknown, _subnodes.length)?.retType ?? Type.Unknown;
14
+ const functionAtoms = this._fnode.type.functionAtoms(Type.Unknown, this._subnodes.length);
15
+ if (!functionAtoms.length) {
16
+ this.throwError(`function ${this._fnode.type} does not take ${this._subnodes.length} arguments)`);
17
+ }
18
+ this._type = Type.union(...functionAtoms.map((i) => i.retType));
14
19
  }
15
20
  get type() {
16
21
  return this._type;
17
22
  }
18
23
  compile(type) {
19
24
  this._fnode = this._fnode.compile(this._fnode.type);
20
- const mergedFunctionAtom = this._fnode.type.mergeFunctionAtom(type, this._subnodes.length);
21
- if (!mergedFunctionAtom) {
22
- this.throwError(`function ${this._fnode.type} does not return ${type} or take ${this._subnodes.length} arguments)`);
25
+ const functionAtoms = this._fnode.type.functionAtoms(type, this._subnodes.length);
26
+ if (!functionAtoms.length) {
27
+ this.throwError(`function ${this._fnode.type} does not take ${this._subnodes.length} arguments returning ${type})`);
28
+ }
29
+ this._type = Type.union(...functionAtoms.map((i) => i.retType));
30
+ /*
31
+ if (this._subnodes.length < functionAtoms.minArity) {
32
+ this.throwError(`function requires at least ${functionAtoms.minArity} arguments not ${this._subnodes.length}`);
23
33
  }
24
- this._type = mergedFunctionAtom.retType;
25
- if (this._subnodes.length < mergedFunctionAtom.minArity) {
26
- this.throwError(`function requires at least ${mergedFunctionAtom.minArity} arguments not ${this._subnodes.length}`);
34
+ if (this._subnodes.length > functionAtoms.maxArity) {
35
+ this.throwError(`function requires at most ${functionAtoms.maxArity} arguments not ${this._subnodes.length}`);
27
36
  }
28
- if (this._subnodes.length > mergedFunctionAtom.maxArity) {
29
- this.throwError(`function requires at most ${mergedFunctionAtom.maxArity} arguments not ${this._subnodes.length}`);
37
+ */
38
+ if (this._fnode.constant) {
39
+ let constant = true;
40
+ for (let i = 0; i < this._subnodes.length; ++i) {
41
+ const argType = Type.union(...functionAtoms.map((a) => a.argType(i)));
42
+ this._subnodes[i] = this._subnodes[i].compile(argType);
43
+ constant &&= this._subnodes[i].constant;
44
+ }
45
+ return constant ? new ConstantNode(this, new Constant(this.evaluate(), this.type)) : this;
30
46
  }
31
- let constant = this._fnode.constant;
32
- for (let i = 0; i < this._subnodes.length; ++i) {
33
- this._subnodes[i] = this._subnodes[i].compile(mergedFunctionAtom.argType(i));
34
- constant &&= this._subnodes[i].constant;
47
+ const arity = functionAtoms.filter((i) => i.isVariadic).map((i) => i.arity).reduce((acc, val) => Math.max(acc, val), 0);
48
+ if (arity > 0) {
49
+ const frame = this._subnodes[arity - 1].starts();
50
+ this._subnodes = this._subnodes.slice(0, arity - 1).concat(new ArrayNode(frame.ends(this._subnodes[this._subnodes.length - 1]), this._subnodes.slice(arity - 1)));
35
51
  }
36
- return constant ? new ConstantNode(this, new Constant(this.evaluate(), this.type)) : this;
52
+ return this;
37
53
  }
38
54
  evaluate() {
39
55
  const func = this._fnode.evaluate();
@@ -12,7 +12,7 @@ export class ConstantNode extends Node {
12
12
  }
13
13
  compile(type) {
14
14
  this._constant.type = this.reduceType(type);
15
- this._subnode = this._subnode?.compile(this._constant.type.mergeFunctionAtomRetType(type));
15
+ this._subnode = this._subnode?.compile(this._constant.type.functionAtomRetType(type));
16
16
  return this;
17
17
  }
18
18
  evaluate() {
@@ -21,14 +21,15 @@ export class SwitchNode extends Node {
21
21
  compile(type) {
22
22
  this._cnode = this._cnode.compile(Type.Boolean);
23
23
  this._type = type;
24
- let constant = this._cnode.constant;
25
- for (let i = 0; i < this._subnodes.length; ++i) {
26
- this._subnodes[i] = this._subnodes[i].compile(type);
27
- constant &&= this._subnodes[i].constant;
24
+ if (this._cnode.constant) {
25
+ let constant = true;
26
+ for (let i = 0; i < this._subnodes.length; ++i) {
27
+ this._subnodes[i] = this._subnodes[i].compile(type);
28
+ constant &&= this._subnodes[i].constant;
29
+ }
30
+ return constant ? new ConstantNode(this, new Constant(this.evaluate(), this.type)) : this;
28
31
  }
29
- return constant
30
- ? new ConstantNode(this, new Constant(this.evaluate(), this.type))
31
- : this;
32
+ return this;
32
33
  }
33
34
  evaluate() {
34
35
  return this._cnode.evaluate() ? this._subnodes[0].evaluate() : this._subnodes[1].evaluate();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "affinirum",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Affinirum Scripting Language",
5
5
  "main": "dst/cjs/index.js",
6
6
  "module": "dst/index.js",