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});