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_new::new;
|
||||||
use derive_wrapper::{AsRef, From};
|
use derive_wrapper::{AsRef, From};
|
||||||
use fasteval::{Compiler, Evaler, Instruction, Slab};
|
use fasteval::{Compiler, EvalNamespace, Evaler, Instruction, Slab};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const SAMPLE_RATE: u16 = 48000;
|
const SAMPLE_RATE: u16 = 48000;
|
||||||
|
@ -118,13 +118,16 @@ impl Token for Slope<'_> {
|
||||||
#[derive(new)]
|
#[derive(new)]
|
||||||
#[cfg_attr(any(debug_assertions, test), derive(Debug))]
|
#[cfg_attr(any(debug_assertions, test), derive(Debug))]
|
||||||
pub struct Expression {
|
pub struct Expression {
|
||||||
|
from: String,
|
||||||
pub(crate) instruction: Instruction,
|
pub(crate) instruction: Instruction,
|
||||||
pub(crate) slab: Slab,
|
pub(crate) slab: Slab,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Expression {
|
impl Clone for Expression {
|
||||||
fn clone(&self) -> Self {
|
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)?
|
.parse(s, &mut slab.ps)?
|
||||||
.from(&slab.ps)
|
.from(&slab.ps)
|
||||||
.compile(&slab.ps, &mut slab.cs);
|
.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
|
.slopes
|
||||||
.iter()
|
.iter()
|
||||||
.map(
|
.map(
|
||||||
|(v, Expression { instruction, slab })| -> Result<(char, f64), fasteval::Error> {
|
|(
|
||||||
|
v,
|
||||||
|
Expression {
|
||||||
|
from: _,
|
||||||
|
instruction,
|
||||||
|
slab,
|
||||||
|
},
|
||||||
|
)|
|
||||||
|
-> Result<(char, f64), fasteval::Error> {
|
||||||
Ok((
|
Ok((
|
||||||
*v,
|
*v,
|
||||||
instruction.eval(
|
instruction.eval(
|
||||||
|
@ -229,11 +244,20 @@ impl Context {
|
||||||
.collect()
|
.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,
|
&self,
|
||||||
Expression { instruction, slab }: &Expression,
|
Expression {
|
||||||
|
from: _,
|
||||||
|
instruction,
|
||||||
|
slab,
|
||||||
|
}: &Expression,
|
||||||
|
ns: &mut impl EvalNamespace,
|
||||||
) -> Result<f64, fasteval::Error> {
|
) -> 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> {
|
pub fn render(&mut self, n: Option<u8>) -> Result<Vec<f64>, CompilerError> {
|
||||||
|
@ -242,13 +266,8 @@ impl Context {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
while (self.current_length()? * SAMPLE_RATE as f64) > *self.get('t')? - curr_t {
|
while (self.current_length()? * SAMPLE_RATE as f64) > *self.get('t')? - curr_t {
|
||||||
{
|
{
|
||||||
let Expression { instruction, slab } = &self.instrument;
|
result.push(self.eval_with(&self.instrument, &mut {
|
||||||
result.push(instruction.eval(&slab, &mut {
|
let mut map = self.namespace_generator();
|
||||||
let mut map = self
|
|
||||||
.variables
|
|
||||||
.iter()
|
|
||||||
.map(|(c, f)| (format!("{c}"), *f))
|
|
||||||
.collect::<BTreeMap<String, f64>>();
|
|
||||||
map.insert('n'.to_string(), note as f64);
|
map.insert('n'.to_string(), note as f64);
|
||||||
map
|
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