@tishlang/tish 1.9.2 → 1.12.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 (84) hide show
  1. package/bin/tish +0 -0
  2. package/crates/js_to_tish/src/transform/expr.rs +8 -6
  3. package/crates/js_to_tish/src/transform/stmt.rs +12 -13
  4. package/crates/tish/Cargo.toml +1 -1
  5. package/crates/tish/src/cargo_native_registry.rs +4 -1
  6. package/crates/tish/src/cli_help.rs +9 -1
  7. package/crates/tish/src/main.rs +66 -11
  8. package/crates/tish/tests/integration_test.rs +145 -7
  9. package/crates/tish_ast/src/ast.rs +3 -9
  10. package/crates/tish_build_utils/src/lib.rs +74 -23
  11. package/crates/tish_builtins/src/array.rs +2 -3
  12. package/crates/tish_builtins/src/construct.rs +15 -28
  13. package/crates/tish_builtins/src/globals.rs +18 -16
  14. package/crates/tish_builtins/src/helpers.rs +1 -4
  15. package/crates/tish_builtins/src/lib.rs +1 -0
  16. package/crates/tish_builtins/src/math.rs +7 -0
  17. package/crates/tish_builtins/src/object.rs +10 -10
  18. package/crates/tish_builtins/src/string.rs +27 -3
  19. package/crates/tish_builtins/src/symbol.rs +83 -0
  20. package/crates/tish_compile/src/codegen.rs +324 -158
  21. package/crates/tish_compile/src/lib.rs +39 -7
  22. package/crates/tish_compile/src/resolve.rs +191 -6
  23. package/crates/tish_compile/src/types.rs +6 -6
  24. package/crates/tish_compile_js/src/codegen.rs +8 -5
  25. package/crates/tish_core/src/console_style.rs +9 -0
  26. package/crates/tish_core/src/json.rs +17 -7
  27. package/crates/tish_core/src/macros.rs +2 -2
  28. package/crates/tish_core/src/value.rs +213 -4
  29. package/crates/tish_cranelift/src/link.rs +1 -1
  30. package/crates/tish_cranelift_runtime/Cargo.toml +4 -0
  31. package/crates/tish_eval/src/eval.rs +135 -73
  32. package/crates/tish_eval/src/http.rs +18 -12
  33. package/crates/tish_eval/src/lib.rs +29 -0
  34. package/crates/tish_eval/src/regex.rs +1 -1
  35. package/crates/tish_eval/src/value.rs +89 -4
  36. package/crates/tish_eval/src/value_convert.rs +30 -8
  37. package/crates/tish_fmt/src/lib.rs +4 -1
  38. package/crates/tish_lexer/src/lib.rs +7 -2
  39. package/crates/tish_llvm/src/lib.rs +2 -2
  40. package/crates/tish_lsp/src/builtin_goto.rs +111 -10
  41. package/crates/tish_lsp/src/import_goto.rs +35 -22
  42. package/crates/tish_lsp/src/main.rs +118 -85
  43. package/crates/tish_native/src/build.rs +270 -24
  44. package/crates/tish_native/src/config.rs +48 -0
  45. package/crates/tish_native/src/lib.rs +139 -12
  46. package/crates/tish_parser/src/lib.rs +5 -2
  47. package/crates/tish_parser/src/parser.rs +45 -75
  48. package/crates/tish_pg/src/error.rs +1 -1
  49. package/crates/tish_pg/src/lib.rs +61 -73
  50. package/crates/tish_resolve/src/lib.rs +283 -158
  51. package/crates/tish_resolve/src/pos.rs +10 -2
  52. package/crates/tish_runtime/Cargo.toml +3 -0
  53. package/crates/tish_runtime/src/http.rs +39 -39
  54. package/crates/tish_runtime/src/http_fetch.rs +12 -12
  55. package/crates/tish_runtime/src/lib.rs +35 -44
  56. package/crates/tish_runtime/src/native_promise.rs +0 -11
  57. package/crates/tish_runtime/src/promise.rs +14 -1
  58. package/crates/tish_runtime/src/promise_io.rs +1 -4
  59. package/crates/tish_runtime/src/timers.rs +12 -7
  60. package/crates/tish_runtime/src/ws.rs +40 -27
  61. package/crates/tish_runtime/tests/fetch_readable_stream.rs +10 -8
  62. package/crates/tish_ui/src/jsx.rs +6 -4
  63. package/crates/tish_ui/src/lib.rs +5 -4
  64. package/crates/tish_ui/src/runtime/hooks.rs +123 -37
  65. package/crates/tish_ui/src/runtime/mod.rs +21 -41
  66. package/crates/tish_vm/Cargo.toml +2 -0
  67. package/crates/tish_vm/src/vm.rs +258 -153
  68. package/crates/tish_wasm/src/lib.rs +60 -7
  69. package/crates/tish_wasm_runtime/Cargo.toml +10 -1
  70. package/crates/tish_wasm_runtime/src/gpu.rs +413 -0
  71. package/crates/tish_wasm_runtime/src/lib.rs +7 -1
  72. package/crates/tishlang_cargo_bindgen/src/classify.rs +1 -3
  73. package/crates/tishlang_cargo_bindgen/src/discover.rs +10 -5
  74. package/crates/tishlang_cargo_bindgen/src/infer.rs +18 -8
  75. package/crates/tishlang_cargo_bindgen/src/lib.rs +25 -26
  76. package/crates/tishlang_cargo_bindgen/src/main.rs +41 -38
  77. package/crates/tishlang_cargo_bindgen/src/metadata.rs +4 -1
  78. package/justfile +3 -3
  79. package/package.json +1 -1
  80. package/platform/darwin-arm64/tish +0 -0
  81. package/platform/darwin-x64/tish +0 -0
  82. package/platform/linux-arm64/tish +0 -0
  83. package/platform/linux-x64/tish +0 -0
  84. package/platform/win32-x64/tish.exe +0 -0
@@ -28,7 +28,8 @@ pub fn select_glue_crate_from_package_json(
28
28
  e
29
29
  )
30
30
  })?;
31
- let j: Value = serde_json::from_str(&raw).map_err(|e| format!("{}: {}", pkg_json_path.display(), e))?;
31
+ let j: Value =
32
+ serde_json::from_str(&raw).map_err(|e| format!("{}: {}", pkg_json_path.display(), e))?;
32
33
  let rust_deps = j
33
34
  .get("tish")
34
35
  .and_then(|t| t.get("rustDependencies"))
@@ -123,7 +124,8 @@ fn dep_version_req_string_glue(spec: &toml::Value) -> Result<String, String> {
123
124
  }
124
125
 
125
126
  /// Crates we ignore when inferring bindgen **upstream** from the **app** `Cargo.toml` (not the glue crate).
126
- const ROOT_MANIFEST_SKIP_DEPS: &[&str] = &["tishlang_runtime", "tishlang_core", "tishlang_build_utils"];
127
+ const ROOT_MANIFEST_SKIP_DEPS: &[&str] =
128
+ &["tishlang_runtime", "tishlang_core", "tishlang_build_utils"];
127
129
 
128
130
  /// Registry semver for bindgen metadata probe; skips path/git/workspace-only entries (project root fallback).
129
131
  fn dep_version_req_string_root(spec: &toml::Value) -> Option<String> {
@@ -136,7 +138,9 @@ fn dep_version_req_string_root(spec: &toml::Value) -> Option<String> {
136
138
  if t.get("path").is_some() || t.get("git").is_some() {
137
139
  return None;
138
140
  }
139
- t.get("version").and_then(|v| v.as_str()).map(|s| s.to_string())
141
+ t.get("version")
142
+ .and_then(|v| v.as_str())
143
+ .map(|s| s.to_string())
140
144
  }
141
145
  _ => None,
142
146
  }
@@ -209,13 +213,15 @@ fn disambiguate_upstream_candidates(
209
213
  /// disambiguating when `serde_json` is present as a JSON-bridge helper alongside another crate.
210
214
  pub fn parse_upstream_from_glue_cargo(cargo_toml_path: &Path) -> Result<(String, String), String> {
211
215
  let s = fs::read_to_string(cargo_toml_path).map_err(|e| e.to_string())?;
212
- let root: toml::Value = toml::from_str(&s).map_err(|e| format!("{}: {}", cargo_toml_path.display(), e))?;
216
+ let root: toml::Value =
217
+ toml::from_str(&s).map_err(|e| format!("{}: {}", cargo_toml_path.display(), e))?;
213
218
  let deps = root
214
219
  .get("dependencies")
215
220
  .and_then(|d| d.as_table())
216
221
  .ok_or_else(|| format!("{} has no [dependencies]", cargo_toml_path.display()))?;
217
222
 
218
- let candidates = collect_upstream_candidates_from_table(deps, &[], dep_version_req_string_glue)?;
223
+ let candidates =
224
+ collect_upstream_candidates_from_table(deps, &[], dep_version_req_string_glue)?;
219
225
  disambiguate_upstream_candidates(
220
226
  candidates,
221
227
  cargo_toml_path,
@@ -226,9 +232,12 @@ pub fn parse_upstream_from_glue_cargo(cargo_toml_path: &Path) -> Result<(String,
226
232
  /// Infer upstream from the **project** `Cargo.toml` when the glue crate does not exist yet.
227
233
  /// Uses `[dependencies]` and `[dev-dependencies]`, skips Tish toolchain path crates (`tishlang_core`, …),
228
234
  /// and only keeps entries with a registry semver (skips bare `path =` / `git` deps).
229
- pub fn parse_upstream_from_root_package_cargo(cargo_toml_path: &Path) -> Result<(String, String), String> {
235
+ pub fn parse_upstream_from_root_package_cargo(
236
+ cargo_toml_path: &Path,
237
+ ) -> Result<(String, String), String> {
230
238
  let s = fs::read_to_string(cargo_toml_path).map_err(|e| e.to_string())?;
231
- let root: toml::Value = toml::from_str(&s).map_err(|e| format!("{}: {}", cargo_toml_path.display(), e))?;
239
+ let root: toml::Value =
240
+ toml::from_str(&s).map_err(|e| format!("{}: {}", cargo_toml_path.display(), e))?;
232
241
 
233
242
  let mut candidates = root
234
243
  .get("dependencies")
@@ -255,7 +264,8 @@ pub fn infer_from_project_root(
255
264
  project_root: &Path,
256
265
  rust_dep_key: Option<&str>,
257
266
  ) -> Result<InferredProjectBindgen, String> {
258
- let (output_crate_name, out_dir) = select_glue_crate_from_package_json(project_root, rust_dep_key)?;
267
+ let (output_crate_name, out_dir) =
268
+ select_glue_crate_from_package_json(project_root, rust_dep_key)?;
259
269
  let glue_cargo = out_dir.join("Cargo.toml");
260
270
  let root_cargo = project_root.join("Cargo.toml");
261
271
 
@@ -22,7 +22,9 @@ mod metadata;
22
22
 
23
23
  pub use classify::SignatureClass;
24
24
  pub use discover::rust_public_fn_location;
25
- pub use metadata::{resolve_dependency_from_manifest, resolve_registry_dependency, ResolvedDependency};
25
+ pub use metadata::{
26
+ resolve_dependency_from_manifest, resolve_registry_dependency, ResolvedDependency,
27
+ };
26
28
 
27
29
  use std::fs;
28
30
  use std::io;
@@ -69,7 +71,10 @@ pub fn generate_from_manifest(
69
71
  generate_from_resolved(cfg, &resolved)
70
72
  }
71
73
 
72
- fn generate_from_resolved(cfg: &BindgenConfig, resolved: &ResolvedDependency) -> Result<(), String> {
74
+ fn generate_from_resolved(
75
+ cfg: &BindgenConfig,
76
+ resolved: &ResolvedDependency,
77
+ ) -> Result<(), String> {
73
78
  let root = resolved.source_root();
74
79
  let fns = discover::discover_public_functions(&root)?;
75
80
 
@@ -102,17 +107,9 @@ fn generate_from_resolved(cfg: &BindgenConfig, resolved: &ResolvedDependency) ->
102
107
  emitted.push((export.clone(), class));
103
108
  }
104
109
 
105
- let lib_rs = render_generated_lib(
106
- &cfg.dependency_name,
107
- &emitted,
108
- need_json_helpers,
109
- )?;
110
+ let lib_rs = render_generated_lib(&cfg.dependency_name, &emitted, need_json_helpers)?;
110
111
 
111
- let cargo_toml = render_output_cargo_toml(
112
- cfg,
113
- resolved.version(),
114
- need_json_helpers,
115
- )?;
112
+ let cargo_toml = render_output_cargo_toml(cfg, resolved.version(), need_json_helpers)?;
116
113
 
117
114
  fs::create_dir_all(cfg.out_dir.join("src")).map_err(|e| e.to_string())?;
118
115
  fs::write(cfg.out_dir.join("Cargo.toml"), cargo_toml).map_err(|e| e.to_string())?;
@@ -128,16 +125,18 @@ impl BindgenConfig {
128
125
  }
129
126
  }
130
127
 
131
- fn render_output_cargo_toml(cfg: &BindgenConfig, dep_exact_version: &str, need_serde_json: bool) -> Result<String, String> {
128
+ fn render_output_cargo_toml(
129
+ cfg: &BindgenConfig,
130
+ dep_exact_version: &str,
131
+ need_serde_json: bool,
132
+ ) -> Result<String, String> {
132
133
  let rt_line = match &cfg.tishlang_runtime {
133
- TishlangRuntimeDep::Path(p) => format!(
134
- "tishlang_runtime = {{ path = {} }}\n",
135
- toml_string_value(p)
136
- ),
137
- TishlangRuntimeDep::Version(req) => format!(
138
- "tishlang_runtime = {}\n",
139
- toml_string_value(req)
140
- ),
134
+ TishlangRuntimeDep::Path(p) => {
135
+ format!("tishlang_runtime = {{ path = {} }}\n", toml_string_value(p))
136
+ }
137
+ TishlangRuntimeDep::Version(req) => {
138
+ format!("tishlang_runtime = {}\n", toml_string_value(req))
139
+ }
141
140
  };
142
141
  let dep_line = format!(
143
142
  "{} = {}\n",
@@ -185,10 +184,7 @@ fn render_generated_lib(
185
184
  use tishlang_runtime::{ObjectMap, Value, VmRef};\n\n",
186
185
  );
187
186
 
188
- out.push_str(&format!(
189
- "use {} as _tish_upstream;\n\n",
190
- crate_ident
191
- ));
187
+ out.push_str(&format!("use {} as _tish_upstream;\n\n", crate_ident));
192
188
 
193
189
  if need_json_helpers {
194
190
  out.push_str(JSON_HELPERS);
@@ -318,7 +314,10 @@ fn canonical_path_string(p: &Path) -> Result<String, String> {
318
314
  }
319
315
 
320
316
  /// Relative path from `out_dir` to `runtime` for Cargo.toml `path =`.
321
- pub fn runtime_path_relative_to_out_dir(out_dir: &Path, runtime: impl AsRef<Path>) -> Result<String, String> {
317
+ pub fn runtime_path_relative_to_out_dir(
318
+ out_dir: &Path,
319
+ runtime: impl AsRef<Path>,
320
+ ) -> Result<String, String> {
322
321
  let abs_rt = runtime
323
322
  .as_ref()
324
323
  .canonicalize()
@@ -8,7 +8,8 @@ use std::path::PathBuf;
8
8
  use clap::Parser;
9
9
  use tishlang_cargo_bindgen::{
10
10
  generate_from_manifest, generate_from_registry_dependency, infer,
11
- resolve_runtime_path_for_output, runtime_path_relative_to_out_dir, BindgenConfig, TishlangRuntimeDep,
11
+ resolve_runtime_path_for_output, runtime_path_relative_to_out_dir, BindgenConfig,
12
+ TishlangRuntimeDep,
12
13
  };
13
14
 
14
15
  #[derive(Parser, Debug)]
@@ -83,49 +84,51 @@ fn run() -> Result<(), String> {
83
84
 
84
85
  let current_dir = std::env::current_dir().map_err(|e| e.to_string())?;
85
86
 
86
- let (
87
- output_crate_name,
88
- out_dir,
89
- dependency_name,
90
- dependency_version_req,
91
- search_root,
92
- ) = if let Some(dep) = args.dependency.as_ref() {
93
- if let Some(out) = args.out_dir.as_ref() {
87
+ let (output_crate_name, out_dir, dependency_name, dependency_version_req, search_root) =
88
+ if let Some(dep) = args.dependency.as_ref() {
89
+ if let Some(out) = args.out_dir.as_ref() {
90
+ let root = args
91
+ .project_root
92
+ .clone()
93
+ .unwrap_or_else(|| out.parent().unwrap_or(out).to_path_buf());
94
+ (
95
+ args.crate_name
96
+ .clone()
97
+ .unwrap_or_else(|| "tish_serde_json".into()),
98
+ out.clone(),
99
+ dep.clone(),
100
+ args.dependency_version.clone(),
101
+ root,
102
+ )
103
+ } else {
104
+ let root = args
105
+ .project_root
106
+ .clone()
107
+ .unwrap_or_else(|| current_dir.clone());
108
+ let (crate_key, od) =
109
+ infer::infer_glue_paths_only(&root, args.crate_name.as_deref())?;
110
+ (
111
+ crate_key,
112
+ od,
113
+ dep.clone(),
114
+ args.dependency_version.clone(),
115
+ root,
116
+ )
117
+ }
118
+ } else {
94
119
  let root = args
95
120
  .project_root
96
121
  .clone()
97
- .unwrap_or_else(|| out.parent().unwrap_or(out).to_path_buf());
122
+ .unwrap_or_else(|| current_dir.clone());
123
+ let inf = infer::infer_from_project_root(&root, args.crate_name.as_deref())?;
98
124
  (
99
- args.crate_name
100
- .clone()
101
- .unwrap_or_else(|| "tish_serde_json".into()),
102
- out.clone(),
103
- dep.clone(),
104
- args.dependency_version.clone(),
125
+ inf.output_crate_name,
126
+ inf.out_dir,
127
+ inf.dependency_name,
128
+ inf.dependency_version_req,
105
129
  root,
106
130
  )
107
- } else {
108
- let root = args.project_root.clone().unwrap_or_else(|| current_dir.clone());
109
- let (crate_key, od) = infer::infer_glue_paths_only(&root, args.crate_name.as_deref())?;
110
- (
111
- crate_key,
112
- od,
113
- dep.clone(),
114
- args.dependency_version.clone(),
115
- root,
116
- )
117
- }
118
- } else {
119
- let root = args.project_root.clone().unwrap_or_else(|| current_dir.clone());
120
- let inf = infer::infer_from_project_root(&root, args.crate_name.as_deref())?;
121
- (
122
- inf.output_crate_name,
123
- inf.out_dir,
124
- inf.dependency_name,
125
- inf.dependency_version_req,
126
- root,
127
- )
128
- };
131
+ };
129
132
 
130
133
  let tishlang_runtime = if let Some(req) = args.tishlang_runtime_version.clone() {
131
134
  TishlangRuntimeDep::Version(req)
@@ -35,7 +35,10 @@ fn from_package(pkg: &Package) -> ResolvedDependency {
35
35
  }
36
36
 
37
37
  /// Build a tiny probe crate, run `cargo metadata`, and return the named package.
38
- pub fn resolve_registry_dependency(name: &str, version_req: &str) -> Result<ResolvedDependency, String> {
38
+ pub fn resolve_registry_dependency(
39
+ name: &str,
40
+ version_req: &str,
41
+ ) -> Result<ResolvedDependency, String> {
39
42
  let probe_dir = tempfile::tempdir().map_err(|e| format!("tempdir: {}", e))?;
40
43
  let probe_toml = format!(
41
44
  r#"[package]
package/justfile CHANGED
@@ -125,15 +125,15 @@ test *ARGS:
125
125
 
126
126
  # Run only tish package tests (same as CI: integration tests only)
127
127
  test-tish *ARGS:
128
- cargo nextest run -p tishlang--features full -- {{ARGS}}
128
+ cargo nextest run -p tishlang --features full -- {{ARGS}}
129
129
 
130
130
  # Skip slow backend tests (native/cranelift/wasi) for fast local iteration
131
131
  test-quick:
132
- cargo nextest run -p tishlang--features full -- --skip test_mvp_programs_native --skip test_mvp_programs_cranelift --skip test_mvp_programs_wasi
132
+ cargo nextest run -p tishlang --features full -- --skip test_mvp_programs_native --skip test_mvp_programs_cranelift --skip test_mvp_programs_wasi
133
133
 
134
134
  # Run tests with coverage (requires llvm-tools: rustup component add llvm-tools-preview)
135
135
  test-coverage:
136
- cargo llvm-cov nextest -p tishlang--features full --lcov --output-path lcov.info --html coverage-html
136
+ cargo llvm-cov nextest -p tishlang --features full --lcov --output-path lcov.info --html coverage-html
137
137
 
138
138
  # Plain cargo test (whole workspace)
139
139
  test-cargo:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tishlang/tish",
3
- "version": "1.9.2",
3
+ "version": "1.12.0",
4
4
  "description": "Tish - minimal TS/JS-compatible language. Run, REPL, build to native or other targets.",
5
5
  "license": "PIF",
6
6
  "repository": {
Binary file
Binary file
Binary file
Binary file
Binary file