Skip to main content

rbx_rsml/
builtins.rs

1use std::sync::LazyLock;
2
3use crate::lexer::{RsmlLexer, Token};
4use crate::parser::{Construct, ParsedRsml, RsmlParser};
5use crate::typechecker::{
6    MacroDefinition, MacroKey, MacroRegistry, collect_macro_def_arg_names, macro_return_context,
7};
8
9const BUILTINS_SOURCE: &str = include_str!("../builtins.rsml");
10
11pub struct BuiltinData {
12    pub parsed: &'static ParsedRsml<'static>,
13    pub registry: MacroRegistry<'static>,
14}
15
16pub static BUILTINS: LazyLock<BuiltinData> = LazyLock::new(|| {
17    let parsed: &'static ParsedRsml<'static> =
18        Box::leak(Box::new(RsmlParser::new(RsmlLexer::new(BUILTINS_SOURCE))));
19
20    let mut registry = MacroRegistry::new();
21    for construct in &parsed.ast {
22        if let Construct::Macro {
23            name: Some(name_node),
24            args,
25            body,
26            return_type,
27            ..
28        } = construct
29        {
30            if let Token::Identifier(name_str) = name_node.token.value() {
31                let arg_names = collect_macro_def_arg_names(args);
32
33                registry.insert(
34                    MacroKey {
35                        name: *name_str,
36                        arity: arg_names.len(),
37                    },
38                    MacroDefinition {
39                        arg_names,
40                        body: body.as_ref().map(|b| &b.content),
41                        return_context: macro_return_context(return_type),
42                    },
43                );
44            }
45        }
46    }
47    BuiltinData { parsed, registry }
48});