Next Generation WASM Microkernel Operating System
1use crate::component::*;
2use crate::core;
3use crate::kw;
4use crate::parser::{Parse, Parser, Result};
5use crate::token::{Id, LParen, NameAnnotation, Span};
6use alloc::vec::Vec;
7
8/// A core instance defined by instantiation or exporting core items.
9#[derive(Debug)]
10pub struct CoreInstance<'a> {
11 /// Where this `core instance` was defined.
12 pub span: Span,
13 /// An identifier that this instance is resolved with (optionally) for name
14 /// resolution.
15 pub id: Option<Id<'a>>,
16 /// An optional name for this instance stored in the custom `name` section.
17 pub name: Option<NameAnnotation<'a>>,
18 /// What kind of instance this is.
19 pub kind: CoreInstanceKind<'a>,
20}
21
22impl<'a> Parse<'a> for CoreInstance<'a> {
23 fn parse(parser: Parser<'a>) -> Result<Self> {
24 let span = parser.parse::<kw::core>()?.0;
25 parser.parse::<kw::instance>()?;
26 let id = parser.parse()?;
27 let name = parser.parse()?;
28 let kind = parser.parse()?;
29
30 Ok(Self {
31 span,
32 id,
33 name,
34 kind,
35 })
36 }
37}
38
39/// The kinds of core instances in the text format.
40#[derive(Debug)]
41pub enum CoreInstanceKind<'a> {
42 /// Instantiate a core module.
43 Instantiate {
44 /// The module being instantiated.
45 module: ItemRef<'a, kw::module>,
46 /// Arguments used to instantiate the instance.
47 args: Vec<CoreInstantiationArg<'a>>,
48 },
49 /// The instance is defined by exporting local items as an instance.
50 BundleOfExports(Vec<CoreInstanceExport<'a>>),
51}
52
53impl<'a> Parse<'a> for CoreInstanceKind<'a> {
54 fn parse(parser: Parser<'a>) -> Result<Self> {
55 if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? {
56 parser.parens(|parser| {
57 parser.parse::<kw::instantiate>()?;
58 Ok(Self::Instantiate {
59 module: parser.parse::<IndexOrRef<'_, _>>()?.0,
60 args: parser.parse()?,
61 })
62 })
63 } else {
64 Ok(Self::BundleOfExports(parser.parse()?))
65 }
66 }
67}
68
69impl Default for kw::module {
70 fn default() -> kw::module {
71 kw::module(Span::from_offset(0))
72 }
73}
74
75/// An argument to instantiate a core module.
76#[derive(Debug)]
77pub struct CoreInstantiationArg<'a> {
78 /// The name of the instantiation argument.
79 pub name: &'a str,
80 /// The kind of core instantiation argument.
81 pub kind: CoreInstantiationArgKind<'a>,
82}
83
84impl<'a> Parse<'a> for CoreInstantiationArg<'a> {
85 fn parse(parser: Parser<'a>) -> Result<Self> {
86 parser.parse::<kw::with>()?;
87 Ok(Self {
88 name: parser.parse()?,
89 kind: parser.parse()?,
90 })
91 }
92}
93
94impl<'a> Parse<'a> for Vec<CoreInstantiationArg<'a>> {
95 fn parse(parser: Parser<'a>) -> Result<Self> {
96 let mut args = Vec::new();
97 while !parser.is_empty() {
98 args.push(parser.parens(|parser| parser.parse())?);
99 }
100 Ok(args)
101 }
102}
103
104/// The kind of core instantiation argument.
105#[derive(Debug)]
106pub enum CoreInstantiationArgKind<'a> {
107 /// The argument is a reference to an instance.
108 Instance(CoreItemRef<'a, kw::instance>),
109 /// The argument is an instance created from local exported core items.
110 ///
111 /// This is syntactic sugar for defining a core instance and also using it
112 /// as an instantiation argument.
113 BundleOfExports(Span, Vec<CoreInstanceExport<'a>>),
114}
115
116impl<'a> Parse<'a> for CoreInstantiationArgKind<'a> {
117 fn parse(parser: Parser<'a>) -> Result<Self> {
118 parser.parens(|parser| {
119 if let Some(r) = parser.parse()? {
120 Ok(Self::Instance(r))
121 } else {
122 let span = parser.parse::<kw::instance>()?.0;
123 Ok(Self::BundleOfExports(span, parser.parse()?))
124 }
125 })
126 }
127}
128
129/// An exported item as part of a core instance.
130#[derive(Debug)]
131pub struct CoreInstanceExport<'a> {
132 /// Where this export was defined.
133 pub span: Span,
134 /// The name of this export from the instance.
135 pub name: &'a str,
136 /// What's being exported from the instance.
137 pub item: CoreItemRef<'a, core::ExportKind>,
138}
139
140impl<'a> Parse<'a> for CoreInstanceExport<'a> {
141 fn parse(parser: Parser<'a>) -> Result<Self> {
142 Ok(Self {
143 span: parser.parse::<kw::export>()?.0,
144 name: parser.parse()?,
145 item: parser.parens(|parser| parser.parse())?,
146 })
147 }
148}
149
150impl<'a> Parse<'a> for Vec<CoreInstanceExport<'a>> {
151 fn parse(parser: Parser<'a>) -> Result<Self> {
152 let mut exports = Vec::new();
153 while !parser.is_empty() {
154 exports.push(parser.parens(|parser| parser.parse())?);
155 }
156 Ok(exports)
157 }
158}
159
160/// A component instance defined by instantiation or exporting items.
161#[derive(Debug)]
162pub struct Instance<'a> {
163 /// Where this `instance` was defined.
164 pub span: Span,
165 /// An identifier that this instance is resolved with (optionally) for name
166 /// resolution.
167 pub id: Option<Id<'a>>,
168 /// An optional name for this instance stored in the custom `name` section.
169 pub name: Option<NameAnnotation<'a>>,
170 /// If present, inline export annotations which indicate names this
171 /// definition should be exported under.
172 pub exports: InlineExport<'a>,
173 /// What kind of instance this is.
174 pub kind: InstanceKind<'a>,
175}
176
177impl<'a> Parse<'a> for Instance<'a> {
178 fn parse(parser: Parser<'a>) -> Result<Self> {
179 let span = parser.parse::<kw::instance>()?.0;
180 let id = parser.parse()?;
181 let name = parser.parse()?;
182 let exports = parser.parse()?;
183 let kind = parser.parse()?;
184
185 Ok(Self {
186 span,
187 id,
188 name,
189 exports,
190 kind,
191 })
192 }
193}
194
195/// The kinds of instances in the text format.
196#[derive(Debug)]
197pub enum InstanceKind<'a> {
198 /// The `(instance (import "x"))` sugar syntax
199 Import {
200 /// The name of the import
201 import: InlineImport<'a>,
202 /// The type of the instance being imported
203 ty: ComponentTypeUse<'a, InstanceType<'a>>,
204 },
205 /// Instantiate a component.
206 Instantiate {
207 /// The component being instantiated.
208 component: ItemRef<'a, kw::component>,
209 /// Arguments used to instantiate the instance.
210 args: Vec<InstantiationArg<'a>>,
211 },
212 /// The instance is defined by exporting local items as an instance.
213 BundleOfExports(Vec<ComponentExport<'a>>),
214}
215
216impl<'a> Parse<'a> for InstanceKind<'a> {
217 fn parse(parser: Parser<'a>) -> Result<Self> {
218 if let Some(import) = parser.parse()? {
219 return Ok(Self::Import {
220 import,
221 ty: parser.parse()?,
222 });
223 }
224
225 if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? {
226 parser.parens(|parser| {
227 parser.parse::<kw::instantiate>()?;
228 Ok(Self::Instantiate {
229 component: parser.parse::<IndexOrRef<'_, _>>()?.0,
230 args: parser.parse()?,
231 })
232 })
233 } else {
234 Ok(Self::BundleOfExports(parser.parse()?))
235 }
236 }
237}
238
239impl Default for kw::component {
240 fn default() -> kw::component {
241 kw::component(Span::from_offset(0))
242 }
243}
244
245/// An argument to instantiate a component.
246#[derive(Debug)]
247pub struct InstantiationArg<'a> {
248 /// The name of the instantiation argument.
249 pub name: &'a str,
250 /// The kind of instantiation argument.
251 pub kind: InstantiationArgKind<'a>,
252}
253
254impl<'a> Parse<'a> for InstantiationArg<'a> {
255 fn parse(parser: Parser<'a>) -> Result<Self> {
256 parser.parse::<kw::with>()?;
257 Ok(Self {
258 name: parser.parse()?,
259 kind: parser.parse()?,
260 })
261 }
262}
263
264impl<'a> Parse<'a> for Vec<InstantiationArg<'a>> {
265 fn parse(parser: Parser<'a>) -> Result<Self> {
266 let mut args = Vec::new();
267 while !parser.is_empty() {
268 args.push(parser.parens(|parser| parser.parse())?);
269 }
270 Ok(args)
271 }
272}
273
274/// The kind of instantiation argument.
275#[derive(Debug)]
276pub enum InstantiationArgKind<'a> {
277 /// The argument is a reference to a component item.
278 Item(ComponentExportKind<'a>),
279 /// The argument is an instance created from local exported items.
280 ///
281 /// This is syntactic sugar for defining an instance and also using it
282 /// as an instantiation argument.
283 BundleOfExports(Span, Vec<ComponentExport<'a>>),
284}
285
286impl<'a> Parse<'a> for InstantiationArgKind<'a> {
287 fn parse(parser: Parser<'a>) -> Result<Self> {
288 if let Some(item) = parser.parse()? {
289 Ok(Self::Item(item))
290 } else {
291 parser.parens(|parser| {
292 let span = parser.parse::<kw::instance>()?.0;
293 Ok(Self::BundleOfExports(span, parser.parse()?))
294 })
295 }
296 }
297}