redscript-mc 1.2.26 → 1.2.28
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 +78 -9
- package/README.zh.md +72 -4
- package/dist/__tests__/cli.test.js +13 -13
- package/dist/__tests__/optimizer-advanced.test.js +4 -4
- package/dist/__tests__/stdlib-advanced.test.js +114 -0
- package/dist/__tests__/stdlib-bigint.test.d.ts +7 -0
- package/dist/__tests__/stdlib-bigint.test.js +428 -0
- package/dist/cli.js +13 -5
- package/dist/codegen/mcfunction/index.d.ts +4 -0
- package/dist/codegen/mcfunction/index.js +9 -4
- package/dist/compile.d.ts +4 -0
- package/dist/compile.js +9 -1
- package/dist/data/arena/function/__load.mcfunction +6 -0
- package/dist/data/arena/function/__tick.mcfunction +2 -0
- package/dist/data/arena/function/announce_leaders/else_1.mcfunction +3 -0
- package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +3 -0
- package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +7 -0
- package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +4 -0
- package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +6 -0
- package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/then_0.mcfunction +4 -0
- package/dist/data/arena/function/announce_leaders.mcfunction +6 -0
- package/dist/data/arena/function/arena_tick/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/arena_tick/then_0.mcfunction +4 -0
- package/dist/data/arena/function/arena_tick.mcfunction +11 -0
- package/dist/data/counter/function/__load.mcfunction +5 -0
- package/dist/data/counter/function/__tick.mcfunction +2 -0
- package/dist/data/counter/function/counter_tick/merge_2.mcfunction +1 -0
- package/dist/data/counter/function/counter_tick/then_0.mcfunction +3 -0
- package/dist/data/counter/function/counter_tick.mcfunction +11 -0
- package/dist/data/gcd2/function/__load.mcfunction +3 -0
- package/dist/data/gcd2/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd2/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd2/function/abs.mcfunction +7 -0
- package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd2/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3/function/__load.mcfunction +3 -0
- package/dist/data/gcd3/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd3/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd3/function/abs.mcfunction +7 -0
- package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd3/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3/function/test.mcfunction +7 -0
- package/dist/data/gcd3nm/function/__load.mcfunction +3 -0
- package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd3nm/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd3nm/function/abs.mcfunction +7 -0
- package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd3nm/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3nm/function/test.mcfunction +7 -0
- package/dist/data/gcd_test/function/__load.mcfunction +3 -0
- package/dist/data/gcd_test/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd_test/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd_test/function/abs.mcfunction +7 -0
- package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd_test/function/gcd.mcfunction +14 -0
- package/dist/data/isqrttest/function/__load.mcfunction +6 -0
- package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +12 -0
- package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +5 -0
- package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +4 -0
- package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +6 -0
- package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt.mcfunction +7 -0
- package/dist/data/isqrttest/function/test.mcfunction +6 -0
- package/dist/data/mathtest/function/__load.mcfunction +3 -0
- package/dist/data/mathtest/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/mathtest/function/abs/then_0.mcfunction +5 -0
- package/dist/data/mathtest/function/abs.mcfunction +6 -0
- package/dist/data/mathtest/function/test.mcfunction +5 -0
- package/dist/data/minecraft/tags/function/load.json +5 -0
- package/dist/data/minecraft/tags/function/tick.json +5 -0
- package/dist/data/mypack/function/__load.mcfunction +13 -0
- package/dist/data/mypack/function/_atan_init.mcfunction +2 -0
- package/dist/data/mypack/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/mypack/function/abs/then_0.mcfunction +5 -0
- package/dist/data/mypack/function/abs.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +2 -0
- package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +19 -0
- package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +4 -0
- package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed.mcfunction +7 -0
- package/dist/data/mypack/function/my_game.mcfunction +10 -0
- package/dist/data/quiz/function/__load.mcfunction +16 -0
- package/dist/data/quiz/function/__tick.mcfunction +6 -0
- package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/answer_a.mcfunction +4 -0
- package/dist/data/quiz/function/answer_b.mcfunction +4 -0
- package/dist/data/quiz/function/answer_c.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/else_1.mcfunction +5 -0
- package/dist/data/quiz/function/ask_question/else_4.mcfunction +5 -0
- package/dist/data/quiz/function/ask_question/else_7.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/merge_2.mcfunction +1 -0
- package/dist/data/quiz/function/ask_question/merge_5.mcfunction +2 -0
- package/dist/data/quiz/function/ask_question/merge_8.mcfunction +2 -0
- package/dist/data/quiz/function/ask_question/then_0.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/then_3.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/then_6.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question.mcfunction +7 -0
- package/dist/data/quiz/function/finish_quiz.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/else_1.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/else_10.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_16.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_4.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_7.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +8 -0
- package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/then_0.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_12.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_15.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/then_3.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/then_6.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_9.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer.mcfunction +11 -0
- package/dist/data/quiz/function/start_quiz.mcfunction +5 -0
- package/dist/data/reqtest/function/__load.mcfunction +4 -0
- package/dist/data/reqtest/function/_table_init.mcfunction +2 -0
- package/dist/data/reqtest/function/no_trig.mcfunction +3 -0
- package/dist/data/reqtest/function/use_table.mcfunction +4 -0
- package/dist/data/reqtest2/function/__load.mcfunction +3 -0
- package/dist/data/reqtest2/function/no_trig.mcfunction +3 -0
- package/dist/data/runtime/function/__load.mcfunction +5 -0
- package/dist/data/runtime/function/__tick.mcfunction +2 -0
- package/dist/data/runtime/function/counter_tick/then_0.mcfunction +3 -0
- package/dist/data/runtime/function/counter_tick.mcfunction +13 -0
- package/dist/data/shop/function/__load.mcfunction +7 -0
- package/dist/data/shop/function/__tick.mcfunction +3 -0
- package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/else_1.mcfunction +5 -0
- package/dist/data/shop/function/complete_purchase/else_4.mcfunction +5 -0
- package/dist/data/shop/function/complete_purchase/else_7.mcfunction +3 -0
- package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/then_0.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/then_3.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/then_6.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase.mcfunction +7 -0
- package/dist/data/shop/function/handle_shop_trigger.mcfunction +3 -0
- package/dist/data/swap_test/function/__load.mcfunction +3 -0
- package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +7 -0
- package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +5 -0
- package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +3 -0
- package/dist/data/swap_test/function/gcd_old.mcfunction +8 -0
- package/dist/data/turret/function/__load.mcfunction +5 -0
- package/dist/data/turret/function/__tick.mcfunction +4 -0
- package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +4 -0
- package/dist/data/turret/function/deploy_turret.mcfunction +8 -0
- package/dist/data/turret/function/turret_tick/at_1.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/tick_body.mcfunction +3 -0
- package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +1 -0
- package/dist/data/turret/function/turret_tick.mcfunction +5 -0
- package/dist/gcd2.map.json +15 -0
- package/dist/gcd3.map.json +17 -0
- package/dist/gcd_test.map.json +15 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +11 -6
- package/dist/isqrttest.map.json +15 -0
- package/dist/lowering/index.d.ts +3 -0
- package/dist/lowering/index.js +161 -64
- package/dist/mathtest.map.json +6 -0
- package/dist/mypack.map.json +27 -0
- package/dist/optimizer/commands.d.ts +1 -0
- package/dist/optimizer/commands.js +18 -11
- package/dist/optimizer/structure.d.ts +1 -0
- package/dist/optimizer/structure.js +6 -1
- package/dist/pack.mcmeta +6 -0
- package/dist/reqtest.map.json +4 -0
- package/dist/reqtest2.map.json +4 -0
- package/dist/runtime/index.js +26 -5
- package/dist/runtime.map.json +7 -0
- package/dist/swap_test.map.json +14 -0
- package/editors/vscode/package-lock.json +3 -3
- package/editors/vscode/package.json +1 -1
- package/examples/math-showcase.mcrs +146 -0
- package/examples/readme-demo.mcrs +92 -0
- package/examples/showcase.mcrs +505 -0
- package/package.json +1 -1
- package/src/__tests__/cli.test.ts +13 -13
- package/src/__tests__/optimizer-advanced.test.ts +4 -4
- package/src/__tests__/stdlib-advanced.test.ts +120 -0
- package/src/__tests__/stdlib-bigint.test.ts +427 -0
- package/src/cli.ts +14 -5
- package/src/codegen/mcfunction/index.ts +14 -5
- package/src/compile.ts +15 -2
- package/src/index.ts +17 -7
- package/src/lowering/index.ts +165 -63
- package/src/optimizer/commands.ts +18 -12
- package/src/optimizer/structure.ts +6 -2
- package/src/runtime/index.ts +27 -5
- package/src/stdlib/advanced.mcrs +81 -0
- package/src/stdlib/bigint.mcrs +205 -0
- package/src/stdlib/math.mcrs +19 -6
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* stdlib/bigint.mcrs — runtime behavioural tests
|
|
4
|
+
*
|
|
5
|
+
* Tests basic BigInt operations (base 10000, 8 limbs = 32 decimal digits).
|
|
6
|
+
* All arithmetic validated against known values.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const compile_1 = require("../compile");
|
|
45
|
+
const runtime_1 = require("../runtime");
|
|
46
|
+
const MATH_SRC = fs.readFileSync(path.join(__dirname, '../../src/stdlib/math.mcrs'), 'utf-8');
|
|
47
|
+
const BIGINT_SRC = fs.readFileSync(path.join(__dirname, '../../src/stdlib/bigint.mcrs'), 'utf-8');
|
|
48
|
+
function run(driver) {
|
|
49
|
+
const result = (0, compile_1.compile)(driver, {
|
|
50
|
+
namespace: 'bitest',
|
|
51
|
+
librarySources: [MATH_SRC, BIGINT_SRC],
|
|
52
|
+
});
|
|
53
|
+
if (!result.success)
|
|
54
|
+
throw new Error(result.error?.message ?? 'compile failed');
|
|
55
|
+
const rt = new runtime_1.MCRuntime('bitest');
|
|
56
|
+
for (const file of result.files ?? []) {
|
|
57
|
+
if (!file.path.endsWith('.mcfunction'))
|
|
58
|
+
continue;
|
|
59
|
+
const match = file.path.match(/data\/([^/]+)\/function\/(.+)\.mcfunction$/);
|
|
60
|
+
if (!match)
|
|
61
|
+
continue;
|
|
62
|
+
rt.loadFunction(`${match[1]}:${match[2]}`, file.content.split('\n'));
|
|
63
|
+
}
|
|
64
|
+
rt.load();
|
|
65
|
+
return rt;
|
|
66
|
+
}
|
|
67
|
+
function sc(rt, key) {
|
|
68
|
+
return rt.getScore('out', `bitest.${key}`) ?? 0;
|
|
69
|
+
}
|
|
70
|
+
// ── storage_set_int roundtrip ─────────────────────────────────────────────────
|
|
71
|
+
describe('storage_set_int roundtrip', () => {
|
|
72
|
+
it('static index: write 99 to arr[2], read back', () => {
|
|
73
|
+
const rt = run(`fn test() {
|
|
74
|
+
storage_set_array("rs:t", "arr", "[10,20,30,40]");
|
|
75
|
+
storage_set_int("rs:t", "arr", 2, 99);
|
|
76
|
+
scoreboard_set("out", "r", storage_get_int("rs:t", "arr", 2));
|
|
77
|
+
}`);
|
|
78
|
+
rt.execFunction('test');
|
|
79
|
+
expect(sc(rt, 'r')).toBe(99);
|
|
80
|
+
});
|
|
81
|
+
it('runtime index: write 777 to arr[idx], read back', () => {
|
|
82
|
+
const rt = run(`fn test() {
|
|
83
|
+
storage_set_array("rs:t", "arr", "[1,2,3,4,5]");
|
|
84
|
+
let idx: int = 3;
|
|
85
|
+
storage_set_int("rs:t", "arr", idx, 777);
|
|
86
|
+
scoreboard_set("out", "r", storage_get_int("rs:t", "arr", idx));
|
|
87
|
+
}`);
|
|
88
|
+
rt.execFunction('test');
|
|
89
|
+
expect(sc(rt, 'r')).toBe(777);
|
|
90
|
+
});
|
|
91
|
+
it('loop write: fill arr[0..3] with 10,20,30,40', () => {
|
|
92
|
+
const rt = run(`fn test() {
|
|
93
|
+
storage_set_array("rs:t", "arr", "[0,0,0,0]");
|
|
94
|
+
let i: int = 0;
|
|
95
|
+
while (i < 4) {
|
|
96
|
+
storage_set_int("rs:t", "arr", i, (i + 1) * 10);
|
|
97
|
+
i = i + 1;
|
|
98
|
+
}
|
|
99
|
+
scoreboard_set("out", "a", storage_get_int("rs:t", "arr", 0));
|
|
100
|
+
scoreboard_set("out", "b", storage_get_int("rs:t", "arr", 1));
|
|
101
|
+
scoreboard_set("out", "c", storage_get_int("rs:t", "arr", 2));
|
|
102
|
+
scoreboard_set("out", "d", storage_get_int("rs:t", "arr", 3));
|
|
103
|
+
}`);
|
|
104
|
+
rt.execFunction('test');
|
|
105
|
+
expect(sc(rt, 'a')).toBe(10);
|
|
106
|
+
expect(sc(rt, 'b')).toBe(20);
|
|
107
|
+
expect(sc(rt, 'c')).toBe(30);
|
|
108
|
+
expect(sc(rt, 'd')).toBe(40);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
// ── bigint_init + from_int ────────────────────────────────────────────────────
|
|
112
|
+
describe('bigint init and load', () => {
|
|
113
|
+
it('bigint_init zeros registers', () => {
|
|
114
|
+
const rt = run(`fn test() {
|
|
115
|
+
bigint_init();
|
|
116
|
+
scoreboard_set("out", "r", bigint_get_a(0));
|
|
117
|
+
}`);
|
|
118
|
+
rt.execFunction('test');
|
|
119
|
+
expect(sc(rt, 'r')).toBe(0);
|
|
120
|
+
});
|
|
121
|
+
it('bigint_from_int_a(12345678): limb0=5678, limb1=1234', () => {
|
|
122
|
+
const rt = run(`fn test() {
|
|
123
|
+
bigint_init();
|
|
124
|
+
bigint_from_int_a(12345678);
|
|
125
|
+
scoreboard_set("out", "l0", bigint_get_a(0));
|
|
126
|
+
scoreboard_set("out", "l1", bigint_get_a(1));
|
|
127
|
+
scoreboard_set("out", "l2", bigint_get_a(2));
|
|
128
|
+
}`);
|
|
129
|
+
rt.execFunction('test');
|
|
130
|
+
expect(sc(rt, 'l0')).toBe(5678);
|
|
131
|
+
expect(sc(rt, 'l1')).toBe(1234);
|
|
132
|
+
expect(sc(rt, 'l2')).toBe(0);
|
|
133
|
+
});
|
|
134
|
+
it('bigint_from_int_a(2000000000): limb0=0, limb1=0, limb2=20', () => {
|
|
135
|
+
// 2000000000 = 20 × 10000^2 (not 2000: 20 × 10^8 = 2×10^9 ✓)
|
|
136
|
+
const rt = run(`fn test() {
|
|
137
|
+
bigint_init();
|
|
138
|
+
bigint_from_int_a(2000000000);
|
|
139
|
+
scoreboard_set("out", "l0", bigint_get_a(0));
|
|
140
|
+
scoreboard_set("out", "l1", bigint_get_a(1));
|
|
141
|
+
scoreboard_set("out", "l2", bigint_get_a(2));
|
|
142
|
+
}`);
|
|
143
|
+
rt.execFunction('test');
|
|
144
|
+
expect(sc(rt, 'l0')).toBe(0);
|
|
145
|
+
expect(sc(rt, 'l1')).toBe(0);
|
|
146
|
+
expect(sc(rt, 'l2')).toBe(20);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
// ── bigint_add ────────────────────────────────────────────────────────────────
|
|
150
|
+
describe('bigint_add', () => {
|
|
151
|
+
it('1 + 1 = 2 (simple)', () => {
|
|
152
|
+
const rt = run(`fn test() {
|
|
153
|
+
bigint_init();
|
|
154
|
+
bigint_from_int_a(1);
|
|
155
|
+
bigint_from_int_b(1);
|
|
156
|
+
bigint_add();
|
|
157
|
+
scoreboard_set("out", "r", bigint_get_c(0));
|
|
158
|
+
}`);
|
|
159
|
+
rt.execFunction('test');
|
|
160
|
+
expect(sc(rt, 'r')).toBe(2);
|
|
161
|
+
});
|
|
162
|
+
it('9999 + 1 = 10000: carry across limb boundary', () => {
|
|
163
|
+
// a=[9999,0,...] + b=[1,0,...] = c=[0,1,0,...] (carry to limb1)
|
|
164
|
+
const rt = run(`fn test() {
|
|
165
|
+
bigint_init();
|
|
166
|
+
bigint_from_int_a(9999);
|
|
167
|
+
bigint_from_int_b(1);
|
|
168
|
+
bigint_add();
|
|
169
|
+
scoreboard_set("out", "l0", bigint_get_c(0));
|
|
170
|
+
scoreboard_set("out", "l1", bigint_get_c(1));
|
|
171
|
+
}`);
|
|
172
|
+
rt.execFunction('test');
|
|
173
|
+
expect(sc(rt, 'l0')).toBe(0);
|
|
174
|
+
expect(sc(rt, 'l1')).toBe(1);
|
|
175
|
+
});
|
|
176
|
+
it('99990000 + 10000 = 100000000: multi-limb carry', () => {
|
|
177
|
+
// a=[0,9999,...] + b=[0,1,...] = c=[0,0,1,...] (carry to limb2)
|
|
178
|
+
const rt = run(`fn test() {
|
|
179
|
+
bigint_init();
|
|
180
|
+
bigint_from_int_a(99990000);
|
|
181
|
+
bigint_from_int_b(10000);
|
|
182
|
+
bigint_add();
|
|
183
|
+
scoreboard_set("out", "l0", bigint_get_c(0));
|
|
184
|
+
scoreboard_set("out", "l1", bigint_get_c(1));
|
|
185
|
+
scoreboard_set("out", "l2", bigint_get_c(2));
|
|
186
|
+
}`);
|
|
187
|
+
rt.execFunction('test');
|
|
188
|
+
expect(sc(rt, 'l0')).toBe(0);
|
|
189
|
+
expect(sc(rt, 'l1')).toBe(0);
|
|
190
|
+
expect(sc(rt, 'l2')).toBe(1);
|
|
191
|
+
});
|
|
192
|
+
it('large add: 999999999 + 999999999', () => {
|
|
193
|
+
// 999999999 = [9999, 9999, 9, 0, ...]
|
|
194
|
+
// + same = [9998, 9999, 18, 0, ...] after carry
|
|
195
|
+
// = 1999999998: l0=9998, l1=9999, l2=19 (carry: 9+9=18, no carry from l2)
|
|
196
|
+
// Wait: l0=9999+9999=19998, carry=1, l0=9998
|
|
197
|
+
// l1=9999+9999+1=19999, carry=1, l1=9999
|
|
198
|
+
// l2=9+9+1=19, carry=0, l2=19
|
|
199
|
+
const rt = run(`fn test() {
|
|
200
|
+
bigint_init();
|
|
201
|
+
bigint_from_int_a(999999999);
|
|
202
|
+
bigint_from_int_b(999999999);
|
|
203
|
+
bigint_add();
|
|
204
|
+
scoreboard_set("out", "l0", bigint_get_c(0));
|
|
205
|
+
scoreboard_set("out", "l1", bigint_get_c(1));
|
|
206
|
+
scoreboard_set("out", "l2", bigint_get_c(2));
|
|
207
|
+
}`);
|
|
208
|
+
rt.execFunction('test');
|
|
209
|
+
expect(sc(rt, 'l0')).toBe(9998); // 1999999998 % 10000 = 9998
|
|
210
|
+
expect(sc(rt, 'l1')).toBe(9999); // floor(1999999998 / 10000) % 10000 = 9999
|
|
211
|
+
expect(sc(rt, 'l2')).toBe(19); // floor(1999999998 / 100000000) = 19
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
// ── bigint_sub ────────────────────────────────────────────────────────────────
|
|
215
|
+
describe('bigint_sub', () => {
|
|
216
|
+
it('10 - 3 = 7', () => {
|
|
217
|
+
const rt = run(`fn test() {
|
|
218
|
+
bigint_init();
|
|
219
|
+
bigint_from_int_a(10);
|
|
220
|
+
bigint_from_int_b(3);
|
|
221
|
+
bigint_sub();
|
|
222
|
+
scoreboard_set("out", "r", bigint_get_c(0));
|
|
223
|
+
}`);
|
|
224
|
+
rt.execFunction('test');
|
|
225
|
+
expect(sc(rt, 'r')).toBe(7);
|
|
226
|
+
});
|
|
227
|
+
it('10000 - 1 = 9999: borrow across limb boundary', () => {
|
|
228
|
+
// a=[0,1,...] - b=[1,0,...] = c=[9999,0,...] (borrow from limb1)
|
|
229
|
+
const rt = run(`fn test() {
|
|
230
|
+
bigint_init();
|
|
231
|
+
bigint_from_int_a(10000);
|
|
232
|
+
bigint_from_int_b(1);
|
|
233
|
+
bigint_sub();
|
|
234
|
+
scoreboard_set("out", "l0", bigint_get_c(0));
|
|
235
|
+
scoreboard_set("out", "l1", bigint_get_c(1));
|
|
236
|
+
}`);
|
|
237
|
+
rt.execFunction('test');
|
|
238
|
+
expect(sc(rt, 'l0')).toBe(9999);
|
|
239
|
+
expect(sc(rt, 'l1')).toBe(0);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
// ── bigint_compare ────────────────────────────────────────────────────────────
|
|
243
|
+
describe('bigint_compare', () => {
|
|
244
|
+
it('1 == 1 → 0', () => {
|
|
245
|
+
const rt = run(`fn test() {
|
|
246
|
+
bigint_init();
|
|
247
|
+
bigint_from_int_a(1);
|
|
248
|
+
bigint_from_int_b(1);
|
|
249
|
+
scoreboard_set("out", "r", bigint_compare());
|
|
250
|
+
}`);
|
|
251
|
+
rt.execFunction('test');
|
|
252
|
+
expect(sc(rt, 'r')).toBe(0);
|
|
253
|
+
});
|
|
254
|
+
it('2 > 1 → 1', () => {
|
|
255
|
+
const rt = run(`fn test() {
|
|
256
|
+
bigint_init();
|
|
257
|
+
bigint_from_int_a(2);
|
|
258
|
+
bigint_from_int_b(1);
|
|
259
|
+
scoreboard_set("out", "r", bigint_compare());
|
|
260
|
+
}`);
|
|
261
|
+
rt.execFunction('test');
|
|
262
|
+
expect(sc(rt, 'r')).toBe(1);
|
|
263
|
+
});
|
|
264
|
+
it('1 < 2 → -1', () => {
|
|
265
|
+
const rt = run(`fn test() {
|
|
266
|
+
bigint_init();
|
|
267
|
+
bigint_from_int_a(1);
|
|
268
|
+
bigint_from_int_b(2);
|
|
269
|
+
scoreboard_set("out", "r", bigint_compare());
|
|
270
|
+
}`);
|
|
271
|
+
rt.execFunction('test');
|
|
272
|
+
expect(sc(rt, 'r')).toBe(-1);
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
// ── bigint_mul_small ──────────────────────────────────────────────────────────
|
|
276
|
+
describe('bigint_mul_small', () => {
|
|
277
|
+
it('12345 * 2 = 24690', () => {
|
|
278
|
+
const rt = run(`fn test() {
|
|
279
|
+
bigint_init();
|
|
280
|
+
bigint_from_int_a(12345);
|
|
281
|
+
bigint_mul_small(2);
|
|
282
|
+
scoreboard_set("out", "l0", bigint_get_c(0));
|
|
283
|
+
scoreboard_set("out", "l1", bigint_get_c(1));
|
|
284
|
+
}`);
|
|
285
|
+
rt.execFunction('test');
|
|
286
|
+
expect(sc(rt, 'l0')).toBe(4690);
|
|
287
|
+
expect(sc(rt, 'l1')).toBe(2);
|
|
288
|
+
});
|
|
289
|
+
it('9999 * 9999 = 99980001: carry', () => {
|
|
290
|
+
// c[0] = 99980001 % 10000 = 1
|
|
291
|
+
// c[1] = floor(99980001 / 10000) = 9998
|
|
292
|
+
const rt = run(`fn test() {
|
|
293
|
+
bigint_init();
|
|
294
|
+
bigint_from_int_a(9999);
|
|
295
|
+
bigint_mul_small(9999);
|
|
296
|
+
scoreboard_set("out", "l0", bigint_get_c(0));
|
|
297
|
+
scoreboard_set("out", "l1", bigint_get_c(1));
|
|
298
|
+
}`);
|
|
299
|
+
rt.execFunction('test');
|
|
300
|
+
expect(sc(rt, 'l0')).toBe(1); // 99980001 % 10000 = 1 (actually 0001)
|
|
301
|
+
expect(sc(rt, 'l1')).toBe(9998); // 9998
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
// ── bigint_mul ────────────────────────────────────────────────────────────────
|
|
305
|
+
describe('bigint_mul', () => {
|
|
306
|
+
it('3 * 4 = 12', () => {
|
|
307
|
+
const rt = run(`fn test() {
|
|
308
|
+
bigint_init();
|
|
309
|
+
bigint_from_int_a(3);
|
|
310
|
+
bigint_from_int_b(4);
|
|
311
|
+
bigint_mul();
|
|
312
|
+
scoreboard_set("out", "r", bigint_get_c(0));
|
|
313
|
+
}`);
|
|
314
|
+
rt.execFunction('test');
|
|
315
|
+
expect(sc(rt, 'r')).toBe(12);
|
|
316
|
+
});
|
|
317
|
+
it('9999 * 9999 = 99980001', () => {
|
|
318
|
+
const rt = run(`fn test() {
|
|
319
|
+
bigint_init();
|
|
320
|
+
bigint_from_int_a(9999);
|
|
321
|
+
bigint_from_int_b(9999);
|
|
322
|
+
bigint_mul();
|
|
323
|
+
scoreboard_set("out", "l0", bigint_get_c(0));
|
|
324
|
+
scoreboard_set("out", "l1", bigint_get_c(1));
|
|
325
|
+
}`);
|
|
326
|
+
rt.execFunction('test');
|
|
327
|
+
expect(sc(rt, 'l0')).toBe(1);
|
|
328
|
+
expect(sc(rt, 'l1')).toBe(9998);
|
|
329
|
+
});
|
|
330
|
+
it('100000 * 100000 = 10^10: spans 3 limbs', () => {
|
|
331
|
+
// 10^10 = [0, 0, 0, 1, 0, ...] in base 10000 (1 * 10000^3 = 10^12? no)
|
|
332
|
+
// 10^10 / 10000^0 % 10000 = 0
|
|
333
|
+
// 10^10 / 10000^1 % 10000 = 0
|
|
334
|
+
// 10^10 / 10000^2 % 10000 = 10000 → wait: 10^10 / 10^8 = 100, 100 % 10000 = 100
|
|
335
|
+
// Actually: 10^10 = 100 * 10^8 = 100 * (10^4)^2
|
|
336
|
+
// l0 = 10^10 % 10^4 = 0
|
|
337
|
+
// l1 = floor(10^10 / 10^4) % 10^4 = floor(10^6) % 10000 = 0
|
|
338
|
+
// l2 = floor(10^10 / 10^8) % 10^4 = 100 % 10000 = 100
|
|
339
|
+
const rt = run(`fn test() {
|
|
340
|
+
bigint_init();
|
|
341
|
+
bigint_from_int_a(100000);
|
|
342
|
+
bigint_from_int_b(100000);
|
|
343
|
+
bigint_mul();
|
|
344
|
+
scoreboard_set("out", "l0", bigint_get_c(0));
|
|
345
|
+
scoreboard_set("out", "l1", bigint_get_c(1));
|
|
346
|
+
scoreboard_set("out", "l2", bigint_get_c(2));
|
|
347
|
+
}`);
|
|
348
|
+
rt.execFunction('test');
|
|
349
|
+
expect(sc(rt, 'l0')).toBe(0);
|
|
350
|
+
expect(sc(rt, 'l1')).toBe(0);
|
|
351
|
+
expect(sc(rt, 'l2')).toBe(100);
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
// ── bigint_fib ────────────────────────────────────────────────────────────────
|
|
355
|
+
describe('bigint_fib', () => {
|
|
356
|
+
it('F(0) = 0', () => {
|
|
357
|
+
const rt = run(`fn test() {
|
|
358
|
+
bigint_fib(0);
|
|
359
|
+
scoreboard_set("out", "r", bigint_get_a(0));
|
|
360
|
+
}`);
|
|
361
|
+
rt.execFunction('test');
|
|
362
|
+
expect(sc(rt, 'r')).toBe(0);
|
|
363
|
+
});
|
|
364
|
+
it('F(1) = 1', () => {
|
|
365
|
+
const rt = run(`fn test() {
|
|
366
|
+
bigint_fib(1);
|
|
367
|
+
scoreboard_set("out", "r", bigint_get_a(0));
|
|
368
|
+
}`);
|
|
369
|
+
rt.execFunction('test');
|
|
370
|
+
expect(sc(rt, 'r')).toBe(1);
|
|
371
|
+
});
|
|
372
|
+
it('F(10) = 55', () => {
|
|
373
|
+
const rt = run(`fn test() {
|
|
374
|
+
bigint_fib(10);
|
|
375
|
+
scoreboard_set("out", "r", bigint_get_a(0));
|
|
376
|
+
}`);
|
|
377
|
+
rt.execFunction('test');
|
|
378
|
+
expect(sc(rt, 'r')).toBe(55);
|
|
379
|
+
});
|
|
380
|
+
it('F(20) = 6765', () => {
|
|
381
|
+
const rt = run(`fn test() {
|
|
382
|
+
bigint_fib(20);
|
|
383
|
+
scoreboard_set("out", "r", bigint_get_a(0));
|
|
384
|
+
}`);
|
|
385
|
+
rt.execFunction('test');
|
|
386
|
+
expect(sc(rt, 'r')).toBe(6765);
|
|
387
|
+
});
|
|
388
|
+
it('F(50) = 12586269025: limb0=9025, limb1=8626, limb2=125', () => {
|
|
389
|
+
// F(50) = 12,586,269,025
|
|
390
|
+
// 12586269025 % 10000 = 9025
|
|
391
|
+
// floor(12586269025 / 10000) % 10000 = 1258626 % 10000 = 8626
|
|
392
|
+
// floor(12586269025 / 10^8) = 125
|
|
393
|
+
const rt = run(`fn test() {
|
|
394
|
+
bigint_fib(50);
|
|
395
|
+
scoreboard_set("out", "l0", bigint_get_a(0));
|
|
396
|
+
scoreboard_set("out", "l1", bigint_get_a(1));
|
|
397
|
+
scoreboard_set("out", "l2", bigint_get_a(2));
|
|
398
|
+
}`);
|
|
399
|
+
rt.execFunction('test');
|
|
400
|
+
expect(sc(rt, 'l0')).toBe(9025);
|
|
401
|
+
expect(sc(rt, 'l1')).toBe(8626);
|
|
402
|
+
expect(sc(rt, 'l2')).toBe(125);
|
|
403
|
+
});
|
|
404
|
+
it('F(100) low limbs check', () => {
|
|
405
|
+
// F(100) = 354224848179261915075
|
|
406
|
+
// % 10000 = 5075
|
|
407
|
+
// floor / 10000 % 10000 = floor(35422484817926191.5075) % 10000 = ...
|
|
408
|
+
// Let's compute:
|
|
409
|
+
// 354224848179261915075 % 10000 = 5075
|
|
410
|
+
// floor(354224848179261915075 / 10000) = 35422484817926191507 (JS BigInt)
|
|
411
|
+
// 35422484817926191507 % 10000 = 1507
|
|
412
|
+
// floor(35422484817926191507 / 10000) = 3542248481792619 (roughly)
|
|
413
|
+
// % 10000 = 2619
|
|
414
|
+
const rt = run(`fn test() {
|
|
415
|
+
bigint_fib(100);
|
|
416
|
+
scoreboard_set("out", "l0", bigint_get_a(0));
|
|
417
|
+
scoreboard_set("out", "l1", bigint_get_a(1));
|
|
418
|
+
scoreboard_set("out", "l2", bigint_get_a(2));
|
|
419
|
+
}`);
|
|
420
|
+
rt.execFunction('test');
|
|
421
|
+
const f100 = BigInt('354224848179261915075');
|
|
422
|
+
const b = BigInt(10000);
|
|
423
|
+
expect(sc(rt, 'l0')).toBe(Number(f100 % b));
|
|
424
|
+
expect(sc(rt, 'l1')).toBe(Number((f100 / b) % b));
|
|
425
|
+
expect(sc(rt, 'l2')).toBe(Number((f100 / b / b) % b));
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
//# sourceMappingURL=stdlib-bigint.test.js.map
|
package/dist/cli.js
CHANGED
|
@@ -60,7 +60,7 @@ function printUsage() {
|
|
|
60
60
|
RedScript Compiler
|
|
61
61
|
|
|
62
62
|
Usage:
|
|
63
|
-
redscript compile <file> [-o <out>] [--output-nbt <file>] [--namespace <ns>] [--target <target>] [--no-dce]
|
|
63
|
+
redscript compile <file> [-o <out>] [--output-nbt <file>] [--namespace <ns>] [--scoreboard <obj>] [--target <target>] [--no-dce]
|
|
64
64
|
redscript watch <dir> [-o <outdir>] [--namespace <ns>] [--hot-reload <url>]
|
|
65
65
|
redscript check <file>
|
|
66
66
|
redscript fmt <file.mcrs> [file2.mcrs ...]
|
|
@@ -85,6 +85,9 @@ Options:
|
|
|
85
85
|
--target <target> Output target: datapack (default), cmdblock, or structure
|
|
86
86
|
--no-dce Disable AST dead code elimination
|
|
87
87
|
--no-mangle Disable variable name mangling (use readable names)
|
|
88
|
+
--scoreboard <obj> Scoreboard objective for variables (default: namespace).
|
|
89
|
+
Each datapack automatically uses its namespace as the objective
|
|
90
|
+
so multiple datapacks can coexist without collisions.
|
|
88
91
|
--stats Print optimizer statistics
|
|
89
92
|
--hot-reload <url> After each successful compile, POST to <url>/reload
|
|
90
93
|
(use with redscript-testharness; e.g. http://localhost:25561)
|
|
@@ -218,6 +221,10 @@ function parseArgs(args) {
|
|
|
218
221
|
result.mangle = false;
|
|
219
222
|
i++;
|
|
220
223
|
}
|
|
224
|
+
else if (arg === '--scoreboard') {
|
|
225
|
+
result.scoreboardObjective = args[++i];
|
|
226
|
+
i++;
|
|
227
|
+
}
|
|
221
228
|
else if (arg === '--hot-reload') {
|
|
222
229
|
result.hotReload = args[++i];
|
|
223
230
|
i++;
|
|
@@ -271,7 +278,7 @@ function printOptimizationStats(stats) {
|
|
|
271
278
|
console.log(` constant folding: ${stats.constantFolds} constants folded`);
|
|
272
279
|
console.log(` Total mcfunction commands: ${stats.totalCommandsBefore} -> ${stats.totalCommandsAfter} (${formatReduction(stats.totalCommandsBefore, stats.totalCommandsAfter)} reduction)`);
|
|
273
280
|
}
|
|
274
|
-
function compileCommand(file, output, namespace, target = 'datapack', showStats = false, dce = true, mangle = true) {
|
|
281
|
+
function compileCommand(file, output, namespace, target = 'datapack', showStats = false, dce = true, mangle = true, scoreboardObjective = undefined) {
|
|
275
282
|
// Read source file
|
|
276
283
|
if (!fs.existsSync(file)) {
|
|
277
284
|
console.error(`Error: File not found: ${file}`);
|
|
@@ -280,7 +287,7 @@ function compileCommand(file, output, namespace, target = 'datapack', showStats
|
|
|
280
287
|
const source = fs.readFileSync(file, 'utf-8');
|
|
281
288
|
try {
|
|
282
289
|
if (target === 'cmdblock') {
|
|
283
|
-
const result = (0, index_1.compile)(source, { namespace, filePath: file, dce, mangle });
|
|
290
|
+
const result = (0, index_1.compile)(source, { namespace, filePath: file, dce, mangle, scoreboardObjective });
|
|
284
291
|
printWarnings(result.warnings);
|
|
285
292
|
// Generate command block JSON
|
|
286
293
|
const hasTick = result.files.some(f => f.path.includes('__tick.mcfunction'));
|
|
@@ -309,7 +316,7 @@ function compileCommand(file, output, namespace, target = 'datapack', showStats
|
|
|
309
316
|
}
|
|
310
317
|
}
|
|
311
318
|
else {
|
|
312
|
-
const result = (0, index_1.compile)(source, { namespace, filePath: file, dce, mangle });
|
|
319
|
+
const result = (0, index_1.compile)(source, { namespace, filePath: file, dce, mangle, scoreboardObjective });
|
|
313
320
|
printWarnings(result.warnings);
|
|
314
321
|
// Default: generate datapack
|
|
315
322
|
// Create output directory
|
|
@@ -483,7 +490,8 @@ async function main() {
|
|
|
483
490
|
const output = target === 'structure'
|
|
484
491
|
? (parsed.outputNbt ?? parsed.output ?? `./${namespace}.nbt`)
|
|
485
492
|
: (parsed.output ?? './dist');
|
|
486
|
-
compileCommand(parsed.file, output, namespace, target, parsed.stats, parsed.dce, parsed.mangle)
|
|
493
|
+
compileCommand(parsed.file, output, namespace, target, parsed.stats, parsed.dce, parsed.mangle, parsed.scoreboardObjective // undefined = derive from namespace in compile()
|
|
494
|
+
);
|
|
487
495
|
}
|
|
488
496
|
break;
|
|
489
497
|
case 'watch':
|
|
@@ -30,6 +30,10 @@ export interface DatapackGenerationResult {
|
|
|
30
30
|
export interface DatapackGenerationOptions {
|
|
31
31
|
optimizeCommands?: boolean;
|
|
32
32
|
mangle?: boolean;
|
|
33
|
+
/** Scoreboard objective used for all scoreboard variables.
|
|
34
|
+
* Defaults to 'rs'. Override per-datapack to avoid collisions
|
|
35
|
+
* when multiple RedScript datapacks are loaded simultaneously. */
|
|
36
|
+
scoreboardObjective?: string;
|
|
33
37
|
}
|
|
34
38
|
export declare function countMcfunctionCommands(files: DatapackFile[]): number;
|
|
35
39
|
export declare function generateDatapackWithStats(module: IRModule, options?: DatapackGenerationOptions): DatapackGenerationResult;
|
|
@@ -26,7 +26,8 @@ const var_allocator_1 = require("../var-allocator");
|
|
|
26
26
|
// ---------------------------------------------------------------------------
|
|
27
27
|
// Utilities
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
|
-
|
|
29
|
+
// Default scoreboard objective — overridden per-compilation via DatapackGenerationOptions.scoreboardObjective
|
|
30
|
+
let OBJ = 'rs';
|
|
30
31
|
function operandToScore(op, alloc) {
|
|
31
32
|
if (op.kind === 'var')
|
|
32
33
|
return `${alloc.alloc(op.name)} ${OBJ}`;
|
|
@@ -335,7 +336,11 @@ function preAllocTerm(term, alloc) {
|
|
|
335
336
|
}
|
|
336
337
|
}
|
|
337
338
|
function generateDatapackWithStats(module, options = {}) {
|
|
338
|
-
const { optimizeCommands = true, mangle = false } = options;
|
|
339
|
+
const { optimizeCommands = true, mangle = false, scoreboardObjective = 'rs' } = options;
|
|
340
|
+
// Set module-level OBJ so all helper functions in this module use the correct objective.
|
|
341
|
+
// This is safe because compilation is synchronous.
|
|
342
|
+
OBJ = scoreboardObjective;
|
|
343
|
+
(0, commands_1.setOptimizerObjective)(scoreboardObjective);
|
|
339
344
|
const alloc = new var_allocator_1.VarAllocator(mangle);
|
|
340
345
|
const files = [];
|
|
341
346
|
const advancements = [];
|
|
@@ -375,10 +380,10 @@ function generateDatapackWithStats(module, options = {}) {
|
|
|
375
380
|
for (const eventType of eventTypes) {
|
|
376
381
|
const detection = types_1.EVENT_TYPES[eventType].detection;
|
|
377
382
|
if (eventType === 'PlayerDeath') {
|
|
378
|
-
loadLines.push(
|
|
383
|
+
loadLines.push(`scoreboard objectives add ${OBJ}.deaths deathCount`);
|
|
379
384
|
}
|
|
380
385
|
else if (eventType === 'EntityKill') {
|
|
381
|
-
loadLines.push(
|
|
386
|
+
loadLines.push(`scoreboard objectives add ${OBJ}.kills totalKillCount`);
|
|
382
387
|
}
|
|
383
388
|
else if (eventType === 'ItemUse') {
|
|
384
389
|
loadLines.push('# ItemUse detection requires a project-specific objective/tag setup');
|
package/dist/compile.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ export interface CompileOptions {
|
|
|
13
13
|
optimize?: boolean;
|
|
14
14
|
dce?: boolean;
|
|
15
15
|
mangle?: boolean;
|
|
16
|
+
/** Scoreboard objective used for all variable slots.
|
|
17
|
+
* Defaults to 'rs'. Set to a unique value (e.g. 'mypack_rs') when loading
|
|
18
|
+
* multiple RedScript datapacks simultaneously to avoid variable collisions. */
|
|
19
|
+
scoreboardObjective?: string;
|
|
16
20
|
/** Additional source files that should be treated as *library* code.
|
|
17
21
|
* Functions in these files are DCE-eligible: they are only compiled into
|
|
18
22
|
* the datapack when actually called from user code. Each string is parsed
|
package/dist/compile.js
CHANGED
|
@@ -209,6 +209,11 @@ function compile(source, options = {}) {
|
|
|
209
209
|
}
|
|
210
210
|
const dceResult = shouldRunDce ? (0, dce_1.eliminateDeadCode)(parsedAst) : { program: parsedAst, warnings: [] };
|
|
211
211
|
const ast = dceResult.program;
|
|
212
|
+
// Configure scoreboard objective for this compilation.
|
|
213
|
+
// Default: use the datapack namespace so each datapack gets its own objective
|
|
214
|
+
// automatically, preventing variable collisions when multiple datapacks coexist.
|
|
215
|
+
const scoreboardObj = options.scoreboardObjective ?? namespace;
|
|
216
|
+
(0, lowering_1.setScoreboardObjective)(scoreboardObj);
|
|
212
217
|
// Lowering
|
|
213
218
|
const ir = new lowering_1.Lowering(namespace, preprocessed.ranges).lower(ast);
|
|
214
219
|
// Optimization
|
|
@@ -217,7 +222,10 @@ function compile(source, options = {}) {
|
|
|
217
222
|
: ir;
|
|
218
223
|
// Code generation — mangle=true by default to prevent cross-function
|
|
219
224
|
// scoreboard variable collisions in the global MC scoreboard namespace.
|
|
220
|
-
const generated = (0, mcfunction_1.generateDatapackWithStats)(optimized, {
|
|
225
|
+
const generated = (0, mcfunction_1.generateDatapackWithStats)(optimized, {
|
|
226
|
+
mangle: options.mangle ?? true,
|
|
227
|
+
scoreboardObjective: scoreboardObj,
|
|
228
|
+
});
|
|
221
229
|
return {
|
|
222
230
|
success: true,
|
|
223
231
|
files: [...generated.files, ...generated.advancements],
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# block: merge_2
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# block: entry
|
|
2
|
+
execute store result score $t0 rs run scoreboard players get @s kills
|
|
3
|
+
scoreboard players operation $kills rs = $t0 rs
|
|
4
|
+
scoreboard players set $t1 rs 0
|
|
5
|
+
execute if score $t0 rs > $top_kills rs run scoreboard players set $t1 rs 1
|
|
6
|
+
execute if score $t1 rs matches 1.. run function arena:announce_leaders/foreach_0/then_0
|
|
7
|
+
execute if score $t1 rs matches ..0 run function arena:announce_leaders/foreach_0/merge_2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# block: merge_2
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# block: entry
|
|
2
|
+
execute store result score $t0 rs run scoreboard players get @s kills
|
|
3
|
+
scoreboard players set $t1 rs 0
|
|
4
|
+
execute if score $t0 rs = $top_kills rs run scoreboard players set $t1 rs 1
|
|
5
|
+
execute if score $t1 rs matches 1.. run function arena:announce_leaders/foreach_1/then_0
|
|
6
|
+
execute if score $t1 rs matches ..0 run function arena:announce_leaders/foreach_1/merge_2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# block: merge_2
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# block: entry
|
|
2
|
+
execute as @a run function arena:announce_leaders/foreach_0
|
|
3
|
+
scoreboard players set $t0 rs 0
|
|
4
|
+
execute if score $const_0 rs > $const_0 rs run scoreboard players set $t0 rs 1
|
|
5
|
+
execute if score $t0 rs matches 1.. run function arena:announce_leaders/then_0
|
|
6
|
+
execute if score $t0 rs matches ..0 run function arena:announce_leaders/else_1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# block: merge_2
|