1use std::collections::HashMap;
2
3pub struct StdLib {
6 event_handlers: HashMap<EventType, Vec<String>>,
7}
8
9#[derive(Debug, Clone, Hash, PartialEq, Eq)]
10pub enum EventType {
11 Load, Tick, Custom(String),
14}
15
16impl Default for StdLib {
17 fn default() -> Self {
18 Self::new()
19 }
20}
21
22impl StdLib {
23 pub fn new() -> Self {
24 Self {
25 event_handlers: HashMap::new(),
26 }
27 }
28
29 pub fn add_event_listener(&mut self, event_type: EventType, function_name: String) {
31 self.event_handlers
32 .entry(event_type)
33 .or_default()
34 .push(function_name);
35 }
36
37 pub fn get_event_handlers(&self, event_type: &EventType) -> Vec<String> {
39 self.event_handlers
40 .get(event_type)
41 .cloned()
42 .unwrap_or_default()
43 }
44
45 pub fn generate_tags(&self, namespace: &str) -> HashMap<String, Vec<String>> {
47 let mut tags = HashMap::new();
48
49 if let Some(handlers) = self.event_handlers.get(&EventType::Load) {
51 let load_functions: Vec<String> = handlers
52 .iter()
53 .map(|f| format!("{}:{}", namespace, f))
54 .collect();
55 tags.insert("minecraft:load".to_string(), load_functions);
56 }
57
58 if let Some(handlers) = self.event_handlers.get(&EventType::Tick) {
60 let tick_functions: Vec<String> = handlers
61 .iter()
62 .map(|f| format!("{}:{}", namespace, f))
63 .collect();
64 tags.insert("minecraft:tick".to_string(), tick_functions);
65 }
66
67 tags
68 }
69}
70
71pub mod builtins {
73 use crate::ast::Expression;
74
75 pub fn range(n: i32) -> Vec<Expression> {
77 (0..n).map(|i| Expression::Number(i as f64)).collect()
78 }
79
80 pub fn len(list: &[Expression]) -> Expression {
82 Expression::Number(list.len() as f64)
83 }
84
85 pub fn to_str(value: &Expression) -> Expression {
87 match value {
88 Expression::Number(n) => Expression::String(n.to_string()),
89 Expression::Boolean(b) => Expression::String(b.to_string()),
90 Expression::String(s) => Expression::String(s.clone()),
91 _ => Expression::String("None".to_string()),
92 }
93 }
94
95 pub fn to_int(value: &Expression) -> Expression {
97 match value {
98 Expression::Number(n) => Expression::Number(n.floor()),
99 Expression::String(s) => {
100 if let Ok(n) = s.parse::<f64>() {
101 Expression::Number(n.floor())
102 } else {
103 Expression::Number(0.0)
104 }
105 }
106 Expression::Boolean(b) => Expression::Number(if *b { 1.0 } else { 0.0 }),
107 _ => Expression::Number(0.0),
108 }
109 }
110}