@tishlang/tish 1.6.0 → 1.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/Cargo.toml +2 -0
- package/README.md +2 -0
- package/bin/tish +0 -0
- package/crates/js_to_tish/src/error.rs +2 -8
- package/crates/js_to_tish/src/transform/expr.rs +128 -137
- package/crates/js_to_tish/src/transform/stmt.rs +62 -32
- package/crates/tish/Cargo.toml +15 -5
- package/crates/tish/src/cargo_native_registry.rs +29 -0
- package/crates/tish/src/cli_help.rs +92 -39
- package/crates/tish/src/main.rs +172 -86
- package/crates/tish/src/repl_completion.rs +3 -3
- package/crates/tish/tests/cargo_example_compile.rs +4 -2
- package/crates/tish/tests/integration_test.rs +216 -54
- package/crates/tish/tests/run_optimize_stdout_parity.rs +3 -7
- package/crates/tish/tests/shortcircuit.rs +20 -5
- package/crates/tish_ast/src/ast.rs +92 -23
- package/crates/tish_build_utils/Cargo.toml +4 -0
- package/crates/tish_build_utils/src/lib.rs +136 -8
- package/crates/tish_builtins/Cargo.toml +5 -1
- package/crates/tish_builtins/src/array.rs +65 -33
- package/crates/tish_builtins/src/construct.rs +34 -39
- package/crates/tish_builtins/src/globals.rs +42 -26
- package/crates/tish_builtins/src/helpers.rs +2 -1
- package/crates/tish_builtins/src/lib.rs +5 -5
- package/crates/tish_builtins/src/math.rs +5 -3
- package/crates/tish_builtins/src/object.rs +3 -2
- package/crates/tish_builtins/src/string.rs +144 -22
- package/crates/tish_bytecode/src/chunk.rs +0 -1
- package/crates/tish_bytecode/src/compiler.rs +173 -71
- package/crates/tish_bytecode/src/opcode.rs +24 -6
- package/crates/tish_bytecode/src/peephole.rs +2 -2
- package/crates/tish_compile/Cargo.toml +1 -0
- package/crates/tish_compile/src/codegen.rs +1621 -453
- package/crates/tish_compile/src/infer.rs +75 -19
- package/crates/tish_compile/src/lib.rs +19 -8
- package/crates/tish_compile/src/resolve.rs +278 -137
- package/crates/tish_compile/src/types.rs +184 -24
- package/crates/tish_compile_js/Cargo.toml +1 -0
- package/crates/tish_compile_js/src/codegen.rs +181 -37
- package/crates/tish_compile_js/src/lib.rs +3 -1
- package/crates/tish_compile_js/src/tests_jsx.rs +30 -6
- package/crates/tish_compiler_wasm/src/lib.rs +16 -13
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +69 -59
- package/crates/tish_core/Cargo.toml +8 -0
- package/crates/tish_core/src/json.rs +107 -56
- package/crates/tish_core/src/lib.rs +4 -2
- package/crates/tish_core/src/macros.rs +5 -5
- package/crates/tish_core/src/uri.rs +9 -6
- package/crates/tish_core/src/value.rs +145 -43
- package/crates/tish_core/src/vmref.rs +178 -0
- package/crates/tish_cranelift/src/link.rs +6 -9
- package/crates/tish_cranelift/src/lower.rs +14 -8
- package/crates/tish_eval/Cargo.toml +17 -2
- package/crates/tish_eval/src/eval.rs +474 -165
- package/crates/tish_eval/src/http.rs +61 -0
- package/crates/tish_eval/src/lib.rs +12 -8
- package/crates/tish_eval/src/natives.rs +136 -38
- package/crates/tish_eval/src/promise.rs +14 -8
- package/crates/tish_eval/src/timers.rs +28 -19
- package/crates/tish_eval/src/value.rs +17 -6
- package/crates/tish_eval/src/value_convert.rs +13 -5
- package/crates/tish_fmt/src/lib.rs +149 -43
- package/crates/tish_lexer/src/lib.rs +232 -63
- package/crates/tish_lexer/src/token.rs +10 -6
- package/crates/tish_llvm/src/lib.rs +17 -8
- 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 +504 -106
- package/crates/tish_native/src/build.rs +4 -8
- package/crates/tish_native/src/lib.rs +54 -21
- package/crates/tish_opt/src/lib.rs +84 -52
- package/crates/tish_parser/src/lib.rs +45 -13
- package/crates/tish_parser/src/parser.rs +505 -130
- 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 +1136 -145
- package/crates/tish_runtime/src/http_fetch.rs +38 -27
- 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 +375 -189
- package/crates/tish_runtime/src/promise.rs +199 -40
- 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 +65 -42
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +5 -4
- package/crates/tish_ui/src/jsx.rs +317 -27
- 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 +725 -281
- package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +11 -4
- package/crates/tish_wasm/src/lib.rs +55 -42
- 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 +26 -0
- package/crates/tishlang_cargo_bindgen/src/classify.rs +265 -0
- package/crates/tishlang_cargo_bindgen/src/discover.rs +120 -0
- package/crates/tishlang_cargo_bindgen/src/infer.rs +372 -0
- package/crates/tishlang_cargo_bindgen/src/lib.rs +350 -0
- package/crates/tishlang_cargo_bindgen/src/main.rs +164 -0
- package/crates/tishlang_cargo_bindgen/src/metadata.rs +114 -0
- 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
|
@@ -22,7 +22,9 @@ pub struct InferCtx {
|
|
|
22
22
|
|
|
23
23
|
impl InferCtx {
|
|
24
24
|
pub fn new() -> Self {
|
|
25
|
-
Self {
|
|
25
|
+
Self {
|
|
26
|
+
scopes: vec![HashMap::new()],
|
|
27
|
+
}
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
fn push_scope(&mut self) {
|
|
@@ -75,17 +77,16 @@ pub fn infer_expr_type(expr: &Expr, ctx: &InferCtx) -> Option<TypeAnnotation> {
|
|
|
75
77
|
Literal::Null => None,
|
|
76
78
|
},
|
|
77
79
|
Expr::Ident { name, .. } => ctx.lookup(name.as_ref()).cloned(),
|
|
78
|
-
Expr::Binary {
|
|
80
|
+
Expr::Binary {
|
|
81
|
+
left, op, right, ..
|
|
82
|
+
} => {
|
|
79
83
|
let lt = infer_expr_type(left, ctx)?;
|
|
80
84
|
let rt = infer_expr_type(right, ctx)?;
|
|
81
85
|
if is_number(<) && is_number(&rt) {
|
|
82
86
|
match op {
|
|
83
|
-
BinOp::Add
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
| BinOp::Div
|
|
87
|
-
| BinOp::Mod
|
|
88
|
-
| BinOp::Pow => Some(number_ann()),
|
|
87
|
+
BinOp::Add | BinOp::Sub | BinOp::Mul | BinOp::Div | BinOp::Mod | BinOp::Pow => {
|
|
88
|
+
Some(number_ann())
|
|
89
|
+
}
|
|
89
90
|
BinOp::Lt
|
|
90
91
|
| BinOp::Le
|
|
91
92
|
| BinOp::Gt
|
|
@@ -103,7 +104,11 @@ pub fn infer_expr_type(expr: &Expr, ctx: &InferCtx) -> Option<TypeAnnotation> {
|
|
|
103
104
|
match op {
|
|
104
105
|
UnaryOp::Neg | UnaryOp::Pos => {
|
|
105
106
|
let t = infer_expr_type(operand, ctx)?;
|
|
106
|
-
if is_number(&t) {
|
|
107
|
+
if is_number(&t) {
|
|
108
|
+
Some(number_ann())
|
|
109
|
+
} else {
|
|
110
|
+
None
|
|
111
|
+
}
|
|
107
112
|
}
|
|
108
113
|
UnaryOp::Not => Some(bool_ann()),
|
|
109
114
|
_ => None,
|
|
@@ -117,7 +122,9 @@ pub fn infer_expr_type(expr: &Expr, ctx: &InferCtx) -> Option<TypeAnnotation> {
|
|
|
117
122
|
/// type annotations filled in on `VarDecl` nodes.
|
|
118
123
|
pub fn infer_program(program: &Program) -> Program {
|
|
119
124
|
let mut ctx = InferCtx::new();
|
|
120
|
-
Program {
|
|
125
|
+
Program {
|
|
126
|
+
statements: infer_statements(&program.statements, &mut ctx),
|
|
127
|
+
}
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
fn infer_statements(stmts: &[Statement], ctx: &mut InferCtx) -> Vec<Statement> {
|
|
@@ -126,7 +133,14 @@ fn infer_statements(stmts: &[Statement], ctx: &mut InferCtx) -> Vec<Statement> {
|
|
|
126
133
|
|
|
127
134
|
fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
128
135
|
match stmt {
|
|
129
|
-
Statement::VarDecl {
|
|
136
|
+
Statement::VarDecl {
|
|
137
|
+
name,
|
|
138
|
+
name_span,
|
|
139
|
+
mutable,
|
|
140
|
+
type_ann,
|
|
141
|
+
init,
|
|
142
|
+
span,
|
|
143
|
+
} => {
|
|
130
144
|
// Already annotated — propagate into ctx but don't change the node.
|
|
131
145
|
if let Some(ann) = type_ann {
|
|
132
146
|
ctx.define(name.as_ref(), ann.clone());
|
|
@@ -139,6 +153,7 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
139
153
|
}
|
|
140
154
|
Statement::VarDecl {
|
|
141
155
|
name: name.clone(),
|
|
156
|
+
name_span: *name_span,
|
|
142
157
|
mutable: *mutable,
|
|
143
158
|
type_ann: inferred,
|
|
144
159
|
init: init.clone(),
|
|
@@ -149,9 +164,18 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
149
164
|
ctx.push_scope();
|
|
150
165
|
let stmts = infer_statements(statements, ctx);
|
|
151
166
|
ctx.pop_scope();
|
|
152
|
-
Statement::Block {
|
|
167
|
+
Statement::Block {
|
|
168
|
+
statements: stmts,
|
|
169
|
+
span: *span,
|
|
170
|
+
}
|
|
153
171
|
}
|
|
154
|
-
Statement::For {
|
|
172
|
+
Statement::For {
|
|
173
|
+
init,
|
|
174
|
+
cond,
|
|
175
|
+
update,
|
|
176
|
+
body,
|
|
177
|
+
span,
|
|
178
|
+
} => {
|
|
155
179
|
// Scope for loop variable
|
|
156
180
|
ctx.push_scope();
|
|
157
181
|
let new_init = init.as_ref().map(|i| Box::new(infer_statement(i, ctx)));
|
|
@@ -165,12 +189,19 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
165
189
|
span: *span,
|
|
166
190
|
}
|
|
167
191
|
}
|
|
168
|
-
Statement::ForOf {
|
|
192
|
+
Statement::ForOf {
|
|
193
|
+
name,
|
|
194
|
+
name_span,
|
|
195
|
+
iterable,
|
|
196
|
+
body,
|
|
197
|
+
span,
|
|
198
|
+
} => {
|
|
169
199
|
ctx.push_scope();
|
|
170
200
|
let new_body = Box::new(infer_statement(body, ctx));
|
|
171
201
|
ctx.pop_scope();
|
|
172
202
|
Statement::ForOf {
|
|
173
203
|
name: name.clone(),
|
|
204
|
+
name_span: *name_span,
|
|
174
205
|
iterable: iterable.clone(),
|
|
175
206
|
body: new_body,
|
|
176
207
|
span: *span,
|
|
@@ -180,17 +211,32 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
180
211
|
ctx.push_scope();
|
|
181
212
|
let new_body = Box::new(infer_statement(body, ctx));
|
|
182
213
|
ctx.pop_scope();
|
|
183
|
-
Statement::While {
|
|
214
|
+
Statement::While {
|
|
215
|
+
cond: cond.clone(),
|
|
216
|
+
body: new_body,
|
|
217
|
+
span: *span,
|
|
218
|
+
}
|
|
184
219
|
}
|
|
185
220
|
Statement::DoWhile { body, cond, span } => {
|
|
186
221
|
ctx.push_scope();
|
|
187
222
|
let new_body = Box::new(infer_statement(body, ctx));
|
|
188
223
|
ctx.pop_scope();
|
|
189
|
-
Statement::DoWhile {
|
|
224
|
+
Statement::DoWhile {
|
|
225
|
+
body: new_body,
|
|
226
|
+
cond: cond.clone(),
|
|
227
|
+
span: *span,
|
|
228
|
+
}
|
|
190
229
|
}
|
|
191
|
-
Statement::If {
|
|
230
|
+
Statement::If {
|
|
231
|
+
cond,
|
|
232
|
+
then_branch,
|
|
233
|
+
else_branch,
|
|
234
|
+
span,
|
|
235
|
+
} => {
|
|
192
236
|
let new_then = Box::new(infer_statement(then_branch, ctx));
|
|
193
|
-
let new_else = else_branch
|
|
237
|
+
let new_else = else_branch
|
|
238
|
+
.as_ref()
|
|
239
|
+
.map(|e| Box::new(infer_statement(e, ctx)));
|
|
194
240
|
Statement::If {
|
|
195
241
|
cond: cond.clone(),
|
|
196
242
|
then_branch: new_then,
|
|
@@ -198,7 +244,16 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
198
244
|
span: *span,
|
|
199
245
|
}
|
|
200
246
|
}
|
|
201
|
-
Statement::FunDecl {
|
|
247
|
+
Statement::FunDecl {
|
|
248
|
+
async_,
|
|
249
|
+
name,
|
|
250
|
+
name_span,
|
|
251
|
+
params,
|
|
252
|
+
rest_param,
|
|
253
|
+
return_type,
|
|
254
|
+
body,
|
|
255
|
+
span,
|
|
256
|
+
} => {
|
|
202
257
|
ctx.push_scope();
|
|
203
258
|
for p in params {
|
|
204
259
|
if let FunParam::Simple(tp) = p {
|
|
@@ -217,6 +272,7 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
217
272
|
Statement::FunDecl {
|
|
218
273
|
async_: *async_,
|
|
219
274
|
name: name.clone(),
|
|
275
|
+
name_span: *name_span,
|
|
220
276
|
params: params.clone(),
|
|
221
277
|
rest_param: rest_param.clone(),
|
|
222
278
|
return_type: return_type.clone(),
|
|
@@ -7,18 +7,19 @@ mod infer;
|
|
|
7
7
|
mod resolve;
|
|
8
8
|
mod types;
|
|
9
9
|
|
|
10
|
+
pub use codegen::CompileError;
|
|
10
11
|
pub use codegen::{
|
|
11
12
|
compile, compile_project, compile_project_full, compile_with_features,
|
|
12
13
|
compile_with_native_modules, compile_with_project_root,
|
|
13
14
|
};
|
|
14
|
-
pub use codegen::CompileError;
|
|
15
15
|
pub use resolve::{
|
|
16
16
|
cargo_export_fn_name, compute_native_build_artifacts, detect_cycles, export_name_to_rust_ident,
|
|
17
17
|
extract_native_import_features, format_rust_dependencies_toml, generate_native_wrapper_rs,
|
|
18
18
|
has_external_native_imports, has_native_imports, infer_native_module_exports,
|
|
19
|
-
is_builtin_native_spec, is_cargo_native_spec,
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
is_builtin_native_spec, is_cargo_native_spec, is_native_import, merge_modules,
|
|
20
|
+
normalize_builtin_spec, read_project_tish_config,
|
|
21
|
+
resolve_bare_spec, resolve_native_modules, resolve_project, resolve_project_from_stdin,
|
|
22
|
+
MergedProgram, NativeBuildArtifacts, NativeModuleInit, ResolvedNativeModule,
|
|
22
23
|
};
|
|
23
24
|
pub use types::{RustType, TypeContext};
|
|
24
25
|
|
|
@@ -44,7 +45,10 @@ fn sum(...args: number[]): number {
|
|
|
44
45
|
// total should be declared as f64
|
|
45
46
|
assert!(rust.contains("let mut total: f64"), "expected total: f64");
|
|
46
47
|
// The return value of run() should convert total back to Value
|
|
47
|
-
assert!(
|
|
48
|
+
assert!(
|
|
49
|
+
rust.contains("Value::Number(total)"),
|
|
50
|
+
"expected Value::Number(total) wrapping"
|
|
51
|
+
);
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
#[test]
|
|
@@ -60,7 +64,10 @@ for (let i = 0; i < 5; i = i + 1) {
|
|
|
60
64
|
let program = parse(src).unwrap();
|
|
61
65
|
let rust = compile(&program).unwrap();
|
|
62
66
|
// outerVar and x are f64 (inferred) — Copy assignment, no .clone() needed.
|
|
63
|
-
assert!(
|
|
67
|
+
assert!(
|
|
68
|
+
rust.contains("let mut outerVar: f64"),
|
|
69
|
+
"expected outerVar: f64"
|
|
70
|
+
);
|
|
64
71
|
assert!(rust.contains("let mut x: f64"), "expected x: f64");
|
|
65
72
|
}
|
|
66
73
|
|
|
@@ -105,13 +112,17 @@ fn factory() {
|
|
|
105
112
|
// This test verifies the full benchmark_granular project compiles and that outerVar
|
|
106
113
|
// is emitted as the inferred f64 type rather than requiring a Value clone.
|
|
107
114
|
let manifest = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
108
|
-
let bench = manifest
|
|
115
|
+
let bench = manifest
|
|
116
|
+
.join("../../tests/core/benchmark_granular.tish")
|
|
117
|
+
.canonicalize()
|
|
118
|
+
.unwrap();
|
|
109
119
|
// Use same default features as tish CLI (http, fs, process, regex)
|
|
110
120
|
let features = ["http", "fs", "process", "regex"]
|
|
111
121
|
.into_iter()
|
|
112
122
|
.map(String::from)
|
|
113
123
|
.collect::<Vec<_>>();
|
|
114
|
-
let (rust, _, _, _) =
|
|
124
|
+
let (rust, _, _, _) =
|
|
125
|
+
compile_project_full(&bench, bench.parent(), &features, true).unwrap();
|
|
115
126
|
// outerVar = 42 is inferred as f64; f64 is Copy so no .clone() is emitted.
|
|
116
127
|
assert!(
|
|
117
128
|
rust.contains("let mut outerVar: f64"),
|