Skip to content

Commit edfe821

Browse files
committed
(parser) fix: indirections can be part of type declaration
1 parent 0448b47 commit edfe821

File tree

14 files changed

+224
-168
lines changed

14 files changed

+224
-168
lines changed

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010
clippy::nursery,
1111
clippy::cargo
1212
)]
13-
//
13+
// lints that are not meant to be used
1414
#![allow(clippy::single_call_fn)]
1515
#![allow(clippy::implicit_return)]
1616
#![allow(clippy::pattern_type_mismatch)]
1717
#![allow(clippy::blanket_clippy_restriction_lints)]
18+
#![allow(clippy::missing_trait_methods)]
1819
//
1920
#![allow(clippy::missing_docs_in_private_items)]
2021
#![allow(clippy::arithmetic_side_effects)]

src/parser/keyword/types/attributes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ use super::PushInNode;
77
use crate::lexer::api::Keyword;
88
use crate::parser::tree::binary::Binary;
99
use crate::parser::tree::blocks::Block;
10+
use crate::parser::tree::literal::{Literal, Variable};
1011
use crate::parser::tree::unary::Unary;
11-
use crate::parser::tree::{FunctionCall, ListInitialiser, Literal, Ternary, Variable};
12+
use crate::parser::tree::{FunctionCall, ListInitialiser, Ternary};
1213

1314
macro_rules! define_attribute_keywords {
1415
($($name:ident: $($variant:ident)*,)*) => {

src/parser/keyword/types/functions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use core::fmt;
22

33
use super::super::Ast;
44
use super::PushInNode;
5-
use crate::parser::tree::{Literal, Variable};
5+
use crate::parser::tree::literal::{Literal, Variable};
66

77
#[derive(Debug, PartialEq, Eq)]
88
pub enum FunctionKeyword {

src/parser/keyword/types/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use functions::FunctionKeyword as Func;
1515

1616
use super::super::tree::node::Ast;
1717
use crate::lexer::api::Keyword;
18-
use crate::parser::tree::Literal;
18+
use crate::parser::tree::literal::Literal;
1919

2020
pub enum KeywordParsing {
2121
Attr(Attr),

src/parser/parse_content.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use super::keyword::handle_keyword;
55
use super::state::{BlockState, ParsingState};
66
use super::symbols::handle_symbol;
77
use super::tree::blocks::Block;
8+
use super::tree::literal::{Literal, Variable};
89
use super::tree::node::Ast;
9-
use super::tree::{Literal, Variable};
1010
use crate::errors::api::{CompileError, Location, Res};
1111
use crate::lexer::api::{Token, TokenValue};
1212

src/parser/symbols/blocks.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub fn blocks_handler(
3535
match block_state {
3636
// semi-colon
3737
TodoBlock::SemiColon => {
38-
handle_colon(current);
38+
handle_semicolon(current);
3939
parse_block(tokens, p_state, current)
4040
}
4141
// parenthesis
@@ -135,7 +135,7 @@ fn handle_brace_block_open(
135135
parse_block(tokens, p_state, current)
136136
}
137137

138-
fn handle_colon(current: &mut Ast) {
138+
fn handle_semicolon(current: &mut Ast) {
139139
if let Ast::Block(Block { elts, full }) = current
140140
&& !*full
141141
{

src/parser/symbols/handlers.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@ use super::super::tree::binary::BinaryOperator;
22
use super::super::tree::node::Ast;
33
use super::super::tree::unary::UnaryOperator;
44

5+
pub fn handle_binary_unary(
6+
current: &mut Ast,
7+
bin_op: BinaryOperator,
8+
un_op: UnaryOperator,
9+
) -> Result<(), String> {
10+
current
11+
.push_op(bin_op)
12+
.map_or_else(|_| current.push_op(un_op), |()| Ok(()))
13+
}
14+
515
pub fn handle_comma(current: &mut Ast) -> Result<(), String> {
616
if current
717
.apply_to_last_list_initialiser(&|vec, _| vec.push(Ast::Empty))
@@ -12,16 +22,6 @@ pub fn handle_comma(current: &mut Ast) -> Result<(), String> {
1222
Ok(())
1323
}
1424

15-
pub fn handle_double_binary(
16-
current: &mut Ast,
17-
bin_op: BinaryOperator,
18-
un_op: UnaryOperator,
19-
) -> Result<(), String> {
20-
current
21-
.push_op(bin_op)
22-
.map_or_else(|_| current.push_op(un_op), |()| Ok(()))
23-
}
24-
2525
pub fn handle_double_unary(
2626
current: &mut Ast,
2727
first: UnaryOperator,

src/parser/symbols/sort_symbols.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::super::tree::node::Ast;
55
use super::super::tree::unary::UnaryOperator;
66
use super::super::tree::TernaryOperator;
77
use super::blocks::TodoBlock;
8-
use super::handlers::{handle_comma, handle_double_binary, handle_double_unary};
8+
use super::handlers::{handle_binary_unary, handle_comma, handle_double_unary};
99
use crate::lexer::api::Symbol;
1010

1111
enum SymbolParsing {
@@ -86,7 +86,7 @@ pub fn handle_one_symbol(symbol: Symbol, current: &mut Ast) -> Result<TodoBlock,
8686
SymbolParsing::UniqueBinary(op) => current.push_op(op)?,
8787
// doubles
8888
SymbolParsing::DoubleUnary(first, second) => handle_double_unary(current, first, second)?,
89-
SymbolParsing::BinaryUnary(bin_op, un_op) => handle_double_binary(current, bin_op, un_op)?,
89+
SymbolParsing::BinaryUnary(bin_op, un_op) => handle_binary_unary(current, bin_op, un_op)?,
9090
// blocks
9191
SymbolParsing::Block(block) => return Ok(block),
9292
// special

src/parser/tree/binary.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use core::fmt;
44

5+
use super::unary::UnaryOperator;
56
use super::{Associativity, Ast, Operator};
67

78
macro_rules! define_binary_operator {
@@ -96,3 +97,9 @@ define_binary_operator!(
9697
XorAssign 14, "^="
9798
OrAssign 14, "|="
9899
);
100+
101+
impl PartialEq<UnaryOperator> for BinaryOperator {
102+
fn eq(&self, _: &UnaryOperator) -> bool {
103+
false
104+
}
105+
}

src/parser/tree/literal.rs

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
use crate::{parser::keyword::types::{attributes::AttributeKeyword, functions::FunctionKeyword}, Number, EMPTY};
2+
use core::{fmt, mem};
3+
4+
#[derive(Debug, PartialEq, Eq)]
5+
pub enum Attribute {
6+
Indirection,
7+
Keyword(AttributeKeyword),
8+
User(String),
9+
}
10+
11+
#[expect(clippy::min_ident_chars)]
12+
impl fmt::Display for Attribute {
13+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
14+
match self {
15+
Self::Indirection => '*'.fmt(f),
16+
Self::Keyword(keywd) => keywd.fmt(f),
17+
Self::User(val) => write!(f, "'{val}'"),
18+
}
19+
}
20+
}
21+
22+
#[derive(Debug, PartialEq)]
23+
pub enum Literal {
24+
Char(char),
25+
ConstantBool(bool),
26+
Empty,
27+
Nullptr,
28+
Number(Number),
29+
Str(String),
30+
Variable(Variable),
31+
}
32+
33+
#[expect(clippy::min_ident_chars)]
34+
impl fmt::Display for Literal {
35+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36+
match self {
37+
Self::Empty => EMPTY.fmt(f),
38+
Self::Nullptr => "NULL".fmt(f),
39+
Self::Char(val) => write!(f, "'{val}'"),
40+
Self::Str(val) => write!(f, "\"{val}\""),
41+
Self::Number(val) => val.fmt(f),
42+
Self::ConstantBool(val) => val.fmt(f),
43+
Self::Variable(val) => val.fmt(f),
44+
}
45+
}
46+
}
47+
48+
49+
#[derive(Debug, PartialEq, Default, Eq)]
50+
pub struct Variable {
51+
pub attrs: Vec<Attribute>,
52+
pub name: VariableName,
53+
}
54+
55+
impl Variable {
56+
pub const fn from_keyword(keyword: FunctionKeyword) -> Self {
57+
Self {
58+
name: VariableName::Keyword(keyword),
59+
attrs: vec![],
60+
}
61+
}
62+
63+
pub fn push_attr(&mut self, attr: AttributeKeyword) {
64+
self.attrs.push(Attribute::Keyword(attr));
65+
}
66+
67+
pub fn push_indirection(&mut self) -> Result<(), String> {
68+
match mem::take(&mut self.name) {
69+
VariableName::Empty => (),
70+
VariableName::Keyword(keywd) => return Err(format!("Found '*' after function keyword {keywd}.")),
71+
VariableName::UserDefined(name) => self.attrs.push(Attribute::User(name)),
72+
}
73+
self.attrs.push(Attribute::Indirection);
74+
Ok(())
75+
}
76+
77+
pub fn push_str(&mut self, value: String) -> Result<(), String> {
78+
match mem::take(&mut self.name) {
79+
VariableName::Empty => {self.name = VariableName::UserDefined(value); Ok(())},
80+
VariableName::Keyword(keyword) => Err(format!("Found 2 successive literals, found identifier {value} after function keyword {keyword}.")),
81+
VariableName::UserDefined(old) => {
82+
self.attrs.push(Attribute::User(old));
83+
self.name = VariableName::UserDefined(value);
84+
Ok(())
85+
}
86+
}
87+
}
88+
89+
}
90+
91+
impl From<String> for Variable {
92+
fn from(name: String) -> Self {
93+
Self {
94+
name: VariableName::UserDefined(name),
95+
attrs: vec![],
96+
}
97+
}
98+
}
99+
100+
impl From<AttributeKeyword> for Variable {
101+
fn from(attr: AttributeKeyword) -> Self {
102+
Self {
103+
name: VariableName::Empty,
104+
attrs: vec![Attribute::Keyword(attr)],
105+
}
106+
}
107+
}
108+
109+
#[expect(clippy::min_ident_chars)]
110+
impl fmt::Display for Variable {
111+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
112+
if self.attrs.is_empty() {
113+
self.name.fmt(f)
114+
} else {
115+
write!(
116+
f,
117+
"({} {})",
118+
self.attrs
119+
.iter()
120+
.map(|attr| format!("{attr}"))
121+
.collect::<Vec<_>>()
122+
.join(" "),
123+
self.name
124+
)
125+
}
126+
}
127+
}
128+
129+
#[derive(Debug, PartialEq, Eq, Default)]
130+
pub enum VariableName {
131+
#[default]
132+
Empty,
133+
Keyword(FunctionKeyword),
134+
UserDefined(String),
135+
}
136+
137+
impl From<&str> for VariableName {
138+
fn from(name: &str) -> Self {
139+
Self::UserDefined(name.to_owned())
140+
}
141+
}
142+
143+
#[expect(clippy::min_ident_chars)]
144+
impl fmt::Display for VariableName {
145+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146+
match self {
147+
Self::Empty => EMPTY.fmt(f),
148+
Self::UserDefined(val) => val.fmt(f),
149+
Self::Keyword(val) => val.fmt(f),
150+
}
151+
}
152+
}

0 commit comments

Comments
 (0)