generalize default variables
This commit is contained in:
parent
bd40b124b0
commit
25f4eb1b13
2 changed files with 21 additions and 7 deletions
|
@ -1,5 +1,5 @@
|
|||
mod cli;
|
||||
use std::io::read_to_string;
|
||||
use std::{collections::HashMap, io::read_to_string};
|
||||
|
||||
use anyhow::{Context as _, anyhow};
|
||||
use bliplib::{
|
||||
|
@ -20,12 +20,17 @@ fn main() -> anyhow::Result<()> {
|
|||
.context("Failed to find (or use) default audio device")?;
|
||||
let sink = Sink::try_new(&stream_handle).context("Epic audio playback failure")?;
|
||||
|
||||
let default_variables = HashMap::from([('l', 4f64), ('L', 0.0), ('t', 0.0)]);
|
||||
|
||||
let parser = Parser::new(
|
||||
opts.notes(),
|
||||
opts.slopes()
|
||||
.map(|(s, (v, e))| (s, VariableChange(*v, e.clone())))
|
||||
.collect::<Vec<_>>(),
|
||||
opts.variables().map(|(v, _)| *v).collect::<Vec<_>>(),
|
||||
opts.variables()
|
||||
.chain(default_variables.iter())
|
||||
.map(|(v, _)| *v)
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let input = read_to_string(opts.input().get()).context("Failed to read input")?;
|
||||
let tokens = parser
|
||||
|
@ -34,7 +39,11 @@ fn main() -> anyhow::Result<()> {
|
|||
.context("Failed to parse input")?;
|
||||
|
||||
let compiler = Compiler::from(Context::new(
|
||||
opts.variables().map(|(a, b)| (*a, *b)),
|
||||
'n',
|
||||
'L',
|
||||
opts.variables()
|
||||
.map(|(a, b)| (*a, *b))
|
||||
.chain(default_variables.into_iter()),
|
||||
opts.instrument().clone(),
|
||||
opts.slopes().map(|(_, (a, b))| (*a, b.clone())),
|
||||
));
|
||||
|
|
|
@ -266,6 +266,8 @@ impl FromStr for Expression {
|
|||
#[derive(Clone, new)]
|
||||
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||
pub struct Context {
|
||||
note_length_variable: char,
|
||||
note_index_variable: char,
|
||||
#[new(default)]
|
||||
pub result: Vec<f64>,
|
||||
#[new(into_iter = "(char, f64)")]
|
||||
|
@ -298,18 +300,19 @@ pub enum CompilerError {
|
|||
|
||||
impl Context {
|
||||
pub fn current_length(&self) -> Result<f64, CompilerError> {
|
||||
self.get_slopes_for('L')
|
||||
self.get_slopes_for(self.note_length_variable)
|
||||
.map_err(CompilerError::from)?
|
||||
.iter()
|
||||
.try_fold(
|
||||
self.clone(),
|
||||
|mut acc, slope| -> Result<Context, CompilerError> {
|
||||
// just in case next slopes use L too
|
||||
*acc.get_mut('L')? = self.eval(slope).map_err(Into::<CompilerError>::into)?;
|
||||
*acc.get_mut(self.note_length_variable)? =
|
||||
self.eval(slope).map_err(Into::<CompilerError>::into)?;
|
||||
Ok(acc)
|
||||
},
|
||||
)?
|
||||
.get('L')
|
||||
.get(self.note_length_variable)
|
||||
.map_err(Into::into)
|
||||
.cloned()
|
||||
}
|
||||
|
@ -377,7 +380,7 @@ impl Context {
|
|||
if let Some(note) = n {
|
||||
let mut result = Vec::new();
|
||||
let mut map = self.namespace_generator().collect::<BTreeMap<_, _>>();
|
||||
map.insert('n'.to_string(), note as f64);
|
||||
map.insert(self.note_index_variable.to_string(), note as f64);
|
||||
while self.current_length()? > *self.get('t')? - curr_t + (1f64 / SAMPLE_RATE as f64) {
|
||||
result.push(self.eval_with(&self.instrument, &mut map)? * f64::MAX);
|
||||
self.tick()?;
|
||||
|
@ -442,6 +445,8 @@ mod tests {
|
|||
|
||||
fn context_generator() -> Context {
|
||||
Context::new(
|
||||
'n',
|
||||
'L',
|
||||
[
|
||||
('a', 5.0),
|
||||
('t', 0.0),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue