@tishlang/tish 1.6.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.
Files changed (79) hide show
  1. package/Cargo.toml +1 -0
  2. package/bin/tish +0 -0
  3. package/crates/js_to_tish/src/error.rs +2 -8
  4. package/crates/js_to_tish/src/transform/expr.rs +101 -130
  5. package/crates/js_to_tish/src/transform/stmt.rs +25 -22
  6. package/crates/tish/Cargo.toml +1 -1
  7. package/crates/tish/src/cli_help.rs +76 -29
  8. package/crates/tish/src/main.rs +85 -54
  9. package/crates/tish/tests/cargo_example_compile.rs +3 -1
  10. package/crates/tish/tests/integration_test.rs +197 -47
  11. package/crates/tish/tests/run_optimize_stdout_parity.rs +3 -7
  12. package/crates/tish/tests/shortcircuit.rs +19 -4
  13. package/crates/tish_ast/src/ast.rs +12 -14
  14. package/crates/tish_build_utils/src/lib.rs +31 -6
  15. package/crates/tish_builtins/src/array.rs +52 -21
  16. package/crates/tish_builtins/src/construct.rs +2 -8
  17. package/crates/tish_builtins/src/globals.rs +30 -15
  18. package/crates/tish_builtins/src/lib.rs +5 -5
  19. package/crates/tish_builtins/src/math.rs +5 -3
  20. package/crates/tish_builtins/src/string.rs +71 -19
  21. package/crates/tish_bytecode/src/chunk.rs +0 -1
  22. package/crates/tish_bytecode/src/compiler.rs +164 -60
  23. package/crates/tish_bytecode/src/opcode.rs +13 -4
  24. package/crates/tish_bytecode/src/peephole.rs +2 -2
  25. package/crates/tish_compile/src/codegen.rs +921 -299
  26. package/crates/tish_compile/src/infer.rs +69 -19
  27. package/crates/tish_compile/src/lib.rs +15 -5
  28. package/crates/tish_compile/src/resolve.rs +112 -69
  29. package/crates/tish_compile/src/types.rs +10 -14
  30. package/crates/tish_compile_js/src/codegen.rs +34 -13
  31. package/crates/tish_compile_js/src/tests_jsx.rs +30 -6
  32. package/crates/tish_compiler_wasm/src/lib.rs +16 -13
  33. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +39 -48
  34. package/crates/tish_core/src/json.rs +5 -3
  35. package/crates/tish_core/src/lib.rs +1 -1
  36. package/crates/tish_core/src/uri.rs +9 -6
  37. package/crates/tish_core/src/value.rs +92 -28
  38. package/crates/tish_cranelift/src/link.rs +6 -9
  39. package/crates/tish_cranelift/src/lower.rs +14 -8
  40. package/crates/tish_eval/src/eval.rs +389 -142
  41. package/crates/tish_eval/src/lib.rs +10 -6
  42. package/crates/tish_eval/src/natives.rs +95 -38
  43. package/crates/tish_eval/src/promise.rs +14 -8
  44. package/crates/tish_eval/src/timers.rs +28 -19
  45. package/crates/tish_eval/src/value.rs +10 -3
  46. package/crates/tish_fmt/src/lib.rs +29 -13
  47. package/crates/tish_lexer/src/lib.rs +217 -63
  48. package/crates/tish_lexer/src/token.rs +6 -6
  49. package/crates/tish_llvm/src/lib.rs +15 -8
  50. package/crates/tish_lsp/src/main.rs +41 -43
  51. package/crates/tish_native/src/build.rs +1 -6
  52. package/crates/tish_native/src/lib.rs +48 -19
  53. package/crates/tish_opt/src/lib.rs +67 -50
  54. package/crates/tish_parser/src/lib.rs +36 -11
  55. package/crates/tish_parser/src/parser.rs +172 -87
  56. package/crates/tish_runtime/src/http.rs +15 -6
  57. package/crates/tish_runtime/src/http_fetch.rs +24 -14
  58. package/crates/tish_runtime/src/lib.rs +224 -168
  59. package/crates/tish_runtime/src/promise.rs +1 -5
  60. package/crates/tish_runtime/src/ws.rs +45 -20
  61. package/crates/tish_runtime/tests/fetch_readable_stream.rs +5 -4
  62. package/crates/tish_ui/src/jsx.rs +41 -22
  63. package/crates/tish_ui/src/lib.rs +2 -2
  64. package/crates/tish_vm/src/vm.rs +309 -112
  65. package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +8 -3
  66. package/crates/tish_wasm/src/lib.rs +38 -28
  67. package/crates/tishlang_cargo_bindgen/Cargo.toml +25 -0
  68. package/crates/tishlang_cargo_bindgen/src/classify.rs +265 -0
  69. package/crates/tishlang_cargo_bindgen/src/discover.rs +52 -0
  70. package/crates/tishlang_cargo_bindgen/src/infer.rs +372 -0
  71. package/crates/tishlang_cargo_bindgen/src/lib.rs +349 -0
  72. package/crates/tishlang_cargo_bindgen/src/main.rs +164 -0
  73. package/crates/tishlang_cargo_bindgen/src/metadata.rs +114 -0
  74. package/package.json +1 -1
  75. package/platform/darwin-arm64/tish +0 -0
  76. package/platform/darwin-x64/tish +0 -0
  77. package/platform/linux-arm64/tish +0 -0
  78. package/platform/linux-x64/tish +0 -0
  79. package/platform/win32-x64/tish.exe +0 -0
@@ -8,11 +8,14 @@ use std::path::{Path, PathBuf};
8
8
  use std::rc::Rc;
9
9
  use std::sync::Arc;
10
10
 
11
- use tishlang_ast::{BinOp, CompoundOp, ExportDeclaration, Expr, FunParam, ImportSpecifier, Literal, LogicalAssignOp, MemberProp, Span, Statement, UnaryOp};
11
+ use tishlang_ast::{
12
+ BinOp, CompoundOp, ExportDeclaration, Expr, FunParam, ImportSpecifier, Literal,
13
+ LogicalAssignOp, MemberProp, Span, Statement, UnaryOp,
14
+ };
12
15
 
13
- use crate::value::{PropMap, Value};
14
16
  #[cfg(any(feature = "fs", feature = "process"))]
15
17
  use crate::natives;
18
+ use crate::value::{PropMap, Value};
16
19
 
17
20
  struct Scope {
18
21
  vars: PropMap,
@@ -93,12 +96,24 @@ impl Evaluator {
93
96
  console.insert("log".into(), Value::Native(natives::console_log));
94
97
  console.insert("warn".into(), Value::Native(natives::console_warn));
95
98
  console.insert("error".into(), Value::Native(natives::console_error));
96
- s.set("console".into(), Value::Object(Rc::new(RefCell::new(console))), true);
99
+ s.set(
100
+ "console".into(),
101
+ Value::Object(Rc::new(RefCell::new(console))),
102
+ true,
103
+ );
97
104
  s.set("parseInt".into(), Value::Native(natives::parse_int), true);
98
- s.set("parseFloat".into(), Value::Native(natives::parse_float), true);
105
+ s.set(
106
+ "parseFloat".into(),
107
+ Value::Native(natives::parse_float),
108
+ true,
109
+ );
99
110
  s.set("decodeURI".into(), Value::Native(natives::decode_uri), true);
100
111
  s.set("encodeURI".into(), Value::Native(natives::encode_uri), true);
101
- s.set("Boolean".into(), Value::Native(natives::boolean_native), true);
112
+ s.set(
113
+ "Boolean".into(),
114
+ Value::Native(natives::boolean_native),
115
+ true,
116
+ );
102
117
  s.set("isFinite".into(), Value::Native(natives::is_finite), true);
103
118
  s.set("isNaN".into(), Value::Native(natives::is_nan), true);
104
119
  s.set("Infinity".into(), Value::Number(f64::INFINITY), true);
@@ -122,32 +137,65 @@ impl Evaluator {
122
137
  math.insert("trunc".into(), Value::Native(natives::math_trunc));
123
138
  math.insert("PI".into(), Value::Number(std::f64::consts::PI));
124
139
  math.insert("E".into(), Value::Number(std::f64::consts::E));
125
- s.set("Math".into(), Value::Object(Rc::new(RefCell::new(math))), true);
140
+ s.set(
141
+ "Math".into(),
142
+ Value::Object(Rc::new(RefCell::new(math))),
143
+ true,
144
+ );
126
145
 
127
146
  let mut json = PropMap::with_capacity(2);
128
147
  json.insert("parse".into(), Value::Native(Self::json_parse_native));
129
- json.insert("stringify".into(), Value::Native(Self::json_stringify_native));
130
- s.set("JSON".into(), Value::Object(Rc::new(RefCell::new(json))), true);
148
+ json.insert(
149
+ "stringify".into(),
150
+ Value::Native(Self::json_stringify_native),
151
+ );
152
+ s.set(
153
+ "JSON".into(),
154
+ Value::Object(Rc::new(RefCell::new(json))),
155
+ true,
156
+ );
131
157
 
132
158
  let mut object = PropMap::with_capacity(5);
133
159
  object.insert("keys".into(), Value::Native(Self::object_keys));
134
160
  object.insert("values".into(), Value::Native(Self::object_values));
135
161
  object.insert("entries".into(), Value::Native(Self::object_entries));
136
162
  object.insert("assign".into(), Value::Native(Self::object_assign));
137
- object.insert("fromEntries".into(), Value::Native(Self::object_from_entries));
138
- s.set("Object".into(), Value::Object(Rc::new(RefCell::new(object))), true);
163
+ object.insert(
164
+ "fromEntries".into(),
165
+ Value::Native(Self::object_from_entries),
166
+ );
167
+ s.set(
168
+ "Object".into(),
169
+ Value::Object(Rc::new(RefCell::new(object))),
170
+ true,
171
+ );
139
172
 
140
173
  let mut array_obj = PropMap::with_capacity(1);
141
174
  array_obj.insert("isArray".into(), Value::Native(natives::array_is_array));
142
- s.set("Array".into(), Value::Object(Rc::new(RefCell::new(array_obj))), true);
175
+ s.set(
176
+ "Array".into(),
177
+ Value::Object(Rc::new(RefCell::new(array_obj))),
178
+ true,
179
+ );
143
180
 
144
181
  let mut string_obj = PropMap::with_capacity(1);
145
- string_obj.insert("fromCharCode".into(), Value::Native(natives::string_from_char_code));
146
- s.set("String".into(), Value::Object(Rc::new(RefCell::new(string_obj))), true);
182
+ string_obj.insert(
183
+ "fromCharCode".into(),
184
+ Value::Native(natives::string_from_char_code),
185
+ );
186
+ s.set(
187
+ "String".into(),
188
+ Value::Object(Rc::new(RefCell::new(string_obj))),
189
+ true,
190
+ );
147
191
 
148
192
  let mut date = PropMap::with_capacity(1);
149
193
  date.insert("now".into(), Value::Native(natives::date_now));
150
- s.set("Date".into(), Value::Object(Rc::new(RefCell::new(date))), true);
194
+ s.set(
195
+ "Date".into(),
196
+ Value::Object(Rc::new(RefCell::new(date))),
197
+ true,
198
+ );
151
199
 
152
200
  s.set(
153
201
  "Uint8Array".into(),
@@ -166,7 +214,11 @@ impl Evaluator {
166
214
 
167
215
  #[cfg(feature = "regex")]
168
216
  {
169
- s.set("RegExp".into(), Value::Native(Self::regexp_constructor_native), true);
217
+ s.set(
218
+ "RegExp".into(),
219
+ Value::Native(Self::regexp_constructor_native),
220
+ true,
221
+ );
170
222
  }
171
223
 
172
224
  // fs, http, process: use import { x } from 'tish:fs' etc. No globals.
@@ -225,16 +277,28 @@ impl Evaluator {
225
277
  self.scope = prev;
226
278
  Ok(last)
227
279
  }
228
- Statement::VarDecl { name, mutable, init, .. } => {
280
+ Statement::VarDecl {
281
+ name,
282
+ mutable,
283
+ init,
284
+ ..
285
+ } => {
229
286
  let value = init
230
287
  .as_ref()
231
288
  .map(|e| self.eval_expr(e))
232
289
  .transpose()?
233
290
  .unwrap_or(Value::Null);
234
- self.scope.borrow_mut().set(Arc::clone(name), value, *mutable);
291
+ self.scope
292
+ .borrow_mut()
293
+ .set(Arc::clone(name), value, *mutable);
235
294
  Ok(Value::Null)
236
295
  }
237
- Statement::VarDeclDestructure { pattern, mutable, init, .. } => {
296
+ Statement::VarDeclDestructure {
297
+ pattern,
298
+ mutable,
299
+ init,
300
+ ..
301
+ } => {
238
302
  let value = self.eval_expr(init)?;
239
303
  self.bind_destruct_pattern(pattern, &value, *mutable)?;
240
304
  Ok(Value::Null)
@@ -269,15 +333,21 @@ impl Evaluator {
269
333
  }
270
334
  Ok(Value::Null)
271
335
  }
272
- Statement::ForOf { name, iterable, body, .. } => {
336
+ Statement::ForOf {
337
+ name,
338
+ iterable,
339
+ body,
340
+ ..
341
+ } => {
273
342
  let iter_val = self.eval_expr(iterable)?;
274
343
  let elements = match &iter_val {
275
- crate::value::Value::Array(arr) => arr.borrow().iter().cloned().collect::<Vec<_>>(),
276
- crate::value::Value::String(s) => {
277
- s.chars()
278
- .map(|c| crate::value::Value::String(Arc::from(c.to_string())))
279
- .collect::<Vec<_>>()
344
+ crate::value::Value::Array(arr) => {
345
+ arr.borrow().iter().cloned().collect::<Vec<_>>()
280
346
  }
347
+ crate::value::Value::String(s) => s
348
+ .chars()
349
+ .map(|c| crate::value::Value::String(Arc::from(c.to_string())))
350
+ .collect::<Vec<_>>(),
281
351
  _ => {
282
352
  return Err(EvalError::Error(format!(
283
353
  "for-of requires iterable (array or string), got {}",
@@ -360,7 +430,12 @@ impl Evaluator {
360
430
  self.scope.borrow_mut().set(Arc::clone(name), func, true);
361
431
  Ok(Value::Null)
362
432
  }
363
- Statement::Switch { expr, cases, default_body, .. } => {
433
+ Statement::Switch {
434
+ expr,
435
+ cases,
436
+ default_body,
437
+ ..
438
+ } => {
364
439
  let v = self.eval_expr(expr)?;
365
440
  let mut matched = false;
366
441
  for (case_expr, body) in cases {
@@ -438,7 +513,7 @@ impl Evaluator {
438
513
  ..
439
514
  } => {
440
515
  let try_result = self.eval_statement(body);
441
-
516
+
442
517
  let result = match try_result {
443
518
  Ok(v) => Ok(v),
444
519
  Err(EvalError::Throw(thrown)) => {
@@ -459,18 +534,24 @@ impl Evaluator {
459
534
  }
460
535
  Err(e) => Err(e),
461
536
  };
462
-
537
+
463
538
  if let Some(finally_stmt) = finally_body {
464
539
  let _ = self.eval_statement(finally_stmt);
465
540
  }
466
-
541
+
467
542
  result
468
543
  }
469
- Statement::Import { specifiers, from, .. } => {
544
+ Statement::Import {
545
+ specifiers, from, ..
546
+ } => {
470
547
  let exports_val = self.load_module(from)?;
471
548
  let exports = match &exports_val {
472
549
  Value::Object(m) => m.borrow().clone(),
473
- _ => return Err(EvalError::Error("Module exports must be object".to_string())),
550
+ _ => {
551
+ return Err(EvalError::Error(
552
+ "Module exports must be object".to_string(),
553
+ ))
554
+ }
474
555
  };
475
556
  let mut scope = self.scope.borrow_mut();
476
557
  for spec in specifiers {
@@ -514,7 +595,8 @@ impl Evaluator {
514
595
  fn load_module(&mut self, from: &str) -> Result<Value, EvalError> {
515
596
  if from.starts_with("cargo:") {
516
597
  return Err(EvalError::Error(
517
- "cargo:… imports are only supported by `tish build` with the Rust native backend.".into(),
598
+ "cargo:… imports are only supported by `tish build` with the Rust native backend."
599
+ .into(),
518
600
  ));
519
601
  }
520
602
  if from.starts_with("tish:") {
@@ -525,24 +607,24 @@ impl Evaluator {
525
607
  return self.load_builtin_module(from);
526
608
  }
527
609
  let dir = self.current_dir.borrow().clone().ok_or_else(|| {
528
- EvalError::Error("Cannot resolve imports: no current file directory (use run_file)".to_string())
610
+ EvalError::Error(
611
+ "Cannot resolve imports: no current file directory (use run_file)".to_string(),
612
+ )
529
613
  })?;
530
614
  let path = Self::resolve_import_path(from, &dir)?;
531
- let path = path.canonicalize().map_err(|e| {
532
- EvalError::Error(format!("Cannot resolve import '{}': {}", from, e))
533
- })?;
615
+ let path = path
616
+ .canonicalize()
617
+ .map_err(|e| EvalError::Error(format!("Cannot resolve import '{}': {}", from, e)))?;
534
618
  {
535
619
  let cache = self.module_cache.borrow();
536
620
  if let Some(m) = cache.get(&path) {
537
621
  return Ok(m.clone());
538
622
  }
539
623
  }
540
- let source = std::fs::read_to_string(&path).map_err(|e| {
541
- EvalError::Error(format!("Cannot read {}: {}", path.display(), e))
542
- })?;
543
- let program = tishlang_parser::parse(&source).map_err(|e| {
544
- EvalError::Error(format!("Parse error in {}: {}", path.display(), e))
545
- })?;
624
+ let source = std::fs::read_to_string(&path)
625
+ .map_err(|e| EvalError::Error(format!("Cannot read {}: {}", path.display(), e)))?;
626
+ let program = tishlang_parser::parse(&source)
627
+ .map_err(|e| EvalError::Error(format!("Parse error in {}: {}", path.display(), e)))?;
546
628
  let module_scope = Scope::child(Rc::clone(&self.scope));
547
629
  let prev_scope = std::mem::replace(&mut self.scope, Rc::clone(&module_scope));
548
630
  let parent_dir = self.current_dir.borrow().clone();
@@ -554,7 +636,9 @@ impl Evaluator {
554
636
  match declaration.as_ref() {
555
637
  ExportDeclaration::Named(s) => {
556
638
  let _ = self.eval_statement(s);
557
- if let Statement::VarDecl { name, .. } | Statement::FunDecl { name, .. } = s.as_ref() {
639
+ if let Statement::VarDecl { name, .. } | Statement::FunDecl { name, .. } =
640
+ s.as_ref()
641
+ {
558
642
  export_names.push(name.to_string());
559
643
  }
560
644
  }
@@ -577,7 +661,9 @@ impl Evaluator {
577
661
  *self.current_dir.borrow_mut() = parent_dir;
578
662
  self.scope = prev_scope;
579
663
  let exports_val = Value::Object(Rc::new(RefCell::new(exports)));
580
- self.module_cache.borrow_mut().insert(path, exports_val.clone());
664
+ self.module_cache
665
+ .borrow_mut()
666
+ .insert(path, exports_val.clone());
581
667
  Ok(exports_val)
582
668
  }
583
669
 
@@ -640,10 +726,22 @@ impl Evaluator {
640
726
  exports.insert("fetchAll".into(), Value::Native(Self::fetch_all_native));
641
727
  exports.insert("serve".into(), Value::Serve);
642
728
  exports.insert("Promise".into(), Value::PromiseConstructor);
643
- exports.insert("setTimeout".into(), Value::TimerBuiltin(Arc::from("setTimeout")));
644
- exports.insert("setInterval".into(), Value::TimerBuiltin(Arc::from("setInterval")));
645
- exports.insert("clearTimeout".into(), Value::Native(Self::clear_timeout_native));
646
- exports.insert("clearInterval".into(), Value::Native(Self::clear_interval_native));
729
+ exports.insert(
730
+ "setTimeout".into(),
731
+ Value::TimerBuiltin(Arc::from("setTimeout")),
732
+ );
733
+ exports.insert(
734
+ "setInterval".into(),
735
+ Value::TimerBuiltin(Arc::from("setInterval")),
736
+ );
737
+ exports.insert(
738
+ "clearTimeout".into(),
739
+ Value::Native(Self::clear_timeout_native),
740
+ );
741
+ exports.insert(
742
+ "clearInterval".into(),
743
+ Value::Native(Self::clear_interval_native),
744
+ );
647
745
  return Ok(Value::Object(Rc::new(RefCell::new(exports))));
648
746
  }
649
747
  #[cfg(not(feature = "http"))]
@@ -657,10 +755,16 @@ impl Evaluator {
657
755
  #[cfg(feature = "ws")]
658
756
  {
659
757
  let mut exports: PropMap = PropMap::default();
660
- exports.insert("WebSocket".into(), Value::Native(Self::ws_web_socket_native));
758
+ exports.insert(
759
+ "WebSocket".into(),
760
+ Value::Native(Self::ws_web_socket_native),
761
+ );
661
762
  exports.insert("Server".into(), Value::Native(Self::ws_server_native));
662
763
  exports.insert("wsSend".into(), Value::Native(Self::ws_send_native));
663
- exports.insert("wsBroadcast".into(), Value::Native(Self::ws_broadcast_native));
764
+ exports.insert(
765
+ "wsBroadcast".into(),
766
+ Value::Native(Self::ws_broadcast_native),
767
+ );
664
768
  return Ok(Value::Object(Rc::new(RefCell::new(exports))));
665
769
  }
666
770
  #[cfg(not(feature = "ws"))]
@@ -677,21 +781,29 @@ impl Evaluator {
677
781
  exports.insert("exit".into(), Value::Native(natives::process_exit));
678
782
  exports.insert("cwd".into(), Value::Native(natives::process_cwd));
679
783
  exports.insert("exec".into(), Value::Native(natives::process_exec));
680
- let argv: Vec<Value> = std::env::args()
681
- .map(|s| Value::String(s.into()))
682
- .collect();
683
- exports.insert("argv".into(), Value::Array(Rc::new(RefCell::new(argv.clone()))));
784
+ let argv: Vec<Value> =
785
+ std::env::args().map(|s| Value::String(s.into())).collect();
786
+ exports.insert(
787
+ "argv".into(),
788
+ Value::Array(Rc::new(RefCell::new(argv.clone()))),
789
+ );
684
790
  let env_obj: PropMap = std::env::vars()
685
791
  .map(|(key, value)| (Arc::from(key.as_str()), Value::String(value.into())))
686
792
  .collect();
687
- exports.insert("env".into(), Value::Object(Rc::new(RefCell::new(env_obj.clone()))));
793
+ exports.insert(
794
+ "env".into(),
795
+ Value::Object(Rc::new(RefCell::new(env_obj.clone()))),
796
+ );
688
797
  let mut process_obj = PropMap::default();
689
798
  process_obj.insert("exit".into(), Value::Native(natives::process_exit));
690
799
  process_obj.insert("cwd".into(), Value::Native(natives::process_cwd));
691
800
  process_obj.insert("exec".into(), Value::Native(natives::process_exec));
692
801
  process_obj.insert("argv".into(), Value::Array(Rc::new(RefCell::new(argv))));
693
802
  process_obj.insert("env".into(), Value::Object(Rc::new(RefCell::new(env_obj))));
694
- exports.insert("process".into(), Value::Object(Rc::new(RefCell::new(process_obj))));
803
+ exports.insert(
804
+ "process".into(),
805
+ Value::Object(Rc::new(RefCell::new(process_obj))),
806
+ );
695
807
  return Ok(Value::Object(Rc::new(RefCell::new(exports))));
696
808
  }
697
809
  #[cfg(not(feature = "process"))]
@@ -1912,7 +2024,13 @@ impl Evaluator {
1912
2024
  /// descending = false: checks for `(a, b) => a - b`
1913
2025
  /// descending = true: checks for `(a, b) => b - a`
1914
2026
  fn is_numeric_sort_comparator(f: &Value, descending: bool) -> bool {
1915
- if let Value::Function { formals, body, rest_param, .. } = f {
2027
+ if let Value::Function {
2028
+ formals,
2029
+ body,
2030
+ rest_param,
2031
+ ..
2032
+ } = f
2033
+ {
1916
2034
  // Must have exactly 2 simple params, no defaults, no rest
1917
2035
  if formals.len() != 2 || rest_param.is_some() {
1918
2036
  return false;
@@ -1936,15 +2054,29 @@ impl Evaluator {
1936
2054
  };
1937
2055
 
1938
2056
  // Check for binary subtraction
1939
- if let Expr::Binary { left, op: BinOp::Sub, right, .. } = expr {
2057
+ if let Expr::Binary {
2058
+ left,
2059
+ op: BinOp::Sub,
2060
+ right,
2061
+ ..
2062
+ } = expr
2063
+ {
1940
2064
  // Check left is Ident(a) and right is Ident(b)
1941
2065
  let (expected_left, expected_right) = if descending {
1942
- (param_b, param_a) // b - a
2066
+ (param_b, param_a) // b - a
1943
2067
  } else {
1944
- (param_a, param_b) // a - b
2068
+ (param_a, param_b) // a - b
1945
2069
  };
1946
2070
 
1947
- if let (Expr::Ident { name: left_name, .. }, Expr::Ident { name: right_name, .. }) = (left.as_ref(), right.as_ref()) {
2071
+ if let (
2072
+ Expr::Ident {
2073
+ name: left_name, ..
2074
+ },
2075
+ Expr::Ident {
2076
+ name: right_name, ..
2077
+ },
2078
+ ) = (left.as_ref(), right.as_ref())
2079
+ {
1948
2080
  return left_name == expected_left && right_name == expected_right;
1949
2081
  }
1950
2082
  }
@@ -1999,8 +2131,17 @@ impl Evaluator {
1999
2131
 
2000
2132
  /// Optimized callback invocation for array methods.
2001
2133
  /// Creates a reusable scope that can be updated for each iteration.
2002
- fn create_callback_scope(&self, f: &Value) -> Option<(Rc<RefCell<Scope>>, Arc<[Arc<str>]>, Arc<Statement>)> {
2003
- if let Value::Function { formals, body, rest_param, .. } = f {
2134
+ fn create_callback_scope(
2135
+ &self,
2136
+ f: &Value,
2137
+ ) -> Option<(Rc<RefCell<Scope>>, Arc<[Arc<str>]>, Arc<Statement>)> {
2138
+ if let Value::Function {
2139
+ formals,
2140
+ body,
2141
+ rest_param,
2142
+ ..
2143
+ } = f
2144
+ {
2004
2145
  if rest_param.is_some() {
2005
2146
  return None;
2006
2147
  }
@@ -2063,12 +2204,14 @@ impl Evaluator {
2063
2204
 
2064
2205
  /// Try to evaluate a simple callback expression directly without creating a scope.
2065
2206
  /// Returns Some(result) for simple patterns like `x => x * 2` or `x => x > 5`.
2066
- fn eval_simple_callback(
2067
- &self,
2068
- f: &Value,
2069
- args: &[Value],
2070
- ) -> Option<Result<Value, EvalError>> {
2071
- if let Value::Function { formals, body, rest_param, .. } = f {
2207
+ fn eval_simple_callback(&self, f: &Value, args: &[Value]) -> Option<Result<Value, EvalError>> {
2208
+ if let Value::Function {
2209
+ formals,
2210
+ body,
2211
+ rest_param,
2212
+ ..
2213
+ } = f
2214
+ {
2072
2215
  if formals.len() != 1 || rest_param.is_some() {
2073
2216
  return None;
2074
2217
  }
@@ -2088,17 +2231,25 @@ impl Evaluator {
2088
2231
  // Fast path for common patterns
2089
2232
  match expr {
2090
2233
  // x * constant or x + constant, etc.
2091
- Expr::Binary { left, op, right, .. } => {
2234
+ Expr::Binary {
2235
+ left, op, right, ..
2236
+ } => {
2092
2237
  let left_val = self.eval_simple_operand(left, param_name, &arg)?;
2093
2238
  let right_val = self.eval_simple_operand(right, param_name, &arg)?;
2094
- Some(self.eval_binop(&left_val, *op, &right_val).map_err(EvalError::Error))
2239
+ Some(
2240
+ self.eval_binop(&left_val, *op, &right_val)
2241
+ .map_err(EvalError::Error),
2242
+ )
2095
2243
  }
2096
2244
  // Just return the parameter
2097
- Expr::Ident { name, .. } if name == param_name => {
2098
- Some(Ok(arg))
2099
- }
2245
+ Expr::Ident { name, .. } if name == param_name => Some(Ok(arg)),
2100
2246
  // Property access: x.prop
2101
- Expr::Member { object, prop, optional, .. } => {
2247
+ Expr::Member {
2248
+ object,
2249
+ prop,
2250
+ optional,
2251
+ ..
2252
+ } => {
2102
2253
  if let Expr::Ident { name, .. } = object.as_ref() {
2103
2254
  if name == param_name {
2104
2255
  return self.eval_simple_member(&arg, prop, *optional);
@@ -2114,7 +2265,12 @@ impl Evaluator {
2114
2265
  }
2115
2266
 
2116
2267
  /// Evaluate a simple operand (identifier or literal).
2117
- fn eval_simple_operand(&self, expr: &Expr, param_name: &Arc<str>, param_val: &Value) -> Option<Value> {
2268
+ fn eval_simple_operand(
2269
+ &self,
2270
+ expr: &Expr,
2271
+ param_name: &Arc<str>,
2272
+ param_val: &Value,
2273
+ ) -> Option<Value> {
2118
2274
  match expr {
2119
2275
  Expr::Ident { name, .. } if name == param_name => Some(param_val.clone()),
2120
2276
  Expr::Literal { value, .. } => match value {
@@ -2128,20 +2284,27 @@ impl Evaluator {
2128
2284
  }
2129
2285
 
2130
2286
  /// Evaluate simple member access.
2131
- fn eval_simple_member(&self, obj: &Value, property: &MemberProp, _optional: bool) -> Option<Result<Value, EvalError>> {
2287
+ fn eval_simple_member(
2288
+ &self,
2289
+ obj: &Value,
2290
+ property: &MemberProp,
2291
+ _optional: bool,
2292
+ ) -> Option<Result<Value, EvalError>> {
2132
2293
  match property {
2133
- MemberProp::Name(name) => {
2134
- match obj {
2135
- Value::Object(o) => {
2136
- let result = o.borrow().get(name.as_ref()).cloned().unwrap_or(Value::Null);
2137
- Some(Ok(result))
2138
- }
2139
- Value::Array(arr) if name.as_ref() == "length" => {
2140
- Some(Ok(Value::Number(arr.borrow().len() as f64)))
2141
- }
2142
- _ => None,
2294
+ MemberProp::Name(name) => match obj {
2295
+ Value::Object(o) => {
2296
+ let result = o
2297
+ .borrow()
2298
+ .get(name.as_ref())
2299
+ .cloned()
2300
+ .unwrap_or(Value::Null);
2301
+ Some(Ok(result))
2302
+ }
2303
+ Value::Array(arr) if name.as_ref() == "length" => {
2304
+ Some(Ok(Value::Number(arr.borrow().len() as f64)))
2143
2305
  }
2144
- }
2306
+ _ => None,
2307
+ },
2145
2308
  _ => None,
2146
2309
  }
2147
2310
  }
@@ -2169,9 +2332,7 @@ impl Evaluator {
2169
2332
 
2170
2333
  fn call_func(&self, f: &Value, args: &[Value]) -> Result<Value, EvalError> {
2171
2334
  match f {
2172
- Value::Native(native_fn) => {
2173
- native_fn(args).map_err(EvalError::Error)
2174
- }
2335
+ Value::Native(native_fn) => native_fn(args).map_err(EvalError::Error),
2175
2336
  #[cfg(feature = "http")]
2176
2337
  Value::PromiseResolver(r) => {
2177
2338
  let value = args.first().cloned().unwrap_or(Value::Null);
@@ -2180,7 +2341,12 @@ impl Evaluator {
2180
2341
  .map_err(EvalError::Error)?;
2181
2342
  for reaction in reactions {
2182
2343
  match reaction {
2183
- crate::promise::Reaction::Then(on_fulfilled, on_rejected, ref resolve, ref reject) => {
2344
+ crate::promise::Reaction::Then(
2345
+ on_fulfilled,
2346
+ on_rejected,
2347
+ ref resolve,
2348
+ ref reject,
2349
+ ) => {
2184
2350
  let handler_result = if is_fulfilled {
2185
2351
  if let Some(ref h) = on_fulfilled {
2186
2352
  self.call_func(h, &[val.clone()])
@@ -2232,8 +2398,10 @@ impl Evaluator {
2232
2398
  #[cfg(feature = "http")]
2233
2399
  Value::Serve => self.run_http_server(args),
2234
2400
  Value::CoreFn(f) => {
2235
- let ca: Result<Vec<tishlang_core::Value>, String> =
2236
- args.iter().map(crate::value_convert::eval_to_core).collect();
2401
+ let ca: Result<Vec<tishlang_core::Value>, String> = args
2402
+ .iter()
2403
+ .map(crate::value_convert::eval_to_core)
2404
+ .collect();
2237
2405
  let ca = ca.map_err(EvalError::Error)?;
2238
2406
  Ok(crate::value_convert::core_to_eval(f(&ca)))
2239
2407
  }
@@ -2247,15 +2415,25 @@ impl Evaluator {
2247
2415
  Value::TimerBuiltin(name) => self.run_timer_builtin(name.as_ref(), args),
2248
2416
  Value::OpaqueMethod(opaque, method_name) => {
2249
2417
  let method = opaque.get_method(method_name.as_ref()).ok_or_else(|| {
2250
- EvalError::Error(format!("Method {} not found on {}", method_name, opaque.type_name()))
2418
+ EvalError::Error(format!(
2419
+ "Method {} not found on {}",
2420
+ method_name,
2421
+ opaque.type_name()
2422
+ ))
2251
2423
  })?;
2252
- let core_args: Result<Vec<tishlang_core::Value>, String> =
2253
- args.iter().map(crate::value_convert::eval_to_core).collect();
2424
+ let core_args: Result<Vec<tishlang_core::Value>, String> = args
2425
+ .iter()
2426
+ .map(crate::value_convert::eval_to_core)
2427
+ .collect();
2254
2428
  let core_args = core_args.map_err(EvalError::Error)?;
2255
2429
  let result = method(&core_args);
2256
2430
  Ok(crate::value_convert::core_to_eval(result))
2257
2431
  }
2258
- Value::Function { formals, rest_param, body } => {
2432
+ Value::Function {
2433
+ formals,
2434
+ rest_param,
2435
+ body,
2436
+ } => {
2259
2437
  let scope = Scope::child(Rc::clone(&self.scope));
2260
2438
  {
2261
2439
  let mut s = scope.borrow_mut();
@@ -2289,8 +2467,13 @@ impl Evaluator {
2289
2467
  }
2290
2468
  }
2291
2469
  if let Some(ref rest_name) = rest_param {
2292
- let rest_vals: Vec<Value> = args.iter().skip(formals.len()).cloned().collect();
2293
- s.set(Arc::clone(rest_name), Value::Array(Rc::new(RefCell::new(rest_vals))), true);
2470
+ let rest_vals: Vec<Value> =
2471
+ args.iter().skip(formals.len()).cloned().collect();
2472
+ s.set(
2473
+ Arc::clone(rest_name),
2474
+ Value::Array(Rc::new(RefCell::new(rest_vals))),
2475
+ true,
2476
+ );
2294
2477
  }
2295
2478
  }
2296
2479
  let mut eval = Evaluator {
@@ -2304,8 +2487,12 @@ impl Evaluator {
2304
2487
  Err(EvalError::Return(v)) => Ok(v),
2305
2488
  Err(EvalError::Throw(v)) => Err(EvalError::Throw(v)),
2306
2489
  Err(EvalError::Error(s)) => Err(EvalError::Error(s)),
2307
- Err(EvalError::Break) => Err(EvalError::Error("break outside loop".to_string())),
2308
- Err(EvalError::Continue) => Err(EvalError::Error("continue outside loop".to_string())),
2490
+ Err(EvalError::Break) => {
2491
+ Err(EvalError::Error("break outside loop".to_string()))
2492
+ }
2493
+ Err(EvalError::Continue) => {
2494
+ Err(EvalError::Error("continue outside loop".to_string()))
2495
+ }
2309
2496
  }
2310
2497
  }
2311
2498
  _ => Err(EvalError::Error("Not a function".to_string())),
@@ -2320,14 +2507,15 @@ impl Evaluator {
2320
2507
  args: &[Value],
2321
2508
  ) -> Result<Value, EvalError> {
2322
2509
  match method {
2323
- "then" => self.run_promise_then_core(
2324
- promise_ref,
2325
- args.first().cloned(),
2326
- args.get(1).cloned(),
2327
- ),
2510
+ "then" => {
2511
+ self.run_promise_then_core(promise_ref, args.first().cloned(), args.get(1).cloned())
2512
+ }
2328
2513
  "catch" => self.run_promise_then_core(promise_ref, None, args.first().cloned()),
2329
2514
  "finally" => self.run_promise_finally(promise_ref, args.first().cloned()),
2330
- _ => Err(EvalError::Error(format!("Unknown promise method: {}", method))),
2515
+ _ => Err(EvalError::Error(format!(
2516
+ "Unknown promise method: {}",
2517
+ method
2518
+ ))),
2331
2519
  }
2332
2520
  }
2333
2521
 
@@ -2428,7 +2616,12 @@ impl Evaluator {
2428
2616
  crate::promise::PromiseState::Pending { .. } => {
2429
2617
  crate::promise::add_reaction(
2430
2618
  state,
2431
- crate::promise::Reaction::Then(on_fulfilled, on_rejected, resolve.clone(), reject.clone()),
2619
+ crate::promise::Reaction::Then(
2620
+ on_fulfilled,
2621
+ on_rejected,
2622
+ resolve.clone(),
2623
+ reject.clone(),
2624
+ ),
2432
2625
  );
2433
2626
  }
2434
2627
  }
@@ -2537,8 +2730,11 @@ impl Evaluator {
2537
2730
  let port = port;
2538
2731
  std::thread::spawn(move || {
2539
2732
  std::thread::sleep(std::time::Duration::from_millis(50));
2540
- if let Ok(mut stream) = std::net::TcpStream::connect(format!("127.0.0.1:{}", port)) {
2541
- let _ = stream.write_all(b"GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n");
2733
+ if let Ok(mut stream) = std::net::TcpStream::connect(format!("127.0.0.1:{}", port))
2734
+ {
2735
+ let _ = stream.write_all(
2736
+ b"GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n",
2737
+ );
2542
2738
  let _ = stream.shutdown(std::net::Shutdown::Write);
2543
2739
  }
2544
2740
  });
@@ -2603,7 +2799,11 @@ impl Evaluator {
2603
2799
  tishlang_ast::DestructPattern::Array(elements) => {
2604
2800
  let arr = match value {
2605
2801
  Value::Array(a) => a.borrow().clone(),
2606
- _ => return Err(EvalError::Error("Cannot destructure non-array value".to_string())),
2802
+ _ => {
2803
+ return Err(EvalError::Error(
2804
+ "Cannot destructure non-array value".to_string(),
2805
+ ))
2806
+ }
2607
2807
  };
2608
2808
 
2609
2809
  for (i, elem) in elements.iter().enumerate() {
@@ -2633,7 +2833,11 @@ impl Evaluator {
2633
2833
  tishlang_ast::DestructPattern::Object(props) => {
2634
2834
  let obj = match value {
2635
2835
  Value::Object(o) => o.borrow().clone(),
2636
- _ => return Err(EvalError::Error("Cannot destructure non-object value".to_string())),
2836
+ _ => {
2837
+ return Err(EvalError::Error(
2838
+ "Cannot destructure non-object value".to_string(),
2839
+ ))
2840
+ }
2637
2841
  };
2638
2842
 
2639
2843
  for prop in props {
@@ -2657,7 +2861,12 @@ impl Evaluator {
2657
2861
  Ok(())
2658
2862
  }
2659
2863
 
2660
- fn bind_destruct_pattern(&mut self, pattern: &tishlang_ast::DestructPattern, value: &Value, mutable: bool) -> Result<(), EvalError> {
2864
+ fn bind_destruct_pattern(
2865
+ &mut self,
2866
+ pattern: &tishlang_ast::DestructPattern,
2867
+ value: &Value,
2868
+ mutable: bool,
2869
+ ) -> Result<(), EvalError> {
2661
2870
  Self::bind_destruct_pattern_scoped(&self.scope, pattern, value, mutable)
2662
2871
  }
2663
2872
 
@@ -2675,11 +2884,8 @@ impl Evaluator {
2675
2884
  Some(Value::Bool(b)) => tishlang_core::Value::Bool(*b),
2676
2885
  Some(_) => tishlang_core::Value::Number(0.0),
2677
2886
  };
2678
- let out = tishlang_builtins::string::last_index_of_str(
2679
- receiver.as_ref(),
2680
- search,
2681
- &position_core,
2682
- );
2887
+ let out =
2888
+ tishlang_builtins::string::last_index_of_str(receiver.as_ref(), search, &position_core);
2683
2889
  match out {
2684
2890
  tishlang_core::Value::Number(n) => Value::Number(n),
2685
2891
  _ => Value::Number(-1.0),
@@ -2963,7 +3169,9 @@ impl Evaluator {
2963
3169
  Ok((Value::Bool(false), rest))
2964
3170
  } else {
2965
3171
  let end = s
2966
- .find(|c: char| !c.is_ascii_digit() && c != '-' && c != '+' && c != '.' && c != 'e' && c != 'E')
3172
+ .find(|c: char| {
3173
+ !c.is_ascii_digit() && c != '-' && c != '+' && c != '.' && c != 'e' && c != 'E'
3174
+ })
2967
3175
  .unwrap_or(s.len());
2968
3176
  let num_str = &s[..end];
2969
3177
  let n: f64 = num_str.parse().map_err(|_| ())?;
@@ -2991,7 +3199,11 @@ impl Evaluator {
2991
3199
  .replace('\t', "\\t")
2992
3200
  ),
2993
3201
  Value::Array(arr) => {
2994
- let inner: Vec<String> = arr.borrow().iter().map(Self::json_stringify_value).collect();
3202
+ let inner: Vec<String> = arr
3203
+ .borrow()
3204
+ .iter()
3205
+ .map(Self::json_stringify_value)
3206
+ .collect();
2995
3207
  format!("[{}]", inner.join(","))
2996
3208
  }
2997
3209
  Value::Object(map) => {
@@ -3010,7 +3222,14 @@ impl Evaluator {
3010
3222
  })
3011
3223
  .collect();
3012
3224
  entries.sort_by(|a, b| a.0.cmp(&b.0));
3013
- format!("{{{}}}", entries.into_iter().map(|(_, s)| s).collect::<Vec<_>>().join(","))
3225
+ format!(
3226
+ "{{{}}}",
3227
+ entries
3228
+ .into_iter()
3229
+ .map(|(_, s)| s)
3230
+ .collect::<Vec<_>>()
3231
+ .join(",")
3232
+ )
3014
3233
  }
3015
3234
  Value::Function { .. } | Value::Native(_) => "null".to_string(),
3016
3235
  #[cfg(feature = "http")]
@@ -3021,7 +3240,8 @@ impl Evaluator {
3021
3240
  | Value::Promise(_)
3022
3241
  | Value::PromiseResolver(_)
3023
3242
  | Value::PromiseConstructor
3024
- | Value::BoundPromiseMethod(_, _) | Value::TimerBuiltin(_) => "null".to_string(),
3243
+ | Value::BoundPromiseMethod(_, _)
3244
+ | Value::TimerBuiltin(_) => "null".to_string(),
3025
3245
  #[cfg(feature = "regex")]
3026
3246
  Value::RegExp(_) => "null".to_string(),
3027
3247
  Value::Opaque(_) | Value::OpaqueMethod(_, _) => "null".to_string(),
@@ -3041,7 +3261,11 @@ impl Evaluator {
3041
3261
 
3042
3262
  fn object_keys(args: &[Value]) -> Result<Value, String> {
3043
3263
  if let Some(Value::Object(obj)) = args.first() {
3044
- let keys: Vec<Value> = obj.borrow().keys().map(|k| Value::String(Arc::clone(k))).collect();
3264
+ let keys: Vec<Value> = obj
3265
+ .borrow()
3266
+ .keys()
3267
+ .map(|k| Value::String(Arc::clone(k)))
3268
+ .collect();
3045
3269
  Ok(Value::Array(Rc::new(RefCell::new(keys))))
3046
3270
  } else {
3047
3271
  Ok(Value::Array(Rc::new(RefCell::new(Vec::new()))))
@@ -3059,12 +3283,16 @@ impl Evaluator {
3059
3283
 
3060
3284
  fn object_entries(args: &[Value]) -> Result<Value, String> {
3061
3285
  if let Some(Value::Object(obj)) = args.first() {
3062
- let entries: Vec<Value> = obj.borrow().iter().map(|(k, v)| {
3063
- Value::Array(Rc::new(RefCell::new(vec![
3064
- Value::String(Arc::clone(k)),
3065
- v.clone(),
3066
- ])))
3067
- }).collect();
3286
+ let entries: Vec<Value> = obj
3287
+ .borrow()
3288
+ .iter()
3289
+ .map(|(k, v)| {
3290
+ Value::Array(Rc::new(RefCell::new(vec![
3291
+ Value::String(Arc::clone(k)),
3292
+ v.clone(),
3293
+ ])))
3294
+ })
3295
+ .collect();
3068
3296
  Ok(Value::Array(Rc::new(RefCell::new(entries))))
3069
3297
  } else {
3070
3298
  Ok(Value::Array(Rc::new(RefCell::new(Vec::new()))))
@@ -3136,7 +3364,10 @@ impl Evaluator {
3136
3364
  .ok_or_else(|| "Promise.all requires an iterable".to_string())?;
3137
3365
  let values: Vec<Value> = match iterable {
3138
3366
  Value::Array(arr) => arr.borrow().clone(),
3139
- Value::String(s) => s.chars().map(|c| Value::String(c.to_string().into())).collect(),
3367
+ Value::String(s) => s
3368
+ .chars()
3369
+ .map(|c| Value::String(c.to_string().into()))
3370
+ .collect(),
3140
3371
  _ => return Err("Promise.all requires array or iterable".to_string()),
3141
3372
  };
3142
3373
  let mut results = Vec::with_capacity(values.len());
@@ -3146,7 +3377,8 @@ impl Evaluator {
3146
3377
  crate::promise::PromiseAwaitResult::Fulfilled(x) => results.push(x),
3147
3378
  crate::promise::PromiseAwaitResult::Rejected(x) => {
3148
3379
  let (promise, resolve_val, reject_val) = crate::promise::create_promise();
3149
- let (_, reject) = crate::promise::extract_resolvers(&resolve_val, &reject_val);
3380
+ let (_, reject) =
3381
+ crate::promise::extract_resolvers(&resolve_val, &reject_val);
3150
3382
  let _ = crate::promise::settle_promise(&reject, x, false);
3151
3383
  return Ok(promise);
3152
3384
  }
@@ -3157,7 +3389,8 @@ impl Evaluator {
3157
3389
  Ok(x) => results.push(crate::value_convert::core_to_eval(x)),
3158
3390
  Err(x) => {
3159
3391
  let (promise, resolve_val, reject_val) = crate::promise::create_promise();
3160
- let (_, reject) = crate::promise::extract_resolvers(&resolve_val, &reject_val);
3392
+ let (_, reject) =
3393
+ crate::promise::extract_resolvers(&resolve_val, &reject_val);
3161
3394
  let _ = crate::promise::settle_promise(
3162
3395
  &reject,
3163
3396
  crate::value_convert::core_to_eval(x),
@@ -3184,7 +3417,10 @@ impl Evaluator {
3184
3417
  .ok_or_else(|| "Promise.race requires an iterable".to_string())?;
3185
3418
  let values: Vec<Value> = match iterable {
3186
3419
  Value::Array(arr) => arr.borrow().clone(),
3187
- Value::String(s) => s.chars().map(|c| Value::String(c.to_string().into())).collect(),
3420
+ Value::String(s) => s
3421
+ .chars()
3422
+ .map(|c| Value::String(c.to_string().into()))
3423
+ .collect(),
3188
3424
  _ => return Err("Promise.race requires array or iterable".to_string()),
3189
3425
  };
3190
3426
  for v in values {
@@ -3192,7 +3428,8 @@ impl Evaluator {
3192
3428
  match p.block_until_settled() {
3193
3429
  Ok(x) => {
3194
3430
  let (promise, resolve_val, reject_val) = crate::promise::create_promise();
3195
- let (resolve, _) = crate::promise::extract_resolvers(&resolve_val, &reject_val);
3431
+ let (resolve, _) =
3432
+ crate::promise::extract_resolvers(&resolve_val, &reject_val);
3196
3433
  crate::promise::settle_promise(
3197
3434
  &resolve,
3198
3435
  crate::value_convert::core_to_eval(x),
@@ -3202,7 +3439,8 @@ impl Evaluator {
3202
3439
  }
3203
3440
  Err(x) => {
3204
3441
  let (promise, resolve_val, reject_val) = crate::promise::create_promise();
3205
- let (_, reject) = crate::promise::extract_resolvers(&resolve_val, &reject_val);
3442
+ let (_, reject) =
3443
+ crate::promise::extract_resolvers(&resolve_val, &reject_val);
3206
3444
  crate::promise::settle_promise(
3207
3445
  &reject,
3208
3446
  crate::value_convert::core_to_eval(x),
@@ -3216,13 +3454,15 @@ impl Evaluator {
3216
3454
  match crate::promise::block_until_settled(p) {
3217
3455
  crate::promise::PromiseAwaitResult::Fulfilled(x) => {
3218
3456
  let (promise, resolve_val, reject_val) = crate::promise::create_promise();
3219
- let (resolve, _) = crate::promise::extract_resolvers(&resolve_val, &reject_val);
3457
+ let (resolve, _) =
3458
+ crate::promise::extract_resolvers(&resolve_val, &reject_val);
3220
3459
  crate::promise::settle_promise(&resolve, x, true)?;
3221
3460
  return Ok(promise);
3222
3461
  }
3223
3462
  crate::promise::PromiseAwaitResult::Rejected(x) => {
3224
3463
  let (promise, resolve_val, reject_val) = crate::promise::create_promise();
3225
- let (_, reject) = crate::promise::extract_resolvers(&resolve_val, &reject_val);
3464
+ let (_, reject) =
3465
+ crate::promise::extract_resolvers(&resolve_val, &reject_val);
3226
3466
  crate::promise::settle_promise(&reject, x, false)?;
3227
3467
  return Ok(promise);
3228
3468
  }
@@ -3239,7 +3479,9 @@ impl Evaluator {
3239
3479
  for a in args {
3240
3480
  cv.push(crate::value_convert::eval_to_core(a)?);
3241
3481
  }
3242
- Ok(crate::value_convert::core_to_eval(tishlang_runtime::web_socket_client(&cv)))
3482
+ Ok(crate::value_convert::core_to_eval(
3483
+ tishlang_runtime::web_socket_client(&cv),
3484
+ ))
3243
3485
  }
3244
3486
 
3245
3487
  #[cfg(feature = "ws")]
@@ -3248,7 +3490,9 @@ impl Evaluator {
3248
3490
  for a in args {
3249
3491
  cv.push(crate::value_convert::eval_to_core(a)?);
3250
3492
  }
3251
- Ok(crate::value_convert::core_to_eval(tishlang_runtime::web_socket_server_construct(&cv)))
3493
+ Ok(crate::value_convert::core_to_eval(
3494
+ tishlang_runtime::web_socket_server_construct(&cv),
3495
+ ))
3252
3496
  }
3253
3497
 
3254
3498
  #[cfg(feature = "ws")]
@@ -3256,7 +3500,9 @@ impl Evaluator {
3256
3500
  let conn = args.first().ok_or("wsSend(conn, data) requires conn")?;
3257
3501
  let conn_core = crate::value_convert::eval_to_core(conn)?;
3258
3502
  let data = args.get(1).map(|v| v.to_string()).unwrap_or_default();
3259
- Ok(Value::Bool(tishlang_runtime::ws_send_native(&conn_core, &data)))
3503
+ Ok(Value::Bool(tishlang_runtime::ws_send_native(
3504
+ &conn_core, &data,
3505
+ )))
3260
3506
  }
3261
3507
 
3262
3508
  #[cfg(feature = "ws")]
@@ -3265,7 +3511,9 @@ impl Evaluator {
3265
3511
  for a in args {
3266
3512
  cv.push(crate::value_convert::eval_to_core(a)?);
3267
3513
  }
3268
- Ok(crate::value_convert::core_to_eval(tishlang_runtime::ws_broadcast_native(&cv)))
3514
+ Ok(crate::value_convert::core_to_eval(
3515
+ tishlang_runtime::ws_broadcast_native(&cv),
3516
+ ))
3269
3517
  }
3270
3518
 
3271
3519
  #[cfg(feature = "http")]
@@ -3319,7 +3567,6 @@ impl Evaluator {
3319
3567
  "await requires the http feature".to_string(),
3320
3568
  ))
3321
3569
  }
3322
-
3323
3570
  }
3324
3571
 
3325
3572
  #[derive(Debug)]