66 lines
1.6 KiB
Rust
66 lines
1.6 KiB
Rust
//! Built-in word definitions and lookup for the Forth VM.
|
|
|
|
mod compile;
|
|
mod core;
|
|
mod effects;
|
|
mod midi;
|
|
mod music;
|
|
mod sequencing;
|
|
mod sound;
|
|
|
|
use std::collections::HashMap;
|
|
use std::sync::LazyLock;
|
|
|
|
pub(crate) use compile::compile_word;
|
|
|
|
/// How a word is compiled into ops.
|
|
#[derive(Clone, Copy)]
|
|
pub enum WordCompile {
|
|
Simple,
|
|
Context(&'static str),
|
|
Param,
|
|
Probability(f64),
|
|
}
|
|
|
|
/// Metadata for a built-in Forth word.
|
|
#[derive(Clone, Copy)]
|
|
pub struct Word {
|
|
pub name: &'static str,
|
|
pub aliases: &'static [&'static str],
|
|
pub category: &'static str,
|
|
pub stack: &'static str,
|
|
pub desc: &'static str,
|
|
pub example: &'static str,
|
|
pub compile: WordCompile,
|
|
pub varargs: bool,
|
|
}
|
|
|
|
/// All built-in words, aggregated from every category module.
|
|
pub static WORDS: LazyLock<Vec<Word>> = LazyLock::new(|| {
|
|
let mut words = Vec::new();
|
|
words.extend_from_slice(self::core::WORDS);
|
|
words.extend_from_slice(sound::WORDS);
|
|
words.extend_from_slice(effects::WORDS);
|
|
words.extend_from_slice(sequencing::WORDS);
|
|
words.extend_from_slice(music::WORDS);
|
|
words.extend_from_slice(midi::WORDS);
|
|
words
|
|
});
|
|
|
|
/// Index mapping word names and aliases to their definitions.
|
|
static WORD_MAP: LazyLock<HashMap<&'static str, &'static Word>> = LazyLock::new(|| {
|
|
let mut map = HashMap::with_capacity(WORDS.len() * 2);
|
|
for word in WORDS.iter() {
|
|
map.insert(word.name, word);
|
|
for alias in word.aliases {
|
|
map.insert(alias, word);
|
|
}
|
|
}
|
|
map
|
|
});
|
|
|
|
/// Find a word by name or alias.
|
|
pub fn lookup_word(name: &str) -> Option<&'static Word> {
|
|
WORD_MAP.get(name).copied()
|
|
}
|