test setup, silence & expression tests
This commit is contained in:
parent
16f79c302a
commit
fa49625f7f
2 changed files with 64 additions and 26 deletions
|
@ -1,37 +1,61 @@
|
||||||
use std::{collections::HashMap, str::FromStr};
|
use std::{collections::HashMap, fmt::Debug, str::FromStr};
|
||||||
|
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
|
use derive_wrapper::{AsRef, From};
|
||||||
use fasteval::{Compiler, Instruction, Slab};
|
use fasteval::{Compiler, Instruction, Slab};
|
||||||
|
|
||||||
pub type TokenVec<'a> = Vec<Box<dyn Token + 'a>>;
|
#[derive(From, AsRef)]
|
||||||
|
#[cfg_attr(test, derive(Debug))]
|
||||||
|
pub struct TokenVec<'a>(Vec<Box<dyn Token + 'a>>);
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
pub trait Token {
|
pub trait Token {
|
||||||
fn apply(&self, context: Context) -> Context {
|
fn apply(&self, context: Context) -> Context {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub trait Token: Debug {
|
||||||
|
fn apply(&self, context: Context) -> Context {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
impl PartialEq for TokenVec<'_> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
format!("{self:?}") == format!("{other:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||||
pub struct Silence;
|
pub struct Silence;
|
||||||
|
|
||||||
impl Token for Silence {}
|
impl Token for Silence {}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||||
pub struct Marker;
|
pub struct Marker;
|
||||||
|
|
||||||
impl Token for Marker {}
|
impl Token for Marker {}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||||
pub struct Note(pub u8);
|
pub struct Note(pub u8);
|
||||||
|
|
||||||
impl Token for Note {}
|
impl Token for Note {}
|
||||||
|
|
||||||
|
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||||
pub struct VariableChange(pub char, pub Expression);
|
pub struct VariableChange(pub char, pub Expression);
|
||||||
|
|
||||||
impl Token for VariableChange {}
|
impl Token for VariableChange {}
|
||||||
|
|
||||||
|
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||||
pub struct Loop<'a>(pub LoopCount, pub TokenVec<'a>);
|
pub struct Loop<'a>(pub LoopCount, pub TokenVec<'a>);
|
||||||
|
|
||||||
|
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||||
pub enum LoopCount {
|
pub enum LoopCount {
|
||||||
Litteral(usize),
|
Litteral(usize),
|
||||||
Variable(char),
|
Variable(char),
|
||||||
|
@ -45,16 +69,18 @@ impl Default for LoopCount {
|
||||||
|
|
||||||
impl Token for Loop<'_> {}
|
impl Token for Loop<'_> {}
|
||||||
|
|
||||||
|
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||||
pub struct Tuplet<'a>(pub TokenVec<'a>);
|
pub struct Tuplet<'a>(pub TokenVec<'a>);
|
||||||
|
|
||||||
impl Token for Tuplet<'_> {}
|
impl Token for Tuplet<'_> {}
|
||||||
|
|
||||||
|
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||||
pub struct Slope<'a>(pub &'a VariableChange, pub TokenVec<'a>);
|
pub struct Slope<'a>(pub &'a VariableChange, pub TokenVec<'a>);
|
||||||
|
|
||||||
impl Token for Slope<'_> {}
|
impl Token for Slope<'_> {}
|
||||||
|
|
||||||
#[derive(new)]
|
#[derive(new)]
|
||||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
#[cfg_attr(any(debug_assertions, test), derive(Debug))]
|
||||||
pub struct Expression {
|
pub struct Expression {
|
||||||
pub(crate) instruction: Instruction,
|
pub(crate) instruction: Instruction,
|
||||||
pub(crate) slab: Slab,
|
pub(crate) slab: Slab,
|
||||||
|
@ -66,6 +92,13 @@ impl Clone for Expression {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
impl PartialEq for Expression {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
format!("{self:?}") == format!("{other:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for Expression {
|
impl FromStr for Expression {
|
||||||
type Err = fasteval::Error;
|
type Err = fasteval::Error;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
@ -78,6 +111,7 @@ impl FromStr for Expression {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
pub result: Vec<f64>,
|
pub result: Vec<f64>,
|
||||||
pub variables: HashMap<char, f64>,
|
pub variables: HashMap<char, f64>,
|
||||||
|
|
|
@ -21,7 +21,8 @@ use nom::{
|
||||||
use nom_locate::LocatedSpan;
|
use nom_locate::LocatedSpan;
|
||||||
|
|
||||||
use crate::compiler::{
|
use crate::compiler::{
|
||||||
Expression, Loop, LoopCount, Marker, Note, Silence, Slope, Token, Tuplet, VariableChange,
|
Expression, Loop, LoopCount, Marker, Note, Silence, Slope, Token, TokenVec, Tuplet,
|
||||||
|
VariableChange,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Builder)]
|
#[derive(Builder)]
|
||||||
|
@ -33,9 +34,7 @@ pub struct Parser<'i, 'n, 's, 'v> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'i, 's> Parser<'i, '_, 's, '_> {
|
impl<'i, 's> Parser<'i, '_, 's, '_> {
|
||||||
pub fn parse_all(
|
pub fn parse_all(&self) -> Result<TokenVec<'s>, Error<nom_locate::LocatedSpan<&'i str>>> {
|
||||||
&self,
|
|
||||||
) -> Result<Vec<Box<dyn Token + 's>>, Error<nom_locate::LocatedSpan<&'i str>>> {
|
|
||||||
token_parser(self)
|
token_parser(self)
|
||||||
.parse_complete(LocatedSpan::new(self.input))
|
.parse_complete(LocatedSpan::new(self.input))
|
||||||
.finish()
|
.finish()
|
||||||
|
@ -45,7 +44,7 @@ impl<'i, 's> Parser<'i, '_, 's, '_> {
|
||||||
|
|
||||||
fn token_parser<'a, 's, I>(
|
fn token_parser<'a, 's, I>(
|
||||||
parser: &Parser<'_, '_, 's, '_>,
|
parser: &Parser<'_, '_, 's, '_>,
|
||||||
) -> impl NomParser<I, Output = Vec<Box<dyn Token + 's>>, Error = nom::error::Error<I>>
|
) -> impl NomParser<I, Output = TokenVec<'s>, Error = nom::error::Error<I>>
|
||||||
where
|
where
|
||||||
I: Input + AsRef<str> + for<'z> nom::Compare<&'z str>,
|
I: Input + AsRef<str> + for<'z> nom::Compare<&'z str>,
|
||||||
<I as Input>::Item: AsChar,
|
<I as Input>::Item: AsChar,
|
||||||
|
@ -70,6 +69,7 @@ where
|
||||||
)),
|
)),
|
||||||
space_or_comment(),
|
space_or_comment(),
|
||||||
))
|
))
|
||||||
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_box<'a>(token: impl Token + 'a) -> Box<dyn Token + 'a> {
|
fn into_box<'a>(token: impl Token + 'a) -> Box<dyn Token + 'a> {
|
||||||
|
@ -279,22 +279,26 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn silence() {
|
fn silence() {
|
||||||
// let parser = |input: &'static str| Silence::parser().parse(input.into());
|
let parser = |input| Silence::parser().parse(input);
|
||||||
// let mut working_cases = vec![(".", ()), ".dd", ".."];
|
let mut working_cases = vec![
|
||||||
// let mut not_working_cases = vec![];
|
(".", ("", Silence)),
|
||||||
// for (test, expected) in working_cases.drain(..) {
|
(".dd", ("dd", Silence)),
|
||||||
// let output = parser(test);
|
("..", (".", Silence)),
|
||||||
// if let Ok((result)) = output {
|
];
|
||||||
// assert_eq!(expected, result);
|
let mut not_working_cases = vec!["", ",", "d.", " "];
|
||||||
// } else {
|
for (test, expected) in working_cases.drain(..) {
|
||||||
// panic!("result was not Ok: {output:?}");
|
let output = parser(test);
|
||||||
// }
|
if let Ok(result) = output {
|
||||||
// }
|
assert_eq!(expected, result);
|
||||||
// for test in not_working_cases.drain(..) {
|
} else {
|
||||||
// let output = parser(test);
|
panic!("result was not Ok: {output:?}");
|
||||||
// assert!(output.is_err(), "result was not Err: {output:?}");
|
}
|
||||||
// }
|
}
|
||||||
// }
|
for test in not_working_cases.drain(..) {
|
||||||
|
let output = parser(test);
|
||||||
|
assert!(output.is_err(), "result was not Err: {output:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue