1 | use super::{ |
2 | core::{Parser, Result}, |
3 | errors::ParserError, |
4 | slice::Slice, |
5 | }; |
6 | use crate::ast; |
7 | |
8 | impl<'s, S> Parser<S> |
9 | where |
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 | |