@tishlang/tish 1.9.1 → 1.10.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/bin/tish +0 -0
- package/crates/js_to_tish/src/transform/expr.rs +8 -6
- package/crates/js_to_tish/src/transform/stmt.rs +12 -13
- package/crates/tish/Cargo.toml +1 -1
- package/crates/tish/src/cargo_native_registry.rs +4 -1
- package/crates/tish/src/main.rs +11 -8
- package/crates/tish/tests/integration_test.rs +145 -7
- package/crates/tish_ast/src/ast.rs +3 -9
- package/crates/tish_build_utils/src/lib.rs +43 -15
- package/crates/tish_builtins/src/array.rs +2 -3
- package/crates/tish_builtins/src/construct.rs +15 -28
- package/crates/tish_builtins/src/globals.rs +18 -16
- package/crates/tish_builtins/src/helpers.rs +1 -4
- package/crates/tish_builtins/src/lib.rs +1 -0
- package/crates/tish_builtins/src/object.rs +10 -10
- package/crates/tish_builtins/src/string.rs +1 -3
- package/crates/tish_builtins/src/symbol.rs +83 -0
- package/crates/tish_compile/src/codegen.rs +123 -138
- package/crates/tish_compile/src/lib.rs +25 -3
- package/crates/tish_compile/src/resolve.rs +6 -3
- package/crates/tish_compile/src/types.rs +6 -6
- package/crates/tish_compile_js/src/codegen.rs +50 -29
- package/crates/tish_compile_js/src/tests_jsx.rs +44 -0
- package/crates/tish_core/src/console_style.rs +9 -0
- package/crates/tish_core/src/json.rs +17 -7
- package/crates/tish_core/src/macros.rs +2 -2
- package/crates/tish_core/src/value.rs +192 -4
- package/crates/tish_cranelift_runtime/Cargo.toml +4 -0
- package/crates/tish_eval/src/eval.rs +135 -73
- package/crates/tish_eval/src/http.rs +18 -12
- package/crates/tish_eval/src/lib.rs +29 -0
- package/crates/tish_eval/src/regex.rs +1 -1
- package/crates/tish_eval/src/value.rs +89 -4
- package/crates/tish_eval/src/value_convert.rs +30 -8
- package/crates/tish_fmt/src/lib.rs +4 -1
- package/crates/tish_lexer/src/lib.rs +7 -2
- package/crates/tish_llvm/src/lib.rs +2 -2
- package/crates/tish_lsp/src/builtin_goto.rs +111 -10
- package/crates/tish_lsp/src/import_goto.rs +35 -22
- package/crates/tish_lsp/src/main.rs +118 -85
- package/crates/tish_native/src/build.rs +187 -10
- package/crates/tish_native/src/lib.rs +92 -8
- package/crates/tish_parser/src/lib.rs +77 -0
- package/crates/tish_parser/src/parser.rs +71 -74
- package/crates/tish_pg/src/error.rs +1 -1
- package/crates/tish_pg/src/lib.rs +61 -73
- package/crates/tish_resolve/src/lib.rs +283 -158
- package/crates/tish_resolve/src/pos.rs +10 -2
- package/crates/tish_runtime/Cargo.toml +3 -0
- package/crates/tish_runtime/src/http.rs +39 -39
- package/crates/tish_runtime/src/http_fetch.rs +12 -12
- package/crates/tish_runtime/src/lib.rs +26 -43
- package/crates/tish_runtime/src/native_promise.rs +0 -11
- package/crates/tish_runtime/src/promise.rs +14 -1
- package/crates/tish_runtime/src/promise_io.rs +1 -4
- package/crates/tish_runtime/src/ws.rs +40 -27
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +10 -8
- package/crates/tish_ui/src/jsx.rs +6 -4
- package/crates/tish_ui/src/lib.rs +2 -2
- package/crates/tish_ui/src/runtime/hooks.rs +5 -15
- package/crates/tish_ui/src/runtime/mod.rs +16 -17
- package/crates/tish_vm/Cargo.toml +2 -0
- package/crates/tish_vm/src/vm.rs +218 -153
- package/crates/tish_wasm/src/lib.rs +33 -7
- package/crates/tish_wasm_runtime/Cargo.toml +4 -1
- package/crates/tish_wasm_runtime/src/lib.rs +2 -1
- package/crates/tishlang_cargo_bindgen/src/classify.rs +1 -3
- package/crates/tishlang_cargo_bindgen/src/discover.rs +10 -5
- package/crates/tishlang_cargo_bindgen/src/infer.rs +18 -8
- package/crates/tishlang_cargo_bindgen/src/lib.rs +25 -26
- package/crates/tishlang_cargo_bindgen/src/main.rs +41 -38
- package/crates/tishlang_cargo_bindgen/src/metadata.rs +4 -1
- package/justfile +3 -3
- 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
|
@@ -90,15 +90,9 @@ fn params_to_sql(values: &[JsonValue]) -> Result<Vec<Box<dyn ToSql + Sync + Send
|
|
|
90
90
|
} else if let Some(u) = n.as_u64() {
|
|
91
91
|
Box::new(u as i64)
|
|
92
92
|
} else if let Some(f) = n.as_f64() {
|
|
93
|
-
if f.fract() == 0.0
|
|
94
|
-
&& f >= i32::MIN as f64
|
|
95
|
-
&& f <= i32::MAX as f64
|
|
96
|
-
{
|
|
93
|
+
if f.fract() == 0.0 && f >= i32::MIN as f64 && f <= i32::MAX as f64 {
|
|
97
94
|
Box::new(f as i32)
|
|
98
|
-
} else if f.fract() == 0.0
|
|
99
|
-
&& f >= i64::MIN as f64
|
|
100
|
-
&& f <= i64::MAX as f64
|
|
101
|
-
{
|
|
95
|
+
} else if f.fract() == 0.0 && f >= i64::MIN as f64 && f <= i64::MAX as f64 {
|
|
102
96
|
Box::new(f as i64)
|
|
103
97
|
} else {
|
|
104
98
|
Box::new(f)
|
|
@@ -110,7 +104,9 @@ fn params_to_sql(values: &[JsonValue]) -> Result<Vec<Box<dyn ToSql + Sync + Send
|
|
|
110
104
|
}
|
|
111
105
|
}
|
|
112
106
|
JsonValue::String(s) => Box::new(s.clone()),
|
|
113
|
-
JsonValue::Array(_) | JsonValue::Object(_) =>
|
|
107
|
+
JsonValue::Array(_) | JsonValue::Object(_) => {
|
|
108
|
+
Box::new(tokio_postgres::types::Json(v.clone()))
|
|
109
|
+
}
|
|
114
110
|
};
|
|
115
111
|
out.push(b);
|
|
116
112
|
}
|
|
@@ -222,7 +218,7 @@ fn row_to_value_direct(row: &Row) -> tishlang_runtime::Value {
|
|
|
222
218
|
};
|
|
223
219
|
om.insert(key, v);
|
|
224
220
|
}
|
|
225
|
-
RtValue::
|
|
221
|
+
RtValue::object(om)
|
|
226
222
|
}
|
|
227
223
|
|
|
228
224
|
fn row_to_object(row: &Row) -> Result<JsonValue> {
|
|
@@ -378,8 +374,8 @@ pub struct PerWorkerClient {
|
|
|
378
374
|
impl PerWorkerClient {
|
|
379
375
|
/// Open a single direct connection (no pool).
|
|
380
376
|
pub async fn connect(connection_string: &str) -> Result<Self> {
|
|
381
|
-
let cfg =
|
|
382
|
-
.map_err(TishPgError::BadConnectionString)?;
|
|
377
|
+
let cfg =
|
|
378
|
+
parse_connection_string(connection_string).map_err(TishPgError::BadConnectionString)?;
|
|
383
379
|
let (client, connection) = cfg.connect(NoTls).await?;
|
|
384
380
|
let driver = tokio::spawn(async move {
|
|
385
381
|
if let Err(e) = connection.await {
|
|
@@ -530,13 +526,11 @@ mod tish_sync {
|
|
|
530
526
|
use super::*;
|
|
531
527
|
use once_cell::sync::Lazy;
|
|
532
528
|
use slab::Slab;
|
|
533
|
-
use std::sync::Mutex;
|
|
534
529
|
use tishlang_runtime::Value as TishValue;
|
|
535
530
|
use tokio::runtime::Runtime as TokioRuntime;
|
|
536
531
|
|
|
537
|
-
static RT: Lazy<TokioRuntime> =
|
|
538
|
-
TokioRuntime::new().expect("tish_pg: failed to build tokio runtime")
|
|
539
|
-
});
|
|
532
|
+
static RT: Lazy<TokioRuntime> =
|
|
533
|
+
Lazy::new(|| TokioRuntime::new().expect("tish_pg: failed to build tokio runtime"));
|
|
540
534
|
// `RwLock` (not `Mutex`) on the registries: hot path is read-only —
|
|
541
535
|
// every query does `get_client(id)` + `get_statement(id)`. Inserts
|
|
542
536
|
// happen once per `connect`/`prepare` at startup. With multiple HTTP
|
|
@@ -544,8 +538,7 @@ mod tish_sync {
|
|
|
544
538
|
// serialised every query through one global lock; `RwLock` lets all
|
|
545
539
|
// concurrent reads run lock-free against each other.
|
|
546
540
|
use std::sync::RwLock;
|
|
547
|
-
static CLIENTS: Lazy<RwLock<Slab<PerWorkerClient>>> =
|
|
548
|
-
Lazy::new(|| RwLock::new(Slab::new()));
|
|
541
|
+
static CLIENTS: Lazy<RwLock<Slab<PerWorkerClient>>> = Lazy::new(|| RwLock::new(Slab::new()));
|
|
549
542
|
static STATEMENTS: Lazy<RwLock<Slab<(usize, Statement)>>> =
|
|
550
543
|
Lazy::new(|| RwLock::new(Slab::new()));
|
|
551
544
|
|
|
@@ -609,12 +602,10 @@ mod tish_sync {
|
|
|
609
602
|
.map(JsonValue::Number)
|
|
610
603
|
.unwrap_or(JsonValue::Null),
|
|
611
604
|
TishValue::String(s) => JsonValue::String(s.to_string()),
|
|
612
|
-
TishValue::Array(a) =>
|
|
613
|
-
JsonValue::Array(a.borrow().iter().map(tish_to_json).collect())
|
|
614
|
-
}
|
|
605
|
+
TishValue::Array(a) => JsonValue::Array(a.borrow().iter().map(tish_to_json).collect()),
|
|
615
606
|
TishValue::Object(o) => {
|
|
616
607
|
let mut m = serde_json::Map::new();
|
|
617
|
-
for (k, v) in o.borrow().iter() {
|
|
608
|
+
for (k, v) in o.borrow().strings.iter() {
|
|
618
609
|
m.insert(k.to_string(), tish_to_json(v));
|
|
619
610
|
}
|
|
620
611
|
JsonValue::Object(m)
|
|
@@ -623,35 +614,35 @@ mod tish_sync {
|
|
|
623
614
|
}
|
|
624
615
|
}
|
|
625
616
|
|
|
626
|
-
fn json_to_tish(v: JsonValue) -> TishValue {
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
}
|
|
617
|
+
// fn json_to_tish(v: JsonValue) -> TishValue {
|
|
618
|
+
// use std::cell::RefCell;
|
|
619
|
+
// use std::rc::Rc;
|
|
620
|
+
// use std::sync::Arc;
|
|
621
|
+
// use tishlang_runtime::ObjectMap;
|
|
622
|
+
// match v {
|
|
623
|
+
// JsonValue::Null => TishValue::Null,
|
|
624
|
+
// JsonValue::Bool(b) => TishValue::Bool(b),
|
|
625
|
+
// JsonValue::Number(n) => TishValue::Number(n.as_f64().unwrap_or(0.0)),
|
|
626
|
+
// JsonValue::String(s) => TishValue::String(s.into()),
|
|
627
|
+
// JsonValue::Array(a) => {
|
|
628
|
+
// let mut out = Vec::with_capacity(a.len());
|
|
629
|
+
// for item in a {
|
|
630
|
+
// out.push(json_to_tish(item));
|
|
631
|
+
// }
|
|
632
|
+
// TishValue::Array(VmRef::new(out))
|
|
633
|
+
// }
|
|
634
|
+
// JsonValue::Object(m) => {
|
|
635
|
+
// // Pre-allocate ObjectMap capacity so HashMap doesn't rehash
|
|
636
|
+
// // on every insert. Common TFB rows are 2 columns (id,
|
|
637
|
+
// // randomnumber or id, message).
|
|
638
|
+
// let mut om = ObjectMap::with_capacity(m.len());
|
|
639
|
+
// for (k, v) in m {
|
|
640
|
+
// om.insert(Arc::from(k), json_to_tish(v));
|
|
641
|
+
// }
|
|
642
|
+
// TishValue::object(om)
|
|
643
|
+
// }
|
|
644
|
+
// }
|
|
645
|
+
// }
|
|
655
646
|
|
|
656
647
|
fn tish_err(msg: impl Into<String>) -> TishValue {
|
|
657
648
|
use std::sync::Arc;
|
|
@@ -659,16 +650,14 @@ mod tish_sync {
|
|
|
659
650
|
let mut om = ObjectMap::with_capacity(2);
|
|
660
651
|
om.insert(Arc::from("error"), TishValue::String(msg.into().into()));
|
|
661
652
|
om.insert(Arc::from("ok"), TishValue::Bool(false));
|
|
662
|
-
TishValue::
|
|
653
|
+
TishValue::object(om)
|
|
663
654
|
}
|
|
664
655
|
|
|
665
|
-
fn rows_to_value(res: QueryResult) -> TishValue {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
))
|
|
671
|
-
}
|
|
656
|
+
// fn rows_to_value(res: QueryResult) -> TishValue {
|
|
657
|
+
// use std::cell::RefCell;
|
|
658
|
+
// use std::rc::Rc;
|
|
659
|
+
// TishValue::Array(VmRef::new(res.rows.into_iter().map(json_to_tish).collect()))
|
|
660
|
+
// }
|
|
672
661
|
|
|
673
662
|
/// `perWorkerClient(connection_string) -> client_handle` (blocking).
|
|
674
663
|
pub fn per_worker_client(args: &[TishValue]) -> TishValue {
|
|
@@ -682,7 +671,10 @@ mod tish_sync {
|
|
|
682
671
|
let id = g.insert(c);
|
|
683
672
|
TishValue::Number(id as f64)
|
|
684
673
|
}
|
|
685
|
-
Err(e) => tish_err(format!(
|
|
674
|
+
Err(e) => tish_err(format!(
|
|
675
|
+
"perWorkerClient: {}",
|
|
676
|
+
crate::format_tish_pg_error(&e)
|
|
677
|
+
)),
|
|
686
678
|
}
|
|
687
679
|
}
|
|
688
680
|
|
|
@@ -694,9 +686,8 @@ mod tish_sync {
|
|
|
694
686
|
let cs = match args.first() {
|
|
695
687
|
Some(TishValue::String(s)) => s.to_string(),
|
|
696
688
|
Some(TishValue::Object(obj)) => {
|
|
697
|
-
use std::sync::Arc;
|
|
698
689
|
let b = obj.borrow();
|
|
699
|
-
match b.get(
|
|
690
|
+
match b.strings.get("connectionString") {
|
|
700
691
|
Some(TishValue::String(s)) => s.to_string(),
|
|
701
692
|
_ => return tish_err("connect: options.connectionString missing"),
|
|
702
693
|
}
|
|
@@ -754,11 +745,7 @@ mod tish_sync {
|
|
|
754
745
|
return tish_err("queryPrepared: expected (client, stmt, params)");
|
|
755
746
|
};
|
|
756
747
|
let params = match args.get(2) {
|
|
757
|
-
Some(TishValue::Array(a)) => a
|
|
758
|
-
.borrow()
|
|
759
|
-
.iter()
|
|
760
|
-
.map(tish_to_json)
|
|
761
|
-
.collect::<Vec<_>>(),
|
|
748
|
+
Some(TishValue::Array(a)) => a.borrow().iter().map(tish_to_json).collect::<Vec<_>>(),
|
|
762
749
|
Some(TishValue::Null) | None => Vec::new(),
|
|
763
750
|
Some(v) => vec![tish_to_json(v)],
|
|
764
751
|
};
|
|
@@ -773,7 +760,10 @@ mod tish_sync {
|
|
|
773
760
|
// produces. Fewer allocations + interned column-name `Arc`s.
|
|
774
761
|
match block_on(client.query_prepared_to_values(&stmt, ¶ms)) {
|
|
775
762
|
Ok(rows) => TishValue::Array(VmRef::new(rows)),
|
|
776
|
-
Err(e) => tish_err(format!(
|
|
763
|
+
Err(e) => tish_err(format!(
|
|
764
|
+
"queryPrepared: {}",
|
|
765
|
+
crate::format_tish_pg_error(&e)
|
|
766
|
+
)),
|
|
777
767
|
}
|
|
778
768
|
}
|
|
779
769
|
|
|
@@ -895,10 +885,8 @@ mod tish_sync {
|
|
|
895
885
|
let rows = raw_client
|
|
896
886
|
.query("SELECT name FROM _tish_pg_migrations", &[])
|
|
897
887
|
.await?;
|
|
898
|
-
let already: std::collections::HashSet<String> =
|
|
899
|
-
.iter()
|
|
900
|
-
.map(|r| r.get::<_, String>(0))
|
|
901
|
-
.collect();
|
|
888
|
+
let already: std::collections::HashSet<String> =
|
|
889
|
+
rows.iter().map(|r| r.get::<_, String>(0)).collect();
|
|
902
890
|
|
|
903
891
|
let mut applied_now: Vec<String> = Vec::new();
|
|
904
892
|
for (name, path) in &files {
|
|
@@ -942,7 +930,7 @@ mod tish_sync {
|
|
|
942
930
|
let mut om = ObjectMap::with_capacity(2);
|
|
943
931
|
om.insert(Arc::from("ok"), TishValue::Bool(true));
|
|
944
932
|
om.insert(Arc::from("applied"), TishValue::Array(VmRef::new(applied)));
|
|
945
|
-
TishValue::
|
|
933
|
+
TishValue::object(om)
|
|
946
934
|
}
|
|
947
935
|
}
|
|
948
936
|
|