## Add default parameter values for function definitions ### Summary This PR adds support for default parameter values in function definitions, reducing boilerplate and improving API ergonomics: ```faust // Define with defaults lowpass(freq, q=0.707) = fi.resonlp(freq, q, 1); // Call - omit defaulted parameters process = lowpass(1000); // q = 0.707 process = lowpass(1000, 1.5); // q = 1.5 ``` ### Motivation Currently, Faust functions require all parameters at every call site, even when sensible defaults exist: ```faust // Without defaults - must specify q every time lowpass(freq, q) = fi.resonlp(freq, q, 1); process = lowpass(1000, 0.707), lowpass(2000, 0.707), lowpass(500, 0.707); // With defaults - cleaner code lowpass(freq, q=0.707) = fi.resonlp(freq, q, 1); process = lowpass(1000), lowpass(2000), lowpass(500); ``` This could be especially valuable for library functions where most users want standard values but experts need tunability. ### Syntax ```faust // Single default gain(x, amount=1.0) = x * amount; // Multiple defaults (must be rightmost parameters) mix(a, b, ratio=0.5) = a * (1-ratio) + b * ratio; env(attack=0.01, decay=0.1, sustain=0.7, release=0.3) = ...; // Defaults can be expressions SR = 48000; nyquist(sr=SR/2) = sr; // Defaults can reference earlier parameters scale(x, factor, offset=factor*0.1) = x * factor + offset; ``` **Constraints:** - Parameters with defaults must come after parameters without defaults - Default expressions are evaluated at definition time ### Implementation - **Parser**: Extended function parameter syntax to accept `= expression` - **Boxes**: Default values stored by position (nil for required params) - **Eval**: Modified function application to fill missing arguments from defaults ### Testing Pass tests: - `default-params-basic.dsp` - single default parameter - `default-params-multiple.dsp` - multiple defaults in one function - `default-params-expression.dsp` - defaults using expressions/constants ### Note on diff size The large diff in generated files (`faustparser.cpp`, etc.) is from flex/bison regeneration. Actual source changes: | File | Lines changed | |------|---------------| | `faustparser.y` | +97 | | `global.hh` | +6 | | `sourcereader.cpp` | +16/-9 | ### Backward Compatibility Fully backward compatible - existing function definitions without defaults work unchanged. ### Future Work Combines naturally with keyword arguments (separate PR): ```faust filter(freq, q=0.707, gain=1.0) = ...; // All these work: process = filter(1000); process = filter(1000, 1.5); process = filter(1000, gain: 2.0); // skip q, override gain process = filter(freq: 1000, gain: 2.0); // named + default ```