@puruslang/prettier-plugin-purus 0.7.1 → 0.8.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 +1 -1
- package/src/index.js +74 -18
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -4,25 +4,28 @@ const KEYWORDS = new Set([
|
|
|
4
4
|
"const", "let", "var", "be",
|
|
5
5
|
"fn", "async", "return", "to", "gives",
|
|
6
6
|
"if", "elif", "else", "unless", "then",
|
|
7
|
-
"while", "until", "for", "in", "range",
|
|
8
|
-
"match", "when", "
|
|
7
|
+
"while", "until", "do", "for", "in", "range",
|
|
8
|
+
"match", "when", "switch", "case",
|
|
9
9
|
"try", "catch", "finally", "throw",
|
|
10
10
|
"import", "from", "export", "default", "require", "use", "namespace", "public", "all", "with",
|
|
11
|
-
"add", "sub", "mul", "div", "mod", "neg", "pow",
|
|
11
|
+
"add", "sub", "mul", "div", "fdiv", "mod", "neg", "pow",
|
|
12
12
|
"eq", "neq", "lt", "gt", "le", "ge",
|
|
13
13
|
"and", "or", "not", "pipe", "coal",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
14
|
+
"band", "bor", "bxor", "bnot", "shl", "shr", "ushr",
|
|
15
|
+
"as", "of", "typeof", "instanceof", "type",
|
|
16
|
+
"new", "delete", "this", "await", "yield", "void",
|
|
17
|
+
"class", "extends", "super", "static", "private", "protected", "get", "set",
|
|
18
|
+
"true", "false", "null", "nil", "undefined", "nan", "infinity",
|
|
18
19
|
"break", "continue",
|
|
19
20
|
"list", "object",
|
|
21
|
+
"function",
|
|
20
22
|
]);
|
|
21
23
|
|
|
22
24
|
const BLOCK_STARTERS = new Set([
|
|
23
25
|
"fn", "if", "elif", "else", "unless",
|
|
24
|
-
"while", "until", "for",
|
|
25
|
-
"match", "when", "
|
|
26
|
+
"while", "until", "do", "for",
|
|
27
|
+
"match", "when", "switch", "case",
|
|
28
|
+
"try", "catch", "finally", "class",
|
|
26
29
|
]);
|
|
27
30
|
|
|
28
31
|
function tokenize(source) {
|
|
@@ -136,13 +139,25 @@ function tokenize(source) {
|
|
|
136
139
|
continue;
|
|
137
140
|
}
|
|
138
141
|
|
|
139
|
-
// Number
|
|
142
|
+
// Number (decimal, 0b binary, 0x hex, BigInt n-suffix)
|
|
140
143
|
if (/[0-9]/.test(source[i])) {
|
|
141
144
|
let start = i;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
i++;
|
|
145
|
+
if (source[i] === "0" && i + 1 < len && (source[i + 1] === "b" || source[i + 1] === "B")) {
|
|
146
|
+
i += 2;
|
|
147
|
+
while (i < len && /[01]/.test(source[i])) i++;
|
|
148
|
+
} else if (source[i] === "0" && i + 1 < len && (source[i + 1] === "x" || source[i + 1] === "X")) {
|
|
149
|
+
i += 2;
|
|
150
|
+
while (i < len && /[0-9a-fA-F]/.test(source[i])) i++;
|
|
151
|
+
} else {
|
|
145
152
|
while (i < len && /[0-9]/.test(source[i])) i++;
|
|
153
|
+
if (i < len && source[i] === "." && i + 1 < len && /[0-9]/.test(source[i + 1])) {
|
|
154
|
+
i++;
|
|
155
|
+
while (i < len && /[0-9]/.test(source[i])) i++;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// BigInt suffix: n
|
|
159
|
+
if (i < len && source[i] === "n" && (i + 1 >= len || !/[a-zA-Z0-9_]/.test(source[i + 1]))) {
|
|
160
|
+
i++;
|
|
146
161
|
}
|
|
147
162
|
tokens.push({ type: "number", value: source.slice(start, i) });
|
|
148
163
|
continue;
|
|
@@ -213,6 +228,32 @@ function isEmptyLine(lineTokens) {
|
|
|
213
228
|
return lineTokens.every(t => t.type === "whitespace");
|
|
214
229
|
}
|
|
215
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Returns "postfix", "prefix", or null for the backslash token at content[ti].
|
|
233
|
+
* Postfix: (ident | ] | number) \ (add|sub keyword) → x\add, x\sub
|
|
234
|
+
* Prefix: (add|sub keyword) \ ident → add\x, sub\x
|
|
235
|
+
*/
|
|
236
|
+
function isIncrDecrSlash(content, ti) {
|
|
237
|
+
if (content[ti].value !== "\\") return null;
|
|
238
|
+
let ni = ti + 1;
|
|
239
|
+
while (ni < content.length && content[ni].type === "whitespace") ni++;
|
|
240
|
+
let pi = ti - 1;
|
|
241
|
+
while (pi >= 0 && content[pi].type === "whitespace") pi--;
|
|
242
|
+
const nextTok = ni < content.length ? content[ni] : null;
|
|
243
|
+
const prevTok = pi >= 0 ? content[pi] : null;
|
|
244
|
+
if (nextTok && nextTok.type === "keyword" && (nextTok.value === "add" || nextTok.value === "sub")) {
|
|
245
|
+
if (prevTok && (prevTok.type === "ident" || prevTok.value === "]" || prevTok.type === "number")) {
|
|
246
|
+
return "postfix";
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (prevTok && prevTok.type === "keyword" && (prevTok.value === "add" || prevTok.value === "sub")) {
|
|
250
|
+
if (nextTok && nextTok.type === "ident") {
|
|
251
|
+
return "prefix";
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
|
|
216
257
|
function formatPurus(source, options = {}) {
|
|
217
258
|
const indent = options.tabWidth || 2;
|
|
218
259
|
const useTabs = options.useTabs || false;
|
|
@@ -258,22 +299,37 @@ function formatPurus(source, options = {}) {
|
|
|
258
299
|
// Normalize to single space between tokens, but not before [ or after [, or before ]
|
|
259
300
|
const next = content[ti + 1];
|
|
260
301
|
const prevChar = lineStr.length > 0 ? lineStr[lineStr.length - 1] : "";
|
|
261
|
-
|
|
302
|
+
// Suppress space before an incr/decr backslash
|
|
303
|
+
const nextIsIncrDecrSlash = next && next.value === "\\" && isIncrDecrSlash(content, ti + 1) !== null;
|
|
304
|
+
// Suppress space after an incr/decr backslash
|
|
305
|
+
let prevIsIncrDecrSlash = false;
|
|
306
|
+
{ let pi = ti - 1; while (pi >= 0 && content[pi].type === "whitespace") pi--;
|
|
307
|
+
prevIsIncrDecrSlash = pi >= 0 && content[pi].value === "\\" && isIncrDecrSlash(content, pi) !== null; }
|
|
308
|
+
if (lineStr.length > 0 && next && next.value !== "]" && next.value !== "[" && prevChar !== "[" && !nextIsIncrDecrSlash && !prevIsIncrDecrSlash) {
|
|
262
309
|
lineStr += " ";
|
|
263
310
|
}
|
|
264
311
|
} else {
|
|
265
312
|
if (ti > 0 && content[ti - 1].type !== "whitespace" && lineStr.length > 0) {
|
|
266
313
|
// Adjacent non-whitespace tokens - check if space needed
|
|
267
314
|
const prev = lineStr[lineStr.length - 1];
|
|
315
|
+
let suppressSpace = false;
|
|
268
316
|
if (tok.value === "." || prev === ".") {
|
|
269
|
-
// No space around dots
|
|
317
|
+
suppressSpace = true; // No space around dots
|
|
270
318
|
} else if (tok.value === "," || tok.value === ";") {
|
|
271
|
-
// No space before comma/semicolon
|
|
319
|
+
suppressSpace = true; // No space before comma/semicolon
|
|
272
320
|
} else if (tok.value === "[" || tok.value === "]" || prev === "[") {
|
|
273
|
-
// No space around brackets
|
|
321
|
+
suppressSpace = true; // No space around brackets
|
|
322
|
+
} else if (tok.value === "\\" && isIncrDecrSlash(content, ti) !== null) {
|
|
323
|
+
suppressSpace = true; // No space before incr/decr backslash
|
|
274
324
|
} else {
|
|
275
|
-
|
|
325
|
+
// No space after incr/decr backslash
|
|
326
|
+
let pi = ti - 1;
|
|
327
|
+
while (pi >= 0 && content[pi].type === "whitespace") pi--;
|
|
328
|
+
if (pi >= 0 && content[pi].value === "\\" && isIncrDecrSlash(content, pi) !== null) {
|
|
329
|
+
suppressSpace = true;
|
|
330
|
+
}
|
|
276
331
|
}
|
|
332
|
+
if (!suppressSpace) lineStr += " ";
|
|
277
333
|
}
|
|
278
334
|
lineStr += tok.value;
|
|
279
335
|
}
|