@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.
Files changed (113) hide show
  1. package/Cargo.toml +2 -0
  2. package/README.md +2 -0
  3. package/bin/tish +0 -0
  4. package/crates/js_to_tish/src/error.rs +2 -8
  5. package/crates/js_to_tish/src/transform/expr.rs +128 -137
  6. package/crates/js_to_tish/src/transform/stmt.rs +62 -32
  7. package/crates/tish/Cargo.toml +15 -5
  8. package/crates/tish/src/cargo_native_registry.rs +29 -0
  9. package/crates/tish/src/cli_help.rs +92 -39
  10. package/crates/tish/src/main.rs +172 -86
  11. package/crates/tish/src/repl_completion.rs +3 -3
  12. package/crates/tish/tests/cargo_example_compile.rs +4 -2
  13. package/crates/tish/tests/integration_test.rs +216 -54
  14. package/crates/tish/tests/run_optimize_stdout_parity.rs +3 -7
  15. package/crates/tish/tests/shortcircuit.rs +20 -5
  16. package/crates/tish_ast/src/ast.rs +92 -23
  17. package/crates/tish_build_utils/Cargo.toml +4 -0
  18. package/crates/tish_build_utils/src/lib.rs +136 -8
  19. package/crates/tish_builtins/Cargo.toml +5 -1
  20. package/crates/tish_builtins/src/array.rs +65 -33
  21. package/crates/tish_builtins/src/construct.rs +34 -39
  22. package/crates/tish_builtins/src/globals.rs +42 -26
  23. package/crates/tish_builtins/src/helpers.rs +2 -1
  24. package/crates/tish_builtins/src/lib.rs +5 -5
  25. package/crates/tish_builtins/src/math.rs +5 -3
  26. package/crates/tish_builtins/src/object.rs +3 -2
  27. package/crates/tish_builtins/src/string.rs +144 -22
  28. package/crates/tish_bytecode/src/chunk.rs +0 -1
  29. package/crates/tish_bytecode/src/compiler.rs +173 -71
  30. package/crates/tish_bytecode/src/opcode.rs +24 -6
  31. package/crates/tish_bytecode/src/peephole.rs +2 -2
  32. package/crates/tish_compile/Cargo.toml +1 -0
  33. package/crates/tish_compile/src/codegen.rs +1621 -453
  34. package/crates/tish_compile/src/infer.rs +75 -19
  35. package/crates/tish_compile/src/lib.rs +19 -8
  36. package/crates/tish_compile/src/resolve.rs +278 -137
  37. package/crates/tish_compile/src/types.rs +184 -24
  38. package/crates/tish_compile_js/Cargo.toml +1 -0
  39. package/crates/tish_compile_js/src/codegen.rs +181 -37
  40. package/crates/tish_compile_js/src/lib.rs +3 -1
  41. package/crates/tish_compile_js/src/tests_jsx.rs +30 -6
  42. package/crates/tish_compiler_wasm/src/lib.rs +16 -13
  43. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +69 -59
  44. package/crates/tish_core/Cargo.toml +8 -0
  45. package/crates/tish_core/src/json.rs +107 -56
  46. package/crates/tish_core/src/lib.rs +4 -2
  47. package/crates/tish_core/src/macros.rs +5 -5
  48. package/crates/tish_core/src/uri.rs +9 -6
  49. package/crates/tish_core/src/value.rs +145 -43
  50. package/crates/tish_core/src/vmref.rs +178 -0
  51. package/crates/tish_cranelift/src/link.rs +6 -9
  52. package/crates/tish_cranelift/src/lower.rs +14 -8
  53. package/crates/tish_eval/Cargo.toml +17 -2
  54. package/crates/tish_eval/src/eval.rs +474 -165
  55. package/crates/tish_eval/src/http.rs +61 -0
  56. package/crates/tish_eval/src/lib.rs +12 -8
  57. package/crates/tish_eval/src/natives.rs +136 -38
  58. package/crates/tish_eval/src/promise.rs +14 -8
  59. package/crates/tish_eval/src/timers.rs +28 -19
  60. package/crates/tish_eval/src/value.rs +17 -6
  61. package/crates/tish_eval/src/value_convert.rs +13 -5
  62. package/crates/tish_fmt/src/lib.rs +149 -43
  63. package/crates/tish_lexer/src/lib.rs +232 -63
  64. package/crates/tish_lexer/src/token.rs +10 -6
  65. package/crates/tish_llvm/src/lib.rs +17 -8
  66. package/crates/tish_lsp/Cargo.toml +4 -1
  67. package/crates/tish_lsp/README.md +1 -1
  68. package/crates/tish_lsp/src/builtin_goto.rs +261 -0
  69. package/crates/tish_lsp/src/import_goto.rs +549 -0
  70. package/crates/tish_lsp/src/main.rs +504 -106
  71. package/crates/tish_native/src/build.rs +4 -8
  72. package/crates/tish_native/src/lib.rs +54 -21
  73. package/crates/tish_opt/src/lib.rs +84 -52
  74. package/crates/tish_parser/src/lib.rs +45 -13
  75. package/crates/tish_parser/src/parser.rs +505 -130
  76. package/crates/tish_resolve/Cargo.toml +13 -0
  77. package/crates/tish_resolve/src/lib.rs +3436 -0
  78. package/crates/tish_resolve/src/pos.rs +133 -0
  79. package/crates/tish_runtime/Cargo.toml +68 -3
  80. package/crates/tish_runtime/src/http.rs +1136 -145
  81. package/crates/tish_runtime/src/http_fetch.rs +38 -27
  82. package/crates/tish_runtime/src/http_hyper.rs +418 -0
  83. package/crates/tish_runtime/src/http_prefork.rs +189 -0
  84. package/crates/tish_runtime/src/lib.rs +375 -189
  85. package/crates/tish_runtime/src/promise.rs +199 -40
  86. package/crates/tish_runtime/src/promise_io.rs +2 -1
  87. package/crates/tish_runtime/src/timers.rs +37 -1
  88. package/crates/tish_runtime/src/ws.rs +65 -42
  89. package/crates/tish_runtime/tests/fetch_readable_stream.rs +5 -4
  90. package/crates/tish_ui/src/jsx.rs +317 -27
  91. package/crates/tish_ui/src/lib.rs +5 -2
  92. package/crates/tish_ui/src/runtime/hooks.rs +406 -45
  93. package/crates/tish_ui/src/runtime/mod.rs +36 -9
  94. package/crates/tish_vm/Cargo.toml +15 -5
  95. package/crates/tish_vm/src/vm.rs +725 -281
  96. package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +11 -4
  97. package/crates/tish_wasm/src/lib.rs +55 -42
  98. package/crates/tish_wasm_runtime/Cargo.toml +2 -1
  99. package/crates/tish_wasm_runtime/src/lib.rs +1 -1
  100. package/crates/tishlang_cargo_bindgen/Cargo.toml +26 -0
  101. package/crates/tishlang_cargo_bindgen/src/classify.rs +265 -0
  102. package/crates/tishlang_cargo_bindgen/src/discover.rs +120 -0
  103. package/crates/tishlang_cargo_bindgen/src/infer.rs +372 -0
  104. package/crates/tishlang_cargo_bindgen/src/lib.rs +350 -0
  105. package/crates/tishlang_cargo_bindgen/src/main.rs +164 -0
  106. package/crates/tishlang_cargo_bindgen/src/metadata.rs +114 -0
  107. package/justfile +8 -0
  108. package/package.json +1 -1
  109. package/platform/darwin-arm64/tish +0 -0
  110. package/platform/darwin-x64/tish +0 -0
  111. package/platform/linux-arm64/tish +0 -0
  112. package/platform/linux-x64/tish +0 -0
  113. 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 { scopes: vec![HashMap::new()] }
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 { left, op, right, .. } => {
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(&lt) && is_number(&rt) {
82
86
  match op {
83
- BinOp::Add
84
- | BinOp::Sub
85
- | BinOp::Mul
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) { Some(number_ann()) } else { None }
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 { statements: infer_statements(&program.statements, &mut ctx) }
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 { name, mutable, type_ann, init, span } => {
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 { statements: stmts, span: *span }
167
+ Statement::Block {
168
+ statements: stmts,
169
+ span: *span,
170
+ }
153
171
  }
154
- Statement::For { init, cond, update, body, span } => {
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 { name, iterable, body, span } => {
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 { cond: cond.clone(), body: new_body, span: *span }
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 { body: new_body, cond: cond.clone(), span: *span }
224
+ Statement::DoWhile {
225
+ body: new_body,
226
+ cond: cond.clone(),
227
+ span: *span,
228
+ }
190
229
  }
191
- Statement::If { cond, then_branch, else_branch, span } => {
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.as_ref().map(|e| Box::new(infer_statement(e, ctx)));
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 { async_, name, params, rest_param, return_type, body, span } => {
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, merge_modules, read_project_tish_config,
20
- resolve_native_modules, resolve_project, resolve_project_from_stdin, NativeBuildArtifacts,
21
- NativeModuleInit, ResolvedNativeModule,
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!(rust.contains("Value::Number(total)"), "expected Value::Number(total) wrapping");
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!(rust.contains("let mut outerVar: f64"), "expected outerVar: f64");
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.join("../../tests/core/benchmark_granular.tish").canonicalize().unwrap();
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, _, _, _) = compile_project_full(&bench, bench.parent(), &features, true).unwrap();
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"),