From 1e665a6f1311d0aa4fe9a88f6a94909abfdc7750 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 12 Feb 2024 15:48:43 -0500 Subject: [PATCH] Fix context error --- src/abstract_tree/block.rs | 2 - src/abstract_tree/for.rs | 37 ++++------ src/context.rs | 146 +++++++++++++++++++------------------ src/error/runtime_error.rs | 7 ++ tests/for_loop.rs | 27 ------- 5 files changed, 99 insertions(+), 120 deletions(-) diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index ff73a67..bbffc1c 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -79,8 +79,6 @@ impl AbstractTree for Block { fn run(&self, source: &str, context: &Context) -> Result { self.context.inherit_from(context)?; - println!("{:?}", self.context); - if self.is_async { let statements = &self.statements; let final_result = RwLock::new(Ok(Value::none())); diff --git a/src/abstract_tree/for.rs b/src/abstract_tree/for.rs index 8ba104d..02d5b91 100644 --- a/src/abstract_tree/for.rs +++ b/src/abstract_tree/for.rs @@ -83,45 +83,40 @@ impl AbstractTree for For { if let Value::Range(range) = expression_run { if self.is_async { range.into_par_iter().try_for_each(|integer| { - let iter_context = Context::with_variables_from(context)?; - - iter_context.set_value(key.clone(), Value::Integer(integer))?; - - self.block.run(source, &iter_context).map(|_value| ()) + self.block + .context() + .set_value(key.clone(), Value::Integer(integer))?; + self.block.run(source, context).map(|_value| ()) })?; } else { - let loop_context = Context::with_variables_from(context)?; - for i in range { - loop_context.set_value(key.clone(), Value::Integer(i))?; - - self.block.run(source, &loop_context)?; + self.block + .context() + .set_value(key.clone(), Value::Integer(i))?; + self.block.run(source, context)?; } } return Ok(Value::none()); } - if let Value::List(list) = expression_run { + if let Value::List(list) = &expression_run { if self.is_async { list.items().par_iter().try_for_each(|value| { - let iter_context = Context::with_variables_from(context)?; - - iter_context.set_value(key.clone(), value.clone())?; - - self.block.run(source, &iter_context).map(|_value| ()) + self.block.context().set_value(key.clone(), value.clone())?; + self.block.run(source, context).map(|_value| ()) })?; } else { - let loop_context = Context::with_variables_from(context)?; - for value in list.items().iter() { - loop_context.set_value(key.clone(), value.clone())?; - - self.block.run(source, &loop_context)?; + self.block.context().set_value(key.clone(), value.clone())?; + self.block.run(source, context)?; } } } + self.block.context().unset(&key)?; + context.inherit_from(self.block.context())?; + Ok(Value::none()) } } diff --git a/src/context.rs b/src/context.rs index 13a07e2..b3db8cf 100644 --- a/src/context.rs +++ b/src/context.rs @@ -6,76 +6,6 @@ use std::{ use crate::{error::rw_lock_error::RwLockError, Type, Value}; -#[derive(Clone, Debug)] -pub enum ValueData { - Value { - inner: Value, - runtime_uses: Arc>, - }, - ExpectedType { - inner: Type, - }, -} - -impl Eq for ValueData {} - -impl PartialEq for ValueData { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - ( - ValueData::Value { - inner: left_inner, - runtime_uses: left_runtime_uses, - }, - ValueData::Value { - inner: right_inner, - runtime_uses: right_runtime_uses, - }, - ) => { - if left_inner != right_inner { - return false; - } else { - *left_runtime_uses.read().unwrap() == *right_runtime_uses.read().unwrap() - } - } - ( - ValueData::ExpectedType { inner: left_inner }, - ValueData::ExpectedType { inner: right_inner }, - ) => left_inner == right_inner, - _ => false, - } - } -} - -impl PartialOrd for ValueData { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for ValueData { - fn cmp(&self, other: &Self) -> Ordering { - use Ordering::*; - - match (self, other) { - ( - ValueData::Value { - inner: inner_left, .. - }, - ValueData::Value { - inner: inner_right, .. - }, - ) => inner_left.cmp(inner_right), - (ValueData::Value { .. }, _) => Greater, - ( - ValueData::ExpectedType { inner: inner_left }, - ValueData::ExpectedType { inner: inner_right }, - ) => inner_left.cmp(inner_right), - (ValueData::ExpectedType { .. }, _) => Less, - } - } -} - #[derive(Clone, Debug)] pub struct Context { inner: Arc>>, @@ -156,6 +86,12 @@ impl Context { Ok(()) } + + pub fn unset(&self, key: &str) -> Result<(), RwLockError> { + self.inner.write()?.remove(key); + + Ok(()) + } } impl Default for Context { @@ -201,3 +137,73 @@ impl Ord for Context { left.cmp(&right) } } + +#[derive(Clone, Debug)] +pub enum ValueData { + Value { + inner: Value, + runtime_uses: Arc>, + }, + ExpectedType { + inner: Type, + }, +} + +impl Eq for ValueData {} + +impl PartialEq for ValueData { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + ( + ValueData::Value { + inner: left_inner, + runtime_uses: left_runtime_uses, + }, + ValueData::Value { + inner: right_inner, + runtime_uses: right_runtime_uses, + }, + ) => { + if left_inner != right_inner { + return false; + } else { + *left_runtime_uses.read().unwrap() == *right_runtime_uses.read().unwrap() + } + } + ( + ValueData::ExpectedType { inner: left_inner }, + ValueData::ExpectedType { inner: right_inner }, + ) => left_inner == right_inner, + _ => false, + } + } +} + +impl PartialOrd for ValueData { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for ValueData { + fn cmp(&self, other: &Self) -> Ordering { + use Ordering::*; + + match (self, other) { + ( + ValueData::Value { + inner: inner_left, .. + }, + ValueData::Value { + inner: inner_right, .. + }, + ) => inner_left.cmp(inner_right), + (ValueData::Value { .. }, _) => Greater, + ( + ValueData::ExpectedType { inner: inner_left }, + ValueData::ExpectedType { inner: inner_right }, + ) => inner_left.cmp(inner_right), + (ValueData::ExpectedType { .. }, _) => Less, + } + } +} diff --git a/src/error/runtime_error.rs b/src/error/runtime_error.rs index 77c87e5..68eb221 100644 --- a/src/error/runtime_error.rs +++ b/src/error/runtime_error.rs @@ -3,6 +3,7 @@ use std::{ io, num::ParseFloatError, string::FromUtf8Error, + sync::PoisonError, time, }; @@ -186,3 +187,9 @@ impl From for RuntimeError { RuntimeError::RwLock(error) } } + +impl From> for RuntimeError { + fn from(_: PoisonError) -> Self { + RuntimeError::RwLock(RwLockError) + } +} diff --git a/tests/for_loop.rs b/tests/for_loop.rs index 44a774a..221d5ea 100644 --- a/tests/for_loop.rs +++ b/tests/for_loop.rs @@ -31,33 +31,6 @@ fn range_for_loop() { ); } -#[test] -fn map_for_loop() { - let result = interpret( - " - map = { - x = 'y' - foo = 'bar' - } - list = [] - - for [key, value] in map { - list += value - } - - list - ", - ); - - assert_eq!( - Ok(Value::List(List::with_items(vec![ - Value::String("y".to_string()), - Value::String("bar".to_string()), - ]))), - result - ); -} - #[test] fn modify_list() { let result = interpret(