@tishlang/tish 1.0.13 → 1.0.15

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 (103) hide show
  1. package/crates/js_to_tish/Cargo.toml +4 -2
  2. package/crates/js_to_tish/src/span_util.rs +1 -1
  3. package/crates/js_to_tish/src/transform/expr.rs +15 -15
  4. package/crates/js_to_tish/src/transform/stmt.rs +7 -7
  5. package/crates/js_to_tish/src/transform.rs +1 -1
  6. package/crates/tish/Cargo.toml +22 -22
  7. package/crates/tish/src/main.rs +46 -46
  8. package/crates/tish/src/repl_completion.rs +4 -4
  9. package/crates/tish/tests/integration_test.rs +28 -28
  10. package/crates/tish_ast/Cargo.toml +3 -1
  11. package/crates/tish_ast/src/ast.rs +1 -1
  12. package/crates/tish_build_utils/Cargo.toml +3 -1
  13. package/crates/tish_build_utils/src/lib.rs +18 -6
  14. package/crates/tish_builtins/Cargo.toml +5 -3
  15. package/crates/tish_builtins/src/array.rs +2 -2
  16. package/crates/tish_builtins/src/globals.rs +3 -3
  17. package/crates/tish_builtins/src/helpers.rs +1 -1
  18. package/crates/tish_builtins/src/lib.rs +3 -3
  19. package/crates/tish_builtins/src/math.rs +1 -1
  20. package/crates/tish_builtins/src/object.rs +2 -2
  21. package/crates/tish_builtins/src/string.rs +1 -1
  22. package/crates/tish_bytecode/Cargo.toml +9 -7
  23. package/crates/tish_bytecode/src/chunk.rs +1 -1
  24. package/crates/tish_bytecode/src/compiler.rs +1 -1
  25. package/crates/tish_bytecode/src/encoding.rs +6 -6
  26. package/crates/tish_bytecode/tests/constant_folding.rs +7 -7
  27. package/crates/tish_bytecode/tests/shortcircuit.rs +11 -11
  28. package/crates/tish_bytecode/tests/sort_optimization.rs +3 -3
  29. package/crates/tish_compile/Cargo.toml +6 -4
  30. package/crates/tish_compile/src/codegen.rs +96 -96
  31. package/crates/tish_compile/src/lib.rs +2 -2
  32. package/crates/tish_compile/src/resolve.rs +7 -7
  33. package/crates/tish_compile/src/types.rs +1 -1
  34. package/crates/tish_compile_js/Cargo.toml +8 -6
  35. package/crates/tish_compile_js/src/codegen.rs +12 -12
  36. package/crates/tish_compile_js/src/js_intrinsics.rs +1 -1
  37. package/crates/tish_compile_js/src/lib.rs +2 -2
  38. package/crates/tish_compile_js/src/tests_jsx.rs +2 -2
  39. package/crates/tish_compiler_wasm/Cargo.toml +8 -6
  40. package/crates/tish_compiler_wasm/src/lib.rs +12 -12
  41. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +3 -3
  42. package/crates/tish_core/Cargo.toml +3 -1
  43. package/crates/tish_core/src/lib.rs +1 -1
  44. package/crates/tish_core/src/macros.rs +1 -1
  45. package/crates/tish_core/src/value.rs +1 -1
  46. package/crates/tish_cranelift/Cargo.toml +6 -4
  47. package/crates/tish_cranelift/src/lib.rs +2 -2
  48. package/crates/tish_cranelift/src/link.rs +11 -11
  49. package/crates/tish_cranelift/src/lower.rs +3 -3
  50. package/crates/tish_cranelift_runtime/Cargo.toml +9 -7
  51. package/crates/tish_cranelift_runtime/src/lib.rs +2 -2
  52. package/crates/tish_eval/Cargo.toml +10 -8
  53. package/crates/tish_eval/src/eval.rs +35 -35
  54. package/crates/tish_eval/src/http.rs +1 -1
  55. package/crates/tish_eval/src/lib.rs +3 -3
  56. package/crates/tish_eval/src/natives.rs +2 -2
  57. package/crates/tish_eval/src/regex.rs +2 -2
  58. package/crates/tish_eval/src/value.rs +7 -7
  59. package/crates/tish_eval/src/value_convert.rs +3 -3
  60. package/crates/tish_fmt/Cargo.toml +3 -3
  61. package/crates/tish_fmt/src/bin/tish-fmt.rs +1 -1
  62. package/crates/tish_fmt/src/lib.rs +3 -3
  63. package/crates/tish_jsx_web/Cargo.toml +3 -1
  64. package/crates/tish_lexer/Cargo.toml +3 -1
  65. package/crates/tish_lint/Cargo.toml +3 -3
  66. package/crates/tish_lint/src/bin/tish-lint.rs +3 -3
  67. package/crates/tish_lint/src/lib.rs +15 -15
  68. package/crates/tish_llvm/Cargo.toml +7 -5
  69. package/crates/tish_llvm/src/lib.rs +10 -10
  70. package/crates/tish_lsp/Cargo.toml +5 -5
  71. package/crates/tish_lsp/src/main.rs +35 -35
  72. package/crates/tish_native/Cargo.toml +10 -8
  73. package/crates/tish_native/src/build.rs +8 -8
  74. package/crates/tish_native/src/lib.rs +39 -39
  75. package/crates/tish_opt/Cargo.toml +5 -3
  76. package/crates/tish_opt/src/lib.rs +27 -27
  77. package/crates/tish_parser/Cargo.toml +5 -3
  78. package/crates/tish_parser/src/lib.rs +4 -4
  79. package/crates/tish_parser/src/parser.rs +2 -2
  80. package/crates/tish_runtime/Cargo.toml +7 -5
  81. package/crates/tish_runtime/src/http.rs +1 -1
  82. package/crates/tish_runtime/src/http_fetch.rs +2 -2
  83. package/crates/tish_runtime/src/lib.rs +21 -21
  84. package/crates/tish_runtime/src/native_promise.rs +1 -1
  85. package/crates/tish_runtime/src/promise.rs +2 -2
  86. package/crates/tish_runtime/src/promise_io.rs +1 -1
  87. package/crates/tish_runtime/src/timers.rs +1 -1
  88. package/crates/tish_runtime/src/ws.rs +1 -1
  89. package/crates/tish_runtime/tests/fetch_readable_stream.rs +2 -2
  90. package/crates/tish_vm/Cargo.toml +14 -12
  91. package/crates/tish_vm/src/lib.rs +2 -2
  92. package/crates/tish_vm/src/vm.rs +42 -42
  93. package/crates/tish_wasm/Cargo.toml +8 -6
  94. package/crates/tish_wasm/src/lib.rs +17 -17
  95. package/crates/tish_wasm_runtime/Cargo.toml +9 -7
  96. package/crates/tish_wasm_runtime/src/lib.rs +4 -4
  97. package/justfile +4 -4
  98. package/package.json +1 -1
  99. package/platform/darwin-arm64/tish +0 -0
  100. package/platform/darwin-x64/tish +0 -0
  101. package/platform/linux-arm64/tish +0 -0
  102. package/platform/linux-x64/tish +0 -0
  103. package/platform/win32-x64/tish.exe +0 -0
@@ -3,7 +3,7 @@
3
3
  use std::borrow::Cow;
4
4
  use std::collections::{HashMap, HashSet};
5
5
  use std::path::Path;
6
- use tish_ast::{ArrayElement, ArrowBody, BinOp, CallArg, CompoundOp, DestructElement, DestructPattern, Expr, Literal, LogicalAssignOp, MemberProp, ObjectProp, Program, Span, Statement, UnaryOp};
6
+ use tishlang_ast::{ArrayElement, ArrowBody, BinOp, CallArg, CompoundOp, DestructElement, DestructPattern, Expr, Literal, LogicalAssignOp, MemberProp, ObjectProp, Program, Span, Statement, UnaryOp};
7
7
  use crate::resolve::is_builtin_native_spec;
8
8
  use crate::types::{RustType, TypeContext};
9
9
 
@@ -191,19 +191,19 @@ impl UsageAnalyzer {
191
191
  Expr::JsxElement { props, children, .. } => {
192
192
  for p in props {
193
193
  match p {
194
- tish_ast::JsxProp::Attr { value: tish_ast::JsxAttrValue::Expr(e), .. } | tish_ast::JsxProp::Spread(e) => self.analyze_expr(e),
194
+ tishlang_ast::JsxProp::Attr { value: tishlang_ast::JsxAttrValue::Expr(e), .. } | tishlang_ast::JsxProp::Spread(e) => self.analyze_expr(e),
195
195
  _ => {}
196
196
  }
197
197
  }
198
198
  for c in children {
199
- if let tish_ast::JsxChild::Expr(e) = c {
199
+ if let tishlang_ast::JsxChild::Expr(e) = c {
200
200
  self.analyze_expr(e);
201
201
  }
202
202
  }
203
203
  }
204
204
  Expr::JsxFragment { children, .. } => {
205
205
  for c in children {
206
- if let tish_ast::JsxChild::Expr(e) = c {
206
+ if let tishlang_ast::JsxChild::Expr(e) = c {
207
207
  self.analyze_expr(e);
208
208
  }
209
209
  }
@@ -249,7 +249,7 @@ impl std::fmt::Display for CompileError {
249
249
  impl std::error::Error for CompileError {}
250
250
 
251
251
  fn program_uses_async(program: &Program) -> bool {
252
- use tish_ast::Statement;
252
+ use tishlang_ast::Statement;
253
253
  fn stmt_has_async(s: &Statement) -> bool {
254
254
  match s {
255
255
  Statement::FunDecl { async_, .. } if *async_ => true,
@@ -311,12 +311,12 @@ fn program_uses_async(program: &Program) -> bool {
311
311
  Expr::TemplateLiteral { exprs, .. } => exprs.iter().any(expr_has_await),
312
312
  Expr::JsxElement { props, children, .. } => {
313
313
  props.iter().any(|p| match p {
314
- tish_ast::JsxProp::Attr { value: tish_ast::JsxAttrValue::Expr(e), .. } | tish_ast::JsxProp::Spread(e) => expr_has_await(e),
314
+ tishlang_ast::JsxProp::Attr { value: tishlang_ast::JsxAttrValue::Expr(e), .. } | tishlang_ast::JsxProp::Spread(e) => expr_has_await(e),
315
315
  _ => false,
316
- }) || children.iter().any(|c| matches!(c, tish_ast::JsxChild::Expr(e) if expr_has_await(e)))
316
+ }) || children.iter().any(|c| matches!(c, tishlang_ast::JsxChild::Expr(e) if expr_has_await(e)))
317
317
  }
318
318
  Expr::JsxFragment { children, .. } => {
319
- children.iter().any(|c| matches!(c, tish_ast::JsxChild::Expr(e) if expr_has_await(e)))
319
+ children.iter().any(|c| matches!(c, tishlang_ast::JsxChild::Expr(e) if expr_has_await(e)))
320
320
  }
321
321
  _ => false,
322
322
  }
@@ -412,7 +412,7 @@ pub fn compile_project_full(
412
412
  }
413
413
 
414
414
  /// Compile with explicit feature flags. When features are provided, codegen uses them
415
- /// to emit builtins (process, serve, etc.) regardless of tish_compile's #[cfg] build.
415
+ /// to emit builtins (process, serve, etc.) regardless of tishlang_compile's #[cfg] build.
416
416
  pub fn compile_with_features(
417
417
  program: &Program,
418
418
  project_root: Option<&Path>,
@@ -429,7 +429,7 @@ pub fn compile_with_native_modules(
429
429
  native_modules: &[crate::resolve::ResolvedNativeModule],
430
430
  optimize: bool,
431
431
  ) -> Result<String, CompileError> {
432
- let program = if optimize { tish_opt::optimize(program) } else { program.clone() };
432
+ let program = if optimize { tishlang_opt::optimize(program) } else { program.clone() };
433
433
  let map: std::collections::HashMap<String, (String, String)> = native_modules
434
434
  .iter()
435
435
  .map(|m| (m.spec.clone(), (m.crate_name.clone(), m.export_fn.clone())))
@@ -507,7 +507,7 @@ impl Codegen {
507
507
  })
508
508
  }
509
509
 
510
- /// Rust init for built-in modules (tish:fs, tish:http, tish:process) - uses tish_runtime.
510
+ /// Rust init for built-in modules (tish:fs, tish:http, tish:process) - uses tishlang_runtime.
511
511
  fn builtin_native_module_rust_init(&self, spec: &str, export_name: &str) -> Option<String> {
512
512
  let init = match spec {
513
513
  "tish:fs" if self.has_feature("fs") => match export_name {
@@ -542,8 +542,8 @@ impl Codegen {
542
542
  "tish:ws" if self.has_feature("ws") => match export_name {
543
543
  "WebSocket" => Some("Value::Function(Rc::new(|args: &[Value]| tish_ws_client(args)))"),
544
544
  "Server" => Some("Value::Function(Rc::new(|args: &[Value]| tish_ws_server_construct(args)))"),
545
- "wsSend" => Some("Value::Function(Rc::new(|args: &[Value]| Value::Bool(tish_runtime::ws_send_native(args.first().unwrap_or(&Value::Null), &args.get(1).map(|v| v.to_display_string()).unwrap_or_default()))))"),
546
- "wsBroadcast" => Some("Value::Function(Rc::new(|args: &[Value]| tish_runtime::ws_broadcast_native(args)))"),
545
+ "wsSend" => Some("Value::Function(Rc::new(|args: &[Value]| Value::Bool(tishlang_runtime::ws_send_native(args.first().unwrap_or(&Value::Null), &args.get(1).map(|v| v.to_display_string()).unwrap_or_default()))))"),
546
+ "wsBroadcast" => Some("Value::Function(Rc::new(|args: &[Value]| tishlang_runtime::ws_broadcast_native(args)))"),
547
547
  _ => None,
548
548
  },
549
549
  _ => return None,
@@ -724,7 +724,7 @@ impl Codegen {
724
724
  /// Detect if an expression is a numeric sort comparator: (a, b) => a - b or (a, b) => b - a
725
725
  /// Returns Some(true) for ascending, Some(false) for descending, None if not detected
726
726
  fn detect_numeric_sort_comparator(expr: &Expr) -> Option<bool> {
727
- use tish_ast::ArrowBody;
727
+ use tishlang_ast::ArrowBody;
728
728
 
729
729
  if let Expr::ArrowFunction { params, body, .. } = expr {
730
730
  // Must have exactly 2 params
@@ -768,25 +768,25 @@ impl Codegen {
768
768
  self.write("use std::collections::HashMap;\n");
769
769
  self.write("use std::rc::Rc;\n");
770
770
  self.write("use std::sync::Arc;\n");
771
- self.write("use tish_runtime::{console_debug as tish_console_debug, console_info as tish_console_info, console_log as tish_console_log, console_warn as tish_console_warn, console_error as tish_console_error, boolean as tish_boolean, decode_uri as tish_decode_uri, encode_uri as tish_encode_uri, in_operator as tish_in_operator, is_finite as tish_is_finite, is_nan as tish_is_nan, json_parse as tish_json_parse, json_stringify as tish_json_stringify, math_abs as tish_math_abs, math_ceil as tish_math_ceil, math_floor as tish_math_floor, math_max as tish_math_max, math_min as tish_math_min, math_round as tish_math_round, math_sqrt as tish_math_sqrt, parse_float as tish_parse_float, parse_int as tish_parse_int, math_random as tish_math_random, math_pow as tish_math_pow, math_sin as tish_math_sin, math_cos as tish_math_cos, math_tan as tish_math_tan, math_log as tish_math_log, math_exp as tish_math_exp, math_sign as tish_math_sign, math_trunc as tish_math_trunc, date_now as tish_date_now, array_is_array as tish_array_is_array, string_from_char_code as tish_string_from_char_code, object_assign as tish_object_assign, object_keys as tish_object_keys, object_values as tish_object_values, object_entries as tish_object_entries, object_from_entries as tish_object_from_entries, TishError, Value};\n");
771
+ self.write("use tishlang_runtime::{console_debug as tish_console_debug, console_info as tish_console_info, console_log as tish_console_log, console_warn as tish_console_warn, console_error as tish_console_error, boolean as tish_boolean, decode_uri as tish_decode_uri, encode_uri as tish_encode_uri, in_operator as tish_in_operator, is_finite as tish_is_finite, is_nan as tish_is_nan, json_parse as tish_json_parse, json_stringify as tish_json_stringify, math_abs as tish_math_abs, math_ceil as tish_math_ceil, math_floor as tish_math_floor, math_max as tish_math_max, math_min as tish_math_min, math_round as tish_math_round, math_sqrt as tish_math_sqrt, parse_float as tish_parse_float, parse_int as tish_parse_int, math_random as tish_math_random, math_pow as tish_math_pow, math_sin as tish_math_sin, math_cos as tish_math_cos, math_tan as tish_math_tan, math_log as tish_math_log, math_exp as tish_math_exp, math_sign as tish_math_sign, math_trunc as tish_math_trunc, date_now as tish_date_now, array_is_array as tish_array_is_array, string_from_char_code as tish_string_from_char_code, object_assign as tish_object_assign, object_keys as tish_object_keys, object_values as tish_object_values, object_entries as tish_object_entries, object_from_entries as tish_object_from_entries, TishError, Value};\n");
772
772
  if self.has_feature("process") {
773
- self.write("use tish_runtime::{process_exit as tish_process_exit, process_cwd as tish_process_cwd, process_exec as tish_process_exec};\n");
773
+ self.write("use tishlang_runtime::{process_exit as tish_process_exit, process_cwd as tish_process_cwd, process_exec as tish_process_exec};\n");
774
774
  }
775
775
  if self.has_feature("http") {
776
776
  if self.is_async {
777
- self.write("use tish_runtime::{fetch_promise as tish_fetch_promise, fetch_all_promise as tish_fetch_all_promise, http_serve as tish_http_serve, timer_set_timeout as tish_timer_set_timeout, timer_clear_timeout as tish_timer_clear_timeout, promise_object as tish_promise_object, await_promise as tish_await_promise};\n");
777
+ self.write("use tishlang_runtime::{fetch_promise as tish_fetch_promise, fetch_all_promise as tish_fetch_all_promise, http_serve as tish_http_serve, timer_set_timeout as tish_timer_set_timeout, timer_clear_timeout as tish_timer_clear_timeout, promise_object as tish_promise_object, await_promise as tish_await_promise};\n");
778
778
  } else {
779
- self.write("use tish_runtime::{fetch_promise as tish_fetch_promise, fetch_all_promise as tish_fetch_all_promise, http_serve as tish_http_serve};\n");
779
+ self.write("use tishlang_runtime::{fetch_promise as tish_fetch_promise, fetch_all_promise as tish_fetch_all_promise, http_serve as tish_http_serve};\n");
780
780
  }
781
781
  }
782
782
  if self.has_feature("fs") {
783
- self.write("use tish_runtime::{read_file as tish_read_file, write_file as tish_write_file, file_exists as tish_file_exists, is_dir as tish_is_dir, read_dir as tish_read_dir, mkdir as tish_mkdir};\n");
783
+ self.write("use tishlang_runtime::{read_file as tish_read_file, write_file as tish_write_file, file_exists as tish_file_exists, is_dir as tish_is_dir, read_dir as tish_read_dir, mkdir as tish_mkdir};\n");
784
784
  }
785
785
  if self.has_feature("ws") {
786
- self.write("use tish_runtime::{web_socket_client as tish_ws_client, web_socket_server_construct as tish_ws_server_construct};\n");
786
+ self.write("use tishlang_runtime::{web_socket_client as tish_ws_client, web_socket_server_construct as tish_ws_server_construct};\n");
787
787
  }
788
788
  if self.has_feature("regex") {
789
- self.write("use tish_runtime::regexp_new;\n");
789
+ self.write("use tishlang_runtime::regexp_new;\n");
790
790
  }
791
791
  self.write("\n");
792
792
 
@@ -1277,7 +1277,7 @@ impl Codegen {
1277
1277
  Statement::Throw { value, .. } => {
1278
1278
  let v = self.emit_expr(value)?;
1279
1279
  self.writeln(&format!(
1280
- "return Err(Box::new(tish_runtime::TishError::Throw({})) as Box<dyn std::error::Error>);",
1280
+ "return Err(Box::new(tishlang_runtime::TishError::Throw({})) as Box<dyn std::error::Error>);",
1281
1281
  v
1282
1282
  ));
1283
1283
  }
@@ -1299,11 +1299,11 @@ impl Codegen {
1299
1299
  if let Some(param) = catch_param {
1300
1300
  self.writeln("if let Err(e) = _try_result {");
1301
1301
  self.indent += 1;
1302
- self.writeln("match e.downcast::<tish_runtime::TishError>() {");
1302
+ self.writeln("match e.downcast::<tishlang_runtime::TishError>() {");
1303
1303
  self.indent += 1;
1304
1304
  self.writeln("Ok(tish_err) => {");
1305
1305
  self.indent += 1;
1306
- self.writeln("if let tish_runtime::TishError::Throw(v) = *tish_err {");
1306
+ self.writeln("if let tishlang_runtime::TishError::Throw(v) = *tish_err {");
1307
1307
  self.writeln(&format!("let {} = v.clone();", Self::escape_ident(param.as_ref())));
1308
1308
  self.emit_statement(catch_stmt)?;
1309
1309
  self.writeln("} else { return Err(Box::new(tish_err)); }");
@@ -1719,15 +1719,15 @@ impl Codegen {
1719
1719
  .collect::<Vec<_>>()
1720
1720
  .join(", ");
1721
1721
  return Ok(format!(
1722
- "tish_runtime::array_push(&{}, &[{}])",
1722
+ "tishlang_runtime::array_push(&{}, &[{}])",
1723
1723
  obj_expr, args_vec
1724
1724
  ));
1725
1725
  }
1726
1726
  "pop" => {
1727
- return Ok(format!("tish_runtime::array_pop(&{})", obj_expr));
1727
+ return Ok(format!("tishlang_runtime::array_pop(&{})", obj_expr));
1728
1728
  }
1729
1729
  "shift" => {
1730
- return Ok(format!("tish_runtime::array_shift(&{})", obj_expr));
1730
+ return Ok(format!("tishlang_runtime::array_shift(&{})", obj_expr));
1731
1731
  }
1732
1732
  "unshift" => {
1733
1733
  let args_vec = arg_exprs.iter()
@@ -1735,7 +1735,7 @@ impl Codegen {
1735
1735
  .collect::<Vec<_>>()
1736
1736
  .join(", ");
1737
1737
  return Ok(format!(
1738
- "tish_runtime::array_unshift(&{}, &[{}])",
1738
+ "tishlang_runtime::array_unshift(&{}, &[{}])",
1739
1739
  obj_expr, args_vec
1740
1740
  ));
1741
1741
  }
@@ -1743,7 +1743,7 @@ impl Codegen {
1743
1743
  let search = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1744
1744
  let from = arg_exprs.get(1).cloned().unwrap_or_else(|| "Value::Null".to_string());
1745
1745
  return Ok(format!(
1746
- "{{ let _obj = ({}).clone(); match &_obj {{ Value::Array(_) => tish_runtime::array_index_of(&_obj, &{}), Value::String(_) => tish_runtime::string_index_of(&_obj, &{}, &{}), _ => Value::Number(-1.0) }} }}",
1746
+ "{{ let _obj = ({}).clone(); match &_obj {{ Value::Array(_) => tishlang_runtime::array_index_of(&_obj, &{}), Value::String(_) => tishlang_runtime::string_index_of(&_obj, &{}, &{}), _ => Value::Number(-1.0) }} }}",
1747
1747
  obj_expr, search, search, from
1748
1748
  ));
1749
1749
  }
@@ -1751,28 +1751,28 @@ impl Codegen {
1751
1751
  let search = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1752
1752
  let from = arg_exprs.get(1).cloned().unwrap_or_else(|| "Value::Null".to_string());
1753
1753
  return Ok(format!(
1754
- "{{ let _obj = ({}).clone(); match &_obj {{ Value::Array(_) => tish_runtime::array_includes(&_obj, &{}, &{}), Value::String(_) => tish_runtime::string_includes(&_obj, &{}, &{}), _ => Value::Bool(false) }} }}",
1754
+ "{{ let _obj = ({}).clone(); match &_obj {{ Value::Array(_) => tishlang_runtime::array_includes(&_obj, &{}, &{}), Value::String(_) => tishlang_runtime::string_includes(&_obj, &{}, &{}), _ => Value::Bool(false) }} }}",
1755
1755
  obj_expr, search, from, search, from
1756
1756
  ));
1757
1757
  }
1758
1758
  "join" => {
1759
1759
  let sep = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1760
1760
  return Ok(format!(
1761
- "tish_runtime::array_join(&{}, &{})",
1761
+ "tishlang_runtime::array_join(&{}, &{})",
1762
1762
  obj_expr, sep
1763
1763
  ));
1764
1764
  }
1765
1765
  "reverse" => {
1766
- return Ok(format!("tish_runtime::array_reverse(&{})", obj_expr));
1766
+ return Ok(format!("tishlang_runtime::array_reverse(&{})", obj_expr));
1767
1767
  }
1768
1768
  "shuffle" => {
1769
- return Ok(format!("tish_runtime::array_shuffle(&{})", obj_expr));
1769
+ return Ok(format!("tishlang_runtime::array_shuffle(&{})", obj_expr));
1770
1770
  }
1771
1771
  "slice" => {
1772
1772
  let start = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Number(0.0)".to_string());
1773
1773
  let end = arg_exprs.get(1).cloned().unwrap_or_else(|| "Value::Null".to_string());
1774
1774
  return Ok(format!(
1775
- "{{ let _obj = ({}).clone(); match &_obj {{ Value::Array(_) => tish_runtime::array_slice(&_obj, &{}, &{}), Value::String(_) => tish_runtime::string_slice(&_obj, &{}, &{}), _ => Value::Null }} }}",
1775
+ "{{ let _obj = ({}).clone(); match &_obj {{ Value::Array(_) => tishlang_runtime::array_slice(&_obj, &{}, &{}), Value::String(_) => tishlang_runtime::string_slice(&_obj, &{}, &{}), _ => Value::Null }} }}",
1776
1776
  obj_expr, start, end, start, end
1777
1777
  ));
1778
1778
  }
@@ -1782,7 +1782,7 @@ impl Codegen {
1782
1782
  .collect::<Vec<_>>()
1783
1783
  .join(", ");
1784
1784
  return Ok(format!(
1785
- "tish_runtime::array_concat(&{}, &[{}])",
1785
+ "tishlang_runtime::array_concat(&{}, &[{}])",
1786
1786
  obj_expr, args_vec
1787
1787
  ));
1788
1788
  }
@@ -1791,37 +1791,37 @@ impl Codegen {
1791
1791
  let start = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Number(0.0)".to_string());
1792
1792
  let end = arg_exprs.get(1).cloned().unwrap_or_else(|| "Value::Null".to_string());
1793
1793
  return Ok(format!(
1794
- "tish_runtime::string_substring(&{}, &{}, &{})",
1794
+ "tishlang_runtime::string_substring(&{}, &{}, &{})",
1795
1795
  obj_expr, start, end
1796
1796
  ));
1797
1797
  }
1798
1798
  "split" => {
1799
1799
  let sep = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1800
1800
  return Ok(format!(
1801
- "tish_runtime::string_split(&{}, &{})",
1801
+ "tishlang_runtime::string_split(&{}, &{})",
1802
1802
  obj_expr, sep
1803
1803
  ));
1804
1804
  }
1805
1805
  "trim" => {
1806
- return Ok(format!("tish_runtime::string_trim(&{})", obj_expr));
1806
+ return Ok(format!("tishlang_runtime::string_trim(&{})", obj_expr));
1807
1807
  }
1808
1808
  "toUpperCase" => {
1809
- return Ok(format!("tish_runtime::string_to_upper_case(&{})", obj_expr));
1809
+ return Ok(format!("tishlang_runtime::string_to_upper_case(&{})", obj_expr));
1810
1810
  }
1811
1811
  "toLowerCase" => {
1812
- return Ok(format!("tish_runtime::string_to_lower_case(&{})", obj_expr));
1812
+ return Ok(format!("tishlang_runtime::string_to_lower_case(&{})", obj_expr));
1813
1813
  }
1814
1814
  "startsWith" => {
1815
1815
  let search = arg_exprs.first().cloned().unwrap_or_else(|| "Value::String(\"\".into())".to_string());
1816
1816
  return Ok(format!(
1817
- "tish_runtime::string_starts_with(&{}, &{})",
1817
+ "tishlang_runtime::string_starts_with(&{}, &{})",
1818
1818
  obj_expr, search
1819
1819
  ));
1820
1820
  }
1821
1821
  "endsWith" => {
1822
1822
  let search = arg_exprs.first().cloned().unwrap_or_else(|| "Value::String(\"\".into())".to_string());
1823
1823
  return Ok(format!(
1824
- "tish_runtime::string_ends_with(&{}, &{})",
1824
+ "tishlang_runtime::string_ends_with(&{}, &{})",
1825
1825
  obj_expr, search
1826
1826
  ));
1827
1827
  }
@@ -1829,7 +1829,7 @@ impl Codegen {
1829
1829
  let search = arg_exprs.first().cloned().unwrap_or_else(|| "Value::String(\"\".into())".to_string());
1830
1830
  let replacement = arg_exprs.get(1).cloned().unwrap_or_else(|| "Value::String(\"\".into())".to_string());
1831
1831
  return Ok(format!(
1832
- "tish_runtime::string_replace(&{}, &{}, &{})",
1832
+ "tishlang_runtime::string_replace(&{}, &{}, &{})",
1833
1833
  obj_expr, search, replacement
1834
1834
  ));
1835
1835
  }
@@ -1837,35 +1837,35 @@ impl Codegen {
1837
1837
  let search = arg_exprs.first().cloned().unwrap_or_else(|| "Value::String(\"\".into())".to_string());
1838
1838
  let replacement = arg_exprs.get(1).cloned().unwrap_or_else(|| "Value::String(\"\".into())".to_string());
1839
1839
  return Ok(format!(
1840
- "tish_runtime::string_replace_all(&{}, &{}, &{})",
1840
+ "tishlang_runtime::string_replace_all(&{}, &{}, &{})",
1841
1841
  obj_expr, search, replacement
1842
1842
  ));
1843
1843
  }
1844
1844
  "match" if cfg!(feature = "regex") => {
1845
1845
  let regexp = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1846
1846
  return Ok(format!(
1847
- "tish_runtime::string_match_regex(&{}, &{})",
1847
+ "tishlang_runtime::string_match_regex(&{}, &{})",
1848
1848
  obj_expr, regexp
1849
1849
  ));
1850
1850
  }
1851
1851
  "charAt" => {
1852
1852
  let idx = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Number(0.0)".to_string());
1853
1853
  return Ok(format!(
1854
- "tish_runtime::string_char_at(&{}, &{})",
1854
+ "tishlang_runtime::string_char_at(&{}, &{})",
1855
1855
  obj_expr, idx
1856
1856
  ));
1857
1857
  }
1858
1858
  "charCodeAt" => {
1859
1859
  let idx = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Number(0.0)".to_string());
1860
1860
  return Ok(format!(
1861
- "tish_runtime::string_char_code_at(&{}, &{})",
1861
+ "tishlang_runtime::string_char_code_at(&{}, &{})",
1862
1862
  obj_expr, idx
1863
1863
  ));
1864
1864
  }
1865
1865
  "repeat" => {
1866
1866
  let count = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Number(0.0)".to_string());
1867
1867
  return Ok(format!(
1868
- "tish_runtime::string_repeat(&{}, &{})",
1868
+ "tishlang_runtime::string_repeat(&{}, &{})",
1869
1869
  obj_expr, count
1870
1870
  ));
1871
1871
  }
@@ -1873,7 +1873,7 @@ impl Codegen {
1873
1873
  let target_len = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Number(0.0)".to_string());
1874
1874
  let pad = arg_exprs.get(1).cloned().unwrap_or_else(|| "Value::Null".to_string());
1875
1875
  return Ok(format!(
1876
- "tish_runtime::string_pad_start(&{}, &{}, &{})",
1876
+ "tishlang_runtime::string_pad_start(&{}, &{}, &{})",
1877
1877
  obj_expr, target_len, pad
1878
1878
  ));
1879
1879
  }
@@ -1881,7 +1881,7 @@ impl Codegen {
1881
1881
  let target_len = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Number(0.0)".to_string());
1882
1882
  let pad = arg_exprs.get(1).cloned().unwrap_or_else(|| "Value::Null".to_string());
1883
1883
  return Ok(format!(
1884
- "tish_runtime::string_pad_end(&{}, &{}, &{})",
1884
+ "tishlang_runtime::string_pad_end(&{}, &{}, &{})",
1885
1885
  obj_expr, target_len, pad
1886
1886
  ));
1887
1887
  }
@@ -1889,7 +1889,7 @@ impl Codegen {
1889
1889
  "toFixed" => {
1890
1890
  let digits = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Number(0.0)".to_string());
1891
1891
  return Ok(format!(
1892
- "tish_runtime::number_to_fixed(&{}, &{})",
1892
+ "tishlang_runtime::number_to_fixed(&{}, &{})",
1893
1893
  obj_expr, digits
1894
1894
  ));
1895
1895
  }
@@ -1897,14 +1897,14 @@ impl Codegen {
1897
1897
  "map" => {
1898
1898
  let callback = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1899
1899
  return Ok(format!(
1900
- "tish_runtime::array_map(&{}, &{})",
1900
+ "tishlang_runtime::array_map(&{}, &{})",
1901
1901
  obj_expr, callback
1902
1902
  ));
1903
1903
  }
1904
1904
  "filter" => {
1905
1905
  let callback = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1906
1906
  return Ok(format!(
1907
- "tish_runtime::array_filter(&{}, &{})",
1907
+ "tishlang_runtime::array_filter(&{}, &{})",
1908
1908
  obj_expr, callback
1909
1909
  ));
1910
1910
  }
@@ -1912,42 +1912,42 @@ impl Codegen {
1912
1912
  let callback = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1913
1913
  let initial = arg_exprs.get(1).cloned().unwrap_or_else(|| "Value::Null".to_string());
1914
1914
  return Ok(format!(
1915
- "tish_runtime::array_reduce(&{}, &{}, &{})",
1915
+ "tishlang_runtime::array_reduce(&{}, &{}, &{})",
1916
1916
  obj_expr, callback, initial
1917
1917
  ));
1918
1918
  }
1919
1919
  "forEach" => {
1920
1920
  let callback = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1921
1921
  return Ok(format!(
1922
- "tish_runtime::array_for_each(&{}, &{})",
1922
+ "tishlang_runtime::array_for_each(&{}, &{})",
1923
1923
  obj_expr, callback
1924
1924
  ));
1925
1925
  }
1926
1926
  "find" => {
1927
1927
  let callback = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1928
1928
  return Ok(format!(
1929
- "tish_runtime::array_find(&{}, &{})",
1929
+ "tishlang_runtime::array_find(&{}, &{})",
1930
1930
  obj_expr, callback
1931
1931
  ));
1932
1932
  }
1933
1933
  "findIndex" => {
1934
1934
  let callback = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1935
1935
  return Ok(format!(
1936
- "tish_runtime::array_find_index(&{}, &{})",
1936
+ "tishlang_runtime::array_find_index(&{}, &{})",
1937
1937
  obj_expr, callback
1938
1938
  ));
1939
1939
  }
1940
1940
  "some" => {
1941
1941
  let callback = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1942
1942
  return Ok(format!(
1943
- "tish_runtime::array_some(&{}, &{})",
1943
+ "tishlang_runtime::array_some(&{}, &{})",
1944
1944
  obj_expr, callback
1945
1945
  ));
1946
1946
  }
1947
1947
  "every" => {
1948
1948
  let callback = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
1949
1949
  return Ok(format!(
1950
- "tish_runtime::array_every(&{}, &{})",
1950
+ "tishlang_runtime::array_every(&{}, &{})",
1951
1951
  obj_expr, callback
1952
1952
  ));
1953
1953
  }
@@ -1957,12 +1957,12 @@ impl Codegen {
1957
1957
  if let Some(ascending) = Self::detect_numeric_sort_comparator(comparator_expr) {
1958
1958
  if ascending {
1959
1959
  return Ok(format!(
1960
- "tish_runtime::array_sort_numeric_asc(&{})",
1960
+ "tishlang_runtime::array_sort_numeric_asc(&{})",
1961
1961
  obj_expr
1962
1962
  ));
1963
1963
  } else {
1964
1964
  return Ok(format!(
1965
- "tish_runtime::array_sort_numeric_desc(&{})",
1965
+ "tishlang_runtime::array_sort_numeric_desc(&{})",
1966
1966
  obj_expr
1967
1967
  ));
1968
1968
  }
@@ -1971,7 +1971,7 @@ impl Codegen {
1971
1971
  // General case: use the callback
1972
1972
  let comparator = arg_exprs.first().map(|c| format!("Some(&{})", c)).unwrap_or_else(|| "None".to_string());
1973
1973
  return Ok(format!(
1974
- "tish_runtime::array_sort(&{}, {})",
1974
+ "tishlang_runtime::array_sort(&{}, {})",
1975
1975
  obj_expr, comparator
1976
1976
  ));
1977
1977
  }
@@ -1988,21 +1988,21 @@ impl Codegen {
1988
1988
  "&[]".to_string()
1989
1989
  };
1990
1990
  return Ok(format!(
1991
- "tish_runtime::array_splice(&{}, &{}, {}, {})",
1991
+ "tishlang_runtime::array_splice(&{}, &{}, {}, {})",
1992
1992
  obj_expr, start, delete_count, items
1993
1993
  ));
1994
1994
  }
1995
1995
  "flat" => {
1996
1996
  let depth = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Number(1.0)".to_string());
1997
1997
  return Ok(format!(
1998
- "tish_runtime::array_flat(&{}, &{})",
1998
+ "tishlang_runtime::array_flat(&{}, &{})",
1999
1999
  obj_expr, depth
2000
2000
  ));
2001
2001
  }
2002
2002
  "flatMap" => {
2003
2003
  let callback = arg_exprs.first().cloned().unwrap_or_else(|| "Value::Null".to_string());
2004
2004
  return Ok(format!(
2005
- "tish_runtime::array_flat_map(&{}, &{})",
2005
+ "tishlang_runtime::array_flat_map(&{}, &{})",
2006
2006
  obj_expr, callback
2007
2007
  ));
2008
2008
  }
@@ -2056,11 +2056,11 @@ impl Codegen {
2056
2056
  if *optional {
2057
2057
  format!(
2058
2058
  "{{ let o = {}.clone(); if matches!(o, Value::Null) {{ Value::Null }} else {{ \
2059
- tish_runtime::get_prop(&o, {}) }} }}",
2059
+ tishlang_runtime::get_prop(&o, {}) }} }}",
2060
2060
  obj, key
2061
2061
  )
2062
2062
  } else {
2063
- format!("tish_runtime::get_prop(&{}, {})", obj, key)
2063
+ format!("tishlang_runtime::get_prop(&{}, {})", obj, key)
2064
2064
  }
2065
2065
  }
2066
2066
  Expr::Index {
@@ -2074,11 +2074,11 @@ impl Codegen {
2074
2074
  if *optional {
2075
2075
  format!(
2076
2076
  "{{ let o = {}.clone(); if matches!(o, Value::Null) {{ Value::Null }} else {{ \
2077
- tish_runtime::get_index(&o, &{}) }} }}",
2077
+ tishlang_runtime::get_index(&o, &{}) }} }}",
2078
2078
  obj, idx
2079
2079
  )
2080
2080
  } else {
2081
- format!("tish_runtime::get_index(&{}, &{})", obj, idx)
2081
+ format!("tishlang_runtime::get_index(&{}, &{})", obj, idx)
2082
2082
  }
2083
2083
  }
2084
2084
  Expr::Conditional {
@@ -2264,12 +2264,12 @@ impl Codegen {
2264
2264
  };
2265
2265
  if self.refcell_wrapped_vars.contains(name.as_ref()) {
2266
2266
  format!(
2267
- "{{ let _rhs = ({}).clone(); *{}.borrow_mut() = tish_runtime::ops::{}(&*{}.borrow(), &_rhs)?; (*{}.borrow()).clone() }}",
2267
+ "{{ let _rhs = ({}).clone(); *{}.borrow_mut() = tishlang_runtime::ops::{}(&*{}.borrow(), &_rhs)?; (*{}.borrow()).clone() }}",
2268
2268
  val, n, op_fn, n, n
2269
2269
  )
2270
2270
  } else {
2271
2271
  format!(
2272
- "{{ let _rhs = ({}).clone(); {} = tish_runtime::ops::{}(&{}, &_rhs)?; {}.clone() }}",
2272
+ "{{ let _rhs = ({}).clone(); {} = tishlang_runtime::ops::{}(&{}, &_rhs)?; {}.clone() }}",
2273
2273
  val, n, op_fn, n, n
2274
2274
  )
2275
2275
  }
@@ -2321,7 +2321,7 @@ impl Codegen {
2321
2321
  let obj = self.emit_expr(object)?;
2322
2322
  let val = self.emit_expr(value)?;
2323
2323
  format!(
2324
- "tish_runtime::set_prop(&({}), \"{}\", ({}).clone())",
2324
+ "tishlang_runtime::set_prop(&({}), \"{}\", ({}).clone())",
2325
2325
  obj,
2326
2326
  prop.as_ref(),
2327
2327
  val
@@ -2332,7 +2332,7 @@ impl Codegen {
2332
2332
  let idx = self.emit_expr(index)?;
2333
2333
  let val = self.emit_expr(value)?;
2334
2334
  format!(
2335
- "tish_runtime::set_index(&({}), &({}), ({}).clone())",
2335
+ "tishlang_runtime::set_index(&({}), &({}), ({}).clone())",
2336
2336
  obj,
2337
2337
  idx,
2338
2338
  val
@@ -2476,19 +2476,19 @@ impl Codegen {
2476
2476
  Expr::JsxElement { props, children, .. } => {
2477
2477
  for p in props {
2478
2478
  match p {
2479
- tish_ast::JsxProp::Attr { value: tish_ast::JsxAttrValue::Expr(e), .. } | tish_ast::JsxProp::Spread(e) => Self::collect_expr_idents(e, idents),
2479
+ tishlang_ast::JsxProp::Attr { value: tishlang_ast::JsxAttrValue::Expr(e), .. } | tishlang_ast::JsxProp::Spread(e) => Self::collect_expr_idents(e, idents),
2480
2480
  _ => {}
2481
2481
  }
2482
2482
  }
2483
2483
  for c in children {
2484
- if let tish_ast::JsxChild::Expr(e) = c {
2484
+ if let tishlang_ast::JsxChild::Expr(e) = c {
2485
2485
  Self::collect_expr_idents(e, idents);
2486
2486
  }
2487
2487
  }
2488
2488
  }
2489
2489
  Expr::JsxFragment { children, .. } => {
2490
2490
  for c in children {
2491
- if let tish_ast::JsxChild::Expr(e) = c {
2491
+ if let tishlang_ast::JsxChild::Expr(e) = c {
2492
2492
  Self::collect_expr_idents(e, idents);
2493
2493
  }
2494
2494
  }
@@ -2664,25 +2664,25 @@ impl Codegen {
2664
2664
  Expr::JsxElement { props, children, .. } => {
2665
2665
  for p in props {
2666
2666
  match p {
2667
- tish_ast::JsxProp::Attr {
2668
- value: tish_ast::JsxAttrValue::Expr(e),
2667
+ tishlang_ast::JsxProp::Attr {
2668
+ value: tishlang_ast::JsxAttrValue::Expr(e),
2669
2669
  ..
2670
2670
  }
2671
- | tish_ast::JsxProp::Spread(e) => {
2671
+ | tishlang_ast::JsxProp::Spread(e) => {
2672
2672
  Self::collect_assigned_idents_in_expr(e, names);
2673
2673
  }
2674
2674
  _ => {}
2675
2675
  }
2676
2676
  }
2677
2677
  for c in children {
2678
- if let tish_ast::JsxChild::Expr(e) = c {
2678
+ if let tishlang_ast::JsxChild::Expr(e) = c {
2679
2679
  Self::collect_assigned_idents_in_expr(e, names);
2680
2680
  }
2681
2681
  }
2682
2682
  }
2683
2683
  Expr::JsxFragment { children, .. } => {
2684
2684
  for c in children {
2685
- if let tish_ast::JsxChild::Expr(e) = c {
2685
+ if let tishlang_ast::JsxChild::Expr(e) = c {
2686
2686
  Self::collect_assigned_idents_in_expr(e, names);
2687
2687
  }
2688
2688
  }
@@ -2725,7 +2725,7 @@ impl Codegen {
2725
2725
  /// Collect variable names that are both captured and mutated by a closure body.
2726
2726
  /// block_vars: vars declared in the enclosing block (candidates for mutation).
2727
2727
  fn collect_mutated_captures_from_closure(
2728
- params: &[tish_ast::TypedParam],
2728
+ params: &[tishlang_ast::TypedParam],
2729
2729
  body: &Statement,
2730
2730
  block_vars: &HashSet<String>,
2731
2731
  result: &mut HashSet<String>,
@@ -2754,7 +2754,7 @@ impl Codegen {
2754
2754
  }
2755
2755
 
2756
2756
  fn collect_mutated_captures_from_arrow(
2757
- params: &[tish_ast::TypedParam],
2757
+ params: &[tishlang_ast::TypedParam],
2758
2758
  body: &ArrowBody,
2759
2759
  block_vars: &HashSet<String>,
2760
2760
  result: &mut HashSet<String>,
@@ -3055,8 +3055,8 @@ impl Codegen {
3055
3055
 
3056
3056
  fn emit_arrow_function(
3057
3057
  &mut self,
3058
- params: &[tish_ast::TypedParam],
3059
- body: &tish_ast::ArrowBody,
3058
+ params: &[tishlang_ast::TypedParam],
3059
+ body: &tishlang_ast::ArrowBody,
3060
3060
  ) -> Result<String, CompileError> {
3061
3061
  // Build the arrow function as a Value::Function closure
3062
3062
  let mut code = String::new();
@@ -3186,11 +3186,11 @@ impl Codegen {
3186
3186
 
3187
3187
  // Emit body based on type
3188
3188
  match body {
3189
- tish_ast::ArrowBody::Expr(expr) => {
3189
+ tishlang_ast::ArrowBody::Expr(expr) => {
3190
3190
  let expr_code = self.emit_expr(expr)?;
3191
3191
  code.push_str(&format!(" {}\n", expr_code));
3192
3192
  }
3193
- tish_ast::ArrowBody::Block(block_stmt) => {
3193
+ tishlang_ast::ArrowBody::Block(block_stmt) => {
3194
3194
  // For block bodies, emit the block statement
3195
3195
  self.function_scope_stack.push(Vec::new());
3196
3196
 
@@ -3284,11 +3284,11 @@ impl Codegen {
3284
3284
  span: Span,
3285
3285
  ) -> Result<String, CompileError> {
3286
3286
  Ok(match op {
3287
- BinOp::Add => format!("tish_runtime::ops::add(&{}, &{}).unwrap_or(Value::Null)", l, r),
3288
- BinOp::Sub => format!("tish_runtime::ops::sub(&{}, &{}).unwrap_or(Value::Null)", l, r),
3289
- BinOp::Mul => format!("tish_runtime::ops::mul(&{}, &{}).unwrap_or(Value::Null)", l, r),
3290
- BinOp::Div => format!("tish_runtime::ops::div(&{}, &{}).unwrap_or(Value::Null)", l, r),
3291
- BinOp::Mod => format!("tish_runtime::ops::modulo(&{}, &{}).unwrap_or(Value::Null)", l, r),
3287
+ BinOp::Add => format!("tishlang_runtime::ops::add(&{}, &{}).unwrap_or(Value::Null)", l, r),
3288
+ BinOp::Sub => format!("tishlang_runtime::ops::sub(&{}, &{}).unwrap_or(Value::Null)", l, r),
3289
+ BinOp::Mul => format!("tishlang_runtime::ops::mul(&{}, &{}).unwrap_or(Value::Null)", l, r),
3290
+ BinOp::Div => format!("tishlang_runtime::ops::div(&{}, &{}).unwrap_or(Value::Null)", l, r),
3291
+ BinOp::Mod => format!("tishlang_runtime::ops::modulo(&{}, &{}).unwrap_or(Value::Null)", l, r),
3292
3292
  BinOp::Pow => format!(
3293
3293
  "Value::Number({{ let Value::Number(a) = &({}) else {{ panic!() }}; \
3294
3294
  let Value::Number(b) = &({}) else {{ panic!() }}; a.powf(*b) }})",
@@ -3296,10 +3296,10 @@ impl Codegen {
3296
3296
  ),
3297
3297
  BinOp::StrictEq => format!("Value::Bool({}.strict_eq(&{}))", l, r),
3298
3298
  BinOp::StrictNe => format!("Value::Bool(!{}.strict_eq(&{}))", l, r),
3299
- BinOp::Lt => format!("tish_runtime::ops::lt(&{}, &{})", l, r),
3300
- BinOp::Le => format!("tish_runtime::ops::le(&{}, &{})", l, r),
3301
- BinOp::Gt => format!("tish_runtime::ops::gt(&{}, &{})", l, r),
3302
- BinOp::Ge => format!("tish_runtime::ops::ge(&{}, &{})", l, r),
3299
+ BinOp::Lt => format!("tishlang_runtime::ops::lt(&{}, &{})", l, r),
3300
+ BinOp::Le => format!("tishlang_runtime::ops::le(&{}, &{})", l, r),
3301
+ BinOp::Gt => format!("tishlang_runtime::ops::gt(&{}, &{})", l, r),
3302
+ BinOp::Ge => format!("tishlang_runtime::ops::ge(&{}, &{})", l, r),
3303
3303
  BinOp::And => format!("Value::Bool({}.is_truthy() && {}.is_truthy())", l, r),
3304
3304
  BinOp::Or => format!("Value::Bool({}.is_truthy() || {}.is_truthy())", l, r),
3305
3305
  BinOp::BitAnd => Self::emit_bitwise_binop(l, r, "&"),