diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index 0189862..acf4d0d 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -20,6 +20,7 @@ use crate::{ pub struct Block { is_async: bool, statements: Vec, + context: Context, } impl AbstractTree for Block { @@ -35,12 +36,13 @@ impl AbstractTree for Block { node.child_count() - 2 }; let mut statements = Vec::with_capacity(statement_count); + let block_context = Context::inherit_from(context)?; for index in 1..node.child_count() - 1 { let child_node = node.child(index).unwrap(); if child_node.kind() == "statement" { - let statement = Statement::from_syntax(child_node, source, &context)?; + let statement = Statement::from_syntax(child_node, source, &block_context)?; statements.push(statement); } @@ -49,22 +51,23 @@ impl AbstractTree for Block { Ok(Block { is_async, statements, + context: block_context, }) } fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { for statement in &self.statements { if let Statement::Return(inner_statement) = statement { - return inner_statement.validate(_source, _context); + return inner_statement.validate(_source, &self.context); } else { - statement.validate(_source, _context)?; + statement.validate(_source, &self.context)?; } } Ok(()) } - fn run(&self, source: &str, context: &Context) -> Result { + fn run(&self, source: &str, _context: &Context) -> Result { if self.is_async { let statements = &self.statements; let final_result = RwLock::new(Ok(Value::none())); @@ -73,7 +76,7 @@ impl AbstractTree for Block { .into_par_iter() .enumerate() .find_map_first(|(index, statement)| { - let result = statement.run(source, context); + let result = statement.run(source, &self.context); let is_last_statement = index == statements.len() - 1; let is_return_statement = if let Statement::Return(_) = statement { true @@ -103,17 +106,17 @@ impl AbstractTree for Block { for statement in &self.statements { if let Statement::Return(inner_statement) = statement { - return inner_statement.run(source, context); + return inner_statement.run(source, &self.context); } - prev_result = Some(statement.run(source, context)); + prev_result = Some(statement.run(source, &self.context)); } prev_result.unwrap_or(Ok(Value::none())) } } - fn expected_type(&self, context: &Context) -> Result { + fn expected_type(&self, _context: &Context) -> Result { if let Some(statement) = self.statements.iter().find(|statement| { if let Statement::Return(_) = statement { true @@ -121,9 +124,9 @@ impl AbstractTree for Block { false } }) { - statement.expected_type(context) + statement.expected_type(&self.context) } else if let Some(statement) = self.statements.last() { - statement.expected_type(context) + statement.expected_type(&self.context) } else { Ok(Type::None) } diff --git a/src/context.rs b/src/context.rs index 8d82dfa..0e15e69 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,8 +1,11 @@ use std::{ collections::HashMap, + fmt::{self, Debug, Display, Formatter}, sync::{Arc, RwLock, RwLockReadGuard}, }; +use serde::{Deserialize, Serialize}; + use crate::{error::rw_lock_error::RwLockError, Type, Value}; #[derive(Clone)] @@ -16,6 +19,26 @@ pub enum ValueData { }, } +impl Eq for ValueData {} + +impl PartialEq for ValueData { + fn eq(&self, other: &Self) -> bool { + todo!() + } +} + +impl PartialOrd for ValueData { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for ValueData { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + todo!() + } +} + #[derive(Clone)] pub struct Context { inner: Arc>>, @@ -87,3 +110,68 @@ impl Context { Ok(()) } } + +impl Eq for Context {} + +impl PartialEq for Context { + fn eq(&self, other: &Self) -> bool { + let self_variables = self.inner().unwrap(); + let other_variables = other.inner().unwrap(); + + if self_variables.len() != other_variables.len() { + return false; + } + + for ((left_key, left_value_data), (right_key, right_value_data)) in + self_variables.iter().zip(other_variables.iter()) + { + if left_key != right_key || left_value_data != right_value_data { + return false; + } + } + + true + } +} + +impl PartialOrd for Context { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Context { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + todo!() + } +} + +impl<'de> Deserialize<'de> for Context { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + todo!() + } +} + +impl Serialize for Context { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + todo!() + } +} + +impl Debug for Context { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{self}") + } +} + +impl Display for Context { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + todo!() + } +}