pacc 8.2.0 → 8.3.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pacc",
3
- "version": "8.2.0",
3
+ "version": "8.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -42,7 +42,7 @@
42
42
  "browser-ava": "^2.3.51",
43
43
  "c8": "^10.1.3",
44
44
  "documentation": "^14.0.3",
45
- "semantic-release": "^25.0.2",
45
+ "semantic-release": "^25.0.3",
46
46
  "typescript": "^5.9.3"
47
47
  },
48
48
  "engines": {
package/src/ast.mjs CHANGED
@@ -30,40 +30,12 @@ export function binopError(op, left, right) {
30
30
  }
31
31
 
32
32
  export function binop(op, left, right, fallback) {
33
- switch (op) {
34
- case DOUBLE_BAR:
35
- return left || right;
36
- case DOUBLE_AMPERSAND:
37
- return left && right;
38
- case EQUAL:
39
- return left == right;
40
- case NOT_EQUAL:
41
- return left != right;
42
- case GREATER:
43
- return left > right;
44
- case LESS:
45
- return left < right;
46
- case GREATER_EQUAL:
47
- return left >= right;
48
- case LESS_EQUAL:
49
- return left <= right;
50
- case PLUS:
51
- return left + right;
52
- case MINUS:
53
- return left - right;
54
- case STAR:
55
- return left * right;
56
- case DIVIDE:
57
- return left / right;
58
- }
33
+
34
+ if(op.binop) { return op.binop(left,right); }
59
35
 
60
36
  return fallback(op, left, right);
61
37
  }
62
38
 
63
- export const ASTNodeTrue = {
64
- eval: () => true
65
- };
66
-
67
39
  export function binopEval(node, current, context) {
68
40
  return binop(
69
41
  node.token,
@@ -75,6 +47,19 @@ export function binopEval(node, current, context) {
75
47
  );
76
48
  }
77
49
 
50
+ export function ASTBinop(token, left, right) {
51
+ if (!left.eval && !right.eval) {
52
+ return binop(token, left, right, binopError);
53
+ }
54
+
55
+ return {
56
+ eval: binopEval,
57
+ token,
58
+ left,
59
+ right
60
+ };
61
+ }
62
+
78
63
  export function pathEval(node, current, context) {
79
64
  let collection = false;
80
65
  let first = true;
@@ -91,9 +76,9 @@ export function pathEval(node, current, context) {
91
76
  current = current.map(x => x[item]);
92
77
  } else {
93
78
  current =
94
- (current instanceof Map ? current.get(item) : current[item]);
79
+ current instanceof Map ? current.get(item) : current[item];
95
80
 
96
- if(first && current === undefined) {
81
+ if (first && current === undefined) {
97
82
  current = context.getGlobal(item);
98
83
  }
99
84
  }
@@ -120,3 +105,7 @@ export function functionEval(node, current, context) {
120
105
  );
121
106
  return context.getGlobal(node.path[0])(...args);
122
107
  }
108
+
109
+ export const ASTTrue = {
110
+ eval: () => true
111
+ };
@@ -11,12 +11,11 @@ import {
11
11
  } from "./tokens.mjs";
12
12
 
13
13
  import {
14
- binopError,
15
- binop,
16
14
  binopEval,
17
15
  pathEval,
18
16
  functionEval,
19
- ASTNodeTrue
17
+ ASTTrue,
18
+ ASTBinop
20
19
  } from "./ast.mjs";
21
20
 
22
21
  /**
@@ -65,7 +64,7 @@ export function parse(input, context = {}) {
65
64
  case OPEN_BRACKET: {
66
65
  if (token === CLOSE_BRACKET) {
67
66
  advance();
68
- return ASTNodeTrue;
67
+ return ASTTrue;
69
68
  }
70
69
 
71
70
  const node = expression(0);
@@ -101,38 +100,16 @@ export function parse(input, context = {}) {
101
100
 
102
101
  const led = (last, left) => {
103
102
  switch (last.type) {
104
- case "infixr": {
105
- const right = expression(last.precedence - 1);
106
- if (typeof left === typeof right) {
107
- switch (typeof left) {
108
- case "string":
109
- case "number":
110
- case "bigint":
111
- case "boolean":
112
- return binop(last, left, right, binopError);
113
- }
114
- }
115
-
116
- return {
117
- eval: binopEval,
118
- token: last,
119
- left,
120
- right
121
- };
122
- }
103
+ case "infixr":
104
+ return ASTBinop(last, left, expression(last.precedence - 1));
123
105
 
124
106
  case "infix": {
125
107
  let right = expression(last.precedence);
126
108
 
127
- if (typeof left === typeof right) {
128
- switch (typeof left) {
129
- case "string":
130
- case "number":
131
- case "bigint":
132
- case "boolean":
133
- return binop(last, left, right, binopError);
134
- }
109
+ if (last.binop) {
110
+ return ASTBinop(last, left, right);
135
111
  }
112
+
136
113
  if (last === DOT) {
137
114
  if (left.path) {
138
115
  left.path.push(...right.path);
@@ -178,7 +155,7 @@ export function parse(input, context = {}) {
178
155
  case OPEN_BRACKET: {
179
156
  if (token === CLOSE_BRACKET) {
180
157
  advance();
181
- left.path.push(ASTNodeTrue);
158
+ left.path.push(ASTTrue);
182
159
  } else {
183
160
  const predicate = expression(0);
184
161
  expect(CLOSE_BRACKET);
package/src/tokens.mjs CHANGED
@@ -11,29 +11,80 @@ const lookup = {};
11
11
  /**
12
12
  *
13
13
  * @param {string} str
14
+ * @param {number} [precedence]
15
+ * @param {string} [type]
14
16
  * @returns {Token}
15
17
  */
16
- function createToken(str, precedence = 0, type) {
18
+ function createToken(str, precedence = 0, type, binop) {
17
19
  const token = { str, precedence, type };
20
+ if (binop) {
21
+ token.binop = binop;
22
+ }
18
23
  lookup[str] = [token];
19
24
  return token;
20
25
  }
21
26
 
22
- export /** @type {Token} */ const PLUS = createToken("+", 50, "infix");
23
- export /** @type {Token} */ const MINUS = createToken("-", 50, "infix");
24
- export /** @type {Token} */ const STAR = createToken("*", 60, "infix");
25
- export /** @type {Token} */ const DIVIDE = createToken("/", 60, "infix");
27
+ export /** @type {Token} */ const PLUS = createToken(
28
+ "+",
29
+ 50,
30
+ "infix",
31
+ (left, right) => left + right
32
+ );
33
+ export /** @type {Token} */ const MINUS = createToken(
34
+ "-",
35
+ 50,
36
+ "infix",
37
+ (left, right) => left - right
38
+ );
39
+ export /** @type {Token} */ const STAR = createToken(
40
+ "*",
41
+ 60,
42
+ "infix",
43
+ (left, right) => left * right
44
+ );
45
+ export /** @type {Token} */ const DIVIDE = createToken(
46
+ "/",
47
+ 60,
48
+ "infix",
49
+ (left, right) => left / right
50
+ );
26
51
  export /** @type {Token} */ const NOT = createToken("!");
27
- export /** @type {Token} */ const NOT_EQUAL = createToken("!=", 40, "infixr");
28
- export /** @type {Token} */ const EQUAL = createToken("=", 40, "infixr");
29
- export /** @type {Token} */ const GREATER = createToken(">", 40, "infixr");
52
+ export /** @type {Token} */ const NOT_EQUAL = createToken(
53
+ "!=",
54
+ 40,
55
+ "infixr",
56
+ (left, right) => left != right
57
+ );
58
+ export /** @type {Token} */ const EQUAL = createToken(
59
+ "=",
60
+ 40,
61
+ "infixr",
62
+ (left, right) => left == right
63
+ );
64
+ export /** @type {Token} */ const GREATER = createToken(
65
+ ">",
66
+ 40,
67
+ "infixr",
68
+ (left, right) => left > right
69
+ );
30
70
  export /** @type {Token} */ const GREATER_EQUAL = createToken(
31
71
  ">=",
32
72
  40,
33
- "infixr"
73
+ "infixr",
74
+ (left, right) => left >= right
75
+ );
76
+ export /** @type {Token} */ const LESS = createToken(
77
+ "<",
78
+ 40,
79
+ "infixr",
80
+ (left, right) => left < right
81
+ );
82
+ export /** @type {Token} */ const LESS_EQUAL = createToken(
83
+ "<=",
84
+ 40,
85
+ "infixr",
86
+ (left, right) => left <= right
34
87
  );
35
- export /** @type {Token} */ const LESS = createToken("<", 40, "infixr");
36
- export /** @type {Token} */ const LESS_EQUAL = createToken("<=", 40, "infixr");
37
88
  export /** @type {Token} */ const OPEN_ROUND = createToken("(", 40, "prefix");
38
89
  export /** @type {Token} */ const CLOSE_ROUND = createToken(")", 0, "infix");
39
90
  export /** @type {Token} */ const OPEN_BRACKET = createToken("[", 10, "prefix");
@@ -41,7 +92,7 @@ export /** @type {Token} */ const CLOSE_BRACKET = createToken("]", 0, "infix");
41
92
  export /** @type {Token} */ const OPEN_CURLY = createToken("{");
42
93
  export /** @type {Token} */ const CLOSE_CURLY = createToken("}");
43
94
  export /** @type {Token} */ const QUESTION = createToken("?", 20, "infix");
44
- export /** @type {Token} */ const COLON = createToken(":", "infix");
95
+ export /** @type {Token} */ const COLON = createToken(":", undefined, "infix");
45
96
  export /** @type {Token} */ const SEMICOLON = createToken(";");
46
97
  export /** @type {Token} */ const COMMA = createToken(",");
47
98
  export /** @type {Token} */ const DOT = createToken(".", 80, "infix");
@@ -49,10 +100,16 @@ export /** @type {Token} */ const AMPERSAND = createToken("&");
49
100
  export /** @type {Token} */ const DOUBLE_AMPERSAND = createToken(
50
101
  "&&",
51
102
  30,
52
- "infixr"
103
+ "infixr",
104
+ (left, right) => left && right
53
105
  );
54
106
  export /** @type {Token} */ const BAR = createToken("|");
55
- export /** @type {Token} */ const DOUBLE_BAR = createToken("||", 30, "infixr");
107
+ export /** @type {Token} */ const DOUBLE_BAR = createToken(
108
+ "||",
109
+ 30,
110
+ "infixr",
111
+ (left, right) => left || right
112
+ );
56
113
  export /** @type {Token} */ const IDENTIFIER = createToken("IDENTIFIER", 0);
57
114
  export /** @type {Token} */ const EOF = createToken("EOF", -1, "eof");
58
115
 
package/types/ast.d.mts CHANGED
@@ -12,9 +12,10 @@
12
12
  export function binopError(op: Token, left: AST, right: AST): void;
13
13
  export function binop(op: any, left: any, right: any, fallback: any): any;
14
14
  export function binopEval(node: any, current: any, context: any): any;
15
+ export function ASTBinop(token: any, left: any, right: any): any;
15
16
  export function pathEval(node: any, current: any, context: any): any;
16
17
  export function functionEval(node: any, current: any, context: any): any;
17
- export namespace ASTNodeTrue {
18
+ export namespace ASTTrue {
18
19
  function eval(): boolean;
19
20
  }
20
21
  export type AST = {