pacc 4.17.0 → 4.18.1

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": "4.17.0",
3
+ "version": "4.18.1",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -19,7 +19,7 @@ import {
19
19
  EOF
20
20
  } from "./tokens.mjs";
21
21
 
22
- export function binop(op, left, right) {
22
+ export function binop(op, left, right, fallback) {
23
23
  switch (op) {
24
24
  case DOUBLE_BAR:
25
25
  return left || right;
@@ -46,6 +46,8 @@ export function binop(op, left, right) {
46
46
  case DIVIDE:
47
47
  return left / right;
48
48
  }
49
+
50
+ return fallback(op, left, right);
49
51
  }
50
52
 
51
53
  export function parse(context) {
@@ -55,6 +57,43 @@ export function parse(context) {
55
57
  const error = new Error(message);
56
58
  throw error;
57
59
  }
60
+ function binopError(op, left, right) {
61
+ error(`Unexpected '${op.str || op}'`);
62
+ }
63
+
64
+ const pathEval = (node, current) => {
65
+ let result = current;
66
+
67
+ for (const p of node.path) {
68
+ switch (typeof p) {
69
+ case "string":
70
+ case "number":
71
+ if(typeof result === 'function') {
72
+ const r = [];
73
+ for(const x of result()) {
74
+ r.push(x[p]);
75
+ }
76
+ result = r;
77
+ }
78
+ else {
79
+ result = result[p];
80
+ }
81
+ break;
82
+ case "object":
83
+ function* filter() {
84
+ for (const x of result) {
85
+ if (p.eval(p, x)) {
86
+ yield x;
87
+ }
88
+ }
89
+ }
90
+ //result = filter;
91
+ result = [...filter()];
92
+ }
93
+ }
94
+
95
+ return result;
96
+ };
58
97
 
59
98
  const advance = () => {
60
99
  const { value, done } = context.tokens.next();
@@ -81,7 +120,7 @@ export function parse(context) {
81
120
  const node = expression(0);
82
121
  expect(CLOSE_BRACKET);
83
122
  if (typeof node === "number") {
84
- return { path: [node] };
123
+ return { eval: pathEval, path: [node] };
85
124
  }
86
125
  return node;
87
126
  }
@@ -93,7 +132,7 @@ export function parse(context) {
93
132
 
94
133
  switch (typeof token) {
95
134
  case "string":
96
- return { path: [token] };
135
+ return { eval: pathEval, path: [token] };
97
136
  case "number":
98
137
  case "bigint":
99
138
  case "boolean":
@@ -113,10 +152,17 @@ export function parse(context) {
113
152
  case "number":
114
153
  case "bigint":
115
154
  case "boolean":
116
- return binop(token, left, right);
155
+ return binop(token, left, right, binopError);
117
156
  }
118
157
  }
119
158
  return {
159
+ eval: (node, current) =>
160
+ binop(
161
+ token,
162
+ left?.eval ? left.eval(left, current) : left,
163
+ right?.eval ? right.eval(right, current) : right,
164
+ binopError
165
+ ),
120
166
  token,
121
167
  left,
122
168
  right
@@ -124,12 +170,12 @@ export function parse(context) {
124
170
  }
125
171
 
126
172
  case "infix": {
127
- const right = expression(token.precedence);
173
+ let right = expression(token.precedence);
128
174
  if (typeof left === typeof right) {
129
175
  switch (typeof left) {
130
176
  case "number":
131
177
  case "bigint":
132
- return binop(token, left, right);
178
+ return binop(token, left, right, binopError);
133
179
  }
134
180
  }
135
181
  if (token === DOT) {
@@ -142,13 +188,21 @@ export function parse(context) {
142
188
  right.path.unshift(left);
143
189
  return right;
144
190
  }
145
- return { path: [left.token, right.token] };
191
+ return { eval: pathEval, path: [left.token, right.token] };
146
192
  }
147
193
 
148
194
  if (right.token === EOF) {
149
195
  error("unexpected EOF");
150
196
  }
197
+
151
198
  return {
199
+ eval: (node, current) =>
200
+ binop(
201
+ token,
202
+ left?.eval ? left.eval(left, current) : left,
203
+ right?.eval ? right.eval(right, current) : right,
204
+ binopError
205
+ ),
152
206
  token,
153
207
  left,
154
208
  right
@@ -184,5 +238,11 @@ export function parse(context) {
184
238
 
185
239
  advance();
186
240
 
187
- return expression(token.precedence ?? 0);
241
+ const result = expression(token.precedence ?? 0);
242
+
243
+ if (context.exec !== false && result?.eval) {
244
+ return result.eval(result, context.root);
245
+ }
246
+
247
+ return result;
188
248
  }
@@ -27,7 +27,7 @@ import { convertValue } from "./attributes.mjs";
27
27
  * @param {Object} definition type def
28
28
  */
29
29
  export function setAttribute(object, expression, value, definition) {
30
- const { path } = parse({ tokens: tokens(expression) });
30
+ const { path } = parse({ tokens: tokens(expression), exec: false });
31
31
 
32
32
  let anchor, anchorKey;
33
33
 
@@ -60,7 +60,7 @@ export function setAttribute(object, expression, value, definition) {
60
60
  * @returns {any} value associated with the given property name
61
61
  */
62
62
  export function getAttribute(object, expression, definition) {
63
- const { path } = parse({ tokens: tokens(expression) });
63
+ const { path } = parse({ tokens: tokens(expression), exec: false });
64
64
 
65
65
  for (const key of path) {
66
66
  if (object !== undefined) {
@@ -1,2 +1,2 @@
1
- export function binop(op: any, left: any, right: any): any;
1
+ export function binop(op: any, left: any, right: any, fallback: any): any;
2
2
  export function parse(context: any): any;