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> {
|
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()));
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
146
src/context.rs
146
src/context.rs
@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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(
|
||||||
|
Loading…
Reference in New Issue
Block a user