use std::sync::Arc;
use arcstr::{literal, ArcStr};
use imbl::vector;
use crate::{model::{Graph, LibFunc, Param}, runtime::{instruction::Instructions, instructions::tup::{AT_REF_TUP, AT_TUP, LEN_TUP}, NumT, Type}};
pub(self) const TUP_LIB: ArcStr = literal!("Tup");
pub fn insert_tup_lib(graph: &mut Graph) {
graph.insert_libfunc(tup_len());
graph.insert_libfunc(tup_at());
}
fn tup_len() -> LibFunc {
LibFunc {
library: TUP_LIB.clone(),
name: "len".into(),
is_async: false,
docs: r#"# Tup.len(tup: (..)) -> int
Return the length of this tuple.
```rust
const tup = ("hi", 42, true);
assert_eq(tup.len(), 3);
```
"#.into(),
params: vector![
Param { name: "tup".into(), param_type: Type::Void, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(LEN_TUP.clone());
Ok(instructions)
})
}
}
fn tup_at() -> LibFunc {
LibFunc {
library: TUP_LIB.clone(),
name: "at".into(),
is_async: false,
docs: r#"# Tup.at(tup: (..), index: int) -> unknown
Return the value (optionally by reference) at the given index in the tuple.
```rust
const tup = ("hi", 42, true);
assert_eq(&tup[1], 42);
```
"#.into(),
params: vector![
Param { name: "tup".into(), param_type: Type::Void, default: None },
Param { name: "index".into(), param_type: Type::Num(NumT::Int), default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
if as_ref {
instructions.push(AT_REF_TUP.clone());
} else {
instructions.push(AT_TUP.clone());
}
Ok(instructions)
})
}
}