@tishlang/tish 1.0.7 → 1.0.11

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 (127) hide show
  1. package/Cargo.toml +43 -0
  2. package/LICENSE +13 -0
  3. package/README.md +66 -0
  4. package/crates/js_to_tish/Cargo.toml +9 -0
  5. package/crates/js_to_tish/README.md +18 -0
  6. package/crates/js_to_tish/src/error.rs +61 -0
  7. package/crates/js_to_tish/src/lib.rs +11 -0
  8. package/crates/js_to_tish/src/span_util.rs +35 -0
  9. package/crates/js_to_tish/src/transform/expr.rs +608 -0
  10. package/crates/js_to_tish/src/transform/stmt.rs +474 -0
  11. package/crates/js_to_tish/src/transform.rs +60 -0
  12. package/crates/tish/Cargo.toml +44 -0
  13. package/crates/tish/src/main.rs +585 -0
  14. package/crates/tish/src/repl_completion.rs +200 -0
  15. package/crates/tish/tests/integration_test.rs +726 -0
  16. package/crates/tish_ast/Cargo.toml +7 -0
  17. package/crates/tish_ast/src/ast.rs +494 -0
  18. package/crates/tish_ast/src/lib.rs +5 -0
  19. package/crates/tish_build_utils/Cargo.toml +5 -0
  20. package/crates/tish_build_utils/src/lib.rs +175 -0
  21. package/crates/tish_builtins/Cargo.toml +12 -0
  22. package/crates/tish_builtins/src/array.rs +410 -0
  23. package/crates/tish_builtins/src/globals.rs +197 -0
  24. package/crates/tish_builtins/src/helpers.rs +38 -0
  25. package/crates/tish_builtins/src/lib.rs +14 -0
  26. package/crates/tish_builtins/src/math.rs +80 -0
  27. package/crates/tish_builtins/src/object.rs +36 -0
  28. package/crates/tish_builtins/src/string.rs +253 -0
  29. package/crates/tish_bytecode/Cargo.toml +15 -0
  30. package/crates/tish_bytecode/src/chunk.rs +97 -0
  31. package/crates/tish_bytecode/src/compiler.rs +1361 -0
  32. package/crates/tish_bytecode/src/encoding.rs +100 -0
  33. package/crates/tish_bytecode/src/lib.rs +19 -0
  34. package/crates/tish_bytecode/src/opcode.rs +110 -0
  35. package/crates/tish_bytecode/src/peephole.rs +159 -0
  36. package/crates/tish_bytecode/src/serialize.rs +163 -0
  37. package/crates/tish_bytecode/tests/constant_folding.rs +84 -0
  38. package/crates/tish_bytecode/tests/shortcircuit.rs +49 -0
  39. package/crates/tish_bytecode/tests/sort_optimization.rs +31 -0
  40. package/crates/tish_compile/Cargo.toml +21 -0
  41. package/crates/tish_compile/src/codegen.rs +3316 -0
  42. package/crates/tish_compile/src/lib.rs +71 -0
  43. package/crates/tish_compile/src/resolve.rs +631 -0
  44. package/crates/tish_compile/src/types.rs +304 -0
  45. package/crates/tish_compile_js/Cargo.toml +16 -0
  46. package/crates/tish_compile_js/examples/jsx_vdom_smoke.tish +8 -0
  47. package/crates/tish_compile_js/src/codegen.rs +794 -0
  48. package/crates/tish_compile_js/src/error.rs +20 -0
  49. package/crates/tish_compile_js/src/js_intrinsics.rs +82 -0
  50. package/crates/tish_compile_js/src/lib.rs +27 -0
  51. package/crates/tish_compile_js/src/tests_jsx.rs +32 -0
  52. package/crates/tish_compiler_wasm/Cargo.toml +19 -0
  53. package/crates/tish_compiler_wasm/src/lib.rs +55 -0
  54. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +462 -0
  55. package/crates/tish_core/Cargo.toml +11 -0
  56. package/crates/tish_core/src/console_style.rs +128 -0
  57. package/crates/tish_core/src/json.rs +327 -0
  58. package/crates/tish_core/src/lib.rs +15 -0
  59. package/crates/tish_core/src/macros.rs +37 -0
  60. package/crates/tish_core/src/uri.rs +115 -0
  61. package/crates/tish_core/src/value.rs +376 -0
  62. package/crates/tish_cranelift/Cargo.toml +17 -0
  63. package/crates/tish_cranelift/src/lib.rs +41 -0
  64. package/crates/tish_cranelift/src/link.rs +120 -0
  65. package/crates/tish_cranelift/src/lower.rs +77 -0
  66. package/crates/tish_cranelift_runtime/Cargo.toml +19 -0
  67. package/crates/tish_cranelift_runtime/src/lib.rs +43 -0
  68. package/crates/tish_eval/Cargo.toml +26 -0
  69. package/crates/tish_eval/src/eval.rs +3205 -0
  70. package/crates/tish_eval/src/http.rs +122 -0
  71. package/crates/tish_eval/src/lib.rs +59 -0
  72. package/crates/tish_eval/src/natives.rs +301 -0
  73. package/crates/tish_eval/src/promise.rs +173 -0
  74. package/crates/tish_eval/src/regex.rs +298 -0
  75. package/crates/tish_eval/src/timers.rs +111 -0
  76. package/crates/tish_eval/src/value.rs +224 -0
  77. package/crates/tish_eval/src/value_convert.rs +85 -0
  78. package/crates/tish_fmt/Cargo.toml +16 -0
  79. package/crates/tish_fmt/src/bin/tish-fmt.rs +41 -0
  80. package/crates/tish_fmt/src/lib.rs +884 -0
  81. package/crates/tish_jsx_web/Cargo.toml +7 -0
  82. package/crates/tish_jsx_web/README.md +18 -0
  83. package/crates/tish_jsx_web/src/lib.rs +157 -0
  84. package/crates/tish_jsx_web/vendor/Lattish.tish +347 -0
  85. package/crates/tish_lexer/Cargo.toml +7 -0
  86. package/crates/tish_lexer/src/lib.rs +430 -0
  87. package/crates/tish_lexer/src/token.rs +155 -0
  88. package/crates/tish_lint/Cargo.toml +17 -0
  89. package/crates/tish_lint/src/bin/tish-lint.rs +77 -0
  90. package/crates/tish_lint/src/lib.rs +278 -0
  91. package/crates/tish_llvm/Cargo.toml +11 -0
  92. package/crates/tish_llvm/src/lib.rs +106 -0
  93. package/crates/tish_lsp/Cargo.toml +22 -0
  94. package/crates/tish_lsp/README.md +26 -0
  95. package/crates/tish_lsp/src/main.rs +615 -0
  96. package/crates/tish_native/Cargo.toml +14 -0
  97. package/crates/tish_native/src/build.rs +102 -0
  98. package/crates/tish_native/src/lib.rs +237 -0
  99. package/crates/tish_opt/Cargo.toml +11 -0
  100. package/crates/tish_opt/src/lib.rs +896 -0
  101. package/crates/tish_parser/Cargo.toml +9 -0
  102. package/crates/tish_parser/src/lib.rs +123 -0
  103. package/crates/tish_parser/src/parser.rs +1714 -0
  104. package/crates/tish_runtime/Cargo.toml +26 -0
  105. package/crates/tish_runtime/src/http.rs +308 -0
  106. package/crates/tish_runtime/src/http_fetch.rs +453 -0
  107. package/crates/tish_runtime/src/lib.rs +1004 -0
  108. package/crates/tish_runtime/src/native_promise.rs +26 -0
  109. package/crates/tish_runtime/src/promise.rs +77 -0
  110. package/crates/tish_runtime/src/promise_io.rs +41 -0
  111. package/crates/tish_runtime/src/timers.rs +125 -0
  112. package/crates/tish_runtime/src/ws.rs +725 -0
  113. package/crates/tish_runtime/tests/fetch_readable_stream.rs +99 -0
  114. package/crates/tish_vm/Cargo.toml +31 -0
  115. package/crates/tish_vm/src/lib.rs +39 -0
  116. package/crates/tish_vm/src/vm.rs +1399 -0
  117. package/crates/tish_wasm/Cargo.toml +13 -0
  118. package/crates/tish_wasm/src/lib.rs +358 -0
  119. package/crates/tish_wasm_runtime/Cargo.toml +25 -0
  120. package/crates/tish_wasm_runtime/src/lib.rs +36 -0
  121. package/justfile +260 -0
  122. package/package.json +8 -3
  123. package/platform/darwin-arm64/tish +0 -0
  124. package/platform/darwin-x64/tish +0 -0
  125. package/platform/linux-arm64/tish +0 -0
  126. package/platform/linux-x64/tish +0 -0
  127. package/platform/win32-x64/tish.exe +0 -0
@@ -0,0 +1,26 @@
1
+ //! Native Promise entrypoints for fetch / fetchAll.
2
+
3
+ use tish_core::Value;
4
+
5
+ pub fn fetch_promise(args: Vec<Value>) -> Value {
6
+ crate::http_fetch::fetch_promise_from_args(args)
7
+ }
8
+
9
+ pub fn fetch_all_promise(args: Vec<Value>) -> Value {
10
+ crate::http_fetch::fetch_all_promise_from_args(args)
11
+ }
12
+
13
+ pub fn fetch_async_promise(args: Vec<Value>) -> Value {
14
+ fetch_promise(args)
15
+ }
16
+
17
+ pub fn await_promise(v: Value) -> Value {
18
+ if let Value::Promise(p) = v {
19
+ match p.block_until_settled() {
20
+ Ok(val) => val,
21
+ Err(rejection) => rejection,
22
+ }
23
+ } else {
24
+ v
25
+ }
26
+ }
@@ -0,0 +1,77 @@
1
+ //! Promise static methods for compiled Tish (resolve, reject, all, race).
2
+
3
+ use std::cell::RefCell;
4
+ use std::collections::HashMap;
5
+ use std::rc::Rc;
6
+ use std::sync::Arc;
7
+ use tish_core::Value;
8
+
9
+ /// Promise.resolve(value) - returns the value (immediate resolve).
10
+ pub fn promise_resolve(args: &[Value]) -> Value {
11
+ args.first().cloned().unwrap_or(Value::Null)
12
+ }
13
+
14
+ /// Promise.reject(value) - returns value as "rejected" placeholder.
15
+ /// Note: await on this in native compile may not throw; use try/catch in interpreter for full support.
16
+ pub fn promise_reject(args: &[Value]) -> Value {
17
+ args.first().cloned().unwrap_or(Value::Null)
18
+ }
19
+
20
+ /// Promise.all(iterable) - awaits each Promise in the array, returns array of resolved values.
21
+ pub fn promise_all(args: &[Value]) -> Value {
22
+ match args.first() {
23
+ Some(Value::Array(arr)) => {
24
+ let arr = arr.borrow();
25
+ let resolved: Vec<Value> = arr
26
+ .iter()
27
+ .map(|v| {
28
+ if let Value::Promise(p) = v {
29
+ match tish_core::TishPromise::block_until_settled(p.as_ref()) {
30
+ Ok(val) => val,
31
+ Err(rejection) => rejection,
32
+ }
33
+ } else {
34
+ v.clone()
35
+ }
36
+ })
37
+ .collect();
38
+ Value::Array(Rc::new(RefCell::new(resolved)))
39
+ }
40
+ Some(v) => v.clone(),
41
+ None => Value::Null,
42
+ }
43
+ }
44
+
45
+ /// Promise.race(iterable) - returns first element of array.
46
+ pub fn promise_race(args: &[Value]) -> Value {
47
+ match args.first() {
48
+ Some(Value::Array(arr)) => arr
49
+ .borrow()
50
+ .first()
51
+ .cloned()
52
+ .unwrap_or(Value::Null),
53
+ _ => Value::Null,
54
+ }
55
+ }
56
+
57
+ /// Build the Promise object with resolve, reject, all, race static methods.
58
+ pub fn promise_object() -> Value {
59
+ let mut map: HashMap<Arc<str>, Value> = HashMap::new();
60
+ map.insert(
61
+ Arc::from("resolve"),
62
+ Value::Function(Rc::new(|args: &[Value]| promise_resolve(args))),
63
+ );
64
+ map.insert(
65
+ Arc::from("reject"),
66
+ Value::Function(Rc::new(|args: &[Value]| promise_reject(args))),
67
+ );
68
+ map.insert(
69
+ Arc::from("all"),
70
+ Value::Function(Rc::new(|args: &[Value]| promise_all(args))),
71
+ );
72
+ map.insert(
73
+ Arc::from("race"),
74
+ Value::Function(Rc::new(|args: &[Value]| promise_race(args))),
75
+ );
76
+ Value::Object(Rc::new(RefCell::new(map)))
77
+ }
@@ -0,0 +1,41 @@
1
+ //! Promises carrying only Send payloads (string results for text(), etc.).
2
+
3
+ use std::cell::RefCell;
4
+ use std::collections::HashMap;
5
+ use std::rc::Rc;
6
+ use std::sync::{Arc, Mutex};
7
+ use tish_core::{Value, TishPromise};
8
+ use tokio::sync::oneshot;
9
+
10
+ fn error_value(msg: String) -> Value {
11
+ let mut obj: HashMap<Arc<str>, Value> = HashMap::with_capacity(2);
12
+ obj.insert(Arc::from("error"), Value::String(msg.into()));
13
+ obj.insert(Arc::from("ok"), Value::Bool(false));
14
+ Value::Object(Rc::new(RefCell::new(obj)))
15
+ }
16
+
17
+ pub struct StringResultPromise {
18
+ pub(crate) rx: Mutex<Option<oneshot::Receiver<Result<String, String>>>>,
19
+ }
20
+
21
+ impl TishPromise for StringResultPromise {
22
+ fn block_until_settled(&self) -> std::result::Result<Value, Value> {
23
+ let rx = self.rx.lock().unwrap().take();
24
+ if let Some(rx) = rx {
25
+ let result = crate::http::block_on_http(rx);
26
+ match result {
27
+ Ok(Ok(s)) => Ok(Value::String(s.into())),
28
+ Ok(Err(e)) => Err(error_value(e)),
29
+ Err(_) => Err(Value::String("Promise dropped".into())),
30
+ }
31
+ } else {
32
+ Err(Value::String("Promise already consumed".into()))
33
+ }
34
+ }
35
+ }
36
+
37
+ pub fn string_result_promise(rx: oneshot::Receiver<Result<String, String>>) -> Value {
38
+ Value::Promise(Arc::new(StringResultPromise {
39
+ rx: Mutex::new(Some(rx)),
40
+ }))
41
+ }
@@ -0,0 +1,125 @@
1
+ //! setTimeout, clearTimeout for compiled Tish and VM.
2
+ //! Callbacks run when blocking ops (e.g. ws.receiveTimeout) yield in their poll loop.
3
+
4
+ use std::cell::RefCell;
5
+ use std::collections::HashMap;
6
+ use std::sync::atomic::{AtomicU64, Ordering};
7
+ use std::time::{Duration, Instant};
8
+
9
+ use tish_core::Value;
10
+
11
+ static NEXT_ID: AtomicU64 = AtomicU64::new(1);
12
+
13
+ fn next_id() -> u64 {
14
+ NEXT_ID.fetch_add(1, Ordering::SeqCst)
15
+ }
16
+
17
+ struct TimerEntry {
18
+ due: Instant,
19
+ callback: Value,
20
+ args: Vec<Value>,
21
+ interval_ms: u64,
22
+ }
23
+
24
+ thread_local! {
25
+ static REGISTRY: RefCell<HashMap<u64, TimerEntry>> = RefCell::new(HashMap::new());
26
+ }
27
+
28
+ fn extract_num(v: Option<&Value>) -> u64 {
29
+ v.and_then(|x| match x {
30
+ Value::Number(n) if n.is_finite() && *n >= 0.0 => Some(*n as u64),
31
+ _ => None,
32
+ })
33
+ .unwrap_or(0)
34
+ }
35
+
36
+ /// Sleep for ms, running due timers before sleeping. Use this instead of thread::sleep
37
+ /// in blocking loops so setTimeout callbacks can fire.
38
+ pub fn sleep_with_drain(ms: u64) {
39
+ run_due_timers();
40
+ std::thread::sleep(Duration::from_millis(ms));
41
+ }
42
+
43
+ /// Run all due timer callbacks.
44
+ fn run_due_timers() {
45
+ let due = take_due_timers();
46
+ for (id, callback, args, interval_ms) in due {
47
+ if let Value::Function(f) = &callback {
48
+ let _ = f(&args);
49
+ }
50
+ if interval_ms > 0 {
51
+ re_register_interval(id, callback, args, interval_ms);
52
+ }
53
+ }
54
+ }
55
+
56
+ fn take_due_timers() -> Vec<(u64, Value, Vec<Value>, u64)> {
57
+ let now = Instant::now();
58
+ REGISTRY.with(|r| {
59
+ let mut reg = r.borrow_mut();
60
+ let due: Vec<_> = reg
61
+ .iter()
62
+ .filter(|(_, e)| e.due <= now)
63
+ .map(|(id, e)| (*id, e.callback.clone(), e.args.clone(), e.interval_ms))
64
+ .collect();
65
+ for (id, _, _, _) in &due {
66
+ reg.remove(id);
67
+ }
68
+ due
69
+ })
70
+ }
71
+
72
+ fn re_register_interval(id: u64, callback: Value, args: Vec<Value>, interval_ms: u64) {
73
+ let due = Instant::now() + Duration::from_millis(interval_ms);
74
+ REGISTRY.with(|r| {
75
+ r.borrow_mut().insert(
76
+ id,
77
+ TimerEntry {
78
+ due,
79
+ callback,
80
+ args,
81
+ interval_ms,
82
+ },
83
+ );
84
+ });
85
+ }
86
+
87
+ /// setTimeout(callback, delayMs, ...args) - returns timer id.
88
+ /// Callbacks run when run_due_timers() is invoked (e.g. from ws.receiveTimeout poll loop).
89
+ pub fn set_timeout(args: &[Value]) -> Value {
90
+ let callback = args.first().cloned().unwrap_or(Value::Null);
91
+ let delay_ms = extract_num(args.get(1)).min(3600_000);
92
+ let extra_args: Vec<Value> = args.iter().skip(2).cloned().collect();
93
+ if matches!(callback, Value::Null) {
94
+ return Value::Number(next_id() as f64);
95
+ }
96
+ let id = next_id();
97
+ let due = Instant::now() + Duration::from_millis(delay_ms);
98
+ REGISTRY.with(|r| {
99
+ r.borrow_mut().insert(
100
+ id,
101
+ TimerEntry {
102
+ due,
103
+ callback,
104
+ args: extra_args,
105
+ interval_ms: 0,
106
+ },
107
+ );
108
+ });
109
+ Value::Number(id as f64)
110
+ }
111
+
112
+ /// clearTimeout(id) - removes timer.
113
+ pub fn clear_timeout(args: &[Value]) -> Value {
114
+ let id = args
115
+ .first()
116
+ .and_then(|v| match v {
117
+ Value::Number(n) if n.is_finite() && *n >= 0.0 => Some(*n as u64),
118
+ _ => None,
119
+ })
120
+ .unwrap_or(0);
121
+ REGISTRY.with(|r| {
122
+ r.borrow_mut().remove(&id);
123
+ });
124
+ Value::Null
125
+ }