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 +2 -2
- package/src/ast.mjs +21 -32
- package/src/expression.mjs +9 -32
- package/src/tokens.mjs +71 -14
- package/types/ast.d.mts +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pacc",
|
|
3
|
-
"version": "8.
|
|
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.
|
|
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
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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
|
+
};
|
package/src/expression.mjs
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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 (
|
|
128
|
-
|
|
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(
|
|
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(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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(
|
|
28
|
-
|
|
29
|
-
|
|
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(
|
|
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
|
|
18
|
+
export namespace ASTTrue {
|
|
18
19
|
function eval(): boolean;
|
|
19
20
|
}
|
|
20
21
|
export type AST = {
|