Skip to content

Commit 7668ca4

Browse files
committed
(fix) nested list initialiser
1 parent d0e6f03 commit 7668ca4

File tree

5 files changed

+214
-68
lines changed

5 files changed

+214
-68
lines changed

src/parser/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ fn parse_block(
3232
current: &mut Node,
3333
) -> Result<(), CompileError> {
3434
tokens.next().map_or(Ok(()), |token| {
35+
println!("Current = {current}\t\tToken = {token:?}");
3536
let (value, location) = token.into_value_location();
3637
match value {
3738
TokenValue::Char(ch) => {

src/parser/state.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
#[derive(PartialEq, Eq)]
2+
pub enum Block {
3+
Parenthesis,
4+
Brace,
5+
Bracket,
6+
}
7+
18
#[derive(Default)]
29
pub struct ParsingState {
3-
pub ternary: usize,
410
pub wanting_colon: bool,
5-
pub closing_bracket: bool,
11+
pub opened_blocks: Vec<Block>,
612
}

src/parser/symbols.rs

Lines changed: 82 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use super::state::ParsingState;
1+
extern crate alloc;
2+
use alloc::vec::IntoIter;
3+
use core::mem;
4+
5+
use super::state::{Block, ParsingState};
26
use super::tree::binary::BinaryOperator;
37
use super::tree::node::Node;
48
use super::tree::unary::UnaryOperator;
@@ -7,15 +11,6 @@ use crate::errors::location::Location;
711
use crate::lexer::api::tokens_types::{Symbol, Token};
812
use crate::parser::parse_block;
913
use crate::parser::tree::{ListInitialiser, TernaryOperator};
10-
extern crate alloc;
11-
use alloc::vec::IntoIter;
12-
13-
fn safe_decr(counter: &mut usize, ch: char) -> Result<TodoState, String> {
14-
*counter = counter
15-
.checked_sub(1)
16-
.ok_or_else(|| format!("Mismactched closing '{ch}'"))?;
17-
Ok(TodoState::CloseBlock)
18-
}
1914

2015
fn handle_double_binary(
2116
current: &mut Node,
@@ -36,11 +31,29 @@ fn handle_double_unary(
3631
.map_or_else(|_| current.push_op(second), |()| Ok(()))
3732
}
3833

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+
3949
// TODO: check for nested
4050
enum TodoState {
4151
None,
52+
OpenBraceBlock,
53+
CloseBraceBlock,
54+
EndBlock,
4255
OpenParens,
43-
CloseBlock,
56+
CloseParens,
4457
OpenBracket,
4558
CloseBracket,
4659
}
@@ -110,58 +123,76 @@ fn handle_one_symbol(
110123
// ternary (only ternary because trigraphs are ignored, and colon is sorted in main function
111124
// in mod.rs)
112125
Interrogation => current.push_op(TernaryOperator)?,
113-
114126
Colon => current.handle_colon()?,
115-
116-
BraceOpen if *current == Node::Empty => *current = Node::Block(vec![]),
117127
// braces & blocks
118-
BraceOpen => {
119-
if let Some(op) = current.contains_operators_on_right() {
120-
return Err(format!(
121-
"Found operator '{op}' applied on list initialiser '{{}}', but this is not allowed."
122-
));
123-
}
124-
current.push_block_as_leaf(Node::ListInitialiser(ListInitialiser::default()))?;
125-
}
128+
BraceOpen => return handle_brace_open(current),
126129
BraceClose => {
127-
if current
128-
.edit_list_initialiser(&|_, full| *full = true)
129-
.is_err()
130-
{
131-
return Err("Mismatched '}'. Found closing brace for a list initialiser, but list was not found.".into());
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);
132134
}
133135
}
134136
BracketOpen => return Ok(TodoState::OpenBracket),
135137
BracketClose => return Ok(TodoState::CloseBracket),
136-
ParenthesisOpen => return Ok(TodoState::OpenParens),
137-
SemiColon | ParenthesisClose => return Ok(TodoState::CloseBlock),
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),
138149
}
139150
Ok(TodoState::None)
140151
}
141152

153+
fn mismatched_err(open: char, close: char) -> String {
154+
format!(
155+
"Mismatched {open}: You either forgot a closing {close} or there is an extra semi-colon."
156+
)
157+
}
158+
142159
pub fn handle_symbol(
143160
symbol: &Symbol,
144161
current: &mut Node,
145162
p_state: &mut ParsingState,
146163
tokens: &mut IntoIter<Token>,
147164
location: Location,
148165
) -> Result<(), CompileError> {
149-
// TODO: i can't believe this works
150166
match handle_one_symbol(symbol, current, p_state).map_err(|err| to_error!(location, "{err}"))? {
167+
// semi-colon
168+
TodoState::EndBlock => Ok(()),
169+
// parenthesis
170+
TodoState::CloseParens => {
171+
p_state.opened_blocks.push(Block::Parenthesis);
172+
Ok(())
173+
}
151174
TodoState::OpenParens => {
152175
let mut parenthesized_block = Node::Empty;
153176
parse_block(tokens, p_state, &mut parenthesized_block)?;
154-
current
155-
.push_block_as_leaf(Node::ParensBlock(Box::from(parenthesized_block)))
156-
.map_err(|err| as_error!(location, "{err}"))?;
157-
parse_block(tokens, p_state, current)
177+
if p_state.opened_blocks.pop() == Some(Block::Parenthesis) {
178+
current
179+
.push_block_as_leaf(Node::ParensBlock(Box::from(parenthesized_block)))
180+
.map_err(|err| as_error!(location, "{err}"))?;
181+
parse_block(tokens, p_state, current)
182+
} else {
183+
Err(to_error!(location, "{}", mismatched_err('(', ')')))
184+
}
158185
}
159186
TodoState::None => parse_block(tokens, p_state, current),
160-
TodoState::CloseBlock => Ok(()),
187+
// bracket
188+
TodoState::CloseBracket => {
189+
p_state.opened_blocks.push(Block::Bracket);
190+
Ok(())
191+
}
161192
TodoState::OpenBracket => {
162193
let mut bracket_node = Node::Empty;
163194
parse_block(tokens, p_state, &mut bracket_node)?;
164-
if p_state.closing_bracket {
195+
if p_state.opened_blocks.pop() == Some(Block::Bracket) {
165196
current
166197
.push_op(BOp::ArraySubscript)
167198
.map_err(|err| to_error!(location, "{err}"))?;
@@ -170,15 +201,24 @@ pub fn handle_symbol(
170201
.map_err(|err| to_error!(location, "{err}"))?;
171202
parse_block(tokens, p_state, current)
172203
} else {
173-
Err(to_error!(
174-
location,
175-
"Expected expression found block, as argument of an array subscript."
176-
))
204+
Err(to_error!(location, "{}", mismatched_err('[', ']')))
177205
}
178206
}
179-
TodoState::CloseBracket => {
180-
p_state.closing_bracket = true;
207+
// brace
208+
TodoState::CloseBraceBlock => {
209+
p_state.opened_blocks.push(Block::Brace);
181210
Ok(())
182211
}
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('{', '}')))
221+
}
222+
}
183223
}
184224
}

src/parser/tree/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,12 @@ pub struct FunctionCall {
9595
#[allow(clippy::min_ident_chars)]
9696
impl fmt::Display for FunctionCall {
9797
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98-
write!(f, "{}({})", self.name, repr_vec_node(&self.args))
98+
write!(
99+
f,
100+
"\u{b0}{}\u{b0}({})",
101+
self.name,
102+
repr_vec_node(&self.args)
103+
)
99104
}
100105
}
101106

0 commit comments

Comments
 (0)