1use super::*;
18
19use leo_errors::{ParserError, Result};
20use leo_span::{Symbol, sym};
21
22impl<N: Network> ParserContext<'_, N> {
23 pub fn parse_program(&mut self) -> Result<Program> {
25 let mut imports = IndexMap::new();
26 let mut program_scopes = IndexMap::new();
27
28 let mut parsed_program_scope = false;
30
31 while self.has_next() {
32 match &self.token.token {
33 Token::Import => {
34 let (id, import) = self.parse_import()?;
35 imports.insert(id, import);
36 }
37 Token::Program => {
38 match parsed_program_scope {
39 true => {
41 return Err(ParserError::only_one_program_scope_is_allowed(self.token.span).into());
42 }
43 false => {
44 parsed_program_scope = true;
45 let program_scope = self.parse_program_scope()?;
46 program_scopes.insert(program_scope.program_id.name.name, program_scope);
47 }
48 }
49 }
50 _ => return Err(Self::unexpected_item(&self.token, &[Token::Import, Token::Program]).into()),
51 }
52 }
53
54 if !parsed_program_scope {
56 return Err(ParserError::missing_program_scope(self.token.span).into());
57 }
58
59 Ok(Program { imports, stubs: IndexMap::new(), program_scopes })
60 }
61
62 fn unexpected_item(token: &SpannedToken, expected: &[Token]) -> ParserError {
63 ParserError::unexpected(
64 &token.token,
65 expected.iter().map(|x| format!("'{x}'")).collect::<Vec<_>>().join(", "),
66 token.span,
67 )
68 }
69
70 pub(super) fn parse_import(&mut self) -> Result<(Symbol, (Program, Span))> {
73 let start = self.expect(&Token::Import)?;
75
76 let import_name = self.expect_identifier()?;
78
79 self.expect(&Token::Dot)?;
81
82 if !self.eat(&Token::Aleo) {
84 return Err(ParserError::invalid_network(self.token.span).into());
86 }
87
88 let end = self.expect(&Token::Semicolon)?;
89
90 Ok((import_name.name, (Program::default(), start + end)))
92 }
93
94 fn parse_program_scope(&mut self) -> Result<ProgramScope> {
96 let start = self.expect(&Token::Program)?;
98
99 let name = self.expect_identifier()?;
101
102 self.program_name = Some(name.name);
104
105 self.expect(&Token::Dot)?;
107
108 let network_span = self.expect(&Token::Aleo).map_err(|_| ParserError::invalid_network(self.token.span))?;
110
111 let program_id = ProgramId {
113 name,
114 network: Identifier { name: sym::aleo, id: self.node_builder.next_id(), span: network_span },
115 };
116
117 self.expect(&Token::LeftCurly)?;
119
120 let mut consts: Vec<(Symbol, ConstDeclaration)> = Vec::new();
122 let (mut transitions, mut functions) = (Vec::new(), Vec::new());
123 let mut structs: Vec<(Symbol, Composite)> = Vec::new();
124 let mut mappings: Vec<(Symbol, Mapping)> = Vec::new();
125
126 while self.has_next() {
127 match &self.token.token {
128 Token::Const => {
129 let declaration = self.parse_const_declaration_statement()?;
130 consts.push((Symbol::intern(&declaration.place.to_string()), declaration));
131 }
132 Token::Struct | Token::Record => {
133 let (id, struct_) = self.parse_struct()?;
134 structs.push((id, struct_));
135 }
136 Token::Mapping => {
137 let (id, mapping) = self.parse_mapping()?;
138 mappings.push((id, mapping));
139 }
140 Token::At | Token::Async | Token::Function | Token::Transition | Token::Inline | Token::Script => {
141 let (id, function) = self.parse_function()?;
142
143 if function.variant.is_transition() {
145 transitions.push((id, function));
146 } else {
147 functions.push((id, function));
148 }
149 }
150 Token::RightCurly => break,
151 _ => {
152 return Err(Self::unexpected_item(&self.token, &[
153 Token::Const,
154 Token::Struct,
155 Token::Record,
156 Token::Mapping,
157 Token::At,
158 Token::Async,
159 Token::Function,
160 Token::Transition,
161 Token::Inline,
162 Token::Script,
163 Token::RightCurly,
164 ])
165 .into());
166 }
167 }
168 }
169
170 let end = self.expect(&Token::RightCurly)?;
172
173 Ok(ProgramScope {
174 program_id,
175 consts,
176 functions: [transitions, functions].concat(),
177 structs,
178 mappings,
179 span: start + end,
180 })
181 }
182
183 fn parse_struct_members(&mut self) -> Result<(Vec<Member>, Span)> {
185 let mut members = Vec::new();
186
187 while !self.check(&Token::RightCurly) {
188 let variable = self.parse_member_variable_declaration()?;
189
190 if !self.check(&Token::RightCurly) && !self.eat(&Token::Comma) {
191 self.emit_err(ParserError::comma_expected_after_member(self.token.span));
192 }
193
194 members.push(variable);
195 }
196 let span = self.expect(&Token::RightCurly)?;
197
198 Ok((members, span))
199 }
200
201 pub(super) fn parse_typed_ident(&mut self) -> Result<(Identifier, Type, Span)> {
203 let name = self.expect_identifier()?;
204 self.expect(&Token::Colon)?;
205 let (type_, span) = self.parse_type()?;
206
207 Ok((name, type_, name.span + span))
208 }
209
210 fn parse_member_variable_declaration(&mut self) -> Result<Member> {
212 let mode = self.parse_mode()?;
213
214 let (identifier, type_, span) = self.parse_typed_ident()?;
215
216 Ok(Member { mode, identifier, type_, span, id: self.node_builder.next_id() })
217 }
218
219 pub(super) fn parse_struct(&mut self) -> Result<(Symbol, Composite)> {
221 let is_record = matches!(&self.token.token, Token::Record);
222 let start = self.expect_any(&[Token::Struct, Token::Record])?;
223
224 let file_type = self.look_ahead(1, |t| &t.token);
226 if self.token.token == Token::Dot && (file_type == &Token::Aleo) {
227 return Err(ParserError::cannot_declare_external_struct(self.token.span).into());
228 }
229
230 let struct_name = self.expect_identifier()?;
231
232 let const_parameters = if self.eat(&Token::DoubleColon) {
233 self.parse_bracket_comma_list(|p| p.parse_const_parameter().map(Some))?.0
234 } else {
235 vec![]
236 };
237
238 self.expect(&Token::LeftCurly)?;
239 let (members, end) = self.parse_struct_members()?;
240
241 let external = if is_record { self.program_name } else { None };
243
244 Ok((struct_name.name, Composite {
245 identifier: struct_name,
246 const_parameters,
247 members,
248 external,
249 is_record,
250 span: start + end,
251 id: self.node_builder.next_id(),
252 }))
253 }
254
255 pub(super) fn parse_mapping(&mut self) -> Result<(Symbol, Mapping)> {
257 let start = self.expect(&Token::Mapping)?;
258 let identifier = self.expect_identifier()?;
259 self.expect(&Token::Colon)?;
260 let (key_type, _) = self.parse_type()?;
261 self.expect(&Token::BigArrow)?;
262 let (value_type, _) = self.parse_type()?;
263 let end = self.expect(&Token::Semicolon)?;
264 Ok((identifier.name, Mapping {
265 identifier,
266 key_type,
267 value_type,
268 span: start + end,
269 id: self.node_builder.next_id(),
270 }))
271 }
272
273 pub(super) fn parse_mode(&mut self) -> Result<Mode> {
276 let private = self.eat(&Token::Private).then_some(self.prev_token.span);
277 let public = self.eat(&Token::Public).then_some(self.prev_token.span);
278 let constant = self.eat(&Token::Constant).then_some(self.prev_token.span);
279
280 match (private, public, constant) {
281 (None, None, None) => Ok(Mode::None),
282 (Some(_), None, None) => Ok(Mode::Private),
283 (None, Some(_), None) => Ok(Mode::Public),
284 (None, None, Some(_)) => Ok(Mode::Constant),
285 _ => {
286 let mut spans = [private, public, constant].into_iter().flatten();
287
288 let starting_span = spans.next().unwrap();
290 let summed_span = spans.fold(starting_span, |span, next| span + next);
292 Err(ParserError::inputs_multiple_variable_modes_specified(summed_span).into())
294 }
295 }
296 }
297
298 fn parse_input(&mut self) -> Result<Input> {
300 let mode = self.parse_mode()?;
301 let name = self.expect_identifier()?;
302 self.expect(&Token::Colon)?;
303
304 let (type_, type_span) = self.parse_type()?;
305 let span = name.span() + type_span;
306
307 Ok(Input { identifier: name, mode, type_, span, id: self.node_builder.next_id() })
308 }
309
310 fn parse_output(&mut self) -> Result<Output> {
312 let mode = self.parse_mode()?;
313 let (type_, span) = self.parse_type()?;
314 Ok(Output { mode, type_, span, id: self.node_builder.next_id() })
315 }
316
317 fn parse_annotation(&mut self) -> Result<Annotation> {
319 let start = self.expect(&Token::At)?;
321 let identifier = match self.token.token {
322 Token::Program => {
323 Identifier { name: sym::program, span: self.expect(&Token::Program)?, id: self.node_builder.next_id() }
324 }
325 _ => self.expect_identifier()?,
326 };
327 let mut span = start + identifier.span;
328
329 if identifier.span.hi - start.lo > 1 + identifier.name.to_string().len() as u32 {
332 return Err(ParserError::space_in_annotation(span).into());
333 }
334
335 let mut map = IndexMap::new();
336
337 if self.eat(&Token::LeftParen) {
338 loop {
339 let key = self.expect_identifier()?;
340 self.expect(&Token::Assign)?;
341 if let Token::StaticString(s) = &self.token.token {
342 map.insert(key.name, s.clone());
343 self.bump();
344 } else {
345 return Err(ParserError::unexpected(&self.token.token, "a string", self.token.span).into());
346 }
347
348 match &self.token.token {
349 Token::Comma => {
350 self.bump();
351 if let Token::RightParen = &self.token.token {
352 span = span + self.token.span;
353 self.bump();
354 break;
355 }
356 }
357 Token::RightParen => {
358 span = span + self.token.span;
359 self.bump();
360 break;
361 }
362 _ => return Err(ParserError::unexpected(&self.token.token, ", or )", self.token.span).into()),
363 }
364 }
365 }
366
367 Ok(Annotation { identifier, span, id: self.node_builder.next_id(), map })
368 }
369
370 fn parse_function(&mut self) -> Result<(Symbol, Function)> {
373 let mut annotations = Vec::new();
376 while self.look_ahead(0, |t| &t.token) == &Token::At {
377 annotations.push(self.parse_annotation()?)
378 }
379 let (is_async, start_async) =
381 if self.token.token == Token::Async { (true, self.expect(&Token::Async)?) } else { (false, Span::dummy()) };
382 let (variant, start) = match self.token.token.clone() {
384 Token::Inline => (Variant::Inline, self.expect(&Token::Inline)?),
385 Token::Script => (Variant::Script, self.expect(&Token::Script)?),
386 Token::Function => {
387 (if is_async { Variant::AsyncFunction } else { Variant::Function }, self.expect(&Token::Function)?)
388 }
389 Token::Transition => (
390 if is_async { Variant::AsyncTransition } else { Variant::Transition },
391 self.expect(&Token::Transition)?,
392 ),
393 _ => self.unexpected("'function', 'transition', or 'inline'")?,
394 };
395 let name = self.expect_identifier()?;
396
397 let const_parameters = if self.eat(&Token::DoubleColon) {
398 self.parse_bracket_comma_list(|p| p.parse_const_parameter().map(Some))?.0
399 } else {
400 vec![]
401 };
402
403 let (inputs, ..) = self.parse_paren_comma_list(|p| p.parse_input().map(Some))?;
405
406 let output = match self.eat(&Token::Arrow) {
408 false => vec![],
409 true => {
410 self.disallow_struct_construction = true;
411 let output = match self.peek_is_left_par() {
412 true => self.parse_paren_comma_list(|p| p.parse_output().map(Some))?.0,
413 false => vec![self.parse_output()?],
414 };
415 self.disallow_struct_construction = false;
416 output
417 }
418 };
419
420 let (_has_empty_block, block) = match &self.token.token {
423 Token::LeftCurly => (false, self.parse_block()?),
424 Token::Semicolon => {
425 let semicolon = self.expect(&Token::Semicolon)?;
426 (true, Block { statements: Vec::new(), span: semicolon, id: self.node_builder.next_id() })
428 }
429 _ => self.unexpected("block or semicolon")?,
430 };
431
432 let span = if start_async == Span::dummy() { start + block.span } else { start_async + block.span };
433
434 Ok((
435 name.name,
436 Function::new(
437 annotations,
438 variant,
439 name,
440 const_parameters,
441 inputs,
442 output,
443 block,
444 span,
445 self.node_builder.next_id(),
446 ),
447 ))
448 }
449}