Skip to content

Commit a28506f

Browse files
authored
Ast simplification (#963)
simplilfy AST by introducing AstNode and Structs for AstStatements the AstStatement-Enum no longer defines the data-structs in the enum itself, we now offer dedicated structs for every AstStatement to allow trait-impls. The AstId and the location are now stored in its own AstNode and no longer in a stores it as part of the AstStatement. renamed ast structs to AstNode and AstStatement
1 parent 87663fb commit a28506f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2306
-2392
lines changed

compiler/plc_ast/src/ast.rs

Lines changed: 506 additions & 458 deletions
Large diffs are not rendered by default.

compiler/plc_ast/src/control_statements.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
use std::fmt::{Debug, Formatter};
22

3-
use crate::ast::AstStatement;
3+
use crate::ast::AstNode;
44

55
#[derive(Clone, PartialEq)]
66
pub struct IfStatement {
77
pub blocks: Vec<ConditionalBlock>,
8-
pub else_block: Vec<AstStatement>,
8+
pub else_block: Vec<AstNode>,
99
}
1010

1111
#[derive(Clone, PartialEq)]
1212
pub struct ForLoopStatement {
13-
pub counter: Box<AstStatement>,
14-
pub start: Box<AstStatement>,
15-
pub end: Box<AstStatement>,
16-
pub by_step: Option<Box<AstStatement>>,
17-
pub body: Vec<AstStatement>,
13+
pub counter: Box<AstNode>,
14+
pub start: Box<AstNode>,
15+
pub end: Box<AstNode>,
16+
pub by_step: Option<Box<AstNode>>,
17+
pub body: Vec<AstNode>,
1818
}
1919

2020
#[derive(Clone, PartialEq)]
2121
/// used for While and Repeat loops
2222
pub struct LoopStatement {
23-
pub condition: Box<AstStatement>,
24-
pub body: Vec<AstStatement>,
23+
pub condition: Box<AstNode>,
24+
pub body: Vec<AstNode>,
2525
}
2626

2727
#[derive(Clone, PartialEq)]
2828
pub struct CaseStatement {
29-
pub selector: Box<AstStatement>,
29+
pub selector: Box<AstNode>,
3030
pub case_blocks: Vec<ConditionalBlock>,
31-
pub else_block: Vec<AstStatement>,
31+
pub else_block: Vec<AstNode>,
3232
}
3333

3434
#[derive(Clone, PartialEq)]
@@ -42,8 +42,8 @@ pub enum AstControlStatement {
4242

4343
#[derive(Clone, PartialEq)]
4444
pub struct ConditionalBlock {
45-
pub condition: Box<AstStatement>,
46-
pub body: Vec<AstStatement>,
45+
pub condition: Box<AstNode>,
46+
pub body: Vec<AstNode>,
4747
}
4848

4949
impl Debug for ConditionalBlock {

compiler/plc_ast/src/literals.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::fmt::{Debug, Formatter};
22

33
use chrono::NaiveDate;
44

5-
use crate::ast::AstStatement;
5+
use crate::ast::AstNode;
66

77
macro_rules! impl_getters {
88
($type:ty, [$($name:ident),+], [$($out:ty),+]) => {
@@ -84,7 +84,7 @@ pub struct StringValue {
8484

8585
#[derive(Clone, PartialEq)]
8686
pub struct Array {
87-
pub elements: Option<Box<AstStatement>>, // expression-list
87+
pub elements: Option<Box<AstNode>>, // expression-list
8888
}
8989

9090
/// calculates the nanoseconds since 1970-01-01-00:00:00 for the given
@@ -170,14 +170,14 @@ impl Time {
170170
}
171171

172172
impl Array {
173-
pub fn elements(&self) -> Option<&AstStatement> {
173+
pub fn elements(&self) -> Option<&AstNode> {
174174
self.elements.as_ref().map(|it| it.as_ref())
175175
}
176176
}
177177

178178
impl AstLiteral {
179179
/// Creates a new literal array
180-
pub fn new_array(elements: Option<Box<AstStatement>>) -> Self {
180+
pub fn new_array(elements: Option<Box<AstNode>>) -> Self {
181181
AstLiteral::Array(Array { elements })
182182
}
183183
/// Creates a new literal integer

compiler/plc_ast/src/pre_processor.rs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use plc_util::convention::internal_type_name;
66

77
use crate::{
88
ast::{
9-
flatten_expression_list, AstFactory, AstStatement, CompilationUnit, DataType, DataTypeDeclaration,
10-
Operator, Pou, UserTypeDeclaration, Variable,
9+
flatten_expression_list, Assignment, AstFactory, AstNode, AstStatement, CompilationUnit, DataType,
10+
DataTypeDeclaration, Operator, Pou, UserTypeDeclaration, Variable,
1111
},
1212
literals::AstLiteral,
1313
provider::IdProvider,
@@ -80,27 +80,24 @@ pub fn pre_process(unit: &mut CompilationUnit, mut id_provider: IdProvider) {
8080
}
8181
}
8282
DataType::EnumType { elements, .. }
83-
if matches!(elements, AstStatement::EmptyStatement { .. }) =>
83+
if matches!(elements.stmt, AstStatement::EmptyStatement { .. }) =>
8484
{
8585
//avoid empty statements, just use an empty expression list to make it easier to work with
86-
let _ = std::mem::replace(
87-
elements,
88-
AstStatement::ExpressionList { expressions: vec![], id: id_provider.next_id() },
89-
);
86+
let _ = std::mem::replace(&mut elements.stmt, AstStatement::ExpressionList(vec![]));
9087
}
9188
DataType::EnumType { elements: original_elements, name: Some(enum_name), .. }
92-
if !matches!(original_elements, AstStatement::EmptyStatement { .. }) =>
89+
if !matches!(original_elements.stmt, AstStatement::EmptyStatement { .. }) =>
9390
{
9491
let mut last_name: Option<String> = None;
9592

96-
fn extract_flat_ref_name(statement: &AstStatement) -> &str {
93+
fn extract_flat_ref_name(statement: &AstNode) -> &str {
9794
statement.get_flat_reference_name().expect("expected assignment")
9895
}
9996

10097
let initialized_enum_elements = flatten_expression_list(original_elements)
10198
.iter()
102-
.map(|it| match it {
103-
AstStatement::Assignment { left, right, .. } => {
99+
.map(|it| match &it.stmt {
100+
AstStatement::Assignment(Assignment { left, right }) => {
104101
//<element-name, initializer, location>
105102
(
106103
extract_flat_ref_name(left.as_ref()),
@@ -115,28 +112,34 @@ pub fn pre_process(unit: &mut CompilationUnit, mut id_provider: IdProvider) {
115112
build_enum_initializer(&last_name, &location, &mut id_provider, enum_name)
116113
});
117114
last_name = Some(element_name.to_string());
118-
AstStatement::Assignment {
119-
id: id_provider.next_id(),
120-
left: Box::new(AstFactory::create_member_reference(
115+
AstFactory::create_assignment(
116+
AstFactory::create_member_reference(
121117
AstFactory::create_identifier(
122118
element_name,
123119
&location,
124120
id_provider.next_id(),
125121
),
126122
None,
127123
id_provider.next_id(),
128-
)),
129-
right: Box::new(enum_literal),
130-
}
124+
),
125+
enum_literal,
126+
id_provider.next_id(),
127+
)
131128
})
132-
.collect::<Vec<AstStatement>>();
129+
.collect::<Vec<AstNode>>();
133130
// if the enum is empty, we dont change anything
134131
if !initialized_enum_elements.is_empty() {
132+
// we can safely unwrap because we checked the vec
133+
let start_loc =
134+
initialized_enum_elements.first().expect("non empty vec").get_location();
135+
let end_loc =
136+
initialized_enum_elements.iter().last().expect("non empty vec").get_location();
135137
//swap the expression list with our new Assignments
136-
let expression = AstStatement::ExpressionList {
137-
expressions: initialized_enum_elements,
138-
id: id_provider.next_id(),
139-
};
138+
let expression = AstFactory::create_expression_list(
139+
initialized_enum_elements,
140+
start_loc.span(&end_loc),
141+
id_provider.next_id(),
142+
);
140143
let _ = std::mem::replace(original_elements, expression);
141144
}
142145
}
@@ -152,7 +155,7 @@ fn build_enum_initializer(
152155
location: &SourceLocation,
153156
id_provider: &mut IdProvider,
154157
enum_name: &mut str,
155-
) -> AstStatement {
158+
) -> AstNode {
156159
if let Some(last_element) = last_name.as_ref() {
157160
// generate a `enum#last + 1` statement
158161
let enum_ref = AstFactory::create_identifier(last_element, location, id_provider.next_id());
@@ -164,11 +167,11 @@ fn build_enum_initializer(
164167
AstFactory::create_binary_expression(
165168
AstFactory::create_cast_statement(type_element, enum_ref, location, id_provider.next_id()),
166169
Operator::Plus,
167-
AstStatement::new_literal(AstLiteral::new_integer(1), id_provider.next_id(), location.clone()),
170+
AstNode::new_literal(AstLiteral::new_integer(1), id_provider.next_id(), location.clone()),
168171
id_provider.next_id(),
169172
)
170173
} else {
171-
AstStatement::new_literal(AstLiteral::new_integer(0), id_provider.next_id(), location.clone())
174+
AstNode::new_literal(AstLiteral::new_integer(0), id_provider.next_id(), location.clone())
172175
}
173176
}
174177

compiler/plc_diagnostics/src/diagnostics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{error::Error, ops::Range};
22

3-
use plc_ast::ast::{AstStatement, DataTypeDeclaration, DiagnosticInfo, PouType};
3+
use plc_ast::ast::{AstNode, DataTypeDeclaration, DiagnosticInfo, PouType};
44
use plc_source::source_location::SourceLocation;
55

66
use crate::errno::ErrNo;
@@ -669,7 +669,7 @@ impl Diagnostic {
669669
}
670670
}
671671

672-
pub fn invalid_range_statement(entity: &AstStatement, range: SourceLocation) -> Diagnostic {
672+
pub fn invalid_range_statement(entity: &AstNode, range: SourceLocation) -> Diagnostic {
673673
Diagnostic::SyntaxError {
674674
message: format!("Expected a range statement, got {entity:?} instead"),
675675
range: vec![range],

compiler/plc_driver/src/pipelines.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl IndexedProject {
182182

183183
/// A project that has been annotated with information about different types and used units
184184
pub struct AnnotatedProject {
185-
units: Vec<(CompilationUnit, IndexSet<Dependency>, StringLiterals)>,
185+
pub units: Vec<(CompilationUnit, IndexSet<Dependency>, StringLiterals)>,
186186
index: Index,
187187
annotations: AstAnnotations,
188188
}

compiler/plc_driver/src/runner.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub fn compile<T: Compilable>(context: &CodegenContext, source: T) -> GeneratedM
3838
..Default::default()
3939
};
4040

41+
dbg!(&annotated_project.units[0].0);
4142
annotated_project.generate_single_module(context, &compile_options).unwrap().unwrap()
4243
}
4344

compiler/plc_xml/src/xml_parser.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use ast::{
2-
ast::{AstId, AstStatement, CompilationUnit, Implementation, LinkageType, PouType as AstPouType},
2+
ast::{AstId, AstNode, CompilationUnit, Implementation, LinkageType, PouType as AstPouType},
33
provider::IdProvider,
44
};
55
use plc::{lexer, parser::expressions_parser::parse_expression};
@@ -119,14 +119,15 @@ impl<'parse> ParseSession<'parse> {
119119
))
120120
}
121121

122-
fn parse_expression(&self, expr: &str, local_id: usize, execution_order: Option<usize>) -> AstStatement {
123-
let exp = parse_expression(&mut lexer::lex_with_ids(
122+
fn parse_expression(&self, expr: &str, local_id: usize, execution_order: Option<usize>) -> AstNode {
123+
let mut exp = parse_expression(&mut lexer::lex_with_ids(
124124
html_escape::decode_html_entities_to_string(expr, &mut String::new()),
125125
self.id_provider.clone(),
126126
self.range_factory.clone(),
127127
));
128128
let loc = exp.get_location();
129-
exp.set_location(self.range_factory.create_block_location(local_id, execution_order).span(&loc))
129+
exp.set_location(self.range_factory.create_block_location(local_id, execution_order).span(&loc));
130+
exp
130131
}
131132

132133
fn parse_model(&self) -> Vec<Implementation> {

compiler/plc_xml/src/xml_parser/action.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use ast::ast::{AstStatement, Implementation, PouType as AstPouType};
1+
use ast::ast::{AstNode, Implementation, PouType as AstPouType};
22

33
use crate::model::action::Action;
44

55
use super::ParseSession;
66

77
impl Action {
8-
pub(crate) fn transform(&self, _session: &ParseSession) -> Vec<AstStatement> {
8+
pub(crate) fn transform(&self, _session: &ParseSession) -> Vec<AstNode> {
99
todo!()
1010
}
1111

compiler/plc_xml/src/xml_parser/block.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use ast::ast::{AstFactory, AstStatement};
1+
use ast::ast::{AstFactory, AstNode};
22

33
use crate::model::{block::Block, fbd::NodeIndex};
44

55
use super::ParseSession;
66

77
impl Block {
8-
pub(crate) fn transform(&self, session: &ParseSession, index: &NodeIndex) -> AstStatement {
8+
pub(crate) fn transform(&self, session: &ParseSession, index: &NodeIndex) -> AstNode {
99
let parameters = self
1010
.variables
1111
.iter()

0 commit comments

Comments
 (0)