Fix context error
This commit is contained in:
parent
b7e0828ced
commit
1e665a6f13
@ -79,8 +79,6 @@ impl AbstractTree for Block {
|
||||
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||
self.context.inherit_from(context)?;
|
||||
|
||||
println!("{:?}", self.context);
|
||||
|
||||
if self.is_async {
|
||||
let statements = &self.statements;
|
||||
let final_result = RwLock::new(Ok(Value::none()));
|
||||
|
@ -83,44 +83,39 @@ 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.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())
|
||||
}
|
||||
|
146
src/context.rs
146
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<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)]
|
||||
pub struct Context {
|
||||
inner: Arc<RwLock<BTreeMap<String, ValueData>>>,
|
||||
@ -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<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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ use std::{
|
||||
io,
|
||||
num::ParseFloatError,
|
||||
string::FromUtf8Error,
|
||||
sync::PoisonError,
|
||||
time,
|
||||
};
|
||||
|
||||
@ -186,3 +187,9 @@ impl From<RwLockError> for RuntimeError {
|
||||
RuntimeError::RwLock(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<PoisonError<T>> for RuntimeError {
|
||||
fn from(_: PoisonError<T>) -> Self {
|
||||
RuntimeError::RwLock(RwLockError)
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user