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 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');

View File

@ -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()))
}

View File

@ -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');
}
}
}

View File

@ -128,7 +128,5 @@ impl Format for Statement {
}
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 {
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');
}
}

View File

@ -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::<Vec<char>>();
let chars = string.chars().collect::<Vec<char>>();
if index <= chars.len() - 1 {
let removed = chars.remove(index);
let new_string = chars
.iter()
.map(|char| char.to_string())
.collect::<String>();
*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)
}
};

View File

@ -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');
}
}

View File

@ -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<RwLock<String>>),
String(String),
Float(f64),
Integer(i64),
Boolean(bool),
@ -50,7 +49,7 @@ impl Default for Value {
impl Value {
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 {
@ -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<RwLockReadGuard<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<&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<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`.
/// 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> {
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<Value> for String {
type Error = Error;
fn try_from(value: Value) -> std::result::Result<Self, Self::Error> {
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 })
}