|
1 | 1 | extern crate alloc; |
2 | 2 | use alloc::vec::IntoIter; |
3 | 3 |
|
4 | | -use super::state::ParsingState; |
| 4 | +use super::state::{BlockState, ParsingState}; |
5 | 5 | use super::symbols::handle_symbol; |
6 | 6 | use super::tree::blocks::Block; |
7 | 7 | use super::tree::node::Node; |
@@ -37,6 +37,22 @@ fn handle_literal( |
37 | 37 | parse_block(tokens, p_state, current) |
38 | 38 | } |
39 | 39 |
|
| 40 | +fn mismatched_error( |
| 41 | + blocks: &mut Vec<BlockState>, |
| 42 | + next_token: Option<Token>, |
| 43 | + filename: String, |
| 44 | +) -> Vec<CompileError> { |
| 45 | + let mut errors = vec![]; |
| 46 | + let location = next_token.map_or_else( |
| 47 | + || Location::from(filename), |
| 48 | + |token| token.into_value_location().1, |
| 49 | + ); |
| 50 | + while let Some(block) = blocks.pop() { |
| 51 | + errors.push(block.mismatched_err_begin(location.clone())); |
| 52 | + } |
| 53 | + errors |
| 54 | +} |
| 55 | + |
40 | 56 | #[expect(clippy::todo, reason = "implementation in process")] |
41 | 57 | pub fn parse_block( |
42 | 58 | tokens: &mut IntoIter<Token>, |
@@ -68,13 +84,24 @@ pub fn parse_block( |
68 | 84 | #[inline] |
69 | 85 | pub fn parse_tokens(tokens: Vec<Token>) -> Res<Node> { |
70 | 86 | let mut nodes = vec![]; |
| 87 | + let filename = tokens |
| 88 | + .first() |
| 89 | + .map(|node| node.get_location().get_values().0.to_owned()); |
71 | 90 | let mut tokens_iter = tokens.into_iter(); |
72 | 91 | while tokens_iter.len() != 0 { |
73 | 92 | let mut outer_node_block = Node::default(); |
74 | 93 | let mut p_state = ParsingState::default(); |
75 | 94 | if let Err(err) = parse_block(&mut tokens_iter, &mut p_state, &mut outer_node_block) { |
76 | 95 | return Res::from_err(err); |
77 | 96 | } |
| 97 | + if !p_state.opened_blocks.is_empty() { |
| 98 | + return Res::from_errors(mismatched_error( |
| 99 | + &mut p_state.opened_blocks, |
| 100 | + tokens_iter.next(), |
| 101 | + filename.expect("while loop never entered if tokens empty"), |
| 102 | + )); |
| 103 | + } |
| 104 | + |
78 | 105 | nodes.push(outer_node_block); |
79 | 106 | } |
80 | 107 | Res::from(clean_nodes(nodes)) |
|
0 commit comments