@tishlang/tish 2.12.0 → 2.16.13

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 (71) hide show
  1. package/Cargo.toml +3 -0
  2. package/bin/tish +0 -0
  3. package/crates/tish/Cargo.toml +1 -1
  4. package/crates/tish/tests/integration_test.rs +80 -0
  5. package/crates/tish_ast/src/ast.rs +10 -0
  6. package/crates/tish_builtins/src/array.rs +529 -56
  7. package/crates/tish_builtins/src/collections.rs +114 -40
  8. package/crates/tish_builtins/src/string.rs +95 -8
  9. package/crates/tish_bytecode/src/chunk.rs +7 -0
  10. package/crates/tish_bytecode/src/compiler.rs +560 -64
  11. package/crates/tish_bytecode/src/lib.rs +1 -1
  12. package/crates/tish_bytecode/src/opcode.rs +154 -2
  13. package/crates/tish_bytecode/src/serialize.rs +2 -0
  14. package/crates/tish_bytecode/tests/append_local_string_builder.rs +63 -0
  15. package/crates/tish_bytecode/tests/math_unary_intrinsic.rs +47 -0
  16. package/crates/tish_compile/src/codegen.rs +17736 -5269
  17. package/crates/tish_compile/src/infer.rs +1707 -190
  18. package/crates/tish_compile/src/lib.rs +29 -4
  19. package/crates/tish_compile/src/resolve.rs +66 -5
  20. package/crates/tish_compile/src/types.rs +224 -28
  21. package/crates/tish_compile/tests/dump_codegen.rs +21 -0
  22. package/crates/tish_compile/tests/perf_codegen_169_173.rs +8 -17
  23. package/crates/tish_compile/tests/perf_codegen_173_part3.rs +61 -0
  24. package/crates/tish_compile/tests/perf_codegen_174.rs +160 -0
  25. package/crates/tish_compile/tests/perf_codegen_175.rs +190 -0
  26. package/crates/tish_compile/tests/perf_codegen_176.rs +60 -0
  27. package/crates/tish_compile/tests/perf_codegen_177.rs +167 -0
  28. package/crates/tish_compile/tests/perf_codegen_178.rs +114 -0
  29. package/crates/tish_compile/tests/perf_codegen_178_rec.rs +124 -0
  30. package/crates/tish_compile/tests/perf_codegen_181.rs +36 -0
  31. package/crates/tish_compile/tests/perf_codegen_320.rs +211 -0
  32. package/crates/tish_compile/tests/perf_codegen_module_const_forof.rs +40 -0
  33. package/crates/tish_compile_js/src/codegen.rs +33 -0
  34. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +100 -2
  35. package/crates/tish_core/Cargo.toml +4 -0
  36. package/crates/tish_core/src/json.rs +104 -5
  37. package/crates/tish_core/src/lib.rs +174 -0
  38. package/crates/tish_core/src/shape.rs +4 -2
  39. package/crates/tish_core/src/value.rs +565 -35
  40. package/crates/tish_core/src/vmref.rs +14 -0
  41. package/crates/tish_eval/src/eval.rs +675 -76
  42. package/crates/tish_eval/src/natives.rs +19 -0
  43. package/crates/tish_eval/src/value.rs +76 -21
  44. package/crates/tish_ffi/src/lib.rs +11 -1
  45. package/crates/tish_ffi/tests/double_free.rs +35 -0
  46. package/crates/tish_fmt/src/lib.rs +75 -1
  47. package/crates/tish_lexer/src/lib.rs +76 -0
  48. package/crates/tish_lexer/src/token.rs +4 -0
  49. package/crates/tish_lint/src/lib.rs +126 -0
  50. package/crates/tish_lsp/README.md +2 -1
  51. package/crates/tish_lsp/src/main.rs +378 -28
  52. package/crates/tish_native/src/build.rs +41 -0
  53. package/crates/tish_parser/Cargo.toml +4 -0
  54. package/crates/tish_parser/src/lib.rs +27 -0
  55. package/crates/tish_parser/src/parser.rs +302 -20
  56. package/crates/tish_resolve/src/lib.rs +9 -0
  57. package/crates/tish_runtime/Cargo.toml +5 -0
  58. package/crates/tish_runtime/src/http.rs +28 -10
  59. package/crates/tish_runtime/src/http_fetch.rs +150 -1
  60. package/crates/tish_runtime/src/http_prefork.rs +72 -11
  61. package/crates/tish_runtime/src/lib.rs +523 -42
  62. package/crates/tish_runtime/src/timers.rs +49 -2
  63. package/crates/tish_ui/src/jsx.rs +3 -0
  64. package/crates/tish_vm/src/jit.rs +2514 -117
  65. package/crates/tish_vm/src/vm.rs +1227 -182
  66. package/package.json +1 -1
  67. package/platform/darwin-arm64/tish +0 -0
  68. package/platform/darwin-x64/tish +0 -0
  69. package/platform/linux-arm64/tish +0 -0
  70. package/platform/linux-x64/tish +0 -0
  71. package/platform/win32-x64/tish.exe +0 -0
package/Cargo.toml CHANGED
@@ -34,6 +34,9 @@ members = [
34
34
  "crates/tish_resolve",
35
35
  "crates/tishlang_cargo_bindgen",
36
36
  ]
37
+ # Generated native-build projects (`tish build`) land under `target/` when TMPDIR points there;
38
+ # never enroll anything beneath `target/` as a workspace member.
39
+ exclude = ["target"]
37
40
  resolver = "2"
38
41
 
39
42
  [workspace.package]
package/bin/tish CHANGED
Binary file
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "tishlang"
3
- version = "2.12.0"
3
+ version = "2.16.13"
4
4
  edition = "2021"
5
5
  description = "Tish CLI - run, REPL, compile to native"
6
6
  license-file = { workspace = true }
@@ -52,6 +52,28 @@ fn integration_compile_cache_dir() -> PathBuf {
52
52
  target_dir().join("integration_compile_cache")
53
53
  }
54
54
 
55
+ /// Remove cache entries under `dir` whose name starts with `prefix` but is not part of the current
56
+ /// generation `keep_leaf` (the current artifact may have an extension appended, e.g. `<leaf>.wasm`,
57
+ /// so we keep anything that *starts with* `keep_leaf`). Best-effort: caps the per-fixture compile
58
+ /// cache so a `tish` rebuild doesn't leave the previous generation behind forever. Parallel-safe —
59
+ /// see the call site in `compile_cached`.
60
+ fn prune_stale_cache_generations(dir: &Path, prefix: &str, keep_leaf: &str) {
61
+ if let Ok(rd) = std::fs::read_dir(dir) {
62
+ for ent in rd.flatten() {
63
+ let name = ent.file_name();
64
+ let name = name.to_string_lossy();
65
+ if name.starts_with(prefix) && !name.starts_with(keep_leaf) {
66
+ let p = ent.path();
67
+ if p.is_dir() {
68
+ let _ = std::fs::remove_dir_all(&p);
69
+ } else {
70
+ let _ = std::fs::remove_file(&p);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+
55
77
  /// Match `tish build` with no `--feature`: link every capability compiled into this `tish` binary.
56
78
  fn native_build_features_for_integration_test() -> Vec<String> {
57
79
  let mut v: Vec<String> = tishlang_vm::all_compiled_capabilities()
@@ -170,6 +192,14 @@ fn compile_cached(bin: &Path, path: &Path, backend: &str) -> PathBuf {
170
192
  // Include `backend` in the leaf name so nested cargo bin names never collide across backends.
171
193
  let leaf = format!("{}__{}__{}", stem, backend, hash8);
172
194
 
195
+ // Cap the cache: `hash8` mixes in the `tish` binary's mtime, so every recompile of `tish`
196
+ // orphans the previous generation of THIS (stem, backend). Drop those stale siblings now, so the
197
+ // cache holds ~one generation per fixture instead of growing without bound across rebuilds
198
+ // (it reached 14 GB in one session and exhausted the disk). Safe under parallel `nextest`: every
199
+ // live process for this (stem, backend) computes the SAME `hash8`, so only genuinely-stale
200
+ // generations (a different hash) are removed, never an artifact a concurrent run is using.
201
+ prune_stale_cache_generations(&cache_base, &format!("{}__{}__", stem, backend), &leaf);
202
+
173
203
  let (artifact_path, compile_args): (PathBuf, Vec<OsString>) = match backend {
174
204
  "native" => {
175
205
  let ext = if cfg!(target_os = "windows") {
@@ -588,6 +618,46 @@ fn test_import_alias() {
588
618
  }
589
619
  }
590
620
 
621
+ /// #305: re-export — `export { foo, bar as inc } from "./dep"` and `export * from "./dep"` in a
622
+ /// middle module, consumed by a named import and a namespace import in the entry. Identical across
623
+ /// the interpreter and the VM (native/cranelift/js verified via the bundle path).
624
+ #[test]
625
+ fn test_reexport() {
626
+ let bin = tish_bin();
627
+ if !bin.exists() {
628
+ return;
629
+ }
630
+ let path = workspace_root()
631
+ .join("tests")
632
+ .join("modules")
633
+ .join("reexport.tish");
634
+ if !path.exists() {
635
+ return;
636
+ }
637
+ let expected = "42\n42\n1.0\n42\n";
638
+ for backend_args in [vec!["run"], vec!["run", "--backend", "vm"]] {
639
+ let mut args = backend_args.clone();
640
+ args.push(path.to_string_lossy().to_string().leak());
641
+ let out = Command::new(&bin)
642
+ .args(&args)
643
+ .current_dir(workspace_root())
644
+ .output()
645
+ .expect("run tish binary");
646
+ assert!(
647
+ out.status.success(),
648
+ "reexport.tish ({:?}) failed: stderr={}",
649
+ backend_args,
650
+ String::from_utf8_lossy(&out.stderr)
651
+ );
652
+ assert_eq!(
653
+ String::from_utf8_lossy(&out.stdout),
654
+ expected,
655
+ "reexport output mismatch on backend {:?}",
656
+ backend_args
657
+ );
658
+ }
659
+ }
660
+
591
661
  /// Combined validation: async/await + Promise + setTimeout + multiple HTTP requests.
592
662
  /// #97: a module's non-exported top-level bindings stay private — a same-named binding in
593
663
  /// another module must not overwrite them (runtime), and the `--target js` bundle must not
@@ -1376,6 +1446,16 @@ fn test_mvp_programs_native() {
1376
1446
  let combined = combined_mvp_native_inputs_hash(&paths);
1377
1447
  let cache_dir = mvp_native_batch_cache_dir(combined);
1378
1448
  let _ = std::fs::create_dir_all(&cache_dir);
1449
+ // Cap the native batch cache: a new combined hash (a codegen / inference / source change) orphans
1450
+ // the previous `native_many/<hash>` directory, each of which holds a full nested Cargo `target/`
1451
+ // (~GBs). Drop the stale siblings, keeping only the current generation. Only `test_mvp_programs_
1452
+ // native` builds here, so there is no cross-process race.
1453
+ if let (Some(parent), Some(keep)) = (
1454
+ cache_dir.parent(),
1455
+ cache_dir.file_name().map(|n| n.to_string_lossy().into_owned()),
1456
+ ) {
1457
+ prune_stale_cache_generations(parent, "", &keep);
1458
+ }
1379
1459
 
1380
1460
  let ext = if cfg!(target_os = "windows") {
1381
1461
  ".exe"
@@ -156,6 +156,16 @@ pub enum ExportDeclaration {
156
156
  Named(Box<Statement>),
157
157
  /// export default expr
158
158
  Default(Expr),
159
+ /// Re-export from another module (#305):
160
+ /// `export { foo, bar as inc } from "./m"` -> specifiers, all=false
161
+ /// `export * from "./m"` -> specifiers=[], all=true
162
+ /// Specifiers reuse `ImportSpecifier::Named` (`{ a as b }`).
163
+ ReExport {
164
+ specifiers: Vec<ImportSpecifier>,
165
+ all: bool,
166
+ from: Arc<str>,
167
+ span: Span,
168
+ },
159
169
  }
160
170
 
161
171
  #[derive(Debug, Clone)]