diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index c4d8441..1f10e35 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -4,7 +4,7 @@ use rayon::prelude::*; use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Format, Map, Result, Statement, Type, Value}; +use crate::{AbstractTree, Error, Expression, Format, Map, Result, Statement, Type, Value}; /// Abstract representation of a block. /// @@ -136,8 +136,26 @@ impl Format for Block { output.push_str("{\n"); } - for statement in &self.statements { - statement.format(output, indent_level + 1); + let mut previous: Option<&Statement> = None; + + for next_statement in &self.statements { + if let Some(previous_statement) = &previous { + match previous_statement { + Statement::While(_) | Statement::Expression(Expression::FunctionCall(_)) => { + output.push('\n'); + } + _ => {} + } + } + + match next_statement { + Statement::Block(_) | Statement::While(_) => output.push('\n'), + _ => {} + } + + next_statement.format(output, indent_level + 1); + + previous = Some(next_statement); } output.push('\n'); diff --git a/src/abstract_tree/index.rs b/src/abstract_tree/index.rs index 9bc64c1..df1f5fb 100644 --- a/src/abstract_tree/index.rs +++ b/src/abstract_tree/index.rs @@ -81,7 +81,7 @@ impl AbstractTree for Index { } Value::String(string) => { let index = self.index.run(source, context)?.as_integer()? as usize; - let item = string.read()?.chars().nth(index).unwrap_or_default(); + let item = string.chars().nth(index).unwrap_or_default(); Ok(Value::string(item.to_string())) } diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index ab217b5..4f09ed6 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -123,8 +123,12 @@ impl AbstractTree for Root { impl Format for Root { fn format(&self, output: &mut String, indent_level: u8) { - for statement in &self.statements { + for (index, statement) in self.statements.iter().enumerate() { + if index > 1 { + output.push('\n'); + } statement.format(output, indent_level); + output.push('\n'); } } } diff --git a/src/abstract_tree/statement.rs b/src/abstract_tree/statement.rs index 364f58f..8ed43e5 100644 --- a/src/abstract_tree/statement.rs +++ b/src/abstract_tree/statement.rs @@ -128,7 +128,5 @@ impl Format for Statement { } Statement::Return(statement) => statement.format(output, indent_level), } - - output.push('\n'); } } diff --git a/src/abstract_tree/while.rs b/src/abstract_tree/while.rs index 24a9591..21de6e9 100644 --- a/src/abstract_tree/while.rs +++ b/src/abstract_tree/while.rs @@ -40,9 +40,12 @@ impl AbstractTree for While { impl Format for While { fn format(&self, output: &mut String, indent_level: u8) { + output.push('\n'); + While::indent(output, indent_level); output.push_str("while "); self.expression.format(output, indent_level); output.push(' '); self.block.format(output, indent_level); + output.push('\n'); } } diff --git a/src/built_in_functions/string.rs b/src/built_in_functions/string.rs index 3efbc2c..495218e 100644 --- a/src/built_in_functions/string.rs +++ b/src/built_in_functions/string.rs @@ -18,8 +18,6 @@ pub enum StringFunction { Lines, Matches, Parse, - Pop, - Push, Remove, ReplaceRange, Retain, @@ -55,8 +53,6 @@ impl StringFunction { StringFunction::Lines => "lines", StringFunction::Matches => "matches", StringFunction::Parse => "parse", - StringFunction::Pop => "pop", - StringFunction::Push => "push", StringFunction::Remove => "remove", StringFunction::ReplaceRange => "replace_range", StringFunction::Retain => "retain", @@ -93,9 +89,10 @@ impl StringFunction { vec![Type::String, Type::String], Type::option(Type::Integer), ), - StringFunction::Insert => { - Type::function(vec![Type::String, Type::Integer, Type::String], Type::None) - } + StringFunction::Insert => Type::function( + vec![Type::String, Type::Integer, Type::String], + Type::String, + ), StringFunction::IsAscii => Type::function(vec![Type::String], Type::Boolean), StringFunction::IsEmpty => Type::function(vec![Type::String], Type::Boolean), StringFunction::Lines => Type::function(vec![Type::String], Type::list(Type::String)), @@ -103,22 +100,20 @@ impl StringFunction { Type::function(vec![Type::String, Type::String], Type::list(Type::String)) } StringFunction::Parse => Type::function(vec![Type::String], Type::Any), - StringFunction::Pop => Type::function(vec![], Type::option(Type::String)), - StringFunction::Push => Type::function(vec![Type::String], Type::None), StringFunction::Remove => Type::function( vec![Type::String, Type::Integer], Type::option(Type::String), ), StringFunction::ReplaceRange => Type::function( vec![Type::String, Type::list(Type::Integer), Type::String], - Type::None, + Type::String, ), StringFunction::Retain => Type::function( vec![ Type::String, Type::function(vec![Type::String], Type::Boolean), ], - Type::None, + Type::String, ), StringFunction::Split => { Type::function(vec![Type::String, Type::String], Type::list(Type::String)) @@ -151,7 +146,7 @@ impl StringFunction { StringFunction::ToLowercase => Type::function(vec![Type::String], Type::String), StringFunction::ToUppercase => Type::function(vec![Type::String], Type::String), StringFunction::Truncate => { - Type::function(vec![Type::String, Type::Integer], Type::None) + Type::function(vec![Type::String, Type::Integer], Type::String) } StringFunction::Trim => Type::function(vec![Type::String], Type::String), StringFunction::TrimEnd => Type::function(vec![Type::String], Type::String), @@ -219,13 +214,13 @@ impl StringFunction { StringFunction::Insert => { Error::expect_argument_amount(self.name(), 3, arguments.len())?; - let mut string = arguments.get(0).unwrap().as_string()?.to_string(); + let mut string = arguments.get(0).unwrap().as_string()?.clone(); let index = arguments.get(1).unwrap().as_integer()? as usize; let insertion = arguments.get(2).unwrap().as_string()?; string.insert_str(index, &insertion); - Value::none() + Value::String(string) } StringFunction::Lines => { Error::expect_argument_amount(self.name(), 1, arguments.len())?; @@ -264,41 +259,20 @@ impl StringFunction { Value::none() } } - StringFunction::Pop => { - Error::expect_argument_amount(self.name(), 1, arguments.len())?; - - let mut string = arguments.first().unwrap().as_string_mut()?; - let popped = string.pop().map(|char| Value::string(char.to_string())); - - Value::option(popped) - } - StringFunction::Push => { - Error::expect_argument_amount(self.name(), 2, arguments.len())?; - - let mut string = arguments.get(0).unwrap().as_string_mut()?; - let addition = arguments.get(1).unwrap().as_string()?; - - string.push_str(&addition); - - Value::none() - } StringFunction::Remove => { Error::expect_argument_amount(self.name(), 2, arguments.len())?; - let mut string = arguments.get(0).unwrap().as_string_mut()?; + let string = arguments.get(0).unwrap().as_string()?; let index = arguments.get(1).unwrap().as_integer()? as usize; - let mut chars = string.chars().collect::>(); + let chars = string.chars().collect::>(); if index <= chars.len() - 1 { - let removed = chars.remove(index); let new_string = chars .iter() .map(|char| char.to_string()) .collect::(); - *string = new_string; - - Value::some(Value::string(removed)) + Value::some(Value::string(new_string)) } else { Value::none() } @@ -306,7 +280,7 @@ impl StringFunction { StringFunction::ReplaceRange => { Error::expect_argument_amount(self.name(), 3, arguments.len())?; - let mut string = arguments.get(0).unwrap().as_string_mut()?; + let mut string = arguments.get(0).unwrap().as_string()?.clone(); let range = arguments.get(1).unwrap().as_list()?.items(); let start = range.get(0).unwrap_or_default().as_integer()? as usize; let end = range.get(1).unwrap_or_default().as_integer()? as usize; @@ -314,12 +288,12 @@ impl StringFunction { string.replace_range(start..end, &pattern); - Value::none() + Value::String(string) } StringFunction::Retain => { Error::expect_argument_amount(self.name(), 2, arguments.len())?; - let mut string = arguments.get(0).unwrap().as_string_mut()?; + let mut string = arguments.get(0).unwrap().as_string()?.clone(); let predicate = arguments.get(1).unwrap().as_function()?; string.retain(|char| { @@ -330,7 +304,7 @@ impl StringFunction { .unwrap() }); - Value::none() + Value::String(string) } StringFunction::Split => { Error::expect_argument_amount(self.name(), 2, arguments.len())?; @@ -532,16 +506,16 @@ impl StringFunction { StringFunction::Truncate => { Error::expect_argument_amount(self.name(), 2, arguments.len())?; - let mut string = arguments.get(0).unwrap().as_string_mut()?; + let input_string = arguments.get(0).unwrap().as_string()?; let new_length = arguments.get(1).unwrap().as_integer()? as usize; - *string = string + let new_string = input_string .chars() .take(new_length) .map(|char| char.to_string()) .collect(); - Value::none() + Value::String(new_string) } }; diff --git a/src/value/function.rs b/src/value/function.rs index b1ae934..107a87e 100644 --- a/src/value/function.rs +++ b/src/value/function.rs @@ -44,6 +44,8 @@ impl Format for Function { Function::BuiltIn(built_in_function) => built_in_function.format(output, indent_level), Function::ContextDefined(function_node) => function_node.format(output, indent_level), } + + output.push('\n'); } } diff --git a/src/value/mod.rs b/src/value/mod.rs index 5db9c85..2a46d8b 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -16,7 +16,6 @@ use std::{ fmt::{self, Display, Formatter}, marker::PhantomData, ops::{Add, AddAssign, Div, Mul, Rem, Sub, SubAssign}, - sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}, }; pub mod function; @@ -34,7 +33,7 @@ pub enum Value { List(List), Map(Map), Function(Function), - String(Arc>), + String(String), Float(f64), Integer(i64), Boolean(bool), @@ -50,7 +49,7 @@ impl Default for Value { impl Value { pub fn string>(string: T) -> Self { - Value::String(Arc::new(RwLock::new(string.into()))) + Value::String(string.into()) } pub fn r#type(&self) -> Type { @@ -158,27 +157,17 @@ impl Value { matches!(self, Value::Map(_)) } - /// Borrows the value stored in `self` as `&str`, or returns `Err` if `self` is not a `Value::String`. - pub fn as_string(&self) -> Result> { + /// Borrows the value stored in `self` as `&String`, or returns `Err` if `self` is not a `Value::String`. + pub fn as_string(&self) -> Result<&String> { match self { - Value::String(string) => Ok(string.read()?), + Value::String(string) => Ok(string), value => Err(Error::ExpectedString { actual: value.clone(), }), } } - /// Borrows the value stored in `self` as `String`, or returns `Err` if `self` is not a `Value::String`. - pub fn as_string_mut(&self) -> Result> { - match self { - Value::String(string) => Ok(string.write()?), - value => Err(Error::ExpectedString { - actual: value.clone(), - }), - } - } - - /// Copies the value stored in `self` as `i64`, or returns `Err` if `self` is not a `Value::Int`. + /// Copies the value stored in `self` as `i64`, or returns `Err` if `self` is not a `Value::Int` pub fn as_integer(&self) -> Result { match self { Value::Integer(i) => Ok(*i), @@ -401,9 +390,7 @@ impl AddAssign for Value { (Value::Integer(left), Value::Integer(right)) => *left += right, (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.write().unwrap() += right.read().unwrap().as_str() - } + (Value::String(left), Value::String(right)) => *left += &right, (Value::List(list), value) => list.items_mut().push(value), _ => {} } @@ -440,9 +427,7 @@ impl PartialEq for Value { (Value::Integer(left), Value::Integer(right)) => left == right, (Value::Float(left), Value::Float(right)) => left == right, (Value::Boolean(left), Value::Boolean(right)) => left == right, - (Value::String(left), Value::String(right)) => { - left.read().unwrap().as_str() == right.read().unwrap().as_str() - } + (Value::String(left), Value::String(right)) => left == right, (Value::List(left), Value::List(right)) => left == right, (Value::Map(left), Value::Map(right)) => left == right, (Value::Function(left), Value::Function(right)) => left == right, @@ -462,11 +447,7 @@ impl PartialOrd for Value { impl Ord for Value { fn cmp(&self, other: &Self) -> Ordering { match (self, other) { - (Value::String(left), Value::String(right)) => left - .read() - .unwrap() - .as_str() - .cmp(right.read().unwrap().as_str()), + (Value::String(left), Value::String(right)) => left.cmp(right), (Value::String(_), _) => Ordering::Greater, (Value::Float(left), Value::Float(right)) => left.total_cmp(right), (Value::Integer(left), Value::Integer(right)) => left.cmp(right), @@ -502,7 +483,7 @@ impl Serialize for Value { S: Serializer, { match self { - Value::String(inner) => serializer.serialize_str(inner.read().unwrap().as_str()), + Value::String(inner) => serializer.serialize_str(inner), Value::Float(inner) => serializer.serialize_f64(*inner), Value::Integer(inner) => serializer.serialize_i64(*inner), Value::Boolean(inner) => serializer.serialize_bool(*inner), @@ -527,7 +508,7 @@ impl Serialize for Value { impl Display for Value { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Value::String(string) => write!(f, "{}", string.read().unwrap()), + Value::String(string) => write!(f, "{string}"), Value::Float(float) => write!(f, "{float}"), Value::Integer(int) => write!(f, "{int}"), Value::Boolean(boolean) => write!(f, "{boolean}"), @@ -598,8 +579,8 @@ impl TryFrom for String { type Error = Error; fn try_from(value: Value) -> std::result::Result { - if let Value::String(rw_lock) = value { - Ok(rw_lock.read()?.to_string()) + if let Value::String(string) = value { + Ok(string) } else { Err(Error::ExpectedString { actual: value }) }