rest of Token.apply impls, Default for everyone

This commit is contained in:
Breval Ferrari 2025-05-23 20:06:28 +02:00
parent 4bc2e2b8ee
commit 4102b93686

View file

@ -1,4 +1,5 @@
use std::{ use std::{
any::{Any, TypeId},
collections::{BTreeMap, HashMap}, collections::{BTreeMap, HashMap},
fmt::Debug, fmt::Debug,
str::FromStr, str::FromStr,
@ -7,21 +8,46 @@ use std::{
use derive_new::new; use derive_new::new;
use derive_wrapper::{AsRef, From}; use derive_wrapper::{AsRef, From};
use fasteval::{Compiler, EvalNamespace, Evaler, Instruction, Slab}; use fasteval::{Compiler, EvalNamespace, Evaler, Instruction, Slab};
use lazy_static::lazy_static;
use thiserror::Error; use thiserror::Error;
const SAMPLE_RATE: u16 = 48000; const SAMPLE_RATE: u16 = 48000;
#[derive(From, AsRef)] #[derive(From, AsRef, Default)]
#[cfg_attr(test, derive(Debug))] #[cfg_attr(test, derive(Debug))]
pub struct TokenVec<'a>(pub(crate) Vec<Box<dyn Token + 'a>>); pub struct TokenVec<'a>(pub(crate) Vec<Box<dyn Token + 'a>>);
pub trait Type {
fn type_id(&self) -> TypeId;
}
macro_rules! impl_type {
($name:ty) => {
impl Type for $name {
fn type_id(&self) -> std::any::TypeId {
<Self as std::any::Any>::type_id(self)
}
}
};
}
macro_rules! impl_type_life {
($name:ty) => {
impl Type for $name {
fn type_id(&self) -> TypeId {
<$name as Any>::type_id(&Default::default())
}
}
};
}
#[cfg(not(test))] #[cfg(not(test))]
pub trait Token { pub trait Token: Type {
fn apply(&self, context: Context) -> Result<Context, CompilerError>; fn apply(&self, context: Context) -> Result<Context, CompilerError>;
} }
#[cfg(test)] #[cfg(test)]
pub trait Token: Debug { pub trait Token: Debug + Type {
fn apply(&self, context: Context) -> Result<Context, CompilerError>; fn apply(&self, context: Context) -> Result<Context, CompilerError>;
} }
@ -32,10 +58,12 @@ impl PartialEq for TokenVec<'_> {
} }
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy, Default)]
#[cfg_attr(test, derive(Debug, PartialEq))] #[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Silence; pub struct Silence;
impl_type!(Silence);
impl Token for Silence { impl Token for Silence {
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> { fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
context.render(None)?; context.render(None)?;
@ -43,10 +71,12 @@ impl Token for Silence {
} }
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy, Default)]
#[cfg_attr(test, derive(Debug, PartialEq))] #[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Marker; pub struct Marker;
impl_type!(Marker);
impl Token for Marker { impl Token for Marker {
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> { fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
context.result.clear(); context.result.clear();
@ -54,10 +84,12 @@ impl Token for Marker {
} }
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy, Default)]
#[cfg_attr(test, derive(Debug, PartialEq))] #[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Note(pub u8); pub struct Note(pub u8);
impl_type!(Note);
impl Token for Note { impl Token for Note {
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> { fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
let mut next = context.render(Some(self.0))?; let mut next = context.render(Some(self.0))?;
@ -66,9 +98,12 @@ impl Token for Note {
} }
} }
#[derive(Clone, Default)]
#[cfg_attr(test, derive(Debug, PartialEq))] #[cfg_attr(test, derive(Debug, PartialEq))]
pub struct VariableChange(pub char, pub Expression); pub struct VariableChange(pub char, pub Expression);
impl_type!(VariableChange);
impl Token for VariableChange { impl Token for VariableChange {
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> { fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
*context.get_mut(self.0)? = context.eval(&self.1)?; *context.get_mut(self.0)? = context.eval(&self.1)?;
@ -76,9 +111,12 @@ impl Token for VariableChange {
} }
} }
#[derive(Default)]
#[cfg_attr(test, derive(Debug, PartialEq))] #[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Loop<'a>(pub LoopCount, pub TokenVec<'a>); pub struct Loop<'a>(pub LoopCount, pub TokenVec<'a>);
impl_type_life!(Loop<'_>);
#[cfg_attr(test, derive(Debug, PartialEq))] #[cfg_attr(test, derive(Debug, PartialEq))]
pub enum LoopCount { pub enum LoopCount {
Litteral(usize), Litteral(usize),
@ -92,30 +130,92 @@ impl Default for LoopCount {
} }
impl Token for Loop<'_> { impl Token for Loop<'_> {
fn apply(&self, context: Context) -> Result<Context, CompilerError> { fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
todo!() let mut old_result = context.result.clone();
let count = match self.0 {
LoopCount::Litteral(n) => n,
LoopCount::Variable(v) => *context.get(v)? as usize,
};
context.result.clear();
let new_context = self
.1
.0
.iter()
.try_fold(context, |context, t| t.apply(context))?;
old_result.append(&mut new_context.result.repeat(count));
Ok(Context {
result: old_result,
..new_context
})
} }
} }
#[derive(Default)]
#[cfg_attr(test, derive(Debug, PartialEq))] #[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Tuplet<'a>(pub TokenVec<'a>); pub struct Tuplet<'a>(pub TokenVec<'a>);
impl_type_life!(Tuplet<'_>);
impl Token for Tuplet<'_> { impl Token for Tuplet<'_> {
fn apply(&self, context: Context) -> Result<Context, CompilerError> { fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
todo!() let mut old_result = context.result.clone();
context.result.clear();
let mut new_context = self
.0
.0
.iter()
.try_fold(context, |context, t| t.apply(context))?;
let len = new_context.result.len();
new_context.result = new_context
.result
.into_iter()
.step_by(
len / self
.0
.0
.iter()
.filter(|t| {
t.as_ref().type_id() == Type::type_id(&Note(0u8))
|| t.as_ref().type_id() == Type::type_id(&Silence)
})
.count(),
)
.collect();
old_result.append(&mut new_context.result);
Ok(Context {
result: old_result,
..new_context
})
} }
} }
#[cfg_attr(test, derive(Debug, PartialEq))] #[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<'_> { lazy_static! {
fn apply(&self, context: Context) -> Result<Context, CompilerError> { static ref VARIABLE_CHANGE_DEFAULT: VariableChange = Default::default();
todo!() }
impl Type for Slope<'_> {
fn type_id(&self) -> TypeId {
<Slope as Any>::type_id(&Slope(&VARIABLE_CHANGE_DEFAULT, Default::default()))
} }
} }
#[derive(new)] impl Token for Slope<'_> {
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
context.slopes.insert(self.0.0, self.0.1.clone());
context = self
.1
.0
.iter()
.try_fold(context, |context, t| t.apply(context))?;
context.slopes.remove(&self.0.0);
Ok(context)
}
}
#[derive(new, Default)]
#[cfg_attr(any(debug_assertions, test), derive(Debug))] #[cfg_attr(any(debug_assertions, test), derive(Debug))]
pub struct Expression { pub struct Expression {
from: String, from: String,
@ -154,6 +254,7 @@ impl FromStr for Expression {
} }
} }
#[derive(Clone)]
#[cfg_attr(test, derive(Debug, PartialEq))] #[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Context { pub struct Context {
pub result: Vec<f64>, pub result: Vec<f64>,