Skip to main content

arcis_interpreter/
interpreter_builder.rs

1use crate::{
2    dependencies::{
3        get_dependencies,
4        get_mock_library,
5        get_standard_library,
6        is_root_arcis,
7        libraries_to_dependency_graph,
8        Libraries,
9    },
10    interpreter::Interpreter,
11};
12use blink_alloc::Blink;
13
14pub struct InterpreterBuilder<'ast> {
15    module: &'ast syn::ItemMod,
16    dependencies: Libraries,
17    standard_library: (std::path::PathBuf, syn::File),
18    mock_library: (std::path::PathBuf, syn::File),
19    arena: Blink,
20}
21
22impl<'ast> InterpreterBuilder<'ast> {
23    pub fn new(module: &'ast syn::ItemMod) -> Self {
24        let dependencies = get_dependencies();
25        let standard_library = get_standard_library();
26        let mock_library = get_mock_library();
27        Self {
28            module,
29            dependencies,
30            standard_library,
31            mock_library,
32            arena: Default::default(),
33        }
34    }
35    pub fn run<'a, 'b>(&'b self) -> Interpreter<'a>
36    where
37        'ast: 'a,
38        'b: 'a,
39    {
40        build_interpreter(
41            self.module,
42            &self.arena,
43            &self.mock_library,
44            &self.standard_library,
45            &self.dependencies,
46        )
47    }
48}
49
50fn build_interpreter<'ast>(
51    module: &'ast syn::ItemMod,
52    arena: &'ast Blink,
53    mock_library: &'ast (std::path::PathBuf, syn::File),
54    standard_library: &'ast (std::path::PathBuf, syn::File),
55    dependencies: &'ast Libraries,
56) -> Interpreter<'ast> {
57    let mut interpreter =
58        Interpreter::with_standard_library(arena, libraries_to_dependency_graph(dependencies));
59    let is_arcis = is_root_arcis();
60    if !is_arcis || module.ident != "arcis_library" {
61        syn::visit::visit_item_mod(&mut interpreter, module);
62    }
63
64    for (file, path) in dependencies.file_iter() {
65        interpreter.visit_crate(file, std::path::Path::new(path));
66    }
67    for forbidden_crate in dependencies.forbidden_crates() {
68        interpreter.forbid_crate(forbidden_crate);
69    }
70    for (path, file) in [mock_library, standard_library] {
71        interpreter.with_source_file(path, |interpreter| {
72            syn::visit::visit_file(interpreter, file);
73        });
74    }
75    interpreter
76}