dust/dust-lang/src/context.rs

99 lines
2.5 KiB
Rust
Raw Normal View History

//! Garbage-collecting context for variables.
2024-08-10 00:52:13 +00:00
use std::collections::HashMap;
use crate::{Identifier, Type, Value};
/// Garbage-collecting context for variables.
#[derive(Debug, Clone)]
2024-08-10 00:52:13 +00:00
pub struct Context {
pub variables: HashMap<Identifier, (VariableData, UsageData)>,
}
impl Context {
pub fn new() -> Self {
Self {
variables: HashMap::new(),
}
}
pub fn contains(&self, identifier: &Identifier) -> bool {
self.variables.contains_key(identifier)
}
pub fn get(&self, identifier: &Identifier) -> Option<&(VariableData, UsageData)> {
self.variables.get(identifier)
}
pub fn get_type(&self, identifier: &Identifier) -> Option<&Type> {
match self.variables.get(identifier) {
Some((VariableData::Type(r#type), _)) => Some(r#type),
_ => None,
}
}
2024-08-10 08:45:30 +00:00
pub fn use_value(&mut self, identifier: &Identifier) -> Option<&Value> {
match self.variables.get_mut(identifier) {
Some((VariableData::Value(value), usage_data)) => {
usage_data.used += 1;
Some(value)
}
2024-08-10 00:52:13 +00:00
_ => None,
}
}
pub fn get_variable_data(&self, identifier: &Identifier) -> Option<&VariableData> {
match self.variables.get(identifier) {
Some((variable_data, _)) => Some(variable_data),
_ => None,
}
}
pub fn set_type(&mut self, identifier: Identifier, r#type: Type) {
self.variables.insert(
identifier,
(VariableData::Type(r#type), UsageData::default()),
);
}
pub fn set_value(&mut self, identifier: Identifier, value: Value) {
self.variables.insert(
identifier,
(VariableData::Value(value), UsageData::default()),
);
}
pub fn collect_garbage(&mut self) {
self.variables
.retain(|_, (_, usage_data)| usage_data.used < usage_data.allowed_uses);
}
2024-08-10 08:45:30 +00:00
pub fn add_allowed_use(&mut self, identifier: &Identifier) -> bool {
if let Some((_, usage_data)) = self.variables.get_mut(identifier) {
usage_data.allowed_uses += 1;
true
} else {
false
}
}
2024-08-10 00:52:13 +00:00
}
impl Default for Context {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
2024-08-10 00:52:13 +00:00
pub enum VariableData {
Value(Value),
Type(Type),
}
#[derive(Default, Debug, Clone)]
2024-08-10 00:52:13 +00:00
pub struct UsageData {
pub allowed_uses: u16,
pub used: u16,
}