Skip to main content

miden_assembly_syntax/
parse.rs

1use alloc::{borrow::Cow, boxed::Box, string::String, sync::Arc};
2
3use miden_debug_types::{SourceFile, SourceManager};
4
5use crate::{ast::Module, diagnostics::Report};
6
7// PARSE TRAIT
8// ================================================================================================
9
10/// This trait is meant to be implemented by any type that can be parsed to a [Module],
11/// to allow methods which expect a [Module] to accept things like:
12///
13/// * A [Module] which was previously parsed or deserialized
14/// * A string representing the source code of a [Module].
15/// * A path to a file containing the source code of a [Module].
16/// * A vector of [crate::ast::Form]s comprising the contents of a [Module].
17pub trait Parse: Sized {
18    /// Parse (or convert) `self` into an executable [Module].
19    fn parse(
20        self,
21        warnings_as_errors: bool,
22        source_manager: Arc<dyn SourceManager>,
23    ) -> Result<Box<Module>, Report>;
24}
25
26// PARSE IMPLEMENTATIONS FOR MODULES
27// ------------------------------------------------------------------------------------------------
28
29impl Parse for Module {
30    #[inline(always)]
31    fn parse(
32        self,
33        _warnings_as_errors: bool,
34        _source_manager: Arc<dyn SourceManager>,
35    ) -> Result<Box<Module>, Report> {
36        Ok(Box::new(self))
37    }
38}
39
40impl Parse for Box<Module> {
41    #[inline(always)]
42    fn parse(
43        self,
44        _warnings_as_errors: bool,
45        _source_manager: Arc<dyn SourceManager>,
46    ) -> Result<Box<Module>, Report> {
47        Ok(self)
48    }
49}
50
51impl Parse for Arc<Module> {
52    fn parse(
53        self,
54        _warnings_as_errors: bool,
55        _source_manager: Arc<dyn SourceManager>,
56    ) -> Result<Box<Module>, Report> {
57        Ok(Box::new(Arc::unwrap_or_clone(self)))
58    }
59}
60
61// PARSE IMPLEMENTATIONS FOR STRINGS
62// ------------------------------------------------------------------------------------------------
63
64impl Parse for Arc<SourceFile> {
65    fn parse(
66        self,
67        warnings_as_errors: bool,
68        source_manager: Arc<dyn SourceManager>,
69    ) -> Result<Box<Module>, Report> {
70        let mut parser = Module::parser(None);
71        parser.set_warnings_as_errors(warnings_as_errors);
72        parser.parse(None, self, source_manager)
73    }
74}
75
76impl Parse for &str {
77    fn parse(
78        self,
79        warnings_as_errors: bool,
80        source_manager: Arc<dyn SourceManager>,
81    ) -> Result<Box<Module>, Report> {
82        let mut parser = Module::parser(None);
83        parser.set_warnings_as_errors(warnings_as_errors);
84        parser.parse_str(None, self, source_manager)
85    }
86}
87
88impl Parse for &String {
89    #[inline]
90    fn parse(
91        self,
92        warnings_as_errors: bool,
93        source_manager: Arc<dyn SourceManager>,
94    ) -> Result<Box<Module>, Report> {
95        Parse::parse(self.as_str(), warnings_as_errors, source_manager)
96    }
97}
98
99impl Parse for String {
100    fn parse(
101        self,
102        warnings_as_errors: bool,
103        source_manager: Arc<dyn SourceManager>,
104    ) -> Result<Box<Module>, Report> {
105        Parse::parse(self.as_str(), warnings_as_errors, source_manager)
106    }
107}
108
109impl Parse for Box<str> {
110    fn parse(
111        self,
112        warnings_as_errors: bool,
113        source_manager: Arc<dyn SourceManager>,
114    ) -> Result<Box<Module>, Report> {
115        Parse::parse(self.as_ref(), warnings_as_errors, source_manager)
116    }
117}
118
119impl Parse for Cow<'_, str> {
120    fn parse(
121        self,
122        warnings_as_errors: bool,
123        source_manager: Arc<dyn SourceManager>,
124    ) -> Result<Box<Module>, Report> {
125        Parse::parse(self.as_ref(), warnings_as_errors, source_manager)
126    }
127}
128
129// PARSE IMPLEMENTATIONS FOR FILES
130// ------------------------------------------------------------------------------------------------
131
132#[cfg(feature = "std")]
133impl Parse for &std::path::Path {
134    fn parse(
135        self,
136        warnings_as_errors: bool,
137        source_manager: Arc<dyn SourceManager>,
138    ) -> Result<Box<Module>, Report> {
139        let mut parser = Module::parser(None);
140        parser.set_warnings_as_errors(warnings_as_errors);
141        parser.parse_file(None, self, source_manager)
142    }
143}
144
145#[cfg(feature = "std")]
146impl Parse for std::path::PathBuf {
147    fn parse(
148        self,
149        warnings_as_errors: bool,
150        source_manager: Arc<dyn SourceManager>,
151    ) -> Result<Box<Module>, Report> {
152        self.as_path().parse(warnings_as_errors, source_manager)
153    }
154}