@tishlang/tish 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) 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 +67 -0
  10. package/crates/tish/tests/fixtures/cargo_example_project/Cargo.toml +3 -0
  11. package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/Cargo.toml +11 -0
  12. package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/src/lib.rs +12 -0
  13. package/crates/tish/tests/fixtures/cargo_example_project/package.json +10 -0
  14. package/crates/tish/tests/fixtures/cargo_example_project/src/main.tish +3 -0
  15. package/crates/tish/tests/integration_test.rs +197 -47
  16. package/crates/tish/tests/run_optimize_stdout_parity.rs +3 -7
  17. package/crates/tish/tests/shortcircuit.rs +19 -4
  18. package/crates/tish_ast/src/ast.rs +12 -14
  19. package/crates/tish_build_utils/src/lib.rs +64 -6
  20. package/crates/tish_builtins/src/array.rs +52 -21
  21. package/crates/tish_builtins/src/construct.rs +2 -8
  22. package/crates/tish_builtins/src/globals.rs +30 -15
  23. package/crates/tish_builtins/src/lib.rs +5 -5
  24. package/crates/tish_builtins/src/math.rs +5 -3
  25. package/crates/tish_builtins/src/string.rs +71 -19
  26. package/crates/tish_bytecode/src/chunk.rs +0 -1
  27. package/crates/tish_bytecode/src/compiler.rs +164 -60
  28. package/crates/tish_bytecode/src/opcode.rs +13 -4
  29. package/crates/tish_bytecode/src/peephole.rs +2 -2
  30. package/crates/tish_compile/Cargo.toml +1 -0
  31. package/crates/tish_compile/src/codegen.rs +989 -318
  32. package/crates/tish_compile/src/infer.rs +69 -19
  33. package/crates/tish_compile/src/lib.rs +21 -8
  34. package/crates/tish_compile/src/resolve.rs +515 -94
  35. package/crates/tish_compile/src/types.rs +10 -14
  36. package/crates/tish_compile_js/src/codegen.rs +34 -13
  37. package/crates/tish_compile_js/src/tests_jsx.rs +30 -6
  38. package/crates/tish_compiler_wasm/src/lib.rs +16 -13
  39. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +40 -48
  40. package/crates/tish_core/src/json.rs +5 -3
  41. package/crates/tish_core/src/lib.rs +1 -1
  42. package/crates/tish_core/src/uri.rs +9 -6
  43. package/crates/tish_core/src/value.rs +92 -28
  44. package/crates/tish_cranelift/src/link.rs +6 -9
  45. package/crates/tish_cranelift/src/lower.rs +14 -8
  46. package/crates/tish_eval/src/eval.rs +398 -141
  47. package/crates/tish_eval/src/lib.rs +10 -6
  48. package/crates/tish_eval/src/natives.rs +95 -38
  49. package/crates/tish_eval/src/promise.rs +14 -8
  50. package/crates/tish_eval/src/timers.rs +28 -19
  51. package/crates/tish_eval/src/value.rs +10 -3
  52. package/crates/tish_fmt/src/lib.rs +29 -13
  53. package/crates/tish_lexer/src/lib.rs +217 -63
  54. package/crates/tish_lexer/src/token.rs +6 -6
  55. package/crates/tish_llvm/src/lib.rs +15 -8
  56. package/crates/tish_lsp/src/main.rs +41 -43
  57. package/crates/tish_native/src/build.rs +38 -15
  58. package/crates/tish_native/src/lib.rs +76 -32
  59. package/crates/tish_opt/src/lib.rs +67 -50
  60. package/crates/tish_parser/src/lib.rs +36 -11
  61. package/crates/tish_parser/src/parser.rs +172 -87
  62. package/crates/tish_runtime/src/http.rs +15 -6
  63. package/crates/tish_runtime/src/http_fetch.rs +24 -14
  64. package/crates/tish_runtime/src/lib.rs +224 -168
  65. package/crates/tish_runtime/src/promise.rs +1 -5
  66. package/crates/tish_runtime/src/ws.rs +45 -20
  67. package/crates/tish_runtime/tests/fetch_readable_stream.rs +5 -4
  68. package/crates/tish_ui/src/jsx.rs +41 -22
  69. package/crates/tish_ui/src/lib.rs +2 -2
  70. package/crates/tish_vm/src/vm.rs +320 -116
  71. package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +8 -3
  72. package/crates/tish_wasm/src/lib.rs +38 -28
  73. package/crates/tishlang_cargo_bindgen/Cargo.toml +25 -0
  74. package/crates/tishlang_cargo_bindgen/src/classify.rs +265 -0
  75. package/crates/tishlang_cargo_bindgen/src/discover.rs +52 -0
  76. package/crates/tishlang_cargo_bindgen/src/infer.rs +372 -0
  77. package/crates/tishlang_cargo_bindgen/src/lib.rs +349 -0
  78. package/crates/tishlang_cargo_bindgen/src/main.rs +164 -0
  79. package/crates/tishlang_cargo_bindgen/src/metadata.rs +114 -0
  80. package/package.json +1 -1
  81. package/platform/darwin-arm64/tish +0 -0
  82. package/platform/darwin-x64/tish +0 -0
  83. package/platform/linux-arm64/tish +0 -0
  84. package/platform/linux-x64/tish +0 -0
  85. package/platform/win32-x64/tish.exe +0 -0
@@ -3,15 +3,15 @@
3
3
  mod eval;
4
4
  #[cfg(feature = "http")]
5
5
  mod http;
6
- pub mod value_convert;
6
+ mod natives;
7
7
  #[cfg(feature = "http")]
8
8
  mod promise;
9
- #[cfg(feature = "http")]
10
- mod timers;
11
- mod natives;
12
9
  #[cfg(feature = "regex")]
13
10
  pub mod regex;
11
+ #[cfg(feature = "http")]
12
+ mod timers;
14
13
  mod value;
14
+ pub mod value_convert;
15
15
 
16
16
  pub use eval::Evaluator;
17
17
  pub use value::PropMap;
@@ -51,11 +51,15 @@ pub fn format_value_for_console(value: &Value, colors: bool) -> String {
51
51
  }
52
52
 
53
53
  /// Run a Tish file with import/export support. Resolves relative imports from the file's directory.
54
- pub fn run_file(path: &std::path::Path, project_root: Option<&std::path::Path>) -> Result<Value, String> {
54
+ pub fn run_file(
55
+ path: &std::path::Path,
56
+ project_root: Option<&std::path::Path>,
57
+ ) -> Result<Value, String> {
55
58
  let path = path
56
59
  .canonicalize()
57
60
  .map_err(|e| format!("Cannot canonicalize {}: {}", path.display(), e))?;
58
- let source = std::fs::read_to_string(&path).map_err(|e| format!("Cannot read {}: {}", path.display(), e))?;
61
+ let source = std::fs::read_to_string(&path)
62
+ .map_err(|e| format!("Cannot read {}: {}", path.display(), e))?;
59
63
  let program = tishlang_parser::parse(&source)?;
60
64
  let mut eval = Evaluator::new();
61
65
  eval.set_current_dir(project_root.or(path.parent()));
@@ -57,16 +57,21 @@ fn get_log_level() -> u8 {
57
57
  pub fn parse_int(args: &[Value]) -> Result<Value, String> {
58
58
  let s = args.first().map(|v| v.to_string()).unwrap_or_default();
59
59
  let s = s.trim();
60
- let radix = args.get(1).and_then(|v| match v {
61
- Value::Number(n) => Some(*n as i32),
62
- _ => None,
63
- }).unwrap_or(10);
60
+ let radix = args
61
+ .get(1)
62
+ .and_then(|v| match v {
63
+ Value::Number(n) => Some(*n as i32),
64
+ _ => None,
65
+ })
66
+ .unwrap_or(10);
64
67
  let n = if (2..=36).contains(&radix) {
65
68
  let prefix: String = s
66
69
  .chars()
67
70
  .take_while(|c| *c == '-' || *c == '+' || c.is_digit(radix as u32))
68
71
  .collect();
69
- i64::from_str_radix(&prefix, radix as u32).ok().map(|n| n as f64)
72
+ i64::from_str_radix(&prefix, radix as u32)
73
+ .ok()
74
+ .map(|n| n as f64)
70
75
  } else {
71
76
  None
72
77
  };
@@ -80,12 +85,16 @@ pub fn parse_float(args: &[Value]) -> Result<Value, String> {
80
85
  }
81
86
 
82
87
  pub fn is_finite(args: &[Value]) -> Result<Value, String> {
83
- let b = args.first().is_some_and(|v| matches!(v, Value::Number(n) if n.is_finite()));
88
+ let b = args
89
+ .first()
90
+ .is_some_and(|v| matches!(v, Value::Number(n) if n.is_finite()));
84
91
  Ok(Value::Bool(b))
85
92
  }
86
93
 
87
94
  pub fn is_nan(args: &[Value]) -> Result<Value, String> {
88
- let b = args.first().is_none_or(|v| matches!(v, Value::Number(n) if n.is_nan()) || !matches!(v, Value::Number(_)));
95
+ let b = args.first().is_none_or(|v| {
96
+ matches!(v, Value::Number(n) if n.is_nan()) || !matches!(v, Value::Number(_))
97
+ });
89
98
  Ok(Value::Bool(b))
90
99
  }
91
100
 
@@ -96,7 +105,9 @@ pub fn boolean_native(args: &[Value]) -> Result<Value, String> {
96
105
 
97
106
  pub fn decode_uri(args: &[Value]) -> Result<Value, String> {
98
107
  let s = args.first().map(|v| v.to_string()).unwrap_or_default();
99
- Ok(Value::String(tishlang_core::percent_decode(&s).unwrap_or(s).into()))
108
+ Ok(Value::String(
109
+ tishlang_core::percent_decode(&s).unwrap_or(s).into(),
110
+ ))
100
111
  }
101
112
 
102
113
  pub fn encode_uri(args: &[Value]) -> Result<Value, String> {
@@ -105,41 +116,61 @@ pub fn encode_uri(args: &[Value]) -> Result<Value, String> {
105
116
  }
106
117
 
107
118
  pub fn math_abs(args: &[Value]) -> Result<Value, String> {
108
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).abs()))
119
+ Ok(Value::Number(
120
+ get_num(args.first().unwrap_or(&Value::Null)).abs(),
121
+ ))
109
122
  }
110
123
 
111
124
  pub fn math_sqrt(args: &[Value]) -> Result<Value, String> {
112
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).sqrt()))
125
+ Ok(Value::Number(
126
+ get_num(args.first().unwrap_or(&Value::Null)).sqrt(),
127
+ ))
113
128
  }
114
129
 
115
130
  pub fn math_min(args: &[Value]) -> Result<Value, String> {
116
- let nums: Vec<f64> = args.iter().filter_map(|v| match v {
117
- Value::Number(n) => Some(*n),
118
- _ => None,
119
- }).collect();
131
+ let nums: Vec<f64> = args
132
+ .iter()
133
+ .filter_map(|v| match v {
134
+ Value::Number(n) => Some(*n),
135
+ _ => None,
136
+ })
137
+ .collect();
120
138
  let n = nums.into_iter().fold(f64::INFINITY, f64::min);
121
139
  Ok(Value::Number(if n == f64::INFINITY { f64::NAN } else { n }))
122
140
  }
123
141
 
124
142
  pub fn math_max(args: &[Value]) -> Result<Value, String> {
125
- let nums: Vec<f64> = args.iter().filter_map(|v| match v {
126
- Value::Number(n) => Some(*n),
127
- _ => None,
128
- }).collect();
143
+ let nums: Vec<f64> = args
144
+ .iter()
145
+ .filter_map(|v| match v {
146
+ Value::Number(n) => Some(*n),
147
+ _ => None,
148
+ })
149
+ .collect();
129
150
  let n = nums.into_iter().fold(f64::NEG_INFINITY, f64::max);
130
- Ok(Value::Number(if n == f64::NEG_INFINITY { f64::NAN } else { n }))
151
+ Ok(Value::Number(if n == f64::NEG_INFINITY {
152
+ f64::NAN
153
+ } else {
154
+ n
155
+ }))
131
156
  }
132
157
 
133
158
  pub fn math_floor(args: &[Value]) -> Result<Value, String> {
134
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).floor()))
159
+ Ok(Value::Number(
160
+ get_num(args.first().unwrap_or(&Value::Null)).floor(),
161
+ ))
135
162
  }
136
163
 
137
164
  pub fn math_ceil(args: &[Value]) -> Result<Value, String> {
138
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).ceil()))
165
+ Ok(Value::Number(
166
+ get_num(args.first().unwrap_or(&Value::Null)).ceil(),
167
+ ))
139
168
  }
140
169
 
141
170
  pub fn math_round(args: &[Value]) -> Result<Value, String> {
142
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).round()))
171
+ Ok(Value::Number(
172
+ get_num(args.first().unwrap_or(&Value::Null)).round(),
173
+ ))
143
174
  }
144
175
 
145
176
  pub fn math_random(_args: &[Value]) -> Result<Value, String> {
@@ -156,33 +187,53 @@ pub fn math_pow(args: &[Value]) -> Result<Value, String> {
156
187
  }
157
188
 
158
189
  pub fn math_sin(args: &[Value]) -> Result<Value, String> {
159
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).sin()))
190
+ Ok(Value::Number(
191
+ get_num(args.first().unwrap_or(&Value::Null)).sin(),
192
+ ))
160
193
  }
161
194
 
162
195
  pub fn math_cos(args: &[Value]) -> Result<Value, String> {
163
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).cos()))
196
+ Ok(Value::Number(
197
+ get_num(args.first().unwrap_or(&Value::Null)).cos(),
198
+ ))
164
199
  }
165
200
 
166
201
  pub fn math_tan(args: &[Value]) -> Result<Value, String> {
167
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).tan()))
202
+ Ok(Value::Number(
203
+ get_num(args.first().unwrap_or(&Value::Null)).tan(),
204
+ ))
168
205
  }
169
206
 
170
207
  pub fn math_log(args: &[Value]) -> Result<Value, String> {
171
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).ln()))
208
+ Ok(Value::Number(
209
+ get_num(args.first().unwrap_or(&Value::Null)).ln(),
210
+ ))
172
211
  }
173
212
 
174
213
  pub fn math_exp(args: &[Value]) -> Result<Value, String> {
175
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).exp()))
214
+ Ok(Value::Number(
215
+ get_num(args.first().unwrap_or(&Value::Null)).exp(),
216
+ ))
176
217
  }
177
218
 
178
219
  pub fn math_sign(args: &[Value]) -> Result<Value, String> {
179
220
  let n = get_num(args.first().unwrap_or(&Value::Null));
180
- let sign = if n.is_nan() { f64::NAN } else if n > 0.0 { 1.0 } else if n < 0.0 { -1.0 } else { 0.0 };
221
+ let sign = if n.is_nan() {
222
+ f64::NAN
223
+ } else if n > 0.0 {
224
+ 1.0
225
+ } else if n < 0.0 {
226
+ -1.0
227
+ } else {
228
+ 0.0
229
+ };
181
230
  Ok(Value::Number(sign))
182
231
  }
183
232
 
184
233
  pub fn math_trunc(args: &[Value]) -> Result<Value, String> {
185
- Ok(Value::Number(get_num(args.first().unwrap_or(&Value::Null)).trunc()))
234
+ Ok(Value::Number(
235
+ get_num(args.first().unwrap_or(&Value::Null)).trunc(),
236
+ ))
186
237
  }
187
238
 
188
239
  pub fn date_now(_args: &[Value]) -> Result<Value, String> {
@@ -199,19 +250,25 @@ pub fn array_is_array(args: &[Value]) -> Result<Value, String> {
199
250
  }
200
251
 
201
252
  pub fn string_from_char_code(args: &[Value]) -> Result<Value, String> {
202
- let s: String = args.iter().filter_map(|v| match v {
203
- Value::Number(n) => Some(char::from_u32(*n as u32).unwrap_or('\u{FFFD}')),
204
- _ => None,
205
- }).collect();
253
+ let s: String = args
254
+ .iter()
255
+ .filter_map(|v| match v {
256
+ Value::Number(n) => Some(char::from_u32(*n as u32).unwrap_or('\u{FFFD}')),
257
+ _ => None,
258
+ })
259
+ .collect();
206
260
  Ok(Value::String(s.into()))
207
261
  }
208
262
 
209
263
  #[cfg(feature = "process")]
210
264
  pub fn process_exit(args: &[Value]) -> Result<Value, String> {
211
- let code = args.first().and_then(|v| match v {
212
- Value::Number(n) => Some(*n as i32),
213
- _ => None,
214
- }).unwrap_or(0);
265
+ let code = args
266
+ .first()
267
+ .and_then(|v| match v {
268
+ Value::Number(n) => Some(*n as i32),
269
+ _ => None,
270
+ })
271
+ .unwrap_or(0);
215
272
  std::process::exit(code);
216
273
  }
217
274
 
@@ -274,7 +331,7 @@ pub fn is_dir(args: &[Value]) -> Result<Value, String> {
274
331
  pub fn read_dir(args: &[Value]) -> Result<Value, String> {
275
332
  use std::cell::RefCell;
276
333
  use std::rc::Rc;
277
-
334
+
278
335
  let path = args.first().map(|v| v.to_string()).unwrap_or_default();
279
336
  match std::fs::read_dir(&path) {
280
337
  Ok(entries) => {
@@ -116,7 +116,11 @@ pub fn settle_promise(
116
116
  }
117
117
  };
118
118
  if let Some(tx) = tx {
119
- let result = if is_resolve { Ok(value.clone()) } else { Err(value.clone()) };
119
+ let result = if is_resolve {
120
+ Ok(value.clone())
121
+ } else {
122
+ Err(value.clone())
123
+ };
120
124
  let _ = tx.send(result);
121
125
  }
122
126
  Ok((value, is_resolve, reactions))
@@ -134,7 +138,9 @@ pub fn add_reaction(state: &PromiseStateRef, reaction: Reaction) {
134
138
  impl Clone for Reaction {
135
139
  fn clone(&self) -> Self {
136
140
  match self {
137
- Reaction::Then(a, b, r1, r2) => Reaction::Then(a.clone(), b.clone(), r1.clone(), r2.clone()),
141
+ Reaction::Then(a, b, r1, r2) => {
142
+ Reaction::Then(a.clone(), b.clone(), r1.clone(), r2.clone())
143
+ }
138
144
  Reaction::Finally(f, r1, r2) => Reaction::Finally(f.clone(), r1.clone(), r2.clone()),
139
145
  }
140
146
  }
@@ -156,18 +162,18 @@ pub fn block_until_settled(promise_ref: &PromiseRef) -> PromiseAwaitResult {
156
162
  match result {
157
163
  Ok(Ok(v)) => PromiseAwaitResult::Fulfilled(v),
158
164
  Ok(Err(v)) => PromiseAwaitResult::Rejected(v),
159
- Err(_) => PromiseAwaitResult::Error(
160
- "Promise channel dropped before settlement".to_string(),
161
- ),
165
+ Err(_) => {
166
+ PromiseAwaitResult::Error("Promise channel dropped before settlement".to_string())
167
+ }
162
168
  }
163
169
  } else {
164
170
  let state = promise_ref.state.borrow();
165
171
  match &*state {
166
172
  PromiseState::Fulfilled(v) => PromiseAwaitResult::Fulfilled(v.clone()),
167
173
  PromiseState::Rejected(v) => PromiseAwaitResult::Rejected(v.clone()),
168
- PromiseState::Pending { .. } => PromiseAwaitResult::Error(
169
- "Promise receiver already consumed".to_string(),
170
- ),
174
+ PromiseState::Pending { .. } => {
175
+ PromiseAwaitResult::Error("Promise receiver already consumed".to_string())
176
+ }
171
177
  }
172
178
  }
173
179
  }
@@ -4,8 +4,8 @@
4
4
 
5
5
  use std::cell::RefCell;
6
6
  use std::collections::HashMap;
7
- use std::time::{Duration, Instant};
8
7
  use std::sync::atomic::{AtomicU64, Ordering};
8
+ use std::time::{Duration, Instant};
9
9
 
10
10
  use crate::value::Value;
11
11
 
@@ -32,12 +32,15 @@ pub fn setTimeout(callback: Value, args: Vec<Value>, delay_ms: u64) -> u64 {
32
32
  let id = next_id();
33
33
  let due = Instant::now() + Duration::from_millis(delay_ms);
34
34
  REGISTRY.with(|r| {
35
- r.borrow_mut().insert(id, TimerEntry {
36
- due,
37
- callback,
38
- args,
39
- interval_ms: 0,
40
- });
35
+ r.borrow_mut().insert(
36
+ id,
37
+ TimerEntry {
38
+ due,
39
+ callback,
40
+ args,
41
+ interval_ms: 0,
42
+ },
43
+ );
41
44
  });
42
45
  id
43
46
  }
@@ -48,12 +51,15 @@ pub fn setInterval(callback: Value, args: Vec<Value>, delay_ms: u64) -> u64 {
48
51
  let id = next_id();
49
52
  let due = Instant::now() + Duration::from_millis(delay_ms);
50
53
  REGISTRY.with(|r| {
51
- r.borrow_mut().insert(id, TimerEntry {
52
- due,
53
- callback,
54
- args,
55
- interval_ms: delay_ms,
56
- });
54
+ r.borrow_mut().insert(
55
+ id,
56
+ TimerEntry {
57
+ due,
58
+ callback,
59
+ args,
60
+ interval_ms: delay_ms,
61
+ },
62
+ );
57
63
  });
58
64
  id
59
65
  }
@@ -88,12 +94,15 @@ pub fn take_due_timers() -> Vec<(u64, Value, Vec<Value>, u64)> {
88
94
  pub fn re_register_interval(id: u64, callback: Value, args: Vec<Value>, interval_ms: u64) {
89
95
  let due = Instant::now() + Duration::from_millis(interval_ms);
90
96
  REGISTRY.with(|r| {
91
- r.borrow_mut().insert(id, TimerEntry {
92
- due,
93
- callback,
94
- args,
95
- interval_ms,
96
- });
97
+ r.borrow_mut().insert(
98
+ id,
99
+ TimerEntry {
100
+ due,
101
+ callback,
102
+ args,
103
+ interval_ms,
104
+ },
105
+ );
97
106
  });
98
107
  }
99
108
 
@@ -15,9 +15,9 @@ use tishlang_core::NativeFn as CoreNativeFn;
15
15
 
16
16
  /// Property map for interpreter `Value::Object` (uses `eval::Value`, not `tishlang_core::Value`).
17
17
  pub type PropMap = AHashMap<Arc<str>, Value>;
18
+ use tishlang_core::TishOpaque;
18
19
  #[cfg(feature = "http")]
19
20
  use tishlang_core::TishPromise;
20
- use tishlang_core::TishOpaque;
21
21
 
22
22
  #[cfg(feature = "http")]
23
23
  pub use crate::promise::PromiseResolver;
@@ -88,7 +88,12 @@ impl std::fmt::Debug for Value {
88
88
  #[cfg(feature = "http")]
89
89
  Value::Serve => write!(f, "Serve"),
90
90
  #[cfg(feature = "regex")]
91
- Value::RegExp(re) => write!(f, "RegExp(/{}/{})", re.borrow().source, re.borrow().flags_string()),
91
+ Value::RegExp(re) => write!(
92
+ f,
93
+ "RegExp(/{}/{})",
94
+ re.borrow().source,
95
+ re.borrow().flags_string()
96
+ ),
92
97
  #[cfg(feature = "http")]
93
98
  Value::Promise(_) => write!(f, "Promise"),
94
99
  #[cfg(feature = "http")]
@@ -187,7 +192,9 @@ impl Value {
187
192
  (Value::Array(a), Value::Array(b)) => Rc::ptr_eq(a, b),
188
193
  (Value::Object(a), Value::Object(b)) => Rc::ptr_eq(a, b),
189
194
  (Value::Opaque(a), Value::Opaque(b)) => Arc::ptr_eq(a, b),
190
- (Value::OpaqueMethod(a, ak), Value::OpaqueMethod(b, bk)) => Arc::ptr_eq(a, b) && ak == bk,
195
+ (Value::OpaqueMethod(a, ak), Value::OpaqueMethod(b, bk)) => {
196
+ Arc::ptr_eq(a, b) && ak == bk
197
+ }
191
198
  _ => false,
192
199
  }
193
200
  }
@@ -2,9 +2,9 @@
2
2
 
3
3
  use tishlang_ast::{
4
4
  ArrayElement, ArrowBody, BinOp, CallArg, CompoundOp, DestructElement, DestructPattern,
5
- ExportDeclaration, Expr, FunParam, ImportSpecifier, JsxAttrValue, JsxChild, JsxProp,
6
- Literal, LogicalAssignOp, MemberProp, ObjectProp, Program, Statement, TypeAnnotation,
7
- TypedParam, UnaryOp,
5
+ ExportDeclaration, Expr, FunParam, ImportSpecifier, JsxAttrValue, JsxChild, JsxProp, Literal,
6
+ LogicalAssignOp, MemberProp, ObjectProp, Program, Statement, TypeAnnotation, TypedParam,
7
+ UnaryOp,
8
8
  };
9
9
 
10
10
  /// Format Tish source. On parse error, returns the parser message.
@@ -79,7 +79,10 @@ impl Printer {
79
79
  }
80
80
  }
81
81
  Statement::VarDeclDestructure {
82
- pattern, mutable, init, ..
82
+ pattern,
83
+ mutable,
84
+ init,
85
+ ..
83
86
  } => {
84
87
  self.indent(level);
85
88
  self.buf.push_str(if *mutable { "let " } else { "const " });
@@ -267,7 +270,9 @@ impl Printer {
267
270
  self.stmt_inline_or_block(fb, level);
268
271
  }
269
272
  }
270
- Statement::Import { specifiers, from, .. } => {
273
+ Statement::Import {
274
+ specifiers, from, ..
275
+ } => {
271
276
  self.indent(level);
272
277
  self.buf.push_str("import ");
273
278
  self.import_specs(specifiers);
@@ -279,8 +284,15 @@ impl Printer {
279
284
  self.buf.push_str("export ");
280
285
  match declaration.as_ref() {
281
286
  ExportDeclaration::Named(inner) => {
282
- if let Statement::FunDecl { async_, name, params, rest_param, return_type, body, .. } =
283
- inner.as_ref()
287
+ if let Statement::FunDecl {
288
+ async_,
289
+ name,
290
+ params,
291
+ rest_param,
292
+ return_type,
293
+ body,
294
+ ..
295
+ } = inner.as_ref()
284
296
  {
285
297
  if *async_ {
286
298
  self.buf.push_str("async ");
@@ -536,7 +548,9 @@ impl Printer {
536
548
  Literal::Null => self.buf.push_str("null"),
537
549
  },
538
550
  Expr::Ident { name, .. } => self.buf.push_str(name.as_ref()),
539
- Expr::Binary { left, op, right, .. } => {
551
+ Expr::Binary {
552
+ left, op, right, ..
553
+ } => {
540
554
  self.expr(left);
541
555
  self.buf.push(' ');
542
556
  self.buf.push_str(binop(*op));
@@ -704,12 +718,16 @@ impl Printer {
704
718
  self.buf.push_str("--");
705
719
  self.buf.push_str(name.as_ref());
706
720
  }
707
- Expr::CompoundAssign { name, op, value, .. } => {
721
+ Expr::CompoundAssign {
722
+ name, op, value, ..
723
+ } => {
708
724
  self.buf.push_str(name.as_ref());
709
725
  self.buf.push_str(compound(*op));
710
726
  self.expr(value);
711
727
  }
712
- Expr::LogicalAssign { name, op, value, .. } => {
728
+ Expr::LogicalAssign {
729
+ name, op, value, ..
730
+ } => {
713
731
  self.buf.push_str(name.as_ref());
714
732
  self.buf.push_str(logical_assign(*op));
715
733
  self.expr(value);
@@ -830,9 +848,7 @@ impl Printer {
830
848
  self.buf.push_str("</>");
831
849
  }
832
850
  Expr::NativeModuleLoad {
833
- spec,
834
- export_name,
835
- ..
851
+ spec, export_name, ..
836
852
  } => {
837
853
  self.buf.push_str("import { ");
838
854
  self.buf.push_str(export_name.as_ref());