Mark 35efae75ac
Some checks failed
Rust / build (push) Has been cancelled
improve .try resolving types, removes subtypes methods
2025-07-15 14:53:54 +02:00

83 lines
3.4 KiB
Rust
Executable File

use std::sync::{Arc, Mutex};
use crate::{
data::{self, int::INT_MAX, Data, MersTypeWInfo, Type},
program::{self, run::CheckInfo},
};
use super::Config;
impl Config {
/// `get: fn` is used to retrieve elements from collections
pub fn with_get(self) -> Self {
self.add_var(
"get",
data::function::Function {
info: program::run::Info::neverused(),
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
fixed_type: None,
fixed_type_out: Arc::new(Mutex::new(None)),
out: Ok(Arc::new(|a, i| {
let mut out = Type::empty();
for a in a.types.iter() {
if let Some(t) = a.as_any().downcast_ref::<data::tuple::TupleT>() {
if t.0.len() != 2 {
return Err(format!("called get on tuple with len != 2").into());
}
if !t.0[1].is_included_in_single(&data::int::IntT(0, INT_MAX)) {
return Err(format!(
"called get with non-int index of type {}",
t.0[1].with_info(i)
)
.into());
}
if let Some(v) = t.0[0].get() {
out.add_all(&v);
} else {
return Err(format!(
"called get on non-gettable type {}, part of {}",
t.with_info(i),
a.with_info(i)
)
.into());
}
} else {
return Err(
format!("called get on non-tuple type {}", a.with_info(i)).into()
);
}
}
Ok(Type::newm(vec![
Arc::new(data::tuple::TupleT(vec![out])),
Arc::new(data::tuple::TupleT(vec![])),
]))
})),
run: Arc::new(|a, i| {
let a = a.get();
if let (Some(v), Some(x)) = (a.get(0, &i.global), a.get(1, &i.global)) {
let (v, x2) = (v?, x?);
let o = if let Some(x3) = x2.get().as_any().downcast_ref::<data::int::Int>()
{
if let Ok(x) = x3.0.try_into() {
if let Some(v) = v.get().get(x, &i.global) {
Ok(Data::one_tuple(v?))
} else {
Ok(Data::empty_tuple())
}
} else {
Ok(Data::empty_tuple())
}
} else {
Err("get called with non-int index".into())
};
o
} else {
Err("get called with less than 2 args".into())
}
}),
inner_statements: None,
},
)
}
}