1
0

Fix context error

This commit is contained in:
Jeff 2024-02-12 15:48:43 -05:00
parent b7e0828ced
commit 1e665a6f13
5 changed files with 99 additions and 120 deletions

View File

@ -79,8 +79,6 @@ impl AbstractTree for Block {
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> { fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
self.context.inherit_from(context)?; self.context.inherit_from(context)?;
println!("{:?}", self.context);
if self.is_async { if self.is_async {
let statements = &self.statements; let statements = &self.statements;
let final_result = RwLock::new(Ok(Value::none())); let final_result = RwLock::new(Ok(Value::none()));

View File

@ -83,45 +83,40 @@ impl AbstractTree for For {
if let Value::Range(range) = expression_run { if let Value::Range(range) = expression_run {
if self.is_async { if self.is_async {
range.into_par_iter().try_for_each(|integer| { range.into_par_iter().try_for_each(|integer| {
let iter_context = Context::with_variables_from(context)?; self.block
.context()
iter_context.set_value(key.clone(), Value::Integer(integer))?; .set_value(key.clone(), Value::Integer(integer))?;
self.block.run(source, context).map(|_value| ())
self.block.run(source, &iter_context).map(|_value| ())
})?; })?;
} else { } else {
let loop_context = Context::with_variables_from(context)?;
for i in range { for i in range {
loop_context.set_value(key.clone(), Value::Integer(i))?; self.block
.context()
self.block.run(source, &loop_context)?; .set_value(key.clone(), Value::Integer(i))?;
self.block.run(source, context)?;
} }
} }
return Ok(Value::none()); return Ok(Value::none());
} }
if let Value::List(list) = expression_run { if let Value::List(list) = &expression_run {
if self.is_async { if self.is_async {
list.items().par_iter().try_for_each(|value| { list.items().par_iter().try_for_each(|value| {
let iter_context = Context::with_variables_from(context)?; self.block.context().set_value(key.clone(), value.clone())?;
self.block.run(source, context).map(|_value| ())
iter_context.set_value(key.clone(), value.clone())?;
self.block.run(source, &iter_context).map(|_value| ())
})?; })?;
} else { } else {
let loop_context = Context::with_variables_from(context)?;
for value in list.items().iter() { for value in list.items().iter() {
loop_context.set_value(key.clone(), value.clone())?; self.block.context().set_value(key.clone(), value.clone())?;
self.block.run(source, context)?;
self.block.run(source, &loop_context)?;
} }
} }
} }
self.block.context().unset(&key)?;
context.inherit_from(self.block.context())?;
Ok(Value::none()) Ok(Value::none())
} }
} }

View File

@ -6,76 +6,6 @@ use std::{
use crate::{error::rw_lock_error::RwLockError, Type, Value}; use crate::{error::rw_lock_error::RwLockError, Type, Value};
#[derive(Clone, Debug)]
pub enum ValueData {
Value {
inner: Value,
runtime_uses: Arc<RwLock<u16>>,
},
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<std::cmp::Ordering> {
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)] #[derive(Clone, Debug)]
pub struct Context { pub struct Context {
inner: Arc<RwLock<BTreeMap<String, ValueData>>>, inner: Arc<RwLock<BTreeMap<String, ValueData>>>,
@ -156,6 +86,12 @@ impl Context {
Ok(()) Ok(())
} }
pub fn unset(&self, key: &str) -> Result<(), RwLockError> {
self.inner.write()?.remove(key);
Ok(())
}
} }
impl Default for Context { impl Default for Context {
@ -201,3 +137,73 @@ impl Ord for Context {
left.cmp(&right) left.cmp(&right)
} }
} }
#[derive(Clone, Debug)]
pub enum ValueData {
Value {
inner: Value,
runtime_uses: Arc<RwLock<u16>>,
},
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<std::cmp::Ordering> {
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,
}
}
}

View File

@ -3,6 +3,7 @@ use std::{
io, io,
num::ParseFloatError, num::ParseFloatError,
string::FromUtf8Error, string::FromUtf8Error,
sync::PoisonError,
time, time,
}; };
@ -186,3 +187,9 @@ impl From<RwLockError> for RuntimeError {
RuntimeError::RwLock(error) RuntimeError::RwLock(error)
} }
} }
impl<T> From<PoisonError<T>> for RuntimeError {
fn from(_: PoisonError<T>) -> Self {
RuntimeError::RwLock(RwLockError)
}
}

View File

@ -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] #[test]
fn modify_list() { fn modify_list() {
let result = interpret( let result = interpret(