@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.
- package/Cargo.toml +1 -0
- package/bin/tish +0 -0
- package/crates/js_to_tish/src/error.rs +2 -8
- package/crates/js_to_tish/src/transform/expr.rs +101 -130
- package/crates/js_to_tish/src/transform/stmt.rs +25 -22
- package/crates/tish/Cargo.toml +1 -1
- package/crates/tish/src/cli_help.rs +76 -29
- package/crates/tish/src/main.rs +85 -54
- package/crates/tish/tests/cargo_example_compile.rs +3 -1
- package/crates/tish/tests/integration_test.rs +197 -47
- package/crates/tish/tests/run_optimize_stdout_parity.rs +3 -7
- package/crates/tish/tests/shortcircuit.rs +19 -4
- package/crates/tish_ast/src/ast.rs +12 -14
- package/crates/tish_build_utils/src/lib.rs +31 -6
- package/crates/tish_builtins/src/array.rs +52 -21
- package/crates/tish_builtins/src/construct.rs +2 -8
- package/crates/tish_builtins/src/globals.rs +30 -15
- package/crates/tish_builtins/src/lib.rs +5 -5
- package/crates/tish_builtins/src/math.rs +5 -3
- package/crates/tish_builtins/src/string.rs +71 -19
- package/crates/tish_bytecode/src/chunk.rs +0 -1
- package/crates/tish_bytecode/src/compiler.rs +164 -60
- package/crates/tish_bytecode/src/opcode.rs +13 -4
- package/crates/tish_bytecode/src/peephole.rs +2 -2
- package/crates/tish_compile/src/codegen.rs +921 -299
- package/crates/tish_compile/src/infer.rs +69 -19
- package/crates/tish_compile/src/lib.rs +15 -5
- package/crates/tish_compile/src/resolve.rs +112 -69
- package/crates/tish_compile/src/types.rs +10 -14
- package/crates/tish_compile_js/src/codegen.rs +34 -13
- package/crates/tish_compile_js/src/tests_jsx.rs +30 -6
- package/crates/tish_compiler_wasm/src/lib.rs +16 -13
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +39 -48
- package/crates/tish_core/src/json.rs +5 -3
- package/crates/tish_core/src/lib.rs +1 -1
- package/crates/tish_core/src/uri.rs +9 -6
- package/crates/tish_core/src/value.rs +92 -28
- package/crates/tish_cranelift/src/link.rs +6 -9
- package/crates/tish_cranelift/src/lower.rs +14 -8
- package/crates/tish_eval/src/eval.rs +389 -142
- package/crates/tish_eval/src/lib.rs +10 -6
- package/crates/tish_eval/src/natives.rs +95 -38
- package/crates/tish_eval/src/promise.rs +14 -8
- package/crates/tish_eval/src/timers.rs +28 -19
- package/crates/tish_eval/src/value.rs +10 -3
- package/crates/tish_fmt/src/lib.rs +29 -13
- package/crates/tish_lexer/src/lib.rs +217 -63
- package/crates/tish_lexer/src/token.rs +6 -6
- package/crates/tish_llvm/src/lib.rs +15 -8
- package/crates/tish_lsp/src/main.rs +41 -43
- package/crates/tish_native/src/build.rs +1 -6
- package/crates/tish_native/src/lib.rs +48 -19
- package/crates/tish_opt/src/lib.rs +67 -50
- package/crates/tish_parser/src/lib.rs +36 -11
- package/crates/tish_parser/src/parser.rs +172 -87
- package/crates/tish_runtime/src/http.rs +15 -6
- package/crates/tish_runtime/src/http_fetch.rs +24 -14
- package/crates/tish_runtime/src/lib.rs +224 -168
- package/crates/tish_runtime/src/promise.rs +1 -5
- package/crates/tish_runtime/src/ws.rs +45 -20
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +5 -4
- package/crates/tish_ui/src/jsx.rs +41 -22
- package/crates/tish_ui/src/lib.rs +2 -2
- package/crates/tish_vm/src/vm.rs +309 -112
- package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +8 -3
- package/crates/tish_wasm/src/lib.rs +38 -28
- package/crates/tishlang_cargo_bindgen/Cargo.toml +25 -0
- package/crates/tishlang_cargo_bindgen/src/classify.rs +265 -0
- package/crates/tishlang_cargo_bindgen/src/discover.rs +52 -0
- package/crates/tishlang_cargo_bindgen/src/infer.rs +372 -0
- package/crates/tishlang_cargo_bindgen/src/lib.rs +349 -0
- package/crates/tishlang_cargo_bindgen/src/main.rs +164 -0
- package/crates/tishlang_cargo_bindgen/src/metadata.rs +114 -0
- package/package.json +1 -1
- package/platform/darwin-arm64/tish +0 -0
- package/platform/darwin-x64/tish +0 -0
- package/platform/linux-arm64/tish +0 -0
- package/platform/linux-x64/tish +0 -0
- package/platform/win32-x64/tish.exe +0 -0
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
mod eval;
|
|
4
4
|
#[cfg(feature = "http")]
|
|
5
5
|
mod http;
|
|
6
|
-
|
|
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(
|
|
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)
|
|
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
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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)
|
|
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
|
|
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|
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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 {
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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() {
|
|
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(
|
|
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
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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 {
|
|
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) =>
|
|
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(_) =>
|
|
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 { .. } =>
|
|
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(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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!(
|
|
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)) =>
|
|
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
|
-
|
|
7
|
-
|
|
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,
|
|
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 {
|
|
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 {
|
|
283
|
-
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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());
|