1use crate::{
19 ast::{
20 Ast,
21 nodes::ExpressionKind,
22 statements::{Statement, StatementKind},
23 },
24 lexer::tokenizer::Tokenizer,
25 parser::parser_logic::Parser,
26 resolver::Resolver,
27 utils::source::SourceFile,
28};
29
30impl Resolver {
31 pub fn resolve_program(&mut self, ast: Ast, statements: Vec<Statement>) -> Vec<Statement> {
32 let statements = self.ast_arena.merge_statements(ast, statements);
33 self.resolve_statements(statements)
34 }
35
36 pub fn resolve_statements(&mut self, statements: Vec<Statement>) -> Vec<Statement> {
37 statements
38 .into_iter()
39 .map(|statement| self.resolve_statement(statement))
40 .collect()
41 }
42
43 fn resolve_statement(&mut self, stmt: Statement) -> Statement {
44 let span = stmt.span;
45 let kind = match stmt.kind {
46 StatementKind::VariableDeclaration {
47 name,
48 type_annotation,
49 value,
50 } => {
51 let value = self.resolve_expression(value);
52 let slot = self.declare(name.clone());
53 StatementKind::ResolvedVariableDeclaration {
54 name,
55 slot,
56 type_annotation,
57 value,
58 }
59 }
60 StatementKind::ConstantDeclaration {
61 name,
62 type_annotation,
63 value,
64 } => {
65 let value = self.resolve_expression(value);
66 let slot = self.declare(name.clone());
67 StatementKind::ResolvedConstantDeclaration {
68 name,
69 slot,
70 type_annotation,
71 value,
72 }
73 }
74 StatementKind::Array {
76 name,
77 type_annotation,
78 value,
79 } => {
80 let value = value
81 .into_iter()
82 .map(|e| self.resolve_expression(e))
83 .collect();
84 let slot = self.declare(name.clone());
85 let value = self
86 .ast_arena
87 .alloc_expr(ExpressionKind::ArrayLiteral(value), span);
88
89 StatementKind::ResolvedArray {
90 name,
91 slot,
92 type_annotation,
93 value,
94 }
95 }
96 StatementKind::ConstantArray {
97 name,
98 type_annotation,
99 value,
100 } => {
101 let value = value
102 .into_iter()
103 .map(|e| self.resolve_expression(e))
104 .collect();
105 let slot = self.declare(name.clone());
106 let value = self
107 .ast_arena
108 .alloc_expr(ExpressionKind::ArrayLiteral(value), span);
109
110 StatementKind::ResolvedConstantArray {
111 name,
112 slot,
113 type_annotation,
114 value,
115 }
116 }
117
118 StatementKind::Set {
119 name,
120 type_annotation,
121 items,
122 } => {
123 let value = items
124 .into_iter()
125 .map(|e| self.resolve_expression(e))
126 .collect();
127 let slot = self.declare(name.clone());
128 let value = self
129 .ast_arena
130 .alloc_expr(ExpressionKind::SetLiteral(value), span);
131
132 StatementKind::ResolvedSet {
133 name,
134 slot,
135 type_annotation,
136 value,
137 }
138 }
139 StatementKind::ConstantSet {
140 name,
141 type_annotation,
142 items,
143 } => {
144 let value = items
145 .into_iter()
146 .map(|e| self.resolve_expression(e))
147 .collect();
148 let slot = self.declare(name.clone());
149 let value = self
150 .ast_arena
151 .alloc_expr(ExpressionKind::SetLiteral(value), span);
152
153 StatementKind::ResolvedConstantSet {
154 name,
155 slot,
156 type_annotation,
157 value,
158 }
159 }
160
161 StatementKind::Map {
162 name,
163 type_annotation,
164 entries,
165 } => {
166 let entries = entries
167 .into_iter()
168 .map(|(k, v)| (self.resolve_expression(k), self.resolve_expression(v)))
169 .collect();
170 let slot = self.declare(name.clone());
171 let value = self
172 .ast_arena
173 .alloc_expr(ExpressionKind::MapLiteral(entries), span);
174
175 StatementKind::ResolvedMap {
176 name,
177 slot,
178 type_annotation,
179 value,
180 }
181 }
182 StatementKind::ConstantMap {
183 name,
184 type_annotation,
185 entries,
186 } => {
187 let entries = entries
188 .into_iter()
189 .map(|(k, v)| (self.resolve_expression(k), self.resolve_expression(v)))
190 .collect();
191 let slot = self.declare(name.clone());
192 let value = self
193 .ast_arena
194 .alloc_expr(ExpressionKind::MapLiteral(entries), span);
195
196 StatementKind::ResolvedConstantMap {
197 name,
198 slot,
199 type_annotation,
200 value,
201 }
202 }
203
204 StatementKind::FunctionDeclaration {
205 name,
206 params,
207 return_type,
208 body,
209 attribute,
210 } => {
211 let slot = self.declare(name.clone());
212 self.push_scope();
213 for p in ¶ms {
214 self.declare(p.param_name.clone());
215 }
216 let body = self.resolve_statements(body);
217 self.pop_scope();
218 StatementKind::ResolvedFunctionDeclaration {
219 name,
220 slot,
221 params,
222 return_type,
223 body,
224 attribute,
225 }
226 }
227 StatementKind::ForEach {
228 variable,
229 iterable,
230 body,
231 } => {
232 let iterable = self.resolve_expression(iterable);
233 self.push_scope();
234 let slot = self.declare(variable.clone());
235 let body = self.resolve_statements(body);
236 self.pop_scope();
237 StatementKind::ResolvedForEach {
238 variable,
239 slot,
240 iterable,
241 body,
242 }
243 }
244 StatementKind::ForRange {
245 variable,
246 range,
247 body,
248 } => {
249 let range = Box::new(self.resolve_statement(*range));
250 self.push_scope();
251 let slot = self.declare(variable.clone());
252 let body = self.resolve_statements(body);
253 self.pop_scope();
254 StatementKind::ResolvedForRange {
255 variable,
256 slot,
257 range,
258 body,
259 }
260 }
261 StatementKind::For {
262 initializer,
263 condition,
264 increment,
265 body,
266 } => {
267 let initializer = Box::new(self.resolve_statement(*initializer));
268 let condition = self.resolve_expression(condition);
269 let increment = self.resolve_expression(increment);
270 let body = self.resolve_statements(body);
271 StatementKind::ResolvedFor {
272 initializer,
273 condition,
274 increment,
275 body,
276 }
277 }
278 StatementKind::While { condition, body } => {
279 let condition = self.resolve_expression(condition);
280 self.push_scope();
281 let body = self.resolve_statements(body);
282 self.pop_scope();
283 StatementKind::While { condition, body }
284 }
285 StatementKind::Conditional {
286 if_branch,
287 else_branch,
288 } => {
289 let if_branch = Box::new(self.resolve_statement(*if_branch));
290 let else_branch = else_branch.map(|e| Box::new(self.resolve_statement(*e)));
291 StatementKind::Conditional {
292 if_branch,
293 else_branch,
294 }
295 }
296
297 StatementKind::ConditionalBranch {
298 condition, body, ..
299 } => {
300 let condition = condition.map(|e| self.resolve_expression(e));
301 let needs_scope = body.iter().any(|s| {
302 matches!(
303 s.kind,
304 StatementKind::VariableDeclaration { .. }
305 | StatementKind::ConstantDeclaration { .. }
306 | StatementKind::Array { .. }
307 | StatementKind::ConstantArray { .. }
308 | StatementKind::Map { .. }
309 | StatementKind::ConstantMap { .. }
310 | StatementKind::FunctionDeclaration { .. }
311 )
312 });
313 if needs_scope {
314 self.push_scope();
315 }
316 let body = self.resolve_statements(body);
317 if needs_scope {
318 self.pop_scope();
319 }
320 StatementKind::ConditionalBranch {
321 condition,
322 body,
323 needs_scope,
324 }
325 }
326
327 StatementKind::Return(expr) => {
328 StatementKind::Return(expr.map(|e| self.resolve_expression(e)))
329 }
330 StatementKind::Expression(expr) => {
331 StatementKind::Expression(self.resolve_expression(expr))
332 }
333
334 StatementKind::ImportFile { path } => {
335 let import_name = format!("{}.rl", path.join("/"));
336 let file_path = self.current_dir.join(&import_name);
337 let Ok(source_text) = std::fs::read_to_string(&file_path) else {
338 return Statement::new(StatementKind::ImportFile { path }, span);
339 };
340 let source_file =
341 SourceFile::new(file_path.to_string_lossy().as_ref(), source_text);
342 let Ok(tokens) = Tokenizer::lex(source_file.clone()) else {
343 return Statement::new(StatementKind::ImportFile { path }, span);
344 };
345 let Ok((imported_ast, stmts)) = Parser::parse(tokens, source_file) else {
346 return Statement::new(StatementKind::ImportFile { path }, span);
347 };
348
349 let stmts = self.ast_arena.merge_statements(imported_ast, stmts);
350
351 let imported_dir = file_path
352 .parent()
353 .unwrap_or(std::path::Path::new(""))
354 .to_path_buf();
355 let prev_dir = std::mem::replace(&mut self.current_dir, imported_dir);
356 let resolved = self.resolve_statements(stmts);
357 self.current_dir = prev_dir;
358
359 StatementKind::ResolvedImportFile {
360 path,
361 body: resolved,
362 }
363 }
364
365 StatementKind::ImportFileNamed { path, names } => {
366 let import_name = format!("{}.rl", path.join("/"));
367 let file_path = self.current_dir.join(&import_name);
368 let Ok(source_text) = std::fs::read_to_string(&file_path) else {
369 return Statement::new(StatementKind::ImportFileNamed { path, names }, span);
370 };
371 let source_file =
372 SourceFile::new(file_path.to_string_lossy().as_ref(), source_text);
373 let Ok(tokens) = Tokenizer::lex(source_file.clone()) else {
374 return Statement::new(StatementKind::ImportFileNamed { path, names }, span);
375 };
376 let Ok((imported_ast, stmts)) = Parser::parse(tokens, source_file) else {
377 return Statement::new(StatementKind::ImportFileNamed { path, names }, span);
378 };
379 let stmts: Vec<_> = stmts
380 .into_iter()
381 .filter(|s| match &s.kind {
382 StatementKind::FunctionDeclaration { name, .. }
383 | StatementKind::VariableDeclaration { name, .. }
384 | StatementKind::ConstantDeclaration { name, .. } => names.contains(name),
385 StatementKind::Array { name, .. }
386 | StatementKind::ConstantArray { name, .. } => names.contains(name),
387 StatementKind::Map { name, .. }
388 | StatementKind::ConstantMap { name, .. } => names.contains(name),
389 _ => false,
390 })
391 .collect();
392
393 let stmts = self.ast_arena.merge_statements(imported_ast, stmts);
394
395 let imported_dir = file_path
396 .parent()
397 .unwrap_or(std::path::Path::new(""))
398 .to_path_buf();
399 let prev_dir = std::mem::replace(&mut self.current_dir, imported_dir);
400 let body = self.resolve_statements(stmts);
401 self.current_dir = prev_dir;
402
403 StatementKind::ResolvedImportFile { path, body }
404 }
405
406 StatementKind::DestructureDeclaration { bindings, value } => {
407 let value = self.resolve_expression(value);
408 let slots = bindings
409 .iter()
410 .map(|(_, name)| self.declare(name.clone()))
411 .collect();
412 StatementKind::ResolvedDestructureDeclaration {
413 bindings,
414 slots,
415 value,
416 }
417 }
418
419 StatementKind::Match { value, arms } => {
420 let value = self.resolve_expression(value);
421 let arms = arms
422 .into_iter()
423 .map(|(pattern, body)| {
424 self.push_scope();
425 let body = self.resolve_statements(body);
426 self.pop_scope();
427 (pattern, body)
428 })
429 .collect();
430 StatementKind::Match { value, arms }
431 }
432
433 other => other,
434 };
435 Statement::new(kind, span)
436 }
437}