redscript-mc 2.3.0 → 2.4.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/src/__tests__/array-dynamic.test.d.ts +12 -0
  3. package/dist/src/__tests__/array-dynamic.test.js +131 -0
  4. package/dist/src/__tests__/array-write.test.d.ts +11 -0
  5. package/dist/src/__tests__/array-write.test.js +149 -0
  6. package/dist/src/ast/types.d.ts +7 -0
  7. package/dist/src/emit/modules.js +5 -0
  8. package/dist/src/hir/lower.js +29 -0
  9. package/dist/src/hir/monomorphize.js +2 -0
  10. package/dist/src/hir/types.d.ts +9 -2
  11. package/dist/src/lir/lower.js +131 -0
  12. package/dist/src/mir/lower.js +73 -3
  13. package/dist/src/mir/macro.js +5 -0
  14. package/dist/src/mir/types.d.ts +12 -0
  15. package/dist/src/mir/verify.js +7 -0
  16. package/dist/src/optimizer/copy_prop.js +5 -0
  17. package/dist/src/optimizer/coroutine.js +12 -0
  18. package/dist/src/optimizer/dce.js +9 -0
  19. package/dist/src/optimizer/unroll.js +3 -0
  20. package/dist/src/parser/index.js +5 -0
  21. package/dist/src/typechecker/index.js +5 -0
  22. package/editors/vscode/package-lock.json +3 -3
  23. package/editors/vscode/package.json +1 -1
  24. package/package.json +1 -1
  25. package/src/__tests__/array-dynamic.test.ts +147 -0
  26. package/src/__tests__/array-write.test.ts +169 -0
  27. package/src/ast/types.ts +1 -0
  28. package/src/emit/modules.ts +5 -0
  29. package/src/hir/lower.ts +30 -0
  30. package/src/hir/monomorphize.ts +2 -0
  31. package/src/hir/types.ts +3 -1
  32. package/src/lir/lower.ts +151 -0
  33. package/src/mir/lower.ts +75 -3
  34. package/src/mir/macro.ts +5 -0
  35. package/src/mir/types.ts +2 -0
  36. package/src/mir/verify.ts +7 -0
  37. package/src/optimizer/copy_prop.ts +5 -0
  38. package/src/optimizer/coroutine.ts +9 -0
  39. package/src/optimizer/dce.ts +6 -0
  40. package/src/optimizer/unroll.ts +3 -0
  41. package/src/parser/index.ts +9 -0
  42. package/src/stdlib/list.mcrs +43 -72
  43. package/src/stdlib/math.mcrs +137 -0
  44. package/src/stdlib/timer.mcrs +32 -0
  45. package/src/typechecker/index.ts +6 -0
@@ -390,3 +390,140 @@ fn exp_fx(x: int): int {
390
390
  }
391
391
  return er;
392
392
  }
393
+
394
+ // ─── Cubic root ──────────────────────────────────────────────────────────────
395
+
396
+ // cbrt_fx(x): integer cube root, returns floor(cbrt(x)).
397
+ // Uses Newton's method: g_next = (2*g + x/g²) / 3
398
+ // cbrt_fx(1000) = 10 (∛1000=10), cbrt_fx(27) = 3, cbrt_fx(8) = 2
399
+ fn cbrt_fx(x: int): int {
400
+ if (x <= 0) { return 0; }
401
+ let g: int = x / 3;
402
+ if (g <= 0) { g = 1; }
403
+ let i: int = 0;
404
+ while (i < 20) {
405
+ let g2: int = g * g;
406
+ if (g2 <= 0) { g2 = 1; }
407
+ let next: int = (2 * g + x / g2) / 3;
408
+ if (next == g) { i = 20; }
409
+ g = next;
410
+ if (g <= 0) { g = 1; }
411
+ i = i + 1;
412
+ }
413
+ return g;
414
+ }
415
+
416
+ // ─── Combinatorics ───────────────────────────────────────────────────────────
417
+
418
+ // factorial(n): n! for n ∈ [0, 12] (13! exceeds int32)
419
+ fn factorial(n: int): int {
420
+ if (n <= 1) { return 1; }
421
+ let r: int = 1;
422
+ let i: int = 2;
423
+ while (i <= n) { r = r * i; i = i + 1; }
424
+ return r;
425
+ }
426
+
427
+ // combinations(n, k): C(n,k) = n! / (k! * (n-k)!) for n ≤ 20, k ≤ n
428
+ // Uses multiplicative formula to avoid overflow: C(n,k) = ∏ (n-i)/(i+1) for i=0..k-1
429
+ fn combinations(n: int, k: int): int {
430
+ if (k <= 0) { return 1; }
431
+ if (k > n) { return 0; }
432
+ // Use smaller k for efficiency: C(n,k) == C(n, n-k)
433
+ let kk: int = k;
434
+ if (n - k < kk) { kk = n - k; }
435
+ let r: int = 1;
436
+ let i: int = 0;
437
+ while (i < kk) {
438
+ r = r * (n - i) / (i + 1);
439
+ i = i + 1;
440
+ }
441
+ return r;
442
+ }
443
+
444
+ // ─── Logarithm ───────────────────────────────────────────────────────────────
445
+
446
+ // log10_fx(x): log base 10, fixed-point ×10000
447
+ // log10(x) = ln(x) / ln(10) ≈ ln(x) / 23026
448
+ fn log10_fx(x: int): int {
449
+ return ln(x) * 10000 / 23026;
450
+ }
451
+
452
+ // log2_fx(x): log base 2, fixed-point ×10000
453
+ // log2(x) = ln(x) / ln(2) ≈ ln(x) / 6931
454
+ fn log2_fx(x: int): int {
455
+ return ln(x) * 10000 / 6931;
456
+ }
457
+
458
+ // loga_fx(base_fx, x): log_base(x), fixed-point ×10000
459
+ // base_fx and x are both ×10000
460
+ // loga_fx(20000, 40000) ≈ 10000 (log_2(4) = 2, but ×10000 → 20000... wait)
461
+ // Actually: log_b(x) = ln(x) / ln(b), both ×10000, so result = ln(x)/ln(b) × 10000
462
+ fn loga_fx(base_fx: int, x: int): int {
463
+ let lb: int = ln(base_fx);
464
+ if (lb == 0) { return 0; }
465
+ return ln(x) * 10000 / lb;
466
+ }
467
+
468
+ // ─── Gamma function approximation ────────────────────────────────────────────
469
+
470
+ // gamma_int(n): Gamma(n) = (n-1)! for positive integers
471
+ fn gamma_int(n: int): int {
472
+ if (n <= 1) { return 1; }
473
+ return factorial(n - 1);
474
+ }
475
+
476
+ // ─── Linear equation solvers ─────────────────────────────────────────────────
477
+
478
+ // solve2x2_x(a, b, e, c, d, f): solve ax + by = e, cx + dy = f → return x × 10000
479
+ // Uses Cramer's rule. Returns 0 if determinant = 0 (singular system).
480
+ // a, b, c, d, e, f are integers (not fixed-point); result is fixed-point ×10000.
481
+ fn solve2x2_x(a: int, b: int, e: int, c: int, d: int, f: int): int {
482
+ let det: int = a * d - b * c;
483
+ if (det == 0) { return 0; }
484
+ return (e * d - b * f) * 10000 / det;
485
+ }
486
+
487
+ // solve2x2_y(a, b, e, c, d, f): same system, return y × 10000
488
+ fn solve2x2_y(a: int, b: int, e: int, c: int, d: int, f: int): int {
489
+ let det: int = a * d - b * c;
490
+ if (det == 0) { return 0; }
491
+ return (a * f - e * c) * 10000 / det;
492
+ }
493
+
494
+ // ─── Quadratic equation ───────────────────────────────────────────────────────
495
+
496
+ // quadratic_disc(a, b, c): discriminant b² - 4ac
497
+ // Returns > 0 (two real roots), 0 (one root), < 0 (no real roots)
498
+ fn quadratic_disc(a: int, b: int, c: int): int {
499
+ return b * b - 4 * a * c;
500
+ }
501
+
502
+ // quadratic_x1(a, b, c): larger root × 10000 using integer sqrt
503
+ // Only valid when discriminant >= 0
504
+ fn quadratic_x1(a: int, b: int, c: int): int {
505
+ if (a == 0) { return 0; }
506
+ let disc: int = b * b - 4 * a * c;
507
+ if (disc < 0) { return 0; }
508
+ let sq: int = isqrt(disc);
509
+ return (0 - b + sq) * 10000 / (2 * a);
510
+ }
511
+
512
+ // quadratic_x2(a, b, c): smaller root × 10000
513
+ fn quadratic_x2(a: int, b: int, c: int): int {
514
+ if (a == 0) { return 0; }
515
+ let disc: int = b * b - 4 * a * c;
516
+ if (disc < 0) { return 0; }
517
+ let sq: int = isqrt(disc);
518
+ return (0 - b - sq) * 10000 / (2 * a);
519
+ }
520
+
521
+ // ─── Fixed-point comparison helpers ──────────────────────────────────────────
522
+
523
+ // approx_eq(a, b, eps): 1 if |a - b| <= eps
524
+ fn approx_eq(a: int, b: int, eps: int): int {
525
+ let d: int = a - b;
526
+ if (d < 0) { d = 0 - d; }
527
+ if (d <= eps) { return 1; }
528
+ return 0;
529
+ }
@@ -75,3 +75,35 @@ impl Timer {
75
75
  }
76
76
  }
77
77
  }
78
+
79
+ // ─── Tick-based stopwatch ─────────────────────────────────────────────────────
80
+
81
+ // tick_to_seconds(ticks): convert MC ticks to seconds (20 ticks = 1 second)
82
+ fn tick_to_seconds(ticks: int): int {
83
+ return ticks / 20;
84
+ }
85
+
86
+ // tick_to_ms(ticks): convert ticks to milliseconds
87
+ fn tick_to_ms(ticks: int): int {
88
+ return ticks * 50;
89
+ }
90
+
91
+ // seconds_to_ticks(s): convert seconds to ticks
92
+ fn seconds_to_ticks(s: int): int {
93
+ return s * 20;
94
+ }
95
+
96
+ // format_time_s(ticks): ticks → seconds component (mod 60)
97
+ fn format_time_s(ticks: int): int {
98
+ return (ticks / 20) % 60;
99
+ }
100
+
101
+ // format_time_m(ticks): ticks → minutes component
102
+ fn format_time_m(ticks: int): int {
103
+ return (ticks / 1200) % 60;
104
+ }
105
+
106
+ // format_time_h(ticks): ticks → hours component
107
+ fn format_time_h(ticks: int): int {
108
+ return ticks / 72000;
109
+ }
@@ -619,6 +619,12 @@ export class TypeChecker {
619
619
  this.checkExpr(expr.value)
620
620
  break
621
621
 
622
+ case 'index_assign':
623
+ this.checkExpr(expr.obj)
624
+ this.checkExpr(expr.index)
625
+ this.checkExpr(expr.value)
626
+ break
627
+
622
628
  case 'index':
623
629
  this.checkExpr(expr.obj)
624
630
  this.checkExpr(expr.index)