use crate::*;
pub fn new_env() -> Robj {
new_env_with_capacity(14)
}
pub fn new_env_with_capacity(capacity: usize) -> Robj {
if capacity <= 5 {
call!("new.env", FALSE, global_env(), 0).unwrap()
} else {
call!("new.env", TRUE, global_env(), capacity as i32 * 2 + 1).unwrap()
}
}
pub fn global_var<K: Into<Robj>>(key: K) -> Result<Robj> {
global_env()
.find_var(key)
.ok_or_else(|| Error::NotFound)
.and_then(|v| v.eval_promise())
}
pub fn local_var<K: Into<Robj>>(key: K) -> Result<Robj> {
current_env()
.find_var(key)
.ok_or_else(|| Error::NotFound)
.and_then(|v| v.eval_promise())
}
pub fn global_function<K: Into<Robj>>(key: K) -> Option<Robj> {
global_env().find_function(key)
}
pub fn find_namespace<K: Into<Robj>>(key: K) -> Option<Robj> {
let res = single_threaded(|| call!(".getNamespace", key.into()));
if let Ok(res) = res {
Some(res)
} else {
None
}
}
pub fn current_env() -> Robj {
unsafe { new_owned(R_GetCurrentEnv()) }
}
pub fn global_env() -> Robj {
unsafe { new_sys(R_GlobalEnv) }
}
pub fn empty_env() -> Robj {
unsafe { new_sys(R_EmptyEnv) }
}
pub fn base_env() -> Robj {
unsafe { new_sys(R_BaseEnv) }
}
pub fn base_namespace() -> Robj {
unsafe { new_sys(R_BaseNamespace) }
}
pub fn namespace_registry() -> Robj {
unsafe { new_sys(R_NamespaceRegistry) }
}
pub fn srcref() -> Robj {
unsafe { new_sys(R_Srcref) }
}
pub fn nil_value() -> Robj {
unsafe { new_sys(R_NilValue) }
}
pub fn unbound_value() -> Robj {
unsafe { new_sys(R_UnboundValue) }
}
pub fn missing_arg() -> Robj {
unsafe { new_sys(R_MissingArg) }
}
pub fn base_symbol() -> Robj {
unsafe { new_sys(R_BaseSymbol) }
}
pub fn brace_symbol() -> Robj {
unsafe { new_sys(R_BraceSymbol) }
}
pub fn bracket_2_symbol() -> Robj {
unsafe { new_sys(R_Bracket2Symbol) }
}
pub fn bracket_symbol() -> Robj {
unsafe { new_sys(R_BracketSymbol) }
}
pub fn class_symbol() -> Robj {
unsafe { new_sys(R_ClassSymbol) }
}
pub fn device_symbol() -> Robj {
unsafe { new_sys(R_DeviceSymbol) }
}
pub fn dimnames_symbol() -> Robj {
unsafe { new_sys(R_DimNamesSymbol) }
}
pub fn dim_symbol() -> Robj {
unsafe { new_sys(R_DimSymbol) }
}
pub fn dollar_symbol() -> Robj {
unsafe { new_sys(R_DollarSymbol) }
}
pub fn dots_symbol() -> Robj {
unsafe { new_sys(R_DotsSymbol) }
}
pub fn double_colon_symbol() -> Robj {
unsafe { new_sys(R_DoubleColonSymbol) }
}
pub fn lastvalue_symbol() -> Robj {
unsafe { new_sys(R_LastvalueSymbol) }
}
pub fn levels_symbol() -> Robj {
unsafe { new_sys(R_LevelsSymbol) }
}
pub fn mode_symbol() -> Robj {
unsafe { new_sys(R_ModeSymbol) }
}
pub fn na_rm_symbol() -> Robj {
unsafe { new_sys(R_NaRmSymbol) }
}
pub fn name_symbol() -> Robj {
unsafe { new_sys(R_NameSymbol) }
}
pub fn names_symbol() -> Robj {
unsafe { new_sys(R_NamesSymbol) }
}
pub fn namespace_env_symbol() -> Robj {
unsafe { new_sys(R_NamespaceEnvSymbol) }
}
pub fn package_symbol() -> Robj {
unsafe { new_sys(R_PackageSymbol) }
}
pub fn previous_symbol() -> Robj {
unsafe { new_sys(R_PreviousSymbol) }
}
pub fn quote_symbol() -> Robj {
unsafe { new_sys(R_QuoteSymbol) }
}
pub fn row_names_symbol() -> Robj {
unsafe { new_sys(R_RowNamesSymbol) }
}
pub fn seeds_symbol() -> Robj {
unsafe { new_sys(R_SeedsSymbol) }
}
pub fn sort_list_symbol() -> Robj {
unsafe { new_sys(R_SortListSymbol) }
}
pub fn source_symbol() -> Robj {
unsafe { new_sys(R_SourceSymbol) }
}
pub fn spec_symbol() -> Robj {
unsafe { new_sys(R_SpecSymbol) }
}
pub fn tsp_symbol() -> Robj {
unsafe { new_sys(R_TspSymbol) }
}
pub fn triple_colon_symbol() -> Robj {
unsafe { new_sys(R_TripleColonSymbol) }
}
pub fn dot_defined() -> Robj {
unsafe { new_sys(R_dot_defined) }
}
pub fn dot_method() -> Robj {
unsafe { new_sys(R_dot_Method) }
}
pub fn dot_package_name() -> Robj {
unsafe { new_sys(R_dot_packageName) }
}
pub fn dot_target() -> Robj {
unsafe { new_sys(R_dot_target) }
}
pub fn na_string() -> Robj {
unsafe { new_sys(R_NaString) }
}
pub fn blank_string() -> Robj {
unsafe { new_sys(R_BlankString) }
}
pub fn blank_scalar_string() -> Robj {
unsafe { new_sys(R_BlankScalarString) }
}
pub fn na_str() -> &'static str {
unsafe { std::str::from_utf8_unchecked(&[b'N', b'A']) }
}
pub fn parse(code: &str) -> Result<Robj> {
single_threaded(|| unsafe {
use libR_sys::*;
let mut status = 0_u32;
let status_ptr = &mut status as *mut u32;
let codeobj: Robj = code.into();
let parsed = new_owned(R_ParseVector(codeobj.get(), -1, status_ptr, R_NilValue));
match status {
1 => Ok(parsed),
_ => Err(Error::ParseError {
code: code.into(),
status,
}),
}
})
}
pub fn eval_string(code: &str) -> Result<Robj> {
single_threaded(|| {
let expr = parse(code)?;
let mut res = Robj::from(());
if let Some(iter) = expr.as_list_iter() {
for lang in iter {
res = lang.eval()?
}
}
Ok(res)
})
}