Skip to main content

carmen_lang/interpreter/
mod.rs

1//! Carmen language interpreter.
2//!
3//! This module contains the core interpreter for the Carmen music programming language.
4//! It provides runtime evaluation of Carmen AST nodes, value representation, environment
5//! management, and execution of musical programs.
6//!
7//! # Key Components
8//!
9//! * [`Value`] - Runtime representation of all Carmen values
10//! * [`Interpreter`] - Main interpreter engine that evaluates Carmen programs
11//! * [`Environment`] - Variable scope management with builtin function registration
12//! * [`BuiltinRegistry`] - Registry of builtin functions available to programs
13//!
14//! # Value System
15//!
16//! The interpreter uses a dynamic type system where all runtime values are represented
17//! by the [`Value`] enum. This includes:
18//! - Basic types: numbers, strings, booleans
19//! - Musical types: pitches, chords, durations, dynamics
20//! - Collection types: lists, tuples, sets
21//! - Structural types: musical events, parts, scores
22//! - Function types: user-defined and builtin functions
23//!
24//! # Execution Model
25//!
26//! Programs are executed statement by statement, with expressions evaluated recursively.
27//! The interpreter maintains a stack of scopes for variable binding and supports
28//! control flow constructs like conditionals, loops, and function calls.
29
30pub mod arg_extraction;
31pub mod builtins;
32
33use crate::ast::*;
34use crate::common::fraction::Fraction;
35use crate::core::*;
36use crate::errors::{AddSpan, CarmenError, CoreResult, ErrorSource, Result};
37use builtins::BuiltinRegistry;
38use std::collections::HashMap;
39use std::fmt;
40use std::str::FromStr;
41
42/// Runtime representation of all Carmen values.
43///
44/// This enum encompasses all possible values that can exist during Carmen program execution,
45/// from basic types like numbers and strings to complex musical structures like scores.
46/// The type system is dynamic, allowing values to be converted and combined at runtime.
47#[derive(Debug, Clone, PartialEq)]
48pub enum Value {
49    /// Floating-point number (covers integers as well)
50    Number(f64),
51    /// Text string
52    String(String),
53    /// Boolean true/false value
54    Boolean(bool),
55    /// Musical pitch with octave information
56    Pitch(Pitch),
57    /// Pitch class without octave (0-11)
58    PitchClass(PitchClass),
59    /// Set of pitch classes for set theory analysis
60    PitchClassSet(PitchClassSet),
61    /// Musical duration (note length)
62    Duration(Duration),
63    /// Dynamic marking (pp, mf, ff, etc.)
64    Dynamic(Dynamic),
65    /// Performance attribute (staccato, legato, etc.)
66    Attribute(Attribute),
67    /// Musical chord (multiple simultaneous pitches)
68    Chord(Chord),
69    /// Musical rest (silence)
70    Rest,
71    /// Ordered collection of values
72    List(Vec<Value>),
73    /// Fixed-size ordered collection, often used for chords
74    Tuple(Vec<Value>),
75    /// Unordered collection of unique values
76    Set(Vec<Value>),
77    /// Musical event with timing and content
78    MusicalEvent(MusicalEvent),
79    /// Musical part containing staves and events
80    Part(Part),
81    /// Musical staff with multiple voices
82    Staff(Staff),
83    /// Timeline containing multiple parts
84    Timeline(Timeline),
85    /// Movement containing a timeline and metadata
86    Movement(Movement),
87    /// Complete musical score with movements or timeline
88    Score(Score),
89    /// Metadata key for score/part/staff annotation
90    MetadataKey(MetadataKey),
91    /// Metadata value for score/part/staff annotation
92    MetadataValue(MetadataValue),
93    /// Context change (tempo, key signature, etc.)
94    ContextChange(ContextChange),
95    /// User-defined function with parameters and body
96    Function {
97        name: String,
98        params: Vec<String>,
99        body: Vec<SpannedStatement>,
100    },
101    /// Reference to a builtin function
102    BuiltinFunction(String),
103    /// Null/empty value
104    Nil,
105}
106
107impl fmt::Display for Value {
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        match self {
110            Value::Number(n) => write!(f, "{n}"),
111            Value::String(s) => write!(f, "\"{s}\""),
112            Value::Boolean(b) => write!(f, "{b}"),
113            Value::Pitch(p) => write!(f, "{}", p.to_note_name()),
114            Value::PitchClass(pc) => write!(f, "{}", pc.to_note_name()),
115            Value::PitchClassSet(pcs) => {
116                let mut classes: Vec<_> = pcs.classes.iter().collect();
117                classes.sort_by_key(|pc| pc.0); // sort by pitch class number
118
119                let names: Vec<String> = classes.iter().map(|&pc| format!("{}", pc.0)).collect();
120                write!(f, "{{{}}}", names.join(", "))
121            }
122            Value::Duration(d) => write!(f, "{}", d.to_fractional_string()),
123            Value::Dynamic(d) => write!(f, "{d:?}"),
124            Value::Attribute(attr) => write!(f, "{attr:?}"),
125            Value::Rest => write!(f, "~"),
126            Value::Chord(chord) => {
127                let notes: Vec<String> = chord
128                    .pitches
129                    .iter()
130                    .map(|pitch| pitch.to_note_name())
131                    .collect();
132                write!(f, "({})", notes.join(", "))
133            }
134            Value::List(items) => {
135                let formatted: Vec<String> = items.iter().map(|v| format!("{v}")).collect();
136                write!(f, "[{}]", formatted.join(", "))
137            }
138            Value::Tuple(items) => {
139                let formatted: Vec<String> = items.iter().map(|v| format!("{v}")).collect();
140                write!(f, "({})", formatted.join(", "))
141            }
142            Value::Set(items) => {
143                let formatted: Vec<String> = items.iter().map(|v| format!("{v}")).collect();
144                write!(f, "{{{}}}", formatted.join(", "))
145            }
146            Value::MusicalEvent(event) => {
147                let duration_str = event.duration.to_fractional_string();
148                let content_str = match &event.content {
149                    EventContent::Note(pitch) => pitch.to_note_name(),
150                    EventContent::Chord(chord) => {
151                        let notes: Vec<String> = chord
152                            .pitches
153                            .iter()
154                            .map(|pitch| pitch.to_note_name())
155                            .collect();
156                        format!("({})", notes.join(", "))
157                    }
158                    EventContent::Rest => "~".to_string(),
159                    EventContent::Sequence(events) => {
160                        format!("[{} events]", events.len())
161                    }
162                };
163
164                let mut parts = vec![duration_str, content_str];
165
166                if let Some(dynamic) = &event.dynamic {
167                    parts.push(format!("{dynamic:?}").to_lowercase());
168                }
169
170                if !event.attributes.is_empty() {
171                    let attrs: Vec<String> = event
172                        .attributes
173                        .iter()
174                        .map(|a| format!("{a:?}").to_lowercase())
175                        .collect();
176                    parts.push(attrs.join(" "));
177                }
178
179                write!(f, "{}", parts.join(" "))
180            }
181            Value::Part(part) => {
182                let event_count = part.total_event_count();
183                let mut result = if let Some(name) = &part.name {
184                    format!("Part \"{name}\"")
185                } else {
186                    "Part".to_string()
187                };
188
189                if !part.staves.is_empty() {
190                    result.push_str(&format!(
191                        " ({} staves, {} events, {:.1}s)",
192                        part.staves.len(),
193                        event_count,
194                        part.total_duration()
195                    ));
196
197                    // Add staff breakdown
198                    let staff_info: Vec<String> = part
199                        .staves
200                        .iter()
201                        .map(|s| {
202                            let voices_count = s.voices.len();
203                            let events_count: usize = s.voices.iter().map(|v| v.events.len()).sum();
204                            let voice_str = if voices_count == 1 { "voice" } else { "voices" };
205                            format!(
206                                "S{}: {} {}, {} events",
207                                s.number, voices_count, voice_str, events_count
208                            )
209                        })
210                        .collect();
211
212                    if staff_info.len() <= 4 {
213                        result.push_str(&format!(" [{}]", staff_info.join(", ")));
214                    } else {
215                        result.push_str(&format!(
216                            " [{}... +{}]",
217                            staff_info[..3].join(", "),
218                            staff_info.len() - 3
219                        ));
220                    }
221                } else {
222                    result.push_str(&format!(
223                        " ({} events, {:.1}s)",
224                        event_count,
225                        part.total_duration()
226                    ));
227                }
228
229                write!(f, "{result}")
230            }
231
232            Value::Staff(staff) => {
233                let voices_count = staff.voices.len();
234                let events_count: usize = staff.voices.iter().map(|v| v.events.len()).sum();
235                let voice_str = if voices_count == 1 { "voice" } else { "voices" };
236                write!(
237                    f,
238                    "Staff {} ({} {}, {} events, {:.1}s)",
239                    staff.number,
240                    voices_count,
241                    voice_str,
242                    events_count,
243                    staff.total_duration()
244                )
245            }
246            Value::Timeline(timeline) => {
247                let total_events: usize =
248                    timeline.parts.iter().map(|p| p.total_event_count()).sum();
249                let total_staves: usize =
250                    timeline.parts.iter().map(|p| p.staves.len().max(1)).sum();
251
252                let mut result = format!(
253                    "Timeline ({} parts, {} staves, {} events, {:.1}s)",
254                    timeline.parts.len(),
255                    total_staves,
256                    total_events,
257                    timeline.total_duration()
258                );
259
260                // Add part breakdown
261                let part_info: Vec<String> = timeline
262                    .parts
263                    .iter()
264                    .map(|p| {
265                        let name = if let Some(name) = &p.name {
266                            format!("\"{name}\"")
267                        } else {
268                            "Unnamed".to_string()
269                        };
270
271                        if p.staves.is_empty() {
272                            format!("{}: {}", name, p.events.len())
273                        } else {
274                            format!("{}: {}s+{}", name, p.staves.len(), p.events.len())
275                        }
276                    })
277                    .collect();
278
279                if !part_info.is_empty() && part_info.len() <= 3 {
280                    result.push_str(&format!(" [{}]", part_info.join(", ")));
281                } else if !part_info.is_empty() {
282                    result.push_str(&format!(
283                        " [{}... +{}]",
284                        part_info[..2].join(", "),
285                        part_info.len() - 2
286                    ));
287                }
288
289                write!(f, "{result}")
290            }
291            Value::Movement(movement) => {
292                let mut result = if let Some(name) = &movement.name {
293                    format!("Movement \"{name}\"")
294                } else {
295                    "Movement".to_string()
296                };
297
298                let total_events: usize = movement
299                    .timeline
300                    .parts
301                    .iter()
302                    .map(|p| p.total_event_count())
303                    .sum();
304                result.push_str(&format!(
305                    " ({} parts, {} events, {:.1}s)",
306                    movement.timeline.parts.len(),
307                    total_events,
308                    movement.total_duration()
309                ));
310
311                // Add part summary
312                let part_info: Vec<String> = movement
313                    .timeline
314                    .parts
315                    .iter()
316                    .map(|p| {
317                        if let Some(name) = &p.name {
318                            format!("\"{name}\"")
319                        } else {
320                            "Unnamed".to_string()
321                        }
322                    })
323                    .collect();
324
325                if !part_info.is_empty() {
326                    if part_info.len() <= 3 {
327                        result.push_str(&format!(" [{}]", part_info.join(", ")));
328                    } else {
329                        result.push_str(&format!(
330                            " [{}... +{} more]",
331                            part_info[..2].join(", "),
332                            part_info.len() - 2
333                        ));
334                    }
335                }
336
337                write!(f, "{result}")
338            }
339            Value::Score(score) => {
340                let mut result = if let Some(name) = &score.name {
341                    format!("Score \"{name}\"")
342                } else {
343                    "Score".to_string()
344                };
345
346                if score.is_multi_movement() {
347                    let total_parts: usize =
348                        score.movements.iter().map(|m| m.timeline.parts.len()).sum();
349                    let total_events: usize = score
350                        .movements
351                        .iter()
352                        .map(|m| {
353                            m.timeline
354                                .parts
355                                .iter()
356                                .map(|p| p.total_event_count())
357                                .sum::<usize>()
358                        })
359                        .sum();
360
361                    result.push_str(&format!(
362                        " ({} movements, {} parts total, {} events, {:.1}s)",
363                        score.movements.len(),
364                        total_parts,
365                        total_events,
366                        score.total_duration()
367                    ));
368
369                    // Add movement summary
370                    let movement_names: Vec<String> = score
371                        .movements
372                        .iter()
373                        .enumerate()
374                        .map(|(i, m)| {
375                            if let Some(name) = &m.name {
376                                format!("\"{name}\"")
377                            } else {
378                                format!("Movement {}", i + 1)
379                            }
380                        })
381                        .collect();
382
383                    if movement_names.len() <= 3 {
384                        result.push_str(&format!(" [{}]", movement_names.join(", ")));
385                    } else {
386                        result.push_str(&format!(
387                            " [{}... +{} more]",
388                            movement_names[..2].join(", "),
389                            movement_names.len() - 2
390                        ));
391                    }
392                } else if let Some(timeline) = &score.timeline {
393                    let total_events: usize =
394                        timeline.parts.iter().map(|p| p.total_event_count()).sum();
395                    result.push_str(&format!(
396                        " ({} parts, {} events, {:.1}s)",
397                        timeline.parts.len(),
398                        total_events,
399                        score.total_duration()
400                    ));
401                }
402
403                write!(f, "{result}")
404            }
405            Value::Function { name, params, .. } => {
406                write!(f, "Function {}({})", name, params.join(", "))
407            }
408            Value::BuiltinFunction(name) => {
409                write!(f, "BuiltinFunction {name}")
410            }
411            Value::MetadataKey(key) => write!(f, "MetadataKey({key:?})"),
412            Value::MetadataValue(value) => write!(f, "MetadataValue({value:?})"),
413            Value::ContextChange(change) => write!(f, "ContextChange({change:?})"),
414            Value::Nil => write!(f, "nil"),
415        }
416    }
417}
418
419impl Value {
420    /// Returns the type name of this value as a string.
421    ///
422    /// Used for error messages and debugging output.
423    pub fn type_name(&self) -> &'static str {
424        match self {
425            Value::Number(_) => "number",
426            Value::String(_) => "string",
427            Value::Boolean(_) => "boolean",
428            Value::Pitch(_) => "pitch",
429            Value::PitchClass(_) => "pitch_class",
430            Value::PitchClassSet(_) => "pitch_class_set",
431            Value::Duration(_) => "duration",
432            Value::Dynamic(_) => "dynamic",
433            Value::Attribute(_) => "attribute",
434            Value::Chord(_) => "chord",
435            Value::Rest => "rest",
436            Value::List(_) => "list",
437            Value::Tuple(_) => "tuple",
438            Value::Set(_) => "set",
439            Value::MusicalEvent(_) => "musical_event",
440            Value::Part(_) => "part",
441            Value::Staff(_) => "staff",
442            Value::Timeline(_) => "timeline",
443            Value::Movement(_) => "movement",
444            Value::Score(_) => "score",
445            Value::MetadataKey(_) => "metadata_key",
446            Value::MetadataValue(_) => "metadata_value",
447            Value::ContextChange(_) => "context_change",
448            Value::Function { .. } => "function",
449            Value::BuiltinFunction(_) => "builtin_function",
450            Value::Nil => "nil",
451        }
452    }
453
454    /// Determines if this value is considered "truthy" in boolean contexts.
455    ///
456    /// # Truthy values
457    /// - All values except: `false`, `nil`, `0.0`, and empty strings/lists
458    pub fn is_truthy(&self) -> bool {
459        match self {
460            Value::Boolean(b) => *b,
461            Value::Nil => false,
462            Value::Number(n) => *n != 0.0,
463            Value::String(s) => !s.is_empty(),
464            Value::List(l) => !l.is_empty(),
465            _ => true,
466        }
467    }
468}
469
470impl From<f64> for Value {
471    fn from(value: f64) -> Self {
472        Value::Number(value)
473    }
474}
475
476impl From<Value> for Option<f64> {
477    fn from(value: Value) -> Self {
478        match value {
479            Value::Number(n) => Some(n),
480            _ => None,
481        }
482    }
483}
484
485impl From<Value> for Option<bool> {
486    fn from(value: Value) -> Self {
487        Some(value.is_truthy())
488    }
489}
490
491impl From<PitchClass> for Value {
492    fn from(pc: PitchClass) -> Self {
493        Value::PitchClass(pc)
494    }
495}
496
497impl From<Value> for Option<PitchClass> {
498    fn from(value: Value) -> Self {
499        match value {
500            Value::PitchClass(pc) => Some(pc),
501            Value::Number(n) if (0.0..=11.0).contains(&n) && n.fract() == 0.0 => {
502                Some(PitchClass::new(n as u8))
503            }
504            _ => None,
505        }
506    }
507}
508
509impl From<Pitch> for Value {
510    fn from(pitch: Pitch) -> Self {
511        Value::Pitch(pitch)
512    }
513}
514
515impl From<Value> for Option<Pitch> {
516    fn from(value: Value) -> Self {
517        match value {
518            Value::Pitch(p) => Some(p),
519            _ => None,
520        }
521    }
522}
523
524impl TryFrom<SpannedLiteral> for Value {
525    type Error = CarmenError;
526
527    fn try_from(literal: SpannedLiteral) -> Result<Self> {
528        match literal.node {
529            Literal::Number(value) => Ok(Value::Number(value)),
530            Literal::String(value) => Ok(Value::String(value)),
531            Literal::Boolean(value) => Ok(Value::Boolean(value)),
532            Literal::Pitch {
533                note,
534                accidentals,
535                octave,
536            } => {
537                if let Some(octave) = octave {
538                    Pitch::from_note_name(&note, accidentals, octave as i8)
539                        .map(Value::Pitch)
540                        .map_err(|e| e.with_span(literal.span))
541                } else {
542                    // Pitch class
543                    PitchClass::from_note_name(&note, accidentals)
544                        .map(Value::PitchClass)
545                        .map_err(|e| e.with_span(literal.span))
546                }
547            }
548            Literal::Duration {
549                numerator,
550                denominator,
551                dots,
552            } => {
553                let base_fraction = Fraction::new(numerator, denominator);
554                let final_fraction = base_fraction.with_dots(dots);
555                Ok(Value::Duration(Duration {
556                    fraction: final_fraction,
557                }))
558            }
559            Literal::Dynamic(value) => Dynamic::from_str(&value)
560                .map(Value::Dynamic)
561                .map_err(|e| e.with_span(literal.span)),
562            Literal::Attribute(value) => Attribute::from_str(&value)
563                .map(Value::Attribute)
564                .map_err(|e| e.with_span(literal.span)),
565            Literal::Rest { .. } => Ok(Value::Rest),
566        }
567    }
568}
569
570impl TryFrom<Value> for MetadataKey {
571    type Error = ErrorSource;
572
573    fn try_from(value: Value) -> CoreResult<Self> {
574        if let Value::String(s) = value {
575            match s.as_str() {
576                "title" => Ok(MetadataKey::Title),
577                "composer" => Ok(MetadataKey::Composer),
578                "copyright" => Ok(MetadataKey::Copyright),
579                "tempo" => Ok(MetadataKey::Tempo),
580                "time_signature" => Ok(MetadataKey::TimeSignature),
581                "key_signature" => Ok(MetadataKey::KeySignature),
582                "clef" => Ok(MetadataKey::Clef),
583                "instrument" => Ok(MetadataKey::Instrument),
584                "channel" => Ok(MetadataKey::Channel),
585                "offset" => Ok(MetadataKey::Offset),
586                _ => Err(ErrorSource::Argument(format!("Invalid metadata key: {s}"))),
587            }
588        } else {
589            Err(ErrorSource::Type(
590                "Expected string for metadata key".to_string(),
591            ))
592        }
593    }
594}
595
596impl TryFrom<Value> for MetadataValue {
597    type Error = ErrorSource;
598
599    fn try_from(value: Value) -> CoreResult<Self> {
600        match value {
601            Value::String(s) => Ok(MetadataValue::String(s)),
602            Value::Number(n) => Ok(MetadataValue::Number(n)),
603            Value::List(l) => {
604                if l.len() == 2 {
605                    if let (Value::Number(num), Value::Number(den)) = (&l[0], &l[1]) {
606                        if num.fract() == 0.0 && den.fract() == 0.0 && *den != 0.0 {
607                            return Ok(MetadataValue::TimeSignature(*num as u32, *den as u32));
608                        }
609                    }
610                }
611                Err(ErrorSource::Type(
612                    "Expected [numerator, denominator] for TimeSignature".to_string(),
613                ))
614            }
615
616            _ => Err(ErrorSource::Type(format!(
617                "Unsupported value type for metadata: {}",
618                value.type_name()
619            ))),
620        }
621    }
622}
623
624/// Variable binding environment with scope management.
625///
626/// The environment maintains a stack of scopes for variable lookup and binding.
627/// It includes a registry of builtin functions that are automatically available
628/// to all Carmen programs.
629pub struct Environment {
630    /// Stack of variable scopes (innermost scope is last)
631    scopes: Vec<HashMap<String, Value>>,
632    /// Registry of builtin functions
633    builtins: BuiltinRegistry,
634}
635
636impl Default for Environment {
637    fn default() -> Self {
638        Self::new()
639    }
640}
641
642impl Environment {
643    /// Creates a new environment with a global scope and registered builtins.
644    pub fn new() -> Self {
645        let mut env = Self {
646            scopes: vec![HashMap::new()],
647            builtins: BuiltinRegistry::new(),
648        };
649        env.define_builtins();
650        env
651    }
652
653    /// Pushes a new variable scope onto the stack.
654    ///
655    /// Used when entering function calls or block expressions.
656    pub fn push_scope(&mut self) {
657        self.scopes.push(HashMap::new());
658    }
659
660    /// Pops the most recent variable scope from the stack.
661    ///
662    /// The global scope is never popped, ensuring at least one scope remains.
663    pub fn pop_scope(&mut self) {
664        if self.scopes.len() > 1 {
665            self.scopes.pop();
666        }
667    }
668
669    /// Defines a variable in the current (innermost) scope.
670    ///
671    /// If the variable already exists in the current scope, it is overwritten.
672    pub fn define(&mut self, name: &str, value: Value) {
673        if let Some(scope) = self.scopes.last_mut() {
674            scope.insert(name.to_string(), value);
675        }
676    }
677
678    /// Looks up a variable by name, searching from innermost to outermost scope.
679    ///
680    /// Returns the first matching variable found, or `None` if not found.
681    pub fn get(&self, name: &str) -> Option<&Value> {
682        for scope in self.scopes.iter().rev() {
683            if let Some(value) = scope.get(name) {
684                return Some(value);
685            }
686        }
687        None
688    }
689
690    /// Registers all builtin functions and their aliases in the global scope.
691    fn define_builtins(&mut self) {
692        // Register builtin functions
693        let function_names: Vec<String> = self
694            .builtins
695            .get_function_names()
696            .into_iter()
697            .map(|name| name.to_string())
698            .collect();
699        for name in &function_names {
700            self.define(name, Value::BuiltinFunction(name.clone()));
701        }
702
703        // Register aliases
704        self.define("pi", Value::BuiltinFunction("pitch_interval".to_string()));
705        self.define("T", Value::BuiltinFunction("transpose".to_string()));
706        self.define(
707            "pci",
708            Value::BuiltinFunction("pitch_class_interval".to_string()),
709        );
710        self.define("I", Value::BuiltinFunction("invert".to_string()));
711        self.define("ic", Value::BuiltinFunction("interval_class".to_string()));
712        self.define(
713            "ic_vector",
714            Value::BuiltinFunction("interval_class_vector".to_string()),
715        )
716    }
717}
718
719/// Control flow states during program execution.
720///
721/// Used to handle early returns from functions and control structures.
722#[allow(clippy::large_enum_variant)]
723#[derive(Debug, Clone, PartialEq)]
724pub enum ControlFlow {
725    /// Normal execution continues
726    None,
727    /// Return from current function with a value
728    Return(Value),
729}
730
731/// Result of executing a statement or expression.
732///
733/// Distinguishes between normal value results and control flow changes.
734#[derive(Debug, Clone, PartialEq)]
735pub enum ExecutionResult {
736    /// Normal execution produced a value
737    Value(Value),
738    /// Control flow change (return, etc.)
739    Control(ControlFlow),
740}
741
742impl ExecutionResult {
743    /// Converts this execution result into a value.
744    ///
745    /// Control flow results are converted to their contained values,
746    /// with `ControlFlow::None` becoming `Value::Nil`.
747    pub fn into_value(self) -> Value {
748        match self {
749            ExecutionResult::Value(val) => val,
750            ExecutionResult::Control(ControlFlow::Return(val)) => val,
751            ExecutionResult::Control(ControlFlow::None) => Value::Nil,
752        }
753    }
754
755    /// Returns `true` if this result represents a return statement.
756    pub fn is_return(&self) -> bool {
757        matches!(self, ExecutionResult::Control(ControlFlow::Return(_)))
758    }
759}
760
761/// The main Carmen interpreter.
762///
763/// Evaluates Carmen AST nodes and executes programs. Maintains program state
764/// including variable bindings and timing information for musical constructs.
765pub struct Interpreter {
766    /// Variable binding environment
767    environment: Environment,
768    /// Current time offset for musical event placement
769    current_time_offset: Fraction,
770}
771
772impl Default for Interpreter {
773    fn default() -> Self {
774        Self::new()
775    }
776}
777
778impl Interpreter {
779    /// Creates a new interpreter with a fresh environment.
780    pub fn new() -> Self {
781        Self {
782            environment: Environment::new(),
783            current_time_offset: Fraction::new(0, 1),
784        }
785    }
786
787    /// Returns all available symbols (variables and functions) in the environment.
788    ///
789    /// Useful for auto-completion and introspection in REPL environments.
790    pub fn get_all_symbols(&self) -> Vec<String> {
791        let mut symbols = Vec::new();
792        for scope in &self.environment.scopes {
793            symbols.extend(scope.keys().cloned());
794        }
795        symbols.extend(
796            self.environment
797                .builtins
798                .get_function_names()
799                .into_iter()
800                .map(String::from),
801        );
802        symbols.sort();
803        symbols.dedup();
804        symbols
805    }
806
807    /// Gets the value of a variable by name.
808    ///
809    /// Returns `None` if the variable is not defined.
810    pub fn get_variable(&self, name: &str) -> Option<Value> {
811        self.environment.get(name).cloned()
812    }
813
814    /// Interprets a complete Carmen program.
815    ///
816    /// Executes all statements in sequence and returns the value of the last
817    /// expression statement, or the returned value if a return statement is encountered.
818    pub fn interpret(&mut self, program: &Program) -> Result<Value> {
819        let mut last_value = Value::Nil;
820
821        for statement in &program.statements {
822            match self.execute_statement(statement)? {
823                ExecutionResult::Value(val) => last_value = val,
824                ExecutionResult::Control(ControlFlow::Return(val)) => return Ok(val),
825                ExecutionResult::Control(ControlFlow::None) => {}
826            }
827        }
828
829        Ok(last_value)
830    }
831
832    /// Creates a properly typed metadata value from a generic value.
833    ///
834    /// Validates that the value is appropriate for the given metadata key
835    /// and converts it to the correct `MetadataValue` variant.
836    fn create_metadata_value(
837        &self,
838        key: &MetadataKey,
839        value: Value,
840        span: &crate::errors::Span,
841    ) -> Result<MetadataValue> {
842        match key {
843            MetadataKey::Title
844            | MetadataKey::Composer
845            | MetadataKey::Copyright
846            | MetadataKey::Instrument => match value {
847                Value::String(s) => Ok(MetadataValue::String(s)),
848                _ => Err(
849                    ErrorSource::Type(format!("Expected string for metadata key '{key}'"))
850                        .with_span(*span),
851                ),
852            },
853            MetadataKey::Tempo | MetadataKey::Channel | MetadataKey::Offset => match value {
854                Value::Number(n) => Ok(MetadataValue::Number(n)),
855                _ => Err(
856                    ErrorSource::Type(format!("Expected number for metadata key '{key}'"))
857                        .with_span(*span),
858                ),
859            },
860            MetadataKey::TimeSignature => match value {
861                Value::Tuple(l) if l.len() == 2 => {
862                    if let (Value::Number(num), Value::Number(den)) = (&l[0], &l[1]) {
863                        if num.fract() == 0.0 && den.fract() == 0.0 && *den > 0.0 {
864                            return Ok(MetadataValue::TimeSignature(*num as u32, *den as u32));
865                        }
866                    }
867                    Err(ErrorSource::Type(
868                        "Expected tuple of two numbers for time signature".to_string(),
869                    )
870                    .with_span(*span))
871                }
872                _ => Err(ErrorSource::Type(
873                    "Expected tuple of (num, den) for time signature".to_string(),
874                )
875                .with_span(*span)),
876            },
877            MetadataKey::KeySignature => match value {
878                Value::String(s) => {
879                    let parts: Vec<&str> = s.split_whitespace().collect();
880                    let key_name = parts[0];
881                    let mode = if parts.len() > 1 {
882                        parts[1].to_lowercase()
883                    } else {
884                        "major".to_string()
885                    };
886
887                    let major_keys = ["C", "G", "D", "A", "E", "B", "F#", "C#"];
888                    let minor_keys = ["A", "E", "B", "F#", "C#", "G#", "D#", "A#"];
889
890                    match mode.as_str() {
891                        "major" => {
892                            if let Some(pos) = major_keys
893                                .iter()
894                                .position(|&k| k.eq_ignore_ascii_case(key_name))
895                            {
896                                Ok(MetadataValue::KeySignature(KeySignature::Major(pos as u8)))
897                            } else {
898                                Err(ErrorSource::Argument(format!(
899                                    "Unsupported major key signature '{s}'"
900                                ))
901                                .with_span(*span))
902                            }
903                        }
904                        "minor" => {
905                            if let Some(pos) = minor_keys
906                                .iter()
907                                .position(|&k| k.eq_ignore_ascii_case(key_name))
908                            {
909                                Ok(MetadataValue::KeySignature(KeySignature::Minor(pos as u8)))
910                            } else {
911                                Err(ErrorSource::Argument(format!(
912                                    "Unsupported minor key signature '{s}'"
913                                ))
914                                .with_span(*span))
915                            }
916                        }
917                        _ => Err(ErrorSource::Argument(format!(
918                            "Unsupported key signature mode '{mode}'"
919                        ))
920                        .with_span(*span)),
921                    }
922                }
923                _ => Err(
924                    ErrorSource::Type("Expected string for key signature".to_string())
925                        .with_span(*span),
926                ),
927            },
928            MetadataKey::Clef => match value {
929                Value::String(s) => Clef::from_str(&s)
930                    .map(MetadataValue::Clef)
931                    .map_err(|e| e.with_span(*span)),
932                _ => {
933                    Err(ErrorSource::Type("Expected string for clef".to_string()).with_span(*span))
934                }
935            },
936        }
937    }
938
939    /// Propagates octave information through a sequence of values.
940    ///
941    /// When a pitch is encountered, its octave becomes the default for subsequent
942    /// pitch classes. This allows writing `[c4, d, e, f]` instead of `[c4, d4, e4, f4]`.
943    fn propagate_implicit_octaves(&self, values: &mut Vec<Value>) {
944        let mut last_octave: Option<i8> = None;
945        for value in values {
946            process_value_octaves(value, &mut last_octave);
947        }
948    }
949
950    /// Executes a single statement and returns the result.
951    ///
952    /// Handles variable declarations, function definitions, return statements,
953    /// metadata declarations, and expression statements.
954    fn execute_statement(&mut self, statement: &SpannedStatement) -> Result<ExecutionResult> {
955        match &statement.node {
956            Statement::Expression(expr) => {
957                // For REPL: expression statements should return their value
958                // The distinction between printing/not printing is handled at REPL level
959                let val = self.evaluate_expression(expr)?;
960                Ok(ExecutionResult::Value(val))
961            }
962            Statement::VariableDeclaration { name, value, .. } => {
963                let val = self.evaluate_expression(value)?;
964                self.environment.define(name, val.clone());
965                Ok(ExecutionResult::Value(val))
966            }
967            Statement::FunctionDeclaration {
968                name, params, body, ..
969            } => {
970                let function = Value::Function {
971                    name: name.clone(),
972                    params: params.clone(),
973                    body: body.clone(),
974                };
975                self.environment.define(name, function.clone());
976                Ok(ExecutionResult::Value(function))
977            }
978            Statement::Return { value, .. } => {
979                let val = if let Some(expr) = value {
980                    self.evaluate_expression(expr)?
981                } else {
982                    Value::Nil
983                };
984                Ok(ExecutionResult::Control(ControlFlow::Return(val)))
985            }
986            Statement::Metadata { key, value, .. } => {
987                let evaluated_value = self.evaluate_expression(value)?;
988                let metadata_key = MetadataKey::try_from(Value::String(key.clone()))
989                    .map_err(|e| e.with_span(value.span))?;
990                let metadata_value =
991                    self.create_metadata_value(&metadata_key, evaluated_value, &value.span)?;
992
993                let change = ContextChange {
994                    key: metadata_key,
995                    value: metadata_value,
996                    time_offset: self.current_time_offset,
997                };
998                Ok(ExecutionResult::Value(Value::ContextChange(change)))
999            }
1000        }
1001    }
1002
1003    /// Builds a musical voice from a sequence of musical events.
1004    ///
1005    /// Calculates timing offsets for each event based on their durations.
1006    fn build_voice(&mut self, events: Vec<Value>) -> Result<Voice> {
1007        let mut voice = Voice::new();
1008        let mut voice_time_offset = Fraction::new(0, 1);
1009        for event_val in events {
1010            if let Value::MusicalEvent(event) = event_val {
1011                let mut event_with_offset = event.clone();
1012                event_with_offset.offset = voice_time_offset;
1013                voice.add_event(event_with_offset);
1014                voice_time_offset += event.total_duration();
1015            }
1016        }
1017        Ok(voice)
1018    }
1019
1020    /// Builds a musical staff from tuple elements representing voices.
1021    ///
1022    /// Each element in the tuple becomes a separate voice on the staff.
1023    fn build_staff_from_tuple(
1024        &mut self,
1025        elements: Vec<Value>,
1026        num_staves: usize,
1027        span: &crate::errors::Span,
1028    ) -> Result<Staff> {
1029        let mut staff = Staff::new((num_staves + 1) as u32);
1030        for voice_val in elements {
1031            let events_for_voice = match voice_val {
1032                Value::List(events) => events,
1033                Value::MusicalEvent(event) => match event.content {
1034                    EventContent::Sequence(events) => {
1035                        events.into_iter().map(Value::MusicalEvent).collect()
1036                    }
1037                    _ => vec![Value::MusicalEvent(event)],
1038                },
1039                _ => {
1040                    return Err(ErrorSource::Runtime(
1041                        "Tuples in a part must contain lists or musical events.".to_string(),
1042                    )
1043                    .with_span(*span));
1044                }
1045            };
1046            let voice = self.build_voice(events_for_voice)?;
1047            staff = staff.add_voice(voice);
1048        }
1049        Ok(staff)
1050    }
1051
1052    /// Evaluates an expression and returns its value.
1053    ///
1054    /// This is the core evaluation function that handles all expression types
1055    /// including literals, variables, function calls, control structures, and
1056    /// musical constructs.
1057    fn evaluate_expression(&mut self, expression: &SpannedExpression) -> Result<Value> {
1058        match &expression.node {
1059            Expression::Literal(literal) => SpannedLiteral {
1060                node: literal.clone(),
1061                span: expression.span,
1062            }
1063            .try_into(),
1064            Expression::Identifier(name) => self.environment.get(name).cloned().ok_or_else(|| {
1065                ErrorSource::Runtime(format!("Undefined variable '{name}'"))
1066                    .with_span(expression.span)
1067            }),
1068            Expression::Binary {
1069                left,
1070                operator,
1071                right,
1072            } => {
1073                let left_val = self.evaluate_expression(left)?;
1074                let right_val = self.evaluate_expression(right)?;
1075                self.evaluate_binary_op(&left_val, operator, &right_val, &expression.span)
1076            }
1077            Expression::Unary { operator, operand } => {
1078                let val = self.evaluate_expression(operand)?;
1079                self.evaluate_unary_op(operator, &val, &expression.span)
1080            }
1081            Expression::Call {
1082                callee,
1083                args,
1084                kwargs,
1085            } => {
1086                let function = self.evaluate_expression(callee)?;
1087                let arg_values: Result<Vec<Value>> = args
1088                    .iter()
1089                    .map(|arg| self.evaluate_expression(arg))
1090                    .collect();
1091                let arg_values = arg_values?;
1092
1093                let kwarg_values: Result<Vec<(String, Value)>> = kwargs
1094                    .iter()
1095                    .map(|(name, expr)| Ok((name.clone(), self.evaluate_expression(expr)?)))
1096                    .collect();
1097                let kwarg_values = kwarg_values?;
1098
1099                self.call_function(&function, &arg_values, &kwarg_values, &expression.span)
1100            }
1101            Expression::Pipe { left, right } => {
1102                let left_val = self.evaluate_expression(left)?;
1103                match right.as_ref() {
1104                    Spanned {
1105                        node:
1106                            Expression::Call {
1107                                callee,
1108                                args,
1109                                kwargs,
1110                            },
1111                        ..
1112                    } => {
1113                        let function = self.evaluate_expression(callee)?;
1114                        let mut arg_values = vec![left_val];
1115                        for arg in args {
1116                            arg_values.push(self.evaluate_expression(arg)?);
1117                        }
1118
1119                        let kwarg_values: Result<Vec<(String, Value)>> = kwargs
1120                            .iter()
1121                            .map(|(name, expr)| Ok((name.clone(), self.evaluate_expression(expr)?)))
1122                            .collect();
1123                        let kwarg_values = kwarg_values?;
1124                        self.call_function(&function, &arg_values, &kwarg_values, &expression.span)
1125                    }
1126                    _ => Err(ErrorSource::Runtime(
1127                        "Pipe right side must be a function call".to_string(),
1128                    )
1129                    .with_span(expression.span)),
1130                }
1131            }
1132            Expression::List { elements, .. } => {
1133                let values: Result<Vec<Value>> = elements
1134                    .iter()
1135                    .map(|elem| self.evaluate_expression(elem))
1136                    .collect();
1137                let mut values = values?;
1138                self.propagate_implicit_octaves(&mut values);
1139                Ok(Value::List(values))
1140            }
1141            Expression::Tuple { elements, .. } => {
1142                let values: Result<Vec<Value>> = elements
1143                    .iter()
1144                    .map(|elem| self.evaluate_expression(elem))
1145                    .collect();
1146                let mut values = values?;
1147                self.propagate_implicit_octaves(&mut values);
1148
1149                // If all elements are pitches, create a chord
1150                if values.iter().all(|v| matches!(v, Value::Pitch(_))) {
1151                    let pitches: Vec<Pitch> = values
1152                        .into_iter()
1153                        .map(|v| match v {
1154                            Value::Pitch(p) => p,
1155                            _ => unreachable!(),
1156                        })
1157                        .collect();
1158                    Ok(Value::Chord(Chord { pitches }))
1159                } else {
1160                    Ok(Value::Tuple(values))
1161                }
1162            }
1163            Expression::Set { elements, .. } => {
1164                let values: Result<Vec<Value>> = elements
1165                    .iter()
1166                    .map(|elem| self.evaluate_expression(elem))
1167                    .collect();
1168                Ok(Value::Set(values?))
1169            }
1170            Expression::Block { statements, .. } => {
1171                self.environment.push_scope();
1172                let mut last_value = Value::Nil;
1173
1174                for stmt in statements {
1175                    match self.execute_statement(stmt)? {
1176                        ExecutionResult::Value(val) => last_value = val,
1177                        ExecutionResult::Control(flow) => {
1178                            self.environment.pop_scope();
1179                            return Ok(ExecutionResult::Control(flow).into_value());
1180                        }
1181                    }
1182                }
1183
1184                self.environment.pop_scope();
1185                Ok(last_value)
1186            }
1187            Expression::If {
1188                condition,
1189                then_branch,
1190                else_branch,
1191                ..
1192            } => {
1193                let condition_val = self.evaluate_expression(condition)?;
1194
1195                if condition_val.is_truthy() {
1196                    self.evaluate_expression(then_branch)
1197                } else if let Some(else_expr) = else_branch {
1198                    self.evaluate_expression(else_expr)
1199                } else {
1200                    Ok(Value::Nil)
1201                }
1202            }
1203            Expression::For {
1204                variable,
1205                iterable,
1206                body,
1207            } => {
1208                let iterable_val = self.evaluate_expression(iterable)?;
1209
1210                match iterable_val {
1211                    Value::List(items) => {
1212                        self.environment.push_scope();
1213                        let mut results = Vec::new();
1214
1215                        for item in items {
1216                            self.environment.define(variable, item);
1217                            results.push(self.evaluate_expression(body)?);
1218                        }
1219
1220                        self.environment.pop_scope();
1221                        Ok(Value::List(results))
1222                    }
1223                    _ => Err(
1224                        ErrorSource::Runtime("For loop requires iterable".to_string())
1225                            .with_span(expression.span),
1226                    ),
1227                }
1228            }
1229            Expression::While { condition, body } => {
1230                let mut results = Vec::new();
1231                let mut iterations = 0;
1232                const MAX_ITERATIONS: usize = 10000; // TODO: Prevent infinite loops in a better way
1233
1234                while iterations < MAX_ITERATIONS {
1235                    let condition_val = self.evaluate_expression(condition)?;
1236                    if !condition_val.is_truthy() {
1237                        break;
1238                    }
1239
1240                    results.push(self.evaluate_expression(body)?);
1241                    iterations += 1;
1242                }
1243
1244                if iterations >= MAX_ITERATIONS {
1245                    return Err(ErrorSource::Runtime(
1246                        "While loop exceeded maximum iterations".to_string(),
1247                    )
1248                    .with_span(expression.span));
1249                }
1250
1251                Ok(Value::List(results))
1252            }
1253            Expression::PitchClassSet { classes, .. } => {
1254                let pitch_classes: Vec<PitchClass> =
1255                    classes.iter().map(|&n| PitchClass::new(n)).collect();
1256                Ok(Value::PitchClassSet(PitchClassSet::new(pitch_classes)))
1257            }
1258            Expression::MusicalEvent {
1259                duration,
1260                pitches,
1261                dynamic,
1262                attributes,
1263                ..
1264            } => {
1265                let duration_val = self.evaluate_expression(duration)?;
1266                let pitches_val = self.evaluate_expression(pitches)?;
1267
1268                let duration = match duration_val {
1269                    Value::Duration(d) => d,
1270                    _ => {
1271                        return Err(ErrorSource::Runtime("Expected duration".to_string())
1272                            .with_span(expression.span))
1273                    }
1274                };
1275
1276                let content =
1277                    match pitches_val {
1278                        Value::Pitch(p) => EventContent::Note(p),
1279                        Value::Chord(c) => EventContent::Chord(c),
1280                        Value::Rest => EventContent::Rest,
1281                        Value::List(elements) => {
1282                            let mut events = Vec::new();
1283                            let mut current_offset = Fraction::new(0, 1);
1284
1285                            for element in elements {
1286                                match element {
1287                                    Value::MusicalEvent(mut event) => {
1288                                        event.offset = current_offset;
1289                                        current_offset += event.duration.fraction;
1290                                        events.push(event);
1291                                    }
1292                                    Value::Pitch(pitch) => {
1293                                        let mut event = MusicalEvent::note(pitch, duration);
1294                                        event.offset = current_offset;
1295                                        events.push(event);
1296                                        current_offset += duration.fraction;
1297                                    }
1298                                    Value::Rest => {
1299                                        let mut rest_event = MusicalEvent::rest(duration);
1300                                        rest_event.offset = current_offset;
1301                                        events.push(rest_event);
1302                                        current_offset += duration.fraction;
1303                                    }
1304                                    Value::Chord(chord) => {
1305                                        let mut chord_event = MusicalEvent::chord(chord, duration);
1306                                        chord_event.offset = current_offset;
1307                                        events.push(chord_event);
1308                                        current_offset += duration.fraction;
1309                                    }
1310                                    _ => return Err(ErrorSource::Runtime(
1311                                        "Expected musical event, pitch, chord or rest in sequence"
1312                                            .to_string(),
1313                                    )
1314                                    .with_span(expression.span)),
1315                                }
1316                            }
1317
1318                            EventContent::Sequence(events)
1319                        }
1320                        Value::Tuple(pitches) => {
1321                            let pitch_vec: Result<Vec<Pitch>> = pitches
1322                                .into_iter()
1323                                .map(|p| match p {
1324                                    Value::Pitch(pitch) => Ok(pitch),
1325                                    _ => Err(ErrorSource::Runtime(
1326                                        "Expected pitch in tuple chord".to_string(),
1327                                    )
1328                                    .with_span(expression.span)),
1329                                })
1330                                .collect();
1331                            EventContent::Chord(Chord {
1332                                pitches: pitch_vec?,
1333                            })
1334                        }
1335                        _ => {
1336                            return Err(ErrorSource::Runtime(
1337                                "Expected pitch, chord, or list of pitches".to_string(),
1338                            )
1339                            .with_span(expression.span))
1340                        }
1341                    };
1342
1343                let mut event = MusicalEvent {
1344                    duration,
1345                    content,
1346                    dynamic: None,
1347                    attributes: Vec::new(),
1348                    offset: Fraction::new(0, 1),
1349                };
1350
1351                if let Some(dyn_expr) = dynamic {
1352                    let dyn_val = self.evaluate_expression(dyn_expr)?;
1353                    if let Value::Dynamic(d) = dyn_val {
1354                        event.dynamic = Some(d);
1355                    }
1356                }
1357
1358                for attr_expr in attributes {
1359                    let attr_val = self.evaluate_expression(attr_expr)?;
1360                    if let Value::Attribute(a) = attr_val {
1361                        event.attributes.push(a);
1362                    }
1363                }
1364
1365                Ok(Value::MusicalEvent(event))
1366            }
1367            Expression::Part { name, body, .. } => {
1368                let part_name = if let Some(name_expr) = name {
1369                    let name_val = self.evaluate_expression(name_expr)?;
1370                    match name_val {
1371                        Value::String(s) => Some(s),
1372                        _ => None,
1373                    }
1374                } else {
1375                    None
1376                };
1377
1378                let mut part = Part::new(part_name);
1379                let initial_time_offset = self.current_time_offset;
1380                self.current_time_offset = Fraction::new(0, 1); // Reset time for new part scope
1381
1382                // Handle block bodies specially to collect all statements
1383                match body.node {
1384                    Expression::Block { ref statements, .. } => {
1385                        self.environment.push_scope();
1386                        let mut collected_changes_in_scope = Vec::new();
1387
1388                        for stmt in statements {
1389                            let result = self.execute_statement(stmt)?;
1390                            match result {
1391                                ExecutionResult::Value(val) => match val {
1392                                    Value::MusicalEvent(event) => {
1393                                        let mut event_with_offset = event.clone();
1394                                        event_with_offset.offset = self.current_time_offset;
1395                                        part.add_event(event_with_offset);
1396                                        self.current_time_offset += event.total_duration();
1397                                    }
1398                                    Value::Staff(staff) => {
1399                                        part.add_staff(staff);
1400                                    }
1401                                    Value::ContextChange(change) => {
1402                                        collected_changes_in_scope.push(change);
1403                                    }
1404                                    Value::List(items) => {
1405                                        for item in items {
1406                                            if let Value::MusicalEvent(event) = item {
1407                                                let mut event_with_offset = event.clone();
1408                                                event_with_offset.offset = self.current_time_offset;
1409                                                part.add_event(event_with_offset);
1410                                                self.current_time_offset += event.total_duration();
1411                                            }
1412                                        }
1413                                    }
1414                                    Value::Tuple(elements) => {
1415                                        let staff = self.build_staff_from_tuple(
1416                                            elements,
1417                                            part.staves.len(),
1418                                            &stmt.span,
1419                                        )?;
1420                                        part.add_staff(staff);
1421                                    }
1422                                    _ => {}
1423                                },
1424                                ExecutionResult::Control(_) => break,
1425                            }
1426                        }
1427
1428                        self.environment.pop_scope();
1429                        part.context_changes.extend(collected_changes_in_scope);
1430                    }
1431                    _ => {
1432                        // Handle non-block bodies
1433                        let body_val = self.evaluate_expression(body)?;
1434                        match body_val {
1435                            Value::MusicalEvent(event) => {
1436                                let mut event_with_offset = event.clone();
1437                                event_with_offset.offset = self.current_time_offset;
1438                                part.add_event(event_with_offset);
1439                                self.current_time_offset += event.total_duration();
1440                            }
1441                            Value::Staff(staff) => {
1442                                part.add_staff(staff);
1443                            }
1444                            Value::ContextChange(change) => {
1445                                part.add_context_change(change);
1446                            }
1447                            Value::List(items) => {
1448                                for item in items {
1449                                    if let Value::MusicalEvent(event) = item {
1450                                        let mut event_with_offset = event.clone();
1451                                        event_with_offset.offset = self.current_time_offset;
1452                                        part.add_event(event_with_offset);
1453                                        self.current_time_offset += event.total_duration();
1454                                    }
1455                                }
1456                            }
1457                            Value::Tuple(elements) => {
1458                                let staff = self.build_staff_from_tuple(
1459                                    elements,
1460                                    part.staves.len(),
1461                                    &expression.span,
1462                                )?;
1463                                part.add_staff(staff);
1464                            }
1465                            _ => {}
1466                        }
1467                    }
1468                }
1469                self.current_time_offset = initial_time_offset; // Restore time
1470                Ok(Value::Part(part))
1471            }
1472            Expression::Staff { number, body, .. } => {
1473                let number_val = self.evaluate_expression(number)?;
1474                let number = match number_val {
1475                    Value::Number(n) => n as u32,
1476                    _ => {
1477                        return Err(
1478                            ErrorSource::Runtime("Expected number for staff".to_string())
1479                                .with_span(expression.span),
1480                        )
1481                    }
1482                };
1483
1484                let mut staff = Staff::new(number);
1485                let initial_time_offset = self.current_time_offset;
1486                self.current_time_offset = Fraction::new(0, 1); // Reset time for new staff scope
1487
1488                let body_val = self.evaluate_expression(body)?;
1489                match body_val {
1490                    Value::MusicalEvent(event) => {
1491                        let voice = self.build_voice(vec![Value::MusicalEvent(event)])?;
1492                        staff = staff.add_voice(voice);
1493                    }
1494                    Value::List(events) => {
1495                        let voice = self.build_voice(events)?;
1496                        staff = staff.add_voice(voice);
1497                    }
1498                    Value::Tuple(elements) => {
1499                        for voice_val in elements {
1500                            let events_for_voice = match voice_val {
1501                                Value::List(events) => events,
1502                                Value::MusicalEvent(event) => match event.content {
1503                                    EventContent::Sequence(events) => {
1504                                        events.into_iter().map(Value::MusicalEvent).collect()
1505                                    }
1506                                    _ => vec![Value::MusicalEvent(event)],
1507                                },
1508                                _ => {
1509                                    return Err(ErrorSource::Runtime(
1510                                        "Tuples in a staff must contain lists or musical events."
1511                                            .to_string(),
1512                                    )
1513                                    .with_span(expression.span));
1514                                }
1515                            };
1516                            let voice = self.build_voice(events_for_voice)?;
1517                            staff = staff.add_voice(voice);
1518                        }
1519                    }
1520                    Value::ContextChange(change) => {
1521                        staff.add_context_change(change);
1522                    }
1523                    _ => {}
1524                }
1525
1526                // After evaluating the main content, check for any context changes within the block
1527                if let Expression::Block { statements, .. } = &body.node {
1528                    for stmt in statements {
1529                        if let Statement::Metadata { key, value, .. } = &stmt.node {
1530                            let evaluated_value = self.evaluate_expression(value)?;
1531                            let metadata_key = MetadataKey::try_from(Value::String(key.clone()))
1532                                .map_err(|e| e.with_span(value.span))?;
1533                            let metadata_value = self.create_metadata_value(
1534                                &metadata_key,
1535                                evaluated_value,
1536                                &value.span,
1537                            )?;
1538                            let change = ContextChange {
1539                                key: metadata_key,
1540                                value: metadata_value,
1541                                time_offset: self.current_time_offset,
1542                            };
1543                            staff.add_context_change(change);
1544                        }
1545                    }
1546                }
1547
1548                self.current_time_offset = initial_time_offset; // Restore time
1549                Ok(Value::Staff(staff))
1550            }
1551            Expression::Timeline { body, .. } => {
1552                let mut timeline = Timeline::default();
1553                let initial_time_offset = self.current_time_offset;
1554                self.current_time_offset = Fraction::new(0, 1); // Reset time for new timeline scope
1555
1556                // Handle block bodies specially to collect all statements
1557                match body.node {
1558                    Expression::Block { ref statements, .. } => {
1559                        self.environment.push_scope();
1560                        let mut collected_changes_in_scope = Vec::new();
1561
1562                        for stmt in statements {
1563                            let result = self.execute_statement(stmt)?;
1564                            match result {
1565                                ExecutionResult::Value(val) => match val {
1566                                    Value::Part(part) => {
1567                                        timeline.add_part(part);
1568                                    }
1569                                    Value::List(parts) => {
1570                                        for part_val in parts {
1571                                            if let Value::Part(part) = part_val {
1572                                                timeline.add_part(part);
1573                                            }
1574                                        }
1575                                    }
1576                                    Value::ContextChange(change) => {
1577                                        collected_changes_in_scope.push(change);
1578                                    }
1579                                    _ => {}
1580                                },
1581                                ExecutionResult::Control(_) => break,
1582                            }
1583                        }
1584
1585                        self.environment.pop_scope();
1586                        timeline.context_changes.extend(collected_changes_in_scope);
1587                    }
1588                    _ => {
1589                        let body_val = self.evaluate_expression(body)?;
1590                        match body_val {
1591                            Value::Part(part) => {
1592                                timeline.add_part(part);
1593                            }
1594                            Value::List(parts) => {
1595                                for part_val in parts {
1596                                    if let Value::Part(part) = part_val {
1597                                        timeline.add_part(part);
1598                                    }
1599                                }
1600                            }
1601                            Value::ContextChange(change) => {
1602                                timeline.add_context_change(change);
1603                            }
1604                            _ => {}
1605                        }
1606                    }
1607                }
1608                self.current_time_offset = initial_time_offset; // Restore time
1609                Ok(Value::Timeline(timeline))
1610            }
1611            Expression::Movement { name, body, .. } => {
1612                let movement_name = if let Some(name_expr) = name {
1613                    let name_val = self.evaluate_expression(name_expr)?;
1614                    match name_val {
1615                        Value::String(s) => Some(s),
1616                        _ => None,
1617                    }
1618                } else {
1619                    None
1620                };
1621
1622                let mut movement = Movement::new(movement_name);
1623                let initial_time_offset = self.current_time_offset;
1624                self.current_time_offset = Fraction::new(0, 1); // Reset time for new movement scope
1625
1626                // Handle block bodies specially to collect all statements
1627                match body.node {
1628                    Expression::Block { ref statements, .. } => {
1629                        self.environment.push_scope();
1630                        let mut collected_changes_in_scope = Vec::new();
1631
1632                        for stmt in statements {
1633                            let result = self.execute_statement(stmt)?;
1634                            match result {
1635                                ExecutionResult::Value(val) => match val {
1636                                    Value::Timeline(timeline) => {
1637                                        movement = movement.with_timeline(timeline);
1638                                    }
1639                                    Value::ContextChange(change) => {
1640                                        collected_changes_in_scope.push(change);
1641                                    }
1642                                    _ => {}
1643                                },
1644                                ExecutionResult::Control(_) => break,
1645                            }
1646                        }
1647
1648                        self.environment.pop_scope();
1649                        movement.context_changes.extend(collected_changes_in_scope);
1650                    }
1651                    _ => {
1652                        let body_val = self.evaluate_expression(body)?;
1653                        match body_val {
1654                            Value::Timeline(timeline) => {
1655                                movement = movement.with_timeline(timeline);
1656                            }
1657                            Value::ContextChange(change) => {
1658                                movement.add_context_change(change);
1659                            }
1660                            _ => {
1661                                return Err(ErrorSource::Runtime(
1662                                    "Movement body must contain a timeline or context changes"
1663                                        .to_string(),
1664                                )
1665                                .with_span(expression.span))
1666                            }
1667                        }
1668                    }
1669                }
1670                self.current_time_offset = initial_time_offset; // Restore time
1671                Ok(Value::Movement(movement))
1672            }
1673            Expression::Score { name, body, .. } => {
1674                let score_name = if let Some(name_expr) = name {
1675                    let name_val = self.evaluate_expression(name_expr)?;
1676                    match name_val {
1677                        Value::String(s) => Some(s),
1678                        _ => None,
1679                    }
1680                } else {
1681                    None
1682                };
1683
1684                let mut score = Score::default();
1685                if let Some(name) = score_name {
1686                    score = score.with_name(name);
1687                }
1688                let initial_time_offset = self.current_time_offset;
1689                self.current_time_offset = Fraction::new(0, 1); // Reset time for new score scope
1690
1691                // Handle block bodies specially to collect all statements
1692                match body.node {
1693                    Expression::Block { ref statements, .. } => {
1694                        self.environment.push_scope();
1695                        let mut collected_changes_in_scope = Vec::new();
1696
1697                        for stmt in statements {
1698                            let result = self.execute_statement(stmt)?;
1699                            match result {
1700                                ExecutionResult::Value(val) => match val {
1701                                    Value::Timeline(timeline) => {
1702                                        score.set_timeline(timeline);
1703                                    }
1704                                    Value::Movement(movement) => {
1705                                        score.add_movement(movement);
1706                                    }
1707                                    Value::ContextChange(change) => {
1708                                        collected_changes_in_scope.push(change);
1709                                    }
1710                                    Value::List(items) => {
1711                                        for item in items {
1712                                            match item {
1713                                                Value::Movement(movement) => {
1714                                                    score.add_movement(movement);
1715                                                }
1716                                                Value::Timeline(timeline) => {
1717                                                    score.set_timeline(timeline);
1718                                                }
1719                                                Value::ContextChange(change) => {
1720                                                    collected_changes_in_scope.push(change);
1721                                                }
1722                                                _ => {}
1723                                            }
1724                                        }
1725                                    }
1726                                    _ => {}
1727                                },
1728                                ExecutionResult::Control(_) => break,
1729                            }
1730                        }
1731
1732                        self.environment.pop_scope();
1733                        score.context_changes.extend(collected_changes_in_scope);
1734                    }
1735                    _ => {
1736                        let body_val = self.evaluate_expression(body)?;
1737                        match body_val {
1738                            Value::Timeline(timeline) => {
1739                                score.set_timeline(timeline);
1740                            }
1741                            Value::Movement(movement) => {
1742                                score.add_movement(movement);
1743                            }
1744                            Value::ContextChange(change) => {
1745                                score.add_context_change(change);
1746                            }
1747                            Value::List(items) => {
1748                                for item in items {
1749                                    match item {
1750                                        Value::Movement(movement) => {
1751                                            score.add_movement(movement);
1752                                        }
1753                                        Value::Timeline(timeline) => {
1754                                            score.set_timeline(timeline);
1755                                        }
1756                                        Value::ContextChange(change) => {
1757                                            score.add_context_change(change);
1758                                        }
1759                                        _ => {}
1760                                    }
1761                                }
1762                            }
1763                            _ => {}
1764                        }
1765                    }
1766                }
1767                self.current_time_offset = initial_time_offset; // Restore time
1768                Ok(Value::Score(score))
1769            }
1770        }
1771    }
1772
1773    /// Evaluates a binary operation between two values.
1774    ///
1775    /// Handles arithmetic, comparison, logical, and musical operations
1776    /// like transposition and duration arithmetic.
1777    fn evaluate_binary_op(
1778        &self,
1779        left: &Value,
1780        operator: &BinaryOp,
1781        right: &Value,
1782        span: &crate::errors::Span,
1783    ) -> Result<Value> {
1784        match (left, operator, right) {
1785            // Arithmetic operations
1786            (Value::Number(a), BinaryOp::Add, Value::Number(b)) => Ok(Value::Number(a + b)),
1787            (Value::Number(a), BinaryOp::Subtract, Value::Number(b)) => Ok(Value::Number(a - b)),
1788            (Value::Number(a), BinaryOp::Multiply, Value::Number(b)) => Ok(Value::Number(a * b)),
1789            (Value::Number(a), BinaryOp::Divide, Value::Number(b)) => {
1790                if *b == 0.0 {
1791                    Err(ErrorSource::Runtime("Division by zero".to_string()).with_span(*span))
1792                } else {
1793                    Ok(Value::Number(a / b))
1794                }
1795            }
1796            (Value::Number(a), BinaryOp::Modulo, Value::Number(b)) => Ok(Value::Number(a % b)),
1797
1798            // String concatenation
1799            (Value::String(a), BinaryOp::Add, Value::String(b)) => {
1800                Ok(Value::String(format!("{a}{b}")))
1801            }
1802
1803            // List operations
1804            (Value::List(a), BinaryOp::Add, Value::List(b)) => {
1805                let mut result = a.clone();
1806                result.extend(b.iter().cloned());
1807                Ok(Value::List(result))
1808            }
1809            (Value::List(a), BinaryOp::Multiply, Value::Number(n)) => {
1810                let n = *n as usize;
1811                let mut result = Vec::new();
1812                for _ in 0..n {
1813                    result.extend(a.clone());
1814                }
1815                Ok(Value::List(result))
1816            }
1817
1818            // Duration operations
1819            (Value::Duration(a), BinaryOp::Add, Value::Duration(b)) => Ok(Value::Duration(a + b)),
1820            (Value::Duration(a), BinaryOp::Multiply, Value::Number(b)) => {
1821                Ok(Value::Duration(a * (*b as u32)))
1822            }
1823
1824            // Pitch transposition
1825            (Value::Pitch(p), BinaryOp::Add, Value::Number(n)) => {
1826                Ok(Value::Pitch(p.transpose(*n as i32)))
1827            }
1828            (Value::Pitch(p), BinaryOp::Subtract, Value::Number(n)) => {
1829                Ok(Value::Pitch(p.transpose(-(*n as i32))))
1830            }
1831
1832            // Pitch class transposition
1833            (Value::PitchClass(pc), BinaryOp::Add, Value::Number(n)) => {
1834                Ok(Value::PitchClass(pc.transpose(*n as i32)))
1835            }
1836            (Value::PitchClass(pc), BinaryOp::Subtract, Value::Number(n)) => {
1837                Ok(Value::PitchClass(pc.transpose(-(*n as i32))))
1838            }
1839
1840            // Pitch class set transposition
1841            // Part concatenation
1842            (Value::Part(a), BinaryOp::Add, Value::Part(b)) => Ok(Value::Part(a.merge(b))),
1843
1844            // Pitch class set transposition
1845            (Value::PitchClassSet(pcs), BinaryOp::Add, Value::Number(n)) => {
1846                Ok(Value::PitchClassSet(pcs.transpose(*n as i32)))
1847            }
1848            (Value::PitchClassSet(pcs), BinaryOp::Subtract, Value::Number(n)) => {
1849                Ok(Value::PitchClassSet(pcs.transpose(-(*n as i32))))
1850            }
1851
1852            // Comparison operations
1853            (Value::Number(a), BinaryOp::Equal, Value::Number(b)) => Ok(Value::Boolean(a == b)),
1854            (Value::Number(a), BinaryOp::NotEqual, Value::Number(b)) => Ok(Value::Boolean(a != b)),
1855            (Value::Number(a), BinaryOp::Less, Value::Number(b)) => Ok(Value::Boolean(a < b)),
1856            (Value::Number(a), BinaryOp::Greater, Value::Number(b)) => Ok(Value::Boolean(a > b)),
1857            (Value::Number(a), BinaryOp::LessEqual, Value::Number(b)) => Ok(Value::Boolean(a <= b)),
1858            (Value::Number(a), BinaryOp::GreaterEqual, Value::Number(b)) => {
1859                Ok(Value::Boolean(a >= b))
1860            }
1861
1862            (Value::String(a), BinaryOp::Equal, Value::String(b)) => Ok(Value::Boolean(a == b)),
1863            (Value::String(a), BinaryOp::NotEqual, Value::String(b)) => Ok(Value::Boolean(a != b)),
1864
1865            (Value::Boolean(a), BinaryOp::Equal, Value::Boolean(b)) => Ok(Value::Boolean(a == b)),
1866            (Value::Boolean(a), BinaryOp::NotEqual, Value::Boolean(b)) => {
1867                Ok(Value::Boolean(a != b))
1868            }
1869
1870            // Logical operations
1871            (Value::Boolean(a), BinaryOp::And, Value::Boolean(b)) => Ok(Value::Boolean(*a && *b)),
1872            (Value::Boolean(a), BinaryOp::Or, Value::Boolean(b)) => Ok(Value::Boolean(*a || *b)),
1873
1874            _ => Err(ErrorSource::Type(format!(
1875                "Unsupported operation: {} {:?} {}",
1876                left.type_name(),
1877                operator,
1878                right.type_name()
1879            ))
1880            .with_span(*span)),
1881        }
1882    }
1883
1884    /// Evaluates a unary operation on a value.
1885    ///
1886    /// Supports negation for numbers and logical NOT for booleans.
1887    fn evaluate_unary_op(
1888        &self,
1889        operator: &UnaryOp,
1890        operand: &Value,
1891        span: &crate::errors::Span,
1892    ) -> Result<Value> {
1893        match (operator, operand) {
1894            (UnaryOp::Minus, Value::Number(n)) => Ok(Value::Number(-n)),
1895            (UnaryOp::Not, Value::Boolean(b)) => Ok(Value::Boolean(!b)),
1896            (UnaryOp::Not, val) => Ok(Value::Boolean(!val.is_truthy())),
1897            _ => Err(ErrorSource::Type(format!(
1898                "Unsupported unary operation: {:?} {}",
1899                operator,
1900                operand.type_name()
1901            ))
1902            .with_span(*span)),
1903        }
1904    }
1905
1906    /// Calls a function (user-defined or builtin) with the given arguments.
1907    ///
1908    /// For user-defined functions, creates a new scope, binds parameters,
1909    /// and executes the function body. For builtin functions, delegates
1910    /// to the builtin registry.
1911    fn call_function(
1912        &mut self,
1913        function: &Value,
1914        args: &[Value],
1915        kwargs: &[(String, Value)],
1916        span: &crate::errors::Span,
1917    ) -> Result<Value> {
1918        match function {
1919            Value::Function { params, body, .. } => {
1920                if args.len() != params.len() {
1921                    return Err(ErrorSource::Runtime(format!(
1922                        "Expected {} arguments, got {}",
1923                        params.len(),
1924                        args.len()
1925                    ))
1926                    .with_span(*span));
1927                }
1928
1929                self.environment.push_scope();
1930
1931                // Bind parameters
1932                for (param, arg) in params.iter().zip(args.iter()) {
1933                    self.environment.define(param, arg.clone());
1934                }
1935
1936                // Execute function body
1937                let mut result = Value::Nil;
1938                for (i, stmt) in body.iter().enumerate() {
1939                    let is_last = i == body.len() - 1;
1940
1941                    match self.execute_statement(stmt)? {
1942                        ExecutionResult::Value(val) => {
1943                            if is_last {
1944                                result = val;
1945                            }
1946                        }
1947                        ExecutionResult::Control(ControlFlow::Return(val)) => {
1948                            self.environment.pop_scope();
1949                            return Ok(val);
1950                        }
1951                        ExecutionResult::Control(ControlFlow::None) => {}
1952                    }
1953                }
1954
1955                self.environment.pop_scope();
1956                Ok(result)
1957            }
1958            Value::BuiltinFunction(name) => {
1959                call_builtin_function(name, args, kwargs, span, &self.environment.builtins)
1960            }
1961            _ => Err(ErrorSource::Runtime("Not a function".to_string()).with_span(*span)),
1962        }
1963    }
1964}
1965
1966/// Recursively processes values to propagate octave information.
1967///
1968/// Updates the `last_octave` tracker based on pitches encountered,
1969/// and converts pitch classes to pitches when an octave is available.
1970fn process_value_octaves(value: &mut Value, last_octave: &mut Option<i8>) {
1971    match value {
1972        Value::Pitch(p) => {
1973            *last_octave = Some(p.octave);
1974        }
1975        Value::PitchClass(pc) => {
1976            if let Some(oct) = *last_octave {
1977                *value = Value::Pitch(Pitch {
1978                    pitch_class: *pc,
1979                    octave: oct,
1980                });
1981            }
1982        }
1983        Value::List(values) | Value::Tuple(values) => {
1984            for val in values {
1985                process_value_octaves(val, last_octave);
1986            }
1987        }
1988        Value::MusicalEvent(event) => {
1989            // Update current_time_offset based on the event's duration
1990            *last_octave = match &event.content {
1991                EventContent::Note(p) => Some(p.octave),
1992                EventContent::Chord(c) => c.pitches.last().map(|p| p.octave),
1993                EventContent::Sequence(events) => events.last().and_then(|e| match &e.content {
1994                    EventContent::Note(p) => Some(p.octave),
1995                    EventContent::Chord(c) => c.pitches.last().map(|p| p.octave),
1996                    _ => None,
1997                }),
1998                _ => None,
1999            };
2000        }
2001        Value::ContextChange(_) => {
2002            // Context changes don't affect octave propagation
2003        }
2004        _ => {}
2005    }
2006}
2007
2008/// Calls a builtin function through the registry.
2009///
2010/// This is a convenience wrapper around the registry's call method.
2011fn call_builtin_function(
2012    name: &str,
2013    args: &[Value],
2014    kwargs: &[(String, Value)],
2015    span: &crate::errors::Span,
2016    registry: &BuiltinRegistry,
2017) -> Result<Value> {
2018    registry.call(name, args, kwargs, span)
2019}