@tishlang/tish 1.0.13 → 1.0.14
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/crates/js_to_tish/Cargo.toml +4 -2
- package/crates/js_to_tish/src/span_util.rs +1 -1
- package/crates/js_to_tish/src/transform/expr.rs +15 -15
- package/crates/js_to_tish/src/transform/stmt.rs +7 -7
- package/crates/js_to_tish/src/transform.rs +1 -1
- package/crates/tish/Cargo.toml +22 -22
- package/crates/tish/src/main.rs +46 -46
- package/crates/tish/src/repl_completion.rs +4 -4
- package/crates/tish/tests/integration_test.rs +28 -28
- package/crates/tish_ast/Cargo.toml +3 -1
- package/crates/tish_ast/src/ast.rs +1 -1
- package/crates/tish_build_utils/Cargo.toml +3 -1
- package/crates/tish_build_utils/src/lib.rs +18 -6
- package/crates/tish_builtins/Cargo.toml +5 -3
- package/crates/tish_builtins/src/array.rs +2 -2
- package/crates/tish_builtins/src/globals.rs +3 -3
- package/crates/tish_builtins/src/helpers.rs +1 -1
- package/crates/tish_builtins/src/lib.rs +3 -3
- package/crates/tish_builtins/src/math.rs +1 -1
- package/crates/tish_builtins/src/object.rs +2 -2
- package/crates/tish_builtins/src/string.rs +1 -1
- package/crates/tish_bytecode/Cargo.toml +9 -7
- package/crates/tish_bytecode/src/chunk.rs +1 -1
- package/crates/tish_bytecode/src/compiler.rs +1 -1
- package/crates/tish_bytecode/src/encoding.rs +6 -6
- package/crates/tish_bytecode/tests/constant_folding.rs +7 -7
- package/crates/tish_bytecode/tests/shortcircuit.rs +11 -11
- package/crates/tish_bytecode/tests/sort_optimization.rs +3 -3
- package/crates/tish_compile/Cargo.toml +6 -4
- package/crates/tish_compile/src/codegen.rs +96 -96
- package/crates/tish_compile/src/lib.rs +2 -2
- package/crates/tish_compile/src/resolve.rs +7 -7
- package/crates/tish_compile/src/types.rs +1 -1
- package/crates/tish_compile_js/Cargo.toml +8 -6
- package/crates/tish_compile_js/src/codegen.rs +12 -12
- package/crates/tish_compile_js/src/js_intrinsics.rs +1 -1
- package/crates/tish_compile_js/src/lib.rs +2 -2
- package/crates/tish_compile_js/src/tests_jsx.rs +2 -2
- package/crates/tish_compiler_wasm/Cargo.toml +8 -6
- package/crates/tish_compiler_wasm/src/lib.rs +12 -12
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +3 -3
- package/crates/tish_core/Cargo.toml +3 -1
- package/crates/tish_core/src/lib.rs +1 -1
- package/crates/tish_core/src/macros.rs +1 -1
- package/crates/tish_core/src/value.rs +1 -1
- package/crates/tish_cranelift/Cargo.toml +6 -4
- package/crates/tish_cranelift/src/lib.rs +2 -2
- package/crates/tish_cranelift/src/link.rs +11 -11
- package/crates/tish_cranelift/src/lower.rs +3 -3
- package/crates/tish_cranelift_runtime/Cargo.toml +9 -7
- package/crates/tish_cranelift_runtime/src/lib.rs +2 -2
- package/crates/tish_eval/Cargo.toml +10 -8
- package/crates/tish_eval/src/eval.rs +35 -35
- package/crates/tish_eval/src/http.rs +1 -1
- package/crates/tish_eval/src/lib.rs +3 -3
- package/crates/tish_eval/src/natives.rs +2 -2
- package/crates/tish_eval/src/regex.rs +2 -2
- package/crates/tish_eval/src/value.rs +7 -7
- package/crates/tish_eval/src/value_convert.rs +3 -3
- package/crates/tish_fmt/Cargo.toml +3 -3
- package/crates/tish_fmt/src/bin/tish-fmt.rs +1 -1
- package/crates/tish_fmt/src/lib.rs +3 -3
- package/crates/tish_jsx_web/Cargo.toml +3 -1
- package/crates/tish_lexer/Cargo.toml +3 -1
- package/crates/tish_lint/Cargo.toml +3 -3
- package/crates/tish_lint/src/bin/tish-lint.rs +3 -3
- package/crates/tish_lint/src/lib.rs +15 -15
- package/crates/tish_llvm/Cargo.toml +7 -5
- package/crates/tish_llvm/src/lib.rs +10 -10
- package/crates/tish_lsp/Cargo.toml +5 -5
- package/crates/tish_lsp/src/main.rs +35 -35
- package/crates/tish_native/Cargo.toml +10 -8
- package/crates/tish_native/src/build.rs +8 -8
- package/crates/tish_native/src/lib.rs +39 -39
- package/crates/tish_opt/Cargo.toml +5 -3
- package/crates/tish_opt/src/lib.rs +27 -27
- package/crates/tish_parser/Cargo.toml +5 -3
- package/crates/tish_parser/src/lib.rs +4 -4
- package/crates/tish_parser/src/parser.rs +2 -2
- package/crates/tish_runtime/Cargo.toml +7 -5
- package/crates/tish_runtime/src/http.rs +1 -1
- package/crates/tish_runtime/src/http_fetch.rs +2 -2
- package/crates/tish_runtime/src/lib.rs +21 -21
- package/crates/tish_runtime/src/native_promise.rs +1 -1
- package/crates/tish_runtime/src/promise.rs +2 -2
- package/crates/tish_runtime/src/promise_io.rs +1 -1
- package/crates/tish_runtime/src/timers.rs +1 -1
- package/crates/tish_runtime/src/ws.rs +1 -1
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +2 -2
- package/crates/tish_vm/Cargo.toml +14 -12
- package/crates/tish_vm/src/lib.rs +2 -2
- package/crates/tish_vm/src/vm.rs +42 -42
- package/crates/tish_wasm/Cargo.toml +8 -6
- package/crates/tish_wasm/src/lib.rs +17 -17
- package/crates/tish_wasm_runtime/Cargo.toml +9 -7
- package/crates/tish_wasm_runtime/src/lib.rs +4 -4
- package/justfile +4 -4
- 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,7 +3,7 @@
|
|
|
3
3
|
use std::borrow::Cow;
|
|
4
4
|
use std::collections::{HashMap, HashSet};
|
|
5
5
|
use std::path::Path;
|
|
6
|
-
use
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
|
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 {
|
|
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
|
|
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(
|
|
546
|
-
"wsBroadcast" => Some("Value::Function(Rc::new(|args: &[Value]|
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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::<
|
|
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
|
|
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
|
-
"
|
|
1722
|
+
"tishlang_runtime::array_push(&{}, &[{}])",
|
|
1723
1723
|
obj_expr, args_vec
|
|
1724
1724
|
));
|
|
1725
1725
|
}
|
|
1726
1726
|
"pop" => {
|
|
1727
|
-
return Ok(format!("
|
|
1727
|
+
return Ok(format!("tishlang_runtime::array_pop(&{})", obj_expr));
|
|
1728
1728
|
}
|
|
1729
1729
|
"shift" => {
|
|
1730
|
-
return Ok(format!("
|
|
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
|
-
"
|
|
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(_) =>
|
|
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(_) =>
|
|
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
|
-
"
|
|
1761
|
+
"tishlang_runtime::array_join(&{}, &{})",
|
|
1762
1762
|
obj_expr, sep
|
|
1763
1763
|
));
|
|
1764
1764
|
}
|
|
1765
1765
|
"reverse" => {
|
|
1766
|
-
return Ok(format!("
|
|
1766
|
+
return Ok(format!("tishlang_runtime::array_reverse(&{})", obj_expr));
|
|
1767
1767
|
}
|
|
1768
1768
|
"shuffle" => {
|
|
1769
|
-
return Ok(format!("
|
|
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(_) =>
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
1801
|
+
"tishlang_runtime::string_split(&{}, &{})",
|
|
1802
1802
|
obj_expr, sep
|
|
1803
1803
|
));
|
|
1804
1804
|
}
|
|
1805
1805
|
"trim" => {
|
|
1806
|
-
return Ok(format!("
|
|
1806
|
+
return Ok(format!("tishlang_runtime::string_trim(&{})", obj_expr));
|
|
1807
1807
|
}
|
|
1808
1808
|
"toUpperCase" => {
|
|
1809
|
-
return Ok(format!("
|
|
1809
|
+
return Ok(format!("tishlang_runtime::string_to_upper_case(&{})", obj_expr));
|
|
1810
1810
|
}
|
|
1811
1811
|
"toLowerCase" => {
|
|
1812
|
-
return Ok(format!("
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
1960
|
+
"tishlang_runtime::array_sort_numeric_asc(&{})",
|
|
1961
1961
|
obj_expr
|
|
1962
1962
|
));
|
|
1963
1963
|
} else {
|
|
1964
1964
|
return Ok(format!(
|
|
1965
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
|
|
2059
|
+
tishlang_runtime::get_prop(&o, {}) }} }}",
|
|
2060
2060
|
obj, key
|
|
2061
2061
|
)
|
|
2062
2062
|
} else {
|
|
2063
|
-
format!("
|
|
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
|
-
|
|
2077
|
+
tishlang_runtime::get_index(&o, &{}) }} }}",
|
|
2078
2078
|
obj, idx
|
|
2079
2079
|
)
|
|
2080
2080
|
} else {
|
|
2081
|
-
format!("
|
|
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() =
|
|
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(); {} =
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
2668
|
-
value:
|
|
2667
|
+
tishlang_ast::JsxProp::Attr {
|
|
2668
|
+
value: tishlang_ast::JsxAttrValue::Expr(e),
|
|
2669
2669
|
..
|
|
2670
2670
|
}
|
|
2671
|
-
|
|
|
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
|
|
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
|
|
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: &[
|
|
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: &[
|
|
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: &[
|
|
3059
|
-
body: &
|
|
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
|
-
|
|
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
|
-
|
|
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!("
|
|
3288
|
-
BinOp::Sub => format!("
|
|
3289
|
-
BinOp::Mul => format!("
|
|
3290
|
-
BinOp::Div => format!("
|
|
3291
|
-
BinOp::Mod => format!("
|
|
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!("
|
|
3300
|
-
BinOp::Le => format!("
|
|
3301
|
-
BinOp::Gt => format!("
|
|
3302
|
-
BinOp::Ge => format!("
|
|
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, "&"),
|