@tishlang/tish-format 1.0.12 → 1.0.13
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 +49 -0
- package/LICENSE +13 -0
- package/README.md +138 -0
- package/bin/tish-format +0 -0
- package/crates/js_to_tish/Cargo.toml +11 -0
- package/crates/js_to_tish/README.md +18 -0
- package/crates/js_to_tish/src/error.rs +55 -0
- package/crates/js_to_tish/src/lib.rs +11 -0
- package/crates/js_to_tish/src/span_util.rs +35 -0
- package/crates/js_to_tish/src/transform/expr.rs +610 -0
- package/crates/js_to_tish/src/transform/stmt.rs +503 -0
- package/crates/js_to_tish/src/transform.rs +60 -0
- package/crates/tish/Cargo.toml +54 -0
- package/crates/tish/src/cargo_native_registry.rs +32 -0
- package/crates/tish/src/cli_help.rs +565 -0
- package/crates/tish/src/main.rs +781 -0
- package/crates/tish/src/repl_completion.rs +200 -0
- package/crates/tish/tests/cargo_example_compile.rs +67 -0
- package/crates/tish/tests/fixtures/cargo_example_project/Cargo.toml +3 -0
- package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/Cargo.toml +11 -0
- package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/src/lib.rs +12 -0
- package/crates/tish/tests/fixtures/cargo_example_project/package.json +10 -0
- package/crates/tish/tests/fixtures/cargo_example_project/src/main.tish +3 -0
- package/crates/tish/tests/integration_test.rs +1095 -0
- package/crates/tish/tests/run_optimize_stdout_parity.rs +50 -0
- package/crates/tish/tests/shortcircuit.rs +65 -0
- package/crates/tish_ast/Cargo.toml +9 -0
- package/crates/tish_ast/src/ast.rs +620 -0
- package/crates/tish_ast/src/lib.rs +5 -0
- package/crates/tish_build_utils/Cargo.toml +11 -0
- package/crates/tish_build_utils/src/lib.rs +577 -0
- package/crates/tish_builtins/Cargo.toml +20 -0
- package/crates/tish_builtins/src/array.rs +441 -0
- package/crates/tish_builtins/src/construct.rs +159 -0
- package/crates/tish_builtins/src/globals.rs +213 -0
- package/crates/tish_builtins/src/helpers.rs +35 -0
- package/crates/tish_builtins/src/lib.rs +16 -0
- package/crates/tish_builtins/src/math.rs +89 -0
- package/crates/tish_builtins/src/object.rs +36 -0
- package/crates/tish_builtins/src/string.rs +647 -0
- package/crates/tish_builtins/src/symbol.rs +83 -0
- package/crates/tish_bytecode/Cargo.toml +17 -0
- package/crates/tish_bytecode/src/chunk.rs +96 -0
- package/crates/tish_bytecode/src/compiler.rs +1760 -0
- package/crates/tish_bytecode/src/encoding.rs +100 -0
- package/crates/tish_bytecode/src/lib.rs +19 -0
- package/crates/tish_bytecode/src/opcode.rs +142 -0
- package/crates/tish_bytecode/src/peephole.rs +189 -0
- package/crates/tish_bytecode/src/serialize.rs +163 -0
- package/crates/tish_bytecode/tests/break_continue_bytecode.rs +44 -0
- package/crates/tish_bytecode/tests/constant_folding.rs +84 -0
- package/crates/tish_bytecode/tests/sort_optimization.rs +31 -0
- package/crates/tish_compile/Cargo.toml +26 -0
- package/crates/tish_compile/src/codegen.rs +5332 -0
- package/crates/tish_compile/src/infer.rs +292 -0
- package/crates/tish_compile/src/lib.rs +164 -0
- package/crates/tish_compile/src/resolve.rs +1388 -0
- package/crates/tish_compile/src/types.rs +501 -0
- package/crates/tish_compile_js/Cargo.toml +18 -0
- package/crates/tish_compile_js/examples/jsx_vdom_smoke.tish +8 -0
- package/crates/tish_compile_js/src/codegen.rs +871 -0
- package/crates/tish_compile_js/src/error.rs +20 -0
- package/crates/tish_compile_js/src/lib.rs +26 -0
- package/crates/tish_compile_js/src/tests_jsx.rs +350 -0
- package/crates/tish_compiler_wasm/Cargo.toml +21 -0
- package/crates/tish_compiler_wasm/src/lib.rs +57 -0
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +473 -0
- package/crates/tish_core/Cargo.toml +26 -0
- package/crates/tish_core/src/console_style.rs +160 -0
- package/crates/tish_core/src/json.rs +387 -0
- package/crates/tish_core/src/lib.rs +17 -0
- package/crates/tish_core/src/macros.rs +36 -0
- package/crates/tish_core/src/uri.rs +118 -0
- package/crates/tish_core/src/value.rs +696 -0
- package/crates/tish_core/src/vmref.rs +178 -0
- package/crates/tish_cranelift/Cargo.toml +19 -0
- package/crates/tish_cranelift/src/lib.rs +43 -0
- package/crates/tish_cranelift/src/link.rs +117 -0
- package/crates/tish_cranelift/src/lower.rs +85 -0
- package/crates/tish_cranelift_runtime/Cargo.toml +25 -0
- package/crates/tish_cranelift_runtime/src/lib.rs +45 -0
- package/crates/tish_eval/Cargo.toml +45 -0
- package/crates/tish_eval/src/eval.rs +3717 -0
- package/crates/tish_eval/src/http.rs +188 -0
- package/crates/tish_eval/src/lib.rs +99 -0
- package/crates/tish_eval/src/natives.rs +399 -0
- package/crates/tish_eval/src/promise.rs +179 -0
- package/crates/tish_eval/src/regex.rs +299 -0
- package/crates/tish_eval/src/timers.rs +120 -0
- package/crates/tish_eval/src/value.rs +318 -0
- package/crates/tish_eval/src/value_convert.rs +111 -0
- package/crates/tish_fmt/Cargo.toml +16 -0
- package/crates/tish_fmt/src/bin/tish-fmt.rs +41 -0
- package/crates/tish_fmt/src/lib.rs +2101 -0
- package/crates/tish_jsx_web/Cargo.toml +9 -0
- package/crates/tish_jsx_web/README.md +5 -0
- package/crates/tish_jsx_web/src/lib.rs +2 -0
- package/crates/tish_lexer/Cargo.toml +9 -0
- package/crates/tish_lexer/src/lib.rs +716 -0
- package/crates/tish_lexer/src/token.rs +163 -0
- package/crates/tish_lint/Cargo.toml +18 -0
- package/crates/tish_lint/src/bin/tish-lint.rs +195 -0
- package/crates/tish_lint/src/lib.rs +289 -0
- package/crates/tish_llvm/Cargo.toml +13 -0
- package/crates/tish_llvm/src/lib.rs +115 -0
- package/crates/tish_lsp/Cargo.toml +25 -0
- package/crates/tish_lsp/README.md +26 -0
- package/crates/tish_lsp/src/builtin_goto.rs +362 -0
- package/crates/tish_lsp/src/import_goto.rs +562 -0
- package/crates/tish_lsp/src/main.rs +1046 -0
- package/crates/tish_native/Cargo.toml +16 -0
- package/crates/tish_native/src/build.rs +427 -0
- package/crates/tish_native/src/config.rs +48 -0
- package/crates/tish_native/src/lib.rs +416 -0
- package/crates/tish_opt/Cargo.toml +13 -0
- package/crates/tish_opt/src/lib.rs +943 -0
- package/crates/tish_parser/Cargo.toml +11 -0
- package/crates/tish_parser/src/lib.rs +332 -0
- package/crates/tish_parser/src/parser.rs +2304 -0
- package/crates/tish_pg/Cargo.toml +34 -0
- package/crates/tish_pg/README.md +38 -0
- package/crates/tish_pg/src/error.rs +52 -0
- package/crates/tish_pg/src/lib.rs +955 -0
- package/crates/tish_resolve/Cargo.toml +13 -0
- package/crates/tish_resolve/src/lib.rs +3561 -0
- package/crates/tish_resolve/src/pos.rs +141 -0
- package/crates/tish_runtime/Cargo.toml +96 -0
- package/crates/tish_runtime/src/http.rs +1298 -0
- package/crates/tish_runtime/src/http_fetch.rs +471 -0
- package/crates/tish_runtime/src/http_hyper.rs +418 -0
- package/crates/tish_runtime/src/http_prefork.rs +189 -0
- package/crates/tish_runtime/src/lib.rs +1192 -0
- package/crates/tish_runtime/src/native_promise.rs +15 -0
- package/crates/tish_runtime/src/promise.rs +248 -0
- package/crates/tish_runtime/src/promise_io.rs +38 -0
- package/crates/tish_runtime/src/timers.rs +166 -0
- package/crates/tish_runtime/src/ws.rs +761 -0
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +102 -0
- package/crates/tish_ui/Cargo.toml +17 -0
- package/crates/tish_ui/src/jsx.rs +682 -0
- package/crates/tish_ui/src/lib.rs +20 -0
- package/crates/tish_ui/src/runtime/hooks.rs +569 -0
- package/crates/tish_ui/src/runtime/mod.rs +180 -0
- package/crates/tish_vm/Cargo.toml +47 -0
- package/crates/tish_vm/src/lib.rs +39 -0
- package/crates/tish_vm/src/vm.rs +2192 -0
- package/crates/tish_vm/tests/fixtures/or_string_cmd.tish +2 -0
- package/crates/tish_vm/tests/lexical_scope_declare.rs +34 -0
- package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +150 -0
- package/crates/tish_wasm/Cargo.toml +15 -0
- package/crates/tish_wasm/src/lib.rs +424 -0
- package/crates/tish_wasm_runtime/Cargo.toml +37 -0
- package/crates/tish_wasm_runtime/src/gpu.rs +413 -0
- package/crates/tish_wasm_runtime/src/lib.rs +42 -0
- package/crates/tishlang_cargo_bindgen/Cargo.toml +26 -0
- package/crates/tishlang_cargo_bindgen/src/classify.rs +263 -0
- package/crates/tishlang_cargo_bindgen/src/discover.rs +125 -0
- package/crates/tishlang_cargo_bindgen/src/infer.rs +382 -0
- package/crates/tishlang_cargo_bindgen/src/lib.rs +349 -0
- package/crates/tishlang_cargo_bindgen/src/main.rs +167 -0
- package/crates/tishlang_cargo_bindgen/src/metadata.rs +117 -0
- package/justfile +268 -0
- package/package.json +1 -1
- package/platform/darwin-arm64/tish-fmt +0 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
//! Global builtin functions with signature (args: &[Value]) -> Value.
|
|
2
|
+
//!
|
|
3
|
+
//! Used by both tishlang_vm (bytecode) and tishlang_runtime (compiled). Keeps tishlang_vm
|
|
4
|
+
//! independent of tishlang_runtime.
|
|
5
|
+
|
|
6
|
+
use std::sync::Arc;
|
|
7
|
+
use tishlang_core::VmRef;
|
|
8
|
+
use tishlang_core::{percent_decode, percent_encode, ObjectMap, Value};
|
|
9
|
+
|
|
10
|
+
/// Boolean(value) - coerce to bool
|
|
11
|
+
pub fn boolean(args: &[Value]) -> Value {
|
|
12
|
+
let v = args.first().unwrap_or(&Value::Null);
|
|
13
|
+
Value::Bool(v.is_truthy())
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/// decodeURI(str)
|
|
17
|
+
pub fn decode_uri(args: &[Value]) -> Value {
|
|
18
|
+
let s = args
|
|
19
|
+
.first()
|
|
20
|
+
.map(Value::to_display_string)
|
|
21
|
+
.unwrap_or_default();
|
|
22
|
+
Value::String(percent_decode(&s).unwrap_or(s).into())
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// encodeURI(str)
|
|
26
|
+
pub fn encode_uri(args: &[Value]) -> Value {
|
|
27
|
+
let s = args
|
|
28
|
+
.first()
|
|
29
|
+
.map(Value::to_display_string)
|
|
30
|
+
.unwrap_or_default();
|
|
31
|
+
Value::String(percent_encode(&s).into())
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/// isFinite(value)
|
|
35
|
+
pub fn is_finite(args: &[Value]) -> Value {
|
|
36
|
+
Value::Bool(
|
|
37
|
+
args.first()
|
|
38
|
+
.is_some_and(|v| matches!(v, Value::Number(n) if n.is_finite())),
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/// isNaN(value)
|
|
43
|
+
pub fn is_nan(args: &[Value]) -> Value {
|
|
44
|
+
Value::Bool(args.first().is_none_or(|v| {
|
|
45
|
+
matches!(v, Value::Number(n) if n.is_nan()) || !matches!(v, Value::Number(_))
|
|
46
|
+
}))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Array.isArray(value)
|
|
50
|
+
pub fn array_is_array(args: &[Value]) -> Value {
|
|
51
|
+
Value::Bool(matches!(args.first(), Some(Value::Array(_))))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// String(value) — convert value to string (JS String constructor as function).
|
|
55
|
+
pub fn string_convert(args: &[Value]) -> Value {
|
|
56
|
+
let v = args.first().unwrap_or(&Value::Null);
|
|
57
|
+
Value::String(v.to_display_string().into())
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// String.fromCharCode(...codes)
|
|
61
|
+
pub fn string_from_char_code(args: &[Value]) -> Value {
|
|
62
|
+
let s: String = args
|
|
63
|
+
.iter()
|
|
64
|
+
.filter_map(|v| match v {
|
|
65
|
+
Value::Number(n) => char::from_u32(*n as u32),
|
|
66
|
+
_ => None,
|
|
67
|
+
})
|
|
68
|
+
.collect();
|
|
69
|
+
Value::String(s.into())
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/// Object.keys(obj)
|
|
73
|
+
pub fn object_keys(args: &[Value]) -> Value {
|
|
74
|
+
if let Some(Value::Object(obj)) = args.first() {
|
|
75
|
+
let obj_borrow = obj.borrow();
|
|
76
|
+
let keys: Vec<Value> = obj_borrow
|
|
77
|
+
.strings
|
|
78
|
+
.keys()
|
|
79
|
+
.map(|k| Value::String(Arc::clone(k)))
|
|
80
|
+
.collect();
|
|
81
|
+
Value::Array(VmRef::new(keys))
|
|
82
|
+
} else {
|
|
83
|
+
Value::Array(VmRef::new(Vec::new()))
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// Object.values(obj)
|
|
88
|
+
pub fn object_values(args: &[Value]) -> Value {
|
|
89
|
+
if let Some(Value::Object(obj)) = args.first() {
|
|
90
|
+
let obj_borrow = obj.borrow();
|
|
91
|
+
let values: Vec<Value> = obj_borrow.strings.values().cloned().collect();
|
|
92
|
+
Value::Array(VmRef::new(values))
|
|
93
|
+
} else {
|
|
94
|
+
Value::Array(VmRef::new(Vec::new()))
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/// Object.entries(obj)
|
|
99
|
+
pub fn object_entries(args: &[Value]) -> Value {
|
|
100
|
+
if let Some(Value::Object(obj)) = args.first() {
|
|
101
|
+
let obj_borrow = obj.borrow();
|
|
102
|
+
let entries: Vec<Value> = obj_borrow
|
|
103
|
+
.strings
|
|
104
|
+
.iter()
|
|
105
|
+
.map(|(k, v)| Value::Array(VmRef::new(vec![Value::String(Arc::clone(k)), v.clone()])))
|
|
106
|
+
.collect();
|
|
107
|
+
Value::Array(VmRef::new(entries))
|
|
108
|
+
} else {
|
|
109
|
+
Value::Array(VmRef::new(Vec::new()))
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/// Object.assign(target, ...sources)
|
|
114
|
+
pub fn object_assign(args: &[Value]) -> Value {
|
|
115
|
+
let target = match args.first() {
|
|
116
|
+
Some(Value::Object(obj)) => obj,
|
|
117
|
+
_ => return Value::Null,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
let additional_capacity: usize = args
|
|
121
|
+
.iter()
|
|
122
|
+
.skip(1)
|
|
123
|
+
.map(|source| {
|
|
124
|
+
if let Value::Object(src) = source {
|
|
125
|
+
src.borrow().len_entries()
|
|
126
|
+
} else {
|
|
127
|
+
0
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
.sum();
|
|
131
|
+
|
|
132
|
+
let mut target_mut = target.borrow_mut();
|
|
133
|
+
target_mut.strings.reserve(additional_capacity);
|
|
134
|
+
|
|
135
|
+
for source in args.iter().skip(1) {
|
|
136
|
+
if let Value::Object(src) = source {
|
|
137
|
+
let src_borrow = src.borrow();
|
|
138
|
+
for (k, v) in src_borrow.strings.iter() {
|
|
139
|
+
target_mut.strings.insert(Arc::clone(k), v.clone());
|
|
140
|
+
}
|
|
141
|
+
if let Some(ss) = &src_borrow.symbols {
|
|
142
|
+
if target_mut.symbols.is_none() {
|
|
143
|
+
target_mut.symbols = Some(Default::default());
|
|
144
|
+
}
|
|
145
|
+
let dst = target_mut.symbols.as_mut().unwrap();
|
|
146
|
+
dst.extend(ss.iter().map(|(id, v)| (*id, v.clone())));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
drop(target_mut);
|
|
151
|
+
Value::Object(target.clone())
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/// parseInt(string, radix?)
|
|
155
|
+
pub fn parse_int(args: &[Value]) -> Value {
|
|
156
|
+
let s = args
|
|
157
|
+
.first()
|
|
158
|
+
.map(Value::to_display_string)
|
|
159
|
+
.unwrap_or_default();
|
|
160
|
+
let s = s.trim();
|
|
161
|
+
let radix = args
|
|
162
|
+
.get(1)
|
|
163
|
+
.and_then(|v| match v {
|
|
164
|
+
Value::Number(n) => Some(*n as i32),
|
|
165
|
+
_ => None,
|
|
166
|
+
})
|
|
167
|
+
.unwrap_or(10);
|
|
168
|
+
|
|
169
|
+
if (2..=36).contains(&radix) {
|
|
170
|
+
let prefix: String = s
|
|
171
|
+
.chars()
|
|
172
|
+
.take_while(|c| *c == '-' || *c == '+' || c.is_digit(radix as u32))
|
|
173
|
+
.collect();
|
|
174
|
+
if let Ok(n) = i64::from_str_radix(&prefix, radix as u32) {
|
|
175
|
+
return Value::Number(n as f64);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
Value::Number(f64::NAN)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/// parseFloat(string)
|
|
182
|
+
pub fn parse_float(args: &[Value]) -> Value {
|
|
183
|
+
let s = args
|
|
184
|
+
.first()
|
|
185
|
+
.map(Value::to_display_string)
|
|
186
|
+
.unwrap_or_default();
|
|
187
|
+
Value::Number(s.trim().parse().unwrap_or(f64::NAN))
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/// Object.fromEntries(entries)
|
|
191
|
+
pub fn object_from_entries(args: &[Value]) -> Value {
|
|
192
|
+
if let Some(Value::Array(entries)) = args.first() {
|
|
193
|
+
let entries_borrow = entries.borrow();
|
|
194
|
+
let mut obj: ObjectMap = ObjectMap::with_capacity(entries_borrow.len());
|
|
195
|
+
|
|
196
|
+
for entry in entries_borrow.iter() {
|
|
197
|
+
if let Value::Array(pair) = entry {
|
|
198
|
+
let pair_borrow = pair.borrow();
|
|
199
|
+
if pair_borrow.len() >= 2 {
|
|
200
|
+
let key: Arc<str> = match &pair_borrow[0] {
|
|
201
|
+
Value::String(s) => Arc::clone(s),
|
|
202
|
+
v => v.to_display_string().into(),
|
|
203
|
+
};
|
|
204
|
+
obj.insert(key, pair_borrow[1].clone());
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
Value::object(obj)
|
|
210
|
+
} else {
|
|
211
|
+
Value::empty_object()
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//! Common helper functions used across builtin implementations.
|
|
2
|
+
|
|
3
|
+
use std::sync::Arc;
|
|
4
|
+
use tishlang_core::{ObjectMap, Value};
|
|
5
|
+
|
|
6
|
+
/// Normalize an array index, handling negative indices.
|
|
7
|
+
/// Returns a valid index within bounds or the default value.
|
|
8
|
+
pub fn normalize_index(idx: &Value, len: i64, default: usize) -> usize {
|
|
9
|
+
match idx {
|
|
10
|
+
Value::Number(n) => {
|
|
11
|
+
let n = *n as i64;
|
|
12
|
+
if n < 0 {
|
|
13
|
+
(len + n).max(0) as usize
|
|
14
|
+
} else {
|
|
15
|
+
n.min(len) as usize
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
_ => default,
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// Create an error object with a single "error" field.
|
|
23
|
+
pub fn make_error_value(e: impl std::fmt::Display) -> Value {
|
|
24
|
+
let mut obj = ObjectMap::with_capacity(1);
|
|
25
|
+
obj.insert(Arc::from("error"), Value::String(e.to_string().into()));
|
|
26
|
+
Value::object(obj)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// Extract a number from a Value, returning None for non-numbers.
|
|
30
|
+
pub fn extract_num(v: Option<&Value>) -> Option<f64> {
|
|
31
|
+
v.and_then(|val| match val {
|
|
32
|
+
Value::Number(n) => Some(*n),
|
|
33
|
+
_ => None,
|
|
34
|
+
})
|
|
35
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//! Shared builtin implementations for Tish.
|
|
2
|
+
//!
|
|
3
|
+
//! Used by the compiled runtime (tishlang_runtime) and bytecode VM (tishlang_vm). The
|
|
4
|
+
//! interpreter (tishlang_eval) implements builtins inline due to different Value
|
|
5
|
+
//! and native signatures.
|
|
6
|
+
|
|
7
|
+
pub mod array;
|
|
8
|
+
pub mod construct;
|
|
9
|
+
pub mod globals;
|
|
10
|
+
pub mod helpers;
|
|
11
|
+
pub mod math;
|
|
12
|
+
pub mod object;
|
|
13
|
+
pub mod string;
|
|
14
|
+
pub mod symbol;
|
|
15
|
+
|
|
16
|
+
pub use tishlang_core::Value;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
//! Math builtin functions.
|
|
2
|
+
|
|
3
|
+
use crate::helpers::extract_num;
|
|
4
|
+
use tishlang_core::Value;
|
|
5
|
+
|
|
6
|
+
macro_rules! math_unary {
|
|
7
|
+
($name:ident, $op:ident) => {
|
|
8
|
+
pub fn $name(args: &[Value]) -> Value {
|
|
9
|
+
let n = extract_num(args.first()).unwrap_or(f64::NAN);
|
|
10
|
+
Value::Number(n.$op())
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
math_unary!(abs, abs);
|
|
16
|
+
math_unary!(sqrt, sqrt);
|
|
17
|
+
math_unary!(floor, floor);
|
|
18
|
+
math_unary!(ceil, ceil);
|
|
19
|
+
math_unary!(round, round);
|
|
20
|
+
math_unary!(sin, sin);
|
|
21
|
+
math_unary!(cos, cos);
|
|
22
|
+
math_unary!(tan, tan);
|
|
23
|
+
math_unary!(asin, asin);
|
|
24
|
+
math_unary!(acos, acos);
|
|
25
|
+
math_unary!(atan, atan);
|
|
26
|
+
math_unary!(log, ln);
|
|
27
|
+
math_unary!(log10, log10);
|
|
28
|
+
math_unary!(log2, log2);
|
|
29
|
+
math_unary!(exp, exp);
|
|
30
|
+
math_unary!(trunc, trunc);
|
|
31
|
+
math_unary!(cbrt, cbrt);
|
|
32
|
+
|
|
33
|
+
pub fn min(args: &[Value]) -> Value {
|
|
34
|
+
let n = args
|
|
35
|
+
.iter()
|
|
36
|
+
.filter_map(|v| extract_num(Some(v)))
|
|
37
|
+
.fold(f64::INFINITY, f64::min);
|
|
38
|
+
Value::Number(if n == f64::INFINITY { f64::NAN } else { n })
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
pub fn max(args: &[Value]) -> Value {
|
|
42
|
+
let n = args
|
|
43
|
+
.iter()
|
|
44
|
+
.filter_map(|v| extract_num(Some(v)))
|
|
45
|
+
.fold(f64::NEG_INFINITY, f64::max);
|
|
46
|
+
Value::Number(if n == f64::NEG_INFINITY { f64::NAN } else { n })
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pub fn pow(args: &[Value]) -> Value {
|
|
50
|
+
let base = extract_num(args.first()).unwrap_or(f64::NAN);
|
|
51
|
+
let exp = extract_num(args.get(1)).unwrap_or(f64::NAN);
|
|
52
|
+
Value::Number(base.powf(exp))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
pub fn random(_args: &[Value]) -> Value {
|
|
56
|
+
Value::Number(rand::random::<f64>())
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
pub fn sign(args: &[Value]) -> Value {
|
|
60
|
+
let n = extract_num(args.first()).unwrap_or(f64::NAN);
|
|
61
|
+
Value::Number(if n.is_nan() {
|
|
62
|
+
f64::NAN
|
|
63
|
+
} else if n > 0.0 {
|
|
64
|
+
1.0
|
|
65
|
+
} else if n < 0.0 {
|
|
66
|
+
-1.0
|
|
67
|
+
} else {
|
|
68
|
+
0.0
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
pub fn atan2(args: &[Value]) -> Value {
|
|
73
|
+
let y = extract_num(args.first()).unwrap_or(f64::NAN);
|
|
74
|
+
let x = extract_num(args.get(1)).unwrap_or(f64::NAN);
|
|
75
|
+
Value::Number(y.atan2(x))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
pub fn hypot(args: &[Value]) -> Value {
|
|
79
|
+
let x = extract_num(args.first()).unwrap_or(0.0);
|
|
80
|
+
let y = extract_num(args.get(1)).unwrap_or(0.0);
|
|
81
|
+
Value::Number(x.hypot(y))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/// ES6 `Math.imul`: 32-bit integer multiply (used by xmur3 PRNG in juke-cards).
|
|
85
|
+
pub fn imul(args: &[Value]) -> Value {
|
|
86
|
+
let a = extract_num(args.first()).unwrap_or(0.0) as i32;
|
|
87
|
+
let b = extract_num(args.get(1)).unwrap_or(0.0) as i32;
|
|
88
|
+
Value::Number(a.wrapping_mul(b) as f64)
|
|
89
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//! Object builtin methods.
|
|
2
|
+
//!
|
|
3
|
+
//! This module will contain shared object method implementations.
|
|
4
|
+
//! Functions will be migrated here from tishlang_runtime and tishlang_eval.
|
|
5
|
+
|
|
6
|
+
use std::sync::Arc;
|
|
7
|
+
use tishlang_core::{ObjectData, ObjectMap, Value, VmRef};
|
|
8
|
+
|
|
9
|
+
/// Create a new empty object Value.
|
|
10
|
+
pub fn new() -> Value {
|
|
11
|
+
Value::empty_object()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/// Create a new object Value with a given capacity.
|
|
15
|
+
pub fn with_capacity(capacity: usize) -> Value {
|
|
16
|
+
Value::Object(VmRef::new(ObjectData {
|
|
17
|
+
strings: ObjectMap::with_capacity(capacity),
|
|
18
|
+
symbols: None,
|
|
19
|
+
}))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// Get the keys of an object (string keys only; matches `Object.keys` in JS).
|
|
23
|
+
pub fn keys(obj: &Value) -> Option<Vec<Arc<str>>> {
|
|
24
|
+
match obj {
|
|
25
|
+
Value::Object(map) => Some(map.borrow().strings.keys().cloned().collect()),
|
|
26
|
+
_ => None,
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/// Get the values of an object (string-keyed properties only).
|
|
31
|
+
pub fn values(obj: &Value) -> Option<Vec<Value>> {
|
|
32
|
+
match obj {
|
|
33
|
+
Value::Object(map) => Some(map.borrow().strings.values().cloned().collect()),
|
|
34
|
+
_ => None,
|
|
35
|
+
}
|
|
36
|
+
}
|