//! Compiled operation variants for the Forth VM instruction set.

use std::sync::Arc;

use super::types::SourceSpan;

/// Single VM instruction produced by the compiler.
#[derive(Clone, Debug, PartialEq)]
pub enum Op {
    PushInt(i64, Option<SourceSpan>),
    PushFloat(f64, Option<SourceSpan>),
    PushStr(Arc<str>, Option<SourceSpan>),
    Dup,
    Dupn,
    Drop,
    Swap,
    Over,
    Rot,
    Nip,
    Tuck,
    Dup2,
    Drop2,
    Swap2,
    Over2,
    Rev,
    Shuffle,
    Sort,
    RSort,
    Sum,
    Prod,
    Forget,
    Add,
    Sub,
    Mul,
    Div,
    Mod,
    Neg,
    Abs,
    Floor,
    Ceil,
    Round,
    Min,
    Max,
    Pow,
    Sqrt,
    Sin,
    Cos,
    Log,
    Eq,
    Ne,
    Lt,
    Gt,
    Le,
    Ge,
    And,
    Or,
    Not,
    Xor,
    Nand,
    Nor,
    IfElse,
    Pick,
    BranchIfZero(usize, Option<SourceSpan>, Option<SourceSpan>),
    Branch(usize),
    NewCmd,
    SetParam(&'static str),
    Emit,
    Get,
    Set,
    SetKeep,
    GetContext(&'static str),
    Rand(Option<SourceSpan>),
    ExpRand(Option<SourceSpan>),
    LogRand(Option<SourceSpan>),
    Seed,
    Cycle(Option<SourceSpan>),
    PCycle(Option<SourceSpan>),
    Choose(Option<SourceSpan>),
    Bounce(Option<SourceSpan>),
    PBounce(Option<SourceSpan>),
    WChoose(Option<SourceSpan>),
    ChanceExec(Option<SourceSpan>),
    ProbExec(Option<SourceSpan>),
    Coin(Option<SourceSpan>),
    Mtof,
    Ftom,
    SetTempo,
    Every(Option<SourceSpan>),
    Except(Option<SourceSpan>),
    EveryOffset(Option<SourceSpan>),
    ExceptOffset(Option<SourceSpan>),
    Bjork(Option<SourceSpan>),
    PBjork(Option<SourceSpan>),
    Quotation(Arc<[Op]>, Option<SourceSpan>),
    When,
    Unless,
    Adsr,
    Ad,
    Apply,
    Ramp,
    Triangle,
    Range,
    LinMap,
    ExpMap,
    Perlin,
    Loop,
    Degree(&'static [i64]),
    Oct,
    ClearCmd,
    SetSpeed,
    At,
    Arp,
    IntRange,
    StepRange,
    Generate,
    GeomRange,
    Euclid,
    EuclidRot,
    Times,
    Chord(&'static [i64]),
    Transpose,
    Invert,
    DownInvert,
    VoiceDrop2,
    VoiceDrop3,
    SetKey,
    DiatonicTriad(&'static [i64]),
    DiatonicSeventh(&'static [i64]),
    // Audio-rate modulation DSL
    ModLfo(u8),
    ModSlide(u8),
    ModRnd(u8),
    ModEnv,
    // Global params
    EmitAll,
    ClearGlobal,
    // MIDI
    MidiEmit,
    GetMidiCC,
    MidiClock,
    MidiStart,
    MidiStop,
    MidiContinue,
    // Recording
    Rec,
    Overdub,
    Orec,
    Odub,
    // Bracket syntax (mark/count for auto-counting)
    Mark,
    Count(Option<SourceSpan>),
    Index(Option<SourceSpan>),
}
