1use super::{
2 core::{Parser, Result},
3 errors::ParserError,
4 slice::Slice,
5};
6use crate::ast;
7
8impl<'s, S> Parser<S>
9where
10 S: Slice<'s>,
11{
12 pub fn parse_runtime(
13 mut self,
14 ) -> std::result::Result<ast::Resource<S>, (ast::Resource<S>, Vec<ParserError>)> {
15 let mut errors = vec![];
16
17 // That default allocation gives the lowest
18 // number of instructions and cycles in ioi.
19 let mut body = Vec::with_capacity(6);
20
21 self.skip_blank_block();
22
23 while self.ptr < self.length {
24 let entry_start = self.ptr;
25 let entry = self.get_entry_runtime(entry_start);
26
27 match entry {
28 Ok(Some(entry)) => {
29 body.push(entry);
30 }
31 Ok(None) => {}
32 Err(mut err) => {
33 self.skip_to_next_entry_start();
34 err.slice = Some(entry_start..self.ptr);
35 errors.push(err);
36 let content = self.source.slice(entry_start..self.ptr);
37 body.push(ast::Entry::Junk { content });
38 }
39 }
40 self.skip_blank_block();
41 }
42
43 if errors.is_empty() {
44 Ok(ast::Resource { body })
45 } else {
46 Err((ast::Resource { body }, errors))
47 }
48 }
49
50 fn get_entry_runtime(&mut self, entry_start: usize) -> Result<Option<ast::Entry<S>>> {
51 let entry = match get_current_byte!(self) {
52 Some(b'#') => {
53 self.skip_comment();
54 None
55 }
56 Some(b'-') => Some(ast::Entry::Term(self.get_term(entry_start)?)),
57 _ => Some(ast::Entry::Message(self.get_message(entry_start)?)),
58 };
59 Ok(entry)
60 }
61}
62