redscript-mc 1.2.29 → 2.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/.claude/commands/build-test.md +10 -0
- package/.claude/commands/deploy-demo.md +12 -0
- package/.claude/commands/stage-status.md +13 -0
- package/.claude/settings.json +12 -0
- package/.github/workflows/ci.yml +1 -0
- package/CLAUDE.md +231 -0
- package/README.md +29 -28
- package/README.zh.md +28 -28
- package/demo.gif +0 -0
- package/dist/cli.js +2 -554
- package/dist/compile.js +2 -266
- package/dist/index.js +2 -159
- package/dist/lexer/index.js +9 -1
- package/dist/lowering/index.js +22 -5
- package/dist/src/__tests__/cli.test.d.ts +1 -0
- package/dist/src/__tests__/cli.test.js +104 -0
- package/dist/src/__tests__/codegen.test.d.ts +1 -0
- package/dist/src/__tests__/codegen.test.js +152 -0
- package/dist/src/__tests__/compile-all.test.d.ts +10 -0
- package/dist/src/__tests__/compile-all.test.js +108 -0
- package/dist/src/__tests__/dce.test.d.ts +1 -0
- package/dist/src/__tests__/dce.test.js +102 -0
- package/dist/src/__tests__/diagnostics.test.d.ts +4 -0
- package/dist/src/__tests__/diagnostics.test.js +177 -0
- package/dist/src/__tests__/e2e.test.d.ts +6 -0
- package/dist/src/__tests__/e2e.test.js +1789 -0
- package/dist/src/__tests__/entity-types.test.d.ts +1 -0
- package/dist/src/__tests__/entity-types.test.js +203 -0
- package/dist/src/__tests__/formatter.test.d.ts +1 -0
- package/dist/src/__tests__/formatter.test.js +40 -0
- package/dist/src/__tests__/lexer.test.d.ts +1 -0
- package/dist/src/__tests__/lexer.test.js +343 -0
- package/dist/src/__tests__/lowering.test.d.ts +1 -0
- package/dist/src/__tests__/lowering.test.js +1015 -0
- package/dist/src/__tests__/macro.test.d.ts +8 -0
- package/dist/src/__tests__/macro.test.js +306 -0
- package/dist/src/__tests__/mc-integration.test.d.ts +12 -0
- package/dist/src/__tests__/mc-integration.test.js +817 -0
- package/dist/src/__tests__/mc-syntax.test.d.ts +1 -0
- package/dist/src/__tests__/mc-syntax.test.js +124 -0
- package/dist/src/__tests__/nbt.test.d.ts +1 -0
- package/dist/src/__tests__/nbt.test.js +82 -0
- package/dist/src/__tests__/optimizer-advanced.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer-advanced.test.js +124 -0
- package/dist/src/__tests__/optimizer.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer.test.js +149 -0
- package/dist/src/__tests__/parser.test.d.ts +1 -0
- package/dist/src/__tests__/parser.test.js +807 -0
- package/dist/src/__tests__/repl.test.d.ts +1 -0
- package/dist/src/__tests__/repl.test.js +27 -0
- package/dist/src/__tests__/runtime.test.d.ts +1 -0
- package/dist/src/__tests__/runtime.test.js +289 -0
- package/dist/src/__tests__/stdlib-advanced.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib-advanced.test.js +374 -0
- package/dist/src/__tests__/stdlib-bigint.test.d.ts +7 -0
- package/dist/src/__tests__/stdlib-bigint.test.js +426 -0
- package/dist/src/__tests__/stdlib-math.test.d.ts +7 -0
- package/dist/src/__tests__/stdlib-math.test.js +351 -0
- package/dist/src/__tests__/stdlib-vec.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib-vec.test.js +263 -0
- package/dist/src/__tests__/structure-optimizer.test.d.ts +1 -0
- package/dist/src/__tests__/structure-optimizer.test.js +33 -0
- package/dist/src/__tests__/typechecker.test.d.ts +1 -0
- package/dist/src/__tests__/typechecker.test.js +552 -0
- package/dist/src/__tests__/var-allocator.test.d.ts +1 -0
- package/dist/src/__tests__/var-allocator.test.js +69 -0
- package/dist/src/ast/types.d.ts +515 -0
- package/dist/src/ast/types.js +9 -0
- package/dist/src/builtins/metadata.d.ts +36 -0
- package/dist/src/builtins/metadata.js +1014 -0
- package/dist/src/cli.d.ts +11 -0
- package/dist/src/cli.js +443 -0
- package/dist/src/codegen/cmdblock/index.d.ts +26 -0
- package/dist/src/codegen/cmdblock/index.js +45 -0
- package/dist/src/codegen/mcfunction/index.d.ts +40 -0
- package/dist/src/codegen/mcfunction/index.js +606 -0
- package/dist/src/codegen/structure/index.d.ts +24 -0
- package/dist/src/codegen/structure/index.js +279 -0
- package/dist/src/codegen/var-allocator.d.ts +45 -0
- package/dist/src/codegen/var-allocator.js +104 -0
- package/dist/src/compile.d.ts +37 -0
- package/dist/src/compile.js +165 -0
- package/dist/src/diagnostics/index.d.ts +44 -0
- package/dist/src/diagnostics/index.js +140 -0
- package/dist/src/events/types.d.ts +35 -0
- package/dist/src/events/types.js +59 -0
- package/dist/src/formatter/index.d.ts +1 -0
- package/dist/src/formatter/index.js +26 -0
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.js +45 -0
- package/dist/src/ir/builder.d.ts +33 -0
- package/dist/src/ir/builder.js +99 -0
- package/dist/src/ir/types.d.ts +132 -0
- package/dist/src/ir/types.js +15 -0
- package/dist/src/lexer/index.d.ts +37 -0
- package/dist/src/lexer/index.js +569 -0
- package/dist/src/lowering/index.d.ts +188 -0
- package/dist/src/lowering/index.js +3405 -0
- package/dist/src/mc-test/client.d.ts +128 -0
- package/dist/src/mc-test/client.js +174 -0
- package/dist/src/mc-test/runner.d.ts +28 -0
- package/dist/src/mc-test/runner.js +151 -0
- package/dist/src/mc-test/setup.d.ts +11 -0
- package/dist/src/mc-test/setup.js +98 -0
- package/dist/src/mc-validator/index.d.ts +17 -0
- package/dist/src/mc-validator/index.js +322 -0
- package/dist/src/nbt/index.d.ts +86 -0
- package/dist/src/nbt/index.js +250 -0
- package/dist/src/optimizer/commands.d.ts +38 -0
- package/dist/src/optimizer/commands.js +451 -0
- package/dist/src/optimizer/dce.d.ts +34 -0
- package/dist/src/optimizer/dce.js +639 -0
- package/dist/src/optimizer/passes.d.ts +34 -0
- package/dist/src/optimizer/passes.js +243 -0
- package/dist/src/optimizer/structure.d.ts +9 -0
- package/dist/src/optimizer/structure.js +356 -0
- package/dist/src/parser/index.d.ts +93 -0
- package/dist/src/parser/index.js +1687 -0
- package/dist/src/repl.d.ts +16 -0
- package/dist/src/repl.js +165 -0
- package/dist/src/runtime/index.d.ts +107 -0
- package/dist/src/runtime/index.js +1409 -0
- package/dist/src/typechecker/index.d.ts +61 -0
- package/dist/src/typechecker/index.js +1034 -0
- package/dist/src/types/entity-hierarchy.d.ts +29 -0
- package/dist/src/types/entity-hierarchy.js +107 -0
- package/dist/src2/__tests__/e2e/basic.test.d.ts +8 -0
- package/dist/src2/__tests__/e2e/basic.test.js +140 -0
- package/dist/src2/__tests__/e2e/macros.test.d.ts +9 -0
- package/dist/src2/__tests__/e2e/macros.test.js +182 -0
- package/dist/src2/__tests__/e2e/migrate.test.d.ts +13 -0
- package/dist/src2/__tests__/e2e/migrate.test.js +2739 -0
- package/dist/src2/__tests__/hir/desugar.test.d.ts +1 -0
- package/dist/src2/__tests__/hir/desugar.test.js +234 -0
- package/dist/src2/__tests__/lir/lower.test.d.ts +1 -0
- package/dist/src2/__tests__/lir/lower.test.js +559 -0
- package/dist/src2/__tests__/lir/types.test.d.ts +1 -0
- package/dist/src2/__tests__/lir/types.test.js +185 -0
- package/dist/src2/__tests__/lir/verify.test.d.ts +1 -0
- package/dist/src2/__tests__/lir/verify.test.js +221 -0
- package/dist/src2/__tests__/mir/arithmetic.test.d.ts +1 -0
- package/dist/src2/__tests__/mir/arithmetic.test.js +130 -0
- package/dist/src2/__tests__/mir/control-flow.test.d.ts +1 -0
- package/dist/src2/__tests__/mir/control-flow.test.js +205 -0
- package/dist/src2/__tests__/mir/verify.test.d.ts +1 -0
- package/dist/src2/__tests__/mir/verify.test.js +223 -0
- package/dist/src2/__tests__/optimizer/block_merge.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/block_merge.test.js +78 -0
- package/dist/src2/__tests__/optimizer/branch_simplify.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/branch_simplify.test.js +58 -0
- package/dist/src2/__tests__/optimizer/constant_fold.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/constant_fold.test.js +131 -0
- package/dist/src2/__tests__/optimizer/copy_prop.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/copy_prop.test.js +91 -0
- package/dist/src2/__tests__/optimizer/dce.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/dce.test.js +76 -0
- package/dist/src2/__tests__/optimizer/pipeline.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/pipeline.test.js +102 -0
- package/dist/src2/emit/compile.d.ts +19 -0
- package/dist/src2/emit/compile.js +80 -0
- package/dist/src2/emit/index.d.ts +17 -0
- package/dist/src2/emit/index.js +172 -0
- package/dist/src2/hir/lower.d.ts +15 -0
- package/dist/src2/hir/lower.js +378 -0
- package/dist/src2/hir/types.d.ts +373 -0
- package/dist/src2/hir/types.js +16 -0
- package/dist/src2/lir/lower.d.ts +15 -0
- package/dist/src2/lir/lower.js +453 -0
- package/dist/src2/lir/types.d.ts +136 -0
- package/dist/src2/lir/types.js +11 -0
- package/dist/src2/lir/verify.d.ts +14 -0
- package/dist/src2/lir/verify.js +113 -0
- package/dist/src2/mir/lower.d.ts +9 -0
- package/dist/src2/mir/lower.js +1030 -0
- package/dist/src2/mir/macro.d.ts +22 -0
- package/dist/src2/mir/macro.js +168 -0
- package/dist/src2/mir/types.d.ts +183 -0
- package/dist/src2/mir/types.js +11 -0
- package/dist/src2/mir/verify.d.ts +16 -0
- package/dist/src2/mir/verify.js +216 -0
- package/dist/src2/optimizer/block_merge.d.ts +12 -0
- package/dist/src2/optimizer/block_merge.js +84 -0
- package/dist/src2/optimizer/branch_simplify.d.ts +9 -0
- package/dist/src2/optimizer/branch_simplify.js +28 -0
- package/dist/src2/optimizer/constant_fold.d.ts +10 -0
- package/dist/src2/optimizer/constant_fold.js +85 -0
- package/dist/src2/optimizer/copy_prop.d.ts +9 -0
- package/dist/src2/optimizer/copy_prop.js +113 -0
- package/dist/src2/optimizer/dce.d.ts +8 -0
- package/dist/src2/optimizer/dce.js +155 -0
- package/dist/src2/optimizer/pipeline.d.ts +10 -0
- package/dist/src2/optimizer/pipeline.js +42 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/compiler-pipeline-redesign.md +2243 -0
- package/docs/optimization-ideas.md +1076 -0
- package/editors/vscode/package-lock.json +3 -3
- package/editors/vscode/package.json +1 -1
- package/examples/readme-demo.mcrs +44 -66
- package/jest.config.js +1 -1
- package/package.json +6 -5
- package/scripts/postbuild.js +15 -0
- package/src/__tests__/cli.test.ts +8 -220
- package/src/__tests__/dce.test.ts +11 -56
- package/src/__tests__/diagnostics.test.ts +59 -38
- package/src/__tests__/mc-integration.test.ts +1 -2
- package/src/ast/types.ts +6 -1
- package/src/cli.ts +29 -156
- package/src/compile.ts +6 -162
- package/src/index.ts +14 -178
- package/src/lexer/index.ts +9 -1
- package/src/mc-test/runner.ts +4 -3
- package/src/parser/index.ts +1 -1
- package/src/repl.ts +1 -1
- package/src/runtime/index.ts +1 -1
- package/src2/__tests__/e2e/basic.test.ts +154 -0
- package/src2/__tests__/e2e/macros.test.ts +199 -0
- package/src2/__tests__/e2e/migrate.test.ts +3008 -0
- package/src2/__tests__/hir/desugar.test.ts +263 -0
- package/src2/__tests__/lir/lower.test.ts +619 -0
- package/src2/__tests__/lir/types.test.ts +207 -0
- package/src2/__tests__/lir/verify.test.ts +249 -0
- package/src2/__tests__/mir/arithmetic.test.ts +156 -0
- package/src2/__tests__/mir/control-flow.test.ts +242 -0
- package/src2/__tests__/mir/verify.test.ts +254 -0
- package/src2/__tests__/optimizer/block_merge.test.ts +84 -0
- package/src2/__tests__/optimizer/branch_simplify.test.ts +64 -0
- package/src2/__tests__/optimizer/constant_fold.test.ts +145 -0
- package/src2/__tests__/optimizer/copy_prop.test.ts +99 -0
- package/src2/__tests__/optimizer/dce.test.ts +83 -0
- package/src2/__tests__/optimizer/pipeline.test.ts +116 -0
- package/src2/emit/compile.ts +99 -0
- package/src2/emit/index.ts +222 -0
- package/src2/hir/lower.ts +428 -0
- package/src2/hir/types.ts +216 -0
- package/src2/lir/lower.ts +556 -0
- package/src2/lir/types.ts +109 -0
- package/src2/lir/verify.ts +129 -0
- package/src2/mir/lower.ts +1160 -0
- package/src2/mir/macro.ts +167 -0
- package/src2/mir/types.ts +106 -0
- package/src2/mir/verify.ts +218 -0
- package/src2/optimizer/block_merge.ts +93 -0
- package/src2/optimizer/branch_simplify.ts +27 -0
- package/src2/optimizer/constant_fold.ts +88 -0
- package/src2/optimizer/copy_prop.ts +106 -0
- package/src2/optimizer/dce.ts +133 -0
- package/src2/optimizer/pipeline.ts +44 -0
- package/tsconfig.json +2 -2
- package/src/__tests__/codegen.test.ts +0 -161
- package/src/__tests__/e2e.test.ts +0 -2039
- package/src/__tests__/entity-types.test.ts +0 -236
- package/src/__tests__/lowering.test.ts +0 -1185
- package/src/__tests__/macro.test.ts +0 -343
- package/src/__tests__/nbt.test.ts +0 -58
- package/src/__tests__/optimizer-advanced.test.ts +0 -144
- package/src/__tests__/optimizer.test.ts +0 -162
- package/src/__tests__/runtime.test.ts +0 -305
- package/src/__tests__/stdlib-advanced.test.ts +0 -379
- package/src/__tests__/stdlib-bigint.test.ts +0 -427
- package/src/__tests__/stdlib-math.test.ts +0 -374
- package/src/__tests__/stdlib-vec.test.ts +0 -259
- package/src/__tests__/structure-optimizer.test.ts +0 -38
- package/src/__tests__/var-allocator.test.ts +0 -75
- package/src/codegen/cmdblock/index.ts +0 -63
- package/src/codegen/mcfunction/index.ts +0 -662
- package/src/codegen/structure/index.ts +0 -346
- package/src/codegen/var-allocator.ts +0 -104
- package/src/ir/builder.ts +0 -116
- package/src/ir/types.ts +0 -134
- package/src/lowering/index.ts +0 -3860
- package/src/optimizer/commands.ts +0 -534
- package/src/optimizer/dce.ts +0 -679
- package/src/optimizer/passes.ts +0 -250
- package/src/optimizer/structure.ts +0 -450
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
describe('LIR types — Slot', () => {
|
|
4
|
+
test('Slot has player and obj fields', () => {
|
|
5
|
+
const slot = { player: '$t0', obj: '__test' };
|
|
6
|
+
expect(slot.player).toBe('$t0');
|
|
7
|
+
expect(slot.obj).toBe('__test');
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
describe('LIR types — instructions', () => {
|
|
11
|
+
test('score_set instruction', () => {
|
|
12
|
+
const instr = { kind: 'score_set', dst: { player: '$x', obj: '__ns' }, value: 42 };
|
|
13
|
+
expect(instr.kind).toBe('score_set');
|
|
14
|
+
});
|
|
15
|
+
test('score_copy instruction', () => {
|
|
16
|
+
const dst = { player: '$x', obj: '__ns' };
|
|
17
|
+
const src = { player: '$y', obj: '__ns' };
|
|
18
|
+
const instr = { kind: 'score_copy', dst, src };
|
|
19
|
+
expect(instr.kind).toBe('score_copy');
|
|
20
|
+
});
|
|
21
|
+
test('score arithmetic instructions', () => {
|
|
22
|
+
const dst = { player: '$x', obj: '__ns' };
|
|
23
|
+
const src = { player: '$y', obj: '__ns' };
|
|
24
|
+
const ops = ['score_add', 'score_sub', 'score_mul', 'score_div', 'score_mod'];
|
|
25
|
+
for (const kind of ops) {
|
|
26
|
+
const instr = { kind, dst, src };
|
|
27
|
+
expect(instr.kind).toBe(kind);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
test('score_min, score_max instructions', () => {
|
|
31
|
+
const dst = { player: '$x', obj: '__ns' };
|
|
32
|
+
const src = { player: '$y', obj: '__ns' };
|
|
33
|
+
const min = { kind: 'score_min', dst, src };
|
|
34
|
+
const max = { kind: 'score_max', dst, src };
|
|
35
|
+
expect(min.kind).toBe('score_min');
|
|
36
|
+
expect(max.kind).toBe('score_max');
|
|
37
|
+
});
|
|
38
|
+
test('score_swap instruction', () => {
|
|
39
|
+
const a = { player: '$x', obj: '__ns' };
|
|
40
|
+
const b = { player: '$y', obj: '__ns' };
|
|
41
|
+
const instr = { kind: 'score_swap', a, b };
|
|
42
|
+
expect(instr.kind).toBe('score_swap');
|
|
43
|
+
});
|
|
44
|
+
test('store_cmd_to_score instruction', () => {
|
|
45
|
+
const dst = { player: '$x', obj: '__ns' };
|
|
46
|
+
const cmd = { kind: 'call', fn: 'test:foo' };
|
|
47
|
+
const instr = { kind: 'store_cmd_to_score', dst, cmd };
|
|
48
|
+
expect(instr.kind).toBe('store_cmd_to_score');
|
|
49
|
+
});
|
|
50
|
+
test('store_score_to_nbt instruction', () => {
|
|
51
|
+
const instr = {
|
|
52
|
+
kind: 'store_score_to_nbt',
|
|
53
|
+
ns: 'rs:data', path: 'value', type: 'int', scale: 1,
|
|
54
|
+
src: { player: '$x', obj: '__ns' },
|
|
55
|
+
};
|
|
56
|
+
expect(instr.kind).toBe('store_score_to_nbt');
|
|
57
|
+
});
|
|
58
|
+
test('store_nbt_to_score instruction', () => {
|
|
59
|
+
const instr = {
|
|
60
|
+
kind: 'store_nbt_to_score',
|
|
61
|
+
dst: { player: '$x', obj: '__ns' },
|
|
62
|
+
ns: 'rs:data', path: 'value', scale: 1,
|
|
63
|
+
};
|
|
64
|
+
expect(instr.kind).toBe('store_nbt_to_score');
|
|
65
|
+
});
|
|
66
|
+
test('nbt_set_literal instruction', () => {
|
|
67
|
+
const instr = { kind: 'nbt_set_literal', ns: 'rs:data', path: 'x', value: '42' };
|
|
68
|
+
expect(instr.kind).toBe('nbt_set_literal');
|
|
69
|
+
});
|
|
70
|
+
test('nbt_copy instruction', () => {
|
|
71
|
+
const instr = {
|
|
72
|
+
kind: 'nbt_copy',
|
|
73
|
+
srcNs: 'rs:a', srcPath: 'x',
|
|
74
|
+
dstNs: 'rs:b', dstPath: 'y',
|
|
75
|
+
};
|
|
76
|
+
expect(instr.kind).toBe('nbt_copy');
|
|
77
|
+
});
|
|
78
|
+
test('call instruction', () => {
|
|
79
|
+
const instr = { kind: 'call', fn: 'test:foo' };
|
|
80
|
+
expect(instr.kind).toBe('call');
|
|
81
|
+
});
|
|
82
|
+
test('call_macro instruction', () => {
|
|
83
|
+
const instr = { kind: 'call_macro', fn: 'test:draw', storage: 'rs:macro_args' };
|
|
84
|
+
expect(instr.kind).toBe('call_macro');
|
|
85
|
+
});
|
|
86
|
+
test('call_if_matches instruction', () => {
|
|
87
|
+
const instr = {
|
|
88
|
+
kind: 'call_if_matches',
|
|
89
|
+
fn: 'test:branch',
|
|
90
|
+
slot: { player: '$cond', obj: '__ns' },
|
|
91
|
+
range: '1',
|
|
92
|
+
};
|
|
93
|
+
expect(instr.kind).toBe('call_if_matches');
|
|
94
|
+
});
|
|
95
|
+
test('call_unless_matches instruction', () => {
|
|
96
|
+
const instr = {
|
|
97
|
+
kind: 'call_unless_matches',
|
|
98
|
+
fn: 'test:branch',
|
|
99
|
+
slot: { player: '$cond', obj: '__ns' },
|
|
100
|
+
range: '1',
|
|
101
|
+
};
|
|
102
|
+
expect(instr.kind).toBe('call_unless_matches');
|
|
103
|
+
});
|
|
104
|
+
test('call_if_score instruction', () => {
|
|
105
|
+
const instr = {
|
|
106
|
+
kind: 'call_if_score',
|
|
107
|
+
fn: 'test:check',
|
|
108
|
+
a: { player: '$x', obj: '__ns' },
|
|
109
|
+
op: 'lt',
|
|
110
|
+
b: { player: '$y', obj: '__ns' },
|
|
111
|
+
};
|
|
112
|
+
expect(instr.kind).toBe('call_if_score');
|
|
113
|
+
});
|
|
114
|
+
test('call_unless_score instruction', () => {
|
|
115
|
+
const instr = {
|
|
116
|
+
kind: 'call_unless_score',
|
|
117
|
+
fn: 'test:check',
|
|
118
|
+
a: { player: '$x', obj: '__ns' },
|
|
119
|
+
op: 'ge',
|
|
120
|
+
b: { player: '$y', obj: '__ns' },
|
|
121
|
+
};
|
|
122
|
+
expect(instr.kind).toBe('call_unless_score');
|
|
123
|
+
});
|
|
124
|
+
test('call_context instruction', () => {
|
|
125
|
+
const instr = {
|
|
126
|
+
kind: 'call_context',
|
|
127
|
+
fn: 'test:helper',
|
|
128
|
+
subcommands: [{ kind: 'as', selector: '@e[tag=foo]' }, { kind: 'at_self' }],
|
|
129
|
+
};
|
|
130
|
+
expect(instr.kind).toBe('call_context');
|
|
131
|
+
});
|
|
132
|
+
test('return_value instruction', () => {
|
|
133
|
+
const instr = { kind: 'return_value', slot: { player: '$result', obj: '__ns' } };
|
|
134
|
+
expect(instr.kind).toBe('return_value');
|
|
135
|
+
});
|
|
136
|
+
test('macro_line instruction', () => {
|
|
137
|
+
const instr = { kind: 'macro_line', template: '$particle end_rod ^$(px) ^$(py) ^5' };
|
|
138
|
+
expect(instr.kind).toBe('macro_line');
|
|
139
|
+
});
|
|
140
|
+
test('raw instruction', () => {
|
|
141
|
+
const instr = { kind: 'raw', cmd: 'say hello' };
|
|
142
|
+
expect(instr.kind).toBe('raw');
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
describe('LIR types — LIRFunction', () => {
|
|
146
|
+
test('basic function structure', () => {
|
|
147
|
+
const fn = {
|
|
148
|
+
name: 'main',
|
|
149
|
+
instructions: [
|
|
150
|
+
{ kind: 'score_set', dst: { player: '$x', obj: '__ns' }, value: 0 },
|
|
151
|
+
],
|
|
152
|
+
isMacro: false,
|
|
153
|
+
macroParams: [],
|
|
154
|
+
};
|
|
155
|
+
expect(fn.name).toBe('main');
|
|
156
|
+
expect(fn.instructions).toHaveLength(1);
|
|
157
|
+
expect(fn.isMacro).toBe(false);
|
|
158
|
+
expect(fn.macroParams).toEqual([]);
|
|
159
|
+
});
|
|
160
|
+
test('macro function structure', () => {
|
|
161
|
+
const fn = {
|
|
162
|
+
name: 'draw_pt',
|
|
163
|
+
instructions: [
|
|
164
|
+
{ kind: 'macro_line', template: '$particle end_rod ^$(px) ^$(py) ^5' },
|
|
165
|
+
],
|
|
166
|
+
isMacro: true,
|
|
167
|
+
macroParams: ['px', 'py'],
|
|
168
|
+
};
|
|
169
|
+
expect(fn.isMacro).toBe(true);
|
|
170
|
+
expect(fn.macroParams).toEqual(['px', 'py']);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
describe('LIR types — LIRModule', () => {
|
|
174
|
+
test('module structure', () => {
|
|
175
|
+
const mod = {
|
|
176
|
+
functions: [],
|
|
177
|
+
namespace: 'mypack',
|
|
178
|
+
objective: '__mypack',
|
|
179
|
+
};
|
|
180
|
+
expect(mod.namespace).toBe('mypack');
|
|
181
|
+
expect(mod.objective).toBe('__mypack');
|
|
182
|
+
expect(mod.functions).toEqual([]);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
//# sourceMappingURL=types.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const verify_1 = require("../../lir/verify");
|
|
4
|
+
const OBJ = '__test';
|
|
5
|
+
const NS = 'test';
|
|
6
|
+
function mkModule(functions) {
|
|
7
|
+
return { functions, namespace: NS, objective: OBJ };
|
|
8
|
+
}
|
|
9
|
+
function mkFn(name, instructions, isMacro = false, macroParams = []) {
|
|
10
|
+
return { name, instructions, isMacro, macroParams };
|
|
11
|
+
}
|
|
12
|
+
function slot(name) {
|
|
13
|
+
return { player: `$${name}`, obj: OBJ };
|
|
14
|
+
}
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Objective checks
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
describe('LIR verifier — objective checks', () => {
|
|
19
|
+
test('accepts slots with correct objective', () => {
|
|
20
|
+
const mod = mkModule([
|
|
21
|
+
mkFn('main', [
|
|
22
|
+
{ kind: 'score_set', dst: slot('x'), value: 42 },
|
|
23
|
+
{ kind: 'score_copy', dst: slot('y'), src: slot('x') },
|
|
24
|
+
]),
|
|
25
|
+
]);
|
|
26
|
+
expect((0, verify_1.verifyLIR)(mod)).toEqual([]);
|
|
27
|
+
});
|
|
28
|
+
test('rejects slot with wrong objective', () => {
|
|
29
|
+
const mod = mkModule([
|
|
30
|
+
mkFn('main', [
|
|
31
|
+
{ kind: 'score_set', dst: { player: '$x', obj: '__wrong' }, value: 42 },
|
|
32
|
+
]),
|
|
33
|
+
]);
|
|
34
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
35
|
+
expect(errors.length).toBe(1);
|
|
36
|
+
expect(errors[0].message).toContain('objective');
|
|
37
|
+
expect(errors[0].message).toContain('__wrong');
|
|
38
|
+
});
|
|
39
|
+
test('rejects wrong objective in src slot', () => {
|
|
40
|
+
const mod = mkModule([
|
|
41
|
+
mkFn('main', [
|
|
42
|
+
{ kind: 'score_copy', dst: slot('x'), src: { player: '$y', obj: '__bad' } },
|
|
43
|
+
]),
|
|
44
|
+
]);
|
|
45
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
46
|
+
expect(errors.length).toBe(1);
|
|
47
|
+
expect(errors[0].message).toContain('__bad');
|
|
48
|
+
});
|
|
49
|
+
test('checks slots in score_swap', () => {
|
|
50
|
+
const mod = mkModule([
|
|
51
|
+
mkFn('main', [
|
|
52
|
+
{ kind: 'score_swap', a: { player: '$x', obj: '__bad' }, b: slot('y') },
|
|
53
|
+
]),
|
|
54
|
+
]);
|
|
55
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
56
|
+
expect(errors.length).toBe(1);
|
|
57
|
+
expect(errors[0].message).toContain('__bad');
|
|
58
|
+
});
|
|
59
|
+
test('checks slots in store_cmd_to_score (recursive)', () => {
|
|
60
|
+
const mod = mkModule([
|
|
61
|
+
mkFn('main', [
|
|
62
|
+
{
|
|
63
|
+
kind: 'store_cmd_to_score',
|
|
64
|
+
dst: slot('r'),
|
|
65
|
+
cmd: {
|
|
66
|
+
kind: 'call_if_score',
|
|
67
|
+
fn: 'test:main',
|
|
68
|
+
a: { player: '$a', obj: '__bad' },
|
|
69
|
+
op: 'eq',
|
|
70
|
+
b: slot('b'),
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
]),
|
|
74
|
+
]);
|
|
75
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
76
|
+
expect(errors.length).toBe(1);
|
|
77
|
+
expect(errors[0].message).toContain('__bad');
|
|
78
|
+
});
|
|
79
|
+
test('checks slot in call_if_matches', () => {
|
|
80
|
+
const mod = mkModule([
|
|
81
|
+
mkFn('main', [
|
|
82
|
+
{
|
|
83
|
+
kind: 'call_if_matches',
|
|
84
|
+
fn: 'test:main',
|
|
85
|
+
slot: { player: '$c', obj: '__bad' },
|
|
86
|
+
range: '1',
|
|
87
|
+
},
|
|
88
|
+
]),
|
|
89
|
+
]);
|
|
90
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
91
|
+
expect(errors.length).toBe(1);
|
|
92
|
+
});
|
|
93
|
+
test('checks slot in return_value', () => {
|
|
94
|
+
const mod = mkModule([
|
|
95
|
+
mkFn('main', [
|
|
96
|
+
{ kind: 'return_value', slot: { player: '$r', obj: '__bad' } },
|
|
97
|
+
]),
|
|
98
|
+
]);
|
|
99
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
100
|
+
expect(errors.length).toBe(1);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Function reference checks
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
describe('LIR verifier — function references', () => {
|
|
107
|
+
test('accepts call to existing function', () => {
|
|
108
|
+
const mod = mkModule([
|
|
109
|
+
mkFn('main', [{ kind: 'call', fn: 'test:helper' }]),
|
|
110
|
+
mkFn('helper', []),
|
|
111
|
+
]);
|
|
112
|
+
expect((0, verify_1.verifyLIR)(mod)).toEqual([]);
|
|
113
|
+
});
|
|
114
|
+
test('rejects call to undefined function', () => {
|
|
115
|
+
const mod = mkModule([
|
|
116
|
+
mkFn('main', [{ kind: 'call', fn: 'test:nonexistent' }]),
|
|
117
|
+
]);
|
|
118
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
119
|
+
expect(errors.length).toBe(1);
|
|
120
|
+
expect(errors[0].message).toContain('undefined function');
|
|
121
|
+
expect(errors[0].message).toContain('nonexistent');
|
|
122
|
+
});
|
|
123
|
+
test('rejects call_macro to undefined function', () => {
|
|
124
|
+
const mod = mkModule([
|
|
125
|
+
mkFn('main', [{ kind: 'call_macro', fn: 'test:missing', storage: 'rs:macro_args' }]),
|
|
126
|
+
]);
|
|
127
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
128
|
+
expect(errors.length).toBe(1);
|
|
129
|
+
expect(errors[0].message).toContain('undefined function');
|
|
130
|
+
});
|
|
131
|
+
test('rejects call_if_matches to undefined function', () => {
|
|
132
|
+
const mod = mkModule([
|
|
133
|
+
mkFn('main', [
|
|
134
|
+
{ kind: 'call_if_matches', fn: 'test:missing', slot: slot('c'), range: '1' },
|
|
135
|
+
]),
|
|
136
|
+
]);
|
|
137
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
138
|
+
expect(errors.length).toBe(1);
|
|
139
|
+
expect(errors[0].message).toContain('undefined function');
|
|
140
|
+
});
|
|
141
|
+
test('rejects call_context to undefined function', () => {
|
|
142
|
+
const mod = mkModule([
|
|
143
|
+
mkFn('main', [
|
|
144
|
+
{ kind: 'call_context', fn: 'test:missing', subcommands: [{ kind: 'at_self' }] },
|
|
145
|
+
]),
|
|
146
|
+
]);
|
|
147
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
148
|
+
expect(errors.length).toBe(1);
|
|
149
|
+
expect(errors[0].message).toContain('undefined function');
|
|
150
|
+
});
|
|
151
|
+
test('checks function refs inside store_cmd_to_score', () => {
|
|
152
|
+
const mod = mkModule([
|
|
153
|
+
mkFn('main', [
|
|
154
|
+
{
|
|
155
|
+
kind: 'store_cmd_to_score',
|
|
156
|
+
dst: slot('r'),
|
|
157
|
+
cmd: { kind: 'call', fn: 'test:missing' },
|
|
158
|
+
},
|
|
159
|
+
]),
|
|
160
|
+
]);
|
|
161
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
162
|
+
expect(errors.length).toBe(1);
|
|
163
|
+
expect(errors[0].message).toContain('undefined function');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
// Macro line checks
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
describe('LIR verifier — macro_line', () => {
|
|
170
|
+
test('accepts macro_line in macro function', () => {
|
|
171
|
+
const mod = mkModule([
|
|
172
|
+
mkFn('draw', [
|
|
173
|
+
{ kind: 'macro_line', template: '$particle end_rod ^$(px)' },
|
|
174
|
+
], true, ['px']),
|
|
175
|
+
]);
|
|
176
|
+
expect((0, verify_1.verifyLIR)(mod)).toEqual([]);
|
|
177
|
+
});
|
|
178
|
+
test('rejects macro_line in non-macro function', () => {
|
|
179
|
+
const mod = mkModule([
|
|
180
|
+
mkFn('main', [
|
|
181
|
+
{ kind: 'macro_line', template: '$particle end_rod ^$(px)' },
|
|
182
|
+
], false),
|
|
183
|
+
]);
|
|
184
|
+
const errors = (0, verify_1.verifyLIR)(mod);
|
|
185
|
+
expect(errors.length).toBe(1);
|
|
186
|
+
expect(errors[0].message).toContain('macro_line');
|
|
187
|
+
expect(errors[0].message).toContain('non-macro');
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
// Clean module
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
describe('LIR verifier — clean module', () => {
|
|
194
|
+
test('accepts a well-formed module', () => {
|
|
195
|
+
const mod = mkModule([
|
|
196
|
+
mkFn('main', [
|
|
197
|
+
{ kind: 'score_set', dst: slot('t0'), value: 1 },
|
|
198
|
+
{ kind: 'score_set', dst: slot('t1'), value: 2 },
|
|
199
|
+
{ kind: 'score_copy', dst: slot('r'), src: slot('t0') },
|
|
200
|
+
{ kind: 'score_add', dst: slot('r'), src: slot('t1') },
|
|
201
|
+
{ kind: 'call', fn: 'test:helper' },
|
|
202
|
+
{ kind: 'return_value', slot: slot('r') },
|
|
203
|
+
]),
|
|
204
|
+
mkFn('helper', [
|
|
205
|
+
{ kind: 'raw', cmd: 'say hello' },
|
|
206
|
+
]),
|
|
207
|
+
]);
|
|
208
|
+
expect((0, verify_1.verifyLIR)(mod)).toEqual([]);
|
|
209
|
+
});
|
|
210
|
+
test('raw and nbt instructions do not trigger errors', () => {
|
|
211
|
+
const mod = mkModule([
|
|
212
|
+
mkFn('main', [
|
|
213
|
+
{ kind: 'raw', cmd: 'say hi' },
|
|
214
|
+
{ kind: 'nbt_set_literal', ns: 'rs:data', path: 'x', value: '42' },
|
|
215
|
+
{ kind: 'nbt_copy', srcNs: 'rs:a', srcPath: 'x', dstNs: 'rs:b', dstPath: 'y' },
|
|
216
|
+
]),
|
|
217
|
+
]);
|
|
218
|
+
expect((0, verify_1.verifyLIR)(mod)).toEqual([]);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
//# sourceMappingURL=verify.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const lexer_1 = require("../../../src/lexer");
|
|
4
|
+
const parser_1 = require("../../../src/parser");
|
|
5
|
+
const lower_1 = require("../../hir/lower");
|
|
6
|
+
const lower_2 = require("../../mir/lower");
|
|
7
|
+
const verify_1 = require("../../mir/verify");
|
|
8
|
+
function compile(source) {
|
|
9
|
+
const tokens = new lexer_1.Lexer(source).tokenize();
|
|
10
|
+
const ast = new parser_1.Parser(tokens).parse('test');
|
|
11
|
+
const hir = (0, lower_1.lowerToHIR)(ast);
|
|
12
|
+
return (0, lower_2.lowerToMIR)(hir);
|
|
13
|
+
}
|
|
14
|
+
function getEntryInstrs(mod) {
|
|
15
|
+
const fn = mod.functions[0];
|
|
16
|
+
const entry = fn.blocks.find(b => b.id === fn.entry);
|
|
17
|
+
return entry.instrs;
|
|
18
|
+
}
|
|
19
|
+
describe('MIR lowering — integer arithmetic', () => {
|
|
20
|
+
test('simple addition: let x = a + b', () => {
|
|
21
|
+
const mod = compile('fn f(a: int, b: int): int { return a + b; }');
|
|
22
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
23
|
+
const instrs = getEntryInstrs(mod);
|
|
24
|
+
// Should have an add instruction
|
|
25
|
+
const addInstr = instrs.find(i => i.kind === 'add');
|
|
26
|
+
expect(addInstr).toBeDefined();
|
|
27
|
+
expect(addInstr.kind).toBe('add');
|
|
28
|
+
});
|
|
29
|
+
test('chained arithmetic: a + b * c', () => {
|
|
30
|
+
const mod = compile('fn f(a: int, b: int, c: int): int { return a + b * c; }');
|
|
31
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
32
|
+
const instrs = getEntryInstrs(mod);
|
|
33
|
+
// Should have both mul and add
|
|
34
|
+
const kinds = instrs.map(i => i.kind);
|
|
35
|
+
expect(kinds).toContain('mul');
|
|
36
|
+
expect(kinds).toContain('add');
|
|
37
|
+
// mul should come before add (b*c computed first)
|
|
38
|
+
const mulIdx = kinds.indexOf('mul');
|
|
39
|
+
const addIdx = kinds.indexOf('add');
|
|
40
|
+
expect(mulIdx).toBeLessThan(addIdx);
|
|
41
|
+
});
|
|
42
|
+
test('subtraction and division', () => {
|
|
43
|
+
const mod = compile('fn f(a: int, b: int): int { return (a - b) / b; }');
|
|
44
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
45
|
+
const instrs = getEntryInstrs(mod);
|
|
46
|
+
const kinds = instrs.map(i => i.kind);
|
|
47
|
+
expect(kinds).toContain('sub');
|
|
48
|
+
expect(kinds).toContain('div');
|
|
49
|
+
});
|
|
50
|
+
test('modulo', () => {
|
|
51
|
+
const mod = compile('fn f(a: int, b: int): int { return a % b; }');
|
|
52
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
53
|
+
const instrs = getEntryInstrs(mod);
|
|
54
|
+
expect(instrs.some(i => i.kind === 'mod')).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
test('negation', () => {
|
|
57
|
+
const mod = compile('fn f(a: int): int { return -a; }');
|
|
58
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
59
|
+
const instrs = getEntryInstrs(mod);
|
|
60
|
+
expect(instrs.some(i => i.kind === 'neg')).toBe(true);
|
|
61
|
+
});
|
|
62
|
+
test('not operator', () => {
|
|
63
|
+
const mod = compile('fn f(a: bool): bool { return !a; }');
|
|
64
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
65
|
+
const instrs = getEntryInstrs(mod);
|
|
66
|
+
expect(instrs.some(i => i.kind === 'not')).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
test('comparison operators produce cmp instructions', () => {
|
|
69
|
+
const mod = compile('fn f(a: int, b: int): bool { return a < b; }');
|
|
70
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
71
|
+
const instrs = getEntryInstrs(mod);
|
|
72
|
+
const cmpInstr = instrs.find(i => i.kind === 'cmp');
|
|
73
|
+
expect(cmpInstr).toBeDefined();
|
|
74
|
+
expect(cmpInstr.op).toBe('lt');
|
|
75
|
+
});
|
|
76
|
+
test('let binding produces copy instruction', () => {
|
|
77
|
+
const mod = compile('fn f(a: int): int { let x: int = a; return x; }');
|
|
78
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
79
|
+
const instrs = getEntryInstrs(mod);
|
|
80
|
+
expect(instrs.some(i => i.kind === 'copy')).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
test('constant literal produces const instruction', () => {
|
|
83
|
+
const mod = compile('fn f(): int { return 42; }');
|
|
84
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
85
|
+
// The return terminator should have the const value
|
|
86
|
+
const fn = mod.functions[0];
|
|
87
|
+
const entry = fn.blocks.find(b => b.id === fn.entry);
|
|
88
|
+
expect(entry.term.kind).toBe('return');
|
|
89
|
+
const ret = entry.term;
|
|
90
|
+
expect(ret.value).toEqual({ kind: 'const', value: 42 });
|
|
91
|
+
});
|
|
92
|
+
test('function call produces call instruction', () => {
|
|
93
|
+
const mod = compile('fn add(a: int, b: int): int { return a + b; } fn f(): int { return add(1, 2); }');
|
|
94
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
95
|
+
// f is the second function
|
|
96
|
+
const fn = mod.functions[1];
|
|
97
|
+
const entry = fn.blocks.find(b => b.id === fn.entry);
|
|
98
|
+
const callInstr = entry.instrs.find(i => i.kind === 'call');
|
|
99
|
+
expect(callInstr).toBeDefined();
|
|
100
|
+
expect(callInstr.fn).toBe('add');
|
|
101
|
+
expect(callInstr.args).toHaveLength(2);
|
|
102
|
+
});
|
|
103
|
+
test('3-address form: each instruction has fresh dst', () => {
|
|
104
|
+
const mod = compile('fn f(a: int, b: int, c: int): int { return a + b + c; }');
|
|
105
|
+
expect((0, verify_1.verifyMIR)(mod)).toEqual([]);
|
|
106
|
+
const instrs = getEntryInstrs(mod);
|
|
107
|
+
const dsts = instrs.filter(i => 'dst' in i).map(i => i.dst);
|
|
108
|
+
// All destination temps should be unique
|
|
109
|
+
expect(new Set(dsts).size).toBe(dsts.length);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe('MIR lowering — module structure', () => {
|
|
113
|
+
test('namespace and objective set correctly', () => {
|
|
114
|
+
const mod = compile('fn f(): void {}');
|
|
115
|
+
expect(mod.namespace).toBe('test');
|
|
116
|
+
expect(mod.objective).toBe('__test');
|
|
117
|
+
});
|
|
118
|
+
test('multiple functions', () => {
|
|
119
|
+
const mod = compile('fn a(): void {} fn b(): void {} fn c(): void {}');
|
|
120
|
+
expect(mod.functions).toHaveLength(3);
|
|
121
|
+
expect(mod.functions.map(f => f.name)).toEqual(['a', 'b', 'c']);
|
|
122
|
+
});
|
|
123
|
+
test('function params are mapped to temps', () => {
|
|
124
|
+
const mod = compile('fn f(x: int, y: int): int { return x + y; }');
|
|
125
|
+
expect(mod.functions[0].params).toHaveLength(2);
|
|
126
|
+
expect(mod.functions[0].params[0].name).toMatch(/^t\d+$/);
|
|
127
|
+
expect(mod.functions[0].params[1].name).toMatch(/^t\d+$/);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
//# sourceMappingURL=arithmetic.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|