implement Clone for Expression (really works)
This commit is contained in:
parent
7e831c40ac
commit
4bc2e2b8ee
1 changed files with 60 additions and 30 deletions
|
@ -6,7 +6,7 @@ use std::{
|
|||
|
||||
use derive_new::new;
|
||||
use derive_wrapper::{AsRef, From};
|
||||
use fasteval::{Compiler, Evaler, Instruction, Slab};
|
||||
use fasteval::{Compiler, EvalNamespace, Evaler, Instruction, Slab};
|
||||
use thiserror::Error;
|
||||
|
||||
const SAMPLE_RATE: u16 = 48000;
|
||||
|
@ -118,13 +118,16 @@ impl Token for Slope<'_> {
|
|||
#[derive(new)]
|
||||
#[cfg_attr(any(debug_assertions, test), derive(Debug))]
|
||||
pub struct Expression {
|
||||
from: String,
|
||||
pub(crate) instruction: Instruction,
|
||||
pub(crate) slab: Slab,
|
||||
}
|
||||
|
||||
impl Clone for Expression {
|
||||
fn clone(&self) -> Self {
|
||||
unimplemented!()
|
||||
self.from
|
||||
.parse()
|
||||
.expect(&format!("expression {self:?} have an invalid from"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +146,11 @@ impl FromStr for Expression {
|
|||
.parse(s, &mut slab.ps)?
|
||||
.from(&slab.ps)
|
||||
.compile(&slab.ps, &mut slab.cs);
|
||||
Ok(Expression::new(instruction, slab))
|
||||
Ok(Expression::new(
|
||||
s.trim_start().trim_end().to_string(),
|
||||
instruction,
|
||||
slab,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,24 +204,32 @@ impl Context {
|
|||
*self.get_mut('t')? += 1f64 / SAMPLE_RATE as f64;
|
||||
{
|
||||
let changes = self
|
||||
.slopes
|
||||
.iter()
|
||||
.map(
|
||||
|(v, Expression { instruction, slab })| -> Result<(char, f64), fasteval::Error> {
|
||||
Ok((
|
||||
*v,
|
||||
instruction.eval(
|
||||
.slopes
|
||||
.iter()
|
||||
.map(
|
||||
|(
|
||||
v,
|
||||
Expression {
|
||||
from: _,
|
||||
instruction,
|
||||
slab,
|
||||
&mut self
|
||||
.variables
|
||||
.iter()
|
||||
.map(|(c, f)| (c.to_string(), *f))
|
||||
.collect::<BTreeMap<String, f64>>(),
|
||||
)?,
|
||||
))
|
||||
},
|
||||
)
|
||||
.collect::<Result<Vec<(char, f64)>, fasteval::Error>>()?;
|
||||
},
|
||||
)|
|
||||
-> Result<(char, f64), fasteval::Error> {
|
||||
Ok((
|
||||
*v,
|
||||
instruction.eval(
|
||||
slab,
|
||||
&mut self
|
||||
.variables
|
||||
.iter()
|
||||
.map(|(c, f)| (c.to_string(), *f))
|
||||
.collect::<BTreeMap<String, f64>>(),
|
||||
)?,
|
||||
))
|
||||
},
|
||||
)
|
||||
.collect::<Result<Vec<(char, f64)>, fasteval::Error>>()?;
|
||||
for (variable, new_value) in changes {
|
||||
*self.get_mut(variable)? = new_value;
|
||||
}
|
||||
|
@ -229,11 +244,20 @@ impl Context {
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub fn eval(
|
||||
pub fn eval(&self, expr: &Expression) -> Result<f64, fasteval::Error> {
|
||||
self.eval_with(expr, &mut self.namespace_generator())
|
||||
}
|
||||
|
||||
pub fn eval_with(
|
||||
&self,
|
||||
Expression { instruction, slab }: &Expression,
|
||||
Expression {
|
||||
from: _,
|
||||
instruction,
|
||||
slab,
|
||||
}: &Expression,
|
||||
ns: &mut impl EvalNamespace,
|
||||
) -> Result<f64, fasteval::Error> {
|
||||
instruction.eval(&slab, &mut self.namespace_generator())
|
||||
instruction.eval(&slab, ns)
|
||||
}
|
||||
|
||||
pub fn render(&mut self, n: Option<u8>) -> Result<Vec<f64>, CompilerError> {
|
||||
|
@ -242,13 +266,8 @@ impl Context {
|
|||
let mut result = Vec::new();
|
||||
while (self.current_length()? * SAMPLE_RATE as f64) > *self.get('t')? - curr_t {
|
||||
{
|
||||
let Expression { instruction, slab } = &self.instrument;
|
||||
result.push(instruction.eval(&slab, &mut {
|
||||
let mut map = self
|
||||
.variables
|
||||
.iter()
|
||||
.map(|(c, f)| (format!("{c}"), *f))
|
||||
.collect::<BTreeMap<String, f64>>();
|
||||
result.push(self.eval_with(&self.instrument, &mut {
|
||||
let mut map = self.namespace_generator();
|
||||
map.insert('n'.to_string(), note as f64);
|
||||
map
|
||||
})?);
|
||||
|
@ -264,3 +283,14 @@ impl Context {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::compiler::Expression;
|
||||
|
||||
#[test]
|
||||
fn expression_is_clone() {
|
||||
let expr: Expression = "1 + 5 / x".parse().unwrap();
|
||||
assert_eq!(expr, expr.clone());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue