//! Word metadata for core language primitives (stack, arithmetic, logic, variables, definitions).

use super::{Word, WordCompile::*};
pub(super) const WORDS: &[Word] = &[
    // Stack manipulation
    Word {
        name: "dup",
        aliases: &[],
        category: "Stack",
        stack: "(a -- a a)",
        desc: "Duplicate top of stack",
        example: "3 dup => 3 3",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "dupn",
        aliases: &["!"],
        category: "Stack",
        stack: "(a n -- a a ... a)",
        desc: "Duplicate a onto stack n times",
        example: "2 4 dupn => 2 2 2 2",
        compile: Simple,
        varargs: true,
    },
    Word {
        name: "drop",
        aliases: &[],
        category: "Stack",
        stack: "(a --)",
        desc: "Remove top of stack",
        example: "1 2 drop => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "swap",
        aliases: &[],
        category: "Stack",
        stack: "(a b -- b a)",
        desc: "Exchange top two items",
        example: "1 2 swap => 2 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "over",
        aliases: &[],
        category: "Stack",
        stack: "(a b -- a b a)",
        desc: "Copy second to top",
        example: "1 2 over => 1 2 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "rot",
        aliases: &[],
        category: "Stack",
        stack: "(a b c -- b c a)",
        desc: "Rotate top three",
        example: "1 2 3 rot => 2 3 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "nip",
        aliases: &[],
        category: "Stack",
        stack: "(a b -- b)",
        desc: "Remove second item",
        example: "1 2 nip => 2",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "tuck",
        aliases: &[],
        category: "Stack",
        stack: "(a b -- b a b)",
        desc: "Copy top under second",
        example: "1 2 tuck => 2 1 2",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "2dup",
        aliases: &[],
        category: "Stack",
        stack: "(a b -- a b a b)",
        desc: "Duplicate top two values",
        example: "1 2 2dup => 1 2 1 2",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "2drop",
        aliases: &[],
        category: "Stack",
        stack: "(a b --)",
        desc: "Drop top two values",
        example: "1 2 3 2drop => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "2swap",
        aliases: &[],
        category: "Stack",
        stack: "(a b c d -- c d a b)",
        desc: "Swap top two pairs",
        example: "1 2 3 4 2swap => 3 4 1 2",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "2over",
        aliases: &[],
        category: "Stack",
        stack: "(a b c d -- a b c d a b)",
        desc: "Copy second pair to top",
        example: "1 2 3 4 2over => 1 2 3 4 1 2",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "rev",
        aliases: &[],
        category: "Stack",
        stack: "(..n n -- ..n)",
        desc: "Reverse top n items",
        example: "1 2 3 3 rev => 3 2 1",
        compile: Simple,
        varargs: true,
    },
    Word {
        name: "shuffle",
        aliases: &[],
        category: "Stack",
        stack: "(..n n -- ..n)",
        desc: "Randomly shuffle top n items",
        example: "1 2 3 3 shuffle",
        compile: Simple,
        varargs: true,
    },
    Word {
        name: "sort",
        aliases: &[],
        category: "Stack",
        stack: "(..n n -- ..n)",
        desc: "Sort top n items ascending",
        example: "3 1 2 3 sort => 1 2 3",
        compile: Simple,
        varargs: true,
    },
    Word {
        name: "rsort",
        aliases: &[],
        category: "Stack",
        stack: "(..n n -- ..n)",
        desc: "Sort top n items descending",
        example: "1 2 3 3 rsort => 3 2 1",
        compile: Simple,
        varargs: true,
    },
    Word {
        name: "sum",
        aliases: &[],
        category: "Stack",
        stack: "(..n n -- total)",
        desc: "Sum top n items",
        example: "1 2 3 3 sum => 6",
        compile: Simple,
        varargs: true,
    },
    Word {
        name: "prod",
        aliases: &[],
        category: "Stack",
        stack: "(..n n -- product)",
        desc: "Multiply top n items",
        example: "2 3 4 3 prod => 24",
        compile: Simple,
        varargs: true,
    },
    // Arithmetic
    Word {
        name: "+",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a b -- a+b)",
        desc: "Add",
        example: "2 3 + => 5",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "-",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a b -- a-b)",
        desc: "Subtract",
        example: "5 3 - => 2",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "*",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a b -- a*b)",
        desc: "Multiply",
        example: "3 4 * => 12",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "/",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a b -- a/b)",
        desc: "Divide",
        example: "10 2 / => 5",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "mod",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a b -- a%b)",
        desc: "Modulo",
        example: "7 3 mod => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "neg",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a -- -a)",
        desc: "Negate",
        example: "5 neg => -5",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "abs",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a -- |a|)",
        desc: "Absolute value",
        example: "-5 abs => 5",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "floor",
        aliases: &[],
        category: "Arithmetic",
        stack: "(f -- n)",
        desc: "Round down to integer",
        example: "3.7 floor => 3",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "ceil",
        aliases: &[],
        category: "Arithmetic",
        stack: "(f -- n)",
        desc: "Round up to integer",
        example: "3.2 ceil => 4",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "round",
        aliases: &[],
        category: "Arithmetic",
        stack: "(f -- n)",
        desc: "Round to nearest integer",
        example: "3.5 round => 4",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "min",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a b -- min)",
        desc: "Minimum of two values",
        example: "3 5 min => 3",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "max",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a b -- max)",
        desc: "Maximum of two values",
        example: "3 5 max => 5",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "pow",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a b -- a^b)",
        desc: "Exponentiation",
        example: "2 3 pow => 8",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "sqrt",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a -- √a)",
        desc: "Square root",
        example: "16 sqrt => 4",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "sin",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a -- sin(a))",
        desc: "Sine (radians)",
        example: "3.14159 2 / sin => 1.0",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "cos",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a -- cos(a))",
        desc: "Cosine (radians)",
        example: "0 cos => 1.0",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "log",
        aliases: &[],
        category: "Arithmetic",
        stack: "(a -- ln(a))",
        desc: "Natural logarithm",
        example: "2.718 log => 1.0",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "linmap",
        aliases: &[],
        category: "Arithmetic",
        stack: "(val inlo inhi outlo outhi -- mapped)",
        desc: "Linear map from [inlo,inhi] to [outlo,outhi]",
        example: "64 0 127 200 2000 linmap => 1007.87",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "expmap",
        aliases: &[],
        category: "Arithmetic",
        stack: "(val lo hi -- mapped)",
        desc: "Exponential map from [0,1] to [lo,hi]",
        example: "0.5 200 8000 expmap => 1264.91",
        compile: Simple,
        varargs: false,
    },
    // Comparison
    Word {
        name: "=",
        aliases: &[],
        category: "Comparison",
        stack: "(a b -- bool)",
        desc: "Equal",
        example: "3 3 = => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "!=",
        aliases: &["<>"],
        category: "Comparison",
        stack: "(a b -- bool)",
        desc: "Not equal",
        example: "3 4 != => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "lt",
        aliases: &[],
        category: "Comparison",
        stack: "(a b -- bool)",
        desc: "Less than",
        example: "2 3 lt => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "gt",
        aliases: &[],
        category: "Comparison",
        stack: "(a b -- bool)",
        desc: "Greater than",
        example: "3 2 gt => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "<=",
        aliases: &[],
        category: "Comparison",
        stack: "(a b -- bool)",
        desc: "Less or equal",
        example: "3 3 <= => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: ">=",
        aliases: &[],
        category: "Comparison",
        stack: "(a b -- bool)",
        desc: "Greater or equal",
        example: "3 3 >= => 1",
        compile: Simple,
        varargs: false,
    },
    // Logic
    Word {
        name: "and",
        aliases: &[],
        category: "Logic",
        stack: "(a b -- bool)",
        desc: "Logical and",
        example: "1 1 and => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "or",
        aliases: &[],
        category: "Logic",
        stack: "(a b -- bool)",
        desc: "Logical or",
        example: "0 1 or => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "not",
        aliases: &[],
        category: "Logic",
        stack: "(a -- bool)",
        desc: "Logical not",
        example: "0 not => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "xor",
        aliases: &[],
        category: "Logic",
        stack: "(a b -- bool)",
        desc: "Exclusive or",
        example: "1 0 xor => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "nand",
        aliases: &[],
        category: "Logic",
        stack: "(a b -- bool)",
        desc: "Not and",
        example: "1 1 nand => 0",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "nor",
        aliases: &[],
        category: "Logic",
        stack: "(a b -- bool)",
        desc: "Not or",
        example: "0 0 nor => 1",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "ifelse",
        aliases: &[],
        category: "Logic",
        stack: "(true-quot false-quot bool --)",
        desc: "Execute true-quot if true, else false-quot",
        example: "( 1 ) ( 2 ) coin ifelse",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "select",
        aliases: &[],
        category: "Logic",
        stack: "(..quots n --)",
        desc: "Execute nth quotation (0-indexed)",
        example: "( 1 ) ( 2 ) ( 3 ) 2 select => 3",
        compile: Simple,
        varargs: true,
    },
    Word {
        name: "?",
        aliases: &[],
        category: "Logic",
        stack: "(quot bool --)",
        desc: "Execute quotation if true",
        example: "( 2 distort ) 0.5 chance ?",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "!?",
        aliases: &[],
        category: "Logic",
        stack: "(quot bool --)",
        desc: "Execute quotation if false",
        example: "( 1 distort ) 0.5 chance !?",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "apply",
        aliases: &[],
        category: "Logic",
        stack: "(quot --)",
        desc: "Execute quotation unconditionally",
        example: "( 2 * ) apply",
        compile: Simple,
        varargs: false,
    },
    // Control
    Word {
        name: "times",
        aliases: &[],
        category: "Control",
        stack: "(n quot --)",
        desc: "Execute quotation n times, @i holds current index",
        example: "4 ( @i . ) times => 0 1 2 3",
        compile: Simple,
        varargs: false,
    },
    // Variables
    Word {
        name: "@<var>",
        aliases: &[],
        category: "Variables",
        stack: "( -- val)",
        desc: "Fetch variable value",
        example: "@freq => 440",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "!<var>",
        aliases: &[],
        category: "Variables",
        stack: "(val --)",
        desc: "Store value in variable",
        example: "440 !freq",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: ",<var>",
        aliases: &[],
        category: "Variables",
        stack: "(val -- val)",
        desc: "Store value in variable, keep on stack",
        example: "440 ,freq => 440",
        compile: Simple,
        varargs: false,
    },
    // Definitions
    Word {
        name: ":",
        aliases: &[],
        category: "Definitions",
        stack: "( -- )",
        desc: "Begin word definition",
        example: ": kick \"kick\" s emit ;",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: ";",
        aliases: &[],
        category: "Definitions",
        stack: "( -- )",
        desc: "End word definition",
        example: ": kick \"kick\" s emit ;",
        compile: Simple,
        varargs: false,
    },
    Word {
        name: "forget",
        aliases: &[],
        category: "Definitions",
        stack: "(name --)",
        desc: "Remove user-defined word from dictionary",
        example: "\"double\" forget",
        compile: Simple,
        varargs: false,
    },
];
