rest of Token.apply impls, Default for everyone
This commit is contained in:
parent
4bc2e2b8ee
commit
4102b93686
1 changed files with 115 additions and 14 deletions
129
src/compiler.rs
129
src/compiler.rs
|
@ -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>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue