1
0

Add reference counting for list values

This commit is contained in:
Jeff 2023-10-26 18:03:59 -04:00
parent a5390c5150
commit 25778cc480
15 changed files with 167 additions and 83 deletions

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Identifier, Item, Map, Result, Value};
use crate::{AbstractTree, Expression, Identifier, Item, List, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Filter {
@ -30,21 +30,23 @@ impl AbstractTree for Filter {
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
let value = self.expression.run(source, context)?;
let list = value.as_list()?;
let values = value.as_list()?.items();
let key = self.identifier.inner();
let mut context = context.clone();
let mut new_list = Vec::with_capacity(list.len());
let mut new_values = Vec::with_capacity(values.len());
for value in list {
for value in values.iter() {
context.set_value(key.clone(), value.clone())?;
let should_include = self.item.run(source, &mut context)?.as_boolean()?;
if should_include {
new_list.push(value.clone());
new_values.push(value.clone());
}
}
Ok(Value::List(new_list))
let list = List::with_items(new_values);
Ok(Value::List(list))
}
}

View File

@ -30,11 +30,11 @@ impl AbstractTree for Find {
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
let value = self.expression.run(source, context)?;
let list = value.as_list()?;
let values = value.as_list()?.items();
let key = self.identifier.inner();
let mut context = context.clone();
for value in list {
for value in values.iter() {
context.set_value(key.clone(), value.clone())?;
let should_return = self.item.run(source, &mut context)?.as_boolean()?;

View File

@ -29,13 +29,13 @@ impl AbstractTree for For {
}
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
let value = self.expression.run(source, context)?;
let list = value.as_list()?;
let expression_run = self.expression.run(source, context)?;
let values = expression_run.as_list()?.items();
let key = self.identifier.inner();
let original_value = context.get_value(key)?;
for value in list {
for value in values.iter() {
context.set_value(key.clone(), value.clone())?;
self.item.run(source, context)?;

View File

@ -26,13 +26,13 @@ impl AbstractTree for Insert {
let table_name = self.identifier.inner().clone();
let mut table = self.identifier.run(source, context)?.as_table()?.clone();
let new_rows = self.expression.run(source, context)?.into_inner_list()?;
let values = new_rows.items();
table.reserve(new_rows.len());
table.reserve(values.len());
println!("{new_rows:?}");
for row in new_rows {
table.insert(row.into_inner_list()?)?;
for row in values.iter() {
let row_values = row.clone().into_inner_list()?;
table.insert(row_values.items().clone())?;
}
context.set_value(table_name, Value::Table(table))?;

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Identifier, Item, Map, Result, Value};
use crate::{AbstractTree, Expression, Identifier, Item, List, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Remove {
@ -29,30 +29,34 @@ impl AbstractTree for Remove {
}
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
let value = self.expression.run(source, context)?;
let mut list = value.into_inner_list()?;
let expression_run = self.expression.run(source, context)?;
let values = expression_run.into_inner_list()?;
let key = self.identifier.inner();
let mut sub_context = context.clone();
let mut should_remove_index = None;
for (index, value) in list.clone().iter().enumerate() {
for (index, value) in values.items().iter().enumerate() {
sub_context.set_value(key.clone(), value.clone())?;
let should_remove = self.item.run(source, &mut sub_context)?.as_boolean()?;
if should_remove {
list.remove(index);
should_remove_index = Some(index);
match &self.expression {
Expression::Identifier(identifier) => {
context.set_value(identifier.inner().clone(), Value::List(list))?;
context
.set_value(identifier.inner().clone(), Value::List(values.clone()))?;
}
_ => {}
}
return Ok(value.clone());
}
}
Ok(Value::Empty)
if let Some(index) = should_remove_index {
Ok(values.items_mut().remove(index))
} else {
Ok(Value::Empty)
}
}
}

View File

@ -11,7 +11,7 @@ use reqwest::blocking::get;
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Error, Expression, Map, Result, Table, Value, ValueType};
use crate::{AbstractTree, Error, Expression, List, Map, Result, Table, Value, ValueType};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub enum Tool {
@ -287,7 +287,7 @@ impl AbstractTree for Tool {
Ok(Value::String(data))
}
Tool::Length(expression) => {
let length = expression.run(source, context)?.as_list()?.len();
let length = expression.run(source, context)?.as_list()?.items().len();
Ok(Value::Integer(length as i64))
}
@ -399,7 +399,7 @@ impl AbstractTree for Tool {
contents.push(Value::String(file_path));
}
Value::List(contents)
Value::List(List::with_items(contents))
} else {
Value::String(read_to_string(path)?)
};
@ -517,7 +517,7 @@ impl AbstractTree for Tool {
Tool::Random(expressions) => {
if expressions.len() == 1 {
let value = expressions[0].run(source, context)?;
let list = value.as_list()?;
let list = value.as_list()?.items();
if list.len() < 2 {
return Err(Error::ExpectedMinLengthList {
@ -555,7 +555,7 @@ impl AbstractTree for Tool {
.map(|column_name| Value::String(column_name))
.collect();
Ok(Value::List(column_names))
Ok(Value::List(List::with_items(column_names)))
}
Tool::Rows(expression) => {
let rows = expression
@ -564,10 +564,10 @@ impl AbstractTree for Tool {
.rows()
.iter()
.cloned()
.map(|row| Value::List(row))
.map(|row| Value::List(List::with_items(row)))
.collect();
Ok(Value::List(rows))
Ok(Value::List(List::with_items(rows)))
}
}
}

View File

@ -1,7 +1,8 @@
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Identifier, Item, Map, Result, Value};
use crate::{AbstractTree, Expression, Identifier, Item, List, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Transform {
@ -29,19 +30,29 @@ impl AbstractTree for Transform {
}
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
let value = self.expression.run(source, context)?;
let list = value.as_list()?;
let expression_run = self.expression.run(source, context)?;
let values = expression_run.as_list()?.items();
let key = self.identifier.inner();
let mut context = context.clone();
let mut new_list = Vec::with_capacity(list.len());
let context = context.clone();
let new_list = List::with_capacity(values.len());
for value in list {
context.set_value(key.clone(), value.clone())?;
values.par_iter().try_for_each_with(
(context, new_list.clone()),
|(context, new_list), value| {
context.set_value(key.clone(), value.clone()).unwrap();
let value = self.item.run(source, &mut context)?;
let item_run = self.item.run(source, context);
new_list.push(value);
}
match item_run {
Ok(value) => {
new_list.items_mut().push(value);
Ok(())
}
Err(error) => Err(error),
}
},
)?;
Ok(Value::List(new_list))
}

View File

@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{
AbstractTree, Error, Expression, Function, Identifier, Item, Map, Result, Table, Value,
AbstractTree, Error, Expression, Function, Identifier, Item, List, Map, Result, Table, Value,
ValueType,
};
@ -157,7 +157,7 @@ impl AbstractTree for ValueNode {
values.push(value);
}
Value::List(values)
Value::List(List::with_items(values))
}
ValueType::Empty => Value::Empty,
ValueType::Map(nodes) => {
@ -185,10 +185,10 @@ impl AbstractTree for ValueNode {
}
let _row_values = row_expression.run(source, context)?;
let row_values = _row_values.as_list()?;
let row_values = _row_values.as_list()?.items();
for value in row_values {
let row = value.as_list()?.clone();
for value in row_values.iter() {
let row = value.as_list()?.items().clone();
rows.push(row)
}

View File

@ -31,7 +31,7 @@ pub fn evaluate(source: &str) -> Result<Value> {
///
/// ```rust
/// # use dust_lang::*;
/// let mut context = VariableMap::new();
/// let mut context = Map::new();
///
/// context.set_value("one".into(), 1.into());
/// context.set_value("two".into(), 2.into());
@ -96,7 +96,7 @@ impl<'context, 'code> Evaluator<'context, 'code> {
#[cfg(test)]
mod tests {
use crate::Table;
use crate::{List, Table};
use super::*;
@ -137,11 +137,11 @@ mod tests {
fn evaluate_list() {
assert_eq!(
evaluate("[1, 2, 'foobar']"),
Ok(Value::List(vec![
Ok(Value::List(List::with_items(vec![
Value::Integer(1),
Value::Integer(2),
Value::String("foobar".to_string()),
]))
])))
);
}

View File

@ -8,7 +8,7 @@ pub use crate::{
abstract_tree::*,
error::*,
evaluator::*,
value::{function::Function, map::Map, table::Table, value_type::ValueType, Value},
value::{function::Function, list::List, map::Map, table::Table, value_type::ValueType, Value},
};
mod abstract_tree;

60
src/value/list.rs Normal file
View File

@ -0,0 +1,60 @@
use std::{
cmp::Ordering,
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
};
use crate::Value;
#[derive(Debug, Clone)]
pub struct List(Arc<RwLock<Vec<Value>>>);
impl List {
pub fn new() -> Self {
List(Arc::new(RwLock::new(Vec::new())))
}
pub fn with_capacity(capacity: usize) -> Self {
List(Arc::new(RwLock::new(Vec::with_capacity(capacity))))
}
pub fn with_items(items: Vec<Value>) -> Self {
List(Arc::new(RwLock::new(items)))
}
pub fn items(&self) -> RwLockReadGuard<'_, Vec<Value>> {
self.0.read().unwrap()
}
pub fn items_mut(&self) -> RwLockWriteGuard<'_, Vec<Value>> {
self.0.write().unwrap()
}
}
impl Eq for List {}
impl PartialEq for List {
fn eq(&self, other: &Self) -> bool {
let left = self.0.read().unwrap().clone().into_iter();
let right = other.0.read().unwrap().clone().into_iter();
left.eq(right)
}
}
impl Ord for List {
fn cmp(&self, other: &Self) -> Ordering {
let left = self.0.read().unwrap().clone().into_iter();
let right = other.0.read().unwrap().clone().into_iter();
left.cmp(right)
}
}
impl PartialOrd for List {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let left = self.0.read().unwrap().clone().into_iter();
let right = other.0.read().unwrap().clone().into_iter();
left.partial_cmp(right)
}
}

View File

@ -9,7 +9,7 @@ use std::{
sync::{Arc, RwLock, RwLockReadGuard},
};
use crate::{value::Value, Error, Result, Table};
use crate::{value::Value, Error, List, Result, Table};
/// A collection dust variables comprised of key-value pairs.
///
@ -53,7 +53,7 @@ impl Map {
});
};
Ok(list.get(index).cloned())
Ok(list.items().get(index).cloned())
} else if let Value::Map(map) = value {
map.get_value(next_identifier)
} else {
@ -83,10 +83,11 @@ impl Map {
});
};
let mut missing_elements = index.saturating_sub(list.len()) + 1;
let mut missing_elements = index.saturating_sub(list.items().len()) + 1;
let mut items = list.items_mut();
while missing_elements > 0 {
list.push(value.clone());
items.push(value.clone());
missing_elements -= 1;
}
@ -197,8 +198,11 @@ impl From<&Table> for Map {
let mut map = Map::new();
for (row_index, row) in value.rows().iter().enumerate() {
map.set_value(row_index.to_string(), Value::List(row.clone()))
.unwrap();
map.set_value(
row_index.to_string(),
Value::List(List::with_items(row.clone())),
)
.unwrap();
}
map

View File

@ -1,7 +1,7 @@
//! Types that represent runtime values.
use crate::{
error::{Error, Result},
Function, Map, Table, ValueType,
Function, List, Map, Table, ValueType,
};
use json::JsonValue;
@ -20,6 +20,7 @@ use std::{
};
pub mod function;
pub mod list;
pub mod map;
pub mod table;
pub mod value_type;
@ -31,7 +32,7 @@ pub mod value_type;
/// value that can be treated as any other.
#[derive(Debug, Clone, Default)]
pub enum Value {
List(Vec<Value>),
List(List),
Map(Map),
Table(Table),
Function(Function),
@ -141,7 +142,7 @@ impl Value {
}
/// Borrows the value stored in `self` as `Vec<Value>`, or returns `Err` if `self` is not a `Value::List`.
pub fn as_list(&self) -> Result<&Vec<Value>> {
pub fn as_list(&self) -> Result<&List> {
match self {
Value::List(list) => Ok(list),
value => Err(Error::ExpectedList {
@ -151,7 +152,7 @@ impl Value {
}
/// Borrows the value stored in `self` as `Vec<Value>`, or returns `Err` if `self` is not a `Value::List`.
pub fn into_inner_list(self) -> Result<Vec<Value>> {
pub fn into_inner_list(self) -> Result<List> {
match self {
Value::List(list) => Ok(list),
value => Err(Error::ExpectedList {
@ -321,7 +322,7 @@ impl AddAssign for Value {
(Value::Float(left), Value::Float(right)) => *left += right,
(Value::Float(left), Value::Integer(right)) => *left += right as f64,
(Value::String(left), Value::String(right)) => *left += &right,
(Value::List(list), value) => list.push(value),
(Value::List(list), value) => list.items_mut().push(value),
_ => {}
}
}
@ -399,9 +400,10 @@ impl Serialize for Value {
Value::Integer(inner) => serializer.serialize_i64(*inner),
Value::Boolean(inner) => serializer.serialize_bool(*inner),
Value::List(inner) => {
let mut list = serializer.serialize_tuple(inner.len())?;
let items = inner.items();
let mut list = serializer.serialize_tuple(items.len())?;
for value in inner {
for value in items.iter() {
list.serialize_element(value)?;
}
@ -425,7 +427,7 @@ impl Display for Value {
Value::Empty => write!(f, "empty"),
Value::List(list) => {
write!(f, "[")?;
for value in list {
for value in list.items().iter() {
write!(f, " {value} ")?;
}
write!(f, "]")
@ -469,7 +471,7 @@ impl From<bool> for Value {
impl From<Vec<Value>> for Value {
fn from(vec: Vec<Value>) -> Self {
Value::List(vec)
Value::List(List::with_items(vec))
}
}
@ -509,15 +511,15 @@ impl TryFrom<JsonValue> for Value {
Ok(Value::Map(map))
}
Array(array) => {
let mut list = Vec::new();
let mut values = Vec::new();
for json_value in array {
let value = Value::try_from(json_value)?;
list.push(value);
values.push(value);
}
Ok(Value::List(list))
Ok(Value::List(List::with_items(values)))
}
}
}
@ -547,15 +549,15 @@ impl TryFrom<&JsonValue> for Value {
Ok(Value::Map(map))
}
Array(array) => {
let mut list = Vec::new();
let mut values = Vec::new();
for json_value in array {
let value = Value::try_from(json_value)?;
list.push(value);
values.push(value);
}
Ok(Value::List(list))
Ok(Value::List(List::with_items(values)))
}
}
}
@ -822,7 +824,7 @@ impl<'de> Visitor<'de> for ValueVisitor {
list.push(value);
}
Ok(Value::List(list))
Ok(Value::List(List::with_items(list)))
}
fn visit_map<M>(self, mut access: M) -> std::result::Result<Value, M::Error>

View File

@ -1,4 +1,4 @@
use crate::{Error, Map, Result, Value};
use crate::{Error, List, Map, Result, Value};
use comfy_table::{Cell, Color, ContentArrangement, Table as ComfyTable};
use serde::{Deserialize, Serialize};
use std::{
@ -146,7 +146,7 @@ impl Display for Table {
Value::List(list) => {
let mut string = "(".to_string();
for (index, value) in list.into_iter().enumerate() {
for (index, value) in list.items().iter().enumerate() {
if index > 0 {
string.push_str(", ");
}
@ -248,11 +248,11 @@ impl From<&Value> for Table {
}
}
impl From<&Vec<Value>> for Table {
fn from(list: &Vec<Value>) -> Self {
impl From<&List> for Table {
fn from(list: &List) -> Self {
let mut table = Table::new(vec!["index".to_string(), "item".to_string()]);
for (i, value) in list.iter().enumerate() {
for (i, value) in list.items().iter().enumerate() {
table
.insert(vec![Value::Integer(i as i64), value.clone()])
.unwrap();
@ -262,13 +262,13 @@ impl From<&Vec<Value>> for Table {
}
}
impl From<&mut Vec<Value>> for Table {
fn from(list: &mut Vec<Value>) -> Self {
impl From<&mut List> for Table {
fn from(list: &mut List) -> Self {
let mut table = Table::new(vec!["index".to_string(), "item".to_string()]);
for (i, value) in list.iter().enumerate() {
for (i, value) in list.items().iter().enumerate() {
if let Ok(list) = value.as_list() {
table.insert(list.clone()).unwrap();
table.insert(list.items().clone()).unwrap();
} else {
table
.insert(vec![Value::Integer(i as i64), value.clone()])

View File

@ -104,6 +104,7 @@ impl From<&Value> for ValueType {
Value::Empty => ValueType::Empty,
Value::List(list) => {
let value_nodes = list
.items()
.iter()
.map(|value| Expression::Value(ValueNode::new(value.value_type(), 0, 0)))
.collect();