pacc 8.3.1 → 8.4.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": "8.3.1",
3
+ "version": "8.4.1",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "ava": "^6.4.1",
42
- "browser-ava": "^2.3.51",
42
+ "browser-ava": "^2.3.52",
43
43
  "c8": "^10.1.3",
44
44
  "documentation": "^14.0.3",
45
45
  "semantic-release": "^25.0.3",
package/src/ast.mjs CHANGED
@@ -30,7 +30,7 @@ function binopError(op, left, right) {
30
30
  }
31
31
 
32
32
  export function binop(op, left, right, fallback) {
33
- if(op.binop) { return op.binop(left,right); }
33
+ if(op.led) { return op.led(left,right); }
34
34
 
35
35
  return fallback(op, left, right);
36
36
  }
@@ -11,15 +11,7 @@ import {
11
11
  } from "./tokens.mjs";
12
12
  import { pathEval, functionEval, ASTTrue, ASTBinop } from "./ast.mjs";
13
13
 
14
- /**
15
- *
16
- * @param {string} message
17
- */
18
- export function error(message) {
19
- throw new Error(message);
20
- }
21
-
22
- export function parse(input, context = {}) {
14
+ export function parseOnly(input, context = {}) {
23
15
  context.getGlobal ||= a => globals[a];
24
16
 
25
17
  input = tokens(input, context);
@@ -40,55 +32,51 @@ export function parse(input, context = {}) {
40
32
 
41
33
  const expect = expected => {
42
34
  if (token !== expected) {
43
- error(`unexpected '${token?.str || token}' expecting '${expected.str}'`);
35
+ throw new Error(
36
+ `unexpected '${token?.str || token}' expecting '${expected.str}'`,
37
+ { cause: token }
38
+ );
44
39
  }
45
40
  advance();
46
41
  };
47
42
 
48
43
  const nud = (last, left) => {
49
- switch (last.type) {
50
- case "prefix":
51
- switch (last) {
52
- case OPEN_ROUND: {
53
- const node = expression(0);
54
- expect(CLOSE_ROUND);
55
- return node;
56
- }
57
- case OPEN_BRACKET: {
58
- if (token === CLOSE_BRACKET) {
59
- advance();
60
- return ASTTrue;
61
- }
62
-
63
- const node = expression(0);
64
- expect(CLOSE_BRACKET);
65
- switch (typeof node) {
66
- case "string":
67
- case "number":
68
- return { eval: pathEval, path: [node] };
69
- }
70
-
71
- return node;
72
- }
44
+ switch (last) {
45
+ case OPEN_ROUND: {
46
+ const node = expression(0);
47
+ expect(CLOSE_ROUND);
48
+ return node;
49
+ }
50
+ case OPEN_BRACKET: {
51
+ if (token === CLOSE_BRACKET) {
52
+ advance();
53
+ return ASTTrue;
73
54
  }
74
- return { token: last, left, right: expression(last.precedence) };
75
- case "eof":
76
- error("unexpected EOF");
77
- }
78
55
 
79
- switch (typeof last) {
80
- case "string":
81
- case "number":
82
- case "bigint":
83
- case "boolean":
84
- return last;
56
+ const node = expression(0);
57
+ expect(CLOSE_BRACKET);
58
+
59
+ switch (typeof node) {
60
+ case "string":
61
+ case "number":
62
+ return { eval: pathEval, path: [node] };
63
+ }
64
+
65
+ return node;
66
+ }
67
+
68
+ case IDENTIFIER:
69
+ return { eval: pathEval, path: [value] };
70
+
71
+ case EOF:
72
+ throw new Error("unexpected EOF");
85
73
  }
86
74
 
87
- if (last === IDENTIFIER) {
88
- return { eval: pathEval, path: [value] };
75
+ if (last.type === "prefix") {
76
+ return { token: last, left, right: expression(last.precedence) };
89
77
  }
90
78
 
91
- return { token: last };
79
+ return last;
92
80
  };
93
81
 
94
82
  const led = (last, left) => {
@@ -100,50 +88,40 @@ export function parse(input, context = {}) {
100
88
  const right = expression(last.precedence);
101
89
 
102
90
  if (last === DOT) {
103
- if (left.path) {
104
- left.path.push(...right.path);
105
- return left;
106
- }
107
-
108
- if (left.eval) {
109
- right.path.unshift(left);
110
- return right;
111
- }
112
-
113
- return { eval: pathEval, path: [left.token, right.token] };
91
+ return last.led(left, right);
114
92
  }
115
93
 
116
94
  return ASTBinop(last, left, right);
117
95
  }
118
- case "prefix":
119
- switch (last) {
120
- case OPEN_ROUND: {
121
- const args = [];
122
- while (token !== CLOSE_ROUND) {
123
- args.push(expression(0));
124
- if (token === COMMA) {
125
- advance();
126
- }
127
- }
128
- left.args = args;
129
- left.eval = functionEval;
96
+ }
130
97
 
98
+ switch (last) {
99
+ case OPEN_ROUND: {
100
+ const args = [];
101
+ while (token !== CLOSE_ROUND) {
102
+ args.push(expression(0));
103
+ if (token === COMMA) {
131
104
  advance();
132
-
133
- return left;
134
- }
135
- case OPEN_BRACKET: {
136
- if (token === CLOSE_BRACKET) {
137
- advance();
138
- left.path.push(ASTTrue);
139
- } else {
140
- const predicate = expression(0);
141
- expect(CLOSE_BRACKET);
142
- left.path.push(predicate);
143
- }
144
- return left;
145
105
  }
146
106
  }
107
+ left.args = args;
108
+ left.eval = functionEval;
109
+
110
+ advance();
111
+
112
+ return left;
113
+ }
114
+ case OPEN_BRACKET: {
115
+ if (token === CLOSE_BRACKET) {
116
+ advance();
117
+ left.path.push(ASTTrue);
118
+ } else {
119
+ const predicate = expression(0);
120
+ expect(CLOSE_BRACKET);
121
+ left.path.push(predicate);
122
+ }
123
+ return left;
124
+ }
147
125
  }
148
126
 
149
127
  return { token };
@@ -165,17 +143,12 @@ export function parse(input, context = {}) {
165
143
 
166
144
  advance();
167
145
 
168
- let result = expression(token.precedence ?? 0);
169
-
170
- if (context.exec !== false && result?.eval) {
171
- result = result.eval(result, context.root, context);
172
-
173
- /*if (typeof result === "function") {
174
- return [...result()];
175
- }*/
176
- }
146
+ return expression(token.precedence ?? 0);
147
+ }
177
148
 
178
- return result;
149
+ export function parse(input, context) {
150
+ const result = parseOnly(input, context);
151
+ return result.eval ? result.eval(result, context.root, context) : result;
179
152
  }
180
153
 
181
154
  export const globals = {
@@ -16,7 +16,7 @@ import {
16
16
  STAR,
17
17
  IDENTIFIER
18
18
  } from "./tokens.mjs";
19
- import { parse } from "./expression.mjs";
19
+ import { parseOnly } from "./expression.mjs";
20
20
  import { toInternal } from "./attributes.mjs";
21
21
 
22
22
  /**
@@ -28,7 +28,7 @@ import { toInternal } from "./attributes.mjs";
28
28
  * @param {Object} definition type def
29
29
  */
30
30
  export function setAttribute(object, expression, value, definition) {
31
- const { path } = parse(expression, { exec: false });
31
+ const { path } = parseOnly(expression);
32
32
 
33
33
  let anchor, anchorKey;
34
34
 
@@ -61,7 +61,7 @@ export function setAttribute(object, expression, value, definition) {
61
61
  * @returns {any} value associated with the given property name
62
62
  */
63
63
  export function getAttribute(object, expression, definition) {
64
- const { path } = parse(expression, { exec: false });
64
+ const { path } = parseOnly(expression);
65
65
 
66
66
  for (const key of path) {
67
67
  if (object !== undefined) {
package/src/tokens.mjs CHANGED
@@ -13,12 +13,13 @@ const lookup = {};
13
13
  * @param {string} str
14
14
  * @param {number} [precedence]
15
15
  * @param {string} [type]
16
+ * @param {Function} [led]
16
17
  * @returns {Token}
17
18
  */
18
- function createToken(str, precedence = 0, type, binop) {
19
+ function createToken(str, precedence = 0, type, led) {
19
20
  const token = { str, precedence, type };
20
- if (binop) {
21
- token.binop = binop;
21
+ if (led) {
22
+ token.led = led;
22
23
  }
23
24
  lookup[str] = [token];
24
25
  return token;
@@ -95,7 +96,20 @@ export /** @type {Token} */ const QUESTION = createToken("?", 20, "infix");
95
96
  export /** @type {Token} */ const COLON = createToken(":", undefined, "infix");
96
97
  export /** @type {Token} */ const SEMICOLON = createToken(";");
97
98
  export /** @type {Token} */ const COMMA = createToken(",");
98
- export /** @type {Token} */ const DOT = createToken(".", 80, "infix");
99
+ export /** @type {Token} */ const DOT = createToken(
100
+ ".",
101
+ 80,
102
+ "infix",
103
+ (left, right) => {
104
+ if (left.path) {
105
+ right.path.unshift(...left.path);
106
+ } else {
107
+ console.log("DOT",right);
108
+ right.path.unshift(left);
109
+ }
110
+ return right;
111
+ }
112
+ );
99
113
  export /** @type {Token} */ const AMPERSAND = createToken("&");
100
114
  export /** @type {Token} */ const DOUBLE_AMPERSAND = createToken(
101
115
  "&&",
@@ -1,9 +1,5 @@
1
- /**
2
- *
3
- * @param {string} message
4
- */
5
- export function error(message: string): void;
6
- export function parse(input: any, context?: {}): any;
1
+ export function parseOnly(input: any, context?: {}): any;
2
+ export function parse(input: any, context: any): any;
7
3
  export namespace globals {
8
4
  export function _in(a: any, b: any): boolean;
9
5
  export { _in as in };