@tilua/compiler 7.0.0 → 8.0.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/README.md +16 -4
- package/dist/{chunk-NM3EVX2J.js → chunk-TOP7NC3Z.js} +14 -2
- package/dist/cli.cjs +13 -2
- package/dist/cli.js +1 -1
- package/dist/index.cjs +13 -2
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -74,9 +74,10 @@ JavaScript module the build loads.
|
|
|
74
74
|
| `const` / `let` | `local` |
|
|
75
75
|
| `class C { … }` | one table for the class, one per instance — see below |
|
|
76
76
|
| `return [a, b]` | `return { a, b }` — several results are an array |
|
|
77
|
-
| `for (const item
|
|
78
|
-
| `for (const item
|
|
79
|
-
| `for (const [k, v]
|
|
77
|
+
| `for (const item of xs)` | `for _, item in xs do … end` — an array or a table walked for its values |
|
|
78
|
+
| `for (const item of step)` | `for item in step do … end` — an iterator function |
|
|
79
|
+
| `for (const [k, v] of pairs(t))` | `for item in unpack(pairs(t), 1, 3) do local k, v = item[1], item[2] … end` — an iteration is `[step, state, first]` |
|
|
80
|
+
| `for (const key in t)` | `for key in pairs(t) do … end` — a table's keys, as in TypeScript |
|
|
80
81
|
| `t ??= v` | `if t == nil then t = v end` — what addresses `t` read once, into locals |
|
|
81
82
|
| `{ m() { … } }` | `{ m = function(this) … end }` — called with `:` |
|
|
82
83
|
| `break outer` from a loop inside `outer` | a flag `outer` declares, raised, and a `break`; after each loop on the way out, a check that breaks again — or, at `outer`, does the `break` or `continue` |
|
|
@@ -117,7 +118,7 @@ Luau without asking:
|
|
|
117
118
|
| `a += b`, `a // b` | `a = a + (b)`, `math.floor(a / (b))` | as written |
|
|
118
119
|
| `continue` | a `break` out of a one-pass `repeat` | as written |
|
|
119
120
|
| `c ? a : b`, `a?.b`, `a ?? b` | `and`/`or` where neither arm can be `false`, else a function called on the spot | `if c then a else b` |
|
|
120
|
-
| `for (const x
|
|
121
|
+
| `for (const x of xs)` | `ipairs(xs)` where `xs` is an array by its type; otherwise `tilua_each(xs)`, which walks a table as Luau would — its `__iter` if it has one, `next` if not | `for _, x in xs do` |
|
|
121
122
|
| `1_000`, `0b101` | plain numbers | as written |
|
|
122
123
|
| `@native` and other attributes | dropped | kept |
|
|
123
124
|
| another file of the bundle | `loadfile` | `require` by path |
|
|
@@ -430,6 +431,17 @@ How a file is loaded depends on the Lua (see [Lua and Luau](#lua-and-luau)):
|
|
|
430
431
|
Either way the files have to stay where they were written, relative to the
|
|
431
432
|
entry's.
|
|
432
433
|
|
|
434
|
+
<!-- compatibility:start -->
|
|
435
|
+
## Compatibility
|
|
436
|
+
|
|
437
|
+
`@tilua/compiler@8.0.0` works with these tilua packages. *Released with* is the
|
|
438
|
+
version it was built and tested against.
|
|
439
|
+
|
|
440
|
+
| Package | Range | Released with | |
|
|
441
|
+
| --- | --- | --- | --- |
|
|
442
|
+
| `@tilua/parser` | `^8.0.0` | 8.0.0 | dependency |
|
|
443
|
+
<!-- compatibility:end -->
|
|
444
|
+
|
|
433
445
|
## Development
|
|
434
446
|
|
|
435
447
|
```bash
|
|
@@ -1448,8 +1448,15 @@ end`).body.statements, out);
|
|
|
1448
1448
|
item = this.names.fresh("item");
|
|
1449
1449
|
prelude.push(...this.destructure(variable, identifier(item), "declare"));
|
|
1450
1450
|
}
|
|
1451
|
-
const form = this.options.types?.loops.get(node) ?? { walks: "values", viaIter: false };
|
|
1451
|
+
const form = this.options.types?.loops.get(node) ?? { walks: node.over === "keys" ? "keys" : "values", viaIter: false };
|
|
1452
1452
|
let source = this.expression(node.iterator);
|
|
1453
|
+
if (form.walks === "keys") {
|
|
1454
|
+
return [genericFor(
|
|
1455
|
+
[item],
|
|
1456
|
+
[call(this.builtin("pairs"), [source])],
|
|
1457
|
+
this.loopBody51(this.block(node.body, prelude)).statements
|
|
1458
|
+
)];
|
|
1459
|
+
}
|
|
1453
1460
|
if (form.viaIter) source = methodCall(source, "__iter", []);
|
|
1454
1461
|
const variables = form.walks === "values" ? [this.names.fresh("_"), item] : [item];
|
|
1455
1462
|
let iterators = form.walks === "iteration" ? [call(this.helper("unpack"), [source, number(1), number(3)])] : [source];
|
|
@@ -2570,6 +2577,7 @@ function usesVararg(node) {
|
|
|
2570
2577
|
return Object.values(record).some(usesVararg);
|
|
2571
2578
|
}
|
|
2572
2579
|
function calleePath(path) {
|
|
2580
|
+
if (!/^[A-Za-z_]\w*(\.[A-Za-z_]\w*)*$/.test(path)) return parseExpressionFromSource(path);
|
|
2573
2581
|
const [head, ...rest] = path.split(".");
|
|
2574
2582
|
return rest.reduce((value, name) => member(value, name), identifier(head));
|
|
2575
2583
|
}
|
|
@@ -2791,6 +2799,7 @@ import {
|
|
|
2791
2799
|
directivesOf,
|
|
2792
2800
|
applyDirectives,
|
|
2793
2801
|
UNUSED_EXPECT_ERROR,
|
|
2802
|
+
UNUSED_EXPECT_WARNING,
|
|
2794
2803
|
ParseError,
|
|
2795
2804
|
LexError,
|
|
2796
2805
|
luauString as luauString4
|
|
@@ -3212,7 +3221,7 @@ async function bundle(options) {
|
|
|
3212
3221
|
}
|
|
3213
3222
|
for (const [file, fileDirectives] of directives) {
|
|
3214
3223
|
const semantic = diagnostics.filter((d) => d.file === file && (d.category === "scope" || d.category === "type"));
|
|
3215
|
-
const { kept, unusedExpectErrors } = applyDirectives(fileDirectives, semantic, (d) => d.line);
|
|
3224
|
+
const { kept, unusedExpectErrors, unusedExpectWarnings } = applyDirectives(fileDirectives, semantic, (d) => d.line, (d) => d.severity === "warning");
|
|
3216
3225
|
const suppressed = new Set(semantic.filter((d) => !kept.includes(d)));
|
|
3217
3226
|
const remaining = diagnostics.filter((d) => !suppressed.has(d));
|
|
3218
3227
|
diagnostics.length = 0;
|
|
@@ -3221,6 +3230,9 @@ async function bundle(options) {
|
|
|
3221
3230
|
for (const d of unusedExpectErrors) {
|
|
3222
3231
|
diagnostics.push({ file, message: UNUSED_EXPECT_ERROR, line: d.line, column: d.column, category: "type" });
|
|
3223
3232
|
}
|
|
3233
|
+
for (const d of unusedExpectWarnings) {
|
|
3234
|
+
diagnostics.push({ file, message: UNUSED_EXPECT_WARNING, line: d.line, column: d.column, category: "type", severity: "warning" });
|
|
3235
|
+
}
|
|
3224
3236
|
}
|
|
3225
3237
|
const moduleProblems = new Set(diagnostics.filter((d) => d.category === "module").map((d) => `${d.file}:${d.line}:${d.column}:${d.message}`));
|
|
3226
3238
|
const reported = diagnostics.filter((d) => d.category !== "type" || !moduleProblems.has(`${d.file}:${d.line}:${d.column}:${d.message}`));
|
package/dist/cli.cjs
CHANGED
|
@@ -1465,8 +1465,15 @@ end`).body.statements, out2);
|
|
|
1465
1465
|
item = this.names.fresh("item");
|
|
1466
1466
|
prelude.push(...this.destructure(variable, identifier(item), "declare"));
|
|
1467
1467
|
}
|
|
1468
|
-
const form = this.options.types?.loops.get(node) ?? { walks: "values", viaIter: false };
|
|
1468
|
+
const form = this.options.types?.loops.get(node) ?? { walks: node.over === "keys" ? "keys" : "values", viaIter: false };
|
|
1469
1469
|
let source = this.expression(node.iterator);
|
|
1470
|
+
if (form.walks === "keys") {
|
|
1471
|
+
return [genericFor(
|
|
1472
|
+
[item],
|
|
1473
|
+
[call(this.builtin("pairs"), [source])],
|
|
1474
|
+
this.loopBody51(this.block(node.body, prelude)).statements
|
|
1475
|
+
)];
|
|
1476
|
+
}
|
|
1470
1477
|
if (form.viaIter) source = methodCall(source, "__iter", []);
|
|
1471
1478
|
const variables = form.walks === "values" ? [this.names.fresh("_"), item] : [item];
|
|
1472
1479
|
let iterators = form.walks === "iteration" ? [call(this.helper("unpack"), [source, number(1), number(3)])] : [source];
|
|
@@ -2587,6 +2594,7 @@ function usesVararg(node) {
|
|
|
2587
2594
|
return Object.values(record).some(usesVararg);
|
|
2588
2595
|
}
|
|
2589
2596
|
function calleePath(path) {
|
|
2597
|
+
if (!/^[A-Za-z_]\w*(\.[A-Za-z_]\w*)*$/.test(path)) return (0, import_luau_parser.parseExpressionFromSource)(path);
|
|
2590
2598
|
const [head, ...rest] = path.split(".");
|
|
2591
2599
|
return rest.reduce((value, name) => member(value, name), identifier(head));
|
|
2592
2600
|
}
|
|
@@ -3209,7 +3217,7 @@ async function bundle(options) {
|
|
|
3209
3217
|
}
|
|
3210
3218
|
for (const [file, fileDirectives] of directives) {
|
|
3211
3219
|
const semantic = diagnostics.filter((d) => d.file === file && (d.category === "scope" || d.category === "type"));
|
|
3212
|
-
const { kept, unusedExpectErrors } = (0, import_parser7.applyDirectives)(fileDirectives, semantic, (d) => d.line);
|
|
3220
|
+
const { kept, unusedExpectErrors, unusedExpectWarnings } = (0, import_parser7.applyDirectives)(fileDirectives, semantic, (d) => d.line, (d) => d.severity === "warning");
|
|
3213
3221
|
const suppressed = new Set(semantic.filter((d) => !kept.includes(d)));
|
|
3214
3222
|
const remaining = diagnostics.filter((d) => !suppressed.has(d));
|
|
3215
3223
|
diagnostics.length = 0;
|
|
@@ -3218,6 +3226,9 @@ async function bundle(options) {
|
|
|
3218
3226
|
for (const d of unusedExpectErrors) {
|
|
3219
3227
|
diagnostics.push({ file, message: import_parser7.UNUSED_EXPECT_ERROR, line: d.line, column: d.column, category: "type" });
|
|
3220
3228
|
}
|
|
3229
|
+
for (const d of unusedExpectWarnings) {
|
|
3230
|
+
diagnostics.push({ file, message: import_parser7.UNUSED_EXPECT_WARNING, line: d.line, column: d.column, category: "type", severity: "warning" });
|
|
3231
|
+
}
|
|
3221
3232
|
}
|
|
3222
3233
|
const moduleProblems = new Set(diagnostics.filter((d) => d.category === "module").map((d) => `${d.file}:${d.line}:${d.column}:${d.message}`));
|
|
3223
3234
|
const reported = diagnostics.filter((d) => d.category !== "type" || !moduleProblems.has(`${d.file}:${d.line}:${d.column}:${d.message}`));
|
package/dist/cli.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1488,8 +1488,15 @@ end`).body.statements, out);
|
|
|
1488
1488
|
item = this.names.fresh("item");
|
|
1489
1489
|
prelude.push(...this.destructure(variable, identifier(item), "declare"));
|
|
1490
1490
|
}
|
|
1491
|
-
const form = this.options.types?.loops.get(node) ?? { walks: "values", viaIter: false };
|
|
1491
|
+
const form = this.options.types?.loops.get(node) ?? { walks: node.over === "keys" ? "keys" : "values", viaIter: false };
|
|
1492
1492
|
let source = this.expression(node.iterator);
|
|
1493
|
+
if (form.walks === "keys") {
|
|
1494
|
+
return [genericFor(
|
|
1495
|
+
[item],
|
|
1496
|
+
[call(this.builtin("pairs"), [source])],
|
|
1497
|
+
this.loopBody51(this.block(node.body, prelude)).statements
|
|
1498
|
+
)];
|
|
1499
|
+
}
|
|
1493
1500
|
if (form.viaIter) source = methodCall(source, "__iter", []);
|
|
1494
1501
|
const variables = form.walks === "values" ? [this.names.fresh("_"), item] : [item];
|
|
1495
1502
|
let iterators = form.walks === "iteration" ? [call(this.helper("unpack"), [source, number(1), number(3)])] : [source];
|
|
@@ -2610,6 +2617,7 @@ function usesVararg(node) {
|
|
|
2610
2617
|
return Object.values(record).some(usesVararg);
|
|
2611
2618
|
}
|
|
2612
2619
|
function calleePath(path) {
|
|
2620
|
+
if (!/^[A-Za-z_]\w*(\.[A-Za-z_]\w*)*$/.test(path)) return (0, import_luau_parser.parseExpressionFromSource)(path);
|
|
2613
2621
|
const [head, ...rest] = path.split(".");
|
|
2614
2622
|
return rest.reduce((value, name) => member(value, name), identifier(head));
|
|
2615
2623
|
}
|
|
@@ -3232,7 +3240,7 @@ async function bundle(options) {
|
|
|
3232
3240
|
}
|
|
3233
3241
|
for (const [file, fileDirectives] of directives) {
|
|
3234
3242
|
const semantic = diagnostics.filter((d) => d.file === file && (d.category === "scope" || d.category === "type"));
|
|
3235
|
-
const { kept, unusedExpectErrors } = (0, import_parser7.applyDirectives)(fileDirectives, semantic, (d) => d.line);
|
|
3243
|
+
const { kept, unusedExpectErrors, unusedExpectWarnings } = (0, import_parser7.applyDirectives)(fileDirectives, semantic, (d) => d.line, (d) => d.severity === "warning");
|
|
3236
3244
|
const suppressed = new Set(semantic.filter((d) => !kept.includes(d)));
|
|
3237
3245
|
const remaining = diagnostics.filter((d) => !suppressed.has(d));
|
|
3238
3246
|
diagnostics.length = 0;
|
|
@@ -3241,6 +3249,9 @@ async function bundle(options) {
|
|
|
3241
3249
|
for (const d of unusedExpectErrors) {
|
|
3242
3250
|
diagnostics.push({ file, message: import_parser7.UNUSED_EXPECT_ERROR, line: d.line, column: d.column, category: "type" });
|
|
3243
3251
|
}
|
|
3252
|
+
for (const d of unusedExpectWarnings) {
|
|
3253
|
+
diagnostics.push({ file, message: import_parser7.UNUSED_EXPECT_WARNING, line: d.line, column: d.column, category: "type", severity: "warning" });
|
|
3254
|
+
}
|
|
3244
3255
|
}
|
|
3245
3256
|
const moduleProblems = new Set(diagnostics.filter((d) => d.category === "module").map((d) => `${d.file}:${d.line}:${d.column}:${d.message}`));
|
|
3246
3257
|
const reported = diagnostics.filter((d) => d.category !== "type" || !moduleProblems.has(`${d.file}:${d.line}:${d.column}:${d.message}`));
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tilua/compiler",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "Compiles tilua to Luau: lowers the @tilua/parser AST to a luau-parser AST and prints it",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"type": "module",
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"luau-parser": "^1.0.3",
|
|
41
|
-
"@tilua/parser": "^
|
|
41
|
+
"@tilua/parser": "^8.0.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/node": "^22.20.2",
|