Improve formatting; Remove string mutability

This commit is contained in:
Jeff 2024-01-06 10:13:47 -05:00
parent 14d967b659
commit 7d7b96d76f
8 changed files with 64 additions and 84 deletions

View File

@ -4,7 +4,7 @@ use rayon::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; 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. /// Abstract representation of a block.
/// ///
@ -136,8 +136,26 @@ impl Format for Block {
output.push_str("{\n"); output.push_str("{\n");
} }
for statement in &self.statements { let mut previous: Option<&Statement> = None;
statement.format(output, indent_level + 1);
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'); output.push('\n');

View File

@ -81,7 +81,7 @@ impl AbstractTree for Index {
} }
Value::String(string) => { Value::String(string) => {
let index = self.index.run(source, context)?.as_integer()? as usize; 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())) Ok(Value::string(item.to_string()))
} }

View File

@ -123,8 +123,12 @@ impl AbstractTree for Root {
impl Format for Root { impl Format for Root {
fn format(&self, output: &mut String, indent_level: u8) { 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); statement.format(output, indent_level);
output.push('\n');
} }
} }
} }

View File

@ -128,7 +128,5 @@ impl Format for Statement {
} }
Statement::Return(statement) => statement.format(output, indent_level), Statement::Return(statement) => statement.format(output, indent_level),
} }
output.push('\n');
} }
} }

View File

@ -40,9 +40,12 @@ impl AbstractTree for While {
impl Format for While { impl Format for While {
fn format(&self, output: &mut String, indent_level: u8) { fn format(&self, output: &mut String, indent_level: u8) {
output.push('\n');
While::indent(output, indent_level);
output.push_str("while "); output.push_str("while ");
self.expression.format(output, indent_level); self.expression.format(output, indent_level);
output.push(' '); output.push(' ');
self.block.format(output, indent_level); self.block.format(output, indent_level);
output.push('\n');
} }
} }

View File

@ -18,8 +18,6 @@ pub enum StringFunction {
Lines, Lines,
Matches, Matches,
Parse, Parse,
Pop,
Push,
Remove, Remove,
ReplaceRange, ReplaceRange,
Retain, Retain,
@ -55,8 +53,6 @@ impl StringFunction {
StringFunction::Lines => "lines", StringFunction::Lines => "lines",
StringFunction::Matches => "matches", StringFunction::Matches => "matches",
StringFunction::Parse => "parse", StringFunction::Parse => "parse",
StringFunction::Pop => "pop",
StringFunction::Push => "push",
StringFunction::Remove => "remove", StringFunction::Remove => "remove",
StringFunction::ReplaceRange => "replace_range", StringFunction::ReplaceRange => "replace_range",
StringFunction::Retain => "retain", StringFunction::Retain => "retain",
@ -93,9 +89,10 @@ impl StringFunction {
vec![Type::String, Type::String], vec![Type::String, Type::String],
Type::option(Type::Integer), Type::option(Type::Integer),
), ),
StringFunction::Insert => { StringFunction::Insert => Type::function(
Type::function(vec![Type::String, Type::Integer, Type::String], Type::None) vec![Type::String, Type::Integer, Type::String],
} Type::String,
),
StringFunction::IsAscii => Type::function(vec![Type::String], Type::Boolean), StringFunction::IsAscii => Type::function(vec![Type::String], Type::Boolean),
StringFunction::IsEmpty => 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)), 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)) Type::function(vec![Type::String, Type::String], Type::list(Type::String))
} }
StringFunction::Parse => Type::function(vec![Type::String], Type::Any), 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( StringFunction::Remove => Type::function(
vec![Type::String, Type::Integer], vec![Type::String, Type::Integer],
Type::option(Type::String), Type::option(Type::String),
), ),
StringFunction::ReplaceRange => Type::function( StringFunction::ReplaceRange => Type::function(
vec![Type::String, Type::list(Type::Integer), Type::String], vec![Type::String, Type::list(Type::Integer), Type::String],
Type::None, Type::String,
), ),
StringFunction::Retain => Type::function( StringFunction::Retain => Type::function(
vec![ vec![
Type::String, Type::String,
Type::function(vec![Type::String], Type::Boolean), Type::function(vec![Type::String], Type::Boolean),
], ],
Type::None, Type::String,
), ),
StringFunction::Split => { StringFunction::Split => {
Type::function(vec![Type::String, Type::String], Type::list(Type::String)) 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::ToLowercase => Type::function(vec![Type::String], Type::String),
StringFunction::ToUppercase => Type::function(vec![Type::String], Type::String), StringFunction::ToUppercase => Type::function(vec![Type::String], Type::String),
StringFunction::Truncate => { 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::Trim => Type::function(vec![Type::String], Type::String),
StringFunction::TrimEnd => Type::function(vec![Type::String], Type::String), StringFunction::TrimEnd => Type::function(vec![Type::String], Type::String),
@ -219,13 +214,13 @@ impl StringFunction {
StringFunction::Insert => { StringFunction::Insert => {
Error::expect_argument_amount(self.name(), 3, arguments.len())?; 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 index = arguments.get(1).unwrap().as_integer()? as usize;
let insertion = arguments.get(2).unwrap().as_string()?; let insertion = arguments.get(2).unwrap().as_string()?;
string.insert_str(index, &insertion); string.insert_str(index, &insertion);
Value::none() Value::String(string)
} }
StringFunction::Lines => { StringFunction::Lines => {
Error::expect_argument_amount(self.name(), 1, arguments.len())?; Error::expect_argument_amount(self.name(), 1, arguments.len())?;
@ -264,41 +259,20 @@ impl StringFunction {
Value::none() 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 => { StringFunction::Remove => {
Error::expect_argument_amount(self.name(), 2, arguments.len())?; 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 index = arguments.get(1).unwrap().as_integer()? as usize;
let mut chars = string.chars().collect::<Vec<char>>(); let chars = string.chars().collect::<Vec<char>>();
if index <= chars.len() - 1 { if index <= chars.len() - 1 {
let removed = chars.remove(index);
let new_string = chars let new_string = chars
.iter() .iter()
.map(|char| char.to_string()) .map(|char| char.to_string())
.collect::<String>(); .collect::<String>();
*string = new_string; Value::some(Value::string(new_string))
Value::some(Value::string(removed))
} else { } else {
Value::none() Value::none()
} }
@ -306,7 +280,7 @@ impl StringFunction {
StringFunction::ReplaceRange => { StringFunction::ReplaceRange => {
Error::expect_argument_amount(self.name(), 3, arguments.len())?; 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 range = arguments.get(1).unwrap().as_list()?.items();
let start = range.get(0).unwrap_or_default().as_integer()? as usize; let start = range.get(0).unwrap_or_default().as_integer()? as usize;
let end = range.get(1).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); string.replace_range(start..end, &pattern);
Value::none() Value::String(string)
} }
StringFunction::Retain => { StringFunction::Retain => {
Error::expect_argument_amount(self.name(), 2, arguments.len())?; 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()?; let predicate = arguments.get(1).unwrap().as_function()?;
string.retain(|char| { string.retain(|char| {
@ -330,7 +304,7 @@ impl StringFunction {
.unwrap() .unwrap()
}); });
Value::none() Value::String(string)
} }
StringFunction::Split => { StringFunction::Split => {
Error::expect_argument_amount(self.name(), 2, arguments.len())?; Error::expect_argument_amount(self.name(), 2, arguments.len())?;
@ -532,16 +506,16 @@ impl StringFunction {
StringFunction::Truncate => { StringFunction::Truncate => {
Error::expect_argument_amount(self.name(), 2, arguments.len())?; 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; let new_length = arguments.get(1).unwrap().as_integer()? as usize;
*string = string let new_string = input_string
.chars() .chars()
.take(new_length) .take(new_length)
.map(|char| char.to_string()) .map(|char| char.to_string())
.collect(); .collect();
Value::none() Value::String(new_string)
} }
}; };

View File

@ -44,6 +44,8 @@ impl Format for Function {
Function::BuiltIn(built_in_function) => built_in_function.format(output, indent_level), Function::BuiltIn(built_in_function) => built_in_function.format(output, indent_level),
Function::ContextDefined(function_node) => function_node.format(output, indent_level), Function::ContextDefined(function_node) => function_node.format(output, indent_level),
} }
output.push('\n');
} }
} }

View File

@ -16,7 +16,6 @@ use std::{
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
marker::PhantomData, marker::PhantomData,
ops::{Add, AddAssign, Div, Mul, Rem, Sub, SubAssign}, ops::{Add, AddAssign, Div, Mul, Rem, Sub, SubAssign},
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
}; };
pub mod function; pub mod function;
@ -34,7 +33,7 @@ pub enum Value {
List(List), List(List),
Map(Map), Map(Map),
Function(Function), Function(Function),
String(Arc<RwLock<String>>), String(String),
Float(f64), Float(f64),
Integer(i64), Integer(i64),
Boolean(bool), Boolean(bool),
@ -50,7 +49,7 @@ impl Default for Value {
impl Value { impl Value {
pub fn string<T: Into<String>>(string: T) -> Self { pub fn string<T: Into<String>>(string: T) -> Self {
Value::String(Arc::new(RwLock::new(string.into()))) Value::String(string.into())
} }
pub fn r#type(&self) -> Type { pub fn r#type(&self) -> Type {
@ -158,27 +157,17 @@ impl Value {
matches!(self, Value::Map(_)) matches!(self, Value::Map(_))
} }
/// Borrows the value stored in `self` as `&str`, or returns `Err` if `self` is not a `Value::String`. /// Borrows the value stored in `self` as `&String`, or returns `Err` if `self` is not a `Value::String`.
pub fn as_string(&self) -> Result<RwLockReadGuard<String>> { pub fn as_string(&self) -> Result<&String> {
match self { match self {
Value::String(string) => Ok(string.read()?), Value::String(string) => Ok(string),
value => Err(Error::ExpectedString { value => Err(Error::ExpectedString {
actual: value.clone(), actual: value.clone(),
}), }),
} }
} }
/// Borrows the value stored in `self` as `String`, or returns `Err` if `self` is not a `Value::String`. /// Copies the value stored in `self` as `i64`, or returns `Err` if `self` is not a `Value::Int`
pub fn as_string_mut(&self) -> Result<RwLockWriteGuard<String>> {
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`.
pub fn as_integer(&self) -> Result<i64> { pub fn as_integer(&self) -> Result<i64> {
match self { match self {
Value::Integer(i) => Ok(*i), Value::Integer(i) => Ok(*i),
@ -401,9 +390,7 @@ impl AddAssign for Value {
(Value::Integer(left), Value::Integer(right)) => *left += right, (Value::Integer(left), Value::Integer(right)) => *left += right,
(Value::Float(left), Value::Float(right)) => *left += right, (Value::Float(left), Value::Float(right)) => *left += right,
(Value::Float(left), Value::Integer(right)) => *left += right as f64, (Value::Float(left), Value::Integer(right)) => *left += right as f64,
(Value::String(left), Value::String(right)) => { (Value::String(left), Value::String(right)) => *left += &right,
*left.write().unwrap() += right.read().unwrap().as_str()
}
(Value::List(list), value) => list.items_mut().push(value), (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::Integer(left), Value::Integer(right)) => left == right,
(Value::Float(left), Value::Float(right)) => left == right, (Value::Float(left), Value::Float(right)) => left == right,
(Value::Boolean(left), Value::Boolean(right)) => left == right, (Value::Boolean(left), Value::Boolean(right)) => left == right,
(Value::String(left), Value::String(right)) => { (Value::String(left), Value::String(right)) => left == right,
left.read().unwrap().as_str() == right.read().unwrap().as_str()
}
(Value::List(left), Value::List(right)) => left == right, (Value::List(left), Value::List(right)) => left == right,
(Value::Map(left), Value::Map(right)) => left == right, (Value::Map(left), Value::Map(right)) => left == right,
(Value::Function(left), Value::Function(right)) => left == right, (Value::Function(left), Value::Function(right)) => left == right,
@ -462,11 +447,7 @@ impl PartialOrd for Value {
impl Ord for Value { impl Ord for Value {
fn cmp(&self, other: &Self) -> Ordering { fn cmp(&self, other: &Self) -> Ordering {
match (self, other) { match (self, other) {
(Value::String(left), Value::String(right)) => left (Value::String(left), Value::String(right)) => left.cmp(right),
.read()
.unwrap()
.as_str()
.cmp(right.read().unwrap().as_str()),
(Value::String(_), _) => Ordering::Greater, (Value::String(_), _) => Ordering::Greater,
(Value::Float(left), Value::Float(right)) => left.total_cmp(right), (Value::Float(left), Value::Float(right)) => left.total_cmp(right),
(Value::Integer(left), Value::Integer(right)) => left.cmp(right), (Value::Integer(left), Value::Integer(right)) => left.cmp(right),
@ -502,7 +483,7 @@ impl Serialize for Value {
S: Serializer, S: Serializer,
{ {
match self { 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::Float(inner) => serializer.serialize_f64(*inner),
Value::Integer(inner) => serializer.serialize_i64(*inner), Value::Integer(inner) => serializer.serialize_i64(*inner),
Value::Boolean(inner) => serializer.serialize_bool(*inner), Value::Boolean(inner) => serializer.serialize_bool(*inner),
@ -527,7 +508,7 @@ impl Serialize for Value {
impl Display for Value { impl Display for Value {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self { match self {
Value::String(string) => write!(f, "{}", string.read().unwrap()), Value::String(string) => write!(f, "{string}"),
Value::Float(float) => write!(f, "{float}"), Value::Float(float) => write!(f, "{float}"),
Value::Integer(int) => write!(f, "{int}"), Value::Integer(int) => write!(f, "{int}"),
Value::Boolean(boolean) => write!(f, "{boolean}"), Value::Boolean(boolean) => write!(f, "{boolean}"),
@ -598,8 +579,8 @@ impl TryFrom<Value> for String {
type Error = Error; type Error = Error;
fn try_from(value: Value) -> std::result::Result<Self, Self::Error> { fn try_from(value: Value) -> std::result::Result<Self, Self::Error> {
if let Value::String(rw_lock) = value { if let Value::String(string) = value {
Ok(rw_lock.read()?.to_string()) Ok(string)
} else { } else {
Err(Error::ExpectedString { actual: value }) Err(Error::ExpectedString { actual: value })
} }