2024-02-25 18:49:26 +00:00
|
|
|
use std::{
|
|
|
|
collections::BTreeMap,
|
|
|
|
sync::{Arc, RwLock},
|
|
|
|
};
|
|
|
|
|
2024-03-06 23:15:25 +00:00
|
|
|
use crate::{
|
|
|
|
abstract_tree::{Identifier, Type},
|
2024-03-19 22:31:52 +00:00
|
|
|
error::{RwLockPoisonError, ValidationError},
|
2024-03-18 12:15:30 +00:00
|
|
|
value::{BUILT_IN_FUNCTIONS, BUILT_IN_MODULES},
|
2024-03-06 23:15:25 +00:00
|
|
|
Value,
|
|
|
|
};
|
2024-02-25 18:49:26 +00:00
|
|
|
|
2024-03-12 01:57:27 +00:00
|
|
|
#[derive(Clone, Debug)]
|
2024-03-17 17:36:31 +00:00
|
|
|
pub struct Context {
|
|
|
|
inner: Arc<RwLock<BTreeMap<Identifier, ValueData>>>,
|
2024-02-25 18:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Context {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
Self {
|
|
|
|
inner: Arc::new(RwLock::new(BTreeMap::new())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
pub fn with_data(data: BTreeMap<Identifier, ValueData>) -> Self {
|
2024-02-25 18:49:26 +00:00
|
|
|
Self {
|
2024-03-06 23:15:25 +00:00
|
|
|
inner: Arc::new(RwLock::new(data)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
pub fn inherit_types_from(&self, other: &Context) -> Result<(), RwLockPoisonError> {
|
|
|
|
let mut self_data = self.inner.write()?;
|
2024-03-10 18:48:53 +00:00
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
for (identifier, value_data) in other.inner.read()?.iter() {
|
2024-03-20 04:28:28 +00:00
|
|
|
if let ValueData::Type(Type::Function { .. }) = value_data {
|
|
|
|
self_data.insert(identifier.clone(), value_data.clone());
|
2024-03-10 18:48:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
Ok(())
|
2024-03-10 18:48:53 +00:00
|
|
|
}
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
pub fn inherit_data_from(&self, other: &Context) -> Result<(), RwLockPoisonError> {
|
|
|
|
let mut self_data = self.inner.write()?;
|
2024-03-10 18:48:53 +00:00
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
for (identifier, value_data) in other.inner.read()?.iter() {
|
|
|
|
self_data.insert(identifier.clone(), value_data.clone());
|
2024-03-10 18:48:53 +00:00
|
|
|
}
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
Ok(())
|
2024-03-10 18:48:53 +00:00
|
|
|
}
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
pub fn contains(&self, identifier: &Identifier) -> Result<bool, RwLockPoisonError> {
|
2024-03-17 22:03:43 +00:00
|
|
|
if self.inner.read()?.contains_key(identifier) {
|
|
|
|
Ok(true)
|
|
|
|
} else {
|
2024-03-18 12:15:30 +00:00
|
|
|
for module in BUILT_IN_MODULES {
|
|
|
|
if identifier.as_str() == module.name() {
|
|
|
|
return Ok(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for function in BUILT_IN_FUNCTIONS {
|
|
|
|
if identifier.as_str() == function.name() {
|
|
|
|
return Ok(true);
|
|
|
|
}
|
2024-03-17 22:03:43 +00:00
|
|
|
}
|
2024-03-18 12:15:30 +00:00
|
|
|
|
|
|
|
Ok(false)
|
2024-03-17 22:03:43 +00:00
|
|
|
}
|
2024-03-12 01:57:27 +00:00
|
|
|
}
|
|
|
|
|
2024-03-19 22:31:52 +00:00
|
|
|
pub fn get_type(&self, identifier: &Identifier) -> Result<Option<Type>, ValidationError> {
|
2024-03-17 17:36:31 +00:00
|
|
|
if let Some(value_data) = self.inner.read()?.get(identifier) {
|
|
|
|
let r#type = match value_data {
|
|
|
|
ValueData::Type(r#type) => r#type.clone(),
|
2024-03-19 22:31:52 +00:00
|
|
|
ValueData::Value(value) => value.r#type(self)?,
|
2024-03-12 01:57:27 +00:00
|
|
|
};
|
|
|
|
|
2024-03-09 11:55:19 +00:00
|
|
|
return Ok(Some(r#type.clone()));
|
2024-03-06 23:15:25 +00:00
|
|
|
}
|
2024-03-09 11:55:19 +00:00
|
|
|
|
2024-03-18 12:15:30 +00:00
|
|
|
for module in BUILT_IN_MODULES {
|
|
|
|
if identifier.as_str() == module.name() {
|
|
|
|
return Ok(Some(module.r#type()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for function in BUILT_IN_MODULES {
|
|
|
|
if identifier.as_str() == function.name() {
|
|
|
|
return Ok(Some(function.r#type()));
|
|
|
|
}
|
|
|
|
}
|
2024-03-09 11:55:19 +00:00
|
|
|
|
2024-03-18 12:15:30 +00:00
|
|
|
Ok(None)
|
2024-03-06 23:15:25 +00:00
|
|
|
}
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
pub fn get_value(&self, identifier: &Identifier) -> Result<Option<Value>, RwLockPoisonError> {
|
|
|
|
if let Some(ValueData::Value(value)) = self.inner.read()?.get(identifier) {
|
|
|
|
Ok(Some(value.clone()))
|
2024-03-12 01:57:27 +00:00
|
|
|
} else {
|
2024-03-18 12:15:30 +00:00
|
|
|
for module in BUILT_IN_MODULES {
|
|
|
|
if identifier.as_str() == module.name() {
|
|
|
|
return Ok(Some(module.value()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for function in BUILT_IN_MODULES {
|
|
|
|
if identifier.as_str() == function.name() {
|
|
|
|
return Ok(Some(function.value()));
|
|
|
|
}
|
|
|
|
}
|
2024-03-12 01:57:27 +00:00
|
|
|
|
2024-03-18 12:15:30 +00:00
|
|
|
Ok(None)
|
2024-02-25 18:49:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-06 23:15:25 +00:00
|
|
|
pub fn set_type(&self, identifier: Identifier, r#type: Type) -> Result<(), RwLockPoisonError> {
|
|
|
|
self.inner
|
|
|
|
.write()?
|
2024-03-17 17:36:31 +00:00
|
|
|
.insert(identifier, ValueData::Type(r#type));
|
2024-02-25 18:49:26 +00:00
|
|
|
|
2024-03-06 23:15:25 +00:00
|
|
|
Ok(())
|
2024-02-25 18:49:26 +00:00
|
|
|
}
|
|
|
|
|
2024-03-06 23:15:25 +00:00
|
|
|
pub fn set_value(&self, identifier: Identifier, value: Value) -> Result<(), RwLockPoisonError> {
|
2024-03-12 01:57:27 +00:00
|
|
|
let mut inner = self.inner.write()?;
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
inner.insert(identifier, ValueData::Value(value));
|
2024-02-25 18:49:26 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
2024-03-17 17:36:31 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub enum ValueData {
|
|
|
|
Type(Type),
|
|
|
|
Value(Value),
|
|
|
|
}
|