Skip to content

Commit

Permalink
Clean up after quasiquotation re-implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
cowuake committed Aug 16, 2024
1 parent a27ea7b commit c1ea710
Showing 1 changed file with 1 addition and 173 deletions.
174 changes: 1 addition & 173 deletions schemius/src/core/s_expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub mod s_procedure;
use cfg_if::cfg_if;

use super::{accessor::*, constants::tokens};
use std::{collections::LinkedList, fmt, result, vec};
use std::{collections::LinkedList, fmt, result};

pub use self::{s_list::*, s_number::*, s_procedure::*};
type SAccessor<T> = ThreadSafeAccessor<T>;
Expand Down Expand Up @@ -437,178 +437,6 @@ impl SExpr {
_ => Ok(false),
}
}

pub fn matching_brackets(&self) -> Option<Vec<(usize, usize, usize)>> {
match self {
SExpr::List(list) => {
let list = list.access();
if !list.s_car().unwrap().symbol_is(tokens::OPEN_PAREN).unwrap() {
return None;
}

let mut pairs: Vec<(usize, usize)> = vec![];

while let Some(right) = list
.iter()
.enumerate()
.filter(|x| {
(pairs.is_empty() || pairs.iter().all(|(_, right)| right != &x.0))
&& x.1.symbol_is(tokens::CLOSED_PAREN).unwrap()
})
.min_by(|x, y| (x.0).cmp(&y.0))
.map(|x| x.0)
{
match list
.iter()
.enumerate()
.filter(|x| {
(pairs.is_empty() || pairs.iter().all(|(left, _)| left != &x.0))
&& x.1.symbol_is(tokens::OPEN_PAREN).unwrap()
})
.filter(|x| x.0 < right)
.max_by(|x, y| (x.0).cmp(&y.0))
.map(|x| x.0)
{
Some(left) => pairs.push((left, right)),
None => break,
}
}

let mut mapping: Vec<(usize, usize, usize)> = vec![];
pairs
.iter()
.map(|(left, right)| {
if *left == 0 && *right == list.s_len() - 1 {
(left, right, 0)
} else {
(
left,
right,
pairs.iter().filter(|(l, r)| l < left && r > left).count(),
)
}
})
.for_each(|(left, right, level)| mapping.push((*left, *right, level)));

Some(mapping)
}
_ => None,
}
}

pub fn find_symbol(&self, symbol: &str) -> Option<Vec<usize>> {
match self.with_explicit_parens() {
Ok(SExpr::List(list)) => {
let borrowed_list = list.access();

if borrowed_list.s_car().unwrap().symbol_is(tokens::OPEN_PAREN).unwrap() {
return None;
}

let indexes: Vec<usize> = borrowed_list
.iter()
.enumerate()
.filter(|(_, x)| x.symbol_is(symbol).unwrap())
.map(|(i, _)| i - 1)
.collect();

if !indexes.is_empty() {
Some(indexes)
} else {
None
}
}
_ => None,
}
}

pub fn with_explicit_parens(&self) -> Result<SExpr, String> {
match self {
SExpr::List(list) => {
let mut new_list = ListImplementation::new();
new_list.push(SExpr::Symbol(String::from(tokens::OPEN_PAREN)));

list.access().iter().for_each(|item| match item {
SExpr::List(_) => {
if let Ok(SExpr::List(internal)) = item.with_explicit_parens() {
internal.access().iter().for_each(|x| new_list.push(x.clone()))
}
}
other => new_list.push(other.clone()),
});

new_list.push(SExpr::Symbol(String::from(tokens::CLOSED_PAREN)));

Ok(SExpr::List(SchemeList::new(new_list.clone())))
}
SExpr::Pair(pair) => {
let pair = pair.access();
SExpr::List(SchemeList::new(ListImplementation::from_iter([
*pair.0.clone(),
SExpr::Symbol(tokens::DOT.to_string()),
*pair.1.clone(),
])))
.with_explicit_parens()
}
other => Ok(other.clone()),
}
}

pub fn without_explicit_parens(&self) -> Result<SExpr, String> {
// TODO: Deal with pairs, since flattening has been extended to them.
match self {
SExpr::List(list) => {
let mut list_without_parens = VectorImplementation::new();
list.access().iter().for_each(|expr| list_without_parens.push(expr.clone()));

if !list_without_parens.first().unwrap().symbol_is(tokens::OPEN_PAREN).unwrap() {
return Ok(self.clone());
}

list_without_parens.remove(0);
list_without_parens.pop();

loop {
let l_index;
let r_index;

match list_without_parens
.iter()
.enumerate()
.filter(|x| x.1.symbol_is(tokens::CLOSED_PAREN).unwrap())
.min_by(|x, y| (x.0).cmp(&y.0))
.map(|x| x.0)
{
Some(r) => {
match list_without_parens
.iter()
.enumerate()
.filter(|x| x.1.symbol_is(tokens::OPEN_PAREN).unwrap())
.filter(|x| x.0 < r)
.max_by(|x, y| (x.0).cmp(&y.0))
.map(|x| x.0)
{
Some(l) => {
l_index = l;
r_index = r;
}
None => break,
}
}
None => break,
}

let internal = SExpr::Vector(SchemeVector::new(
list_without_parens[(l_index + 1)..r_index].to_vec(),
));
list_without_parens.splice(l_index..(r_index + 1), [internal]);
}

Ok(SExpr::Vector(SAccessor::new(list_without_parens.clone())))
}
other => Ok(other.clone()),
}
}
}

#[cfg(test)]
Expand Down

0 comments on commit c1ea710

Please sign in to comment.