rbx-rsml 1.0.1

A lexer and parser for the RSML language.
Documentation
use std::sync::LazyLock;

use crate::lexer::{RsmlLexer, Token};
use crate::parser::{Construct, ParsedRsml, RsmlParser};
use crate::typechecker::{
    MacroDefinition, MacroKey, MacroRegistry, collect_macro_def_arg_names, macro_return_context,
};

const BUILTINS_SOURCE: &str = include_str!("../builtins.rsml");

pub struct BuiltinData {
    pub parsed: &'static ParsedRsml<'static>,
    pub registry: MacroRegistry<'static>,
}

pub static BUILTINS: LazyLock<BuiltinData> = LazyLock::new(|| {
    let parsed: &'static ParsedRsml<'static> =
        Box::leak(Box::new(RsmlParser::new(RsmlLexer::new(BUILTINS_SOURCE))));

    let mut registry = MacroRegistry::new();
    for construct in &parsed.ast {
        if let Construct::Macro {
            name: Some(name_node),
            args,
            body,
            return_type,
            ..
        } = construct
        {
            if let Token::Identifier(name_str) = name_node.token.value() {
                let arg_names = collect_macro_def_arg_names(args);

                registry.insert(
                    MacroKey {
                        name: *name_str,
                        arity: arg_names.len(),
                    },
                    MacroDefinition {
                        arg_names,
                        body: body.as_ref().map(|b| &b.content),
                        return_context: macro_return_context(return_type),
                    },
                );
            }
        }
    }
    BuiltinData { parsed, registry }
});