Skip to content

Commit 8b39c22

Browse files
committed
(tree) rev: block handlers
1 parent 7668ca4 commit 8b39c22

File tree

10 files changed

+236
-143
lines changed

10 files changed

+236
-143
lines changed

src/errors/result.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use core::{convert, ops};
22

33
use super::compile::CompileError;
4-
use crate::prelude::display_errors;
4+
use crate::errors::display::display_errors;
55

6+
#[derive(Debug)]
67
pub struct Res<T> {
78
errors: Vec<CompileError>,
89
result: T,
@@ -34,7 +35,7 @@ impl<T> Res<T> {
3435
self.result
3536
} else {
3637
display_errors(self.errors, files, err_type);
37-
panic!()
38+
panic!(/* Fail when displaying errors */)
3839
}
3940
}
4041

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ mod parser;
5858

5959
#[allow(clippy::pub_use, unused_imports)]
6060
pub mod prelude {
61-
pub use crate::errors::display::display_errors;
6261
pub use crate::errors::location::Location;
6362
pub use crate::errors::result::Res;
6463
pub use crate::lexer::api::{number_types, tokens_types};

src/parser/mod.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ fn parse_block(
3232
current: &mut Node,
3333
) -> Result<(), CompileError> {
3434
tokens.next().map_or(Ok(()), |token| {
35-
println!("Current = {current}\t\tToken = {token:?}");
3635
let (value, location) = token.into_value_location();
3736
match value {
3837
TokenValue::Char(ch) => {
@@ -55,6 +54,18 @@ fn parse_block(
5554
})
5655
}
5756

57+
fn clean_nodes(nodes: Vec<Node>) -> Node {
58+
let mut cleaned = nodes
59+
.into_iter()
60+
.filter(|node| *node != Node::Empty)
61+
.collect::<Vec<_>>();
62+
if cleaned.len() == 1 {
63+
cleaned.pop().expect("len == 1")
64+
} else {
65+
Node::Block(cleaned)
66+
}
67+
}
68+
5869
#[must_use]
5970
#[inline]
6071
pub fn parse_tokens(tokens: Vec<Token>) -> Res<Node> {
@@ -68,5 +79,5 @@ pub fn parse_tokens(tokens: Vec<Token>) -> Res<Node> {
6879
}
6980
nodes.push(outer_node_block);
7081
}
71-
Res::from(Node::Block(nodes))
82+
Res::from(clean_nodes(nodes))
7283
}

src/parser/state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
#[derive(PartialEq, Eq)]
1+
#[derive(PartialEq, Eq, Debug)]
22
pub enum Block {
33
Parenthesis,
44
Brace,
55
Bracket,
66
}
77

8-
#[derive(Default)]
8+
#[derive(Default, Debug)]
99
pub struct ParsingState {
1010
pub wanting_colon: bool,
1111
pub opened_blocks: Vec<Block>,

src/parser/symbols.rs

Lines changed: 87 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use super::state::{Block, ParsingState};
66
use super::tree::binary::BinaryOperator;
77
use super::tree::node::Node;
88
use super::tree::unary::UnaryOperator;
9-
use crate::errors::compile::{as_error, to_error, CompileError};
9+
use crate::errors::compile::{as_error, CompileError};
1010
use crate::errors::location::Location;
1111
use crate::lexer::api::tokens_types::{Symbol, Token};
1212
use crate::parser::parse_block;
@@ -31,27 +31,12 @@ fn handle_double_unary(
3131
.map_or_else(|_| current.push_op(second), |()| Ok(()))
3232
}
3333

34-
fn handle_brace_open(current: &mut Node) -> Result<TodoState, String> {
35-
let res = current.can_push_list_initialiser();
36-
println!("BRACE OPEN = {res:?}");
37-
match res {
38-
Err(op) => Err(format!(
39-
"Found operator '{op}' applied on list initialiser '{{}}', but this is not allowed."
40-
)),
41-
Ok(true) => {
42-
current.push_block_as_leaf(Node::ListInitialiser(ListInitialiser::default()))?;
43-
Ok(TodoState::None)
44-
}
45-
Ok(false) => Ok(TodoState::OpenBraceBlock),
46-
}
47-
}
48-
4934
// TODO: check for nested
50-
enum TodoState {
35+
enum BlockState {
5136
None,
5237
OpenBraceBlock,
5338
CloseBraceBlock,
54-
EndBlock,
39+
SemiColon,
5540
OpenParens,
5641
CloseParens,
5742
OpenBracket,
@@ -64,7 +49,7 @@ fn handle_one_symbol(
6449
symbol: &Symbol,
6550
current: &mut Node,
6651
p_state: &ParsingState,
67-
) -> Result<TodoState, String> {
52+
) -> Result<BlockState, String> {
6853
#[allow(clippy::enum_glob_use)]
6954
use Symbol::*;
7055
match symbol {
@@ -125,29 +110,15 @@ fn handle_one_symbol(
125110
Interrogation => current.push_op(TernaryOperator)?,
126111
Colon => current.handle_colon()?,
127112
// braces & blocks
128-
BraceOpen => return handle_brace_open(current),
129-
BraceClose => {
130-
let res = current.edit_list_initialiser(&|_, full| *full = true);
131-
println!("BRACE CLOSE = {res:?}");
132-
if res.is_err() {
133-
return Ok(TodoState::CloseBraceBlock);
134-
}
135-
}
136-
BracketOpen => return Ok(TodoState::OpenBracket),
137-
BracketClose => return Ok(TodoState::CloseBracket),
138-
ParenthesisOpen => {
139-
if !current.try_make_function() {
140-
return Ok(TodoState::OpenParens);
141-
}
142-
}
143-
ParenthesisClose => {
144-
if !current.try_close_function() {
145-
return Ok(TodoState::CloseParens);
146-
}
147-
}
148-
SemiColon => return Ok(TodoState::EndBlock),
113+
BraceOpen => return Ok(BlockState::OpenBraceBlock),
114+
BraceClose => return Ok(BlockState::CloseBraceBlock),
115+
BracketOpen => return Ok(BlockState::OpenBracket),
116+
BracketClose => return Ok(BlockState::CloseBracket),
117+
ParenthesisOpen => return Ok(BlockState::OpenParens),
118+
ParenthesisClose => return Ok(BlockState::CloseParens),
119+
SemiColon => return Ok(BlockState::SemiColon),
149120
}
150-
Ok(TodoState::None)
121+
Ok(BlockState::None)
151122
}
152123

153124
fn mismatched_err(open: char, close: char) -> String {
@@ -156,22 +127,33 @@ fn mismatched_err(open: char, close: char) -> String {
156127
)
157128
}
158129

159-
pub fn handle_symbol(
160-
symbol: &Symbol,
130+
fn blocks_handler(
161131
current: &mut Node,
162-
p_state: &mut ParsingState,
163132
tokens: &mut IntoIter<Token>,
133+
p_state: &mut ParsingState,
164134
location: Location,
135+
block_state: &BlockState,
165136
) -> Result<(), CompileError> {
166-
match handle_one_symbol(symbol, current, p_state).map_err(|err| to_error!(location, "{err}"))? {
137+
match block_state {
167138
// semi-colon
168-
TodoState::EndBlock => Ok(()),
139+
BlockState::SemiColon => {
140+
if let Node::Block(block) = current
141+
&& !block.last().is_none_or(|node| *node == Node::Empty)
142+
{
143+
block.push(Node::Empty);
144+
} else if *current != Node::Empty {
145+
*current = Node::Block(vec![mem::take(current), Node::Empty]);
146+
} else {
147+
/* last is empty: nothing to be done */
148+
}
149+
parse_block(tokens, p_state, current)
150+
}
169151
// parenthesis
170-
TodoState::CloseParens => {
152+
BlockState::CloseParens if !current.try_close_function() => {
171153
p_state.opened_blocks.push(Block::Parenthesis);
172154
Ok(())
173155
}
174-
TodoState::OpenParens => {
156+
BlockState::OpenParens if !current.try_make_function() => {
175157
let mut parenthesized_block = Node::Empty;
176158
parse_block(tokens, p_state, &mut parenthesized_block)?;
177159
if p_state.opened_blocks.pop() == Some(Block::Parenthesis) {
@@ -180,45 +162,81 @@ pub fn handle_symbol(
180162
.map_err(|err| as_error!(location, "{err}"))?;
181163
parse_block(tokens, p_state, current)
182164
} else {
183-
Err(to_error!(location, "{}", mismatched_err('(', ')')))
165+
Err(as_error!(location, "{}", mismatched_err('(', ')')))
184166
}
185167
}
186-
TodoState::None => parse_block(tokens, p_state, current),
187168
// bracket
188-
TodoState::CloseBracket => {
169+
BlockState::CloseBracket => {
189170
p_state.opened_blocks.push(Block::Bracket);
190171
Ok(())
191172
}
192-
TodoState::OpenBracket => {
173+
BlockState::OpenBracket => {
193174
let mut bracket_node = Node::Empty;
194175
parse_block(tokens, p_state, &mut bracket_node)?;
195176
if p_state.opened_blocks.pop() == Some(Block::Bracket) {
196-
current
197-
.push_op(BOp::ArraySubscript)
198-
.map_err(|err| to_error!(location, "{err}"))?;
199-
current
177+
if let Err(err) = current.push_op(BOp::ArraySubscript) { Err(as_error!(location, "{err}")) } else {
178+
current
200179
.push_block_as_leaf(bracket_node)
201-
.map_err(|err| to_error!(location, "{err}"))?;
202-
parse_block(tokens, p_state, current)
180+
.map_err(|err| as_error!(location, "{err}"))?;
181+
parse_block(tokens, p_state, current)
182+
}
203183
} else {
204-
Err(to_error!(location, "{}", mismatched_err('[', ']')))
184+
Err(as_error!(location, "{}", mismatched_err('[', ']')))
205185
}
206186
}
207187
// brace
208-
TodoState::CloseBraceBlock => {
188+
BlockState::CloseBraceBlock
189+
if current
190+
.edit_list_initialiser(&|_, full| *full = true)
191+
.is_err() =>
192+
{
209193
p_state.opened_blocks.push(Block::Brace);
210194
Ok(())
211195
}
212-
TodoState::OpenBraceBlock => {
213-
let mut brace_block = Node::Empty;
214-
parse_block(tokens, p_state, &mut brace_block)?;
215-
if p_state.opened_blocks.pop() == Some(Block::Brace) {
216-
let old = mem::take(current);
217-
*current = Node::Block(vec![old, brace_block]);
218-
parse_block(tokens, p_state, current)
219-
} else {
220-
Err(to_error!(location, "{}", mismatched_err('{', '}')))
196+
BlockState::OpenBraceBlock => {
197+
match current.can_push_list_initialiser() {
198+
Err(op) => Err(as_error!(location, "Found operator '{op}' applied on list initialiser '{{}}', but this is not allowed.")),
199+
Ok(true) => {
200+
current.push_block_as_leaf(Node::ListInitialiser(ListInitialiser::default())).map_err(|err| as_error!(location, "{err}"))?;
201+
parse_block(tokens, p_state, current)
202+
}
203+
Ok(false) => {
204+
let mut brace_block = Node::Empty;
205+
parse_block(tokens, p_state, &mut brace_block)?;
206+
if p_state.opened_blocks.pop() == Some(Block::Brace) {
207+
if let Node::Block(vec) = current {
208+
vec.push(brace_block);
209+
} else if *current == Node::Empty {
210+
*current = brace_block;
211+
} else {
212+
*current =
213+
Node::Block(vec![mem::take(current), brace_block]);
214+
}
215+
parse_block(tokens, p_state, current)
216+
} else {
217+
Err(as_error!(location, "{}", mismatched_err('{', '}')))
218+
}
219+
220+
}
221221
}
222222
}
223+
// others
224+
BlockState::None
225+
| BlockState::OpenParens
226+
| BlockState::CloseParens
227+
| BlockState::CloseBraceBlock => parse_block(tokens, p_state, current),
228+
}
229+
}
230+
231+
pub fn handle_symbol(
232+
symbol: &Symbol,
233+
current: &mut Node,
234+
p_state: &mut ParsingState,
235+
tokens: &mut IntoIter<Token>,
236+
location: Location,
237+
) -> Result<(), CompileError> {
238+
match handle_one_symbol(symbol, current, p_state) {
239+
Err(err) => Err(as_error!(location, "{err}")),
240+
Ok(block_state) => blocks_handler(current, tokens, p_state, location, &block_state),
223241
}
224242
}

src/parser/tree/conversions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use core::mem;
22

33
use super::binary::{Binary, BinaryOperator};
44
use super::node::Node;
5+
use super::traits::Operator;
56
use super::unary::{Unary, UnaryOperator};
6-
use super::{Operator, Ternary, TernaryOperator};
7+
use super::{Ternary, TernaryOperator};
78

89
pub trait OperatorConversions: Operator
910
where

0 commit comments

Comments
 (0)