@tishlang/tish 1.5.0 → 1.7.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 +1 -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 +101 -130
- package/crates/js_to_tish/src/transform/stmt.rs +25 -22
- package/crates/tish/Cargo.toml +1 -1
- package/crates/tish/src/cli_help.rs +76 -29
- package/crates/tish/src/main.rs +85 -54
- package/crates/tish/tests/cargo_example_compile.rs +67 -0
- package/crates/tish/tests/fixtures/cargo_example_project/Cargo.toml +3 -0
- package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/Cargo.toml +11 -0
- package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/src/lib.rs +12 -0
- package/crates/tish/tests/fixtures/cargo_example_project/package.json +10 -0
- package/crates/tish/tests/fixtures/cargo_example_project/src/main.tish +3 -0
- package/crates/tish/tests/integration_test.rs +197 -47
- package/crates/tish/tests/run_optimize_stdout_parity.rs +3 -7
- package/crates/tish/tests/shortcircuit.rs +19 -4
- package/crates/tish_ast/src/ast.rs +12 -14
- package/crates/tish_build_utils/src/lib.rs +64 -6
- package/crates/tish_builtins/src/array.rs +52 -21
- package/crates/tish_builtins/src/construct.rs +2 -8
- package/crates/tish_builtins/src/globals.rs +30 -15
- package/crates/tish_builtins/src/lib.rs +5 -5
- package/crates/tish_builtins/src/math.rs +5 -3
- package/crates/tish_builtins/src/string.rs +71 -19
- package/crates/tish_bytecode/src/chunk.rs +0 -1
- package/crates/tish_bytecode/src/compiler.rs +164 -60
- package/crates/tish_bytecode/src/opcode.rs +13 -4
- package/crates/tish_bytecode/src/peephole.rs +2 -2
- package/crates/tish_compile/Cargo.toml +1 -0
- package/crates/tish_compile/src/codegen.rs +989 -318
- package/crates/tish_compile/src/infer.rs +69 -19
- package/crates/tish_compile/src/lib.rs +21 -8
- package/crates/tish_compile/src/resolve.rs +515 -94
- package/crates/tish_compile/src/types.rs +10 -14
- package/crates/tish_compile_js/src/codegen.rs +34 -13
- 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 +40 -48
- package/crates/tish_core/src/json.rs +5 -3
- package/crates/tish_core/src/lib.rs +1 -1
- package/crates/tish_core/src/uri.rs +9 -6
- package/crates/tish_core/src/value.rs +92 -28
- package/crates/tish_cranelift/src/link.rs +6 -9
- package/crates/tish_cranelift/src/lower.rs +14 -8
- package/crates/tish_eval/src/eval.rs +398 -141
- package/crates/tish_eval/src/lib.rs +10 -6
- package/crates/tish_eval/src/natives.rs +95 -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 +10 -3
- package/crates/tish_fmt/src/lib.rs +29 -13
- package/crates/tish_lexer/src/lib.rs +217 -63
- package/crates/tish_lexer/src/token.rs +6 -6
- package/crates/tish_llvm/src/lib.rs +15 -8
- package/crates/tish_lsp/src/main.rs +41 -43
- package/crates/tish_native/src/build.rs +38 -15
- package/crates/tish_native/src/lib.rs +76 -32
- package/crates/tish_opt/src/lib.rs +67 -50
- package/crates/tish_parser/src/lib.rs +36 -11
- package/crates/tish_parser/src/parser.rs +172 -87
- package/crates/tish_runtime/src/http.rs +15 -6
- package/crates/tish_runtime/src/http_fetch.rs +24 -14
- package/crates/tish_runtime/src/lib.rs +224 -168
- package/crates/tish_runtime/src/promise.rs +1 -5
- package/crates/tish_runtime/src/ws.rs +45 -20
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +5 -4
- package/crates/tish_ui/src/jsx.rs +41 -22
- package/crates/tish_ui/src/lib.rs +2 -2
- package/crates/tish_vm/src/vm.rs +320 -116
- package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +8 -3
- package/crates/tish_wasm/src/lib.rs +38 -28
- package/crates/tishlang_cargo_bindgen/Cargo.toml +25 -0
- package/crates/tishlang_cargo_bindgen/src/classify.rs +265 -0
- package/crates/tishlang_cargo_bindgen/src/discover.rs +52 -0
- package/crates/tishlang_cargo_bindgen/src/infer.rs +372 -0
- package/crates/tishlang_cargo_bindgen/src/lib.rs +349 -0
- package/crates/tishlang_cargo_bindgen/src/main.rs +164 -0
- package/crates/tishlang_cargo_bindgen/src/metadata.rs +114 -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,13 @@ 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
|
+
mutable,
|
|
139
|
+
type_ann,
|
|
140
|
+
init,
|
|
141
|
+
span,
|
|
142
|
+
} => {
|
|
130
143
|
// Already annotated — propagate into ctx but don't change the node.
|
|
131
144
|
if let Some(ann) = type_ann {
|
|
132
145
|
ctx.define(name.as_ref(), ann.clone());
|
|
@@ -149,9 +162,18 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
149
162
|
ctx.push_scope();
|
|
150
163
|
let stmts = infer_statements(statements, ctx);
|
|
151
164
|
ctx.pop_scope();
|
|
152
|
-
Statement::Block {
|
|
165
|
+
Statement::Block {
|
|
166
|
+
statements: stmts,
|
|
167
|
+
span: *span,
|
|
168
|
+
}
|
|
153
169
|
}
|
|
154
|
-
Statement::For {
|
|
170
|
+
Statement::For {
|
|
171
|
+
init,
|
|
172
|
+
cond,
|
|
173
|
+
update,
|
|
174
|
+
body,
|
|
175
|
+
span,
|
|
176
|
+
} => {
|
|
155
177
|
// Scope for loop variable
|
|
156
178
|
ctx.push_scope();
|
|
157
179
|
let new_init = init.as_ref().map(|i| Box::new(infer_statement(i, ctx)));
|
|
@@ -165,7 +187,12 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
165
187
|
span: *span,
|
|
166
188
|
}
|
|
167
189
|
}
|
|
168
|
-
Statement::ForOf {
|
|
190
|
+
Statement::ForOf {
|
|
191
|
+
name,
|
|
192
|
+
iterable,
|
|
193
|
+
body,
|
|
194
|
+
span,
|
|
195
|
+
} => {
|
|
169
196
|
ctx.push_scope();
|
|
170
197
|
let new_body = Box::new(infer_statement(body, ctx));
|
|
171
198
|
ctx.pop_scope();
|
|
@@ -180,17 +207,32 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
180
207
|
ctx.push_scope();
|
|
181
208
|
let new_body = Box::new(infer_statement(body, ctx));
|
|
182
209
|
ctx.pop_scope();
|
|
183
|
-
Statement::While {
|
|
210
|
+
Statement::While {
|
|
211
|
+
cond: cond.clone(),
|
|
212
|
+
body: new_body,
|
|
213
|
+
span: *span,
|
|
214
|
+
}
|
|
184
215
|
}
|
|
185
216
|
Statement::DoWhile { body, cond, span } => {
|
|
186
217
|
ctx.push_scope();
|
|
187
218
|
let new_body = Box::new(infer_statement(body, ctx));
|
|
188
219
|
ctx.pop_scope();
|
|
189
|
-
Statement::DoWhile {
|
|
220
|
+
Statement::DoWhile {
|
|
221
|
+
body: new_body,
|
|
222
|
+
cond: cond.clone(),
|
|
223
|
+
span: *span,
|
|
224
|
+
}
|
|
190
225
|
}
|
|
191
|
-
Statement::If {
|
|
226
|
+
Statement::If {
|
|
227
|
+
cond,
|
|
228
|
+
then_branch,
|
|
229
|
+
else_branch,
|
|
230
|
+
span,
|
|
231
|
+
} => {
|
|
192
232
|
let new_then = Box::new(infer_statement(then_branch, ctx));
|
|
193
|
-
let new_else = else_branch
|
|
233
|
+
let new_else = else_branch
|
|
234
|
+
.as_ref()
|
|
235
|
+
.map(|e| Box::new(infer_statement(e, ctx)));
|
|
194
236
|
Statement::If {
|
|
195
237
|
cond: cond.clone(),
|
|
196
238
|
then_branch: new_then,
|
|
@@ -198,7 +240,15 @@ fn infer_statement(stmt: &Statement, ctx: &mut InferCtx) -> Statement {
|
|
|
198
240
|
span: *span,
|
|
199
241
|
}
|
|
200
242
|
}
|
|
201
|
-
Statement::FunDecl {
|
|
243
|
+
Statement::FunDecl {
|
|
244
|
+
async_,
|
|
245
|
+
name,
|
|
246
|
+
params,
|
|
247
|
+
rest_param,
|
|
248
|
+
return_type,
|
|
249
|
+
body,
|
|
250
|
+
span,
|
|
251
|
+
} => {
|
|
202
252
|
ctx.push_scope();
|
|
203
253
|
for p in params {
|
|
204
254
|
if let FunParam::Simple(tp) = p {
|
|
@@ -7,15 +7,18 @@ 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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
cargo_export_fn_name, compute_native_build_artifacts, detect_cycles, export_name_to_rust_ident,
|
|
17
|
+
extract_native_import_features, format_rust_dependencies_toml, generate_native_wrapper_rs,
|
|
18
|
+
has_external_native_imports, has_native_imports, infer_native_module_exports,
|
|
19
|
+
is_builtin_native_spec, is_cargo_native_spec, merge_modules, read_project_tish_config,
|
|
20
|
+
resolve_native_modules, resolve_project, resolve_project_from_stdin, NativeBuildArtifacts,
|
|
21
|
+
NativeModuleInit, ResolvedNativeModule,
|
|
19
22
|
};
|
|
20
23
|
pub use types::{RustType, TypeContext};
|
|
21
24
|
|
|
@@ -41,7 +44,10 @@ fn sum(...args: number[]): number {
|
|
|
41
44
|
// total should be declared as f64
|
|
42
45
|
assert!(rust.contains("let mut total: f64"), "expected total: f64");
|
|
43
46
|
// The return value of run() should convert total back to Value
|
|
44
|
-
assert!(
|
|
47
|
+
assert!(
|
|
48
|
+
rust.contains("Value::Number(total)"),
|
|
49
|
+
"expected Value::Number(total) wrapping"
|
|
50
|
+
);
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
#[test]
|
|
@@ -57,7 +63,10 @@ for (let i = 0; i < 5; i = i + 1) {
|
|
|
57
63
|
let program = parse(src).unwrap();
|
|
58
64
|
let rust = compile(&program).unwrap();
|
|
59
65
|
// outerVar and x are f64 (inferred) — Copy assignment, no .clone() needed.
|
|
60
|
-
assert!(
|
|
66
|
+
assert!(
|
|
67
|
+
rust.contains("let mut outerVar: f64"),
|
|
68
|
+
"expected outerVar: f64"
|
|
69
|
+
);
|
|
61
70
|
assert!(rust.contains("let mut x: f64"), "expected x: f64");
|
|
62
71
|
}
|
|
63
72
|
|
|
@@ -102,13 +111,17 @@ fn factory() {
|
|
|
102
111
|
// This test verifies the full benchmark_granular project compiles and that outerVar
|
|
103
112
|
// is emitted as the inferred f64 type rather than requiring a Value clone.
|
|
104
113
|
let manifest = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
105
|
-
let bench = manifest
|
|
114
|
+
let bench = manifest
|
|
115
|
+
.join("../../tests/core/benchmark_granular.tish")
|
|
116
|
+
.canonicalize()
|
|
117
|
+
.unwrap();
|
|
106
118
|
// Use same default features as tish CLI (http, fs, process, regex)
|
|
107
119
|
let features = ["http", "fs", "process", "regex"]
|
|
108
120
|
.into_iter()
|
|
109
121
|
.map(String::from)
|
|
110
122
|
.collect::<Vec<_>>();
|
|
111
|
-
let (rust, _, _
|
|
123
|
+
let (rust, _, _, _) =
|
|
124
|
+
compile_project_full(&bench, bench.parent(), &features, true).unwrap();
|
|
112
125
|
// outerVar = 42 is inferred as f64; f64 is Copy so no .clone() is emitted.
|
|
113
126
|
assert!(
|
|
114
127
|
rust.contains("let mut outerVar: f64"),
|