pub struct KeywordInfo {
pub text: &'static str,
pub category: &'static str,
pub spec_ref: Option<&'static str>,
}
pub struct OperatorInfo {
pub symbol: &'static str,
pub precedence: Option<u8>,
pub associativity: &'static str,
pub kind: &'static str,
pub spec_ref: Option<&'static str>,
}
#[must_use]
pub fn keywords() -> Vec<KeywordInfo> {
vec![
KeywordInfo { text: "fn", category: "declaration", spec_ref: Some("§1.4") },
KeywordInfo { text: "let", category: "declaration", spec_ref: Some("§1.4") },
KeywordInfo { text: "mut", category: "modifier", spec_ref: Some("§3") },
KeywordInfo { text: "const", category: "declaration", spec_ref: Some("§1.4") },
KeywordInfo { text: "if", category: "control-flow", spec_ref: Some("§5") },
KeywordInfo { text: "else", category: "control-flow", spec_ref: Some("§5") },
KeywordInfo { text: "match", category: "control-flow", spec_ref: Some("§7") },
KeywordInfo { text: "for", category: "control-flow", spec_ref: Some("§6") },
KeywordInfo { text: "in", category: "control-flow", spec_ref: Some("§6") },
KeywordInfo { text: "while", category: "control-flow", spec_ref: Some("§6") },
KeywordInfo { text: "loop", category: "control-flow", spec_ref: Some("§6") },
KeywordInfo { text: "break", category: "control-flow", spec_ref: Some("§6") },
KeywordInfo { text: "continue", category: "control-flow", spec_ref: Some("§6") },
KeywordInfo { text: "return", category: "control-flow", spec_ref: Some("§6") },
KeywordInfo { text: "guard", category: "control-flow", spec_ref: Some("§6") },
KeywordInfo { text: "with", category: "effects", spec_ref: Some("§8") },
KeywordInfo { text: "handling", category: "effects", spec_ref: Some("§8") },
KeywordInfo { text: "handle", category: "effects", spec_ref: Some("§8") },
KeywordInfo { text: "record", category: "declaration", spec_ref: Some("§4") },
KeywordInfo { text: "enum", category: "declaration", spec_ref: Some("§4") },
KeywordInfo { text: "class", category: "declaration", spec_ref: Some("§4") },
KeywordInfo { text: "trait", category: "declaration", spec_ref: Some("§4") },
KeywordInfo { text: "impl", category: "declaration", spec_ref: Some("§4") },
KeywordInfo { text: "self", category: "keyword", spec_ref: Some("§4") },
KeywordInfo { text: "Self", category: "type", spec_ref: Some("§4") },
KeywordInfo { text: "module", category: "declaration", spec_ref: Some("§10") },
KeywordInfo { text: "use", category: "declaration", spec_ref: Some("§10") },
KeywordInfo { text: "public", category: "visibility", spec_ref: Some("§10") },
KeywordInfo { text: "internal", category: "visibility", spec_ref: Some("§10") },
KeywordInfo { text: "native", category: "modifier", spec_ref: Some("§13") },
KeywordInfo { text: "async", category: "effects", spec_ref: Some("§8") },
KeywordInfo { text: "await", category: "effects", spec_ref: Some("§8") },
KeywordInfo { text: "effect", category: "effects", spec_ref: Some("§8") },
KeywordInfo { text: "platform", category: "declaration", spec_ref: Some("§13") },
KeywordInfo { text: "where", category: "declaration", spec_ref: Some("§4") },
KeywordInfo { text: "type", category: "declaration", spec_ref: Some("§4") },
KeywordInfo { text: "true", category: "literal", spec_ref: Some("§1.3") },
KeywordInfo { text: "false", category: "literal", spec_ref: Some("§1.3") },
KeywordInfo { text: "Ok", category: "constructor", spec_ref: Some("§6.3") },
KeywordInfo { text: "Err", category: "constructor", spec_ref: Some("§6.3") },
KeywordInfo { text: "Some", category: "constructor", spec_ref: Some("§6.3") },
KeywordInfo { text: "None", category: "constructor", spec_ref: Some("§6.3") },
KeywordInfo { text: "property", category: "declaration", spec_ref: Some("§4") },
KeywordInfo { text: "forall", category: "type", spec_ref: Some("§4") },
KeywordInfo { text: "unreachable", category: "keyword", spec_ref: Some("§6") },
KeywordInfo { text: "is", category: "operator", spec_ref: Some("§7") },
]
}
#[must_use]
pub fn operators() -> Vec<OperatorInfo> {
vec![
OperatorInfo { symbol: "=", precedence: Some(1), associativity: "right", kind: "assignment", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "+=", precedence: Some(1), associativity: "right", kind: "assignment", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "-=", precedence: Some(1), associativity: "right", kind: "assignment", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "*=", precedence: Some(1), associativity: "right", kind: "assignment", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "/=", precedence: Some(1), associativity: "right", kind: "assignment", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "%=", precedence: Some(1), associativity: "right", kind: "assignment", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "|>", precedence: Some(2), associativity: "left", kind: "pipe", spec_ref: Some("§5.1") },
OperatorInfo { symbol: ">>", precedence: Some(3), associativity: "left", kind: "compose", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "..", precedence: Some(4), associativity: "none", kind: "range", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "..=",precedence: Some(4), associativity: "none", kind: "range", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "||", precedence: Some(5), associativity: "left", kind: "logical", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "&&", precedence: Some(6), associativity: "left", kind: "logical", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "==", precedence: Some(7), associativity: "none", kind: "comparison", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "!=", precedence: Some(7), associativity: "none", kind: "comparison", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "<", precedence: Some(7), associativity: "none", kind: "comparison", spec_ref: Some("§5.1") },
OperatorInfo { symbol: ">", precedence: Some(7), associativity: "none", kind: "comparison", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "<=", precedence: Some(7), associativity: "none", kind: "comparison", spec_ref: Some("§5.1") },
OperatorInfo { symbol: ">=", precedence: Some(7), associativity: "none", kind: "comparison", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "|", precedence: Some(8), associativity: "left", kind: "bitwise", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "^", precedence: Some(9), associativity: "left", kind: "bitwise", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "&", precedence: Some(10), associativity: "left", kind: "bitwise", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "+", precedence: Some(11), associativity: "left", kind: "arithmetic", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "-", precedence: Some(11), associativity: "left", kind: "arithmetic", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "*", precedence: Some(12), associativity: "left", kind: "arithmetic", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "/", precedence: Some(12), associativity: "left", kind: "arithmetic", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "%", precedence: Some(12), associativity: "left", kind: "arithmetic", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "**", precedence: Some(13), associativity: "right", kind: "arithmetic", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "!", precedence: Some(14), associativity: "right", kind: "unary", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "~", precedence: Some(14), associativity: "right", kind: "unary", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "?", precedence: Some(15), associativity: "left", kind: "postfix", spec_ref: Some("§5.1") },
OperatorInfo { symbol: ".", precedence: Some(15), associativity: "left", kind: "access", spec_ref: Some("§5.1") },
OperatorInfo { symbol: "=>", precedence: None, associativity: "none", kind: "punctuation", spec_ref: None },
OperatorInfo { symbol: "->", precedence: None, associativity: "none", kind: "punctuation", spec_ref: None },
OperatorInfo { symbol: "<<", precedence: Some(10), associativity: "left", kind: "bitwise", spec_ref: Some("§5.1") },
OperatorInfo { symbol: ":", precedence: None, associativity: "none", kind: "punctuation", spec_ref: None },
OperatorInfo { symbol: ";", precedence: None, associativity: "none", kind: "punctuation", spec_ref: None },
OperatorInfo { symbol: ",", precedence: None, associativity: "none", kind: "punctuation", spec_ref: None },
OperatorInfo { symbol: "@", precedence: None, associativity: "none", kind: "annotation", spec_ref: None },
OperatorInfo { symbol: "#", precedence: None, associativity: "none", kind: "attribute", spec_ref: None },
OperatorInfo { symbol: "_", precedence: None, associativity: "none", kind: "wildcard", spec_ref: None },
]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_keyword_round_trips_through_lookup() {
for kw in keywords() {
assert!(
crate::keyword_lookup(kw.text).is_some(),
"keyword {:?} not in keyword_lookup",
kw.text
);
}
}
#[test]
fn keywords_are_non_empty() {
assert!(!keywords().is_empty());
}
#[test]
fn operators_are_non_empty() {
assert!(!operators().is_empty());
}
#[test]
fn operator_precedence_in_range() {
for op in operators() {
if let Some(p) = op.precedence {
assert!((1..=15).contains(&p), "op {:?} precedence {}", op.symbol, p);
}
}
}
}