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::{
any::{Any, TypeId},
collections::{BTreeMap, HashMap},
fmt::Debug,
str::FromStr,
@ -7,21 +8,46 @@ use std::{
use derive_new::new;
use derive_wrapper::{AsRef, From};
use fasteval::{Compiler, EvalNamespace, Evaler, Instruction, Slab};
use lazy_static::lazy_static;
use thiserror::Error;
const SAMPLE_RATE: u16 = 48000;
#[derive(From, AsRef)]
#[derive(From, AsRef, Default)]
#[cfg_attr(test, derive(Debug))]
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))]
pub trait Token {
pub trait Token: Type {
fn apply(&self, context: Context) -> Result<Context, CompilerError>;
}
#[cfg(test)]
pub trait Token: Debug {
pub trait Token: Debug + Type {
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))]
pub struct Silence;
impl_type!(Silence);
impl Token for Silence {
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
context.render(None)?;
@ -43,10 +71,12 @@ impl Token for Silence {
}
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Default)]
#[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Marker;
impl_type!(Marker);
impl Token for Marker {
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
context.result.clear();
@ -54,10 +84,12 @@ impl Token for Marker {
}
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Default)]
#[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Note(pub u8);
impl_type!(Note);
impl Token for Note {
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
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))]
pub struct VariableChange(pub char, pub Expression);
impl_type!(VariableChange);
impl Token for VariableChange {
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
*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))]
pub struct Loop<'a>(pub LoopCount, pub TokenVec<'a>);
impl_type_life!(Loop<'_>);
#[cfg_attr(test, derive(Debug, PartialEq))]
pub enum LoopCount {
Litteral(usize),
@ -92,30 +130,92 @@ impl Default for LoopCount {
}
impl Token for Loop<'_> {
fn apply(&self, context: Context) -> Result<Context, CompilerError> {
todo!()
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
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))]
pub struct Tuplet<'a>(pub TokenVec<'a>);
impl_type_life!(Tuplet<'_>);
impl Token for Tuplet<'_> {
fn apply(&self, context: Context) -> Result<Context, CompilerError> {
todo!()
fn apply(&self, mut context: Context) -> Result<Context, CompilerError> {
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))]
pub struct Slope<'a>(pub &'a VariableChange, pub TokenVec<'a>);
impl Token for Slope<'_> {
fn apply(&self, context: Context) -> Result<Context, CompilerError> {
todo!()
lazy_static! {
static ref VARIABLE_CHANGE_DEFAULT: VariableChange = Default::default();
}
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))]
pub struct Expression {
from: String,
@ -154,6 +254,7 @@ impl FromStr for Expression {
}
}
#[derive(Clone)]
#[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Context {
pub result: Vec<f64>,