@tishlang/tish 2.2.5 → 2.8.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/bin/tish +0 -0
- package/crates/js_to_tish/src/transform/expr.rs +5 -1
- package/crates/tish/Cargo.toml +1 -1
- package/crates/tish/src/cli_help.rs +12 -0
- package/crates/tish/src/main.rs +69 -11
- package/crates/tish_ast/src/ast.rs +12 -5
- package/crates/tish_build_utils/src/lib.rs +37 -0
- package/crates/tish_builtins/src/array.rs +82 -1
- package/crates/tish_builtins/src/globals.rs +50 -16
- package/crates/tish_builtins/src/math.rs +63 -9
- package/crates/tish_builtins/src/number.rs +20 -1
- package/crates/tish_builtins/src/string.rs +68 -4
- package/crates/tish_builtins/src/typedarrays.rs +23 -16
- package/crates/tish_bytecode/src/compiler.rs +94 -28
- package/crates/tish_bytecode/tests/break_continue_bytecode.rs +19 -0
- package/crates/tish_compile/src/check.rs +11 -10
- package/crates/tish_compile/src/codegen.rs +1386 -42
- package/crates/tish_compile/src/infer.rs +16 -16
- package/crates/tish_compile/src/lib.rs +38 -0
- package/crates/tish_compile/src/resolve.rs +3 -2
- package/crates/tish_compile/src/types.rs +26 -9
- package/crates/tish_compile_js/src/codegen.rs +55 -4
- package/crates/tish_compile_js/src/tests_jsx.rs +44 -0
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +1 -0
- package/crates/tish_core/Cargo.toml +2 -0
- package/crates/tish_core/src/json.rs +135 -34
- package/crates/tish_core/src/lib.rs +23 -1
- package/crates/tish_core/src/value.rs +64 -11
- package/crates/tish_eval/src/eval.rs +144 -197
- package/crates/tish_eval/src/natives.rs +45 -45
- package/crates/tish_eval/src/regex.rs +35 -27
- package/crates/tish_eval/src/value.rs +8 -0
- package/crates/tish_fmt/src/lib.rs +46 -2
- package/crates/tish_lint/src/bin/tish-lint.rs +17 -8
- package/crates/tish_lint/src/lib.rs +197 -21
- package/crates/tish_lsp/Cargo.toml +7 -1
- package/crates/tish_lsp/src/import_goto.rs +52 -7
- package/crates/tish_lsp/src/main.rs +913 -145
- package/crates/tish_opt/src/lib.rs +5 -3
- package/crates/tish_parser/src/lib.rs +23 -5
- package/crates/tish_parser/src/parser.rs +35 -35
- package/crates/tish_resolve/src/lib.rs +567 -17
- package/crates/tish_runtime/src/lib.rs +58 -18
- package/crates/tish_ui/src/jsx.rs +2 -2
- package/crates/tish_vm/src/jit.rs +212 -10
- package/crates/tish_vm/src/vm.rs +39 -18
- package/crates/tish_wasm/src/lib.rs +116 -22
- 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
|
@@ -88,6 +88,7 @@ pub fn compile_program_to_wasm(
|
|
|
88
88
|
program: &Program,
|
|
89
89
|
output_path: &Path,
|
|
90
90
|
optimize: bool,
|
|
91
|
+
gpu: bool,
|
|
91
92
|
) -> Result<(), WasmError> {
|
|
92
93
|
let program = if optimize {
|
|
93
94
|
tishlang_opt::optimize(program)
|
|
@@ -103,10 +104,87 @@ pub fn compile_program_to_wasm(
|
|
|
103
104
|
message: e.to_string(),
|
|
104
105
|
})?
|
|
105
106
|
};
|
|
106
|
-
emit_wasm_from_chunk(&chunk, output_path)
|
|
107
|
+
emit_wasm_from_chunk(&chunk, output_path, gpu)
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
/// The HTML loader emitted next to the wasm + JS glue. `gpu = false` imports `run` and calls
|
|
111
|
+
/// `run(chunk)` (plain VM). `gpu = true` (#277) imports `start`, bootstraps WebGPU into a `host`
|
|
112
|
+
/// env object, and calls `start(chunk, host)`. The GPU loader is a working default — edit
|
|
113
|
+
/// `buildHost()` to add app assets, pick a specific canvas, or change the surface configuration.
|
|
114
|
+
fn loader_html(stem: &str, chunk_b64: &str, gpu: bool) -> String {
|
|
115
|
+
let js_name = format!("{}.js", stem);
|
|
116
|
+
if gpu {
|
|
117
|
+
format!(
|
|
118
|
+
r#"<!DOCTYPE html>
|
|
119
|
+
<html>
|
|
120
|
+
<head><meta charset="utf-8"><title>{title}</title><style>html,body{{margin:0;height:100%}}#tish-canvas{{width:100vw;height:100vh;display:block}}</style></head>
|
|
121
|
+
<body>
|
|
122
|
+
<canvas id="tish-canvas"></canvas>
|
|
123
|
+
<script type="module">
|
|
124
|
+
const CHUNK_B64 = "{chunk}";
|
|
125
|
+
const chunk = Uint8Array.from(atob(CHUNK_B64), c => c.charCodeAt(0));
|
|
126
|
+
import init, {{ start }} from './{js}';
|
|
127
|
+
|
|
128
|
+
// The `host` global your tish program reads. Customize freely.
|
|
129
|
+
async function buildHost() {{
|
|
130
|
+
if (!navigator.gpu) throw new Error("WebGPU not available (use a WebGPU-capable browser / context).");
|
|
131
|
+
const adapter = await navigator.gpu.requestAdapter();
|
|
132
|
+
if (!adapter) throw new Error("No WebGPU adapter.");
|
|
133
|
+
const device = await adapter.requestDevice();
|
|
134
|
+
const canvas = document.getElementById("tish-canvas");
|
|
135
|
+
const dpr = self.devicePixelRatio || 1;
|
|
136
|
+
canvas.width = Math.floor(canvas.clientWidth * dpr);
|
|
137
|
+
canvas.height = Math.floor(canvas.clientHeight * dpr);
|
|
138
|
+
const context = canvas.getContext("webgpu");
|
|
139
|
+
const format = navigator.gpu.getPreferredCanvasFormat();
|
|
140
|
+
context.configure({{ device, format, alphaMode: "opaque" }});
|
|
141
|
+
return {{ gpu: navigator.gpu, adapter, device, queue: device.queue, context, format, canvas, assets: {{}} }};
|
|
142
|
+
}}
|
|
143
|
+
|
|
144
|
+
try {{
|
|
145
|
+
const host = await buildHost();
|
|
146
|
+
await init();
|
|
147
|
+
start(chunk, host);
|
|
148
|
+
}} catch (e) {{
|
|
149
|
+
document.body.innerHTML = "<pre style='color:#c00;padding:1rem;font:14px monospace'>" + (e && e.message || e) + "</pre>";
|
|
150
|
+
throw e;
|
|
151
|
+
}}
|
|
152
|
+
</script>
|
|
153
|
+
</body>
|
|
154
|
+
</html>
|
|
155
|
+
"#,
|
|
156
|
+
title = stem,
|
|
157
|
+
chunk = chunk_b64,
|
|
158
|
+
js = js_name
|
|
159
|
+
)
|
|
160
|
+
} else {
|
|
161
|
+
format!(
|
|
162
|
+
r#"<!DOCTYPE html>
|
|
163
|
+
<html>
|
|
164
|
+
<head><meta charset="utf-8"><title>{}</title></head>
|
|
165
|
+
<body>
|
|
166
|
+
<script type="module">
|
|
167
|
+
const CHUNK_B64 = "{}";
|
|
168
|
+
const chunk = Uint8Array.from(atob(CHUNK_B64), c => c.charCodeAt(0));
|
|
169
|
+
import init, {{ run }} from './{}';
|
|
170
|
+
await init();
|
|
171
|
+
run(chunk);
|
|
172
|
+
</script>
|
|
173
|
+
</body>
|
|
174
|
+
</html>
|
|
175
|
+
"#,
|
|
176
|
+
stem, chunk_b64, js_name
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/// Build the wasm runtime + emit the JS/HTML loader for a serialized `chunk`.
|
|
182
|
+
///
|
|
183
|
+
/// `gpu = false` → `--features browser`, plain `run(chunk)` VM entry (the default `--target wasm`).
|
|
184
|
+
/// `gpu = true` → `--features gpu`, the reflection WebGPU bridge ([`tishlang_wasm_runtime`]'s
|
|
185
|
+
/// `gpu.rs`) and a `start(chunk, host)` entry; the emitted HTML bootstraps WebGPU (adapter/device/
|
|
186
|
+
/// canvas/context) into the `host` global the tish program reads. (#277, `--target wasm-gpu`.)
|
|
187
|
+
fn emit_wasm_from_chunk(chunk: &Chunk, output_path: &Path, gpu: bool) -> Result<(), WasmError> {
|
|
110
188
|
let chunk_bytes = serialize(chunk);
|
|
111
189
|
let chunk_b64 = BASE64.encode(&chunk_bytes);
|
|
112
190
|
let stem = output_path
|
|
@@ -139,7 +217,7 @@ fn emit_wasm_from_chunk(chunk: &Chunk, output_path: &Path) -> Result<(), WasmErr
|
|
|
139
217
|
"wasm32-unknown-unknown",
|
|
140
218
|
"--release",
|
|
141
219
|
"--features",
|
|
142
|
-
"browser",
|
|
220
|
+
if gpu { "gpu" } else { "browser" },
|
|
143
221
|
])
|
|
144
222
|
.status()
|
|
145
223
|
.map_err(|e| WasmError {
|
|
@@ -182,24 +260,7 @@ fn emit_wasm_from_chunk(chunk: &Chunk, output_path: &Path) -> Result<(), WasmErr
|
|
|
182
260
|
message: "wasm-bindgen failed".to_string(),
|
|
183
261
|
});
|
|
184
262
|
}
|
|
185
|
-
let
|
|
186
|
-
let html = format!(
|
|
187
|
-
r#"<!DOCTYPE html>
|
|
188
|
-
<html>
|
|
189
|
-
<head><meta charset="utf-8"><title>{}</title></head>
|
|
190
|
-
<body>
|
|
191
|
-
<script type="module">
|
|
192
|
-
const CHUNK_B64 = "{}";
|
|
193
|
-
const chunk = Uint8Array.from(atob(CHUNK_B64), c => c.charCodeAt(0));
|
|
194
|
-
import init, {{ run }} from './{}';
|
|
195
|
-
await init();
|
|
196
|
-
run(chunk);
|
|
197
|
-
</script>
|
|
198
|
-
</body>
|
|
199
|
-
</html>
|
|
200
|
-
"#,
|
|
201
|
-
stem, chunk_b64, js_name
|
|
202
|
-
);
|
|
263
|
+
let html = loader_html(stem, &chunk_b64, gpu);
|
|
203
264
|
let html_path = out_dir_abs.join(format!("{}.html", stem));
|
|
204
265
|
std::fs::write(&html_path, html).map_err(|e| WasmError {
|
|
205
266
|
message: format!("Cannot write {}: {}", html_path.display(), e),
|
|
@@ -221,14 +282,17 @@ run(chunk);
|
|
|
221
282
|
/// - `{output}.html` — loader (open in browser)
|
|
222
283
|
///
|
|
223
284
|
/// Requires: `rustup target add wasm32-unknown-unknown`, `wasm-bindgen-cli`
|
|
285
|
+
/// `gpu = true` targets the WebGPU runtime (`--features gpu`, `start(chunk, host)` entry); see
|
|
286
|
+
/// [`emit_wasm_from_chunk`]. (#277, exposed as `--target wasm-gpu`.)
|
|
224
287
|
pub fn compile_to_wasm(
|
|
225
288
|
entry_path: &Path,
|
|
226
289
|
project_root: Option<&Path>,
|
|
227
290
|
output_path: &Path,
|
|
228
291
|
optimize: bool,
|
|
292
|
+
gpu: bool,
|
|
229
293
|
) -> Result<(), WasmError> {
|
|
230
294
|
let (chunk, _) = resolve_and_compile_to_chunk(entry_path, project_root, optimize)?;
|
|
231
|
-
emit_wasm_from_chunk(&chunk, output_path)
|
|
295
|
+
emit_wasm_from_chunk(&chunk, output_path, gpu)
|
|
232
296
|
}
|
|
233
297
|
|
|
234
298
|
/// Compile a Tish project to a raw serialized bytecode chunk.
|
|
@@ -426,3 +490,33 @@ fn main() {
|
|
|
426
490
|
);
|
|
427
491
|
Ok(())
|
|
428
492
|
}
|
|
493
|
+
|
|
494
|
+
#[cfg(test)]
|
|
495
|
+
mod tests {
|
|
496
|
+
use super::loader_html;
|
|
497
|
+
|
|
498
|
+
#[test]
|
|
499
|
+
fn gpu_loader_uses_start_and_bootstraps_webgpu() {
|
|
500
|
+
// #277: the wasm-gpu loader must call the `start(chunk, host)` entry (not `run`) and build
|
|
501
|
+
// the WebGPU `host` env (adapter/device/context) the tish program reads.
|
|
502
|
+
let html = loader_html("viz", "QkFTRTY0", true);
|
|
503
|
+
assert!(html.contains("import init, { start }"), "imports start");
|
|
504
|
+
assert!(html.contains("start(chunk, host)"), "calls start with host");
|
|
505
|
+
assert!(html.contains("navigator.gpu.requestAdapter()"), "bootstraps adapter");
|
|
506
|
+
assert!(html.contains("getContext(\"webgpu\")"), "configures the canvas context");
|
|
507
|
+
assert!(html.contains("device, queue: device.queue, context, format, canvas"), "host shape");
|
|
508
|
+
assert!(html.contains("from './viz.js'"), "imports the right glue");
|
|
509
|
+
assert!(!html.contains("run(chunk)"), "must NOT use the plain run() entry");
|
|
510
|
+
assert!(html.contains("QkFTRTY0"), "embeds the chunk");
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
#[test]
|
|
514
|
+
fn plain_loader_uses_run() {
|
|
515
|
+
let html = loader_html("app", "QkFTRTY0", false);
|
|
516
|
+
assert!(html.contains("import init, { run }"), "imports run");
|
|
517
|
+
assert!(html.contains("run(chunk)"), "calls run");
|
|
518
|
+
assert!(!html.contains("start("), "no gpu start entry");
|
|
519
|
+
assert!(!html.contains("requestAdapter"), "no webgpu bootstrap");
|
|
520
|
+
assert!(html.contains("from './app.js'"), "imports the right glue");
|
|
521
|
+
}
|
|
522
|
+
}
|
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
|