1use std::{
4 collections::{HashMap, VecDeque},
5 sync::Arc,
6};
7
8use brush_parser::ast;
9
10#[derive(Clone, Default)]
12pub struct FunctionEnv {
13 functions: HashMap<String, Registration>,
14}
15
16impl FunctionEnv {
17 pub fn get(&self, name: &str) -> Option<&Registration> {
23 self.functions.get(name)
24 }
25
26 pub fn get_mut(&mut self, name: &str) -> Option<&mut Registration> {
33 self.functions.get_mut(name)
34 }
35
36 pub fn remove(&mut self, name: &str) -> Option<Registration> {
42 self.functions.remove(name)
43 }
44
45 pub fn update(&mut self, name: String, registration: Registration) {
52 self.functions.insert(name, registration);
53 }
54
55 pub fn clear(&mut self) {
57 self.functions.clear();
58 }
59
60 pub fn iter(&self) -> impl Iterator<Item = (&String, &Registration)> {
62 self.functions.iter()
63 }
64}
65
66#[derive(Clone)]
68pub struct Registration {
69 pub(crate) definition: Arc<brush_parser::ast::FunctionDefinition>,
71 exported: bool,
73}
74
75impl From<brush_parser::ast::FunctionDefinition> for Registration {
76 fn from(definition: brush_parser::ast::FunctionDefinition) -> Self {
77 Self {
78 definition: Arc::new(definition),
79 exported: false,
80 }
81 }
82}
83
84impl Registration {
85 pub fn definition(&self) -> &brush_parser::ast::FunctionDefinition {
87 &self.definition
88 }
89
90 pub const fn export(&mut self) {
92 self.exported = true;
93 }
94
95 pub const fn unexport(&mut self) {
97 self.exported = false;
98 }
99
100 pub const fn is_exported(&self) -> bool {
102 self.exported
103 }
104}
105
106#[derive(Clone, Debug)]
108pub struct FunctionCall {
109 pub function_name: String,
111 pub function_definition: Arc<brush_parser::ast::FunctionDefinition>,
113}
114
115#[derive(Clone, Debug, Default)]
117pub struct CallStack {
118 frames: VecDeque<FunctionCall>,
119}
120
121impl std::fmt::Display for CallStack {
122 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123 if self.is_empty() {
124 return Ok(());
125 }
126
127 writeln!(f, "Function call stack (most recent first):")?;
128
129 for (index, frame) in self.iter().enumerate() {
130 writeln!(f, " #{}| {}", index, frame.function_name)?;
131 }
132
133 Ok(())
134 }
135}
136
137impl CallStack {
138 pub fn new() -> Self {
140 Self::default()
141 }
142
143 pub fn pop(&mut self) -> Option<FunctionCall> {
146 self.frames.pop_front()
147 }
148
149 pub fn push(&mut self, name: impl Into<String>, function_def: &Arc<ast::FunctionDefinition>) {
156 self.frames.push_front(FunctionCall {
157 function_name: name.into(),
158 function_definition: function_def.clone(),
159 });
160 }
161
162 pub fn depth(&self) -> usize {
164 self.frames.len()
165 }
166
167 pub fn is_empty(&self) -> bool {
169 self.frames.is_empty()
170 }
171
172 pub fn iter(&self) -> impl Iterator<Item = &FunctionCall> {
175 self.frames.iter()
176 }
177}