implement Clone for Expression (really works)

This commit is contained in:
Breval Ferrari 2025-05-23 15:25:45 +02:00
parent 7e831c40ac
commit 4bc2e2b8ee

View file

@ -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,
))
}
}
@ -200,7 +207,15 @@ impl Context {
.slopes
.iter()
.map(
|(v, Expression { instruction, slab })| -> Result<(char, f64), fasteval::Error> {
|(
v,
Expression {
from: _,
instruction,
slab,
},
)|
-> Result<(char, f64), fasteval::Error> {
Ok((
*v,
instruction.eval(
@ -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());
}
}