diff options
Diffstat (limited to 'rprt-engine/src/selection_functions')
6 files changed, 150 insertions, 51 deletions
diff --git a/rprt-engine/src/selection_functions/function_character.rs b/rprt-engine/src/selection_functions/function_character.rs index 0d0699f..94c0963 100644 --- a/rprt-engine/src/selection_functions/function_character.rs +++ b/rprt-engine/src/selection_functions/function_character.rs @@ -1,9 +1,12 @@ -use crate::selection::Selection; -use crate::selection_function_param; -use crate::selection_functions::types::{get_buffer, SFArguments, SFError, SFResult}; -use crate::state::EditorState; +use crate::{ + dispatch_selection_function, + selection::Selection, + selection_function, + selection_functions::types::{get_buffer, SFArguments, SFError, SFResult}, + state::EditorState, +}; -selection_function_param! { +selection_function! { name: character, param_type: usize, niladic: |(param, es): (usize, &EditorState)| { @@ -19,7 +22,7 @@ selection_function_param! { ) } -selection_function_param!( +selection_function!( name: sequential_character, param_type: usize, niladic: |_| Err(SFError::NoNiladicForm(";n").into()), @@ -33,7 +36,7 @@ selection_function_param!( } ); -selection_function_param!( +selection_function!( name: reverse_character, param_type: usize, niladic: |(param, es): (usize, &EditorState)| { @@ -53,7 +56,7 @@ selection_function_param!( ) ); -selection_function_param!( +selection_function!( name: sequential_reverse_character, param_type: usize, niladic: |_| Err(SFError::NoNiladicForm(";'n").into()), @@ -65,7 +68,7 @@ selection_function_param!( } ); -selection_function_param!( +selection_function!( name: reverse_sequential_character, param_type: usize, niladic: |_| Err(SFError::NoNiladicForm("';n").into()), @@ -76,3 +79,13 @@ selection_function_param!( Ok(Selection::Position {buffer_id, pos: if *param<int.start {int.start - *param} else {0}}) } ); + +dispatch_selection_function!( + name: selection_function_character, + param_type: usize, + base: character, + sequential: sequential_character, + reverse: reverse_character, + sequential_reverse: sequential_reverse_character, + reverse_sequential: reverse_sequential_character, +); diff --git a/rprt-engine/src/selection_functions/function_empty.rs b/rprt-engine/src/selection_functions/function_empty.rs index a817dcf..bf0a45c 100644 --- a/rprt-engine/src/selection_functions/function_empty.rs +++ b/rprt-engine/src/selection_functions/function_empty.rs @@ -1,5 +1,7 @@ -use crate::selection::Selection; -use crate::selection_functions::types::{SFArguments, SFResult}; +use crate::{ + selection::Selection, + selection_functions::types::{SFArguments, SFResult}, +}; pub fn empty_sequential(_: SFArguments) -> SFResult { Ok(Selection::empty()) diff --git a/rprt-engine/src/selection_functions/function_end.rs b/rprt-engine/src/selection_functions/function_end.rs index 3f18fd3..cec7c90 100644 --- a/rprt-engine/src/selection_functions/function_end.rs +++ b/rprt-engine/src/selection_functions/function_end.rs @@ -1,11 +1,15 @@ -use crate::selection::Selection; -use crate::selection_function; -use crate::selection_functions::types::{get_buffer, SFArguments, SFError, SFResult}; -use crate::state::EditorState; +use crate::{ + dispatch_selection_function, + selection::Selection, + selection_function, + selection_functions::types::{get_buffer, SFArguments, SFError, SFResult}, + state::EditorState, +}; selection_function! { name: end, - niladic: |es: &EditorState| { + param_type: (), + niladic: |(_, es): ((), &EditorState)| { let buf = get_buffer(es, es.current_buffer_id)?; Ok(Selection::Position { buffer_id: es.current_buffer_id, @@ -18,7 +22,8 @@ selection_function! { selection_function! { name: reverse_end, - niladic: |es: &EditorState| { + param_type: (), + niladic: |(_, es): ((), &EditorState)| { Ok(Selection::Position { buffer_id: es.current_buffer_id, pos: 0, @@ -30,9 +35,10 @@ selection_function! { selection_function! { name: sequential_end, + param_type: (), niladic: |_| Err(SFError::NoNiladicForm(";$").into()), monadic_rank0: |_, buffer_id, pos| Ok(Selection::Position { buffer_id, pos }), - monadic_rank1: |es, buffer_id, _| { + monadic_rank1: |(_, es), buffer_id, _| { let buf = get_buffer(es, buffer_id)?; Ok(Selection::Position { buffer_id, pos: buf.max_pos() }) } @@ -40,6 +46,7 @@ selection_function! { selection_function! { name: sequential_reverse_end, + param_type: (), niladic: |_| Err(SFError::NoNiladicForm(";'$").into()), monadic_rank0: |_, buffer_id, pos| { Ok(Selection::Position { buffer_id, pos }) @@ -54,6 +61,7 @@ selection_function! { selection_function! { name: reverse_sequential_end, + param_type: (), niladic: |_| Err(SFError::NoNiladicForm("';$").into()), monadic_rank0: |_, buffer_id, pos| { Ok(Selection::Position { buffer_id, pos }) @@ -65,3 +73,13 @@ selection_function! { }) } } + +dispatch_selection_function!( + name: selection_function_end, + param_type: (), + base: end, + sequential: sequential_end, + reverse: reverse_end, + sequential_reverse: sequential_reverse_end, + reverse_sequential: reverse_sequential_end, +); diff --git a/rprt-engine/src/selection_functions/mod.rs b/rprt-engine/src/selection_functions/mod.rs index 3f64be4..b753200 100644 --- a/rprt-engine/src/selection_functions/mod.rs +++ b/rprt-engine/src/selection_functions/mod.rs @@ -1,5 +1,59 @@ -pub mod function_character; -pub mod function_empty; -pub mod function_end; -pub mod result_transformation; -pub mod types; +use crate::{ + expression::{BuiltinSelectionFn, ResultTransform, SearchModifier}, + selection::Selection, + selection_functions::{ + function_character::selection_function_character, + function_end::selection_function_end, + result_transformation::{complement_transform, conditional_transform}, + types::SFArguments, + }, + state::EditorState, +}; + +mod function_character; +mod function_empty; +mod function_end; +mod result_transformation; +mod types; + +pub use crate::selection_functions::types::{SFError, SFResult}; + +pub fn evaluate_selection_function( + es: &EditorState, + sf: BuiltinSelectionFn, + search_mod: Option<SearchModifier>, + result_transform: Option<ResultTransform>, + left: Option<Selection>, + right: Option<Selection>, +) -> SFResult { + let sf_args = match (left, right) { + (None, None) => Ok(SFArguments::Niladic { es }), + (Some(left), None) => Ok(SFArguments::Monadic { es, left }), + (Some(left), Some(right)) => Ok(SFArguments::Dyadic { es, left, right }), + _ => Err(SFError::NoLeftArgument), + }?; + let res = match sf { + BuiltinSelectionFn::CharOffset(off) => { + selection_function_character(off, &sf_args, search_mod) + } + BuiltinSelectionFn::EndOfBuffer => selection_function_end((), &sf_args, search_mod), + x => Err(SFError::NotImplemented(x).into()), + }?; + + if let Some(result_transform) = result_transform { + match result_transform { + ResultTransform::Complement => complement_transform(es, res), + ResultTransform::Conditional => conditional_transform(res, &sf_args), + ResultTransform::ConditionalComplement => { + let res = complement_transform(es, res)?; + conditional_transform(res, &sf_args) + } + ResultTransform::ComplementConditional => { + let res = conditional_transform(res, &sf_args)?; + complement_transform(es, res) + } + } + } else { + Ok(res) + } +} diff --git a/rprt-engine/src/selection_functions/result_transformation.rs b/rprt-engine/src/selection_functions/result_transformation.rs index 89a071a..865038c 100644 --- a/rprt-engine/src/selection_functions/result_transformation.rs +++ b/rprt-engine/src/selection_functions/result_transformation.rs @@ -1,9 +1,11 @@ -use crate::buffer::BufferID; -use crate::selection::{Interval, Selection}; -use crate::selection_functions::types::{SFArguments, SFError, SFResult}; -use crate::state::EditorState; +use crate::{ + buffer::BufferID, + selection::{Interval, Selection}, + selection_functions::types::{SFArguments, SFError, SFResult}, + state::EditorState, +}; -pub fn complement_transform(es: &EditorState, result: Selection, _: &SFArguments) -> SFResult { +pub fn complement_transform(es: &EditorState, result: Selection) -> SFResult { fn complement_rank0( es: &EditorState, buffer_id: BufferID, @@ -55,11 +57,7 @@ pub fn complement_transform(es: &EditorState, result: Selection, _: &SFArguments result.vectorise(es, complement_rank0, complement_rank1) } -pub fn conditional_transform( - _: &EditorState, - mut result: Selection, - arg: &SFArguments, -) -> SFResult { +pub fn conditional_transform(mut result: Selection, arg: &SFArguments) -> SFResult { if !result.is_empty() { Ok(match arg { // TODO: think about this niladic case? diff --git a/rprt-engine/src/selection_functions/types.rs b/rprt-engine/src/selection_functions/types.rs index aaf0086..6bd94bf 100644 --- a/rprt-engine/src/selection_functions/types.rs +++ b/rprt-engine/src/selection_functions/types.rs @@ -1,6 +1,9 @@ -use crate::buffer::{Buffer, BufferID}; -use crate::selection::{Selection, VectoriseError}; -use crate::state::EditorState; +use crate::{ + buffer::{Buffer, BufferID}, + expression::BuiltinSelectionFn, + selection::{Selection, VectoriseError}, + state::EditorState, +}; use thiserror::Error; #[derive(Error, Debug)] @@ -9,8 +12,12 @@ pub enum SFError { BufferNotFound(BufferID), #[error("Function {0} has no dyadic form")] NoDyadicForm(&'static str), - #[error("Function {0} has no dyadic form")] + #[error("Function {0} has no niladic form")] NoNiladicForm(&'static str), + #[error("Selection functions take their primary argument on the left")] + NoLeftArgument, + #[error("{0} is not yet implemented")] + NotImplemented(BuiltinSelectionFn), } pub enum SFArguments<'a> { @@ -34,15 +41,16 @@ pub type SFResult = Result<Selection, VectoriseError<SFError>>; macro_rules! selection_function { ( name: $name:ident, + param_type: $P:ty, niladic: $niladic_body:expr, monadic_rank0: $monadic_rank0_body:expr, monadic_rank1: $monadic_rank1_body:expr ) => { - pub fn $name(arg: SFArguments) -> SFResult { + fn $name(param: $P, arg: &SFArguments) -> SFResult { match arg { - SFArguments::Niladic { es } => $niladic_body(es), + SFArguments::Niladic { es } => ($niladic_body)((param, es)), SFArguments::Monadic { es, left } => { - left.vectorise(es, $monadic_rank0_body, $monadic_rank1_body) + left.vectorise(&(param, es), $monadic_rank0_body, $monadic_rank1_body) } SFArguments::Dyadic { .. } => Err(SFError::NoDyadicForm(stringify!($name)).into()), } @@ -51,21 +59,27 @@ macro_rules! selection_function { } #[macro_export] -macro_rules! selection_function_param { +macro_rules! dispatch_selection_function { ( name: $name:ident, param_type: $P:ty, - niladic: $niladic_body:expr, - monadic_rank0: $monadic_rank0_body:expr, - monadic_rank1: $monadic_rank1_body:expr + base: $bs:ident, + sequential: $sq:ident, + reverse: $rv:ident, + sequential_reverse: $sr:ident, + reverse_sequential: $rs:ident, ) => { - pub fn $name(param: $P, arg: SFArguments) -> SFResult { - match arg { - SFArguments::Niladic { es } => ($niladic_body)((param, es)), - SFArguments::Monadic { es, left } => { - left.vectorise(&(param, es), $monadic_rank0_body, $monadic_rank1_body) - } - SFArguments::Dyadic { .. } => Err(SFError::NoDyadicForm(stringify!($name)).into()), + pub fn $name( + param: $P, + arg: &SFArguments, + search_mod: Option<crate::expression::SearchModifier>, + ) -> SFResult { + match search_mod { + None => ($bs)(param, arg), + Some(crate::expression::SearchModifier::Sequential) => ($sq)(param, arg), + Some(crate::expression::SearchModifier::Reverse) => ($rv)(param, arg), + Some(crate::expression::SearchModifier::SequentialReverse) => ($sr)(param, arg), + Some(crate::expression::SearchModifier::ReverseSequential) => ($rs)(param, arg), } } }; |
