// phonemes.sy -- The 44 English phonemes as native Scyla.
//
// Every English word is a sequence of phonemes — the smallest units of sound
// that distinguish meaning. Phonograms (letters on a page) map to phonemes
// (sounds in the air) deterministically once you know the context. This
// module gives Scyla native addresses for every phoneme so the compiled_lang
// architecture can reason about pronunciation, fuzzy phonetic matching, and
// rhyme / sound-class distance at the same fidelity it reasons about letters.
//
// The 44-phoneme inventory:
//   24 consonants (stops, fricatives, affricates, nasals, approximants)
//   12 monophthong vowels
//    8 diphthongs
//
// Each phoneme carries its IPA symbol, place and manner of articulation,
// voicing, category, and an example word.
//
// Sources:
//   - International Phonetic Association (IPA) 2020 chart
//   - Ladefoged & Johnson, "A Course in Phonetics" (7th ed, 2014)
//   - Cambridge English Pronouncing Dictionary (18th ed)
//
// Marjorie McCubbins + Aether, April 2026
// Patent pending: 64/034,536 (continuation-in-part)

// ═══════════════════════════════════════════════════════
// STRUCT
// ═══════════════════════════════════════════════════════

struct Phoneme {
    address: Int,
    ipa: String,
    category: String,       // "consonant", "vowel", "diphthong"
    place: String,          // bilabial, alveolar, velar, etc. (or vowel height)
    manner: String,         // stop, fricative, nasal, etc. (or vowel frontness)
    voicing: String,        // "voiced", "voiceless", "n/a"
    example: String,        // example word
    example_highlight: String,   // letters in the example word that realize this phoneme
}

fn phoneme(a: Int, i: String, c: String, p: String, m: String, v: String, e: String, h: String) -> Phoneme {
    return Phoneme { address: a, ipa: i, category: c, place: p, manner: m, voicing: v, example: e, example_highlight: h }
}

fn unknown_phoneme() -> Phoneme {
    return phoneme(0, "?", "unknown", "", "", "", "", "")
}

// ═══════════════════════════════════════════════════════
// LOOKUP BY ADDRESS (1 - 44)
// ═══════════════════════════════════════════════════════

fn lookup_phoneme(addr: Int) -> Phoneme {
    // ─── Consonants (1-24) ───
    if addr == 1  { return phoneme(1,  "p",  "consonant", "bilabial",       "stop",        "voiceless", "pat",     "p") }
    if addr == 2  { return phoneme(2,  "b",  "consonant", "bilabial",       "stop",        "voiced",    "bat",     "b") }
    if addr == 3  { return phoneme(3,  "t",  "consonant", "alveolar",       "stop",        "voiceless", "top",     "t") }
    if addr == 4  { return phoneme(4,  "d",  "consonant", "alveolar",       "stop",        "voiced",    "dog",     "d") }
    if addr == 5  { return phoneme(5,  "k",  "consonant", "velar",          "stop",        "voiceless", "cat",     "c") }
    if addr == 6  { return phoneme(6,  "g",  "consonant", "velar",          "stop",        "voiced",    "go",      "g") }
    if addr == 7  { return phoneme(7,  "f",  "consonant", "labiodental",    "fricative",   "voiceless", "fan",     "f") }
    if addr == 8  { return phoneme(8,  "v",  "consonant", "labiodental",    "fricative",   "voiced",    "van",     "v") }
    if addr == 9  { return phoneme(9,  "θ",  "consonant", "dental",         "fricative",   "voiceless", "think",   "th") }
    if addr == 10 { return phoneme(10, "ð",  "consonant", "dental",         "fricative",   "voiced",    "this",    "th") }
    if addr == 11 { return phoneme(11, "s",  "consonant", "alveolar",       "fricative",   "voiceless", "sit",     "s") }
    if addr == 12 { return phoneme(12, "z",  "consonant", "alveolar",       "fricative",   "voiced",    "zoo",     "z") }
    if addr == 13 { return phoneme(13, "ʃ",  "consonant", "postalveolar",   "fricative",   "voiceless", "ship",    "sh") }
    if addr == 14 { return phoneme(14, "ʒ",  "consonant", "postalveolar",   "fricative",   "voiced",    "measure", "s") }
    if addr == 15 { return phoneme(15, "h",  "consonant", "glottal",        "fricative",   "voiceless", "hat",     "h") }
    if addr == 16 { return phoneme(16, "tʃ", "consonant", "postalveolar",   "affricate",   "voiceless", "chip",    "ch") }
    if addr == 17 { return phoneme(17, "dʒ", "consonant", "postalveolar",   "affricate",   "voiced",    "jam",     "j") }
    if addr == 18 { return phoneme(18, "m",  "consonant", "bilabial",       "nasal",       "voiced",    "mat",     "m") }
    if addr == 19 { return phoneme(19, "n",  "consonant", "alveolar",       "nasal",       "voiced",    "no",      "n") }
    if addr == 20 { return phoneme(20, "ŋ",  "consonant", "velar",          "nasal",       "voiced",    "sing",    "ng") }
    if addr == 21 { return phoneme(21, "l",  "consonant", "alveolar",       "lateral",     "voiced",    "let",     "l") }
    if addr == 22 { return phoneme(22, "r",  "consonant", "alveolar",       "approximant", "voiced",    "red",     "r") }
    if addr == 23 { return phoneme(23, "w",  "consonant", "labial-velar",   "approximant", "voiced",    "win",     "w") }
    if addr == 24 { return phoneme(24, "j",  "consonant", "palatal",        "approximant", "voiced",    "yes",     "y") }

    // ─── Monophthong Vowels (25-36) ───
    if addr == 25 { return phoneme(25, "i",  "vowel", "close",          "front",      "voiced", "see",     "ee") }
    if addr == 26 { return phoneme(26, "ɪ",  "vowel", "near-close",     "near-front", "voiced", "sit",     "i") }
    if addr == 27 { return phoneme(27, "ɛ",  "vowel", "open-mid",       "front",      "voiced", "bed",     "e") }
    if addr == 28 { return phoneme(28, "æ",  "vowel", "near-open",      "front",      "voiced", "cat",     "a") }
    if addr == 29 { return phoneme(29, "ə",  "vowel", "mid",            "central",    "voiced", "about",   "a") }
    if addr == 30 { return phoneme(30, "ʌ",  "vowel", "open-mid",       "back",       "voiced", "cup",     "u") }
    if addr == 31 { return phoneme(31, "ɑ",  "vowel", "open",           "back",       "voiced", "father",  "a") }
    if addr == 32 { return phoneme(32, "ɒ",  "vowel", "open",           "back",       "voiced", "hot",     "o") }
    if addr == 33 { return phoneme(33, "ɔ",  "vowel", "open-mid",       "back",       "voiced", "thought", "ough") }
    if addr == 34 { return phoneme(34, "ʊ",  "vowel", "near-close",     "near-back",  "voiced", "put",     "u") }
    if addr == 35 { return phoneme(35, "u",  "vowel", "close",          "back",       "voiced", "boot",    "oo") }
    if addr == 36 { return phoneme(36, "ɜ",  "vowel", "open-mid",       "central",    "voiced", "bird",    "ir") }

    // ─── Diphthongs (37-44) ───
    if addr == 37 { return phoneme(37, "eɪ", "diphthong", "mid-to-close", "front",  "voiced", "say",   "ay") }
    if addr == 38 { return phoneme(38, "aɪ", "diphthong", "open-to-close", "front", "voiced", "my",    "y") }
    if addr == 39 { return phoneme(39, "ɔɪ", "diphthong", "open-to-close", "front", "voiced", "boy",   "oy") }
    if addr == 40 { return phoneme(40, "oʊ", "diphthong", "mid-to-close",  "back",  "voiced", "go",    "o") }
    if addr == 41 { return phoneme(41, "aʊ", "diphthong", "open-to-close", "back",  "voiced", "cow",   "ow") }
    if addr == 42 { return phoneme(42, "ɪə", "diphthong", "close-to-mid",  "front", "voiced", "ear",   "ea") }
    if addr == 43 { return phoneme(43, "eə", "diphthong", "mid-to-mid",    "front", "voiced", "air",   "ai") }
    if addr == 44 { return phoneme(44, "ʊə", "diphthong", "close-to-mid",  "back",  "voiced", "poor",  "oo") }

    return unknown_phoneme()
}

// ═══════════════════════════════════════════════════════
// LOOKUP BY IPA SYMBOL
// ═══════════════════════════════════════════════════════

fn phoneme_by_ipa(ipa: String) -> Phoneme {
    if ipa == "p"  { return lookup_phoneme(1) }
    if ipa == "b"  { return lookup_phoneme(2) }
    if ipa == "t"  { return lookup_phoneme(3) }
    if ipa == "d"  { return lookup_phoneme(4) }
    if ipa == "k"  { return lookup_phoneme(5) }
    if ipa == "g"  { return lookup_phoneme(6) }
    if ipa == "f"  { return lookup_phoneme(7) }
    if ipa == "v"  { return lookup_phoneme(8) }
    if ipa == "θ"  { return lookup_phoneme(9) }
    if ipa == "ð"  { return lookup_phoneme(10) }
    if ipa == "s"  { return lookup_phoneme(11) }
    if ipa == "z"  { return lookup_phoneme(12) }
    if ipa == "ʃ"  { return lookup_phoneme(13) }
    if ipa == "ʒ"  { return lookup_phoneme(14) }
    if ipa == "h"  { return lookup_phoneme(15) }
    if ipa == "tʃ" { return lookup_phoneme(16) }
    if ipa == "dʒ" { return lookup_phoneme(17) }
    if ipa == "m"  { return lookup_phoneme(18) }
    if ipa == "n"  { return lookup_phoneme(19) }
    if ipa == "ŋ"  { return lookup_phoneme(20) }
    if ipa == "l"  { return lookup_phoneme(21) }
    if ipa == "r"  { return lookup_phoneme(22) }
    if ipa == "w"  { return lookup_phoneme(23) }
    if ipa == "j"  { return lookup_phoneme(24) }
    if ipa == "i"  { return lookup_phoneme(25) }
    if ipa == "ɪ"  { return lookup_phoneme(26) }
    if ipa == "ɛ"  { return lookup_phoneme(27) }
    if ipa == "æ"  { return lookup_phoneme(28) }
    if ipa == "ə"  { return lookup_phoneme(29) }
    if ipa == "ʌ"  { return lookup_phoneme(30) }
    if ipa == "ɑ"  { return lookup_phoneme(31) }
    if ipa == "ɒ"  { return lookup_phoneme(32) }
    if ipa == "ɔ"  { return lookup_phoneme(33) }
    if ipa == "ʊ"  { return lookup_phoneme(34) }
    if ipa == "u"  { return lookup_phoneme(35) }
    if ipa == "ɜ"  { return lookup_phoneme(36) }
    if ipa == "eɪ" { return lookup_phoneme(37) }
    if ipa == "aɪ" { return lookup_phoneme(38) }
    if ipa == "ɔɪ" { return lookup_phoneme(39) }
    if ipa == "oʊ" { return lookup_phoneme(40) }
    if ipa == "aʊ" { return lookup_phoneme(41) }
    if ipa == "ɪə" { return lookup_phoneme(42) }
    if ipa == "eə" { return lookup_phoneme(43) }
    if ipa == "ʊə" { return lookup_phoneme(44) }
    return unknown_phoneme()
}

// ═══════════════════════════════════════════════════════
// QUICK-ACCESS HELPERS
// ═══════════════════════════════════════════════════════

fn phoneme_count() -> Int {
    return 44
}

fn consonant_count() -> Int {
    return 24
}

fn vowel_count() -> Int {
    return 12
}

fn diphthong_count() -> Int {
    return 8
}

fn is_valid_phoneme_address(addr: Int) -> Bool {
    return addr >= 1 and addr <= 44
}
