Skip to content

Commit 8d161f1

Browse files
committed
(fix) functions and blocks
1 parent 3a9d4f6 commit 8d161f1

File tree

10 files changed

+189
-82
lines changed

10 files changed

+189
-82
lines changed

src/errors/display.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub fn display_errors(errors: Vec<CompileError>, files: &[(String, &str)], err_t
1010
}
1111
for error in errors {
1212
let (location, message, err_lvl, length) = error.get();
13-
let (filename, line_nb, column_nb) = location.get();
13+
let (filename, line_nb, column_nb) = location.into_values();
1414
let code_lines = files_status
1515
.get(&filename)
1616
.expect("Never happens: File of error doesn't exist");

src/errors/location.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ pub struct Location {
1010
}
1111

1212
impl Location {
13-
pub(crate) fn get(self) -> (String, usize, usize) {
14-
(self.file, self.line, self.col)
13+
pub(crate) const fn get_values(&self) -> (&String, usize, usize) {
14+
(&self.file, self.line, self.col)
1515
}
1616

1717
pub(crate) fn incr_col(&mut self) {
@@ -34,6 +34,10 @@ impl Location {
3434
}
3535
}
3636

37+
pub(crate) fn into_values(self) -> (String, usize, usize) {
38+
(self.file, self.line, self.col)
39+
}
40+
3741
pub(crate) fn to_error(&self, msg: String) -> CompileError {
3842
CompileError::from((self.to_owned(), msg, ErrorLevel::Error))
3943
}

src/errors/result.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@ impl<T: Default> Res<T> {
3030
errors: vec![err],
3131
}
3232
}
33-
}
3433

35-
impl<T> Res<Option<T>> {
36-
pub(crate) const fn from_errors(errors: Vec<CompileError>) -> Self {
34+
pub(crate) fn from_errors(errors: Vec<CompileError>) -> Self {
3735
Self {
38-
result: None,
36+
result: T::default(),
3937
errors,
4038
}
4139
}

src/lexer/numbers/types.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,12 @@ impl NumberType {
105105
Self::Int => Self::UInt,
106106
Self::Long if signed => Self::LongLong,
107107
Self::Long => Self::ULong,
108-
Self::LongLong if signed => return None,
109-
Self::LongLong => Self::ULongLong,
110-
Self::Float => Self::Double,
111-
Self::Double => Self::LongDouble,
112-
Self::LongDouble => return None,
108+
Self::LongLong if !signed => Self::ULongLong,
113109
Self::UInt => Self::ULong,
114110
Self::ULong => Self::ULongLong,
115-
Self::ULongLong => return None,
111+
Self::ULongLong | Self::LongLong | Self::Float | Self::Double | Self::LongDouble => {
112+
return None
113+
}
116114
})
117115
}
118116

src/lexer/types/tokens_types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ impl Token {
104104
}
105105
}
106106

107+
pub(crate) const fn get_location(&self) -> &Location {
108+
&self.location
109+
}
110+
107111
#[inline]
108112
#[must_use]
109113
pub const fn get_value(&self) -> &TokenValue {

src/parser/parse_content.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
extern crate alloc;
22
use alloc::vec::IntoIter;
33

4-
use super::state::ParsingState;
4+
use super::state::{BlockState, ParsingState};
55
use super::symbols::handle_symbol;
66
use super::tree::blocks::Block;
77
use super::tree::node::Node;
@@ -37,6 +37,22 @@ fn handle_literal(
3737
parse_block(tokens, p_state, current)
3838
}
3939

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+
4056
#[expect(clippy::todo, reason = "implementation in process")]
4157
pub fn parse_block(
4258
tokens: &mut IntoIter<Token>,
@@ -68,13 +84,24 @@ pub fn parse_block(
6884
#[inline]
6985
pub fn parse_tokens(tokens: Vec<Token>) -> Res<Node> {
7086
let mut nodes = vec![];
87+
let filename = tokens
88+
.first()
89+
.map(|node| node.get_location().get_values().0.to_owned());
7190
let mut tokens_iter = tokens.into_iter();
7291
while tokens_iter.len() != 0 {
7392
let mut outer_node_block = Node::default();
7493
let mut p_state = ParsingState::default();
7594
if let Err(err) = parse_block(&mut tokens_iter, &mut p_state, &mut outer_node_block) {
7695
return Res::from_err(err);
7796
}
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+
78105
nodes.push(outer_node_block);
79106
}
80107
Res::from(clean_nodes(nodes))

src/parser/state.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,37 @@
1+
use crate::errors::api::CompileError;
2+
use crate::Location;
3+
14
#[derive(PartialEq, Eq, Debug)]
25
pub enum BlockState {
36
Brace,
47
Bracket,
58
Parenthesis,
69
}
710

11+
impl BlockState {
12+
const fn get_delimiters(&self) -> (char, char) {
13+
match self {
14+
Self::Brace => ('{', '}'),
15+
Self::Bracket => ('[', ']'),
16+
Self::Parenthesis => ('(', ')'),
17+
}
18+
}
19+
20+
pub fn mismatched_err_begin(&self, location: Location) -> CompileError {
21+
let (open, close) = self.get_delimiters();
22+
location.into_error(format!(
23+
"Mismatched '{close}'. Perhaps you forgot an opening '{open}'?"
24+
))
25+
}
26+
27+
pub fn mismatched_err_end(&self, location: Location) -> CompileError {
28+
let (open, close) = self.get_delimiters();
29+
location.into_error(format!(
30+
"Mismatched '{open}': reached end of block. Perhaps you forgot a closing '{close}'?"
31+
))
32+
}
33+
}
34+
835
#[derive(Default, Debug)]
936
pub struct ParsingState {
1037
pub opened_blocks: Vec<BlockState>,

src/parser/symbols/blocks.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub fn blocks_handler(
5252
.map_err(|err| location.into_error(err))?;
5353
parse_block(tokens, p_state, current)
5454
} else {
55-
Err(location.into_error(mismatched_err('(', ')')))
55+
Err(BlockState::Parenthesis.mismatched_err_end(location))
5656
}
5757
}
5858
// bracket
@@ -73,7 +73,7 @@ pub fn blocks_handler(
7373
parse_block(tokens, p_state, current)
7474
}
7575
} else {
76-
Err(location.into_error(mismatched_err('[', ']')))
76+
Err(BlockState::Bracket.mismatched_err_end(location))
7777
}
7878
}
7979
// brace
@@ -114,7 +114,7 @@ fn handle_brace_block_open(
114114
let mut brace_block = Node::Block(Block::default());
115115
parse_block(tokens, p_state, &mut brace_block)?;
116116
if p_state.opened_blocks.pop() != Some(BlockState::Brace) {
117-
return Err(location.into_error(mismatched_err('{', '}')));
117+
return Err(BlockState::Brace.mismatched_err_end(location));
118118
}
119119
if let Node::Block(Block { full, .. }) = &mut brace_block {
120120
*full = true;
@@ -151,9 +151,3 @@ fn handle_colon(current: &mut Node) {
151151
/* last is empty: nothing to be done */
152152
}
153153
}
154-
155-
fn mismatched_err(open: char, close: char) -> String {
156-
format!(
157-
"Mismatched {open}: You either forgot a closing {close} or there is an extra semi-colon."
158-
)
159-
}

src/parser/tree/node.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,14 @@ impl Node {
381381
}
382382
}
383383
Ordering::Equal => {
384-
// doing whatever works ?
385-
op.try_push_op_as_root(self)
384+
// doing whatever works ? no ! e.g.: !g(!x) gives !!g(x)
385+
// for `op.try_push_op_as_root(self)`
386+
if let Some(node) = arg {
387+
node.push_op(op)
388+
} else {
389+
*arg = Some(Box::from(op.try_to_node()?));
390+
Ok(())
391+
}
386392
}
387393
}
388394
}
@@ -440,7 +446,12 @@ impl Node {
440446
//
441447
//
442448
// success
443-
Self::FunctionCall(FunctionCall { full: full @ false, .. }) => {*full = true; true }
449+
Self::FunctionCall(FunctionCall { full: full @ false, args, .. }) => {
450+
if !args.last_mut().is_some_and(Self::try_close_function) {
451+
*full = true; }
452+
true
453+
454+
}
444455
//
445456
//
446457
// failure

0 commit comments

Comments
 (0)