microcad_lang/eval/statements/use_statement.rs
1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4use crate::eval::*;
5
6/// Trait used by [UseDeclaration] and implemented by [SymbolTable] and passed through by [Context]
7/// to put symbols on the [Stack] (for `use statements`).
8pub trait UseSymbol {
9 /// Find a symbol in the symbol table and copy it to the locals.
10 ///
11 /// Might load any related external file if not already loaded.
12 ///
13 /// # Arguments
14 /// - `name`: Name of the symbol to search for
15 /// - `id`: if given overwrites the ID from qualified name (use as)
16 /// - `within`: Target symbol
17 fn use_symbol(
18 &mut self,
19 visibility: Visibility,
20 name: &QualifiedName,
21 id: Option<Identifier>,
22 within: &QualifiedName,
23 ) -> EvalResult<Symbol>;
24
25 /// Find a symbol in the symbol table and copy all it's children to the locals and the target.
26 ///
27 /// Might load any related external file if not already loaded.
28 ///
29 /// # Arguments
30 /// - `name`: Name of the symbol to search for
31 /// - `within`: Target symbol
32 fn use_symbols_of(
33 &mut self,
34 visibility: Visibility,
35 name: &QualifiedName,
36 within: &QualifiedName,
37 ) -> EvalResult<Symbol>;
38}
39
40impl Eval<()> for UseStatement {
41 fn eval(&self, context: &mut EvalContext) -> EvalResult<()> {
42 context.grant(self)?;
43
44 if !context.is_module() {
45 log::trace!("Evaluating use statement: {self}");
46 let current = &context.current_name();
47 let visibility = self.visibility;
48 match &self.decl {
49 UseDeclaration::Use(name) => {
50 let mut symbol = context.lookup(name)?;
51 symbol.set_visibility(visibility);
52 if let Err(err) = context.add_symbol(symbol.id(), symbol) {
53 context.error(name, err)?;
54 }
55 }
56 UseDeclaration::UseAll(name) => {
57 if let Err(err) = context.use_symbols_of(visibility, name, current) {
58 context.error(name, err)?
59 }
60 }
61 UseDeclaration::UseAlias(name, alias) => {
62 if let Err(err) =
63 context.use_symbol(visibility, name, Some(alias.clone()), current)
64 {
65 context.error(name, err)?;
66 }
67 }
68 }
69 }
70 Ok(())
71 }
72}