@tishlang/tish 1.7.0 → 1.9.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/Cargo.toml +2 -0
- package/README.md +2 -0
- package/bin/tish +0 -0
- package/crates/js_to_tish/src/transform/expr.rs +28 -8
- package/crates/js_to_tish/src/transform/stmt.rs +49 -22
- package/crates/tish/Cargo.toml +14 -5
- package/crates/tish/src/cargo_native_registry.rs +29 -0
- package/crates/tish/src/cli_help.rs +16 -10
- package/crates/tish/src/main.rs +87 -32
- package/crates/tish/src/repl_completion.rs +3 -3
- package/crates/tish/tests/cargo_example_compile.rs +1 -1
- package/crates/tish/tests/integration_test.rs +19 -7
- package/crates/tish/tests/shortcircuit.rs +1 -1
- package/crates/tish_ast/src/ast.rs +80 -9
- package/crates/tish_build_utils/Cargo.toml +4 -0
- package/crates/tish_build_utils/src/lib.rs +105 -2
- package/crates/tish_builtins/Cargo.toml +5 -1
- package/crates/tish_builtins/src/array.rs +13 -12
- package/crates/tish_builtins/src/construct.rs +34 -33
- package/crates/tish_builtins/src/globals.rs +12 -11
- package/crates/tish_builtins/src/helpers.rs +2 -1
- package/crates/tish_builtins/src/object.rs +3 -2
- package/crates/tish_builtins/src/string.rs +73 -3
- package/crates/tish_bytecode/src/compiler.rs +12 -14
- package/crates/tish_bytecode/src/opcode.rs +12 -3
- package/crates/tish_compile/Cargo.toml +1 -0
- package/crates/tish_compile/src/codegen.rs +745 -199
- package/crates/tish_compile/src/infer.rs +6 -0
- package/crates/tish_compile/src/lib.rs +4 -3
- package/crates/tish_compile/src/resolve.rs +180 -82
- package/crates/tish_compile/src/types.rs +175 -11
- package/crates/tish_compile_js/Cargo.toml +1 -0
- package/crates/tish_compile_js/src/codegen.rs +152 -29
- package/crates/tish_compile_js/src/lib.rs +3 -1
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +31 -12
- package/crates/tish_core/Cargo.toml +8 -0
- package/crates/tish_core/src/json.rs +102 -53
- package/crates/tish_core/src/lib.rs +3 -1
- package/crates/tish_core/src/macros.rs +5 -5
- package/crates/tish_core/src/value.rs +53 -15
- package/crates/tish_core/src/vmref.rs +178 -0
- package/crates/tish_eval/Cargo.toml +17 -2
- package/crates/tish_eval/src/eval.rs +90 -28
- package/crates/tish_eval/src/http.rs +61 -0
- package/crates/tish_eval/src/lib.rs +3 -3
- package/crates/tish_eval/src/natives.rs +41 -0
- package/crates/tish_eval/src/value.rs +7 -3
- package/crates/tish_eval/src/value_convert.rs +13 -5
- package/crates/tish_fmt/src/lib.rs +120 -30
- package/crates/tish_lexer/src/lib.rs +20 -5
- package/crates/tish_lexer/src/token.rs +4 -0
- package/crates/tish_llvm/src/lib.rs +3 -1
- package/crates/tish_lsp/Cargo.toml +4 -1
- package/crates/tish_lsp/README.md +1 -1
- package/crates/tish_lsp/src/builtin_goto.rs +261 -0
- package/crates/tish_lsp/src/import_goto.rs +549 -0
- package/crates/tish_lsp/src/main.rs +502 -102
- package/crates/tish_native/src/build.rs +3 -2
- package/crates/tish_native/src/lib.rs +6 -2
- package/crates/tish_opt/src/lib.rs +17 -2
- package/crates/tish_parser/src/lib.rs +10 -3
- package/crates/tish_parser/src/parser.rs +346 -56
- package/crates/tish_pg/Cargo.toml +34 -0
- package/crates/tish_pg/README.md +38 -0
- package/crates/tish_pg/src/error.rs +52 -0
- package/crates/tish_pg/src/lib.rs +967 -0
- package/crates/tish_resolve/Cargo.toml +13 -0
- package/crates/tish_resolve/src/lib.rs +3436 -0
- package/crates/tish_resolve/src/pos.rs +133 -0
- package/crates/tish_runtime/Cargo.toml +68 -3
- package/crates/tish_runtime/src/http.rs +1123 -141
- package/crates/tish_runtime/src/http_fetch.rs +15 -14
- package/crates/tish_runtime/src/http_hyper.rs +418 -0
- package/crates/tish_runtime/src/http_prefork.rs +189 -0
- package/crates/tish_runtime/src/lib.rs +159 -29
- package/crates/tish_runtime/src/promise.rs +199 -36
- package/crates/tish_runtime/src/promise_io.rs +2 -1
- package/crates/tish_runtime/src/timers.rs +37 -1
- package/crates/tish_runtime/src/ws.rs +26 -28
- package/crates/tish_ui/src/jsx.rs +279 -8
- package/crates/tish_ui/src/lib.rs +5 -2
- package/crates/tish_ui/src/runtime/hooks.rs +406 -45
- package/crates/tish_ui/src/runtime/mod.rs +36 -9
- package/crates/tish_vm/Cargo.toml +15 -5
- package/crates/tish_vm/src/vm.rs +506 -259
- package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +3 -1
- package/crates/tish_wasm/src/lib.rs +17 -14
- package/crates/tish_wasm_runtime/Cargo.toml +2 -1
- package/crates/tish_wasm_runtime/src/lib.rs +1 -1
- package/crates/tishlang_cargo_bindgen/Cargo.toml +1 -0
- package/crates/tishlang_cargo_bindgen/src/discover.rs +68 -0
- package/crates/tishlang_cargo_bindgen/src/lib.rs +5 -4
- package/justfile +8 -0
- package/package.json +1 -1
- package/platform/darwin-arm64/tish +0 -0
- package/platform/darwin-x64/tish +0 -0
- package/platform/linux-arm64/tish +0 -0
- package/platform/linux-x64/tish +0 -0
- package/platform/win32-x64/tish.exe +0 -0
|
@@ -120,7 +120,9 @@ fn merged_module_program_bytecode_matches_parse_for_string_or_fixture() {
|
|
|
120
120
|
let src = std::fs::read_to_string(&fixture).expect("read fixture");
|
|
121
121
|
let modules = tishlang_compile::resolve_project(&fixture, Some(fixture.parent().unwrap()))
|
|
122
122
|
.expect("resolve");
|
|
123
|
-
let merged = tishlang_compile::merge_modules(modules)
|
|
123
|
+
let merged = tishlang_compile::merge_modules(modules)
|
|
124
|
+
.expect("merge")
|
|
125
|
+
.program;
|
|
124
126
|
let flat = tishlang_parser::parse(&src).expect("parse");
|
|
125
127
|
let m_opt = tishlang_opt::optimize(&merged);
|
|
126
128
|
let f_opt = tishlang_opt::optimize(&flat);
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
//! Compiles Tish to bytecode, then produces a .wasm VM binary + loader.
|
|
4
4
|
//! The VM runs in the browser; your program runs as serialized bytecode.
|
|
5
5
|
|
|
6
|
+
use std::collections::BTreeSet;
|
|
6
7
|
use std::path::Path;
|
|
7
8
|
use std::process::Command;
|
|
8
9
|
|
|
@@ -43,7 +44,9 @@ fn resolve_and_compile_to_chunk(
|
|
|
43
44
|
message: e.to_string(),
|
|
44
45
|
})?;
|
|
45
46
|
let program = {
|
|
46
|
-
let prog = merge_modules(modules)
|
|
47
|
+
let prog = merge_modules(modules)
|
|
48
|
+
.map(|m| m.program)
|
|
49
|
+
.map_err(|e| WasmError {
|
|
47
50
|
message: e.to_string(),
|
|
48
51
|
})?;
|
|
49
52
|
if optimize {
|
|
@@ -227,7 +230,7 @@ pub fn compile_to_wasi(
|
|
|
227
230
|
let (chunk, program) = resolve_and_compile_to_chunk(entry_path, project_root, optimize)?;
|
|
228
231
|
if has_external_native_imports(&program) {
|
|
229
232
|
return Err(WasmError {
|
|
230
|
-
message: "WASI backend does not support external native imports (tish:egui, @scope/pkg). Built-in tish:fs, tish:http, tish:process are supported.".to_string(),
|
|
233
|
+
message: "WASI backend does not support external native imports (tish:egui, @scope/pkg). Built-in tish:fs, tish:http, tish:process, tish:timers are supported.".to_string(),
|
|
231
234
|
});
|
|
232
235
|
}
|
|
233
236
|
let wasi_features = extract_native_import_features(&program);
|
|
@@ -274,18 +277,18 @@ pub fn compile_to_wasi(
|
|
|
274
277
|
.to_string_lossy()
|
|
275
278
|
.replace('\\', "/");
|
|
276
279
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
280
|
+
// Bundled perf (`tests/main.tish`) and many scripts use global setTimeout without a top-level
|
|
281
|
+
// `import` (so `extract_native_import_features` is empty). Always link timers for WASI VM.
|
|
282
|
+
let mut wasi_feature_set: BTreeSet<String> = wasi_features.into_iter().collect();
|
|
283
|
+
wasi_feature_set.insert("timers".to_string());
|
|
284
|
+
let features_str = format!(
|
|
285
|
+
", features = [{}]",
|
|
286
|
+
wasi_feature_set
|
|
287
|
+
.iter()
|
|
288
|
+
.map(|f| format!("{:?}", f))
|
|
289
|
+
.collect::<Vec<_>>()
|
|
290
|
+
.join(", ")
|
|
291
|
+
);
|
|
289
292
|
let cargo_toml = format!(
|
|
290
293
|
r#"[package]
|
|
291
294
|
name = "tish_wasi_{stem}"
|
|
@@ -12,10 +12,11 @@ crate-type = ["cdylib", "rlib"]
|
|
|
12
12
|
[features]
|
|
13
13
|
# For wasm32-unknown-unknown (browser): wasm-bindgen, console output
|
|
14
14
|
browser = ["dep:wasm-bindgen", "tishlang_vm/wasm"]
|
|
15
|
-
# Built-in modules for WASI (wasm32-wasip1): file I/O, process, http
|
|
15
|
+
# Built-in modules for WASI (wasm32-wasip1): file I/O, process, http, timers
|
|
16
16
|
fs = ["tishlang_vm/fs"]
|
|
17
17
|
process = ["tishlang_vm/process"]
|
|
18
18
|
http = ["tishlang_vm/http"]
|
|
19
|
+
timers = ["tishlang_vm/timers"]
|
|
19
20
|
|
|
20
21
|
[dependencies]
|
|
21
22
|
tishlang_bytecode = { path = "../tish_bytecode", version = ">=0.1" }
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//!
|
|
3
3
|
//! Two targets:
|
|
4
4
|
//! - **Browser** (wasm32-unknown-unknown): use `--features browser`, wasm-bindgen, console output
|
|
5
|
-
//! - **WASI/Wasmtime** (wasm32-
|
|
5
|
+
//! - **WASI/Wasmtime** (wasm32-wasip1): optional `timers` / `http` / … via Cargo features; `compile_to_wasi` enables `timers` by default.
|
|
6
6
|
|
|
7
7
|
use tishlang_bytecode::deserialize;
|
|
8
8
|
use tishlang_vm::Vm;
|
|
@@ -18,6 +18,7 @@ path = "src/lib.rs"
|
|
|
18
18
|
cargo_metadata = "0.19"
|
|
19
19
|
clap = { version = "4.6", features = ["derive", "color"] }
|
|
20
20
|
pathdiff = "0.2"
|
|
21
|
+
proc-macro2 = { version = "1.0", features = ["span-locations"] }
|
|
21
22
|
serde_json = "1"
|
|
22
23
|
syn = { version = "2.0", features = ["full", "extra-traits"] }
|
|
23
24
|
tempfile = "3"
|
|
@@ -50,3 +50,71 @@ pub fn discover_public_functions(crate_root: &Path) -> Result<HashMap<String, It
|
|
|
50
50
|
|
|
51
51
|
Ok(map.into_iter().map(|(k, (_, v))| (k, v)).collect())
|
|
52
52
|
}
|
|
53
|
+
|
|
54
|
+
/// On-disk location of a top-level `pub fn {fn_name}` under `crate_root/src` (LSP line/column, 0-based).
|
|
55
|
+
///
|
|
56
|
+
/// Requires `proc-macro2` built with `span-locations` (this crate enables it) so spans from
|
|
57
|
+
/// `syn::parse_file` carry line/column.
|
|
58
|
+
pub fn rust_public_fn_location(
|
|
59
|
+
crate_root: &Path,
|
|
60
|
+
fn_name: &str,
|
|
61
|
+
) -> Result<(PathBuf, u32, u32), String> {
|
|
62
|
+
let src = crate_root.join("src");
|
|
63
|
+
if !src.is_dir() {
|
|
64
|
+
return Err(format!("no src/ under {}", crate_root.display()));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
for entry in WalkDir::new(&src)
|
|
68
|
+
.into_iter()
|
|
69
|
+
.filter_map(|e| e.ok())
|
|
70
|
+
.filter(|e| e.path().extension().map(|x| x == "rs").unwrap_or(false))
|
|
71
|
+
{
|
|
72
|
+
let path = entry.path();
|
|
73
|
+
let text = fs::read_to_string(path).map_err(|e| format!("read {}: {}", path.display(), e))?;
|
|
74
|
+
let file = syn::parse_file(&text).map_err(|e| format!("parse {}: {}", path.display(), e))?;
|
|
75
|
+
|
|
76
|
+
for item in file.items {
|
|
77
|
+
if let Item::Fn(f) = item {
|
|
78
|
+
if !is_pub(&f.vis) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if f.sig.ident != fn_name {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
let lc = f.sig.ident.span().start();
|
|
85
|
+
let line = u32::try_from(lc.line)
|
|
86
|
+
.map_err(|_| "span line out of range".to_string())?
|
|
87
|
+
.saturating_sub(1);
|
|
88
|
+
let col = u32::try_from(lc.column).map_err(|_| "span column out of range".to_string())?;
|
|
89
|
+
return Ok((path.to_path_buf(), line, col));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
Err(format!(
|
|
95
|
+
"no public fn `{}` found under {}/src",
|
|
96
|
+
fn_name,
|
|
97
|
+
crate_root.display()
|
|
98
|
+
))
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
#[cfg(test)]
|
|
102
|
+
mod tests {
|
|
103
|
+
use super::*;
|
|
104
|
+
use tempfile::tempdir;
|
|
105
|
+
|
|
106
|
+
#[test]
|
|
107
|
+
fn rust_public_fn_location_finds_fn() {
|
|
108
|
+
let tmp = tempdir().unwrap();
|
|
109
|
+
let src = tmp.path().join("src");
|
|
110
|
+
fs::create_dir_all(&src).unwrap();
|
|
111
|
+
fs::write(
|
|
112
|
+
src.join("lib.rs"),
|
|
113
|
+
"// comment\npub fn hello_tish_export() -> i32 { 0 }\n",
|
|
114
|
+
)
|
|
115
|
+
.unwrap();
|
|
116
|
+
let (path, line, _col) = rust_public_fn_location(tmp.path(), "hello_tish_export").unwrap();
|
|
117
|
+
assert!(path.ends_with("lib.rs"));
|
|
118
|
+
assert_eq!(line, 1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -21,6 +21,7 @@ pub mod infer;
|
|
|
21
21
|
mod metadata;
|
|
22
22
|
|
|
23
23
|
pub use classify::SignatureClass;
|
|
24
|
+
pub use discover::rust_public_fn_location;
|
|
24
25
|
pub use metadata::{resolve_dependency_from_manifest, resolve_registry_dependency, ResolvedDependency};
|
|
25
26
|
|
|
26
27
|
use std::fs;
|
|
@@ -181,7 +182,7 @@ fn render_generated_lib(
|
|
|
181
182
|
use std::cell::RefCell;\n\
|
|
182
183
|
use std::rc::Rc;\n\
|
|
183
184
|
use std::sync::Arc;\n\
|
|
184
|
-
use tishlang_runtime::{ObjectMap, Value};\n\n",
|
|
185
|
+
use tishlang_runtime::{ObjectMap, Value, VmRef};\n\n",
|
|
185
186
|
);
|
|
186
187
|
|
|
187
188
|
out.push_str(&format!(
|
|
@@ -244,15 +245,15 @@ fn json_to_tish(v: serde_json::Value) -> Value {
|
|
|
244
245
|
serde_json::Value::Bool(b) => Value::Bool(b),
|
|
245
246
|
serde_json::Value::Number(n) => Value::Number(n.as_f64().unwrap_or(0.0)),
|
|
246
247
|
serde_json::Value::String(s) => Value::String(s.into()),
|
|
247
|
-
serde_json::Value::Array(a) => Value::Array(
|
|
248
|
+
serde_json::Value::Array(a) => Value::Array(VmRef::new(
|
|
248
249
|
a.into_iter().map(json_to_tish).collect(),
|
|
249
|
-
))
|
|
250
|
+
)),
|
|
250
251
|
serde_json::Value::Object(m) => {
|
|
251
252
|
let mut om = ObjectMap::default();
|
|
252
253
|
for (k, v) in m {
|
|
253
254
|
om.insert(Arc::from(k), json_to_tish(v));
|
|
254
255
|
}
|
|
255
|
-
Value::Object(
|
|
256
|
+
Value::Object(VmRef::new(om))
|
|
256
257
|
}
|
|
257
258
|
}
|
|
258
259
|
}
|
package/justfile
CHANGED
|
@@ -250,6 +250,14 @@ optional-chaining-profile:
|
|
|
250
250
|
perf *ARGS:
|
|
251
251
|
./scripts/run_performance_manual.sh {{ARGS}}
|
|
252
252
|
|
|
253
|
+
# Bundled perf suite: per-test table + whole-program timings (tests/main.tish); add --verbose for full stdout
|
|
254
|
+
perf-suite *ARGS:
|
|
255
|
+
./scripts/run_performance_suite.sh {{ARGS}}
|
|
256
|
+
|
|
257
|
+
# Regenerate tests/main.tish + tests/main.js after changing paired pure perf tests
|
|
258
|
+
perf-suite-gen:
|
|
259
|
+
./scripts/generate_perf_ci_main.sh
|
|
260
|
+
|
|
253
261
|
# Show binary sizes for different builds
|
|
254
262
|
sizes:
|
|
255
263
|
@echo "Building secure binary..."
|
package/package.json
CHANGED
|
Binary file
|
package/platform/darwin-x64/tish
CHANGED
|
Binary file
|
|
Binary file
|
package/platform/linux-x64/tish
CHANGED
|
Binary file
|
|
Binary file
|